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