Commit 18c83588bc830dbad5a96ca19a85184da58f4d09

Authored by Tom Rini

Merge branch 'master' of git://git.denx.de/u-boot-mmc

Showing 15 changed files Side-by-side Diff

arch/arm/cpu/armv7/omap-common/boot-common.c
... ... @@ -66,7 +66,18 @@
66 66  
67 67 u32 spl_boot_mode(void)
68 68 {
69   - return gd->arch.omap_boot_params.omap_bootmode;
  69 + u32 val = gd->arch.omap_boot_params.omap_bootmode;
  70 +
  71 + if (val == MMCSD_MODE_RAW)
  72 + return MMCSD_MODE_RAW;
  73 + else if (val == MMCSD_MODE_FAT)
  74 + return MMCSD_MODE_FAT;
  75 + else
  76 +#ifdef CONFIG_SUPPORT_EMMC_BOOT
  77 + return MMCSD_MODE_EMMCBOOT;
  78 +#else
  79 + return MMCSD_MODE_UNDEFINED;
  80 +#endif
70 81 }
71 82  
72 83 void spl_board_init(void)
arch/arm/include/asm/arch-exynos/dwmmc.h
... ... @@ -23,6 +23,10 @@
23 23 #define MPSCTRL_ENCRYPTION (0x1<<1)
24 24 #define MPSCTRL_VALID (0x1<<0)
25 25  
  26 +/* CLKSEL Register */
  27 +#define DWMCI_DIVRATIO_BIT 24
  28 +#define DWMCI_DIVRATIO_MASK 0x7
  29 +
26 30 #ifdef CONFIG_OF_CONTROL
27 31 int exynos_dwmmc_init(const void *blob);
28 32 #endif
board/ti/dra7xx/README
  1 +Summary
  2 +=======
  3 +
  4 +This document covers various features of the 'dra7xx_evm' build and some
  5 +related uses.
  6 +
  7 +eMMC boot partition use
  8 +=======================
  9 +
  10 +It is possible, depending on SYSBOOT configuration to boot from the eMMC
  11 +boot partitions using (name depending on documentation referenced)
  12 +Alternative Boot operation mode or Boot Sequence Option 1/2. In this
  13 +example we load MLO and u-boot.img from the build into DDR and then use
  14 +'mmc bootbus' to set the required rate (see TRM) and 'mmc partconfig' to
  15 +set boot0 as the boot device.
  16 +U-Boot # setenv autoload no
  17 +U-Boot # usb start
  18 +U-Boot # dhcp
  19 +U-Boot # mmc dev 1 1
  20 +U-Boot # tftp ${loadaddr} dra7xx/MLO
  21 +U-Boot # mmc write ${loadaddr} 0 100
  22 +U-Boot # tftp ${loadaddr} dra7xx/u-boot.img
  23 +U-Boot # mmc write ${loadaddr} 300 400
  24 +U-Boot # mmc bootbus 1 2 0 2
  25 +U-Boot # mmc partconf 1 1 1 0
board/ti/omap5_uevm/README
  1 +Summary
  2 +=======
  3 +
  4 +This document covers various features of the 'omap5_uevm' build and some
  5 +related uses.
  6 +
  7 +eMMC boot partition use
  8 +=======================
  9 +
  10 +It is possible, depending on SYSBOOT configuration to boot from the eMMC
  11 +boot partitions using (name depending on documentation referenced)
  12 +Alternative Boot operation mode or Boot Sequence Option 1/2. In this
  13 +example we load MLO and u-boot.img from the build into DDR and then use
  14 +'mmc bootbus' to set the required rate (see TRM) and 'mmc partconfig' to
  15 +set boot0 as the boot device.
  16 +U-Boot # setenv autoload no
  17 +U-Boot # usb start
  18 +U-Boot # dhcp
  19 +U-Boot # mmc dev 1 1
  20 +U-Boot # tftp ${loadaddr} omap5uevm/MLO
  21 +U-Boot # mmc write ${loadaddr} 0 100
  22 +U-Boot # tftp ${loadaddr} omap5uevm/u-boot.img
  23 +U-Boot # mmc write ${loadaddr} 300 400
  24 +U-Boot # mmc bootbus 1 2 0 2
  25 +U-Boot # mmc partconf 1 1 1 0
