xref: /rk3399_ARM-atf/drivers/synopsys/emmc/dw_mmc.c (revision 091f39675a98ee9e22ed78f52e239880bedf8911)
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 <errno.h>
14 #include <mmc.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 DWMMC_ADDRESS_MASK		U(0x0f)
111 
112 #define TIMEOUT				100000
113 
114 struct dw_idmac_desc {
115 	unsigned int	des0;
116 	unsigned int	des1;
117 	unsigned int	des2;
118 	unsigned int	des3;
119 };
120 
121 static void dw_init(void);
122 static int dw_send_cmd(struct mmc_cmd *cmd);
123 static int dw_set_ios(unsigned int clk, unsigned int width);
124 static int dw_prepare(int lba, uintptr_t buf, size_t size);
125 static int dw_read(int lba, uintptr_t buf, size_t size);
126 static int dw_write(int lba, uintptr_t buf, size_t size);
127 
128 static const struct mmc_ops dw_mmc_ops = {
129 	.init		= dw_init,
130 	.send_cmd	= dw_send_cmd,
131 	.set_ios	= dw_set_ios,
132 	.prepare	= dw_prepare,
133 	.read		= dw_read,
134 	.write		= dw_write,
135 };
136 
137 static dw_mmc_params_t dw_params;
138 
139 static void dw_update_clk(void)
140 {
141 	unsigned int data;
142 
143 	mmio_write_32(dw_params.reg_base + DWMMC_CMD,
144 		      CMD_WAIT_PRVDATA_COMPLETE | CMD_UPDATE_CLK_ONLY |
145 		      CMD_START);
146 	while (1) {
147 		data = mmio_read_32(dw_params.reg_base + DWMMC_CMD);
148 		if ((data & CMD_START) == 0)
149 			break;
150 		data = mmio_read_32(dw_params.reg_base + DWMMC_RINTSTS);
151 		assert((data & INT_HLE) == 0);
152 	}
153 }
154 
155 static void dw_set_clk(int clk)
156 {
157 	unsigned int data;
158 	int div;
159 
160 	assert(clk > 0);
161 
162 	for (div = 1; div < 256; div++) {
163 		if ((dw_params.clk_rate / (2 * div)) <= clk) {
164 			break;
165 		}
166 	}
167 	assert(div < 256);
168 
169 	/* wait until controller is idle */
170 	do {
171 		data = mmio_read_32(dw_params.reg_base + DWMMC_STATUS);
172 	} while (data & STATUS_DATA_BUSY);
173 
174 	/* disable clock before change clock rate */
175 	mmio_write_32(dw_params.reg_base + DWMMC_CLKENA, 0);
176 	dw_update_clk();
177 
178 	mmio_write_32(dw_params.reg_base + DWMMC_CLKDIV, div);
179 	dw_update_clk();
180 
181 	/* enable clock */
182 	mmio_write_32(dw_params.reg_base + DWMMC_CLKENA, 1);
183 	mmio_write_32(dw_params.reg_base + DWMMC_CLKSRC, 0);
184 	dw_update_clk();
185 }
186 
187 static void dw_init(void)
188 {
189 	unsigned int data;
190 	uintptr_t base;
191 
192 	assert((dw_params.reg_base & MMC_BLOCK_MASK) == 0);
193 
194 	base = dw_params.reg_base;
195 	mmio_write_32(base + DWMMC_PWREN, 1);
196 	mmio_write_32(base + DWMMC_CTRL, CTRL_RESET_ALL);
197 	do {
198 		data = mmio_read_32(base + DWMMC_CTRL);
199 	} while (data);
200 
201 	/* enable DMA in CTRL */
202 	data = CTRL_INT_EN | CTRL_DMA_EN | CTRL_IDMAC_EN;
203 	mmio_write_32(base + DWMMC_CTRL, data);
204 	mmio_write_32(base + DWMMC_RINTSTS, ~0);
205 	mmio_write_32(base + DWMMC_INTMASK, 0);
206 	mmio_write_32(base + DWMMC_TMOUT, ~0);
207 	mmio_write_32(base + DWMMC_IDINTEN, ~0);
208 	mmio_write_32(base + DWMMC_BLKSIZ, MMC_BLOCK_SIZE);
209 	mmio_write_32(base + DWMMC_BYTCNT, 256 * 1024);
210 	mmio_write_32(base + DWMMC_DEBNCE, 0x00ffffff);
211 	mmio_write_32(base + DWMMC_BMOD, BMOD_SWRESET);
212 	do {
213 		data = mmio_read_32(base + DWMMC_BMOD);
214 	} while (data & BMOD_SWRESET);
215 	/* enable DMA in BMOD */
216 	data |= BMOD_ENABLE | BMOD_FB;
217 	mmio_write_32(base + DWMMC_BMOD, data);
218 
219 	udelay(100);
220 	dw_set_clk(MMC_BOOT_CLK_RATE);
221 	udelay(100);
222 }
223 
224 static int dw_send_cmd(struct mmc_cmd *cmd)
225 {
226 	unsigned int op, data, err_mask;
227 	uintptr_t base;
228 	int timeout;
229 
230 	assert(cmd);
231 
232 	base = dw_params.reg_base;
233 
234 	switch (cmd->cmd_idx) {
235 	case 0:
236 		op = CMD_SEND_INIT;
237 		break;
238 	case 12:
239 		op = CMD_STOP_ABORT_CMD;
240 		break;
241 	case 13:
242 		op = CMD_WAIT_PRVDATA_COMPLETE;
243 		break;
244 	case 8:
245 	case 17:
246 	case 18:
247 		op = CMD_DATA_TRANS_EXPECT | CMD_WAIT_PRVDATA_COMPLETE;
248 		break;
249 	case 24:
250 	case 25:
251 		op = CMD_WRITE | CMD_DATA_TRANS_EXPECT |
252 		     CMD_WAIT_PRVDATA_COMPLETE;
253 		break;
254 	default:
255 		op = 0;
256 		break;
257 	}
258 	op |= CMD_USE_HOLD_REG | CMD_START;
259 	switch (cmd->resp_type) {
260 	case 0:
261 		break;
262 	case MMC_RESPONSE_R(2):
263 		op |= CMD_RESP_EXPECT | CMD_CHECK_RESP_CRC |
264 		      CMD_RESP_LEN;
265 		break;
266 	case MMC_RESPONSE_R(3):
267 		op |= CMD_RESP_EXPECT;
268 		break;
269 	default:
270 		op |= CMD_RESP_EXPECT | CMD_CHECK_RESP_CRC;
271 		break;
272 	}
273 	timeout = TIMEOUT;
274 	do {
275 		data = mmio_read_32(base + DWMMC_STATUS);
276 		if (--timeout <= 0)
277 			panic();
278 	} while (data & STATUS_DATA_BUSY);
279 
280 	mmio_write_32(base + DWMMC_RINTSTS, ~0);
281 	mmio_write_32(base + DWMMC_CMDARG, cmd->cmd_arg);
282 	mmio_write_32(base + DWMMC_CMD, op | cmd->cmd_idx);
283 
284 	err_mask = INT_EBE | INT_HLE | INT_RTO | INT_RCRC | INT_RE |
285 		   INT_DCRC | INT_DRT | INT_SBE;
286 	timeout = TIMEOUT;
287 	do {
288 		udelay(500);
289 		data = mmio_read_32(base + DWMMC_RINTSTS);
290 
291 		if (data & err_mask)
292 			return -EIO;
293 		if (data & INT_DTO)
294 			break;
295 		if (--timeout == 0) {
296 			ERROR("%s, RINTSTS:0x%x\n", __func__, data);
297 			panic();
298 		}
299 	} while (!(data & INT_CMD_DONE));
300 
301 	if (op & CMD_RESP_EXPECT) {
302 		cmd->resp_data[0] = mmio_read_32(base + DWMMC_RESP0);
303 		if (op & CMD_RESP_LEN) {
304 			cmd->resp_data[1] = mmio_read_32(base + DWMMC_RESP1);
305 			cmd->resp_data[2] = mmio_read_32(base + DWMMC_RESP2);
306 			cmd->resp_data[3] = mmio_read_32(base + DWMMC_RESP3);
307 		}
308 	}
309 	return 0;
310 }
311 
312 static int dw_set_ios(unsigned int clk, unsigned int width)
313 {
314 	switch (width) {
315 	case MMC_BUS_WIDTH_1:
316 		mmio_write_32(dw_params.reg_base + DWMMC_CTYPE, CTYPE_1BIT);
317 		break;
318 	case MMC_BUS_WIDTH_4:
319 		mmio_write_32(dw_params.reg_base + DWMMC_CTYPE, CTYPE_4BIT);
320 		break;
321 	case MMC_BUS_WIDTH_8:
322 		mmio_write_32(dw_params.reg_base + DWMMC_CTYPE, CTYPE_8BIT);
323 		break;
324 	default:
325 		assert(0);
326 		break;
327 	}
328 	dw_set_clk(clk);
329 	return 0;
330 }
331 
332 static int dw_prepare(int lba, uintptr_t buf, size_t size)
333 {
334 	struct dw_idmac_desc *desc;
335 	int desc_cnt, i, last;
336 	uintptr_t base;
337 
338 	assert(((buf & DWMMC_ADDRESS_MASK) == 0) &&
339 	       ((size % MMC_BLOCK_SIZE) == 0) &&
340 	       (dw_params.desc_size > 0) &&
341 	       ((dw_params.reg_base & MMC_BLOCK_MASK) == 0) &&
342 	       ((dw_params.desc_base & MMC_BLOCK_MASK) == 0) &&
343 	       ((dw_params.desc_size & MMC_BLOCK_MASK) == 0));
344 
345 	flush_dcache_range(buf, size);
346 
347 	desc_cnt = (size + DWMMC_DMA_MAX_BUFFER_SIZE - 1) /
348 		   DWMMC_DMA_MAX_BUFFER_SIZE;
349 	assert(desc_cnt * sizeof(struct dw_idmac_desc) < dw_params.desc_size);
350 
351 	base = dw_params.reg_base;
352 	desc = (struct dw_idmac_desc *)dw_params.desc_base;
353 	mmio_write_32(base + DWMMC_BYTCNT, size);
354 	mmio_write_32(base + DWMMC_RINTSTS, ~0);
355 	for (i = 0; i < desc_cnt; i++) {
356 		desc[i].des0 = IDMAC_DES0_OWN | IDMAC_DES0_CH | IDMAC_DES0_DIC;
357 		desc[i].des1 = IDMAC_DES1_BS1(DWMMC_DMA_MAX_BUFFER_SIZE);
358 		desc[i].des2 = buf + DWMMC_DMA_MAX_BUFFER_SIZE * i;
359 		desc[i].des3 = dw_params.desc_base +
360 			       (sizeof(struct dw_idmac_desc)) * (i + 1);
361 	}
362 	/* first descriptor */
363 	desc->des0 |= IDMAC_DES0_FS;
364 	/* last descriptor */
365 	last = desc_cnt - 1;
366 	(desc + last)->des0 |= IDMAC_DES0_LD;
367 	(desc + last)->des0 &= ~(IDMAC_DES0_DIC | IDMAC_DES0_CH);
368 	(desc + last)->des1 = IDMAC_DES1_BS1(size - (last *
369 				  DWMMC_DMA_MAX_BUFFER_SIZE));
370 	/* set next descriptor address as 0 */
371 	(desc + last)->des3 = 0;
372 
373 	mmio_write_32(base + DWMMC_DBADDR, dw_params.desc_base);
374 	flush_dcache_range(dw_params.desc_base,
375 			   desc_cnt * DWMMC_DMA_MAX_BUFFER_SIZE);
376 
377 	return 0;
378 }
379 
380 static int dw_read(int lba, uintptr_t buf, size_t size)
381 {
382 	return 0;
383 }
384 
385 static int dw_write(int lba, uintptr_t buf, size_t size)
386 {
387 	return 0;
388 }
389 
390 void dw_mmc_init(dw_mmc_params_t *params, struct mmc_device_info *info)
391 {
392 	assert((params != 0) &&
393 	       ((params->reg_base & MMC_BLOCK_MASK) == 0) &&
394 	       ((params->desc_base & MMC_BLOCK_MASK) == 0) &&
395 	       ((params->desc_size & MMC_BLOCK_MASK) == 0) &&
396 	       (params->desc_size > 0) &&
397 	       (params->clk_rate > 0) &&
398 	       ((params->bus_width == MMC_BUS_WIDTH_1) ||
399 		(params->bus_width == MMC_BUS_WIDTH_4) ||
400 		(params->bus_width == MMC_BUS_WIDTH_8)));
401 
402 	memcpy(&dw_params, params, sizeof(dw_mmc_params_t));
403 	mmc_init(&dw_mmc_ops, params->clk_rate, params->bus_width,
404 		 params->flags, info);
405 }
406