2 * ARM PrimeCell MultiMedia Card Interface - PL180
4 * Copyright (C) ST-Ericsson SA 2010
6 * Author: Ulf Hansson <ulf.hansson@stericsson.com>
7 * Author: Martin Lundholm <martin.xa.lundholm@stericsson.com>
8 * Ported to drivers/mmc/ by: Matt Waddel <matt.waddel@linaro.org>
10 * SPDX-License-Identifier: GPL-2.0+
19 #include "arm_pl180_mmci.h"
22 static int wait_for_command_end(struct mmc
*dev
, struct mmc_cmd
*cmd
)
24 u32 hoststatus
, statusmask
;
25 struct pl180_mmc_host
*host
= dev
->priv
;
27 statusmask
= SDI_STA_CTIMEOUT
| SDI_STA_CCRCFAIL
;
28 if ((cmd
->resp_type
& MMC_RSP_PRESENT
))
29 statusmask
|= SDI_STA_CMDREND
;
31 statusmask
|= SDI_STA_CMDSENT
;
34 hoststatus
= readl(&host
->base
->status
) & statusmask
;
37 writel(statusmask
, &host
->base
->status_clear
);
38 if (hoststatus
& SDI_STA_CTIMEOUT
) {
39 debug("CMD%d time out\n", cmd
->cmdidx
);
41 } else if ((hoststatus
& SDI_STA_CCRCFAIL
) &&
42 (cmd
->resp_type
& MMC_RSP_CRC
)) {
43 printf("CMD%d CRC error\n", cmd
->cmdidx
);
47 if (cmd
->resp_type
& MMC_RSP_PRESENT
) {
48 cmd
->response
[0] = readl(&host
->base
->response0
);
49 cmd
->response
[1] = readl(&host
->base
->response1
);
50 cmd
->response
[2] = readl(&host
->base
->response2
);
51 cmd
->response
[3] = readl(&host
->base
->response3
);
52 debug("CMD%d response[0]:0x%08X, response[1]:0x%08X, "
53 "response[2]:0x%08X, response[3]:0x%08X\n",
54 cmd
->cmdidx
, cmd
->response
[0], cmd
->response
[1],
55 cmd
->response
[2], cmd
->response
[3]);
61 /* send command to the mmc card and wait for results */
62 static int do_command(struct mmc
*dev
, struct mmc_cmd
*cmd
)
66 struct pl180_mmc_host
*host
= dev
->priv
;
68 sdi_cmd
= ((cmd
->cmdidx
& SDI_CMD_CMDINDEX_MASK
) | SDI_CMD_CPSMEN
);
71 sdi_cmd
|= SDI_CMD_WAITRESP
;
72 if (cmd
->resp_type
& MMC_RSP_136
)
73 sdi_cmd
|= SDI_CMD_LONGRESP
;
76 writel((u32
)cmd
->cmdarg
, &host
->base
->argument
);
77 udelay(COMMAND_REG_DELAY
);
78 writel(sdi_cmd
, &host
->base
->command
);
79 result
= wait_for_command_end(dev
, cmd
);
81 /* After CMD2 set RCA to a none zero value. */
82 if ((result
== 0) && (cmd
->cmdidx
== MMC_CMD_ALL_SEND_CID
))
85 /* After CMD3 open drain is switched off and push pull is used. */
86 if ((result
== 0) && (cmd
->cmdidx
== MMC_CMD_SET_RELATIVE_ADDR
)) {
87 u32 sdi_pwr
= readl(&host
->base
->power
) & ~SDI_PWR_OPD
;
88 writel(sdi_pwr
, &host
->base
->power
);
94 static int read_bytes(struct mmc
*dev
, u32
*dest
, u32 blkcount
, u32 blksize
)
97 u64 xfercount
= blkcount
* blksize
;
98 struct pl180_mmc_host
*host
= dev
->priv
;
99 u32 status
, status_err
;
101 debug("read_bytes: blkcount=%u blksize=%u\n", blkcount
, blksize
);
103 status
= readl(&host
->base
->status
);
104 status_err
= status
& (SDI_STA_DCRCFAIL
| SDI_STA_DTIMEOUT
|
106 while ((!status_err
) && (xfercount
>= sizeof(u32
))) {
107 if (status
& SDI_STA_RXDAVL
) {
108 *(tempbuff
) = readl(&host
->base
->fifo
);
110 xfercount
-= sizeof(u32
);
112 status
= readl(&host
->base
->status
);
113 status_err
= status
& (SDI_STA_DCRCFAIL
| SDI_STA_DTIMEOUT
|
117 status_err
= status
&
118 (SDI_STA_DCRCFAIL
| SDI_STA_DTIMEOUT
| SDI_STA_DBCKEND
|
120 while (!status_err
) {
121 status
= readl(&host
->base
->status
);
122 status_err
= status
&
123 (SDI_STA_DCRCFAIL
| SDI_STA_DTIMEOUT
| SDI_STA_DBCKEND
|
127 if (status
& SDI_STA_DTIMEOUT
) {
128 printf("Read data timed out, xfercount: %llu, status: 0x%08X\n",
131 } else if (status
& SDI_STA_DCRCFAIL
) {
132 printf("Read data bytes CRC error: 0x%x\n", status
);
134 } else if (status
& SDI_STA_RXOVERR
) {
135 printf("Read data RX overflow error\n");
139 writel(SDI_ICR_MASK
, &host
->base
->status_clear
);
142 printf("Read data error, xfercount: %llu\n", xfercount
);
149 static int write_bytes(struct mmc
*dev
, u32
*src
, u32 blkcount
, u32 blksize
)
153 u64 xfercount
= blkcount
* blksize
;
154 struct pl180_mmc_host
*host
= dev
->priv
;
155 u32 status
, status_err
;
157 debug("write_bytes: blkcount=%u blksize=%u\n", blkcount
, blksize
);
159 status
= readl(&host
->base
->status
);
160 status_err
= status
& (SDI_STA_DCRCFAIL
| SDI_STA_DTIMEOUT
);
161 while (!status_err
&& xfercount
) {
162 if (status
& SDI_STA_TXFIFOBW
) {
163 if (xfercount
>= SDI_FIFO_BURST_SIZE
* sizeof(u32
)) {
164 for (i
= 0; i
< SDI_FIFO_BURST_SIZE
; i
++)
165 writel(*(tempbuff
+ i
),
167 tempbuff
+= SDI_FIFO_BURST_SIZE
;
168 xfercount
-= SDI_FIFO_BURST_SIZE
* sizeof(u32
);
170 while (xfercount
>= sizeof(u32
)) {
171 writel(*(tempbuff
), &host
->base
->fifo
);
173 xfercount
-= sizeof(u32
);
177 status
= readl(&host
->base
->status
);
178 status_err
= status
& (SDI_STA_DCRCFAIL
| SDI_STA_DTIMEOUT
);
181 status_err
= status
&
182 (SDI_STA_DCRCFAIL
| SDI_STA_DTIMEOUT
| SDI_STA_DBCKEND
);
183 while (!status_err
) {
184 status
= readl(&host
->base
->status
);
185 status_err
= status
&
186 (SDI_STA_DCRCFAIL
| SDI_STA_DTIMEOUT
| SDI_STA_DBCKEND
);
189 if (status
& SDI_STA_DTIMEOUT
) {
190 printf("Write data timed out, xfercount:%llu,status:0x%08X\n",
193 } else if (status
& SDI_STA_DCRCFAIL
) {
194 printf("Write data CRC error\n");
198 writel(SDI_ICR_MASK
, &host
->base
->status_clear
);
201 printf("Write data error, xfercount:%llu", xfercount
);
208 static int do_data_transfer(struct mmc
*dev
,
210 struct mmc_data
*data
)
212 int error
= -ETIMEDOUT
;
213 struct pl180_mmc_host
*host
= dev
->priv
;
216 u32 data_len
= (u32
) (data
->blocks
* data
->blocksize
);
218 if (!host
->version2
) {
219 blksz
= (ffs(data
->blocksize
) - 1);
220 data_ctrl
|= ((blksz
<< 4) & SDI_DCTRL_DBLKSIZE_MASK
);
222 blksz
= data
->blocksize
;
223 data_ctrl
|= (blksz
<< SDI_DCTRL_DBLOCKSIZE_V2_SHIFT
);
225 data_ctrl
|= SDI_DCTRL_DTEN
| SDI_DCTRL_BUSYMODE
;
227 writel(SDI_DTIMER_DEFAULT
, &host
->base
->datatimer
);
228 writel(data_len
, &host
->base
->datalength
);
229 udelay(DATA_REG_DELAY
);
231 if (data
->flags
& MMC_DATA_READ
) {
232 data_ctrl
|= SDI_DCTRL_DTDIR_IN
;
233 writel(data_ctrl
, &host
->base
->datactrl
);
235 error
= do_command(dev
, cmd
);
239 error
= read_bytes(dev
, (u32
*)data
->dest
, (u32
)data
->blocks
,
240 (u32
)data
->blocksize
);
241 } else if (data
->flags
& MMC_DATA_WRITE
) {
242 error
= do_command(dev
, cmd
);
246 writel(data_ctrl
, &host
->base
->datactrl
);
247 error
= write_bytes(dev
, (u32
*)data
->src
, (u32
)data
->blocks
,
248 (u32
)data
->blocksize
);
254 static int host_request(struct mmc
*dev
,
256 struct mmc_data
*data
)
261 result
= do_data_transfer(dev
, cmd
, data
);
263 result
= do_command(dev
, cmd
);
268 /* MMC uses open drain drivers in the enumeration phase */
269 static int mmc_host_reset(struct mmc
*dev
)
271 struct pl180_mmc_host
*host
= dev
->priv
;
273 writel(host
->pwr_init
, &host
->base
->power
);
278 static void host_set_ios(struct mmc
*dev
)
280 struct pl180_mmc_host
*host
= dev
->priv
;
283 sdi_clkcr
= readl(&host
->base
->clock
);
285 /* Ramp up the clock rate */
290 if (dev
->clock
>= dev
->f_max
) {
292 dev
->clock
= dev
->f_max
;
294 clkdiv
= (host
->clock_in
/ dev
->clock
) - 2;
297 tmp_clock
= host
->clock_in
/ (clkdiv
+ 2);
298 while (tmp_clock
> dev
->clock
) {
300 tmp_clock
= host
->clock_in
/ (clkdiv
+ 2);
303 if (clkdiv
> SDI_CLKCR_CLKDIV_MASK
)
304 clkdiv
= SDI_CLKCR_CLKDIV_MASK
;
306 tmp_clock
= host
->clock_in
/ (clkdiv
+ 2);
307 dev
->clock
= tmp_clock
;
308 sdi_clkcr
&= ~(SDI_CLKCR_CLKDIV_MASK
);
312 /* Set the bus width */
313 if (dev
->bus_width
) {
316 switch (dev
->bus_width
) {
318 buswidth
|= SDI_CLKCR_WIDBUS_1
;
321 buswidth
|= SDI_CLKCR_WIDBUS_4
;
324 buswidth
|= SDI_CLKCR_WIDBUS_8
;
327 printf("Invalid bus width: %d\n", dev
->bus_width
);
330 sdi_clkcr
&= ~(SDI_CLKCR_WIDBUS_MASK
);
331 sdi_clkcr
|= buswidth
;
334 writel(sdi_clkcr
, &host
->base
->clock
);
335 udelay(CLK_CHANGE_DELAY
);
339 * mmc_host_init - initialize the mmc controller.
340 * Set initial clock and power for mmc slot.
341 * Initialize mmc struct and register with mmc framework.
343 int arm_pl180_mmci_init(struct pl180_mmc_host
*host
)
348 dev
= malloc(sizeof(struct mmc
));
352 memset(dev
, 0, sizeof(struct mmc
));
355 writel(host
->pwr_init
, &host
->base
->power
);
356 writel(host
->clkdiv_init
, &host
->base
->clock
);
357 udelay(CLK_CHANGE_DELAY
);
359 /* Disable mmc interrupts */
360 sdi_u32
= readl(&host
->base
->mask0
) & ~SDI_MASK0_MASK
;
361 writel(sdi_u32
, &host
->base
->mask0
);
362 strncpy(dev
->name
, host
->name
, sizeof(dev
->name
));
363 dev
->send_cmd
= host_request
;
364 dev
->set_ios
= host_set_ios
;
365 dev
->init
= mmc_host_reset
;
368 dev
->host_caps
= host
->caps
;
369 dev
->voltages
= host
->voltages
;
370 dev
->f_min
= host
->clock_min
;
371 dev
->f_max
= host
->clock_max
;
372 dev
->b_max
= host
->b_max
;
374 debug("registered mmc interface number is:%d\n", dev
->block_dev
.dev
);