... ... @@ -131,36 +131,6 @@
131 131 "- display info of the current MMC device"
132 132 );
133 133  
134   -#ifdef CONFIG_SUPPORT_EMMC_BOOT
135   -static int boot_part_access(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
136   -{
137   - int err;
138   - err = mmc_boot_part_access(mmc, ack, part_num, access);
139   -
140   - if ((err == 0) && (access != 0)) {
141   - printf("\t\t\t!!!Notice!!!\n");
142   -
143   - printf("!You must close EMMC boot Partition");
144   - printf("after all images are written\n");
145   -
146   - printf("!EMMC boot partition has continuity");
147   - printf("at image writing time.\n");
148   -
149   - printf("!So, do not close the boot partition");
150   - printf("before all images are written.\n");
151   - return 0;
152   - } else if ((err == 0) && (access == 0))
153   - return 0;
154   - else if ((err != 0) && (access != 0)) {
155   - printf("EMMC boot partition-%d OPEN Failed.\n", part_num);
156   - return 1;
157   - } else {
158   - printf("EMMC boot partition-%d CLOSE Failed.\n", part_num);
159   - return 1;
160   - }
161   -}
162   -#endif
163   -
164 134 static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
165 135 {
166 136 enum mmc_state state;
... ... @@ -195,7 +165,7 @@
195 165 return 1;
196 166 else
197 167 return 0;
198   - } else if (strncmp(argv[1], "part", 4) == 0) {
  168 + } else if (strcmp(argv[1], "part") == 0) {
199 169 block_dev_desc_t *mmc_dev;
200 170 struct mmc *mmc;
201 171  
202 172  
203 173  
204 174  
... ... @@ -273,15 +243,16 @@
273 243  
274 244 return 0;
275 245 #ifdef CONFIG_SUPPORT_EMMC_BOOT
276   - } else if ((strcmp(argv[1], "open") == 0) ||
277   - (strcmp(argv[1], "close") == 0)) {
  246 + } else if (strcmp(argv[1], "partconf") == 0) {
278 247 int dev;
279 248 struct mmc *mmc;
280   - u8 part_num, access = 0;
  249 + u8 ack, part_num, access;
281 250  
282   - if (argc == 4) {
  251 + if (argc == 6) {
283 252 dev = simple_strtoul(argv[2], NULL, 10);
284   - part_num = simple_strtoul(argv[3], NULL, 10);
  253 + ack = simple_strtoul(argv[3], NULL, 10);
  254 + part_num = simple_strtoul(argv[4], NULL, 10);
  255 + access = simple_strtoul(argv[5], NULL, 10);
285 256 } else {
286 257 return CMD_RET_USAGE;
287 258 }
288 259  
289 260  
290 261  
291 262  
292 263  
... ... @@ -293,32 +264,53 @@
293 264 }
294 265  
295 266 if (IS_SD(mmc)) {
296   - printf("SD device cannot be opened/closed\n");
  267 + puts("PARTITION_CONFIG only exists on eMMC\n");
297 268 return 1;
298 269 }
299 270  
300   - if ((part_num <= 0) || (part_num > MMC_NUM_BOOT_PARTITION)) {
301   - printf("Invalid boot partition number:\n");
302   - printf("Boot partition number cannot be <= 0\n");
303   - printf("EMMC44 supports only 2 boot partitions\n");
  271 + /* acknowledge to be sent during boot operation */
  272 + return mmc_set_part_conf(mmc, ack, part_num, access);
  273 + } else if (strcmp(argv[1], "bootbus") == 0) {
  274 + int dev;
  275 + struct mmc *mmc;
  276 + u8 width, reset, mode;
  277 +
  278 + if (argc == 6) {
  279 + dev = simple_strtoul(argv[2], NULL, 10);
  280 + width = simple_strtoul(argv[3], NULL, 10);
  281 + reset = simple_strtoul(argv[4], NULL, 10);
  282 + mode = simple_strtoul(argv[5], NULL, 10);
  283 + } else {
  284 + return CMD_RET_USAGE;
  285 + }
  286 +
  287 + mmc = find_mmc_device(dev);
  288 + if (!mmc) {
  289 + printf("no mmc device at slot %x\n", dev);
304 290 return 1;
305 291 }
306 292  
307   - if (strcmp(argv[1], "open") == 0)
308   - access = part_num; /* enable R/W access to boot part*/
309   - else
310   - access = 0; /* No access to boot partition */
  293 + if (IS_SD(mmc)) {
  294 + puts("BOOT_BUS_WIDTH only exists on eMMC\n");
  295 + return 1;
  296 + }
311 297  
312 298 /* acknowledge to be sent during boot operation */
313   - return boot_part_access(mmc, 1, part_num, access);
314   -
315   - } else if (strcmp(argv[1], "bootpart") == 0) {
  299 + return mmc_set_boot_bus_width(mmc, width, reset, mode);
  300 + } else if (strcmp(argv[1], "bootpart-resize") == 0) {
316 301 int dev;
317   - dev = simple_strtoul(argv[2], NULL, 10);
  302 + struct mmc *mmc;
  303 + u32 bootsize, rpmbsize;
318 304  
319   - u32 bootsize = simple_strtoul(argv[3], NULL, 10);
320   - u32 rpmbsize = simple_strtoul(argv[4], NULL, 10);
321   - struct mmc *mmc = find_mmc_device(dev);
  305 + if (argc == 5) {
  306 + dev = simple_strtoul(argv[2], NULL, 10);
  307 + bootsize = simple_strtoul(argv[3], NULL, 10);
  308 + rpmbsize = simple_strtoul(argv[4], NULL, 10);
  309 + } else {
  310 + return CMD_RET_USAGE;
  311 + }
  312 +
  313 + mmc = find_mmc_device(dev);
322 314 if (!mmc) {
323 315 printf("no mmc device at slot %x\n", dev);
324 316 return 1;
... ... @@ -438,12 +430,12 @@
438 430 "mmc dev [dev] [part] - show or set current mmc device [partition]\n"
439 431 "mmc list - lists available devices\n"
440 432 #ifdef CONFIG_SUPPORT_EMMC_BOOT
441   - "mmc open <dev> <boot_partition>\n"
442   - " - Enable boot_part for booting and enable R/W access of boot_part\n"
443   - "mmc close <dev> <boot_partition>\n"
444   - " - Enable boot_part for booting and disable access to boot_part\n"
445   - "mmc bootpart <device num> <boot part size MB> <RPMB part size MB>\n"
446   - " - change sizes of boot and RPMB partitions of specified device\n"
  433 + "mmc bootbus dev boot_bus_width reset_boot_bus_width boot_mode\n"
  434 + " - Set the BOOT_BUS_WIDTH field of the specified device\n"
  435 + "mmc bootpart-resize <dev> <boot part size MB> <RPMB part size MB>\n"
  436 + " - Change sizes of boot and RPMB partitions of specified device\n"
  437 + "mmc partconf dev boot_ack boot_partition partition_access\n"
  438 + " - Change the bits of the PARTITION_CONFIG field of the specified device\n"
447 439 #endif
448 440 "mmc setdsr - set DSR register value\n"
449 441 );
common/spl/spl_mmc.c
... ... @@ -111,6 +111,30 @@
111 111 CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION,
112 112 CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME);
113 113 #endif
  114 +#ifdef CONFIG_SUPPORT_EMMC_BOOT
  115 + } else if (boot_mode == MMCSD_MODE_EMMCBOOT) {
  116 + /*
  117 + * We need to check what the partition is configured to.
  118 + * 1 and 2 match up to boot0 / boot1 and 7 is user data
  119 + * which is the first physical partition (0).
  120 + */
  121 + int part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
  122 +
  123 + if (part == 7)
  124 + part = 0;
  125 +
  126 + if (mmc_switch_part(0, part)) {
  127 +#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
  128 + puts("MMC partition switch failed\n");
  129 +#endif
  130 + hang();
  131 + }
  132 +#ifdef CONFIG_SPL_OS_BOOT
  133 + if (spl_start_uboot() || mmc_load_image_raw_os(mmc))
  134 +#endif
  135 + err = mmc_load_image_raw(mmc,
  136 + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
  137 +#endif
114 138 } else {
115 139 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
116 140 puts("spl: wrong MMC boot mode\n");
drivers/mmc/dw_mmc.c
... ... @@ -237,7 +237,7 @@
237 237 * host->bus_hz should be set from user.
238 238 */
239 239 if (host->get_mmc_clk)
240   - sclk = host->get_mmc_clk(host->dev_index);
  240 + sclk = host->get_mmc_clk(host);
241 241 else if (host->bus_hz)
242 242 sclk = host->bus_hz;
243 243 else {
drivers/mmc/exynos_dw_mmc.c
... ... @@ -29,9 +29,22 @@
29 29 dwmci_writel(host, DWMCI_CLKSEL, host->clksel_val);
30 30 }
31 31  
32   -unsigned int exynos_dwmci_get_clk(int dev_index)
  32 +unsigned int exynos_dwmci_get_clk(struct dwmci_host *host)
33 33 {
34   - return get_mmc_clk(dev_index);
  34 + unsigned long sclk;
  35 + int8_t clk_div;
  36 +
  37 + /*
  38 + * Since SDCLKIN is divided inside controller by the DIVRATIO
  39 + * value set in the CLKSEL register, we need to use the same output
  40 + * clock value to calculate the CLKDIV value.
  41 + * as per user manual:cclk_in = SDCLKIN / (DIVRATIO + 1)
  42 + */
  43 + clk_div = ((dwmci_readl(host, DWMCI_CLKSEL) >> DWMCI_DIVRATIO_BIT)
  44 + & DWMCI_DIVRATIO_MASK) + 1;
  45 + sclk = get_mmc_clk(host->dev_index);
  46 +
  47 + return sclk / clk_div;
35 48 }
36 49  
37 50 static void exynos_dwmci_board_init(struct dwmci_host *host)
... ... @@ -430,7 +430,7 @@
430 430 mmc->ocr = cmd.response[0];
431 431  
432 432 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
433   - mmc->rca = 0;
  433 + mmc->rca = 1;
434 434  
435 435 return 0;
436 436 }
437 437  
438 438  
439 439  
440 440  
441 441  
442 442  
443 443  
444 444  
445 445  
... ... @@ -1442,67 +1442,44 @@
1442 1442 }
1443 1443  
1444 1444 /*
1445   - * This function shall form and send the commands to open / close the
1446   - * boot partition specified by user.
  1445 + * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
  1446 + * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
  1447 + * and BOOT_MODE.
1447 1448 *
1448   - * Input Parameters:
1449   - * ack: 0x0 - No boot acknowledge sent (default)
1450   - * 0x1 - Boot acknowledge sent during boot operation
1451   - * part_num: User selects boot data that will be sent to master
1452   - * 0x0 - Device not boot enabled (default)
1453   - * 0x1 - Boot partition 1 enabled for boot
1454   - * 0x2 - Boot partition 2 enabled for boot
1455   - * access: User selects partitions to access
1456   - * 0x0 : No access to boot partition (default)
1457   - * 0x1 : R/W boot partition 1
1458   - * 0x2 : R/W boot partition 2
1459   - * 0x3 : R/W Replay Protected Memory Block (RPMB)
1460   - *
1461 1449 * Returns 0 on success.
1462 1450 */
1463   -int mmc_boot_part_access(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
  1451 +int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
1464 1452 {
1465 1453 int err;
1466   - struct mmc_cmd cmd;
1467 1454  
1468   - /* Boot ack enable, boot partition enable , boot partition access */
1469   - cmd.cmdidx = MMC_CMD_SWITCH;
1470   - cmd.resp_type = MMC_RSP_R1b;
  1455 + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
  1456 + EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
  1457 + EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
  1458 + EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
1471 1459  
1472   - cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
1473   - (EXT_CSD_PART_CONF << 16) |
1474   - ((EXT_CSD_BOOT_ACK(ack) |
1475   - EXT_CSD_BOOT_PART_NUM(part_num) |
1476   - EXT_CSD_PARTITION_ACCESS(access)) << 8);
1477   -
1478   - err = mmc_send_cmd(mmc, &cmd, NULL);
1479   - if (err) {
1480   - if (access) {
1481   - debug("mmc boot partition#%d open fail:Error1 = %d\n",
1482   - part_num, err);
1483   - } else {
1484   - debug("mmc boot partition#%d close fail:Error = %d\n",
1485   - part_num, err);
1486   - }
  1460 + if (err)
1487 1461 return err;
1488   - }
  1462 + return 0;
  1463 +}
1489 1464  
1490   - if (access) {
1491   - /* 4bit transfer mode at booting time. */
1492   - cmd.cmdidx = MMC_CMD_SWITCH;
1493   - cmd.resp_type = MMC_RSP_R1b;
  1465 +/*
  1466 + * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
  1467 + * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
  1468 + * PARTITION_ACCESS.
  1469 + *
  1470 + * Returns 0 on success.
  1471 + */
  1472 +int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
  1473 +{
  1474 + int err;
1494 1475  
1495   - cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
1496   - (EXT_CSD_BOOT_BUS_WIDTH << 16) |
1497   - ((1 << 0) << 8);
  1476 + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
  1477 + EXT_CSD_BOOT_ACK(ack) |
  1478 + EXT_CSD_BOOT_PART_NUM(part_num) |
  1479 + EXT_CSD_PARTITION_ACCESS(access));
1498 1480  
1499   - err = mmc_send_cmd(mmc, &cmd, NULL);
1500   - if (err) {
1501   - debug("mmc boot partition#%d open fail:Error2 = %d\n",
1502   - part_num, err);
1503   - return err;
1504   - }
1505   - }
  1481 + if (err)
  1482 + return err;
1506 1483 return 0;
1507 1484 }
1508 1485 #endif
drivers/mmc/zynq_sdhci.c
... ... @@ -23,7 +23,8 @@
23 23  
24 24 host->name = "zynq_sdhci";
25 25 host->ioaddr = (void *)regbase;
26   - host->quirks = SDHCI_QUIRK_NO_CD | SDHCI_QUIRK_WAIT_SEND_CMD;
  26 + host->quirks = SDHCI_QUIRK_NO_CD | SDHCI_QUIRK_WAIT_SEND_CMD |
  27 + SDHCI_QUIRK_BROKEN_R1B;
27 28 host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
28 29  
29 30 host->host_caps = MMC_MODE_HC;
include/configs/dra7xx_evm.h
... ... @@ -73,6 +73,8 @@
73 73 #define CONFIG_SPL_SPI_CS 0
74 74 #define CONFIG_SYS_SPI_U_BOOT_OFFS 0x20000
75 75  
  76 +#define CONFIG_SUPPORT_EMMC_BOOT
  77 +
76 78 /* USB xHCI HOST */
77 79 #define CONFIG_CMD_USB
78 80 #define CONFIG_USB_HOST
include/configs/omap5_uevm.h
... ... @@ -37,6 +37,7 @@
37 37 #define CONFIG_PARTITION_UUIDS
38 38 #define CONFIG_CMD_PART
39 39 #define CONFIG_HSMMC2_8BIT
  40 +#define CONFIG_SUPPORT_EMMC_BOOT
40 41  
41 42 /* Required support for the TCA642X GPIO we have on the uEVM */
42 43 #define CONFIG_TCA642X
... ... @@ -142,7 +142,7 @@
142 142  
143 143 void (*clksel)(struct dwmci_host *host);
144 144 void (*board_init)(struct dwmci_host *host);
145   - unsigned int (*get_mmc_clk)(int dev_index);
  145 + unsigned int (*get_mmc_clk)(struct dwmci_host *host);
146 146 };
147 147  
148 148 struct dwmci_idmac {
... ... @@ -187,6 +187,9 @@
187 187 #define EXT_CSD_BOOT_PART_NUM(x) (x << 3)
188 188 #define EXT_CSD_PARTITION_ACCESS(x) (x << 0)
189 189  
  190 +#define EXT_CSD_BOOT_BUS_WIDTH_MODE(x) (x << 3)
  191 +#define EXT_CSD_BOOT_BUS_WIDTH_RESET(x) (x << 2)
  192 +#define EXT_CSD_BOOT_BUS_WIDTH_WIDTH(x) (x)
190 193  
191 194 #define R1_ILLEGAL_COMMAND (1 << 22)
192 195 #define R1_APP_CMD (1 << 5)
... ... @@ -310,8 +313,10 @@
310 313 /* Function to change the size of boot partition and rpmb partitions */
311 314 int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
312 315 unsigned long rpmbsize);
313   -/* Function to send commands to open/close the specified boot partition */
314   -int mmc_boot_part_access(struct mmc *mmc, u8 ack, u8 part_num, u8 access);
  316 +/* Function to modify the PARTITION_CONFIG field of EXT_CSD */
  317 +int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access);
  318 +/* Function to modify the BOOT_BUS_WIDTH field of EXT_CSD */
  319 +int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode);
315 320  
316 321 /**
317 322 * Start device initialization and return immediately; it does not block on
... ... @@ -16,6 +16,7 @@
16 16 #define MMCSD_MODE_UNDEFINED 0
17 17 #define MMCSD_MODE_RAW 1
18 18 #define MMCSD_MODE_FAT 2
  19 +#define MMCSD_MODE_EMMCBOOT 3
19 20  
20 21 struct spl_image_info {
21 22 const char *name;