]> git.sur5r.net Git - u-boot/blob - drivers/mmc/gen_atmel_mci.c
Merge git://www.denx.de/git/u-boot-imx
[u-boot] / drivers / mmc / gen_atmel_mci.c
1 /*
2  * Copyright (C) 2010
3  * Rob Emanuele <rob@emanuele.us>
4  * Reinhard Meyer, EMK Elektronik <reinhard.meyer@emk-elektronik.de>
5  *
6  * Original Driver:
7  * Copyright (C) 2004-2006 Atmel Corporation
8  *
9  * SPDX-License-Identifier:     GPL-2.0+
10  */
11
12 #include <common.h>
13 #include <clk.h>
14 #include <dm.h>
15 #include <mmc.h>
16 #include <part.h>
17 #include <malloc.h>
18 #include <asm/io.h>
19 #include <linux/errno.h>
20 #include <asm/byteorder.h>
21 #include <asm/arch/clk.h>
22 #include <asm/arch/hardware.h>
23 #include "atmel_mci.h"
24
25 DECLARE_GLOBAL_DATA_PTR;
26
27 #ifndef CONFIG_SYS_MMC_CLK_OD
28 # define CONFIG_SYS_MMC_CLK_OD  150000
29 #endif
30
31 #define MMC_DEFAULT_BLKLEN      512
32
33 #if defined(CONFIG_ATMEL_MCI_PORTB)
34 # define MCI_BUS 1
35 #else
36 # define MCI_BUS 0
37 #endif
38
39 struct atmel_mci_priv {
40         struct mmc_config       cfg;
41         struct atmel_mci        *mci;
42         unsigned int            initialized:1;
43         unsigned int            curr_clk;
44 #ifdef CONFIG_DM_MMC
45         struct mmc      mmc;
46         ulong           bus_clk_rate;
47 #endif
48 };
49
50 /* Read Atmel MCI IP version */
51 static unsigned int atmel_mci_get_version(struct atmel_mci *mci)
52 {
53         return readl(&mci->version) & 0x00000fff;
54 }
55
56 /*
57  * Print command and status:
58  *
59  * - always when DEBUG is defined
60  * - on command errors
61  */
62 static void dump_cmd(u32 cmdr, u32 arg, u32 status, const char* msg)
63 {
64         debug("gen_atmel_mci: CMDR %08x (%2u) ARGR %08x (SR: %08x) %s\n",
65               cmdr, cmdr & 0x3F, arg, status, msg);
66 }
67
68 /* Setup for MCI Clock and Block Size */
69 #ifdef CONFIG_DM_MMC
70 static void mci_set_mode(struct atmel_mci_priv *priv, u32 hz, u32 blklen)
71 {
72         struct mmc *mmc = &priv->mmc;
73         u32 bus_hz = priv->bus_clk_rate;
74 #else
75 static void mci_set_mode(struct mmc *mmc, u32 hz, u32 blklen)
76 {
77         struct atmel_mci_priv *priv = mmc->priv;
78         u32 bus_hz = get_mci_clk_rate();
79 #endif
80
81         atmel_mci_t *mci = priv->mci;
82         u32 clkdiv = 255;
83         unsigned int version = atmel_mci_get_version(mci);
84         u32 clkodd = 0;
85         u32 mr;
86
87         debug("mci: bus_hz is %u, setting clock %u Hz, block size %u\n",
88                 bus_hz, hz, blklen);
89         if (hz > 0) {
90                 if (version >= 0x500) {
91                         clkdiv = DIV_ROUND_UP(bus_hz, hz) - 2;
92                         if (clkdiv > 511)
93                                 clkdiv = 511;
94
95                         clkodd = clkdiv & 1;
96                         clkdiv >>= 1;
97
98                         debug("mci: setting clock %u Hz, block size %u\n",
99                               bus_hz / (clkdiv * 2 + clkodd + 2), blklen);
100                 } else {
101                         /* find clkdiv yielding a rate <= than requested */
102                         for (clkdiv = 0; clkdiv < 255; clkdiv++) {
103                                 if ((bus_hz / (clkdiv + 1) / 2) <= hz)
104                                         break;
105                         }
106                         debug("mci: setting clock %u Hz, block size %u\n",
107                               (bus_hz / (clkdiv + 1)) / 2, blklen);
108
109                 }
110         }
111         if (version >= 0x500)
112                 priv->curr_clk = bus_hz / (clkdiv * 2 + clkodd + 2);
113         else
114                 priv->curr_clk = (bus_hz / (clkdiv + 1)) / 2;
115         blklen &= 0xfffc;
116
117         mr = MMCI_BF(CLKDIV, clkdiv);
118
119         /* MCI IP version >= 0x200 has R/WPROOF */
120         if (version >= 0x200)
121                 mr |= MMCI_BIT(RDPROOF) | MMCI_BIT(WRPROOF);
122
123         /*
124          * MCI IP version >= 0x500 use bit 16 as clkodd.
125          * MCI IP version < 0x500 use upper 16 bits for blklen.
126          */
127         if (version >= 0x500)
128                 mr |= MMCI_BF(CLKODD, clkodd);
129         else
130                 mr |= MMCI_BF(BLKLEN, blklen);
131
132         writel(mr, &mci->mr);
133
134         /* MCI IP version >= 0x200 has blkr */
135         if (version >= 0x200)
136                 writel(MMCI_BF(BLKLEN, blklen), &mci->blkr);
137
138         if (mmc->card_caps & mmc->cfg->host_caps & MMC_MODE_HS)
139                 writel(MMCI_BIT(HSMODE), &mci->cfg);
140
141         priv->initialized = 1;
142 }
143
144 /* Return the CMDR with flags for a given command and data packet */
145 static u32 mci_encode_cmd(
146         struct mmc_cmd *cmd, struct mmc_data *data, u32* error_flags)
147 {
148         u32 cmdr = 0;
149
150         /* Default Flags for Errors */
151         *error_flags |= (MMCI_BIT(DTOE) | MMCI_BIT(RDIRE) | MMCI_BIT(RENDE) |
152                 MMCI_BIT(RINDE) | MMCI_BIT(RTOE));
153
154         /* Default Flags for the Command */
155         cmdr |= MMCI_BIT(MAXLAT);
156
157         if (data) {
158                 cmdr |= MMCI_BF(TRCMD, 1);
159                 if (data->blocks > 1)
160                         cmdr |= MMCI_BF(TRTYP, 1);
161                 if (data->flags & MMC_DATA_READ)
162                         cmdr |= MMCI_BIT(TRDIR);
163         }
164
165         if (cmd->resp_type & MMC_RSP_CRC)
166                 *error_flags |= MMCI_BIT(RCRCE);
167         if (cmd->resp_type & MMC_RSP_136)
168                 cmdr |= MMCI_BF(RSPTYP, 2);
169         else if (cmd->resp_type & MMC_RSP_BUSY)
170                 cmdr |= MMCI_BF(RSPTYP, 3);
171         else if (cmd->resp_type & MMC_RSP_PRESENT)
172                 cmdr |= MMCI_BF(RSPTYP, 1);
173
174         return cmdr | MMCI_BF(CMDNB, cmd->cmdidx);
175 }
176
177 /* Entered into function pointer in mci_send_cmd */
178 static u32 mci_data_read(atmel_mci_t *mci, u32* data, u32 error_flags)
179 {
180         u32 status;
181
182         do {
183                 status = readl(&mci->sr);
184                 if (status & (error_flags | MMCI_BIT(OVRE)))
185                         goto io_fail;
186         } while (!(status & MMCI_BIT(RXRDY)));
187
188         if (status & MMCI_BIT(RXRDY)) {
189                 *data = readl(&mci->rdr);
190                 status = 0;
191         }
192 io_fail:
193         return status;
194 }
195
196 /* Entered into function pointer in mci_send_cmd */
197 static u32 mci_data_write(atmel_mci_t *mci, u32* data, u32 error_flags)
198 {
199         u32 status;
200
201         do {
202                 status = readl(&mci->sr);
203                 if (status & (error_flags | MMCI_BIT(UNRE)))
204                         goto io_fail;
205         } while (!(status & MMCI_BIT(TXRDY)));
206
207         if (status & MMCI_BIT(TXRDY)) {
208                 writel(*data, &mci->tdr);
209                 status = 0;
210         }
211 io_fail:
212         return status;
213 }
214
215 /*
216  * Entered into mmc structure during driver init
217  *
218  * Sends a command out on the bus and deals with the block data.
219  * Takes the mmc pointer, a command pointer, and an optional data pointer.
220  */
221 #ifdef CONFIG_DM_MMC
222 static int atmel_mci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
223                               struct mmc_data *data)
224 {
225         struct atmel_mci_priv *priv = dev_get_priv(dev);
226         struct mmc *mmc = mmc_get_mmc_dev(dev);
227 #else
228 static int
229 mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
230 {
231         struct atmel_mci_priv *priv = mmc->priv;
232 #endif
233         atmel_mci_t *mci = priv->mci;
234         u32 cmdr;
235         u32 error_flags = 0;
236         u32 status;
237
238         if (!priv->initialized) {
239                 puts ("MCI not initialized!\n");
240                 return -ECOMM;
241         }
242
243         /* Figure out the transfer arguments */
244         cmdr = mci_encode_cmd(cmd, data, &error_flags);
245
246         /* For multi blocks read/write, set the block register */
247         if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK)
248                         || (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK))
249                 writel(data->blocks | MMCI_BF(BLKLEN, mmc->read_bl_len),
250                         &mci->blkr);
251
252         /* Send the command */
253         writel(cmd->cmdarg, &mci->argr);
254         writel(cmdr, &mci->cmdr);
255
256 #ifdef DEBUG
257         dump_cmd(cmdr, cmd->cmdarg, 0, "DEBUG");
258 #endif
259
260         /* Wait for the command to complete */
261         while (!((status = readl(&mci->sr)) & MMCI_BIT(CMDRDY)));
262
263         if ((status & error_flags) & MMCI_BIT(RTOE)) {
264                 dump_cmd(cmdr, cmd->cmdarg, status, "Command Time Out");
265                 return -ETIMEDOUT;
266         } else if (status & error_flags) {
267                 dump_cmd(cmdr, cmd->cmdarg, status, "Command Failed");
268                 return -ECOMM;
269         }
270
271         /* Copy the response to the response buffer */
272         if (cmd->resp_type & MMC_RSP_136) {
273                 cmd->response[0] = readl(&mci->rspr);
274                 cmd->response[1] = readl(&mci->rspr1);
275                 cmd->response[2] = readl(&mci->rspr2);
276                 cmd->response[3] = readl(&mci->rspr3);
277         } else
278                 cmd->response[0] = readl(&mci->rspr);
279
280         /* transfer all of the blocks */
281         if (data) {
282                 u32 word_count, block_count;
283                 u32* ioptr;
284                 u32 sys_blocksize, dummy, i;
285                 u32 (*mci_data_op)
286                         (atmel_mci_t *mci, u32* data, u32 error_flags);
287
288                 if (data->flags & MMC_DATA_READ) {
289                         mci_data_op = mci_data_read;
290                         sys_blocksize = mmc->read_bl_len;
291                         ioptr = (u32*)data->dest;
292                 } else {
293                         mci_data_op = mci_data_write;
294                         sys_blocksize = mmc->write_bl_len;
295                         ioptr = (u32*)data->src;
296                 }
297
298                 status = 0;
299                 for (block_count = 0;
300                                 block_count < data->blocks && !status;
301                                 block_count++) {
302                         word_count = 0;
303                         do {
304                                 status = mci_data_op(mci, ioptr, error_flags);
305                                 word_count++;
306                                 ioptr++;
307                         } while (!status && word_count < (data->blocksize/4));
308 #ifdef DEBUG
309                         if (data->flags & MMC_DATA_READ)
310                         {
311                                 u32 cnt = word_count * 4;
312                                 printf("Read Data:\n");
313                                 print_buffer(0, data->dest + cnt * block_count,
314                                              1, cnt, 0);
315                         }
316 #endif
317 #ifdef DEBUG
318                         if (!status && word_count < (sys_blocksize / 4))
319                                 printf("filling rest of block...\n");
320 #endif
321                         /* fill the rest of a full block */
322                         while (!status && word_count < (sys_blocksize / 4)) {
323                                 status = mci_data_op(mci, &dummy,
324                                         error_flags);
325                                 word_count++;
326                         }
327                         if (status) {
328                                 dump_cmd(cmdr, cmd->cmdarg, status,
329                                         "Data Transfer Failed");
330                                 return -ECOMM;
331                         }
332                 }
333
334                 /* Wait for Transfer End */
335                 i = 0;
336                 do {
337                         status = readl(&mci->sr);
338
339                         if (status & error_flags) {
340                                 dump_cmd(cmdr, cmd->cmdarg, status,
341                                         "DTIP Wait Failed");
342                                 return -ECOMM;
343                         }
344                         i++;
345                 } while ((status & MMCI_BIT(DTIP)) && i < 10000);
346                 if (status & MMCI_BIT(DTIP)) {
347                         dump_cmd(cmdr, cmd->cmdarg, status,
348                                 "XFER DTIP never unset, ignoring");
349                 }
350         }
351
352         /*
353          * After the switch command, wait for 8 clocks before the next
354          * command
355          */
356         if (cmd->cmdidx == MMC_CMD_SWITCH)
357                 udelay(8*1000000 / priv->curr_clk); /* 8 clk in us */
358
359         return 0;
360 }
361
362 #ifdef CONFIG_DM_MMC
363 static int atmel_mci_set_ios(struct udevice *dev)
364 {
365         struct atmel_mci_priv *priv = dev_get_priv(dev);
366         struct mmc *mmc = mmc_get_mmc_dev(dev);
367 #else
368 /* Entered into mmc structure during driver init */
369 static int mci_set_ios(struct mmc *mmc)
370 {
371         struct atmel_mci_priv *priv = mmc->priv;
372 #endif
373         atmel_mci_t *mci = priv->mci;
374         int bus_width = mmc->bus_width;
375         unsigned int version = atmel_mci_get_version(mci);
376         int busw;
377
378         /* Set the clock speed */
379 #ifdef CONFIG_DM_MMC
380         mci_set_mode(priv, mmc->clock, MMC_DEFAULT_BLKLEN);
381 #else
382         mci_set_mode(mmc, mmc->clock, MMC_DEFAULT_BLKLEN);
383 #endif
384
385         /*
386          * set the bus width and select slot for this interface
387          * there is no capability for multiple slots on the same interface yet
388          */
389         if ((version & 0xf00) >= 0x300) {
390                 switch (bus_width) {
391                 case 8:
392                         busw = 3;
393                         break;
394                 case 4:
395                         busw = 2;
396                         break;
397                 default:
398                         busw = 0;
399                         break;
400                 }
401
402                 writel(busw << 6 | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr);
403         } else {
404                 busw = (bus_width == 4) ? 1 : 0;
405
406                 writel(busw << 7 | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr);
407         }
408
409         return 0;
410 }
411
412 #ifdef CONFIG_DM_MMC
413 static int atmel_mci_hw_init(struct atmel_mci_priv *priv)
414 {
415 #else
416 /* Entered into mmc structure during driver init */
417 static int mci_init(struct mmc *mmc)
418 {
419         struct atmel_mci_priv *priv = mmc->priv;
420 #endif
421         atmel_mci_t *mci = priv->mci;
422
423         /* Initialize controller */
424         writel(MMCI_BIT(SWRST), &mci->cr);      /* soft reset */
425         writel(MMCI_BIT(PWSDIS), &mci->cr);     /* disable power save */
426         writel(MMCI_BIT(MCIEN), &mci->cr);      /* enable mci */
427         writel(MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr);   /* select port */
428
429         /* This delay can be optimized, but stick with max value */
430         writel(0x7f, &mci->dtor);
431         /* Disable Interrupts */
432         writel(~0UL, &mci->idr);
433
434         /* Set default clocks and blocklen */
435 #ifdef CONFIG_DM_MMC
436         mci_set_mode(priv, CONFIG_SYS_MMC_CLK_OD, MMC_DEFAULT_BLKLEN);
437 #else
438         mci_set_mode(mmc, CONFIG_SYS_MMC_CLK_OD, MMC_DEFAULT_BLKLEN);
439 #endif
440
441         return 0;
442 }
443
444 #ifndef CONFIG_DM_MMC
445 static const struct mmc_ops atmel_mci_ops = {
446         .send_cmd       = mci_send_cmd,
447         .set_ios        = mci_set_ios,
448         .init           = mci_init,
449 };
450
451 /*
452  * This is the only exported function
453  *
454  * Call it with the MCI register base address
455  */
456 int atmel_mci_init(void *regs)
457 {
458         struct mmc *mmc;
459         struct mmc_config *cfg;
460         struct atmel_mci_priv *priv;
461         unsigned int version;
462
463         priv = calloc(1, sizeof(*priv));
464         if (!priv)
465                 return -ENOMEM;
466
467         cfg = &priv->cfg;
468
469         cfg->name = "mci";
470         cfg->ops = &atmel_mci_ops;
471
472         priv->mci = (struct atmel_mci *)regs;
473         priv->initialized = 0;
474
475         /* need to be able to pass these in on a board by board basis */
476         cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
477         version = atmel_mci_get_version(priv->mci);
478         if ((version & 0xf00) >= 0x300) {
479                 cfg->host_caps = MMC_MODE_8BIT;
480                 cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
481         }
482
483         cfg->host_caps |= MMC_MODE_4BIT;
484
485         /*
486          * min and max frequencies determined by
487          * max and min of clock divider
488          */
489         cfg->f_min = get_mci_clk_rate() / (2*256);
490         cfg->f_max = get_mci_clk_rate() / (2*1);
491
492         cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
493
494         mmc = mmc_create(cfg, priv);
495
496         if (mmc == NULL) {
497                 free(priv);
498                 return -ENODEV;
499         }
500         /* NOTE: possibly leaking the priv structure */
501
502         return 0;
503 }
504 #endif
505
506 #ifdef CONFIG_DM_MMC
507 static const struct dm_mmc_ops atmel_mci_mmc_ops = {
508         .send_cmd = atmel_mci_send_cmd,
509         .set_ios = atmel_mci_set_ios,
510 };
511
512 static void atmel_mci_setup_cfg(struct atmel_mci_priv *priv)
513 {
514         struct mmc_config *cfg;
515         u32 version;
516
517         cfg = &priv->cfg;
518         cfg->name = "Atmel mci";
519         cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
520
521         /*
522          * If the version is above 3.0, the capabilities of the 8-bit
523          * bus width and high speed are supported.
524          */
525         version = atmel_mci_get_version(priv->mci);
526         if ((version & 0xf00) >= 0x300) {
527                 cfg->host_caps = MMC_MODE_8BIT |
528                                  MMC_MODE_HS | MMC_MODE_HS_52MHz;
529         }
530
531         cfg->host_caps |= MMC_MODE_4BIT;
532         cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
533         cfg->f_min = priv->bus_clk_rate / (2 * 256);
534         cfg->f_max = priv->bus_clk_rate / 2;
535 }
536
537 static int atmel_mci_enable_clk(struct udevice *dev)
538 {
539         struct atmel_mci_priv *priv = dev_get_priv(dev);
540         struct clk clk;
541         ulong clk_rate;
542         int ret = 0;
543
544         ret = clk_get_by_index(dev, 0, &clk);
545         if (ret) {
546                 ret = -EINVAL;
547                 goto failed;
548         }
549
550         ret = clk_enable(&clk);
551         if (ret)
552                 goto failed;
553
554         clk_rate = clk_get_rate(&clk);
555         if (!clk_rate) {
556                 ret = -EINVAL;
557                 goto failed;
558         }
559
560         priv->bus_clk_rate = clk_rate;
561
562 failed:
563         clk_free(&clk);
564
565         return ret;
566 }
567
568 static int atmel_mci_probe(struct udevice *dev)
569 {
570         struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
571         struct atmel_mci_priv *priv = dev_get_priv(dev);
572         struct mmc *mmc;
573         int ret;
574
575         ret = atmel_mci_enable_clk(dev);
576         if (ret)
577                 return ret;
578
579         priv->mci = (struct atmel_mci *)devfdt_get_addr_ptr(dev);
580
581         atmel_mci_setup_cfg(priv);
582
583         mmc = &priv->mmc;
584         mmc->cfg = &priv->cfg;
585         mmc->dev = dev;
586         upriv->mmc = mmc;
587
588         atmel_mci_hw_init(priv);
589
590         return 0;
591 }
592
593 static int atmel_mci_bind(struct udevice *dev)
594 {
595         struct atmel_mci_priv *priv = dev_get_priv(dev);
596
597         return mmc_bind(dev, &priv->mmc, &priv->cfg);
598 }
599
600 static const struct udevice_id atmel_mci_ids[] = {
601         { .compatible = "atmel,hsmci" },
602         { }
603 };
604
605 U_BOOT_DRIVER(atmel_mci) = {
606         .name = "atmel-mci",
607         .id = UCLASS_MMC,
608         .of_match = atmel_mci_ids,
609         .bind = atmel_mci_bind,
610         .probe = atmel_mci_probe,
611         .priv_auto_alloc_size = sizeof(struct atmel_mci_priv),
612         .ops = &atmel_mci_mmc_ops,
613 };
614 #endif