code style scripts/checkpatch.pl (linux-3.9-rc1) formatting
[linux-2.6.32.60-moxart.git] / drivers / mmc / host / moxart.c
blob98bf7b97884a073d3fd50c8795ee6cc244ad9450
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>
20 #include <linux/io.h>
22 #include <asm/dma.h>
23 #include <asm/irq.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>
31 #include "moxart.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)
50 int remain;
51 struct mmc_data *data = host->data;
53 host->cur_sg++;
54 host->num_sg--;
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;
63 return host->num_sg;
66 static void moxart_do_fifo(struct moxart_host *host, struct mmc_data *data)
68 char *buffer;
69 int wcnt, i;
71 if (host->size == data->bytes_xfered)
72 return;
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;
92 } else {
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, &param);
103 apb_dma_enable(host->dma);
104 } else {
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);
113 } else {
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);
121 wcnt <<= 2;
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;
136 if (mrq == NULL)
137 return;
139 host->mrq = NULL;
140 host->data = NULL;
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;
147 int blksz_bits;
149 host->data = data;
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);
157 timeout *= 2;
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); */
174 } else {
175 /* dbg_printk(KERN_INFO "moxart_prepare_data: calling writel("
176 * "MSD_INT_FIFO_URUN | MSD_INT_FIFO_ORUN |
177 MSD_INT_CARD_CHANGE,
178 &host->reg->interrupt_mask); \n"); */
179 writel(MSD_INT_FIFO_URUN | MSD_INT_FIFO_ORUN |
180 MSD_INT_CARD_CHANGE,
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;
189 int retry = 0;
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",
199 cmd->opcode); */
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);
210 else
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;
220 break;
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;
226 break;
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;
233 break;
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
246 * kunmap_atomic:
247 * spin_lock_irqsave:s can be re-enabled without
248 * warnings and locking issues.
249 * dbg_printk(KERN_INFO "moxart_send_command"
250 * " response:"
251 * " %x:%x:%x:%x\n", cmd->resp[0],
252 * cmd->resp[1], cmd->resp[2],
253 * cmd->resp[3]);
255 cmd->error = MMC_ERR_NONE;
256 break;
258 } else {
259 if (status & MSD_CMD_SENT) {
260 writel(MSD_CLR_CMD_SENT, &host->reg->clear);
261 cmd->error = MMC_ERR_NONE;
262 break;
268 static irqreturn_t moxart_irq(int irq, void *devid)
270 struct moxart_host *host = devid;
271 unsigned int status;
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),
284 &host->reg->clear);
285 tasklet_schedule(&host->fifo_run_tasklet);
288 return IRQ_HANDLED;
291 static void moxart_fifo_run(unsigned long param)
293 struct moxart_host *host = (struct moxart_host *) param;
294 struct mmc_data *data;
295 unsigned long flags;
297 host = (struct moxart_host *) param;
298 data = host->data;
299 if (host->mrq == NULL || data == NULL) {
300 /* spin_unlock_irqrestore(&host->lock, flags); */
301 return;
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) {
311 unsigned int status;
312 while (1) {
313 status = readl(&host->reg->status);
314 if (status & (MSD_DATA_CRC_OK | MSD_DATA_CRC_FAIL |
315 MSD_DATA_END))
316 break;
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);
331 if (data->stop)
332 moxart_send_command(host, data->stop);
334 } else {
335 spin_unlock_irqrestore(&host->lock, flags);
336 return;
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;
346 unsigned int status;
347 int delay;
348 unsigned long flags;
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");
355 delay = 0;
356 if (host->data) {
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);
367 if (host->mrq) {
368 host->mrq->cmd->error = MMC_ERR_TIMEOUT;
369 moxart_request_done(host);
372 } else {
373 dbg_printk(KERN_INFO "MOXART MMC/SD card inserted.\n");
374 delay = 500;
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"); */
387 if (host)
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;
395 unsigned long flags;
397 /* dbg_printk(KERN_INFO "moxart_request\n"); */
399 spin_lock_irqsave(&host->lock, flags);
401 host->mrq = mrq;
402 cmd = mrq->cmd;
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;
407 goto request_done;
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); */
422 return;
425 request_done:
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);
434 unsigned long flags;
435 unsigned short power;
437 spin_lock_irqsave(&host->lock, flags);
438 if (ios->clock) {
439 int div;
440 #ifdef MSD_SUPPORT_GET_CLOCK
441 div = (host->sysclk / (host->mmc->f_max * 2)) - 1;
442 #else
443 div = (APB_CLK / (host->mmc->f_max * 2)) - 1;
444 #endif
446 if (div > MSD_CLK_DIV_MASK)
447 div = MSD_CLK_DIV_MASK;
448 else if (div < 0)
449 div = 0;
451 div |= MSD_CLK_SD;
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);
462 } else {
463 if (ios->vdd < MIN_POWER)
464 power = 0;
465 else
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);
474 else
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)
482 int ret;
483 struct moxart_host *host = mmc_priv(mmc);
485 (readl(&host->reg->status) & MSD_WRITE_PROT) ? (ret = 1) : (ret = 0);
486 return ret;
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;
499 int ret;
501 mmc = mmc_alloc_host(sizeof(struct moxart_host), dev);
502 if (!mmc) {
503 ret = -ENOMEM;
504 goto out;
507 mmc->ops = &moxart_ops;
508 mmc->caps = MMC_CAP_4_BIT_DATA;
509 mmc->f_min = 400000;
510 mmc->f_max = 25000000;
511 mmc->ocr_avail = 0xffff00; /* support 2.0v - 3.6v power */
513 host = mmc_priv(mmc);
514 host->mmc = 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);
523 if (host->dma)
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;
531 switch (val) {
532 case 0:
533 div = 2;
534 break;
535 case 1:
536 div = 3;
537 break;
538 case 2:
539 div = 4;
540 break;
541 case 3:
542 div = 6;
543 break;
544 case 4:
545 div = 8;
546 break;
547 default:
548 div = 2;
549 break;
551 host->sysclk = (38684*mul + 10000) / (div * 10000);
552 host->sysclk = (host->sysclk * 1000000) / 2;
553 #endif
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);
563 /* reset chip */
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);
579 if (ret)
580 goto out;
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);
586 mmc_add_host(mmc);
588 dev_info(dev, "MOXART MMC: finished moxart_probe\n");
589 return 0;
591 out:
592 if (mmc)
593 mmc_free_host(mmc);
594 return ret;
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);
604 if (mmc) {
605 mmc_remove_host(mmc);
607 if (host->dma) {
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);
621 mmc_free_host(mmc);
623 return 0;
626 static struct platform_device moxart_device = {
627 .name = "MOXART MMC",
628 .id = -1,
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");