From e75eaf100bdf01b94757e2b40365b46a7d380275 Mon Sep 17 00:00:00 2001 From: Lubomir Popov Date: Tue, 11 Nov 2014 12:25:42 +0200 Subject: mmc: Cosmetic fix for nicer, aligned device list printout If print_mmc_devices() was called with a '\n' separator (as done for example by the "mmc list" command), it offset the 2-nd and all subsequent lines by one space. Fixing this. Signed-off-by: Lubomir Popov --- drivers/mmc/mmc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 8436bc7..9dc924c 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1408,8 +1408,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"); -- cgit v1.1 From d7b2912991bb18db26b6c6b51cdc637142e21d3e Mon Sep 17 00:00:00 2001 From: Markus Niebel Date: Tue, 18 Nov 2014 15:11:42 +0100 Subject: MMC: fix user capacity for partitioned eMMC card if the card claims to be high capacity and the card is partitioned the capacity shall still be read from ext_csd SEC_COUNT even if the resulting capacity is smaller than 2 GiB Signed-off-by: Markus Niebel Acked-by: Jaehoon Chung --- drivers/mmc/mmc.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers/mmc') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 9dc924c..4a8cf65 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1022,6 +1022,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; -- cgit v1.1 From edab723b47bfba617efb55f97d01e273546ec2bf Mon Sep 17 00:00:00 2001 From: Markus Niebel Date: Tue, 18 Nov 2014 15:13:53 +0100 Subject: MMC: add MMC_VERSION_5_0 Signed-off-by: Markus Niebel Acked-by: Jaehoon Chung --- drivers/mmc/mmc.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/mmc') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 4a8cf65..99f03c9 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -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; } /* -- cgit v1.1 From dfcb683a31d4222c30a9ef5d4acea1142f6bde48 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Fri, 28 Nov 2014 20:42:33 +0900 Subject: mmc: exynos_dw-mmc: change debug message To debug more exactly, add the index for device. Signed-off-by: Jaehoon Chung --- drivers/mmc/exynos_dw_mmc.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index d96dfe1..dfa209b 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -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; } -- cgit v1.1 From 786e8f818c25265d12d5d06e257fe2b1ba516134 Mon Sep 17 00:00:00 2001 From: Andrew Gabbasov Date: Mon, 1 Dec 2014 06:59:09 -0600 Subject: mmc: Fix handling of bus widths and DDR card capabilities If the MMC_MODE_DDR_52MHz flag is set in card capabilities bitmask, it is never cleared, even if switching to DDR mode fails, and if the controller driver uses this flag to check the DDR mode, it can take incorrect actions. Also, DDR related checks in mmc_startup() incorrectly handle the case when the host controller does not support some bus widths (e.g. can't support 8 bits), since the host_caps is checked for DDR bit, but not bus width bits. This fix clearly separates using of card_caps bitmask, having there the flags for the capabilities, that the card can support, and actual operation mode, described outside of card_caps (i.e. bus_width and ddr_mode fields in mmc structure). Separate host controller drivers may need to be updated to use the actual flags. Respectively, the capabilities checks in mmc_startup are made more correct and clear. Also, some clean up is made with errors handling and code syntax layout. Signed-off-by: Andrew Gabbasov --- drivers/mmc/mmc.c | 52 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 21 deletions(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 99f03c9..a290031 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -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; @@ -1121,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, }; @@ -1134,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, @@ -1149,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; @@ -1324,6 +1333,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); -- cgit v1.1 From 201d5ac4388d66bf7a78e71c32939b3fc5779207 Mon Sep 17 00:00:00 2001 From: Andrew Gabbasov Date: Mon, 1 Dec 2014 06:59:10 -0600 Subject: mmc: Fix Dual Data Rate capability recognition Since the driver doesn't work in 1.2V or 1.8V signaling level modes, Dual Data Rate mode can be supported by the driver only if it is supported by the card in regular 3.3V mode. So, check for a particular single bit in card type field. Signed-off-by: Andrew Gabbasov --- drivers/mmc/mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index a290031..65d8b3a 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -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 { -- cgit v1.1 From 5af8f45cd049cf01790a17ff68e61303bc08abc3 Mon Sep 17 00:00:00 2001 From: Andrew Gabbasov Date: Mon, 1 Dec 2014 06:59:11 -0600 Subject: mmc: Fix block length for DDR mode Block length for write and read commands is fixed to 512 bytes when the card is in Dual Data Rate mode. If block length read from CSD is different, make sure the driver will use correct length in all further calculations and settings. Signed-off-by: Andrew Gabbasov --- drivers/mmc/mmc.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/mmc') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 65d8b3a..1eb9c27 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1188,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; -- cgit v1.1 From 2b8a9692f9d8a744b6a93a9bed115ca46541ca1f Mon Sep 17 00:00:00 2001 From: Andrew Gabbasov Date: Mon, 1 Dec 2014 06:59:12 -0600 Subject: mmc: dw_mmc: Use active DDR mode flag The card_caps bit should denote the card capability to use DDR mode, but we need the flag indicating that the DDR mode is active. Signed-off-by: Andrew Gabbasov --- drivers/mmc/dw_mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 785eed5..b18c75d 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -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; -- cgit v1.1