1
2
3
4
5
6
7
8
9
10
11
12#include <common.h>
13#include <mmc.h>
14#include <part.h>
15#include <malloc.h>
16#include <asm/io.h>
17#include <asm/errno.h>
18#include <asm/byteorder.h>
19#include <asm/arch/clk.h>
20#include <asm/arch/hardware.h>
21#include "atmel_mci.h"
22
23#ifndef CONFIG_SYS_MMC_CLK_OD
24# define CONFIG_SYS_MMC_CLK_OD 150000
25#endif
26
27#define MMC_DEFAULT_BLKLEN 512
28
29#if defined(CONFIG_ATMEL_MCI_PORTB)
30# define MCI_BUS 1
31#else
32# define MCI_BUS 0
33#endif
34
35static int initialized = 0;
36
37
38static unsigned int atmel_mci_get_version(struct atmel_mci *mci)
39{
40 return readl(&mci->version) & 0x00000fff;
41}
42
43
44
45
46
47
48
49static void dump_cmd(u32 cmdr, u32 arg, u32 status, const char* msg)
50{
51 printf("gen_atmel_mci: CMDR %08x (%2u) ARGR %08x (SR: %08x) %s\n",
52 cmdr, cmdr&0x3F, arg, status, msg);
53}
54
55
56static void mci_set_mode(struct mmc *mmc, u32 hz, u32 blklen)
57{
58 atmel_mci_t *mci = mmc->priv;
59 u32 bus_hz = get_mci_clk_rate();
60 u32 clkdiv = 255;
61 unsigned int version = atmel_mci_get_version(mci);
62 u32 clkodd = 0;
63 u32 mr;
64
65 debug("mci: bus_hz is %u, setting clock %u Hz, block size %u\n",
66 bus_hz, hz, blklen);
67 if (hz > 0) {
68 if (version >= 0x500) {
69 clkdiv = DIV_ROUND_UP(bus_hz, hz) - 2;
70 if (clkdiv > 511)
71 clkdiv = 511;
72
73 clkodd = clkdiv & 1;
74 clkdiv >>= 1;
75
76 printf("mci: setting clock %u Hz, block size %u\n",
77 bus_hz / (clkdiv * 2 + clkodd + 2), blklen);
78 } else {
79
80 for (clkdiv = 0; clkdiv < 255; clkdiv++) {
81 if ((bus_hz / (clkdiv + 1) / 2) <= hz)
82 break;
83 }
84 printf("mci: setting clock %u Hz, block size %u\n",
85 (bus_hz / (clkdiv + 1)) / 2, blklen);
86
87 }
88 }
89
90 blklen &= 0xfffc;
91
92 mr = MMCI_BF(CLKDIV, clkdiv);
93
94
95 if (version >= 0x200)
96 mr |= MMCI_BIT(RDPROOF) | MMCI_BIT(WRPROOF);
97
98
99
100
101
102 if (version >= 0x500)
103 mr |= MMCI_BF(CLKODD, clkodd);
104 else
105 mr |= MMCI_BF(BLKLEN, blklen);
106
107 writel(mr, &mci->mr);
108
109
110 if (version >= 0x200)
111 writel(MMCI_BF(BLKLEN, blklen), &mci->blkr);
112
113 if (mmc->card_caps & mmc->cfg->host_caps & MMC_MODE_HS)
114 writel(MMCI_BIT(HSMODE), &mci->cfg);
115
116 initialized = 1;
117}
118
119
120static u32 mci_encode_cmd(
121 struct mmc_cmd *cmd, struct mmc_data *data, u32* error_flags)
122{
123 u32 cmdr = 0;
124
125
126 *error_flags |= (MMCI_BIT(DTOE) | MMCI_BIT(RDIRE) | MMCI_BIT(RENDE) |
127 MMCI_BIT(RINDE) | MMCI_BIT(RTOE));
128
129
130 cmdr |= MMCI_BIT(MAXLAT);
131
132 if (data) {
133 cmdr |= MMCI_BF(TRCMD, 1);
134 if (data->blocks > 1)
135 cmdr |= MMCI_BF(TRTYP, 1);
136 if (data->flags & MMC_DATA_READ)
137 cmdr |= MMCI_BIT(TRDIR);
138 }
139
140 if (cmd->resp_type & MMC_RSP_CRC)
141 *error_flags |= MMCI_BIT(RCRCE);
142 if (cmd->resp_type & MMC_RSP_136)
143 cmdr |= MMCI_BF(RSPTYP, 2);
144 else if (cmd->resp_type & MMC_RSP_BUSY)
145 cmdr |= MMCI_BF(RSPTYP, 3);
146 else if (cmd->resp_type & MMC_RSP_PRESENT)
147 cmdr |= MMCI_BF(RSPTYP, 1);
148
149 return cmdr | MMCI_BF(CMDNB, cmd->cmdidx);
150}
151
152
153static u32 mci_data_read(atmel_mci_t *mci, u32* data, u32 error_flags)
154{
155 u32 status;
156
157 do {
158 status = readl(&mci->sr);
159 if (status & (error_flags | MMCI_BIT(OVRE)))
160 goto io_fail;
161 } while (!(status & MMCI_BIT(RXRDY)));
162
163 if (status & MMCI_BIT(RXRDY)) {
164 *data = readl(&mci->rdr);
165 status = 0;
166 }
167io_fail:
168 return status;
169}
170
171
172static u32 mci_data_write(atmel_mci_t *mci, u32* data, u32 error_flags)
173{
174 u32 status;
175
176 do {
177 status = readl(&mci->sr);
178 if (status & (error_flags | MMCI_BIT(UNRE)))
179 goto io_fail;
180 } while (!(status & MMCI_BIT(TXRDY)));
181
182 if (status & MMCI_BIT(TXRDY)) {
183 writel(*data, &mci->tdr);
184 status = 0;
185 }
186io_fail:
187 return status;
188}
189
190
191
192
193
194
195
196static int
197mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
198{
199 atmel_mci_t *mci = mmc->priv;
200 u32 cmdr;
201 u32 error_flags = 0;
202 u32 status;
203
204 if (!initialized) {
205 puts ("MCI not initialized!\n");
206 return COMM_ERR;
207 }
208
209
210 cmdr = mci_encode_cmd(cmd, data, &error_flags);
211
212
213 if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK)
214 || (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK))
215 writel(data->blocks | MMCI_BF(BLKLEN, mmc->read_bl_len),
216 &mci->blkr);
217
218
219 writel(cmd->cmdarg, &mci->argr);
220 writel(cmdr, &mci->cmdr);
221
222#ifdef DEBUG
223 dump_cmd(cmdr, cmd->cmdarg, 0, "DEBUG");
224#endif
225
226
227 while (!((status = readl(&mci->sr)) & MMCI_BIT(CMDRDY)));
228
229 if ((status & error_flags) & MMCI_BIT(RTOE)) {
230 dump_cmd(cmdr, cmd->cmdarg, status, "Command Time Out");
231 return TIMEOUT;
232 } else if (status & error_flags) {
233 dump_cmd(cmdr, cmd->cmdarg, status, "Command Failed");
234 return COMM_ERR;
235 }
236
237
238 if (cmd->resp_type & MMC_RSP_136) {
239 cmd->response[0] = readl(&mci->rspr);
240 cmd->response[1] = readl(&mci->rspr1);
241 cmd->response[2] = readl(&mci->rspr2);
242 cmd->response[3] = readl(&mci->rspr3);
243 } else
244 cmd->response[0] = readl(&mci->rspr);
245
246
247 if (data) {
248 u32 word_count, block_count;
249 u32* ioptr;
250 u32 sys_blocksize, dummy, i;
251 u32 (*mci_data_op)
252 (atmel_mci_t *mci, u32* data, u32 error_flags);
253
254 if (data->flags & MMC_DATA_READ) {
255 mci_data_op = mci_data_read;
256 sys_blocksize = mmc->read_bl_len;
257 ioptr = (u32*)data->dest;
258 } else {
259 mci_data_op = mci_data_write;
260 sys_blocksize = mmc->write_bl_len;
261 ioptr = (u32*)data->src;
262 }
263
264 status = 0;
265 for (block_count = 0;
266 block_count < data->blocks && !status;
267 block_count++) {
268 word_count = 0;
269 do {
270 status = mci_data_op(mci, ioptr, error_flags);
271 word_count++;
272 ioptr++;
273 } while (!status && word_count < (data->blocksize/4));
274#ifdef DEBUG
275 if (data->flags & MMC_DATA_READ)
276 {
277 u32 cnt = word_count * 4;
278 printf("Read Data:\n");
279 print_buffer(0, data->dest + cnt * block_count,
280 1, cnt, 0);
281 }
282#endif
283#ifdef DEBUG
284 if (!status && word_count < (sys_blocksize / 4))
285 printf("filling rest of block...\n");
286#endif
287
288 while (!status && word_count < (sys_blocksize / 4)) {
289 status = mci_data_op(mci, &dummy,
290 error_flags);
291 word_count++;
292 }
293 if (status) {
294 dump_cmd(cmdr, cmd->cmdarg, status,
295 "Data Transfer Failed");
296 return COMM_ERR;
297 }
298 }
299
300
301 i = 0;
302 do {
303 status = readl(&mci->sr);
304
305 if (status & error_flags) {
306 dump_cmd(cmdr, cmd->cmdarg, status,
307 "DTIP Wait Failed");
308 return COMM_ERR;
309 }
310 i++;
311 } while ((status & MMCI_BIT(DTIP)) && i < 10000);
312 if (status & MMCI_BIT(DTIP)) {
313 dump_cmd(cmdr, cmd->cmdarg, status,
314 "XFER DTIP never unset, ignoring");
315 }
316 }
317
318 return 0;
319}
320
321
322static void mci_set_ios(struct mmc *mmc)
323{
324 atmel_mci_t *mci = mmc->priv;
325 int bus_width = mmc->bus_width;
326 unsigned int version = atmel_mci_get_version(mci);
327 int busw;
328
329
330 mci_set_mode(mmc, mmc->clock, MMC_DEFAULT_BLKLEN);
331
332
333
334
335
336 if ((version & 0xf00) >= 0x300) {
337 switch (bus_width) {
338 case 8:
339 busw = 3;
340 break;
341 case 4:
342 busw = 2;
343 break;
344 default:
345 busw = 0;
346 break;
347 }
348
349 writel(busw << 6 | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr);
350 } else {
351 busw = (bus_width == 4) ? 1 : 0;
352
353 writel(busw << 7 | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr);
354 }
355}
356
357
358static int mci_init(struct mmc *mmc)
359{
360 atmel_mci_t *mci = mmc->priv;
361
362
363 writel(MMCI_BIT(SWRST), &mci->cr);
364 writel(MMCI_BIT(PWSDIS), &mci->cr);
365 writel(MMCI_BIT(MCIEN), &mci->cr);
366 writel(MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr);
367
368
369 writel(0x7f, &mci->dtor);
370
371 writel(~0UL, &mci->idr);
372
373
374 mci_set_mode(mmc, CONFIG_SYS_MMC_CLK_OD, MMC_DEFAULT_BLKLEN);
375
376 return 0;
377}
378
379static const struct mmc_ops atmel_mci_ops = {
380 .send_cmd = mci_send_cmd,
381 .set_ios = mci_set_ios,
382 .init = mci_init,
383};
384
385
386
387
388
389
390int atmel_mci_init(void *regs)
391{
392 struct mmc *mmc;
393 struct mmc_config *cfg;
394 struct atmel_mci *mci;
395 unsigned int version;
396
397 cfg = malloc(sizeof(*cfg));
398 if (cfg == NULL)
399 return -1;
400 memset(cfg, 0, sizeof(*cfg));
401
402 mci = (struct atmel_mci *)regs;
403
404 cfg->name = "mci";
405 cfg->ops = &atmel_mci_ops;
406
407
408 cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
409 version = atmel_mci_get_version(mci);
410 if ((version & 0xf00) >= 0x300) {
411 cfg->host_caps = MMC_MODE_8BIT;
412 cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
413 }
414
415 cfg->host_caps |= MMC_MODE_4BIT;
416
417
418
419
420
421 cfg->f_min = get_mci_clk_rate() / (2*256);
422 cfg->f_max = get_mci_clk_rate() / (2*1);
423
424 cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
425
426 mmc = mmc_create(cfg, regs);
427
428 if (mmc == NULL) {
429 free(cfg);
430 return -1;
431 }
432
433
434 return 0;
435}
436