2 * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
4 * SPDX-License-Identifier: BSD-3-Clause
12 #include <arch_helpers.h>
13 #include <common/debug.h>
14 #include <drivers/delay_timer.h>
15 #include <drivers/mmc.h>
16 #include <drivers/synopsys/dw_mmc.h>
19 #define DWMMC_CTRL (0x00)
20 #define CTRL_IDMAC_EN (1 << 25)
21 #define CTRL_DMA_EN (1 << 5)
22 #define CTRL_INT_EN (1 << 4)
23 #define CTRL_DMA_RESET (1 << 2)
24 #define CTRL_FIFO_RESET (1 << 1)
25 #define CTRL_RESET (1 << 0)
26 #define CTRL_RESET_ALL (CTRL_DMA_RESET | CTRL_FIFO_RESET | \
29 #define DWMMC_PWREN (0x04)
30 #define DWMMC_CLKDIV (0x08)
31 #define DWMMC_CLKSRC (0x0c)
32 #define DWMMC_CLKENA (0x10)
33 #define DWMMC_TMOUT (0x14)
34 #define DWMMC_CTYPE (0x18)
35 #define CTYPE_8BIT (1 << 16)
36 #define CTYPE_4BIT (1)
37 #define CTYPE_1BIT (0)
39 #define DWMMC_BLKSIZ (0x1c)
40 #define DWMMC_BYTCNT (0x20)
41 #define DWMMC_INTMASK (0x24)
42 #define INT_EBE (1 << 15)
43 #define INT_SBE (1 << 13)
44 #define INT_HLE (1 << 12)
45 #define INT_FRUN (1 << 11)
46 #define INT_DRT (1 << 9)
47 #define INT_RTO (1 << 8)
48 #define INT_DCRC (1 << 7)
49 #define INT_RCRC (1 << 6)
50 #define INT_RXDR (1 << 5)
51 #define INT_TXDR (1 << 4)
52 #define INT_DTO (1 << 3)
53 #define INT_CMD_DONE (1 << 2)
54 #define INT_RE (1 << 1)
56 #define DWMMC_CMDARG (0x28)
57 #define DWMMC_CMD (0x2c)
58 #define CMD_START (1 << 31)
59 #define CMD_USE_HOLD_REG (1 << 29) /* 0 if SDR50/100 */
60 #define CMD_UPDATE_CLK_ONLY (1 << 21)
61 #define CMD_SEND_INIT (1 << 15)
62 #define CMD_STOP_ABORT_CMD (1 << 14)
63 #define CMD_WAIT_PRVDATA_COMPLETE (1 << 13)
64 #define CMD_WRITE (1 << 10)
65 #define CMD_DATA_TRANS_EXPECT (1 << 9)
66 #define CMD_CHECK_RESP_CRC (1 << 8)
67 #define CMD_RESP_LEN (1 << 7)
68 #define CMD_RESP_EXPECT (1 << 6)
69 #define CMD(x) (x & 0x3f)
71 #define DWMMC_RESP0 (0x30)
72 #define DWMMC_RESP1 (0x34)
73 #define DWMMC_RESP2 (0x38)
74 #define DWMMC_RESP3 (0x3c)
75 #define DWMMC_RINTSTS (0x44)
76 #define DWMMC_STATUS (0x48)
77 #define STATUS_DATA_BUSY (1 << 9)
79 #define DWMMC_FIFOTH (0x4c)
80 #define FIFOTH_TWMARK(x) (x & 0xfff)
81 #define FIFOTH_RWMARK(x) ((x & 0x1ff) << 16)
82 #define FIFOTH_DMA_BURST_SIZE(x) ((x & 0x7) << 28)
84 #define DWMMC_DEBNCE (0x64)
85 #define DWMMC_BMOD (0x80)
86 #define BMOD_ENABLE (1 << 7)
87 #define BMOD_FB (1 << 1)
88 #define BMOD_SWRESET (1 << 0)
90 #define DWMMC_DBADDR (0x88)
91 #define DWMMC_IDSTS (0x8c)
92 #define DWMMC_IDINTEN (0x90)
93 #define DWMMC_CARDTHRCTL (0x100)
94 #define CARDTHRCTL_RD_THR(x) ((x & 0xfff) << 16)
95 #define CARDTHRCTL_RD_THR_EN (1 << 0)
97 #define IDMAC_DES0_DIC (1 << 1)
98 #define IDMAC_DES0_LD (1 << 2)
99 #define IDMAC_DES0_FS (1 << 3)
100 #define IDMAC_DES0_CH (1 << 4)
101 #define IDMAC_DES0_ER (1 << 5)
102 #define IDMAC_DES0_CES (1 << 30)
103 #define IDMAC_DES0_OWN (1 << 31)
104 #define IDMAC_DES1_BS1(x) ((x) & 0x1fff)
105 #define IDMAC_DES2_BS2(x) (((x) & 0x1fff) << 13)
107 #define DWMMC_DMA_MAX_BUFFER_SIZE (512 * 8)
109 #define DWMMC_8BIT_MODE (1 << 6)
111 #define DWMMC_ADDRESS_MASK U(0x0f)
113 #define TIMEOUT 100000
115 struct dw_idmac_desc
{
122 static void dw_init(void);
123 static int dw_send_cmd(struct mmc_cmd
*cmd
);
124 static int dw_set_ios(unsigned int clk
, unsigned int width
);
125 static int dw_prepare(int lba
, uintptr_t buf
, size_t size
);
126 static int dw_read(int lba
, uintptr_t buf
, size_t size
);
127 static int dw_write(int lba
, uintptr_t buf
, size_t size
);
129 static const struct mmc_ops dw_mmc_ops
= {
131 .send_cmd
= dw_send_cmd
,
132 .set_ios
= dw_set_ios
,
133 .prepare
= dw_prepare
,
138 static dw_mmc_params_t dw_params
;
140 static void dw_update_clk(void)
144 mmio_write_32(dw_params
.reg_base
+ DWMMC_CMD
,
145 CMD_WAIT_PRVDATA_COMPLETE
| CMD_UPDATE_CLK_ONLY
|
148 data
= mmio_read_32(dw_params
.reg_base
+ DWMMC_CMD
);
149 if ((data
& CMD_START
) == 0)
151 data
= mmio_read_32(dw_params
.reg_base
+ DWMMC_RINTSTS
);
152 assert((data
& INT_HLE
) == 0);
156 static void dw_set_clk(int clk
)
163 for (div
= 1; div
< 256; div
++) {
164 if ((dw_params
.clk_rate
/ (2 * div
)) <= clk
) {
170 /* wait until controller is idle */
172 data
= mmio_read_32(dw_params
.reg_base
+ DWMMC_STATUS
);
173 } while (data
& STATUS_DATA_BUSY
);
175 /* disable clock before change clock rate */
176 mmio_write_32(dw_params
.reg_base
+ DWMMC_CLKENA
, 0);
179 mmio_write_32(dw_params
.reg_base
+ DWMMC_CLKDIV
, div
);
183 mmio_write_32(dw_params
.reg_base
+ DWMMC_CLKENA
, 1);
184 mmio_write_32(dw_params
.reg_base
+ DWMMC_CLKSRC
, 0);
188 static void dw_init(void)
193 assert((dw_params
.reg_base
& MMC_BLOCK_MASK
) == 0);
195 base
= dw_params
.reg_base
;
196 mmio_write_32(base
+ DWMMC_PWREN
, 1);
197 mmio_write_32(base
+ DWMMC_CTRL
, CTRL_RESET_ALL
);
199 data
= mmio_read_32(base
+ DWMMC_CTRL
);
202 /* enable DMA in CTRL */
203 data
= CTRL_INT_EN
| CTRL_DMA_EN
| CTRL_IDMAC_EN
;
204 mmio_write_32(base
+ DWMMC_CTRL
, data
);
205 mmio_write_32(base
+ DWMMC_RINTSTS
, ~0);
206 mmio_write_32(base
+ DWMMC_INTMASK
, 0);
207 mmio_write_32(base
+ DWMMC_TMOUT
, ~0);
208 mmio_write_32(base
+ DWMMC_IDINTEN
, ~0);
209 mmio_write_32(base
+ DWMMC_BLKSIZ
, MMC_BLOCK_SIZE
);
210 mmio_write_32(base
+ DWMMC_BYTCNT
, 256 * 1024);
211 mmio_write_32(base
+ DWMMC_DEBNCE
, 0x00ffffff);
212 mmio_write_32(base
+ DWMMC_BMOD
, BMOD_SWRESET
);
214 data
= mmio_read_32(base
+ DWMMC_BMOD
);
215 } while (data
& BMOD_SWRESET
);
216 /* enable DMA in BMOD */
217 data
|= BMOD_ENABLE
| BMOD_FB
;
218 mmio_write_32(base
+ DWMMC_BMOD
, data
);
221 dw_set_clk(MMC_BOOT_CLK_RATE
);
225 static int dw_send_cmd(struct mmc_cmd
*cmd
)
227 unsigned int op
, data
, err_mask
;
233 base
= dw_params
.reg_base
;
235 switch (cmd
->cmd_idx
) {
240 op
= CMD_STOP_ABORT_CMD
;
243 op
= CMD_WAIT_PRVDATA_COMPLETE
;
248 op
= CMD_DATA_TRANS_EXPECT
| CMD_WAIT_PRVDATA_COMPLETE
;
252 op
= CMD_WRITE
| CMD_DATA_TRANS_EXPECT
|
253 CMD_WAIT_PRVDATA_COMPLETE
;
259 op
|= CMD_USE_HOLD_REG
| CMD_START
;
260 switch (cmd
->resp_type
) {
263 case MMC_RESPONSE_R2
:
264 op
|= CMD_RESP_EXPECT
| CMD_CHECK_RESP_CRC
|
267 case MMC_RESPONSE_R3
:
268 op
|= CMD_RESP_EXPECT
;
271 op
|= CMD_RESP_EXPECT
| CMD_CHECK_RESP_CRC
;
276 data
= mmio_read_32(base
+ DWMMC_STATUS
);
279 } while (data
& STATUS_DATA_BUSY
);
281 mmio_write_32(base
+ DWMMC_RINTSTS
, ~0);
282 mmio_write_32(base
+ DWMMC_CMDARG
, cmd
->cmd_arg
);
283 mmio_write_32(base
+ DWMMC_CMD
, op
| cmd
->cmd_idx
);
285 err_mask
= INT_EBE
| INT_HLE
| INT_RTO
| INT_RCRC
| INT_RE
|
286 INT_DCRC
| INT_DRT
| INT_SBE
;
290 data
= mmio_read_32(base
+ DWMMC_RINTSTS
);
296 if (--timeout
== 0) {
297 ERROR("%s, RINTSTS:0x%x\n", __func__
, data
);
300 } while (!(data
& INT_CMD_DONE
));
302 if (op
& CMD_RESP_EXPECT
) {
303 cmd
->resp_data
[0] = mmio_read_32(base
+ DWMMC_RESP0
);
304 if (op
& CMD_RESP_LEN
) {
305 cmd
->resp_data
[1] = mmio_read_32(base
+ DWMMC_RESP1
);
306 cmd
->resp_data
[2] = mmio_read_32(base
+ DWMMC_RESP2
);
307 cmd
->resp_data
[3] = mmio_read_32(base
+ DWMMC_RESP3
);
313 static int dw_set_ios(unsigned int clk
, unsigned int width
)
316 case MMC_BUS_WIDTH_1
:
317 mmio_write_32(dw_params
.reg_base
+ DWMMC_CTYPE
, CTYPE_1BIT
);
319 case MMC_BUS_WIDTH_4
:
320 mmio_write_32(dw_params
.reg_base
+ DWMMC_CTYPE
, CTYPE_4BIT
);
322 case MMC_BUS_WIDTH_8
:
323 mmio_write_32(dw_params
.reg_base
+ DWMMC_CTYPE
, CTYPE_8BIT
);
333 static int dw_prepare(int lba
, uintptr_t buf
, size_t size
)
335 struct dw_idmac_desc
*desc
;
336 int desc_cnt
, i
, last
;
339 assert(((buf
& DWMMC_ADDRESS_MASK
) == 0) &&
340 ((size
% MMC_BLOCK_SIZE
) == 0) &&
341 (dw_params
.desc_size
> 0) &&
342 ((dw_params
.reg_base
& MMC_BLOCK_MASK
) == 0) &&
343 ((dw_params
.desc_base
& MMC_BLOCK_MASK
) == 0) &&
344 ((dw_params
.desc_size
& MMC_BLOCK_MASK
) == 0));
346 flush_dcache_range(buf
, size
);
348 desc_cnt
= (size
+ DWMMC_DMA_MAX_BUFFER_SIZE
- 1) /
349 DWMMC_DMA_MAX_BUFFER_SIZE
;
350 assert(desc_cnt
* sizeof(struct dw_idmac_desc
) < dw_params
.desc_size
);
352 base
= dw_params
.reg_base
;
353 desc
= (struct dw_idmac_desc
*)dw_params
.desc_base
;
354 mmio_write_32(base
+ DWMMC_BYTCNT
, size
);
355 mmio_write_32(base
+ DWMMC_RINTSTS
, ~0);
356 for (i
= 0; i
< desc_cnt
; i
++) {
357 desc
[i
].des0
= IDMAC_DES0_OWN
| IDMAC_DES0_CH
| IDMAC_DES0_DIC
;
358 desc
[i
].des1
= IDMAC_DES1_BS1(DWMMC_DMA_MAX_BUFFER_SIZE
);
359 desc
[i
].des2
= buf
+ DWMMC_DMA_MAX_BUFFER_SIZE
* i
;
360 desc
[i
].des3
= dw_params
.desc_base
+
361 (sizeof(struct dw_idmac_desc
)) * (i
+ 1);
363 /* first descriptor */
364 desc
->des0
|= IDMAC_DES0_FS
;
365 /* last descriptor */
367 (desc
+ last
)->des0
|= IDMAC_DES0_LD
;
368 (desc
+ last
)->des0
&= ~(IDMAC_DES0_DIC
| IDMAC_DES0_CH
);
369 (desc
+ last
)->des1
= IDMAC_DES1_BS1(size
- (last
*
370 DWMMC_DMA_MAX_BUFFER_SIZE
));
371 /* set next descriptor address as 0 */
372 (desc
+ last
)->des3
= 0;
374 mmio_write_32(base
+ DWMMC_DBADDR
, dw_params
.desc_base
);
375 flush_dcache_range(dw_params
.desc_base
,
376 desc_cnt
* DWMMC_DMA_MAX_BUFFER_SIZE
);
381 static int dw_read(int lba
, uintptr_t buf
, size_t size
)
386 static int dw_write(int lba
, uintptr_t buf
, size_t size
)
391 void dw_mmc_init(dw_mmc_params_t
*params
, struct mmc_device_info
*info
)
393 assert((params
!= 0) &&
394 ((params
->reg_base
& MMC_BLOCK_MASK
) == 0) &&
395 ((params
->desc_base
& MMC_BLOCK_MASK
) == 0) &&
396 ((params
->desc_size
& MMC_BLOCK_MASK
) == 0) &&
397 (params
->desc_size
> 0) &&
398 (params
->clk_rate
> 0) &&
399 ((params
->bus_width
== MMC_BUS_WIDTH_1
) ||
400 (params
->bus_width
== MMC_BUS_WIDTH_4
) ||
401 (params
->bus_width
== MMC_BUS_WIDTH_8
)));
403 memcpy(&dw_params
, params
, sizeof(dw_mmc_params_t
));
404 mmc_init(&dw_mmc_ops
, params
->clk_rate
, params
->bus_width
,
405 params
->flags
, info
);