1 /*
2 * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <arch.h>
8 #include <arch_helpers.h>
9 #include <assert.h>
10 #include <debug.h>
11 #include <delay_timer.h>
12 #include <dw_mmc.h>
13 #include <emmc.h>
14 #include <errno.h>
15 #include <mmio.h>
16 #include <string.h>
17
18 #define DWMMC_CTRL (0x00)
19 #define CTRL_IDMAC_EN (1 << 25)
20 #define CTRL_DMA_EN (1 << 5)
21 #define CTRL_INT_EN (1 << 4)
22 #define CTRL_DMA_RESET (1 << 2)
23 #define CTRL_FIFO_RESET (1 << 1)
24 #define CTRL_RESET (1 << 0)
25 #define CTRL_RESET_ALL (CTRL_DMA_RESET | CTRL_FIFO_RESET | \
26 CTRL_RESET)
27
28 #define DWMMC_PWREN (0x04)
29 #define DWMMC_CLKDIV (0x08)
30 #define DWMMC_CLKSRC (0x0c)
31 #define DWMMC_CLKENA (0x10)
32 #define DWMMC_TMOUT (0x14)
33 #define DWMMC_CTYPE (0x18)
34 #define CTYPE_8BIT (1 << 16)
35 #define CTYPE_4BIT (1)
36 #define CTYPE_1BIT (0)
37
38 #define DWMMC_BLKSIZ (0x1c)
39 #define DWMMC_BYTCNT (0x20)
40 #define DWMMC_INTMASK (0x24)
41 #define INT_EBE (1 << 15)
42 #define INT_SBE (1 << 13)
43 #define INT_HLE (1 << 12)
44 #define INT_FRUN (1 << 11)
45 #define INT_DRT (1 << 9)
46 #define INT_RTO (1 << 8)
47 #define INT_DCRC (1 << 7)
48 #define INT_RCRC (1 << 6)
49 #define INT_RXDR (1 << 5)
50 #define INT_TXDR (1 << 4)
51 #define INT_DTO (1 << 3)
52 #define INT_CMD_DONE (1 << 2)
53 #define INT_RE (1 << 1)
54
55 #define DWMMC_CMDARG (0x28)
56 #define DWMMC_CMD (0x2c)
57 #define CMD_START (1 << 31)
58 #define CMD_USE_HOLD_REG (1 << 29) /* 0 if SDR50/100 */
59 #define CMD_UPDATE_CLK_ONLY (1 << 21)
60 #define CMD_SEND_INIT (1 << 15)
61 #define CMD_STOP_ABORT_CMD (1 << 14)
62 #define CMD_WAIT_PRVDATA_COMPLETE (1 << 13)
63 #define CMD_WRITE (1 << 10)
64 #define CMD_DATA_TRANS_EXPECT (1 << 9)
65 #define CMD_CHECK_RESP_CRC (1 << 8)
66 #define CMD_RESP_LEN (1 << 7)
67 #define CMD_RESP_EXPECT (1 << 6)
68 #define CMD(x) (x & 0x3f)
69
70 #define DWMMC_RESP0 (0x30)
71 #define DWMMC_RESP1 (0x34)
72 #define DWMMC_RESP2 (0x38)
73 #define DWMMC_RESP3 (0x3c)
74 #define DWMMC_RINTSTS (0x44)
75 #define DWMMC_STATUS (0x48)
76 #define STATUS_DATA_BUSY (1 << 9)
77
78 #define DWMMC_FIFOTH (0x4c)
79 #define FIFOTH_TWMARK(x) (x & 0xfff)
80 #define FIFOTH_RWMARK(x) ((x & 0x1ff) << 16)
81 #define FIFOTH_DMA_BURST_SIZE(x) ((x & 0x7) << 28)
82
83 #define DWMMC_DEBNCE (0x64)
84 #define DWMMC_BMOD (0x80)
85 #define BMOD_ENABLE (1 << 7)
86 #define BMOD_FB (1 << 1)
87 #define BMOD_SWRESET (1 << 0)
88
89 #define DWMMC_DBADDR (0x88)
90 #define DWMMC_IDSTS (0x8c)
91 #define DWMMC_IDINTEN (0x90)
92 #define DWMMC_CARDTHRCTL (0x100)
93 #define CARDTHRCTL_RD_THR(x) ((x & 0xfff) << 16)
94 #define CARDTHRCTL_RD_THR_EN (1 << 0)
95
96 #define IDMAC_DES0_DIC (1 << 1)
97 #define IDMAC_DES0_LD (1 << 2)
98 #define IDMAC_DES0_FS (1 << 3)
99 #define IDMAC_DES0_CH (1 << 4)
100 #define IDMAC_DES0_ER (1 << 5)
101 #define IDMAC_DES0_CES (1 << 30)
102 #define IDMAC_DES0_OWN (1 << 31)
103 #define IDMAC_DES1_BS1(x) ((x) & 0x1fff)
104 #define IDMAC_DES2_BS2(x) (((x) & 0x1fff) << 13)
105
106 #define DWMMC_DMA_MAX_BUFFER_SIZE (512 * 8)
107
108 #define DWMMC_8BIT_MODE (1 << 6)
109
110 #define TIMEOUT 100000
111
112 struct dw_idmac_desc {
113 unsigned int des0;
114 unsigned int des1;
115 unsigned int des2;
116 unsigned int des3;
117 };
118
119 static void dw_init(void);
120 static int dw_send_cmd(emmc_cmd_t *cmd);
121 static int dw_set_ios(int clk, int width);
122 static int dw_prepare(int lba, uintptr_t buf, size_t size);
123 static int dw_read(int lba, uintptr_t buf, size_t size);
124 static int dw_write(int lba, uintptr_t buf, size_t size);
125
126 static const emmc_ops_t dw_mmc_ops = {
127 .init = dw_init,
128 .send_cmd = dw_send_cmd,
129 .set_ios = dw_set_ios,
130 .prepare = dw_prepare,
131 .read = dw_read,
132 .write = dw_write,
133 };
134
135 static dw_mmc_params_t dw_params;
136
dw_update_clk(void)137 static void dw_update_clk(void)
138 {
139 unsigned int data;
140
141 mmio_write_32(dw_params.reg_base + DWMMC_CMD,
142 CMD_WAIT_PRVDATA_COMPLETE | CMD_UPDATE_CLK_ONLY |
143 CMD_START);
144 while (1) {
145 data = mmio_read_32(dw_params.reg_base + DWMMC_CMD);
146 if ((data & CMD_START) == 0)
147 break;
148 data = mmio_read_32(dw_params.reg_base + DWMMC_RINTSTS);
149 assert(data & INT_HLE);
150 }
151 }
152
dw_set_clk(int clk)153 static void dw_set_clk(int clk)
154 {
155 unsigned int data;
156 int div;
157
158 assert(clk > 0);
159
160 for (div = 1; div < 256; div++) {
161 if ((dw_params.clk_rate / (2 * div)) <= clk) {
162 break;
163 }
164 }
165 assert(div < 256);
166
167 /* wait until controller is idle */
168 do {
169 data = mmio_read_32(dw_params.reg_base + DWMMC_STATUS);
170 } while (data & STATUS_DATA_BUSY);
171
172 /* disable clock before change clock rate */
173 mmio_write_32(dw_params.reg_base + DWMMC_CLKENA, 0);
174 dw_update_clk();
175
176 mmio_write_32(dw_params.reg_base + DWMMC_CLKDIV, div);
177 dw_update_clk();
178
179 /* enable clock */
180 mmio_write_32(dw_params.reg_base + DWMMC_CLKENA, 1);
181 mmio_write_32(dw_params.reg_base + DWMMC_CLKSRC, 0);
182 dw_update_clk();
183 }
184
dw_init(void)185 static void dw_init(void)
186 {
187 unsigned int data;
188 uintptr_t base;
189
190 assert((dw_params.reg_base & EMMC_BLOCK_MASK) == 0);
191
192 base = dw_params.reg_base;
193 mmio_write_32(base + DWMMC_PWREN, 1);
194 mmio_write_32(base + DWMMC_CTRL, CTRL_RESET_ALL);
195 do {
196 data = mmio_read_32(base + DWMMC_CTRL);
197 } while (data);
198
199 /* enable DMA in CTRL */
200 data = CTRL_INT_EN | CTRL_DMA_EN | CTRL_IDMAC_EN;
201 mmio_write_32(base + DWMMC_CTRL, data);
202 mmio_write_32(base + DWMMC_RINTSTS, ~0);
203 mmio_write_32(base + DWMMC_INTMASK, 0);
204 mmio_write_32(base + DWMMC_TMOUT, ~0);
205 mmio_write_32(base + DWMMC_IDINTEN, ~0);
206 mmio_write_32(base + DWMMC_BLKSIZ, EMMC_BLOCK_SIZE);
207 mmio_write_32(base + DWMMC_BYTCNT, 256 * 1024);
208 mmio_write_32(base + DWMMC_DEBNCE, 0x00ffffff);
209 mmio_write_32(base + DWMMC_BMOD, BMOD_SWRESET);
210 do {
211 data = mmio_read_32(base + DWMMC_BMOD);
212 } while (data & BMOD_SWRESET);
213 /* enable DMA in BMOD */
214 data |= BMOD_ENABLE | BMOD_FB;
215 mmio_write_32(base + DWMMC_BMOD, data);
216
217 udelay(100);
218 dw_set_clk(EMMC_BOOT_CLK_RATE);
219 udelay(100);
220 }
221
dw_send_cmd(emmc_cmd_t * cmd)222 static int dw_send_cmd(emmc_cmd_t *cmd)
223 {
224 unsigned int op, data, err_mask;
225 uintptr_t base;
226 int timeout;
227
228 assert(cmd);
229
230 base = dw_params.reg_base;
231
232 switch (cmd->cmd_idx) {
233 case EMMC_CMD0:
234 op = CMD_SEND_INIT;
235 break;
236 case EMMC_CMD12:
237 op = CMD_STOP_ABORT_CMD;
238 break;
239 case EMMC_CMD13:
240 op = CMD_WAIT_PRVDATA_COMPLETE;
241 break;
242 case EMMC_CMD8:
243 case EMMC_CMD17:
244 case EMMC_CMD18:
245 op = CMD_DATA_TRANS_EXPECT | CMD_WAIT_PRVDATA_COMPLETE;
246 break;
247 case EMMC_CMD24:
248 case EMMC_CMD25:
249 op = CMD_WRITE | CMD_DATA_TRANS_EXPECT |
250 CMD_WAIT_PRVDATA_COMPLETE;
251 break;
252 default:
253 op = 0;
254 break;
255 }
256 op |= CMD_USE_HOLD_REG | CMD_START;
257 switch (cmd->resp_type) {
258 case 0:
259 break;
260 case EMMC_RESPONSE_R2:
261 op |= CMD_RESP_EXPECT | CMD_CHECK_RESP_CRC |
262 CMD_RESP_LEN;
263 break;
264 case EMMC_RESPONSE_R3:
265 op |= CMD_RESP_EXPECT;
266 break;
267 default:
268 op |= CMD_RESP_EXPECT | CMD_CHECK_RESP_CRC;
269 break;
270 }
271 timeout = TIMEOUT;
272 do {
273 data = mmio_read_32(base + DWMMC_STATUS);
274 if (--timeout <= 0)
275 panic();
276 } while (data & STATUS_DATA_BUSY);
277
278 mmio_write_32(base + DWMMC_RINTSTS, ~0);
279 mmio_write_32(base + DWMMC_CMDARG, cmd->cmd_arg);
280 mmio_write_32(base + DWMMC_CMD, op | cmd->cmd_idx);
281
282 err_mask = INT_EBE | INT_HLE | INT_RTO | INT_RCRC | INT_RE |
283 INT_DCRC | INT_DRT | INT_SBE;
284 timeout = TIMEOUT;
285 do {
286 udelay(500);
287 data = mmio_read_32(base + DWMMC_RINTSTS);
288
289 if (data & err_mask)
290 return -EIO;
291 if (data & INT_DTO)
292 break;
293 if (--timeout == 0) {
294 ERROR("%s, RINTSTS:0x%x\n", __func__, data);
295 panic();
296 }
297 } while (!(data & INT_CMD_DONE));
298
299 if (op & CMD_RESP_EXPECT) {
300 cmd->resp_data[0] = mmio_read_32(base + DWMMC_RESP0);
301 if (op & CMD_RESP_LEN) {
302 cmd->resp_data[1] = mmio_read_32(base + DWMMC_RESP1);
303 cmd->resp_data[2] = mmio_read_32(base + DWMMC_RESP2);
304 cmd->resp_data[3] = mmio_read_32(base + DWMMC_RESP3);
305 }
306 }
307 return 0;
308 }
309
dw_set_ios(int clk,int width)310 static int dw_set_ios(int clk, int width)
311 {
312 switch (width) {
313 case EMMC_BUS_WIDTH_1:
314 mmio_write_32(dw_params.reg_base + DWMMC_CTYPE, CTYPE_1BIT);
315 break;
316 case EMMC_BUS_WIDTH_4:
317 mmio_write_32(dw_params.reg_base + DWMMC_CTYPE, CTYPE_4BIT);
318 break;
319 case EMMC_BUS_WIDTH_8:
320 mmio_write_32(dw_params.reg_base + DWMMC_CTYPE, CTYPE_8BIT);
321 break;
322 default:
323 assert(0);
324 }
325 dw_set_clk(clk);
326 return 0;
327 }
328
dw_prepare(int lba,uintptr_t buf,size_t size)329 static int dw_prepare(int lba, uintptr_t buf, size_t size)
330 {
331 struct dw_idmac_desc *desc;
332 int desc_cnt, i, last;
333 uintptr_t base;
334
335 assert(((buf & EMMC_BLOCK_MASK) == 0) &&
336 ((size % EMMC_BLOCK_SIZE) == 0) &&
337 (dw_params.desc_size > 0) &&
338 ((dw_params.reg_base & EMMC_BLOCK_MASK) == 0) &&
339 ((dw_params.desc_base & EMMC_BLOCK_MASK) == 0) &&
340 ((dw_params.desc_size & EMMC_BLOCK_MASK) == 0));
341
342 desc_cnt = (size + DWMMC_DMA_MAX_BUFFER_SIZE - 1) /
343 DWMMC_DMA_MAX_BUFFER_SIZE;
344 assert(desc_cnt * sizeof(struct dw_idmac_desc) < dw_params.desc_size);
345
346 base = dw_params.reg_base;
347 desc = (struct dw_idmac_desc *)dw_params.desc_base;
348 mmio_write_32(base + DWMMC_BYTCNT, size);
349 mmio_write_32(base + DWMMC_RINTSTS, ~0);
350 for (i = 0; i < desc_cnt; i++) {
351 desc[i].des0 = IDMAC_DES0_OWN | IDMAC_DES0_CH | IDMAC_DES0_DIC;
352 desc[i].des1 = IDMAC_DES1_BS1(DWMMC_DMA_MAX_BUFFER_SIZE);
353 desc[i].des2 = buf + DWMMC_DMA_MAX_BUFFER_SIZE * i;
354 desc[i].des3 = dw_params.desc_base +
355 (sizeof(struct dw_idmac_desc)) * (i + 1);
356 }
357 /* first descriptor */
358 desc->des0 |= IDMAC_DES0_FS;
359 /* last descriptor */
360 last = desc_cnt - 1;
361 (desc + last)->des0 |= IDMAC_DES0_LD;
362 (desc + last)->des0 &= ~(IDMAC_DES0_DIC | IDMAC_DES0_CH);
363 (desc + last)->des1 = IDMAC_DES1_BS1(size - (last *
364 DWMMC_DMA_MAX_BUFFER_SIZE));
365 /* set next descriptor address as 0 */
366 (desc + last)->des3 = 0;
367
368 mmio_write_32(base + DWMMC_DBADDR, dw_params.desc_base);
369 clean_dcache_range(dw_params.desc_base,
370 desc_cnt * DWMMC_DMA_MAX_BUFFER_SIZE);
371
372 return 0;
373 }
374
dw_read(int lba,uintptr_t buf,size_t size)375 static int dw_read(int lba, uintptr_t buf, size_t size)
376 {
377 return 0;
378 }
379
dw_write(int lba,uintptr_t buf,size_t size)380 static int dw_write(int lba, uintptr_t buf, size_t size)
381 {
382 return 0;
383 }
384
dw_mmc_init(dw_mmc_params_t * params)385 void dw_mmc_init(dw_mmc_params_t *params)
386 {
387 assert((params != 0) &&
388 ((params->reg_base & EMMC_BLOCK_MASK) == 0) &&
389 ((params->desc_base & EMMC_BLOCK_MASK) == 0) &&
390 ((params->desc_size & EMMC_BLOCK_MASK) == 0) &&
391 (params->desc_size > 0) &&
392 (params->clk_rate > 0) &&
393 ((params->bus_width == EMMC_BUS_WIDTH_1) ||
394 (params->bus_width == EMMC_BUS_WIDTH_4) ||
395 (params->bus_width == EMMC_BUS_WIDTH_8)));
396
397 memcpy(&dw_params, params, sizeof(dw_mmc_params_t));
398 emmc_init(&dw_mmc_ops, params->clk_rate, params->bus_width,
399 params->flags);
400 }
401