1 /* MOXART MMC/SD device driver (based on MOXA sources)
2 * Copyright (C) 2013 Jonas Jensen <jonas.jensen@gmail.com>
3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by the
5 * Free Software Foundation; either version 2 of the License,
6 * or (at your option) any later version. */
8 #include <linux/version.h>
9 #include <linux/module.h>
10 #include <linux/init.h>
11 #include <linux/ioport.h>
12 #include <linux/platform_device.h>
13 #include <linux/delay.h>
14 #include <linux/interrupt.h>
15 #include <linux/blkdev.h>
16 #include <linux/dma-mapping.h>
17 #include <linux/mmc/host.h>
18 #include <linux/sched.h>
19 #include <linux/mmc/sd.h>
24 #include <asm/sizes.h>
26 #include <mach/apb_dma.h>
27 #include <mach/irqs.h>
28 #include <mach/hardware.h>
29 #include <mach/gpio.h>
33 static inline void moxart_init_sg(struct moxart_host
*host
,
34 struct mmc_data
*data
)
36 /* Get info. about SG list from data structure. */
37 host
->cur_sg
= data
->sg
;
38 host
->num_sg
= data
->sg_len
;
39 host
->remain
= host
->cur_sg
->length
;
41 if (host
->remain
> host
->size
)
42 host
->remain
= host
->size
;
43 host
->mapped_sg
= NULL
;
45 data
->error
= MMC_ERR_NONE
;
48 static inline int moxart_next_sg(struct moxart_host
*host
)
51 struct mmc_data
*data
= host
->data
;
56 if (host
->num_sg
> 0) {
57 host
->remain
= host
->cur_sg
->length
;
58 remain
= host
->size
- data
->bytes_xfered
;
59 if (remain
> 0 && remain
< host
->remain
)
60 host
->remain
= remain
;
66 static void moxart_do_fifo(struct moxart_host
*host
, struct mmc_data
*data
)
71 if (host
->size
== data
->bytes_xfered
)
74 /* local_irq_save(kmap_flags); */
75 /* dbg_printk(KERN_INFO "moxart_do_fifo: kmap_atomic\n"); */
76 host
->mapped_sg
= kmap_atomic(sg_page(host
->cur_sg
), KM_BIO_SRC_IRQ
);
77 buffer
= host
->mapped_sg
+ host
->cur_sg
->offset
;
79 if (host
->size
> MSD_FIFO_LENB
&& host
->dma
) {
80 struct apb_dma_conf_param param
;
81 param
.size
= host
->remain
;
82 param
.burst_mode
= APB_DMAB_BURST_MODE
;
83 param
.data_width
= APB_DMAB_DATA_WIDTH_4
;
84 if (data
->flags
& MMC_DATA_WRITE
) {
85 param
.source_addr
= (unsigned int) buffer
;
86 param
.dest_addr
= (unsigned int)
87 &host
->reg
->data_window
;
88 param
.dest_inc
= APB_DMAB_DEST_INC_0
;
89 param
.source_inc
= APB_DMAB_DEST_INC_4_16
;
90 param
.dest_sel
= APB_DMAB_DEST_APB
;
91 param
.source_sel
= APB_DMAB_SOURCE_AHB
;
93 param
.dest_addr
= (unsigned int) buffer
;
94 param
.source_addr
= (unsigned int)
95 &host
->reg
->data_window
;
96 param
.source_inc
= APB_DMAB_DEST_INC_0
;
97 param
.dest_inc
= APB_DMAB_DEST_INC_4_16
;
98 param
.source_sel
= APB_DMAB_DEST_APB
;
99 param
.dest_sel
= APB_DMAB_SOURCE_AHB
;
101 data
->bytes_xfered
+= host
->remain
;
102 apb_dma_conf(host
->dma
, ¶m
);
103 apb_dma_enable(host
->dma
);
105 wcnt
= host
->remain
>> 2;
106 if (data
->flags
& MMC_DATA_WRITE
) {
107 /* dbg_printk(KERN_INFO "moxart_do_fifo:"
108 * " MMC_DATA_WRITE)\n"); */
109 for (i
= 0; i
< wcnt
; i
++, buffer
+= 4) {
110 writel(*(unsigned int *)buffer
,
111 &host
->reg
->data_window
);
114 /* dbg_printk(KERN_INFO "moxart_do_fifo:"
115 * " MMC_DATA_READ)\n"); */
116 for (i
= 0; i
< wcnt
; i
++, buffer
+= 4) {
117 *(unsigned int *)buffer
= readl(
118 &host
->reg
->data_window
);
122 host
->remain
-= wcnt
;
123 data
->bytes_xfered
+= wcnt
;
126 /* dbg_printk(KERN_INFO "moxart_do_fifo: kunmap_atomic\n"); */
127 kunmap_atomic(host
->mapped_sg
, KM_BIO_SRC_IRQ
);
128 moxart_next_sg(host
);
129 /* local_irq_restore(kmap_flags); */
132 static void moxart_request_done(struct moxart_host
*host
)
134 struct mmc_request
*mrq
= host
->mrq
;
141 mmc_request_done(host
->mmc
, mrq
);
144 static void moxart_prepare_data(struct moxart_host
*host
, struct mmc_data
*data
)
146 unsigned int timeout
, datactrl
;
150 host
->size
= data
->blocks
* data
->blksz
;
151 blksz_bits
= ffs(data
->blksz
) - 1;
152 BUG_ON(1 << blksz_bits
!= data
->blksz
);
154 moxart_init_sg(host
, data
);
156 timeout
= (host
->mmc
->f_max
/ 1000) * (data
->timeout_ns
/ 1000);
159 datactrl
= (blksz_bits
& MSD_BLK_SIZE_MASK
) | MSD_DATA_EN
;
160 if (data
->flags
& MMC_DATA_WRITE
)
161 datactrl
|= MSD_DATA_WRITE
;
162 if (host
->size
> MSD_FIFO_LENB
&& host
->dma
)
163 datactrl
|= MSD_DMA_EN
;
164 writel(timeout
, &host
->reg
->data_timer
);
165 writel(host
->size
, &host
->reg
->data_length
);
166 writel(datactrl
, &host
->reg
->data_control
);
168 if (host
->size
> MSD_FIFO_LENB
&& host
->dma
) {
169 writel(MSD_INT_CARD_CHANGE
, &host
->reg
->interrupt_mask
);
170 /* dbg_printk(KERN_INFO "moxart_prepare_data:"
171 * " calling moxart_do_fifo\n"); */
172 moxart_do_fifo(host
, data
);
173 /* tasklet_schedule(&host->fifo_run_tasklet); */
175 /* dbg_printk(KERN_INFO "moxart_prepare_data: calling writel("
176 * "MSD_INT_FIFO_URUN | MSD_INT_FIFO_ORUN |
178 &host->reg->interrupt_mask); \n"); */
179 writel(MSD_INT_FIFO_URUN
| MSD_INT_FIFO_ORUN
|
181 &host
->reg
->interrupt_mask
);
185 static void moxart_send_command(struct moxart_host
*host
,
186 struct mmc_command
*cmd
)
188 unsigned int status
, cmdctrl
;
191 /* dbg_printk(KERN_INFO "moxart_send_command\n"); */
192 cmd
->error
= MMC_ERR_TIMEOUT
;
193 writel(MSD_CLR_RSP_TIMEOUT
| MSD_CLR_RSP_CRC_OK
|
194 MSD_CLR_RSP_CRC_FAIL
| MSD_CLR_CMD_SENT
, &host
->reg
->clear
);
195 writel(cmd
->arg
, &host
->reg
->argument
);
197 /* same info provided by CONFIG_MMC_DEBUG (when it actually works) */
198 /* dbg_printk(KERN_INFO "moxart_send_command: cmd->opcode=%d",
201 cmdctrl
= cmd
->opcode
& MSD_CMD_IDX_MASK
;
202 if (cmdctrl
== SD_APP_SET_BUS_WIDTH
|| cmdctrl
== SD_APP_OP_COND
||
203 cmdctrl
== SD_APP_SEND_SCR
) {
204 /* this is SD application specific command */
205 cmdctrl
|= MSD_APP_CMD
;
208 if (cmd
->flags
& MMC_RSP_136
)
209 cmdctrl
|= (MSD_LONG_RSP
| MSD_NEED_RSP
);
211 cmdctrl
|= MSD_NEED_RSP
;
213 /* dbg_printk(KERN_INFO " cmdctrl=%d\n", cmdctrl); */
214 writel(cmdctrl
| MSD_CMD_EN
, &host
->reg
->command
);
216 while (retry
++ < MSD_RETRY_COUNT
) { /* wait response */
217 status
= readl(&host
->reg
->status
);
218 if (status
& MSD_CARD_DETECT
) { /* card is removed */
219 cmd
->error
= MMC_ERR_TIMEOUT
;
222 if (cmdctrl
& MSD_NEED_RSP
) {
223 if (status
& MSD_RSP_TIMEOUT
) {
224 writel(MSD_CLR_RSP_TIMEOUT
, &host
->reg
->clear
);
225 cmd
->error
= MMC_ERR_TIMEOUT
;
228 /* if ( status & MSD_RSP_CRC_FAIL ) { */
229 if ((cmd
->flags
& MMC_RSP_CRC
) &&
230 (status
& MSD_RSP_CRC_FAIL
)) {
231 writel(MSD_CLR_RSP_CRC_FAIL
, &host
->reg
->clear
);
232 cmd
->error
= MMC_ERR_BADCRC
;
235 if (status
& MSD_RSP_CRC_OK
) {
236 writel(MSD_CLR_RSP_CRC_OK
, &host
->reg
->clear
);
237 cmd
->resp
[0] = readl(&host
->reg
->response0
);
238 cmd
->resp
[1] = readl(&host
->reg
->response1
);
239 cmd
->resp
[2] = readl(&host
->reg
->response2
);
240 cmd
->resp
[3] = readl(&host
->reg
->response3
);
242 * following dbg_printk "fixes" commit <
243 * 16326b589a33c5a70bc53381c9096aa8fc1eaafc
244 * (because of commented spin_lock_irqsave:s)
245 * when kmap_atomic is followed up with
247 * spin_lock_irqsave:s can be re-enabled without
248 * warnings and locking issues.
249 * dbg_printk(KERN_INFO "moxart_send_command"
251 * " %x:%x:%x:%x\n", cmd->resp[0],
252 * cmd->resp[1], cmd->resp[2],
255 cmd
->error
= MMC_ERR_NONE
;
259 if (status
& MSD_CMD_SENT
) {
260 writel(MSD_CLR_CMD_SENT
, &host
->reg
->clear
);
261 cmd
->error
= MMC_ERR_NONE
;
268 static irqreturn_t
moxart_irq(int irq
, void *devid
)
270 struct moxart_host
*host
= devid
;
273 status
= readl(&host
->reg
->status
); /* get the interrupt status */
274 if (status
& MSD_CARD_CHANGE
) { /* has card inserted or removed */
275 /* writel(MSD_CLR_CARD_CHANGE, &host->reg->clear); */
276 /* dbg_printk(KERN_INFO "moxart_irq: status &"
277 * " MSD_CARD_CHANGE\n"); */
278 tasklet_schedule(&host
->card_change_tasklet
);
280 if (status
& (MSD_FIFO_ORUN
| MSD_FIFO_URUN
)) {
281 /* dbg_printk(KERN_INFO "moxart_irq: status &"
282 * " (MSD_FIFO_ORUN | MSD_FIFO_URUN)\n"); */
283 writel(status
& (MSD_FIFO_ORUN
| MSD_FIFO_URUN
),
285 tasklet_schedule(&host
->fifo_run_tasklet
);
291 static void moxart_fifo_run(unsigned long param
)
293 struct moxart_host
*host
= (struct moxart_host
*) param
;
294 struct mmc_data
*data
;
297 host
= (struct moxart_host
*) param
;
299 if (host
->mrq
== NULL
|| data
== NULL
) {
300 /* spin_unlock_irqrestore(&host->lock, flags); */
304 /* dbg_printk(KERN_INFO "moxart_fifo_run:"
305 * " moxart_do_fifo(host, data)\n"); */
306 moxart_do_fifo(host
, data
);
308 spin_lock_irqsave(&host
->lock
, flags
);
310 if (host
->size
== data
->bytes_xfered
) {
313 status
= readl(&host
->reg
->status
);
314 if (status
& (MSD_DATA_CRC_OK
| MSD_DATA_CRC_FAIL
|
317 schedule_timeout_interruptible(5);
320 if (status
& MSD_DATA_CRC_OK
)
321 writel(MSD_CLR_DATA_CRC_OK
, &host
->reg
->clear
);
323 if (status
& MSD_DATA_CRC_FAIL
) {
324 writel(MSD_CLR_DATA_CRC_FAIL
, &host
->reg
->clear
);
325 data
->error
= MMC_ERR_TIMEOUT
;
328 if (status
& MSD_DATA_END
)
329 writel(MSD_CLR_DATA_END
, &host
->reg
->clear
);
332 moxart_send_command(host
, data
->stop
);
335 spin_unlock_irqrestore(&host
->lock
, flags
);
339 spin_unlock_irqrestore(&host
->lock
, flags
);
340 moxart_request_done(host
);
343 static void moxart_card_change(unsigned long param
)
345 struct moxart_host
*host
= (struct moxart_host
*) param
;
350 spin_lock_irqsave(&host
->lock
, flags
);
351 status
= readl(&host
->reg
->status
);
353 if (status
& MSD_CARD_DETECT
) {
354 dbg_printk(KERN_INFO
"MOXART MMC/SD card removed.\n");
358 if (host
->dma
&& host
->size
> MSD_FIFO_LENB
)
359 apb_dma_disable(host
->dma
);
361 host
->size
= host
->data
->bytes_xfered
;
362 moxart_fifo_run(*(unsigned long *) host
);
363 host
->data
->error
= MMC_ERR_TIMEOUT
;
364 moxart_request_done(host
);
368 host
->mrq
->cmd
->error
= MMC_ERR_TIMEOUT
;
369 moxart_request_done(host
);
373 dbg_printk(KERN_INFO
"MOXART MMC/SD card inserted.\n");
377 writel(MSD_CLR_CARD_CHANGE
, &host
->reg
->clear
);
378 spin_unlock_irqrestore(&host
->lock
, flags
);
379 mmc_detect_change(host
->mmc
, msecs_to_jiffies(delay
));
382 static void moxart_dma_irq(void *param
)
384 struct moxart_host
*host
= (struct moxart_host
*) param
;
386 /* dbg_printk(KERN_INFO "moxart_dma_irq\n"); */
388 tasklet_schedule(&host
->fifo_run_tasklet
);
391 static void moxart_request(struct mmc_host
*mmc
, struct mmc_request
*mrq
)
393 struct moxart_host
*host
= mmc_priv(mmc
);
394 struct mmc_command
*cmd
;
397 /* dbg_printk(KERN_INFO "moxart_request\n"); */
399 spin_lock_irqsave(&host
->lock
, flags
);
404 if (readl(&host
->reg
->status
) & MSD_CARD_DETECT
) {
405 /* card is removed if no card inserted, return timeout error */
406 cmd
->error
= MMC_ERR_TIMEOUT
;
410 if (cmd
->data
) { /* request include data or not */
411 /* dbg_printk(KERN_INFO "moxart_request: cmd->data\n"); */
412 moxart_prepare_data(host
, cmd
->data
);
415 moxart_send_command(host
, cmd
);
417 if (cmd
->data
&& cmd
->error
== MMC_ERR_NONE
) {
418 spin_unlock_irqrestore(&host
->lock
, flags
);
419 /* only added this to avoid lockups/warnings when DMA interrupt
420 * was broken (it really should not be done here) */
421 /* moxart_request_done(host); */
426 spin_unlock_irqrestore(&host
->lock
, flags
);
427 moxart_request_done(host
);
430 #define MIN_POWER (MMC_VDD_360 - MSD_SD_POWER_MASK)
431 static void moxart_set_ios(struct mmc_host
*mmc
, struct mmc_ios
*ios
)
433 struct moxart_host
*host
= mmc_priv(mmc
);
435 unsigned short power
;
437 spin_lock_irqsave(&host
->lock
, flags
);
440 #ifdef MSD_SUPPORT_GET_CLOCK
441 div
= (host
->sysclk
/ (host
->mmc
->f_max
* 2)) - 1;
443 div
= (APB_CLK
/ (host
->mmc
->f_max
* 2)) - 1;
446 if (div
> MSD_CLK_DIV_MASK
)
447 div
= MSD_CLK_DIV_MASK
;
452 writel(div
, &host
->reg
->clock_control
);
453 } else if (!(readl(&host
->reg
->clock_control
) & MSD_CLK_DIS
)) {
454 /* ensure that the clock is off. */
455 writel(readl(&host
->reg
->clock_control
) | MSD_CLK_DIS
,
456 &host
->reg
->clock_control
);
459 if (ios
->power_mode
== MMC_POWER_OFF
) {
460 writel(readl(&host
->reg
->power_control
) & ~MSD_SD_POWER_ON
,
461 &host
->reg
->power_control
);
463 if (ios
->vdd
< MIN_POWER
)
466 power
= ios
->vdd
- MIN_POWER
;
468 writel(MSD_SD_POWER_ON
| (unsigned int) power
,
469 &host
->reg
->power_control
);
472 if (ios
->bus_width
== MMC_BUS_WIDTH_1
)
473 writel(MSD_SINGLE_BUS
, &host
->reg
->bus_width
);
475 writel(MSD_WIDE_BUS
, &host
->reg
->bus_width
);
477 spin_unlock_irqrestore(&host
->lock
, flags
);
480 static int moxart_get_ro(struct mmc_host
*mmc
)
483 struct moxart_host
*host
= mmc_priv(mmc
);
485 (readl(&host
->reg
->status
) & MSD_WRITE_PROT
) ? (ret
= 1) : (ret
= 0);
489 static struct mmc_host_ops moxart_ops
= {
490 .request
= moxart_request
,
491 .set_ios
= moxart_set_ios
,
492 .get_ro
= moxart_get_ro
,
495 static int moxart_probe(struct device
*dev
)
497 struct mmc_host
*mmc
;
498 struct moxart_host
*host
= NULL
;
501 mmc
= mmc_alloc_host(sizeof(struct moxart_host
), dev
);
507 mmc
->ops
= &moxart_ops
;
508 mmc
->caps
= MMC_CAP_4_BIT_DATA
;
510 mmc
->f_max
= 25000000;
511 mmc
->ocr_avail
= 0xffff00; /* support 2.0v - 3.6v power */
513 host
= mmc_priv(mmc
);
515 spin_lock_init(&host
->lock
);
516 tasklet_init(&host
->card_change_tasklet
, moxart_card_change
,
517 (unsigned long) host
);
518 tasklet_init(&host
->fifo_run_tasklet
, moxart_fifo_run
,
519 (unsigned long) host
);
520 host
->reg
= (struct moxart_reg
*)IO_ADDRESS(MOXART_MMC_BASE
);
521 host
->dma
= apb_dma_alloc(APB_DMA_SD_REQ_NO
);
524 apb_dma_set_irq(host
->dma
, moxart_dma_irq
, host
);
527 #ifdef MSD_SUPPORT_GET_CLOCK
528 unsigned int mul
, val
, div
; /* get system clock */
529 mul
= (readl(IO_ADDRESS(MOXART_PMU_BASE
+0x30)) >> 3) & 0x1ff;
530 val
= (readl(IO_ADDRESS(MOXART_PMU_BASE
+0x0c)) >> 4) & 0x7;
551 host
->sysclk
= (38684*mul
+ 10000) / (div
* 10000);
552 host
->sysclk
= (host
->sysclk
* 1000000) / 2;
556 /* change I/O multiplexing to SD, so the GPIO 17-10 will be fail */
557 moxart_gpio_mp_clear(0xff << 10);
559 /* Ensure that the host controller is shut down, and setup with
560 our defaults. disable all interrupt */
561 writel(0, &host
->reg
->interrupt_mask
);
564 writel(MSD_SDC_RST
, &host
->reg
->command
);
566 /* wait for reset finished */
567 while (readl(&host
->reg
->command
) & MSD_SDC_RST
)
570 /* disable all interrupt */
571 writel(0, &host
->reg
->interrupt_mask
);
573 writel(MSD_WIDE_BUS
, &host
->reg
->bus_width
);
575 moxart_int_set_irq(IRQ_MMC
, EDGE
, H_ACTIVE
);
576 ret
= request_irq(IRQ_MMC
, moxart_irq
,
577 IRQF_DISABLED
, "MOXART MMC", host
);
582 /* writel(MSD_INT_CARD_CHANGE|MSD_INT_FIFO_ORUN|MSD_INT_FIFO_URUN,
583 &host->reg->interrupt_mask); */
584 writel(MSD_INT_CARD_CHANGE
, &host
->reg
->interrupt_mask
);
585 dev_set_drvdata(dev
, mmc
);
588 dev_info(dev
, "MOXART MMC: finished moxart_probe\n");
597 static int moxart_remove(struct device
*dev
)
599 struct mmc_host
*mmc
= dev_get_drvdata(dev
);
600 struct moxart_host
*host
= mmc_priv(mmc
);
602 dev_set_drvdata(dev
, NULL
);
605 mmc_remove_host(mmc
);
608 apb_dma_disable(host
->dma
);
609 apb_dma_release_irq(host
->dma
);
610 apb_dma_release(host
->dma
);
612 writel(0, &host
->reg
->interrupt_mask
);
613 writel(0, &host
->reg
->power_control
);
614 writel(readl(&host
->reg
->clock_control
) | MSD_CLK_DIS
,
615 &host
->reg
->clock_control
);
617 free_irq(IRQ_MMC
, host
);
618 tasklet_kill(&host
->card_change_tasklet
);
619 tasklet_kill(&host
->fifo_run_tasklet
);
626 static struct platform_device moxart_device
= {
627 .name
= "MOXART MMC",
631 static struct device_driver moxart_driver
= {
632 .name
= "MOXART MMC",
633 .bus
= &platform_bus_type
,
634 .probe
= moxart_probe
,
635 .remove
= moxart_remove
,
638 static int __init
moxart_init(void)
640 platform_device_register(&moxart_device
);
641 return driver_register(&moxart_driver
);
644 static void __exit
moxart_exit(void)
646 platform_device_unregister(&moxart_device
);
647 driver_unregister(&moxart_driver
);
650 module_init(moxart_init
);
651 module_exit(moxart_exit
);
653 MODULE_DESCRIPTION("MOXART MMC interface driver");
654 MODULE_LICENSE("GPL");