]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'master' of git://git.denx.de/u-boot-mmc
authorTom Rini <trini@ti.com>
Fri, 12 Dec 2014 20:02:00 +0000 (15:02 -0500)
committerTom Rini <trini@ti.com>
Fri, 12 Dec 2014 20:02:00 +0000 (15:02 -0500)
common/cmd_mmc.c
drivers/mmc/dw_mmc.c
drivers/mmc/exynos_dw_mmc.c
drivers/mmc/mmc.c
include/mmc.h

index 4286e2696363cab44b44772251a4f52c488395a2..96478e45c14039cd88a1a59427d0ec7f1a44d07e 100644 (file)
@@ -90,7 +90,8 @@ static void print_mmcinfo(struct mmc *mmc)
        puts("Capacity: ");
        print_size(mmc->capacity, "\n");
 
-       printf("Bus Width: %d-bit\n", mmc->bus_width);
+       printf("Bus Width: %d-bit%s\n", mmc->bus_width,
+                       mmc->ddr_mode ? " DDR" : "");
 }
 static struct mmc *init_mmc_device(int dev, bool force_init)
 {
index 785eed567c3f370e45fb3fc2febd6887750acaa7..b18c75dee2c815a7a9ddd82eac826109544cc3c0 100644 (file)
@@ -318,7 +318,7 @@ static void dwmci_set_ios(struct mmc *mmc)
        dwmci_writel(host, DWMCI_CTYPE, ctype);
 
        regs = dwmci_readl(host, DWMCI_UHS_REG);
-       if (mmc->card_caps & MMC_MODE_DDR_52MHz)
+       if (mmc->ddr_mode)
                regs |= DWMCI_DDR_MODE;
        else
                regs &= DWMCI_DDR_MODE;
index d96dfe16a538bba12a83b679608a3472e3c56e3d..dfa209bdeda0e39e0e95b513627f71107d14e25f 100644 (file)
@@ -101,7 +101,7 @@ static int exynos_dwmci_core_init(struct dwmci_host *host, int index)
        host->get_mmc_clk = exynos_dwmci_get_clk;
        /* Add the mmc channel to be registered with mmc core */
        if (add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ)) {
-               debug("dwmmc%d registration failed\n", index);
+               printf("DWMMC%d registration failed\n", index);
                return -1;
        }
        return 0;
@@ -146,7 +146,7 @@ static int do_dwmci_init(struct dwmci_host *host)
        flag = host->buswidth == 8 ? PINMUX_FLAG_8BIT_MODE : PINMUX_FLAG_NONE;
        err = exynos_pinmux_config(host->dev_id, flag);
        if (err) {
-               debug("DWMMC not configure\n");
+               printf("DWMMC%d not configure\n", index);
                return err;
        }
 
