1
2
3
4
5
6
7
8
9
10#include <common.h>
11#include <errno.h>
12#include <log.h>
13#include <malloc.h>
14#include <part.h>
15#include <mmc.h>
16#include <asm/io.h>
17#include <asm/arch/cpu.h>
18#include <asm/arch/soc.h>
19#include <mvebu_mmc.h>
20
21DECLARE_GLOBAL_DATA_PTR;
22
23#define DRIVER_NAME "MVEBU_MMC"
24
25#define MVEBU_TARGET_DRAM 0
26
27#define TIMEOUT_DELAY 5*CONFIG_SYS_HZ
28
29static void mvebu_mmc_write(u32 offs, u32 val)
30{
31 writel(val, CONFIG_SYS_MMC_BASE + (offs));
32}
33
34static u32 mvebu_mmc_read(u32 offs)
35{
36 return readl(CONFIG_SYS_MMC_BASE + (offs));
37}
38
39static int mvebu_mmc_setup_data(struct mmc_data *data)
40{
41 u32 ctrl_reg;
42
43 debug("%s, data %s : blocks=%d blksz=%d\n", DRIVER_NAME,
44 (data->flags & MMC_DATA_READ) ? "read" : "write",
45 data->blocks, data->blocksize);
46
47
48 ctrl_reg = mvebu_mmc_read(SDIO_HOST_CTRL);
49 ctrl_reg |= SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX);
50 mvebu_mmc_write(SDIO_HOST_CTRL, ctrl_reg);
51
52 if (data->flags & MMC_DATA_READ) {
53 mvebu_mmc_write(SDIO_SYS_ADDR_LOW, (u32)data->dest & 0xffff);
54 mvebu_mmc_write(SDIO_SYS_ADDR_HI, (u32)data->dest >> 16);
55 } else {
56 mvebu_mmc_write(SDIO_SYS_ADDR_LOW, (u32)data->src & 0xffff);
57 mvebu_mmc_write(SDIO_SYS_ADDR_HI, (u32)data->src >> 16);
58 }
59
60 mvebu_mmc_write(SDIO_BLK_COUNT, data->blocks);
61 mvebu_mmc_write(SDIO_BLK_SIZE, data->blocksize);
62
63 return 0;
64}
65
66static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
67 struct mmc_data *data)
68{
69 ulong start;
70 ushort waittype = 0;
71 ushort resptype = 0;
72 ushort xfertype = 0;
73 ushort resp_indx = 0;
74
75 debug("%s: cmdidx [0x%x] resp_type[0x%x] cmdarg[0x%x]\n",
76 DRIVER_NAME, cmd->cmdidx, cmd->resp_type, cmd->cmdarg);
77
78 debug("%s: cmd %d (hw state 0x%04x)\n", DRIVER_NAME,
79 cmd->cmdidx, mvebu_mmc_read(SDIO_HW_STATE));
80
81
82
83
84
85
86
87
88
89
90 if (!(mvebu_mmc_read(SDIO_HW_STATE) & CMD_FIFO_EMPTY)) {
91 ushort hw_state, count = 0;
92
93 start = get_timer(0);
94 do {
95 hw_state = mvebu_mmc_read(SDIO_HW_STATE);
96 if ((get_timer(0) - start) > TIMEOUT_DELAY) {
97 printf("%s : FIFO_EMPTY bit missing\n",
98 DRIVER_NAME);
99 break;
100 }
101 count++;
102 } while (!(hw_state & CMD_FIFO_EMPTY));
103 debug("%s *** wait for FIFO_EMPTY bit (hw=0x%04x, count=%d, jiffies=%ld)\n",
104 DRIVER_NAME, hw_state, count, (get_timer(0) - (start)));
105 }
106
107
108 mvebu_mmc_write(SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK);
109 mvebu_mmc_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK);
110
111 resptype = SDIO_CMD_INDEX(cmd->cmdidx);
112
113
114 if (cmd->resp_type & MMC_RSP_BUSY)
115 resptype |= SDIO_CMD_RSP_48BUSY;
116 else if (cmd->resp_type & MMC_RSP_136)
117 resptype |= SDIO_CMD_RSP_136;
118 else if (cmd->resp_type & MMC_RSP_PRESENT)
119 resptype |= SDIO_CMD_RSP_48;
120 else
121 resptype |= SDIO_CMD_RSP_NONE;
122
123 if (cmd->resp_type & MMC_RSP_CRC)
124 resptype |= SDIO_CMD_CHECK_CMDCRC;
125
126 if (cmd->resp_type & MMC_RSP_OPCODE)
127 resptype |= SDIO_CMD_INDX_CHECK;
128
129 if (cmd->resp_type & MMC_RSP_PRESENT) {
130 resptype |= SDIO_UNEXPECTED_RESP;
131 waittype |= SDIO_NOR_UNEXP_RSP;
132 }
133
134 if (data) {
135 int err = mvebu_mmc_setup_data(data);
136
137 if (err) {
138 debug("%s: command DATA error :%x\n",
139 DRIVER_NAME, err);
140 return err;
141 }
142
143 resptype |= SDIO_CMD_DATA_PRESENT | SDIO_CMD_CHECK_DATACRC16;
144 xfertype |= SDIO_XFER_MODE_HW_WR_DATA_EN;
145 if (data->flags & MMC_DATA_READ) {
146 xfertype |= SDIO_XFER_MODE_TO_HOST;
147 waittype = SDIO_NOR_DMA_INI;
148 } else {
149 waittype |= SDIO_NOR_XFER_DONE;
150 }
151 } else {
152 waittype |= SDIO_NOR_CMD_DONE;
153 }
154
155
156 mvebu_mmc_write(SDIO_ARG_LOW, cmd->cmdarg & 0xffff);
157 mvebu_mmc_write(SDIO_ARG_HI, cmd->cmdarg >> 16);
158
159
160 mvebu_mmc_write(SDIO_XFER_MODE, xfertype);
161
162
163 mvebu_mmc_write(SDIO_CMD, resptype);
164
165 start = get_timer(0);
166
167 while (!((mvebu_mmc_read(SDIO_NOR_INTR_STATUS)) & waittype)) {
168 if (mvebu_mmc_read(SDIO_NOR_INTR_STATUS) & SDIO_NOR_ERROR) {
169 debug("%s: error! cmdidx : %d, err reg: %04x\n",
170 DRIVER_NAME, cmd->cmdidx,
171 mvebu_mmc_read(SDIO_ERR_INTR_STATUS));
172 if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) &
173 (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT)) {
174 debug("%s: command READ timed out\n",
175 DRIVER_NAME);
176 return -ETIMEDOUT;
177 }
178 debug("%s: command READ error\n", DRIVER_NAME);
179 return -ECOMM;
180 }
181
182 if ((get_timer(0) - start) > TIMEOUT_DELAY) {
183 debug("%s: command timed out\n", DRIVER_NAME);
184 return -ETIMEDOUT;
185 }
186 }
187
188
189 if (cmd->resp_type & MMC_RSP_136) {
190 uint response[8];
191
192 for (resp_indx = 0; resp_indx < 8; resp_indx++)
193 response[resp_indx]
194 = mvebu_mmc_read(SDIO_RSP(resp_indx));
195
196 cmd->response[0] = ((response[0] & 0x03ff) << 22) |
197 ((response[1] & 0xffff) << 6) |
198 ((response[2] & 0xfc00) >> 10);
199 cmd->response[1] = ((response[2] & 0x03ff) << 22) |
200 ((response[3] & 0xffff) << 6) |
201 ((response[4] & 0xfc00) >> 10);
202 cmd->response[2] = ((response[4] & 0x03ff) << 22) |
203 ((response[5] & 0xffff) << 6) |
204 ((response[6] & 0xfc00) >> 10);
205 cmd->response[3] = ((response[6] & 0x03ff) << 22) |
206 ((response[7] & 0x3fff) << 8);
207 } else if (cmd->resp_type & MMC_RSP_PRESENT) {
208 uint response[3];
209
210 for (resp_indx = 0; resp_indx < 3; resp_indx++)
211 response[resp_indx]
212 = mvebu_mmc_read(SDIO_RSP(resp_indx));
213
214 cmd->response[0] = ((response[2] & 0x003f) << (8 - 8)) |
215 ((response[1] & 0xffff) << (14 - 8)) |
216 ((response[0] & 0x03ff) << (30 - 8));
217 cmd->response[1] = ((response[0] & 0xfc00) >> 10);
218 cmd->response[2] = 0;
219 cmd->response[3] = 0;
220 } else {
221 cmd->response[0] = 0;
222 cmd->response[1] = 0;
223 cmd->response[2] = 0;
224 cmd->response[3] = 0;
225 }
226
227 debug("%s: resp[0x%x] ", DRIVER_NAME, cmd->resp_type);
228 debug("[0x%x] ", cmd->response[0]);
229 debug("[0x%x] ", cmd->response[1]);
230 debug("[0x%x] ", cmd->response[2]);
231 debug("[0x%x] ", cmd->response[3]);
232 debug("\n");
233
234 if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) &
235 (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT))
236 return -ETIMEDOUT;
237
238 return 0;
239}
240
241static void mvebu_mmc_power_up(void)
242{
243 debug("%s: power up\n", DRIVER_NAME);
244
245
246 mvebu_mmc_write(SDIO_NOR_INTR_EN, 0);
247 mvebu_mmc_write(SDIO_ERR_INTR_EN, 0);
248
249
250 mvebu_mmc_write(SDIO_SW_RESET, SDIO_SW_RESET_NOW);
251
252 mvebu_mmc_write(SDIO_XFER_MODE, 0);
253
254
255 mvebu_mmc_write(SDIO_NOR_STATUS_EN, SDIO_POLL_MASK);
256 mvebu_mmc_write(SDIO_ERR_STATUS_EN, SDIO_POLL_MASK);
257
258
259 mvebu_mmc_write(SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK);
260 mvebu_mmc_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK);
261}
262
263static void mvebu_mmc_set_clk(unsigned int clock)
264{
265 unsigned int m;
266
267 if (clock == 0) {
268 debug("%s: clock off\n", DRIVER_NAME);
269 mvebu_mmc_write(SDIO_XFER_MODE, SDIO_XFER_MODE_STOP_CLK);
270 mvebu_mmc_write(SDIO_CLK_DIV, MVEBU_MMC_BASE_DIV_MAX);
271 } else {
272 m = MVEBU_MMC_BASE_FAST_CLOCK/(2*clock) - 1;
273 if (m > MVEBU_MMC_BASE_DIV_MAX)
274 m = MVEBU_MMC_BASE_DIV_MAX;
275 mvebu_mmc_write(SDIO_CLK_DIV, m & MVEBU_MMC_BASE_DIV_MAX);
276 debug("%s: clock (%d) div : %d\n", DRIVER_NAME, clock, m);
277 }
278}
279
280static void mvebu_mmc_set_bus(unsigned int bus)
281{
282 u32 ctrl_reg = 0;
283
284 ctrl_reg = mvebu_mmc_read(SDIO_HOST_CTRL);
285 ctrl_reg &= ~SDIO_HOST_CTRL_DATA_WIDTH_4_BITS;
286
287 switch (bus) {
288 case 4:
289 ctrl_reg |= SDIO_HOST_CTRL_DATA_WIDTH_4_BITS;
290 break;
291 case 1:
292 default:
293 ctrl_reg |= SDIO_HOST_CTRL_DATA_WIDTH_1_BIT;
294 }
295
296
297 ctrl_reg |= SDIO_HOST_CTRL_BIG_ENDIAN;
298 ctrl_reg &= ~SDIO_HOST_CTRL_LSB_FIRST;
299
300
301 ctrl_reg |= SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX);
302 ctrl_reg |= SDIO_HOST_CTRL_TMOUT_EN;
303
304 ctrl_reg |= SDIO_HOST_CTRL_PUSH_PULL_EN;
305
306 ctrl_reg |= SDIO_HOST_CTRL_CARD_TYPE_MEM_ONLY;
307
308 debug("%s: ctrl 0x%04x: %s %s %s\n", DRIVER_NAME, ctrl_reg,
309 (ctrl_reg & SDIO_HOST_CTRL_PUSH_PULL_EN) ?
310 "push-pull" : "open-drain",
311 (ctrl_reg & SDIO_HOST_CTRL_DATA_WIDTH_4_BITS) ?
312 "4bit-width" : "1bit-width",
313 (ctrl_reg & SDIO_HOST_CTRL_HI_SPEED_EN) ?
314 "high-speed" : "");
315
316 mvebu_mmc_write(SDIO_HOST_CTRL, ctrl_reg);
317}
318
319static int mvebu_mmc_set_ios(struct mmc *mmc)
320{
321 debug("%s: bus[%d] clock[%d]\n", DRIVER_NAME,
322 mmc->bus_width, mmc->clock);
323 mvebu_mmc_set_bus(mmc->bus_width);
324 mvebu_mmc_set_clk(mmc->clock);
325
326 return 0;
327}
328
329
330
331
332static void mvebu_window_setup(void)
333{
334 int i;
335
336 for (i = 0; i < 4; i++) {
337 mvebu_mmc_write(WINDOW_CTRL(i), 0);
338 mvebu_mmc_write(WINDOW_BASE(i), 0);
339 }
340 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
341 u32 size, base, attrib;
342
343
344 switch (i) {
345 case 0:
346 attrib = KWCPU_ATTR_DRAM_CS0;
347 break;
348 case 1:
349 attrib = KWCPU_ATTR_DRAM_CS1;
350 break;
351 case 2:
352 attrib = KWCPU_ATTR_DRAM_CS2;
353 break;
354 case 3:
355 attrib = KWCPU_ATTR_DRAM_CS3;
356 break;
357 default:
358
359 attrib = 0;
360 break;
361 }
362
363 size = gd->bd->bi_dram[i].size;
364 base = gd->bd->bi_dram[i].start;
365 if (size && attrib) {
366 mvebu_mmc_write(WINDOW_CTRL(i),
367 MVCPU_WIN_CTRL_DATA(size,
368 MVEBU_TARGET_DRAM,
369 attrib,
370 MVCPU_WIN_ENABLE));
371 } else {
372 mvebu_mmc_write(WINDOW_CTRL(i), MVCPU_WIN_DISABLE);
373 }
374 mvebu_mmc_write(WINDOW_BASE(i), base);
375 }
376}
377
378static int mvebu_mmc_initialize(struct mmc *mmc)
379{
380 debug("%s: mvebu_mmc_initialize\n", DRIVER_NAME);
381
382
383
384
385
386
387 mvebu_mmc_write(SDIO_HOST_CTRL,
388 SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX) |
389 SDIO_HOST_CTRL_DATA_WIDTH_4_BITS |
390 SDIO_HOST_CTRL_BIG_ENDIAN |
391 SDIO_HOST_CTRL_PUSH_PULL_EN |
392 SDIO_HOST_CTRL_CARD_TYPE_MEM_ONLY);
393
394 mvebu_mmc_write(SDIO_CLK_CTRL, 0);
395
396
397 mvebu_mmc_write(SDIO_NOR_STATUS_EN, SDIO_POLL_MASK);
398 mvebu_mmc_write(SDIO_ERR_STATUS_EN, SDIO_POLL_MASK);
399
400
401 mvebu_mmc_write(SDIO_NOR_INTR_EN, 0);
402 mvebu_mmc_write(SDIO_ERR_INTR_EN, 0);
403
404 mvebu_window_setup();
405
406
407 mvebu_mmc_write(SDIO_SW_RESET, SDIO_SW_RESET_NOW);
408
409 return 0;
410}
411
412static const struct mmc_ops mvebu_mmc_ops = {
413 .send_cmd = mvebu_mmc_send_cmd,
414 .set_ios = mvebu_mmc_set_ios,
415 .init = mvebu_mmc_initialize,
416};
417
418static struct mmc_config mvebu_mmc_cfg = {
419 .name = DRIVER_NAME,
420 .ops = &mvebu_mmc_ops,
421 .f_min = MVEBU_MMC_BASE_FAST_CLOCK / MVEBU_MMC_BASE_DIV_MAX,
422 .f_max = MVEBU_MMC_CLOCKRATE_MAX,
423 .voltages = MMC_VDD_32_33 | MMC_VDD_33_34,
424 .host_caps = MMC_MODE_4BIT | MMC_MODE_HS |
425 MMC_MODE_HS_52MHz,
426 .part_type = PART_TYPE_DOS,
427 .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
428};
429
430int mvebu_mmc_init(bd_t *bis)
431{
432 struct mmc *mmc;
433
434 mvebu_mmc_power_up();
435
436 mmc = mmc_create(&mvebu_mmc_cfg, bis);
437 if (mmc == NULL)
438 return -1;
439
440 return 0;
441}
442