2 * This is a driver for the SDHC controller found in Freescale MX2/MX3
3 * SoCs. It is basically the same hardware as found on MX1 (imxmmc.c).
4 * Unlike the hardware found on MX1, this hardware just works and does
5 * not need all the quirks found in imxmmc.c, hence the seperate driver.
7 * Copyright (C) 2009 Ilya Yanok, <yanok@emcraft.com>
8 * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
9 * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com>
11 * derived from pxamci.c by Russell King
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
26 #include <asm/errno.h>
28 #include <asm/arch/clock.h>
30 #define DRIVER_NAME "mxc-mmc"
50 #define STR_STP_CLK_RESET (1 << 3)
51 #define STR_STP_CLK_START_CLK (1 << 1)
52 #define STR_STP_CLK_STOP_CLK (1 << 0)
54 #define STATUS_CARD_INSERTION (1 << 31)
55 #define STATUS_CARD_REMOVAL (1 << 30)
56 #define STATUS_YBUF_EMPTY (1 << 29)
57 #define STATUS_XBUF_EMPTY (1 << 28)
58 #define STATUS_YBUF_FULL (1 << 27)
59 #define STATUS_XBUF_FULL (1 << 26)
60 #define STATUS_BUF_UND_RUN (1 << 25)
61 #define STATUS_BUF_OVFL (1 << 24)
62 #define STATUS_SDIO_INT_ACTIVE (1 << 14)
63 #define STATUS_END_CMD_RESP (1 << 13)
64 #define STATUS_WRITE_OP_DONE (1 << 12)
65 #define STATUS_DATA_TRANS_DONE (1 << 11)
66 #define STATUS_READ_OP_DONE (1 << 11)
67 #define STATUS_WR_CRC_ERROR_CODE_MASK (3 << 10)
68 #define STATUS_CARD_BUS_CLK_RUN (1 << 8)
69 #define STATUS_BUF_READ_RDY (1 << 7)
70 #define STATUS_BUF_WRITE_RDY (1 << 6)
71 #define STATUS_RESP_CRC_ERR (1 << 5)
72 #define STATUS_CRC_READ_ERR (1 << 3)
73 #define STATUS_CRC_WRITE_ERR (1 << 2)
74 #define STATUS_TIME_OUT_RESP (1 << 1)
75 #define STATUS_TIME_OUT_READ (1 << 0)
76 #define STATUS_ERR_MASK 0x2f
78 #define CMD_DAT_CONT_CMD_RESP_LONG_OFF (1 << 12)
79 #define CMD_DAT_CONT_STOP_READWAIT (1 << 11)
80 #define CMD_DAT_CONT_START_READWAIT (1 << 10)
81 #define CMD_DAT_CONT_BUS_WIDTH_4 (2 << 8)
82 #define CMD_DAT_CONT_INIT (1 << 7)
83 #define CMD_DAT_CONT_WRITE (1 << 4)
84 #define CMD_DAT_CONT_DATA_ENABLE (1 << 3)
85 #define CMD_DAT_CONT_RESPONSE_48BIT_CRC (1 << 0)
86 #define CMD_DAT_CONT_RESPONSE_136BIT (2 << 0)
87 #define CMD_DAT_CONT_RESPONSE_48BIT (3 << 0)
89 #define INT_SDIO_INT_WKP_EN (1 << 18)
90 #define INT_CARD_INSERTION_WKP_EN (1 << 17)
91 #define INT_CARD_REMOVAL_WKP_EN (1 << 16)
92 #define INT_CARD_INSERTION_EN (1 << 15)
93 #define INT_CARD_REMOVAL_EN (1 << 14)
94 #define INT_SDIO_IRQ_EN (1 << 13)
95 #define INT_DAT0_EN (1 << 12)
96 #define INT_BUF_READ_EN (1 << 4)
97 #define INT_BUF_WRITE_EN (1 << 3)
98 #define INT_END_CMD_RES_EN (1 << 2)
99 #define INT_WRITE_OP_DONE_EN (1 << 1)
100 #define INT_READ_OP_EN (1 << 0)
104 struct mxcmci_regs
*base
;
109 unsigned int power_mode
;
112 struct mmc_data
*data
;
114 unsigned int dma_nents
;
115 unsigned int datasize
;
116 unsigned int dma_dir
;
124 static struct mxcmci_host mxcmci_host
;
126 /* maintainer note: do we really want to have a global host pointer? */
127 static struct mxcmci_host
*host
= &mxcmci_host
;
129 static inline int mxcmci_use_dma(struct mxcmci_host
*host
)
134 static void mxcmci_softreset(struct mxcmci_host
*host
)
139 writel(STR_STP_CLK_RESET
, &host
->base
->str_stp_clk
);
140 writel(STR_STP_CLK_RESET
| STR_STP_CLK_START_CLK
,
141 &host
->base
->str_stp_clk
);
143 for (i
= 0; i
< 8; i
++)
144 writel(STR_STP_CLK_START_CLK
, &host
->base
->str_stp_clk
);
146 writel(0xff, &host
->base
->res_to
);
149 static void mxcmci_setup_data(struct mxcmci_host
*host
, struct mmc_data
*data
)
151 unsigned int nob
= data
->blocks
;
152 unsigned int blksz
= data
->blocksize
;
153 unsigned int datasize
= nob
* blksz
;
157 writel(nob
, &host
->base
->nob
);
158 writel(blksz
, &host
->base
->blk_len
);
159 host
->datasize
= datasize
;
162 static int mxcmci_start_cmd(struct mxcmci_host
*host
, struct mmc_cmd
*cmd
,
165 if (host
->cmd
!= NULL
)
166 printf("mxcmci: error!\n");
169 switch (cmd
->resp_type
) {
170 case MMC_RSP_R1
: /* short CRC, OPCODE */
171 case MMC_RSP_R1b
:/* short CRC, OPCODE, BUSY */
172 cmdat
|= CMD_DAT_CONT_RESPONSE_48BIT_CRC
;
174 case MMC_RSP_R2
: /* long 136 bit + CRC */
175 cmdat
|= CMD_DAT_CONT_RESPONSE_136BIT
;
177 case MMC_RSP_R3
: /* short */
178 cmdat
|= CMD_DAT_CONT_RESPONSE_48BIT
;
183 printf("mxcmci: unhandled response type 0x%x\n",
188 writel(cmd
->cmdidx
, &host
->base
->cmd
);
189 writel(cmd
->cmdarg
, &host
->base
->arg
);
190 writel(cmdat
, &host
->base
->cmd_dat_cont
);
195 static void mxcmci_finish_request(struct mxcmci_host
*host
,
196 struct mmc_cmd
*cmd
, struct mmc_data
*data
)
202 static int mxcmci_finish_data(struct mxcmci_host
*host
, unsigned int stat
)
206 if (stat
& STATUS_ERR_MASK
) {
207 printf("request failed. status: 0x%08x\n",
209 if (stat
& STATUS_CRC_READ_ERR
) {
210 data_error
= -EILSEQ
;
211 } else if (stat
& STATUS_CRC_WRITE_ERR
) {
212 u32 err_code
= (stat
>> 9) & 0x3;
213 if (err_code
== 2) /* No CRC response */
214 data_error
= TIMEOUT
;
216 data_error
= -EILSEQ
;
217 } else if (stat
& STATUS_TIME_OUT_READ
) {
218 data_error
= TIMEOUT
;
229 static int mxcmci_read_response(struct mxcmci_host
*host
, unsigned int stat
)
231 struct mmc_cmd
*cmd
= host
->cmd
;
234 u32
*resp
= (u32
*)cmd
->response
;
239 if (stat
& STATUS_TIME_OUT_RESP
) {
240 printf("CMD TIMEOUT\n");
242 } else if (stat
& STATUS_RESP_CRC_ERR
&& cmd
->resp_type
& MMC_RSP_CRC
) {
243 printf("cmd crc error\n");
247 if (cmd
->resp_type
& MMC_RSP_PRESENT
) {
248 if (cmd
->resp_type
& MMC_RSP_136
) {
249 for (i
= 0; i
< 4; i
++) {
250 a
= readl(&host
->base
->res_fifo
) & 0xFFFF;
251 b
= readl(&host
->base
->res_fifo
) & 0xFFFF;
252 resp
[i
] = a
<< 16 | b
;
255 a
= readl(&host
->base
->res_fifo
) & 0xFFFF;
256 b
= readl(&host
->base
->res_fifo
) & 0xFFFF;
257 c
= readl(&host
->base
->res_fifo
) & 0xFFFF;
258 resp
[0] = a
<< 24 | b
<< 8 | c
>> 8;
264 static int mxcmci_poll_status(struct mxcmci_host
*host
, u32 mask
)
267 unsigned long timeout
= get_ticks() + CONFIG_SYS_HZ
;
270 stat
= readl(&host
->base
->status
);
271 if (stat
& STATUS_ERR_MASK
)
273 if (timeout
< get_ticks())
274 return STATUS_TIME_OUT_READ
;
280 static int mxcmci_pull(struct mxcmci_host
*host
, void *_buf
, int bytes
)
286 stat
= mxcmci_poll_status(host
,
287 STATUS_BUF_READ_RDY
| STATUS_READ_OP_DONE
);
290 *buf
++ = readl(&host
->base
->buffer_access
);
298 stat
= mxcmci_poll_status(host
,
299 STATUS_BUF_READ_RDY
| STATUS_READ_OP_DONE
);
302 tmp
= readl(&host
->base
->buffer_access
);
303 memcpy(b
, &tmp
, bytes
);
309 static int mxcmci_push(struct mxcmci_host
*host
, const void *_buf
, int bytes
)
312 const u32
*buf
= _buf
;
315 stat
= mxcmci_poll_status(host
, STATUS_BUF_WRITE_RDY
);
318 writel(*buf
++, &host
->base
->buffer_access
);
323 const u8
*b
= (u8
*)buf
;
326 stat
= mxcmci_poll_status(host
, STATUS_BUF_WRITE_RDY
);
330 memcpy(&tmp
, b
, bytes
);
331 writel(tmp
, &host
->base
->buffer_access
);
334 stat
= mxcmci_poll_status(host
, STATUS_BUF_WRITE_RDY
);
341 static int mxcmci_transfer_data(struct mxcmci_host
*host
)
343 struct mmc_data
*data
= host
->data
;
345 unsigned long length
;
347 length
= data
->blocks
* data
->blocksize
;
350 if (data
->flags
& MMC_DATA_READ
) {
351 stat
= mxcmci_pull(host
, data
->dest
, length
);
354 host
->datasize
+= length
;
356 stat
= mxcmci_push(host
, (const void *)(data
->src
), length
);
359 host
->datasize
+= length
;
360 stat
= mxcmci_poll_status(host
, STATUS_WRITE_OP_DONE
);
367 static int mxcmci_cmd_done(struct mxcmci_host
*host
, unsigned int stat
)
372 ret
= mxcmci_read_response(host
, stat
);
375 mxcmci_finish_request(host
, host
->cmd
, host
->data
);
380 mxcmci_finish_request(host
, host
->cmd
, host
->data
);
384 datastat
= mxcmci_transfer_data(host
);
385 ret
= mxcmci_finish_data(host
, datastat
);
386 mxcmci_finish_request(host
, host
->cmd
, host
->data
);
390 static int mxcmci_request(struct mmc
*mmc
, struct mmc_cmd
*cmd
,
391 struct mmc_data
*data
)
393 struct mxcmci_host
*host
= mmc
->priv
;
394 unsigned int cmdat
= host
->cmdat
;
398 host
->cmdat
&= ~CMD_DAT_CONT_INIT
;
400 mxcmci_setup_data(host
, data
);
402 cmdat
|= CMD_DAT_CONT_DATA_ENABLE
;
404 if (data
->flags
& MMC_DATA_WRITE
)
405 cmdat
|= CMD_DAT_CONT_WRITE
;
408 if ((ret
= mxcmci_start_cmd(host
, cmd
, cmdat
))) {
409 mxcmci_finish_request(host
, cmd
, data
);
414 stat
= readl(&host
->base
->status
);
415 writel(stat
, &host
->base
->status
);
416 } while (!(stat
& STATUS_END_CMD_RESP
));
418 return mxcmci_cmd_done(host
, stat
);
421 static void mxcmci_set_clk_rate(struct mxcmci_host
*host
, unsigned int clk_ios
)
423 unsigned int divider
;
425 unsigned long clk_in
= mxc_get_clock(MXC_ESDHC_CLK
);
427 while (prescaler
<= 0x800) {
428 for (divider
= 1; divider
<= 0xF; divider
++) {
431 x
= (clk_in
/ (divider
+ 1));
434 x
/= (prescaler
* 2);
448 writel((prescaler
<< 4) | divider
, &host
->base
->clk_rate
);
451 static void mxcmci_set_ios(struct mmc
*mmc
)
453 struct mxcmci_host
*host
= mmc
->priv
;
454 if (mmc
->bus_width
== 4)
455 host
->cmdat
|= CMD_DAT_CONT_BUS_WIDTH_4
;
457 host
->cmdat
&= ~CMD_DAT_CONT_BUS_WIDTH_4
;
460 mxcmci_set_clk_rate(host
, mmc
->clock
);
461 writel(STR_STP_CLK_START_CLK
, &host
->base
->str_stp_clk
);
463 writel(STR_STP_CLK_STOP_CLK
, &host
->base
->str_stp_clk
);
466 host
->clock
= mmc
->clock
;
469 static int mxcmci_init(struct mmc
*mmc
)
471 struct mxcmci_host
*host
= mmc
->priv
;
473 mxcmci_softreset(host
);
475 host
->rev_no
= readl(&host
->base
->rev_no
);
476 if (host
->rev_no
!= 0x400) {
477 printf("wrong rev.no. 0x%08x. aborting.\n",
482 /* recommended in data sheet */
483 writel(0x2db4, &host
->base
->read_to
);
485 writel(0, &host
->base
->int_cntr
);
490 static const struct mmc_ops mxcmci_ops
= {
491 .send_cmd
= mxcmci_request
,
492 .set_ios
= mxcmci_set_ios
,
496 static struct mmc_config mxcmci_cfg
= {
499 .host_caps
= MMC_MODE_4BIT
,
500 .voltages
= MMC_VDD_32_33
| MMC_VDD_33_34
,
501 .b_max
= CONFIG_SYS_MMC_MAX_BLK_COUNT
,
504 static int mxcmci_initialize(bd_t
*bis
)
506 host
->base
= (struct mxcmci_regs
*)CONFIG_MXC_MCI_REGS_BASE
;
508 mxcmci_cfg
.f_min
= mxc_get_clock(MXC_ESDHC_CLK
) >> 7;
509 mxcmci_cfg
.f_max
= mxc_get_clock(MXC_ESDHC_CLK
) >> 1;
511 host
->mmc
= mmc_create(&mxcmci_cfg
, host
);
512 if (host
->mmc
== NULL
)
518 int mxc_mmc_init(bd_t
*bis
)
520 return mxcmci_initialize(bis
);