2 * linux/drivers/mmc/moxasd.c - Moxa CPU SD/MMC driver
4 * Copyright (C) 2005 Moxa Tech., All Rights Reserved.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 #include <linux/config.h>
12 #include <asm/arch/cpe/cpe.h>
13 #include <asm/arch/cpe_int.h>
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/ioport.h>
17 #include <linux/device.h>
18 #include <linux/delay.h>
19 #include <linux/interrupt.h>
20 #include <linux/blkdev.h>
21 #include <linux/dma-mapping.h>
22 #include <linux/mmc/host.h>
23 #include <linux/sched.h>
24 #include <linux/delay.h>
25 #include <linux/mmc/protocol.h>
30 #include <asm/sizes.h>
31 #include <asm/arch/gpio.h>
35 //#define MSD_SUPPORT_GET_CLOCK 1
37 #define MSD_RETRY_COUNT 1000
39 //#define CONFIG_MMC_DEBUG
40 #ifdef CONFIG_MMC_DEBUG
41 #define DBG(x...) printk(x)
51 #ifdef MSD_SUPPORT_GET_CLOCK
54 struct mmc_request *mrq;
55 struct mmc_data *data;
57 struct scatterlist *cur_sg; /* Current SG entry */
58 unsigned int num_sg; /* Number of entries left */
59 void *mapped_sg; /* vaddr of mapped sg */
60 unsigned int offset; /* Offset into current entry */
61 unsigned int remain; /* Data left in curren entry */
62 int size; /* Total size of transfer */
64 struct tasklet_struct card_change_tasklet;
65 struct tasklet_struct fifo_run_tasklet;
68 static inline void moxasd_init_sg(struct moxasd_host* host, struct mmc_data* data)
71 * Get info. about SG list from data structure.
74 host->cur_sg = data->sg;
75 host->num_sg = data->sg_len;
78 host->remain = host->cur_sg->length;
79 data->error = MMC_ERR_NONE;
82 static inline int moxasd_next_sg(struct moxasd_host* host)
85 * Skip to next SG entry.
94 if (host->num_sg > 0) {
96 host->remain = host->cur_sg->length;
102 static inline char *moxasd_kmap_sg(struct moxasd_host* host)
104 host->mapped_sg = kmap_atomic(host->cur_sg->page, KM_BIO_SRC_IRQ) +
105 host->cur_sg->offset;
106 return host->mapped_sg;
109 static inline void moxasd_check_data_crc(struct moxasd_host *host, struct mmc_data *data)
113 status = readl(&host->reg->status);
114 if ( status & MSD_DATA_CRC_OK ) {
115 writel(MSD_CLR_DATA_CRC_OK, &host->reg->clear);
117 if ( status & MSD_DATA_CRC_FAIL ) {
118 writel(MSD_CLR_DATA_CRC_FAIL, &host->reg->clear);
119 data->error = MMC_ERR_TIMEOUT;
121 if ( status & MSD_DATA_END ) {
122 writel(MSD_CLR_DATA_END, &host->reg->clear);
126 static inline int moxasd_check_fifo_ready(struct moxasd_host *host)
130 status = readl(&host->reg->status);
131 if ( status & MSD_CARD_DETECT ) { // card is removed
134 if ( status & (MSD_FIFO_URUN|MSD_FIFO_ORUN) ) {
135 writel(status&(MSD_FIFO_URUN|MSD_FIFO_ORUN), &host->reg->clear);
137 if ( status & MSD_DATA_TIMEOUT ) {
138 writel(MSD_CLR_DATA_TIMEOUT, &host->reg->clear);
144 static void moxasd_do_fifo(struct moxasd_host *host, struct mmc_data *data)
149 if ( host->size == data->bytes_xfered ) {
152 //buffer = moxasd_kmap_sg(host) + host->offset;
153 buffer = moxasd_kmap_sg(host);
154 if ( host->size > MSD_FIFO_LENB && host->dma ) {
155 apb_dma_conf_param param;
156 param.size = host->remain;
157 param.burst_mode = APB_DMAB_BURST_MODE;
158 param.data_width = APB_DMAB_DATA_WIDTH_4;
159 if ( data->flags & MMC_DATA_WRITE ) {
160 param.source_addr = (unsigned int)buffer;
161 param.dest_addr = (unsigned int)&host->reg->data_window;
162 param.dest_inc = APB_DMAB_DEST_INC_0;
163 param.source_inc = APB_DMAB_DEST_INC_4_16;
164 param.dest_sel = APB_DMAB_DEST_APB;
165 param.source_sel = APB_DMAB_SOURCE_AHB;
167 param.dest_addr = (unsigned int)buffer;
168 param.source_addr = (unsigned int)&host->reg->data_window;
169 param.source_inc = APB_DMAB_DEST_INC_0;
170 param.dest_inc = APB_DMAB_DEST_INC_4_16;
171 param.source_sel = APB_DMAB_DEST_APB;
172 param.dest_sel = APB_DMAB_SOURCE_AHB;
174 data->bytes_xfered += host->remain;
175 #if 0 // don't need to do this
176 host->offset = host->remain;
179 apb_dma_conf(host->dma, ¶m);
180 kunmap_atomic(host->mapped_sg, KM_BIO_SRC_IRQ);
181 moxasd_next_sg(host);
182 apb_dma_enable(host->dma);
185 if ( host->remain >= MSD_FIFO_LENB )
186 wcnt = MSD_FIFO_LENW;
189 wcnt = host->remain >> 2;
190 if ( data->flags & MMC_DATA_WRITE ) {
191 for ( i=0; i<wcnt; i++, buffer+=4 )
192 writel(*(unsigned int *)buffer, &host->reg->data_window);
194 for ( i=0; i<wcnt; i++, buffer+=4 )
195 *(unsigned int *)buffer = readl(&host->reg->data_window);
198 host->offset += wcnt;
199 host->remain -= wcnt;
200 data->bytes_xfered += wcnt;
201 kunmap_atomic(host->mapped_sg, KM_BIO_SRC_IRQ);
202 /* because this will be just one time
203 if ( host->remain <= 0 )
204 moxasd_next_sg(host);
209 static void moxasd_request_done(struct moxasd_host *host)
211 struct mmc_request *mrq=host->mrq;
218 mmc_request_done(host->mmc, mrq);
221 static void moxasd_prepare_data(struct moxasd_host *host, struct mmc_data *data)
223 unsigned int timeout, datactrl;
226 moxasd_init_sg(host, data);
228 // initialize the timeout value
229 timeout = (host->mmc->f_max/1000000) * (data->timeout_ns/1000);
230 timeout += data->timeout_clks;
231 writel(timeout, &host->reg->data_timer);
233 // initialize the data size
234 host->size = data->blocks << data->blksz_bits;
235 writel(host->size, &host->reg->data_length);
237 // initialize the data control
238 datactrl = (data->blksz_bits & MSD_BLK_SIZE_MASK) | MSD_DATA_EN;
239 if ( data->flags & MMC_DATA_WRITE ) {
240 datactrl |= MSD_DATA_WRITE;
242 if ( host->size > MSD_FIFO_LENB && host->dma ) {
243 datactrl |= MSD_DMA_EN;
245 writel(datactrl, &host->reg->data_control);
248 //if ( host->size > MSD_FIFO_LENB && (data->flags & MMC_DATA_READ) ) {
249 if ( host->size > MSD_FIFO_LENB ) {
250 // disable the overrun & underrun interrupt
254 writel(MSD_INT_CARD_CHANGE, &host->reg->interrupt_mask);
255 restore_flags(flags);
256 moxasd_do_fifo(host, data);
258 // enable the overrun & underrun interrupt
262 writel(MSD_INT_FIFO_URUN|MSD_INT_FIFO_ORUN|MSD_INT_CARD_CHANGE, &host->reg->interrupt_mask);
263 restore_flags(flags);
268 static void moxasd_send_command(struct moxasd_host *host, struct mmc_command *cmd)
270 unsigned int status, cmdctrl;
273 // first clear status
274 writel(MSD_CLR_RSP_TIMEOUT|MSD_CLR_RSP_CRC_OK|MSD_CLR_RSP_CRC_FAIL|MSD_CLR_CMD_SENT, &host->reg->clear);
277 writel(cmd->arg, &host->reg->argument);
280 cmdctrl = cmd->opcode & MSD_CMD_IDX_MASK;
281 if ( cmdctrl == SD_APP_SET_BUS_WIDTH ||
282 cmdctrl == SD_APP_OP_COND ||
283 cmdctrl == SD_APP_SEND_SCR ) // this is SD application specific command
284 cmdctrl |= MSD_APP_CMD;
285 if ( cmd->flags & MMC_RSP_LONG )
286 cmdctrl |= (MSD_LONG_RSP|MSD_NEED_RSP);
287 if ( cmd->flags & MMC_RSP_SHORT )
288 cmdctrl |= MSD_NEED_RSP;
289 writel(cmdctrl|MSD_CMD_EN, &host->reg->command);
293 while ( retry++ < MSD_RETRY_COUNT ) {
294 status = readl(&host->reg->status);
295 if ( status & MSD_CARD_DETECT ) { // card is removed
296 cmd->error = MMC_ERR_TIMEOUT;
299 if ( cmdctrl & MSD_NEED_RSP ) {
300 if ( status & MSD_RSP_TIMEOUT ) {
301 writel(MSD_CLR_RSP_TIMEOUT, &host->reg->clear);
302 cmd->error = MMC_ERR_TIMEOUT;
306 if ( status & MSD_RSP_CRC_FAIL ) {
308 if ( (cmd->flags&MMC_RSP_CRC) && (status&MSD_RSP_CRC_FAIL) ) {
310 writel(MSD_CLR_RSP_CRC_FAIL, &host->reg->clear);
311 cmd->error = MMC_ERR_BADCRC;
314 if ( status & MSD_RSP_CRC_OK ) {
315 writel(MSD_CLR_RSP_CRC_OK, &host->reg->clear);
317 cmd->resp[0] = readl(&host->reg->response0);
318 cmd->resp[1] = readl(&host->reg->response1);
319 cmd->resp[2] = readl(&host->reg->response2);
320 cmd->resp[3] = readl(&host->reg->response3);
321 cmd->error = MMC_ERR_NONE;
325 if ( status & MSD_CMD_SENT ) {
326 writel(MSD_CLR_CMD_SENT, &host->reg->clear);
327 cmd->error = MMC_ERR_NONE;
333 // cmd->error = MMC_ERR_TIMEOUT;
334 cmd->error = MMC_ERR_NONE;
338 static irqreturn_t moxasd_irq(int irq, void *devid, struct pt_regs *regs)
340 struct moxasd_host *host=devid;
343 // get the interrupt status
345 status = readl(&host->reg->status);
347 // acknowledge the interurpt
348 if ( status & MSD_CARD_CHANGE ) { // has card inserted or removed
349 //writel(MSD_CLR_CARD_CHANGE, &host->reg->clear);
350 tasklet_schedule(&host->card_change_tasklet);
353 if ( status & (MSD_FIFO_ORUN|MSD_FIFO_URUN) ) {
354 writel(status&(MSD_FIFO_ORUN|MSD_FIFO_URUN), &host->reg->clear);
355 tasklet_schedule(&host->fifo_run_tasklet);
361 static void moxasd_fifo_run(unsigned long param)
363 struct moxasd_host *host=(struct moxasd_host *)param;
364 struct mmc_data *data;
367 if ( !moxasd_check_fifo_ready(host) && host->data ) {
368 host->size = host->data->bytes_xfered;
369 host->data->error = MMC_ERR_TIMEOUT;
370 if ( host->dma && host->size > MSD_FIFO_LENB ) {
371 apb_dma_disable(host->dma);
374 writel(readl(&host->reg->status)&(MSD_FIFO_URUN|MSD_FIFO_ORUN), &host->reg->clear);
377 spin_lock(&host->lock);
378 if ( host->mrq == NULL ) {
379 spin_unlock(&host->lock);
382 #if 0 // never happened
383 if ( host->data == NULL ) {
384 goto moxasd_fifo_run_done;
388 moxasd_do_fifo(host, data);
389 if ( host->size == data->bytes_xfered ) {
391 // maybe need to check the data is OK or fail
392 if ( data->error == MMC_ERR_NONE ) {
393 moxasd_check_data_crc(host, data);
397 moxasd_send_command(host, data->stop);
400 spin_unlock(&host->lock);
401 //tasklet_schedule(&host->fifo_run_tasklet);
405 //moxasd_fifo_run_done:
406 moxasd_request_done(host);
407 spin_unlock(&host->lock);
410 static void moxasd_card_change(unsigned long param)
412 struct moxasd_host *host=(struct moxasd_host *)param;
416 spin_lock(&host->lock);
417 udelay(3000); // to wait the hardware stably for card inserted or removed
418 status = readl(&host->reg->status);
419 if ( status & MSD_CARD_DETECT ) { // card removed
420 printk("Moxa CPU SD/MMC card is removed.\n");
423 if ( host->dma && host->size > MSD_FIFO_LENB )
424 apb_dma_disable(host->dma);
425 host->size = host->data->bytes_xfered;
426 spin_unlock(&host->lock);
427 moxasd_fifo_run(*(unsigned long *)host);
428 spin_lock(&host->lock);
430 } else { // card inserted
431 printk("Moxa CPU SD/MMC card is inserted.\n");
432 if ( readl(&host->reg->clock_control) & MSD_CLK_SD ) { // SD
433 host->mmc->f_max = 25000000;
435 host->mmc->mode = MMC_MODE_SD;
437 host->mmc->f_max = 20000000;
438 host->mmc->mode = MMC_MODE_MMC;
442 writel(MSD_CLR_CARD_CHANGE, &host->reg->clear);
443 spin_unlock(&host->lock);
444 mmc_detect_change(host->mmc, msecs_to_jiffies(delay));
447 static void moxasd_dma_irq(void *param)
449 struct moxasd_host *host=(struct moxasd_host *)param;
452 struct mmc_data *data=host->data;
453 if ( host->dma->error_flag ) {
454 host->size = data->bytes_xfered;
455 data->error = MMC_ERR_TIMEOUT;
458 tasklet_schedule(&host->fifo_run_tasklet);
463 static void moxasd_request(struct mmc_host *mmc, struct mmc_request *mrq)
465 struct moxasd_host *host=mmc_priv(mmc);
466 struct mmc_command *cmd;
468 spin_lock(&host->lock);
472 // if no card inserted, return timeout error
473 if ( readl(&host->reg->status) & MSD_CARD_DETECT ) { // card is removed
474 cmd->error = MMC_ERR_TIMEOUT;
478 // request include data or not
480 moxasd_prepare_data(host, cmd->data);
484 // do request command
485 moxasd_send_command(host, cmd);
487 if ( cmd->data && cmd->error == MMC_ERR_NONE ) {
488 spin_unlock(&host->lock);
494 moxasd_request_done(host);
495 spin_unlock(&host->lock);
498 #define MIN_POWER (MMC_VDD_360 - MSD_SD_POWER_MASK)
499 static void moxasd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
501 struct moxasd_host *host=mmc_priv(mmc);
503 spin_lock(&host->lock);
506 #ifdef MSD_SUPPORT_GET_CLOCK
507 div = (host->sysclk / (host->mmc->f_max * 2)) - 1;
509 div = (APB_CLK / (host->mmc->f_max * 2)) - 1;
511 if ( div > MSD_CLK_DIV_MASK )
512 div = MSD_CLK_DIV_MASK;
515 if ( host->mmc->mode == MMC_MODE_SD )
517 writel(div, &host->reg->clock_control);
518 } else if ( !(readl(&host->reg->clock_control) & MSD_CLK_DIS) ) {
520 * Ensure that the clock is off.
522 writel(readl(&host->reg->clock_control)|MSD_CLK_DIS, &host->reg->clock_control);
525 if ( ios->power_mode == MMC_POWER_OFF ) {
526 writel(readl(&host->reg->power_control)&~MSD_SD_POWER_ON, &host->reg->power_control);
528 unsigned short power;
529 if ( ios->vdd < MIN_POWER )
532 power = ios->vdd - MIN_POWER;
533 writel(MSD_SD_POWER_ON|(unsigned int)power, &host->reg->power_control);
537 if ( ios->bus_width == MMC_BUS_WIDTH_1 ) {
538 writel(MSD_SINGLE_BUS, &host->reg->bus_width);
540 writel(MSD_WIDE_BUS, &host->reg->bus_width);
543 spin_unlock(&host->lock);
547 * To check write protect or not. Return 0 for none, 1 for write protect.
549 static int moxasd_get_ro(struct mmc_host *mmc)
551 struct moxasd_host *host=mmc_priv(mmc);
553 if ( readl(&host->reg->status) & MSD_WRITE_PROT )
559 static struct mmc_host_ops moxasd_ops = {
560 .request = moxasd_request,
561 .set_ios = moxasd_set_ios,
562 .get_ro = moxasd_get_ro,
565 static int moxasd_probe(struct device *dev)
567 struct mmc_host *mmc;
568 struct moxasd_host *host=NULL;
571 mmc = mmc_alloc_host(sizeof(struct moxasd_host), dev);
577 mmc->ops = &moxasd_ops;
579 mmc->f_max = 25000000;
581 mmc->mode = MMC_MODE_SD;
583 mmc->ocr_avail = 0xffff00; // support 2.0v - 3.6v power
585 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
586 mmc->caps = MMC_CAP_4_BIT_DATA;
587 mmc->max_hw_segs = 128;
588 mmc->max_phys_segs = 128;
589 mmc->max_sectors = 128;
590 mmc->max_seg_size = mmc->max_sectors * 512;
593 host = mmc_priv(mmc);
595 spin_lock_init(&host->lock);
596 tasklet_init(&host->card_change_tasklet, moxasd_card_change, (unsigned long)host);
597 tasklet_init(&host->fifo_run_tasklet, moxasd_fifo_run, (unsigned long)host);
598 host->reg = (moxasd_reg *)CPE_SD_VA_BASE;
599 host->dma = apb_dma_alloc(APB_DMA_SD_REQ_NO);
601 apb_dma_set_irq(host->dma, moxasd_dma_irq, host);
604 #ifdef MSD_SUPPORT_GET_CLOCK
607 unsigned int mul, val, div;
608 mul = (*(volatile unsigned int *)(CPE_PMU_VA_BASE+0x30) >> 3) & 0x1ff;
609 val = (*(volatile unsigned int *)(CPE_PMU_VA_BASE+0x0c) >> 4) & 0x7;
611 case 0 : div = 2; break;
612 case 1 : div = 3; break;
613 case 2 : div = 4; break;
614 case 3 : div = 6; break;
615 case 4 : div = 8; break;
616 default : div = 2; break;
618 host->sysclk = (38684*mul + 10000) / (div * 10000);
619 host->sysclk = (host->sysclk * 1000000) / 2;
623 // change I/O multiplexing to SD, so the GPIO 17-10 will be fail
624 #if 0 // mask by Victor Yu. 03-06-2006
625 *(volatile unsigned int *)(CPE_PMU_VA_BASE+0x100) &= (~(0xff<<10));
626 #else // add by Victor Yu. 03-06-2006
627 mcpu_gpio_mp_clear(0xff<<10);
631 * Ensure that the host controller is shut down, and setup
634 writel(0, &host->reg->interrupt_mask); // disable all interrupt
635 writel(MSD_SDC_RST, &host->reg->command); // reset chip
636 while ( readl(&host->reg->command) & MSD_SDC_RST); // wait for reset finished
637 writel(0, &host->reg->interrupt_mask); // disable all interrupt
639 // to check any card inserted or not
641 if ( !(readl(&host->reg->status) & MSD_CARD_DETECT) ) { // is inserted
642 if ( readl(&host->reg->clock_control) & MSD_CLK_SD ) { // is SD card
643 mmc->f_max = 25000000;
644 mmc->mode = MMC_MODE_SD;
645 } else { // is MMC card
646 mmc->f_max = 20000000;
647 mmc->mode = MMC_MODE_MMC;
652 mmc->caps = MMC_CAP_4_BIT_DATA;
653 writel(MSD_WIDE_BUS, &host->reg->bus_width);
655 cpe_int_set_irq(IRQ_SD, EDGE, H_ACTIVE);
656 ret = request_irq(IRQ_SD, moxasd_irq, SA_INTERRUPT, "MOXASD", host);
660 //writel(MSD_INT_CARD_CHANGE|MSD_INT_FIFO_ORUN|MSD_INT_FIFO_URUN, &host->reg->interrupt_mask);
661 writel(MSD_INT_CARD_CHANGE, &host->reg->interrupt_mask);
662 dev_set_drvdata(dev, mmc);
674 static int moxasd_remove(struct device *dev)
676 struct mmc_host *mmc=dev_get_drvdata(dev);
678 dev_set_drvdata(dev, NULL);
681 struct moxasd_host *host=mmc_priv(mmc);
683 mmc_remove_host(mmc);
687 apb_dma_disable(host->dma);
688 apb_dma_release_irq(host->dma);
689 apb_dma_release(host->dma);
691 writel(0, &host->reg->interrupt_mask);
692 writel(0, &host->reg->power_control);
693 writel(readl(&host->reg->clock_control)|MSD_CLK_DIS, &host->reg->clock_control);
695 free_irq(IRQ_SD, host);
696 tasklet_kill(&host->card_change_tasklet);
697 tasklet_kill(&host->fifo_run_tasklet);
704 static struct platform_device moxasd_device = {
709 static struct device_driver moxasd_driver = {
711 .bus = &platform_bus_type,
712 .probe = moxasd_probe,
713 .remove = moxasd_remove,
716 static int __init moxasd_init(void)
720 printk("Moxa CPU SD/MMC Device Driver V1.0 initialize ");
721 platform_device_register(&moxasd_device);
722 ret = driver_register(&moxasd_driver);
725 platform_device_unregister(&moxasd_device);
732 static void __exit moxasd_exit(void)
734 platform_device_unregister(&moxasd_device);
735 driver_unregister(&moxasd_driver);
738 module_init(moxasd_init);
739 module_exit(moxasd_exit);
741 MODULE_DESCRIPTION("Moxa CPU SD/Multimedia Card Interface Driver");
742 MODULE_LICENSE("GPL");