@@ -162,21 +162,22 @@ static int exynos_dwmci_get_config(const void *blob, int node,
        /* Extract device id for each mmc channel */
        host->dev_id = pinmux_decode_periph_id(blob, node);
 
+       host->dev_index = fdtdec_get_int(blob, node, "index", host->dev_id);
+       if (host->dev_index == host->dev_id)
+               host->dev_index = host->dev_id - PERIPH_ID_SDMMC0;
+
+
        /* Get the bus width from the device node */
        host->buswidth = fdtdec_get_int(blob, node, "samsung,bus-width", 0);
        if (host->buswidth <= 0) {
-               debug("DWMMC: Can't get bus-width\n");
+               printf("DWMMC%d: Can't get bus-width\n", host->dev_index);
                return -EINVAL;
        }
 
-       host->dev_index = fdtdec_get_int(blob, node, "index", host->dev_id);
-       if (host->dev_index == host->dev_id)
-               host->dev_index = host->dev_id - PERIPH_ID_SDMMC0;
-
        /* Set the base address from the device node */
        base = fdtdec_get_addr(blob, node, "reg");
        if (!base) {
-               debug("DWMMC: Can't get base address\n");
+               printf("DWMMC%d: Can't get base address\n", host->dev_index);
                return -EINVAL;
        }
        host->ioaddr = (void *)base;
@@ -184,7 +185,8 @@ static int exynos_dwmci_get_config(const void *blob, int node,
        /* Extract the timing info from the node */
        err =  fdtdec_get_int_array(blob, node, "samsung,timing", timing, 3);
        if (err) {
-               debug("Can't get sdr-timings for devider\n");
+               printf("DWMMC%d: Can't get sdr-timings for devider\n",
+                               host->dev_index);
                return -EINVAL;
        }
 
@@ -214,7 +216,7 @@ static int exynos_dwmci_process_node(const void *blob,
                host = &dwmci_host[i];
                err = exynos_dwmci_get_config(blob, node, host);
                if (err) {
-                       debug("%s: failed to decode dev %d\n", __func__, i);
+                       printf("%s: failed to decode dev %d\n", __func__, i);
                        return err;
                }
 
index 8436bc7f5d3c28eaf974efe57da48ae278e867c1..1eb9c2733948bf954aa00414824aa491adc4a4e3 100644 (file)
@@ -159,7 +159,7 @@ int mmc_set_blocklen(struct mmc *mmc, int len)
 {
        struct mmc_cmd cmd;
 
-       if (mmc->card_caps & MMC_MODE_DDR_52MHz)
+       if (mmc->ddr_mode)
                return 0;
 
        cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
@@ -486,7 +486,7 @@ static int mmc_change_freq(struct mmc *mmc)
        char cardtype;
        int err;
 
-       mmc->card_caps = 0;
+       mmc->card_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
 
        if (mmc_host_is_spi(mmc))
                return 0;
@@ -519,7 +519,7 @@ static int mmc_change_freq(struct mmc *mmc)
 
        /* High Speed is set, there are two types: 52MHz and 26MHz */
        if (cardtype & EXT_CSD_CARD_TYPE_52) {
-               if (cardtype & EXT_CSD_CARD_TYPE_DDR_52)
+               if (cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
                        mmc->card_caps |= MMC_MODE_DDR_52MHz;
                mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
        } else {
@@ -1001,6 +1001,9 @@ static int mmc_startup(struct mmc *mmc)
                case 6:
                        mmc->version = MMC_VERSION_4_5;
                        break;
+               case 7:
+                       mmc->version = MMC_VERSION_5_0;
+                       break;
                }
 
                /*
@@ -1022,6 +1025,21 @@ static int mmc_startup(struct mmc *mmc)
                        mmc->erase_grp_size =
                                ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
                                        MMC_MAX_BLOCK_LEN * 1024;
+                       /*
+                        * if high capacity and partition setting completed
+                        * SEC_COUNT is valid even if it is smaller than 2 GiB
+                        * JEDEC Standard JESD84-B45, 6.2.4
+                        */
+                       if (mmc->high_capacity &&
+                           (ext_csd[EXT_CSD_PARTITION_SETTING] &
+                            EXT_CSD_PARTITION_SETTING_COMPLETED)) {
+                               capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
+                                       (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
+                                       (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
+                                       (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
+                               capacity *= MMC_MAX_BLOCK_LEN;
+                               mmc->capacity_user = capacity;
+                       }
                } else {
                        /* Calculate the group size from the csd value. */
                        int erase_gsz, erase_gmul;
@@ -1103,8 +1121,10 @@ static int mmc_startup(struct mmc *mmc)
 
                /* An array to map CSD bus widths to host cap bits */
                static unsigned ext_to_hostcaps[] = {
-                       [EXT_CSD_DDR_BUS_WIDTH_4] = MMC_MODE_DDR_52MHz,
-                       [EXT_CSD_DDR_BUS_WIDTH_8] = MMC_MODE_DDR_52MHz,
+                       [EXT_CSD_DDR_BUS_WIDTH_4] =
+                               MMC_MODE_DDR_52MHz | MMC_MODE_4BIT,
+                       [EXT_CSD_DDR_BUS_WIDTH_8] =
+                               MMC_MODE_DDR_52MHz | MMC_MODE_8BIT,
                        [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
                        [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
                };
@@ -1116,13 +1136,13 @@ static int mmc_startup(struct mmc *mmc)
 
                for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
                        unsigned int extw = ext_csd_bits[idx];
+                       unsigned int caps = ext_to_hostcaps[extw];
 
                        /*
-                        * Check to make sure the controller supports
-                        * this bus width, if it's more than 1
+                        * Check to make sure the card and controller support
+                        * these capabilities
                         */
-                       if (extw != EXT_CSD_BUS_WIDTH_1 &&
-                                       !(mmc->cfg->host_caps & ext_to_hostcaps[extw]))
+                       if ((mmc->card_caps & caps) != caps)
                                continue;
 
                        err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
@@ -1131,26 +1151,33 @@ static int mmc_startup(struct mmc *mmc)
                        if (err)
                                continue;
 
+                       mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0;
                        mmc_set_bus_width(mmc, widths[idx]);
 
                        err = mmc_send_ext_csd(mmc, test_csd);
+
+                       if (err)
+                               continue;
+
                        /* Only compare read only fields */
-                       if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \
-                                   == test_csd[EXT_CSD_PARTITIONING_SUPPORT]
-                                && ext_csd[EXT_CSD_HC_WP_GRP_SIZE] \
-                                   == test_csd[EXT_CSD_HC_WP_GRP_SIZE] \
-                                && ext_csd[EXT_CSD_REV] \
-                                   == test_csd[EXT_CSD_REV]
-                                && ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] \
-                                   == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
-                                && memcmp(&ext_csd[EXT_CSD_SEC_CNT], \
-                                       &test_csd[EXT_CSD_SEC_CNT], 4) == 0) {
-
-                               mmc->card_caps |= ext_to_hostcaps[extw];
+                       if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
+                               == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
+                           ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
+                               == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
+                           ext_csd[EXT_CSD_REV]
+                               == test_csd[EXT_CSD_REV] &&
+                           ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
+                               == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
+                           memcmp(&ext_csd[EXT_CSD_SEC_CNT],
+                                  &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
                                break;
-                       }
+                       else
+                               err = SWITCH_ERR;
                }
 
+               if (err)
+                       return err;
+
                if (mmc->card_caps & MMC_MODE_HS) {
                        if (mmc->card_caps & MMC_MODE_HS_52MHz)
                                mmc->tran_speed = 52000000;
@@ -1161,6 +1188,12 @@ static int mmc_startup(struct mmc *mmc)
 
        mmc_set_clock(mmc, mmc->tran_speed);
 
+       /* Fix the block length for DDR mode */
+       if (mmc->ddr_mode) {
+               mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
+               mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
+       }
+
        /* fill in device description */
        mmc->block_dev.lun = 0;
        mmc->block_dev.type = 0;
@@ -1306,6 +1339,7 @@ int mmc_start_init(struct mmc *mmc)
        if (err)
                return err;
 
+       mmc->ddr_mode = 0;
        mmc_set_bus_width(mmc, 1);
        mmc_set_clock(mmc, 1);
 
@@ -1408,8 +1442,11 @@ void print_mmc_devices(char separator)
 
                printf("%s: %d", m->cfg->name, m->block_dev.dev);
 
-               if (entry->next != &mmc_devices)
-                       printf("%c ", separator);
+               if (entry->next != &mmc_devices) {
+                       printf("%c", separator);
+                       if (separator != '\n')
+                               puts (" ");
+               }
        }
 
        printf("\n");
index adffc35af028fc009bfc2d8619ca3d312073d86b..7ec255d882199c88dc7bf79f52857c87a796a46c 100644 (file)
@@ -31,6 +31,7 @@
 #define MMC_VERSION_4_3                (MMC_VERSION_MMC | 0x403)
 #define MMC_VERSION_4_41       (MMC_VERSION_MMC | 0x429)
 #define MMC_VERSION_4_5                (MMC_VERSION_MMC | 0x405)
+#define MMC_VERSION_5_0                (MMC_VERSION_MMC | 0x500)
 
 #define MMC_MODE_HS            (1 << 0)
 #define MMC_MODE_HS_52MHz      (1 << 1)
  * EXT_CSD fields
  */
 #define EXT_CSD_GP_SIZE_MULT           143     /* R/W */
+#define EXT_CSD_PARTITION_SETTING      155     /* R/W */
 #define EXT_CSD_PARTITIONS_ATTRIBUTE   156     /* R/W */
 #define EXT_CSD_PARTITIONING_SUPPORT   160     /* RO */
 #define EXT_CSD_RST_N_FUNCTION         162     /* R/W */
 #define EXT_CSD_BOOT_BUS_WIDTH_RESET(x)        (x << 2)
 #define EXT_CSD_BOOT_BUS_WIDTH_WIDTH(x)        (x)
 
+#define EXT_CSD_PARTITION_SETTING_COMPLETED    (1 << 0)
+
 #define R1_ILLEGAL_COMMAND             (1 << 22)
 #define R1_APP_CMD                     (1 << 5)
 
@@ -314,6 +318,7 @@ struct mmc {
        char init_in_progress;  /* 1 if we have done mmc_start_init() */
        char preinit;           /* start init as early as possible */
        uint op_cond_response;  /* the response byte from the last op_cond */
+       int ddr_mode;
 };
 
 int mmc_register(struct mmc *mmc);