aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/mxcmmc.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2009-01-06 11:04:14 -0500
committerPierre Ossman <drzeus@drzeus.cx>2009-02-02 14:57:05 -0500
commitd96be879ff469759af6d7fcebdb66237c18da6f8 (patch)
treeb15b65b27edc43c5aae914f66a111735914a58e7 /drivers/mmc/host/mxcmmc.c
parent27421e211a39784694b597dbf35848b88363c248 (diff)
mmc: Add a MX2/MX3 specific SDHC driver
This patch adds a MX2/MX3 specific SDHC driver. The hardware is basically the same as in the MX1, but unlike the MX1 controller the MX2 controller just works as expected. Since the MX1 driver has more workarounds for bugs than anything else I had no success with supporting MX1 and MX2 in a sane way in one driver. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc/host/mxcmmc.c')
-rw-r--r--drivers/mmc/host/mxcmmc.c880
1 files changed, 880 insertions, 0 deletions
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
new file mode 100644
index 000000000000..dda0be4e25dc
--- /dev/null
+++ b/drivers/mmc/host/mxcmmc.c
@@ -0,0 +1,880 @@
1/*
2 * linux/drivers/mmc/host/mxcmmc.c - Freescale i.MX MMCI driver
3 *
4 * This is a driver for the SDHC controller found in Freescale MX2/MX3
5 * SoCs. It is basically the same hardware as found on MX1 (imxmmc.c).
6 * Unlike the hardware found on MX1, this hardware just works and does
7 * not need all the quirks found in imxmmc.c, hence the seperate driver.
8 *
9 * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
10 * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com>
11 *
12 * derived from pxamci.c by Russell King
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 *
18 */
19
20#include <linux/module.h>
21#include <linux/init.h>
22#include <linux/ioport.h>
23#include <linux/platform_device.h>
24#include <linux/interrupt.h>
25#include <linux/irq.h>
26#include <linux/blkdev.h>
27#include <linux/dma-mapping.h>
28#include <linux/mmc/host.h>
29#include <linux/mmc/card.h>
30#include <linux/delay.h>
31#include <linux/clk.h>
32#include <linux/io.h>
33#include <linux/gpio.h>
34
35#include <asm/dma.h>
36#include <asm/irq.h>
37#include <asm/sizes.h>
38#include <mach/mmc.h>
39
40#ifdef CONFIG_ARCH_MX2
41#include <mach/dma-mx1-mx2.h>
42#define HAS_DMA
43#endif
44
45#define DRIVER_NAME "imx-mmc"
46
47#define MMC_REG_STR_STP_CLK 0x00
48#define MMC_REG_STATUS 0x04
49#define MMC_REG_CLK_RATE 0x08
50#define MMC_REG_CMD_DAT_CONT 0x0C
51#define MMC_REG_RES_TO 0x10
52#define MMC_REG_READ_TO 0x14
53#define MMC_REG_BLK_LEN 0x18
54#define MMC_REG_NOB 0x1C
55#define MMC_REG_REV_NO 0x20
56#define MMC_REG_INT_CNTR 0x24
57#define MMC_REG_CMD 0x28
58#define MMC_REG_ARG 0x2C
59#define MMC_REG_RES_FIFO 0x34
60#define MMC_REG_BUFFER_ACCESS 0x38
61
62#define STR_STP_CLK_RESET (1 << 3)
63#define STR_STP_CLK_START_CLK (1 << 1)
64#define STR_STP_CLK_STOP_CLK (1 << 0)
65
66#define STATUS_CARD_INSERTION (1 << 31)
67#define STATUS_CARD_REMOVAL (1 << 30)
68#define STATUS_YBUF_EMPTY (1 << 29)
69#define STATUS_XBUF_EMPTY (1 << 28)
70#define STATUS_YBUF_FULL (1 << 27)
71#define STATUS_XBUF_FULL (1 << 26)
72#define STATUS_BUF_UND_RUN (1 << 25)
73#define STATUS_BUF_OVFL (1 << 24)
74#define STATUS_SDIO_INT_ACTIVE (1 << 14)
75#define STATUS_END_CMD_RESP (1 << 13)
76#define STATUS_WRITE_OP_DONE (1 << 12)
77#define STATUS_DATA_TRANS_DONE (1 << 11)
78#define STATUS_READ_OP_DONE (1 << 11)
79#define STATUS_WR_CRC_ERROR_CODE_MASK (3 << 10)
80#define STATUS_CARD_BUS_CLK_RUN (1 << 8)
81#define STATUS_BUF_READ_RDY (1 << 7)
82#define STATUS_BUF_WRITE_RDY (1 << 6)
83#define STATUS_RESP_CRC_ERR (1 << 5)
84#define STATUS_CRC_READ_ERR (1 << 3)
85#define STATUS_CRC_WRITE_ERR (1 << 2)
86#define STATUS_TIME_OUT_RESP (1 << 1)
87#define STATUS_TIME_OUT_READ (1 << 0)
88#define STATUS_ERR_MASK 0x2f
89
90#define CMD_DAT_CONT_CMD_RESP_LONG_OFF (1 << 12)
91#define CMD_DAT_CONT_STOP_READWAIT (1 << 11)
92#define CMD_DAT_CONT_START_READWAIT (1 << 10)
93#define CMD_DAT_CONT_BUS_WIDTH_4 (2 << 8)
94#define CMD_DAT_CONT_INIT (1 << 7)
95#define CMD_DAT_CONT_WRITE (1 << 4)
96#define CMD_DAT_CONT_DATA_ENABLE (1 << 3)
97#define CMD_DAT_CONT_RESPONSE_48BIT_CRC (1 << 0)
98#define CMD_DAT_CONT_RESPONSE_136BIT (2 << 0)
99#define CMD_DAT_CONT_RESPONSE_48BIT (3 << 0)
100
101#define INT_SDIO_INT_WKP_EN (1 << 18)
102#define INT_CARD_INSERTION_WKP_EN (1 << 17)
103#define INT_CARD_REMOVAL_WKP_EN (1 << 16)
104#define INT_CARD_INSERTION_EN (1 << 15)
105#define INT_CARD_REMOVAL_EN (1 << 14)
106#define INT_SDIO_IRQ_EN (1 << 13)
107#define INT_DAT0_EN (1 << 12)
108#define INT_BUF_READ_EN (1 << 4)
109#define INT_BUF_WRITE_EN (1 << 3)
110#define INT_END_CMD_RES_EN (1 << 2)
111#define INT_WRITE_OP_DONE_EN (1 << 1)
112#define INT_READ_OP_EN (1 << 0)
113
114struct mxcmci_host {
115 struct mmc_host *mmc;
116 struct resource *res;
117 void __iomem *base;
118 int irq;
119 int detect_irq;
120 int dma;
121 int do_dma;
122 unsigned int power_mode;
123 struct imxmmc_platform_data *pdata;
124
125 struct mmc_request *req;
126 struct mmc_command *cmd;
127 struct mmc_data *data;
128
129 unsigned int dma_nents;
130 unsigned int datasize;
131 unsigned int dma_dir;
132
133 u16 rev_no;
134 unsigned int cmdat;
135
136 struct clk *clk;
137
138 int clock;
139
140 struct work_struct datawork;
141};
142
143static inline int mxcmci_use_dma(struct mxcmci_host *host)
144{
145 return host->do_dma;
146}
147
148static void mxcmci_softreset(struct mxcmci_host *host)
149{
150 int i;
151
152 /* reset sequence */
153 writew(STR_STP_CLK_RESET, host->base + MMC_REG_STR_STP_CLK);
154 writew(STR_STP_CLK_RESET | STR_STP_CLK_START_CLK,
155 host->base + MMC_REG_STR_STP_CLK);
156
157 for (i = 0; i < 8; i++)
158 writew(STR_STP_CLK_START_CLK, host->base + MMC_REG_STR_STP_CLK);
159
160 writew(0xff, host->base + MMC_REG_RES_TO);
161}
162
163static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
164{
165 unsigned int nob = data->blocks;
166 unsigned int blksz = data->blksz;
167 unsigned int datasize = nob * blksz;
168#ifdef HAS_DMA
169 struct scatterlist *sg;
170 int i;
171#endif
172 if (data->flags & MMC_DATA_STREAM)
173 nob = 0xffff;
174
175 host->data = data;
176 data->bytes_xfered = 0;
177
178 writew(nob, host->base + MMC_REG_NOB);
179 writew(blksz, host->base + MMC_REG_BLK_LEN);
180 host->datasize = datasize;
181
182#ifdef HAS_DMA
183 for_each_sg(data->sg, sg, data->sg_len, i) {
184 if (sg->offset & 3 || sg->length & 3) {
185 host->do_dma = 0;
186 return;
187 }
188 }
189
190 if (data->flags & MMC_DATA_READ) {
191 host->dma_dir = DMA_FROM_DEVICE;
192 host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
193 data->sg_len, host->dma_dir);
194
195 imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize,
196 host->res->start + MMC_REG_BUFFER_ACCESS,
197 DMA_MODE_READ);
198 } else {
199 host->dma_dir = DMA_TO_DEVICE;
200 host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
201 data->sg_len, host->dma_dir);
202
203 imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize,
204 host->res->start + MMC_REG_BUFFER_ACCESS,
205 DMA_MODE_WRITE);
206 }
207
208 wmb();
209
210 imx_dma_enable(host->dma);
211#endif /* HAS_DMA */
212}
213
214static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
215 unsigned int cmdat)
216{
217 WARN_ON(host->cmd != NULL);
218 host->cmd = cmd;
219
220 switch (mmc_resp_type(cmd)) {
221 case MMC_RSP_R1: /* short CRC, OPCODE */
222 case MMC_RSP_R1B:/* short CRC, OPCODE, BUSY */
223 cmdat |= CMD_DAT_CONT_RESPONSE_48BIT_CRC;
224 break;
225 case MMC_RSP_R2: /* long 136 bit + CRC */
226 cmdat |= CMD_DAT_CONT_RESPONSE_136BIT;
227 break;
228 case MMC_RSP_R3: /* short */
229 cmdat |= CMD_DAT_CONT_RESPONSE_48BIT;
230 break;
231 case MMC_RSP_NONE:
232 break;
233 default:
234 dev_err(mmc_dev(host->mmc), "unhandled response type 0x%x\n",
235 mmc_resp_type(cmd));
236 cmd->error = -EINVAL;
237 return -EINVAL;
238 }
239
240 if (mxcmci_use_dma(host))
241 writel(INT_READ_OP_EN | INT_WRITE_OP_DONE_EN |
242 INT_END_CMD_RES_EN,
243 host->base + MMC_REG_INT_CNTR);
244 else
245 writel(INT_END_CMD_RES_EN, host->base + MMC_REG_INT_CNTR);
246
247 writew(cmd->opcode, host->base + MMC_REG_CMD);
248 writel(cmd->arg, host->base + MMC_REG_ARG);
249 writew(cmdat, host->base + MMC_REG_CMD_DAT_CONT);
250
251 return 0;
252}
253
254static void mxcmci_finish_request(struct mxcmci_host *host,
255 struct mmc_request *req)
256{
257 writel(0, host->base + MMC_REG_INT_CNTR);
258
259 host->req = NULL;
260 host->cmd = NULL;
261 host->data = NULL;
262
263 mmc_request_done(host->mmc, req);
264}
265
266static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat)
267{
268 struct mmc_data *data = host->data;
269 int data_error;
270
271#ifdef HAS_DMA
272 if (mxcmci_use_dma(host)) {
273 imx_dma_disable(host->dma);
274 dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_nents,
275 host->dma_dir);
276 }
277#endif
278
279 if (stat & STATUS_ERR_MASK) {
280 dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",
281 stat);
282 if (stat & STATUS_CRC_READ_ERR) {
283 data->error = -EILSEQ;
284 } else if (stat & STATUS_CRC_WRITE_ERR) {
285 u32 err_code = (stat >> 9) & 0x3;
286 if (err_code == 2) /* No CRC response */
287 data->error = -ETIMEDOUT;
288 else
289 data->error = -EILSEQ;
290 } else if (stat & STATUS_TIME_OUT_READ) {
291 data->error = -ETIMEDOUT;
292 } else {
293 data->error = -EIO;
294 }
295 } else {
296 data->bytes_xfered = host->datasize;
297 }
298
299 data_error = data->error;
300
301 host->data = NULL;
302
303 return data_error;
304}
305
306static void mxcmci_read_response(struct mxcmci_host *host, unsigned int stat)
307{
308 struct mmc_command *cmd = host->cmd;
309 int i;
310 u32 a, b, c;
311
312 if (!cmd)
313 return;
314
315 if (stat & STATUS_TIME_OUT_RESP) {
316 dev_dbg(mmc_dev(host->mmc), "CMD TIMEOUT\n");
317 cmd->error = -ETIMEDOUT;
318 } else if (stat & STATUS_RESP_CRC_ERR && cmd->flags & MMC_RSP_CRC) {
319 dev_dbg(mmc_dev(host->mmc), "cmd crc error\n");
320 cmd->error = -EILSEQ;
321 }
322
323 if (cmd->flags & MMC_RSP_PRESENT) {
324 if (cmd->flags & MMC_RSP_136) {
325 for (i = 0; i < 4; i++) {
326 a = readw(host->base + MMC_REG_RES_FIFO);
327 b = readw(host->base + MMC_REG_RES_FIFO);
328 cmd->resp[i] = a << 16 | b;
329 }
330 } else {
331 a = readw(host->base + MMC_REG_RES_FIFO);
332 b = readw(host->base + MMC_REG_RES_FIFO);
333 c = readw(host->base + MMC_REG_RES_FIFO);
334 cmd->resp[0] = a << 24 | b << 8 | c >> 8;
335 }
336 }
337}
338
339static int mxcmci_poll_status(struct mxcmci_host *host, u32 mask)
340{
341 u32 stat;
342 unsigned long timeout = jiffies + HZ;
343
344 do {
345 stat = readl(host->base + MMC_REG_STATUS);
346 if (stat & STATUS_ERR_MASK)
347 return stat;
348 if (time_after(jiffies, timeout))
349 return STATUS_TIME_OUT_READ;
350 if (stat & mask)
351 return 0;
352 cpu_relax();
353 } while (1);
354}
355
356static int mxcmci_pull(struct mxcmci_host *host, void *_buf, int bytes)
357{
358 unsigned int stat;
359 u32 *buf = _buf;
360
361 while (bytes > 3) {
362 stat = mxcmci_poll_status(host,
363 STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
364 if (stat)
365 return stat;
366 *buf++ = readl(host->base + MMC_REG_BUFFER_ACCESS);
367 bytes -= 4;
368 }
369
370 if (bytes) {
371 u8 *b = (u8 *)buf;
372 u32 tmp;
373
374 stat = mxcmci_poll_status(host,
375 STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
376 if (stat)
377 return stat;
378 tmp = readl(host->base + MMC_REG_BUFFER_ACCESS);
379 memcpy(b, &tmp, bytes);
380 }
381
382 return 0;
383}
384
385static int mxcmci_push(struct mxcmci_host *host, void *_buf, int bytes)
386{
387 unsigned int stat;
388 u32 *buf = _buf;
389
390 while (bytes > 3) {
391 stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
392 if (stat)
393 return stat;
394 writel(*buf++, host->base + MMC_REG_BUFFER_ACCESS);
395 bytes -= 4;
396 }
397
398 if (bytes) {
399 u8 *b = (u8 *)buf;
400 u32 tmp;
401
402 stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
403 if (stat)
404 return stat;
405
406 memcpy(&tmp, b, bytes);
407 writel(tmp, host->base + MMC_REG_BUFFER_ACCESS);
408 }
409
410 stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
411 if (stat)
412 return stat;
413
414 return 0;
415}
416
417static int mxcmci_transfer_data(struct mxcmci_host *host)
418{
419 struct mmc_data *data = host->req->data;
420 struct scatterlist *sg;
421 int stat, i;
422
423 host->datasize = 0;
424
425 host->data = data;
426 host->datasize = 0;
427
428 if (data->flags & MMC_DATA_READ) {
429 for_each_sg(data->sg, sg, data->sg_len, i) {
430 stat = mxcmci_pull(host, sg_virt(sg), sg->length);
431 if (stat)
432 return stat;
433 host->datasize += sg->length;
434 }
435 } else {
436 for_each_sg(data->sg, sg, data->sg_len, i) {
437 stat = mxcmci_push(host, sg_virt(sg), sg->length);
438 if (stat)
439 return stat;
440 host->datasize += sg->length;
441 }
442 stat = mxcmci_poll_status(host, STATUS_WRITE_OP_DONE);
443 if (stat)
444 return stat;
445 }
446 return 0;
447}
448
449static void mxcmci_datawork(struct work_struct *work)
450{
451 struct mxcmci_host *host = container_of(work, struct mxcmci_host,
452 datawork);
453 int datastat = mxcmci_transfer_data(host);
454 mxcmci_finish_data(host, datastat);
455
456 if (host->req->stop) {
457 if (mxcmci_start_cmd(host, host->req->stop, 0)) {
458 mxcmci_finish_request(host, host->req);
459 return;
460 }
461 } else {
462 mxcmci_finish_request(host, host->req);
463 }
464}
465
466#ifdef HAS_DMA
467static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat)
468{
469 struct mmc_data *data = host->data;
470 int data_error;
471
472 if (!data)
473 return;
474
475 data_error = mxcmci_finish_data(host, stat);
476
477 mxcmci_read_response(host, stat);
478 host->cmd = NULL;
479
480 if (host->req->stop) {
481 if (mxcmci_start_cmd(host, host->req->stop, 0)) {
482 mxcmci_finish_request(host, host->req);
483 return;
484 }
485 } else {
486 mxcmci_finish_request(host, host->req);
487 }
488}
489#endif /* HAS_DMA */
490
491static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat)
492{
493 mxcmci_read_response(host, stat);
494 host->cmd = NULL;
495
496 if (!host->data && host->req) {
497 mxcmci_finish_request(host, host->req);
498 return;
499 }
500
501 /* For the DMA case the DMA engine handles the data transfer
502 * automatically. For non DMA we have to to it ourselves.
503 * Don't do it in interrupt context though.
504 */
505 if (!mxcmci_use_dma(host) && host->data)
506 schedule_work(&host->datawork);
507
508}
509
510static irqreturn_t mxcmci_irq(int irq, void *devid)
511{
512 struct mxcmci_host *host = devid;
513 u32 stat;
514
515 stat = readl(host->base + MMC_REG_STATUS);
516 writel(stat, host->base + MMC_REG_STATUS);
517
518 dev_dbg(mmc_dev(host->mmc), "%s: 0x%08x\n", __func__, stat);
519
520 if (stat & STATUS_END_CMD_RESP)
521 mxcmci_cmd_done(host, stat);
522#ifdef HAS_DMA
523 if (mxcmci_use_dma(host) &&
524 (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE)))
525 mxcmci_data_done(host, stat);
526#endif
527 return IRQ_HANDLED;
528}
529
530static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req)
531{
532 struct mxcmci_host *host = mmc_priv(mmc);
533 unsigned int cmdat = host->cmdat;
534
535 WARN_ON(host->req != NULL);
536
537 host->req = req;
538 host->cmdat &= ~CMD_DAT_CONT_INIT;
539#ifdef HAS_DMA
540 host->do_dma = 1;
541#endif
542 if (req->data) {
543 mxcmci_setup_data(host, req->data);
544
545 cmdat |= CMD_DAT_CONT_DATA_ENABLE;
546
547 if (req->data->flags & MMC_DATA_WRITE)
548 cmdat |= CMD_DAT_CONT_WRITE;
549 }
550
551 if (mxcmci_start_cmd(host, req->cmd, cmdat))
552 mxcmci_finish_request(host, req);
553}
554
555static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios)
556{
557 unsigned int divider;
558 int prescaler = 0;
559 unsigned int clk_in = clk_get_rate(host->clk);
560
561 while (prescaler <= 0x800) {
562 for (divider = 1; divider <= 0xF; divider++) {
563 int x;
564
565 x = (clk_in / (divider + 1));
566
567 if (prescaler)
568 x /= (prescaler * 2);
569
570 if (x <= clk_ios)
571 break;
572 }
573 if (divider < 0x10)
574 break;
575
576 if (prescaler == 0)
577 prescaler = 1;
578 else
579 prescaler <<= 1;
580 }
581
582 writew((prescaler << 4) | divider, host->base + MMC_REG_CLK_RATE);
583
584 dev_dbg(mmc_dev(host->mmc), "scaler: %d divider: %d in: %d out: %d\n",
585 prescaler, divider, clk_in, clk_ios);
586}
587
588static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
589{
590 struct mxcmci_host *host = mmc_priv(mmc);
591#ifdef HAS_DMA
592 unsigned int blen;
593 /*
594 * use burstlen of 64 in 4 bit mode (--> reg value 0)
595 * use burstlen of 16 in 1 bit mode (--> reg value 16)
596 */
597 if (ios->bus_width == MMC_BUS_WIDTH_4)
598 blen = 0;
599 else
600 blen = 16;
601
602 imx_dma_config_burstlen(host->dma, blen);
603#endif
604 if (ios->bus_width == MMC_BUS_WIDTH_4)
605 host->cmdat |= CMD_DAT_CONT_BUS_WIDTH_4;
606 else
607 host->cmdat &= ~CMD_DAT_CONT_BUS_WIDTH_4;
608
609 if (host->power_mode != ios->power_mode) {
610 if (host->pdata && host->pdata->setpower)
611 host->pdata->setpower(mmc_dev(mmc), ios->vdd);
612 host->power_mode = ios->power_mode;
613 if (ios->power_mode == MMC_POWER_ON)
614 host->cmdat |= CMD_DAT_CONT_INIT;
615 }
616
617 if (ios->clock) {
618 mxcmci_set_clk_rate(host, ios->clock);
619 writew(STR_STP_CLK_START_CLK, host->base + MMC_REG_STR_STP_CLK);
620 } else {
621 writew(STR_STP_CLK_STOP_CLK, host->base + MMC_REG_STR_STP_CLK);
622 }
623
624 host->clock = ios->clock;
625}
626
627static irqreturn_t mxcmci_detect_irq(int irq, void *data)
628{
629 struct mmc_host *mmc = data;
630
631 dev_dbg(mmc_dev(mmc), "%s\n", __func__);
632
633 mmc_detect_change(mmc, msecs_to_jiffies(250));
634 return IRQ_HANDLED;
635}
636
637static int mxcmci_get_ro(struct mmc_host *mmc)
638{
639 struct mxcmci_host *host = mmc_priv(mmc);
640
641 if (host->pdata && host->pdata->get_ro)
642 return !!host->pdata->get_ro(mmc_dev(mmc));
643 /*
644 * Board doesn't support read only detection; let the mmc core
645 * decide what to do.
646 */
647 return -ENOSYS;
648}
649
650
651static const struct mmc_host_ops mxcmci_ops = {
652 .request = mxcmci_request,
653 .set_ios = mxcmci_set_ios,
654 .get_ro = mxcmci_get_ro,
655};
656
657static int mxcmci_probe(struct platform_device *pdev)
658{
659 struct mmc_host *mmc;
660 struct mxcmci_host *host = NULL;
661 struct resource *r;
662 int ret = 0, irq;
663
664 printk(KERN_INFO "i.MX SDHC driver\n");
665
666 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
667 irq = platform_get_irq(pdev, 0);
668 if (!r || irq < 0)
669 return -EINVAL;
670
671 r = request_mem_region(r->start, resource_size(r), pdev->name);
672 if (!r)
673 return -EBUSY;
674
675 mmc = mmc_alloc_host(sizeof(struct mxcmci_host), &pdev->dev);
676 if (!mmc) {
677 ret = -ENOMEM;
678 goto out_release_mem;
679 }
680
681 mmc->ops = &mxcmci_ops;
682 mmc->caps = MMC_CAP_4_BIT_DATA;
683
684 /* MMC core transfer sizes tunable parameters */
685 mmc->max_hw_segs = 64;
686 mmc->max_phys_segs = 64;
687 mmc->max_blk_size = 2048;
688 mmc->max_blk_count = 65535;
689 mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
690 mmc->max_seg_size = mmc->max_seg_size;
691
692 host = mmc_priv(mmc);
693 host->base = ioremap(r->start, resource_size(r));
694 if (!host->base) {
695 ret = -ENOMEM;
696 goto out_free;
697 }
698
699 host->mmc = mmc;
700 host->pdata = pdev->dev.platform_data;
701
702 if (host->pdata && host->pdata->ocr_avail)
703 mmc->ocr_avail = host->pdata->ocr_avail;
704 else
705 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
706
707 host->res = r;
708 host->irq = irq;
709
710 host->clk = clk_get(&pdev->dev, "sdhc_clk");
711 if (IS_ERR(host->clk)) {
712 ret = PTR_ERR(host->clk);
713 goto out_iounmap;
714 }
715 clk_enable(host->clk);
716
717 mxcmci_softreset(host);
718
719 host->rev_no = readw(host->base + MMC_REG_REV_NO);
720 if (host->rev_no != 0x400) {
721 ret = -ENODEV;
722 dev_err(mmc_dev(host->mmc), "wrong rev.no. 0x%08x. aborting.\n",
723 host->rev_no);
724 goto out_clk_put;
725 }
726
727 mmc->f_min = clk_get_rate(host->clk) >> 7;
728 mmc->f_max = clk_get_rate(host->clk) >> 1;
729
730 /* recommended in data sheet */
731 writew(0x2db4, host->base + MMC_REG_READ_TO);
732
733 writel(0, host->base + MMC_REG_INT_CNTR);
734
735#ifdef HAS_DMA
736 host->dma = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_LOW);
737 if (host->dma < 0) {
738 dev_err(mmc_dev(host->mmc), "imx_dma_request_by_prio failed\n");
739 ret = -EBUSY;
740 goto out_clk_put;
741 }
742
743 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
744 if (!r) {
745 ret = -EINVAL;
746 goto out_free_dma;
747 }
748
749 ret = imx_dma_config_channel(host->dma,
750 IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_FIFO,
751 IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
752 r->start, 0);
753 if (ret) {
754 dev_err(mmc_dev(host->mmc), "failed to config DMA channel\n");
755 goto out_free_dma;
756 }
757#endif
758 INIT_WORK(&host->datawork, mxcmci_datawork);
759
760 ret = request_irq(host->irq, mxcmci_irq, 0, DRIVER_NAME, host);
761 if (ret)
762 goto out_free_dma;
763
764 platform_set_drvdata(pdev, mmc);
765
766 if (host->pdata && host->pdata->init) {
767 ret = host->pdata->init(&pdev->dev, mxcmci_detect_irq,
768 host->mmc);
769 if (ret)
770 goto out_free_irq;
771 }
772
773 mmc_add_host(mmc);
774
775 return 0;
776
777out_free_irq:
778 free_irq(host->irq, host);
779out_free_dma:
780#ifdef HAS_DMA
781 imx_dma_free(host->dma);
782#endif
783out_clk_put:
784 clk_disable(host->clk);
785 clk_put(host->clk);
786out_iounmap:
787 iounmap(host->base);
788out_free:
789 mmc_free_host(mmc);
790out_release_mem:
791 release_mem_region(host->res->start, resource_size(host->res));
792 return ret;
793}
794
795static int mxcmci_remove(struct platform_device *pdev)
796{
797 struct mmc_host *mmc = platform_get_drvdata(pdev);
798 struct mxcmci_host *host = mmc_priv(mmc);
799
800 platform_set_drvdata(pdev, NULL);
801
802 mmc_remove_host(mmc);
803
804 if (host->pdata && host->pdata->exit)
805 host->pdata->exit(&pdev->dev, mmc);
806
807 free_irq(host->irq, host);
808 iounmap(host->base);
809#ifdef HAS_DMA
810 imx_dma_free(host->dma);
811#endif
812 clk_disable(host->clk);
813 clk_put(host->clk);
814
815 release_mem_region(host->res->start, resource_size(host->res));
816 release_resource(host->res);
817
818 mmc_free_host(mmc);
819
820 return 0;
821}
822
823#ifdef CONFIG_PM
824static int mxcmci_suspend(struct platform_device *dev, pm_message_t state)
825{
826 struct mmc_host *mmc = platform_get_drvdata(dev);
827 int ret = 0;
828
829 if (mmc)
830 ret = mmc_suspend_host(mmc, state);
831
832 return ret;
833}
834
835static int mxcmci_resume(struct platform_device *dev)
836{
837 struct mmc_host *mmc = platform_get_drvdata(dev);
838 struct mxcmci_host *host;
839 int ret = 0;
840
841 if (mmc) {
842 host = mmc_priv(mmc);
843 ret = mmc_resume_host(mmc);
844 }
845
846 return ret;
847}
848#else
849#define mxcmci_suspend NULL
850#define mxcmci_resume NULL
851#endif /* CONFIG_PM */
852
853static struct platform_driver mxcmci_driver = {
854 .probe = mxcmci_probe,
855 .remove = mxcmci_remove,
856 .suspend = mxcmci_suspend,
857 .resume = mxcmci_resume,
858 .driver = {
859 .name = DRIVER_NAME,
860 .owner = THIS_MODULE,
861 }
862};
863
864static int __init mxcmci_init(void)
865{
866 return platform_driver_register(&mxcmci_driver);
867}
868
869static void __exit mxcmci_exit(void)
870{
871 platform_driver_unregister(&mxcmci_driver);
872}
873
874module_init(mxcmci_init);
875module_exit(mxcmci_exit);
876
877MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver");
878MODULE_AUTHOR("Sascha Hauer, Pengutronix");
879MODULE_LICENSE("GPL");
880MODULE_ALIAS("platform:imx-mmc");