Re: [RFC PATCH] mmc: sdhci-of-arasan: Add the support for sdhci-5.1
On 08/11/2015 03:34 AM, Shawn Lin wrote: This patch adds the quirks and compatible string in sdhci-of-arasan.c to support sdhci-arasan5.1 version of controller. No documented controller IP version is found in the TRM, so we use ths version of command queueing engine integrated into this controller by arasan to specify our controller. Signed-off-by: Shawn Lin shawn@rock-chips.com --- Documentation/devicetree/bindings/mmc/arasan,sdhci.txt | 2 +- drivers/mmc/host/sdhci-of-arasan.c | 4 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt index 7e94903..da541c3 100644 --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt @@ -9,7 +9,7 @@ Device Tree Bindings for the Arasan SDHCI Controller Required Properties: - compatible: Compatibility string. Must be 'arasan,sdhci-8.9a' or -'arasan,sdhci-4.9a' +'arasan,sdhci-4.9a' or 'arasan,sdhci-5.1' - reg: From mmc bindings: Register location and length. - clocks: From clock bindings: Handles to clock inputs. - clock-names: From clock bindings: Tuple including clk_xin and clk_ahb diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index ef5a7d2..c9012f5 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -175,6 +175,9 @@ static int sdhci_arasan_probe(struct platform_device *pdev) if (of_device_is_compatible(pdev-dev.of_node, arasan,sdhci-4.9a)) { host-quirks |= SDHCI_QUIRK_NO_HISPD_BIT; host-quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; + } else if (of_device_is_compatible(pdev-dev.of_node, +arasan,sdhci-5.1)) { + host-quirks |= SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN; Is this broken Arasan version or just broken capability on your SoC? Thanks, Michal -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6] mmc: dw_mmc: add quirk for broken data transfer over scheme
Hi, Heiko. Is this patch based on ulf's tree? At my dw-mmc tree, this patch can't apply.. So if you're ok, i will rework this patch about my dw-mmc tree. how about? Best Regards, Jaehoon Chung On 08/10/2015 08:12 PM, Heiko Stübner wrote: From: Addy Ke addy...@rock-chips.com This patch add a new quirk to add a s/w timer to notify the driver to terminate current transfer and report a data timeout to the core, if DTO interrupt does NOT come within the given time. dw_mmc call mmc_request_done func to finish transfer depends on DTO interrupt. If DTO interrupt does not come in sending data state, the current transfer will be blocked. We got the reply from synopsys: There are two counters but both use the same value of [31:8] bits. Data timeout counter doesn't wait for stop clock and you should get DRTO even when the clock is not stopped. Host Starvation timeout counter is triggered with stop clock condition. This means that host should get DRTO and DTO interrupt. But this case really exists, when driver reads tuning data from card on RK3288-pink2 board. I measured waveforms by oscilloscope and found that card clock was always on and data lines were always holded high level in sending data state. There are two possibility that data over interrupt doesn't come in reading data state on RK3X SoCs: - get command done interrupt, but doesn't get any data-related interrupt. - get data error interrupt, but doesn't get data over interrupt. Signed-off-by: Addy Ke addy...@rock-chips.com Address review comments from Jaehoon Chung. Signed-off-by: Heiko Stuebner he...@sntech.de --- Changes in v2: - fix some typo. - remove extra timeout value (250ms). - remove dw_mci_dto_start_monitor func. - use broken-dto for new quirk and change Subject for it. Changes in v3: - Remove dts for broken-dto, just add this quirk in dw_mci_rockchip_init Changes in v4: - fix bug that may cause 32 bit overflow by (drto_clks * 1000). - doesn't call mod_timer in writing data state, becase TMOUT register only for reading data. Changes in v5: - fix some typo. - add a buffer for drto_ms. - move drto_ms related code to a helper function. Changes in v6: - better spare time comment - let dw_mci_set_drto start the timer itself drivers/mmc/host/dw_mmc-rockchip.c | 3 ++ drivers/mmc/host/dw_mmc.c | 64 -- include/linux/mmc/dw_mmc.h | 4 +++ 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc- rockchip.c index de15121..bc76aa2 100644 --- a/drivers/mmc/host/dw_mmc-rockchip.c +++ b/drivers/mmc/host/dw_mmc-rockchip.c @@ -73,6 +73,9 @@ static int dw_mci_rockchip_init(struct dw_mci *host) /* It is slot 8 on Rockchip SoCs */ host-sdio_id0 = 8; + /* It needs this quirk on all Rockchip SoCs */ + host-pdata-quirks |= DW_MCI_QUIRK_BROKEN_DTO; + return 0; } diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 4e95ca9..459e68b 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1528,6 +1528,20 @@ static int dw_mci_data_complete(struct dw_mci *host, struct mmc_data *data) return data-error; } +static void dw_mci_set_drto(struct dw_mci *host) +{ + unsigned int drto_clks; + unsigned int drto_ms; + + drto_clks = mci_readl(host, TMOUT) 8; + drto_ms = DIV_ROUND_UP(drto_clks, host-bus_hz / 1000); + + /* add a bit spare time */ + drto_ms += 10; + + mod_timer(host-dto_timer, jiffies + msecs_to_jiffies(drto_ms)); +} + static void dw_mci_tasklet_func(unsigned long priv) { struct dw_mci *host = (struct dw_mci *)priv; @@ -1605,8 +1619,16 @@ static void dw_mci_tasklet_func(unsigned long priv) } if (!test_and_clear_bit(EVENT_XFER_COMPLETE, - host-pending_events)) + host-pending_events)) { + /* + * If all data-related interrupts don't come + * within the given time in reading data state. + */ + if ((host-quirks DW_MCI_QUIRK_BROKEN_DTO) + (host-dir_status == DW_MCI_RECV_STATUS)) + dw_mci_set_drto(host); break; + } set_bit(EVENT_XFER_COMPLETE, host-completed_events); @@ -1639,8 +1661,17 @@ static void dw_mci_tasklet_func(unsigned long priv) case STATE_DATA_BUSY: if (!test_and_clear_bit(EVENT_DATA_COMPLETE, - host-pending_events)) + host-pending_events)) { +
[GIT PULL] Update dw-mmc controller
Dear, Ulf. Could you pull these patches into your repository? Best Regards, Jaehoon Chung The following changes since commit 77a5f675e2d80469b93c3dea1913c0450c4942be: mmc: block: add fixup of broken CMD23 for Sandisk card (2015-07-23 14:28:47 +0200) are available in the git repository at: https://github.com/jh80chung/dw-mmc.git tags/dw-mmc-for-ulf-v4.2 for you to fetch changes up to a4c8b2edf78584dc7148ce06208d0f12d3b04a1b: mmc: dw_mmc: add quirk for broken data transfer over scheme (2015-08-11 01:33:32 +0900) Addy Ke (1): mmc: dw_mmc: add quirk for broken data transfer over scheme Alexey Brodkin (1): mmc: dw_mmc: handle data blocks than 4kB if IDMAC is used Heiko Stuebner (1): mmc: dw_mmc: fix pio mode when internal dmac is enabled Jaehoon Chung (3): mmc: dw_mmc: fix the wrong condition checking mmc: dw_mmc: remove the unused blk_setting mmc: dw_mmc: print the message for deprecated property Shawn Lin (1): mmc: dw_mmc: Fix coding style issues drivers/mmc/host/dw_mmc-rockchip.c | 3 + drivers/mmc/host/dw_mmc.c | 284 + include/linux/mmc/dw_mmc.h | 5 +- 3 files changed, 204 insertions(+), 88 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Initial signal voltage ?
in mmc_power_up() we have: /* Try to set signal voltage to 3.3V but fall back to 1.8v or 1.2v */ if (__mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330) == 0) dev_err(mmc_dev(host), Initial signal voltage of 3.3v\n); else if (__mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180) == 0) dev_err(mmc_dev(host), Initial signal voltage of 1.8v\n); else if (__mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120) == 0) dev_err(mmc_dev(host), Initial signal voltage of 1.2v\n); Here one jut brutally tries to set the initial power to 3.3 but nowhere in general code there is a check if the controller can handle this w.r.t HOST CAPS. Where should this check be performed, I am guessing either here or in sdhci? This is all new to me so I am just throwing this out there Jocke-- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] mmc: dw_mmc: fix the wrong condition checking
Hi Jaehoon On Thu, Aug 6, 2015 at 12:53 PM, Jaehoon Chung jh80.ch...@samsung.com wrote: When num-slots is lower than 1, it's right that should be returned -ENODEV. make sense. Signed-off-by: Jaehoon Chung jh80.ch...@samsung.com Reviewed-by: Alim Akhtar alim.akh...@samsung.com Tested-by: Alim Akhtar alim.akh...@samsung.com --- drivers/mmc/host/dw_mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 3c0e199..de88e64 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -2760,7 +2760,7 @@ int dw_mci_probe(struct dw_mci *host) } } - if (host-pdata-num_slots 1) { + if (host-pdata-num_slots 1) { dev_err(host-dev, Platform data must supply num_slots.\n); return -ENODEV; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- Regards, Alim -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v4 1/9] mmc: dw_mmc: Add external dma interface support
Hi Shawn On Thu, Aug 6, 2015 at 12:14 PM, Shawn Lin shawn@rock-chips.com wrote: DesignWare MMC Controller can supports two types of DMA mode: external dma and internal dma. We get a RK312x platform integrated dw_mmc and ARM pl330 dma controller. This patch add edmac ops to support these platforms. I've tested it on RK312x platform with edmac mode and RK3288 platform with idmac mode. Just curious to know if their are any performance (read/write) difference with Idmac and edmac? Signed-off-by: Shawn Lin shawn@rock-chips.com --- Changes in v4: - remove host-trans_mode and use host-use_dma to indicate transfer mode. - remove all bt-bindings' changes since we don't need new properities. - check transfer mode at runtime by reading HCON reg - spilt defconfig changes for each sub-architecture - fix the title of cover letter - reuse some code for reducing code size Changes in v3: - choose transfer mode at runtime - remove all CONFIG_MMC_DW_IDMAC config option - add supports-idmac property for some platforms Changes in v2: - Fix typo of dev_info msg - remove unused dmach from declaration of dw_mci_dma_slave drivers/mmc/host/Kconfig| 11 +- drivers/mmc/host/dw_mmc-pltfm.c | 2 + drivers/mmc/host/dw_mmc.c | 258 include/linux/mmc/dw_mmc.h | 27 - 4 files changed, 232 insertions(+), 66 deletions(-) diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 6a0f9c7..a86c0eb 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -607,15 +607,7 @@ config MMC_DW help This selects support for the Synopsys DesignWare Mobile Storage IP block, this provides host support for SD and MMC interfaces, in both - PIO and external DMA modes. - -config MMC_DW_IDMAC - bool Internal DMAC interface - depends on MMC_DW - help - This selects support for the internal DMAC block within the Synopsys - Designware Mobile Storage IP block. This disables the external DMA - interface. + PIO, internal DMA mode and external DMA modes. config MMC_DW_PLTFM tristate Synopsys Designware MCI Support as platform device @@ -644,7 +636,6 @@ config MMC_DW_K3 tristate K3 specific extensions for Synopsys DW Memory Card Interface depends on MMC_DW select MMC_DW_PLTFM - select MMC_DW_IDMAC help This selects support for Hisilicon K3 SoC specific extensions to the Synopsys DesignWare Memory Card Interface driver. Select this option diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c index ec6dbcd..7e1d13b 100644 --- a/drivers/mmc/host/dw_mmc-pltfm.c +++ b/drivers/mmc/host/dw_mmc-pltfm.c @@ -59,6 +59,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev, host-pdata = pdev-dev.platform_data; regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + /* Get registers' physical base address */ + host-phy_regs = (void *)(regs-start); host-regs = devm_ioremap_resource(pdev-dev, regs); if (IS_ERR(host-regs)) return PTR_ERR(host-regs); diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 40e9d8e..5d6cdff 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -56,7 +56,7 @@ #define DW_MCI_FREQ_MAX2 /* unit: HZ */ #define DW_MCI_FREQ_MIN40 /* unit: HZ */ -#ifdef CONFIG_MMC_DW_IDMAC + #define IDMAC_INT_CLR (SDMMC_IDMAC_INT_AI | SDMMC_IDMAC_INT_NI | \ SDMMC_IDMAC_INT_CES | SDMMC_IDMAC_INT_DU | \ SDMMC_IDMAC_INT_FBE | SDMMC_IDMAC_INT_RI | \ @@ -99,7 +99,6 @@ struct idmac_desc { __le32 des3; /* buffer 2 physical address */ }; -#endif /* CONFIG_MMC_DW_IDMAC */ static bool dw_mci_reset(struct dw_mci *host); static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset); @@ -403,7 +402,6 @@ static int dw_mci_get_dma_dir(struct mmc_data *data) return DMA_FROM_DEVICE; } -#ifdef CONFIG_MMC_DW_IDMAC static void dw_mci_dma_cleanup(struct dw_mci *host) { struct mmc_data *data = host-data; @@ -441,12 +439,21 @@ static void dw_mci_idmac_stop_dma(struct dw_mci *host) mci_writel(host, BMOD, temp); } -static void dw_mci_idmac_complete_dma(struct dw_mci *host) +static void dw_mci_dmac_complete_dma(void *arg) { + struct dw_mci *host = arg; struct mmc_data *data = host-data; dev_vdbg(host-dev, DMA complete\n); + if (host-use_dma == TRANS_MODE_EDMAC) + if (data (data-flags MMC_DATA_READ)) + /* Invalidate cache after read */ + dma_sync_sg_for_cpu(mmc_dev(host-cur_slot-mmc), + data-sg,
Re: [PATCH 2/3] mmc: dw_mmc: remove the unused blk_setting
Hi Jaehoon On Thu, Aug 6, 2015 at 12:53 PM, Jaehoon Chung jh80.ch...@samsung.com wrote: blk_setting doesn't use anywhere. This does not apply cleanly on Ulf's next branch. Probably this has dependency on https://patchwork.kernel.org/patch/6930201/ Signed-off-by: Jaehoon Chung jh80.ch...@samsung.com --- Anyway, patch looks good so, Reviewed-by: Alim Akhtar alim.akh...@samsung.com Tested on exynos5800, no functionality changes, so Tested-by: Alim Akhtar alim.akh...@samsung.com drivers/mmc/host/dw_mmc.c | 34 +- include/linux/mmc/dw_mmc.h | 1 - 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index de88e64..091df65 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -2436,28 +2436,20 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) if (ret) goto err_host_allocated; - if (host-pdata-blk_settings) { - mmc-max_segs = host-pdata-blk_settings-max_segs; - mmc-max_blk_size = host-pdata-blk_settings-max_blk_size; - mmc-max_blk_count = host-pdata-blk_settings-max_blk_count; - mmc-max_req_size = host-pdata-blk_settings-max_req_size; - mmc-max_seg_size = host-pdata-blk_settings-max_seg_size; + /* Useful defaults if platform data is unset. */ + if (host-use_dma) { + mmc-max_segs = host-ring_size; + mmc-max_blk_size = 65536; + mmc-max_seg_size = 0x1000; + mmc-max_req_size = mmc-max_seg_size * host-ring_size; + mmc-max_blk_count = mmc-max_req_size / 512; } else { - /* Useful defaults if platform data is unset. */ - if (host-use_dma) { - mmc-max_segs = host-ring_size; - mmc-max_blk_size = 65536; - mmc-max_seg_size = 0x1000; - mmc-max_req_size = mmc-max_seg_size * host-ring_size; - mmc-max_blk_count = mmc-max_req_size / 512; - } else { - mmc-max_segs = 64; - mmc-max_blk_size = 65536; /* BLKSIZ is 16 bits */ - mmc-max_blk_count = 512; - mmc-max_req_size = mmc-max_blk_size * - mmc-max_blk_count; - mmc-max_seg_size = mmc-max_req_size; - } + mmc-max_segs = 64; + mmc-max_blk_size = 65536; /* BLKSIZ is 16 bits */ + mmc-max_blk_count = 512; + mmc-max_req_size = mmc-max_blk_size * + mmc-max_blk_count; + mmc-max_seg_size = mmc-max_req_size; } if (dw_mci_get_cd(mmc)) diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h index 5be9767..9c06f2d 100644 --- a/include/linux/mmc/dw_mmc.h +++ b/include/linux/mmc/dw_mmc.h @@ -259,7 +259,6 @@ struct dw_mci_board { struct dw_mci_dma_ops *dma_ops; struct dma_pdata *data; - struct block_settings *blk_settings; }; #endif /* LINUX_MMC_DW_MMC_H */ -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- Regards, Alim -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v4 1/9] mmc: dw_mmc: Add external dma interface support
在 2015/8/11 2:03, Alim Akhtar 写道: Hi Shawn On Thu, Aug 6, 2015 at 12:14 PM, Shawn Lin shawn@rock-chips.com wrote: DesignWare MMC Controller can supports two types of DMA mode: external dma and internal dma. We get a RK312x platform integrated dw_mmc and ARM pl330 dma controller. This patch add edmac ops to support these platforms. I've tested it on RK312x platform with edmac mode and RK3288 platform with idmac mode. Just curious to know if their are any performance (read/write) difference with Idmac and edmac? yes, actually the performance with edmac is worse than that does with idmac since other peripheral blocks(e.g:I2C/uart/i2s etc.) share generic DMA with it that means dw_mmc has to compete with them to request the free channel and be shceduled if generic DMA is busy. Signed-off-by: Shawn Lin shawn@rock-chips.com --- Changes in v4: - remove host-trans_mode and use host-use_dma to indicate transfer mode. - remove all bt-bindings' changes since we don't need new properities. - check transfer mode at runtime by reading HCON reg - spilt defconfig changes for each sub-architecture - fix the title of cover letter - reuse some code for reducing code size Changes in v3: - choose transfer mode at runtime - remove all CONFIG_MMC_DW_IDMAC config option - add supports-idmac property for some platforms Changes in v2: - Fix typo of dev_info msg - remove unused dmach from declaration of dw_mci_dma_slave drivers/mmc/host/Kconfig| 11 +- drivers/mmc/host/dw_mmc-pltfm.c | 2 + drivers/mmc/host/dw_mmc.c | 258 include/linux/mmc/dw_mmc.h | 27 - 4 files changed, 232 insertions(+), 66 deletions(-) diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 6a0f9c7..a86c0eb 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -607,15 +607,7 @@ config MMC_DW help This selects support for the Synopsys DesignWare Mobile Storage IP block, this provides host support for SD and MMC interfaces, in both - PIO and external DMA modes. - -config MMC_DW_IDMAC - bool Internal DMAC interface - depends on MMC_DW - help - This selects support for the internal DMAC block within the Synopsys - Designware Mobile Storage IP block. This disables the external DMA - interface. + PIO, internal DMA mode and external DMA modes. config MMC_DW_PLTFM tristate Synopsys Designware MCI Support as platform device @@ -644,7 +636,6 @@ config MMC_DW_K3 tristate K3 specific extensions for Synopsys DW Memory Card Interface depends on MMC_DW select MMC_DW_PLTFM - select MMC_DW_IDMAC help This selects support for Hisilicon K3 SoC specific extensions to the Synopsys DesignWare Memory Card Interface driver. Select this option diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c index ec6dbcd..7e1d13b 100644 --- a/drivers/mmc/host/dw_mmc-pltfm.c +++ b/drivers/mmc/host/dw_mmc-pltfm.c @@ -59,6 +59,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev, host-pdata = pdev-dev.platform_data; regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + /* Get registers' physical base address */ + host-phy_regs = (void *)(regs-start); host-regs = devm_ioremap_resource(pdev-dev, regs); if (IS_ERR(host-regs)) return PTR_ERR(host-regs); diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 40e9d8e..5d6cdff 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -56,7 +56,7 @@ #define DW_MCI_FREQ_MAX2 /* unit: HZ */ #define DW_MCI_FREQ_MIN40 /* unit: HZ */ -#ifdef CONFIG_MMC_DW_IDMAC + #define IDMAC_INT_CLR (SDMMC_IDMAC_INT_AI | SDMMC_IDMAC_INT_NI | \ SDMMC_IDMAC_INT_CES | SDMMC_IDMAC_INT_DU | \ SDMMC_IDMAC_INT_FBE | SDMMC_IDMAC_INT_RI | \ @@ -99,7 +99,6 @@ struct idmac_desc { __le32 des3; /* buffer 2 physical address */ }; -#endif /* CONFIG_MMC_DW_IDMAC */ static bool dw_mci_reset(struct dw_mci *host); static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset); @@ -403,7 +402,6 @@ static int dw_mci_get_dma_dir(struct mmc_data *data) return DMA_FROM_DEVICE; } -#ifdef CONFIG_MMC_DW_IDMAC static void dw_mci_dma_cleanup(struct dw_mci *host) { struct mmc_data *data = host-data; @@ -441,12 +439,21 @@ static void dw_mci_idmac_stop_dma(struct dw_mci *host) mci_writel(host, BMOD, temp); } -static void dw_mci_idmac_complete_dma(struct dw_mci *host) +static void dw_mci_dmac_complete_dma(void *arg) { + struct dw_mci *host = arg; struct mmc_data *data = host-data; dev_vdbg(host-dev, DMA complete\n); + if (host-use_dma ==
[PATCH v2] mmc: sdhci-of-esdhc: add workaround for pre divider initial value
For eSDHC(version 2.3), the pre divider only could divide base clock by 2 at least. Add workaround for this to avoid unexpected issue. Signed-off-by: Yangbo Lu yangbo...@freescale.com --- drivers/mmc/host/sdhci-of-esdhc.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 797be75..653f335 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -208,6 +208,12 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) if (clock == 0) return; + /* Workaround to start pre_div at 2 for VNN VENDOR_V_23 */ + temp = esdhc_readw(host, SDHCI_HOST_VERSION); + temp = (temp SDHCI_VENDOR_VER_MASK) SDHCI_VENDOR_VER_SHIFT; + if (temp VENDOR_V_23) + pre_div = 2; + /* Workaround to reduce the clock frequency for p1010 esdhc */ if (of_find_compatible_node(NULL, NULL, fsl,p1010-esdhc)) { if (clock 2000) -- 2.1.0.27.g96db324 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mmc: sdhci-of-arasan: Add the support for sdhci-5.1
This patch adds the quirks and compatible string in sdhci-of-arasan.c to support sdhci-arasan5.1 version of controller. Signed-off-by: Shawn Lin shawn@rock-chips.com --- Documentation/devicetree/bindings/mmc/arasan,sdhci.txt | 2 +- drivers/mmc/host/sdhci-of-arasan.c | 4 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt index 7e94903..da541c3 100644 --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt @@ -9,7 +9,7 @@ Device Tree Bindings for the Arasan SDHCI Controller Required Properties: - compatible: Compatibility string. Must be 'arasan,sdhci-8.9a' or -'arasan,sdhci-4.9a' +'arasan,sdhci-4.9a' or 'arasan,sdhci-5.1' - reg: From mmc bindings: Register location and length. - clocks: From clock bindings: Handles to clock inputs. - clock-names: From clock bindings: Tuple including clk_xin and clk_ahb diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index ef5a7d2..c9012f5 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -175,6 +175,9 @@ static int sdhci_arasan_probe(struct platform_device *pdev) if (of_device_is_compatible(pdev-dev.of_node, arasan,sdhci-4.9a)) { host-quirks |= SDHCI_QUIRK_NO_HISPD_BIT; host-quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; + } else if (of_device_is_compatible(pdev-dev.of_node, + arasan,sdhci-5.1)) { + host-quirks |= SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN; } sdhci_get_of_property(pdev); @@ -217,6 +220,7 @@ static int sdhci_arasan_remove(struct platform_device *pdev) static const struct of_device_id sdhci_arasan_of_match[] = { { .compatible = arasan,sdhci-8.9a }, + { .compatible = arasan,sdhci-5.1 }, { .compatible = arasan,sdhci-4.9a }, { } }; -- 2.3.7 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH] mmc: sdhci-of-arasan: Add the support for sdhci-5.1
This patch adds the quirks and compatible string in sdhci-of-arasan.c to support sdhci-arasan5.1 version of controller. No documented controller IP version is found in the TRM, so we use ths version of command queueing engine integrated into this controller by arasan to specify our controller. Signed-off-by: Shawn Lin shawn@rock-chips.com --- Documentation/devicetree/bindings/mmc/arasan,sdhci.txt | 2 +- drivers/mmc/host/sdhci-of-arasan.c | 4 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt index 7e94903..da541c3 100644 --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt @@ -9,7 +9,7 @@ Device Tree Bindings for the Arasan SDHCI Controller Required Properties: - compatible: Compatibility string. Must be 'arasan,sdhci-8.9a' or -'arasan,sdhci-4.9a' +'arasan,sdhci-4.9a' or 'arasan,sdhci-5.1' - reg: From mmc bindings: Register location and length. - clocks: From clock bindings: Handles to clock inputs. - clock-names: From clock bindings: Tuple including clk_xin and clk_ahb diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index ef5a7d2..c9012f5 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -175,6 +175,9 @@ static int sdhci_arasan_probe(struct platform_device *pdev) if (of_device_is_compatible(pdev-dev.of_node, arasan,sdhci-4.9a)) { host-quirks |= SDHCI_QUIRK_NO_HISPD_BIT; host-quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; + } else if (of_device_is_compatible(pdev-dev.of_node, + arasan,sdhci-5.1)) { + host-quirks |= SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN; } sdhci_get_of_property(pdev); @@ -217,6 +220,7 @@ static int sdhci_arasan_remove(struct platform_device *pdev) static const struct of_device_id sdhci_arasan_of_match[] = { { .compatible = arasan,sdhci-8.9a }, + { .compatible = arasan,sdhci-5.1 }, { .compatible = arasan,sdhci-4.9a }, { } }; -- 2.3.7 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mmc: sdhci-of-arasan: Add the support for sdhci-5.1
On 2015/8/11 9:14, Shawn Lin wrote: This patch adds the quirks and compatible string in sdhci-of-arasan.c to support sdhci-arasan5.1 version of controller. Sorry for wrong send-email ops, pls ignore this patch :( Signed-off-by: Shawn Lin shawn@rock-chips.com --- Documentation/devicetree/bindings/mmc/arasan,sdhci.txt | 2 +- drivers/mmc/host/sdhci-of-arasan.c | 4 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt index 7e94903..da541c3 100644 --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt @@ -9,7 +9,7 @@ Device Tree Bindings for the Arasan SDHCI Controller Required Properties: - compatible: Compatibility string. Must be 'arasan,sdhci-8.9a' or -'arasan,sdhci-4.9a' +'arasan,sdhci-4.9a' or 'arasan,sdhci-5.1' - reg: From mmc bindings: Register location and length. - clocks: From clock bindings: Handles to clock inputs. - clock-names: From clock bindings: Tuple including clk_xin and clk_ahb diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index ef5a7d2..c9012f5 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -175,6 +175,9 @@ static int sdhci_arasan_probe(struct platform_device *pdev) if (of_device_is_compatible(pdev-dev.of_node, arasan,sdhci-4.9a)) { host-quirks |= SDHCI_QUIRK_NO_HISPD_BIT; host-quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; + } else if (of_device_is_compatible(pdev-dev.of_node, + arasan,sdhci-5.1)) { + host-quirks |= SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN; } sdhci_get_of_property(pdev); @@ -217,6 +220,7 @@ static int sdhci_arasan_remove(struct platform_device *pdev) static const struct of_device_id sdhci_arasan_of_match[] = { { .compatible = arasan,sdhci-8.9a }, + { .compatible = arasan,sdhci-5.1 }, { .compatible = arasan,sdhci-4.9a }, { } }; -- Shawn Lin -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] i.MX25/35/SDHCI: switch off DMA usage
Hello, On Wednesday 22 April 2015 15:33:00, Dong Aisheng wrote: On Friday 27 March 2015 12:44:03 Dong Aisheng wrote: On Fri, Mar 27, 2015 at 11:52:04AM +0100, Juergen Borleis wrote: DMA and the required overhead on very small data blocks seems an expensive operation. Due to erratum ENGCM07207 for i.MX25 and i.MX35 SoCs the support for multiblock transfers is disabled which results into a huge amount of single 512 byte sector transfers and interrupts. This slows down the transmission speed to below 500 kiB/s (even at 50 MHz SD card clock). Using PIO instead of DMA to avoid ENGCM07207 happens and re-enabling multiblock transfers again improve the transmission capability up to about 2.5 MiB/s. I'm still not sure if ENGCM07207 is related to DMA only and can not happen when PIO is used instead. Someone out there with experience regarding this topic? The errata does not state it's related to DMA only. http://cache.freescale.com/files/dsp/doc/errata/IMX35CE.pdf I could double check with our IC guys to confirm it. Gentle ping. Hi Juergen, Got the info from our IC guy. PIO mode is not related to AHB access, so AHB hang is not exist. But, he supposes the incorrect state machine of IP after sending CMD12 should also exist on PIO mode. We may still needs reset the controller after sending CMD12.(Reset before sending CMD12 should also work) BTW the errata already indicates a workaround for AHB hang: To abort data transfers on the AHB, software can reset the eSDHC by writing 1 to SYSCTL[24] (RSTA). So the issue could be avoided by reset controller. And the current SDHCI driver already does reset if any error(cmd or data) happens, and current MMC core seems only sending stop command when meets error. (not sending stop during normal transfer). So it looks to me the issue may already be workarounded and can not be reproduced. I'm not sure if anyone really meets the issue. By googling the original post of this patch, it seems the patch owner also did not reproduce this issue. See: http://lists.infradead.org/pipermail/linux-arm-kernel/2010-October/029818.html I would suggest someone who has the MX35/MX25 boards, to run the test again by manually triggering a data error.(e.g: shorting data line to ground during transfer). Then to see if the controller can still work well. If can not reproduce, then we can remove this errata and back to DMA mode. I did some timing tests on my imx35 based board by removing the SDHCI_QUIRK_NO_MULTIBLOCK. Patches are inlined below. Current v4.2-rc6: # time dd if=/dev/mmcblk0 of=/dev/null bs=1M count=100 100+0 records in 100+0 records out real3m 8.40s user0m 0.02s sys 0m 3.67s Current v4.2-rc6 + patch1: # time dd if=/dev/mmcblk0 of=/dev/null bs=1M count=100 100+0 records in 100+0 records out real0m 5.90s user0m 0.02s sys 0m 1.43s So apparently using multiblock transfers increases the performance considerably. I tried your suggestion to short a data line (DAT0 in my case) to GND. The transfers fail with data CRC errors. So far as expected. But after releasing short DAT0 to GND the data CRC errors remain. I can only get the transfers back to work when unplugging/pluggin the card or reboot the system. But this behavior is also the case when using SDHCI_QUIRK_NO_MULTIBLOCK, aka. the current state. I have no explanation for that. Sample error message is: [ 297.671266] mmcblk0: error -84 transferring data, sector 506, nr 6, cmd response 0x900, card status 0x0 So card state 0x900 is fine. I also get the same when doing # cat /sys/kernel/debug/mmc0/mmc0\:1234/status 0900 So I cannot say anything if using multiblock transfers has any negative effect. Up to now it has the same behavior regarding data crc errors as running without multiblock. While at it I was curious why ADMA was disabled at all. So I did another test _with_ multiblock transfer and ADMA. Current v4.2-rc6 + patch2: # time dd if=/dev/mmcblk0 of=/dev/null bs=1M count=100 100+0 records in 100+0 records out real0m 5.28s user0m 0.00s sys 0m 1.26s Everything seems ok so far. Why has ADMA been disabled at all? Checking git history this quirk was added with the initial commit 95f25efe0ce22e28d61722d655d2ef582f5f7520 (mmc: sdhci-pltfm: add -pltfm driver for imx35/51). Any comments regarding multiblock and (not so) broken ADMA? Best regard, Alexander patch1: 8-- diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index c6b9f64..bc82abe 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -1065,8 +1065,7 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) if (imx_data-socdata-flags ESDHC_FLAG_ENGCM07207) /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */ -
[PATCH v5 2/6] mmc: sdhci-esdhc-imx: add tuning-step seting support
tuning-step is the delay cell steps in tuning procedure. The default value of tuning-step is 1. Some boards or cards need another value to pass the tuning procedure. For example, imx7d-sdb board need the tuning-step value as 2, otherwise it can't pass the tuning procedure. So this patch add the tuning-step setting in driver, so that user can set the tuning-step value in dts. Signed-off-by: Haibo Chen haibo.c...@freescale.com --- drivers/mmc/host/sdhci-esdhc-imx.c | 9 + include/linux/platform_data/mmc-esdhc-imx.h | 1 + 2 files changed, 10 insertions(+) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 2a816ad..03c9f33 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -75,6 +75,7 @@ #define ESDHC_STD_TUNING_EN(1 24) /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ #define ESDHC_TUNING_START_TAP 0x1 +#define ESDHC_TUNING_STEP_SHIFT16 /* pinctrl state */ #define ESDHC_PINCTRL_STATE_100MHZ state_100mhz @@ -474,6 +475,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) } else if (imx_data-socdata-flags ESDHC_FLAG_STD_TUNING) { u32 v = readl(host-ioaddr + SDHCI_ACMD12_ERR); u32 m = readl(host-ioaddr + ESDHC_MIX_CTRL); + u32 tuning_ctrl; if (val SDHCI_CTRL_TUNED_CLK) { v |= ESDHC_MIX_CTRL_SMPCLK_SEL; } else { @@ -484,6 +486,11 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) if (val SDHCI_CTRL_EXEC_TUNING) { v |= ESDHC_MIX_CTRL_EXE_TUNE; m |= ESDHC_MIX_CTRL_FBCLK_SEL; + tuning_ctrl = readl(host-ioaddr + ESDHC_TUNING_CTRL); + tuning_ctrl |= ESDHC_STD_TUNING_EN | ESDHC_TUNING_START_TAP; + if (imx_data-boarddata.tuning_step) + tuning_ctrl |= imx_data-boarddata.tuning_step ESDHC_TUNING_STEP_SHIFT; + writel(tuning_ctrl, host-ioaddr + ESDHC_TUNING_CTRL); } else { v = ~ESDHC_MIX_CTRL_EXE_TUNE; } @@ -965,6 +972,8 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev, if (gpio_is_valid(boarddata-wp_gpio)) boarddata-wp_type = ESDHC_WP_GPIO; + of_property_read_u32(np, fsl,tuning-step, boarddata-tuning_step); + if (of_find_property(np, no-1-8-v, NULL)) boarddata-support_vsel = false; else diff --git a/include/linux/platform_data/mmc-esdhc-imx.h b/include/linux/platform_data/mmc-esdhc-imx.h index e1571ef..95ccab3 100644 --- a/include/linux/platform_data/mmc-esdhc-imx.h +++ b/include/linux/platform_data/mmc-esdhc-imx.h @@ -45,5 +45,6 @@ struct esdhc_platform_data { int max_bus_width; bool support_vsel; unsigned int delay_line; + unsigned int tuning_step; /* The delay cell steps in tuning procedure */ }; #endif /* __ASM_ARCH_IMX_ESDHC_H */ -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 0/6] mmc: imx: a few fixes and new feature
Changes for v5: -move the clear exist timing setting to a common place rather than only in HS200 mode. -put the patch 6 ahead of patch 5. Haibo Chen (6): mmc: sdhci-esdhc-imx: add imx7d support and support HS400 mmc: sdhci-esdhc-imx: add tuning-step seting support mmc: sdhci-esdhc-imx: add compatible string in bingding doc ARM: dts: imx7d-sdb: add eMMC5.0 support mmc: sdhci-esdhc-imx: set back the burst_length_enable bit to 1 mmc: sdhci-esdhc-imx: change default watermark level and burst length .../devicetree/bindings/mmc/fsl-imx-esdhc.txt | 6 ++ arch/arm/boot/dts/imx7d-sdb.dts| 13 +++ drivers/mmc/host/sdhci-esdhc-imx.c | 116 - include/linux/platform_data/mmc-esdhc-imx.h| 1 + 4 files changed, 132 insertions(+), 4 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 4/6] ARM: dts: imx7d-sdb: add eMMC5.0 support
imx7d-sdb board has a eMMC5.0 on usdhc3. This eMMC support HS400. This patch add usdhc3 support for HS400 Signed-off-by: Haibo Chen haibo.c...@freescale.com --- arch/arm/boot/dts/imx7d-sdb.dts | 13 + 1 file changed, 13 insertions(+) diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts index fdd1d7c..8059458 100644 --- a/arch/arm/boot/dts/imx7d-sdb.dts +++ b/arch/arm/boot/dts/imx7d-sdb.dts @@ -241,6 +241,19 @@ status = okay; }; +usdhc3 { + pinctrl-names = default, state_100mhz, state_200mhz; + pinctrl-0 = pinctrl_usdhc3; + pinctrl-1 = pinctrl_usdhc3_100mhz; + pinctrl-2 = pinctrl_usdhc3_200mhz; + assigned-clocks = clks IMX7D_USDHC3_ROOT_CLK; + assigned-clock-rates = 4; + bus-width = 8; + fsl,tuning-step = 2; + non-removable; + status = okay; +}; + iomuxc { pinctrl-names = default; pinctrl-0 = pinctrl_hog; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 1/6] mmc: sdhci-esdhc-imx: add imx7d support and support HS400
On Mon, Aug 10, 2015 at 04:18:03PM +0800, Haibo Chen wrote: The imx7d usdhc is derived from imx6sx, the difference is that imx7d support HS400. So introduce a new compatible string for imx7d and add HS400 support for imx7d usdhc. Signed-off-by: Haibo Chen haibo.c...@freescale.com --- drivers/mmc/host/sdhci-esdhc-imx.c | 88 -- 1 file changed, 85 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index c6b9f64..2a816ad 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -44,6 +44,7 @@ #define ESDHC_MIX_CTRL_EXE_TUNE (1 22) #define ESDHC_MIX_CTRL_SMPCLK_SEL (1 23) #define ESDHC_MIX_CTRL_FBCLK_SEL(1 25) +#define ESDHC_MIX_CTRL_HS400_EN (1 26) /* Bits 3 and 6 are not SDHCI standard definitions */ #define ESDHC_MIX_CTRL_SDHCI_MASK 0xb7 /* Tuning bits */ @@ -60,6 +61,16 @@ #define ESDHC_TUNE_CTRL_MIN 0 #define ESDHC_TUNE_CTRL_MAX ((1 7) - 1) +/* strobe dll register */ +#define ESDHC_STROBE_DLL_CTRL0x70 +#define ESDHC_STROBE_DLL_CTRL_ENABLE (1 0) +#define ESDHC_STROBE_DLL_CTRL_RESET (1 1) +#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT 3 + +#define ESDHC_STROBE_DLL_STATUS 0x74 +#define ESDHC_STROBE_DLL_STS_REF_LOCK(1 1) +#define ESDHC_STROBE_DLL_STS_SLV_LOCK0x1 + #define ESDHC_TUNING_CTRL0xcc #define ESDHC_STD_TUNING_EN (1 24) /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ @@ -120,6 +131,11 @@ #define ESDHC_FLAG_ERR004536 BIT(7) /* The IP supports HS200 mode */ #define ESDHC_FLAG_HS200 BIT(8) +/* The IP supports HS400 mode */ +#define ESDHC_FLAG_HS400 BIT(9) + +/* A higher clock ferquency than this rate requires strobell dll control */ +#define ESDHC_STROBE_DLL_CLK_FREQ1 struct esdhc_soc_data { u32 flags; @@ -156,6 +172,12 @@ static struct esdhc_soc_data usdhc_imx6sx_data = { | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200, }; +static struct esdhc_soc_data usdhc_imx7d_data = { + .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING + | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 + | ESDHC_FLAG_HS400, +}; + struct pltfm_imx_data { u32 scratchpad; struct pinctrl *pinctrl; @@ -199,6 +221,7 @@ static const struct of_device_id imx_esdhc_dt_ids[] = { { .compatible = fsl,imx6sx-usdhc, .data = usdhc_imx6sx_data, }, { .compatible = fsl,imx6sl-usdhc, .data = usdhc_imx6sl_data, }, { .compatible = fsl,imx6q-usdhc, .data = usdhc_imx6q_data, }, + { .compatible = fsl,imx7d-usdhc, .data = usdhc_imx7d_data, }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids); @@ -274,6 +297,9 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg) val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 | SDHCI_USE_SDR50_TUNING; + + if (imx_data-socdata-flags ESDHC_FLAG_HS400) + val |= SDHCI_SUPPORT_HS400; } } @@ -774,6 +800,7 @@ static int esdhc_change_pinstate(struct sdhci_host *host, break; case MMC_TIMING_UHS_SDR104: case MMC_TIMING_MMC_HS200: + case MMC_TIMING_MMC_HS400: pinctrl = imx_data-pins_200mhz; break; default: @@ -784,12 +811,57 @@ static int esdhc_change_pinstate(struct sdhci_host *host, return pinctrl_select_state(imx_data-pinctrl, pinctrl); } +/* + * For HS400 eMMC, there is a data_strobe line, this signal is generated + * by the device and used for data output and CRC status response output + * in HS400 mode. The frequency of this signal follows the frequency of + * CLK generated by host. Host receive the data which is aligned to the + * edge of data_strobe line. Due to the time delay between CLK line and + * data_strobe line, if the delay time is larger than one clock cycle, + * then CLK and data_strobe line will misaligned, read error shows up. + * So when the CLK is higher than 100MHz, each clock cycle is short enough, + * host should config the delay target. + */ +static void esdhc_set_strobe_dll(struct sdhci_host *host) +{ + u32 v; + + if (host-mmc-actual_clock ESDHC_STROBE_DLL_CLK_FREQ) { + /* force a reset on strobe dll */ + writel(ESDHC_STROBE_DLL_CTRL_RESET, + host-ioaddr + ESDHC_STROBE_DLL_CTRL); + /* + * enable strobe dll ctrl and adjust the delay target + * for the uSDHC loopback read clock + */ + v = ESDHC_STROBE_DLL_CTRL_ENABLE | + (7
[PATCH v5 1/6] mmc: sdhci-esdhc-imx: add imx7d support and support HS400
The imx7d usdhc is derived from imx6sx, the difference is that imx7d support HS400. So introduce a new compatible string for imx7d and add HS400 support for imx7d usdhc. Signed-off-by: Haibo Chen haibo.c...@freescale.com --- drivers/mmc/host/sdhci-esdhc-imx.c | 88 -- 1 file changed, 85 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index c6b9f64..2a816ad 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -44,6 +44,7 @@ #define ESDHC_MIX_CTRL_EXE_TUNE (1 22) #define ESDHC_MIX_CTRL_SMPCLK_SEL (1 23) #define ESDHC_MIX_CTRL_FBCLK_SEL (1 25) +#define ESDHC_MIX_CTRL_HS400_EN (1 26) /* Bits 3 and 6 are not SDHCI standard definitions */ #define ESDHC_MIX_CTRL_SDHCI_MASK 0xb7 /* Tuning bits */ @@ -60,6 +61,16 @@ #define ESDHC_TUNE_CTRL_MIN 0 #define ESDHC_TUNE_CTRL_MAX ((1 7) - 1) +/* strobe dll register */ +#define ESDHC_STROBE_DLL_CTRL 0x70 +#define ESDHC_STROBE_DLL_CTRL_ENABLE (1 0) +#define ESDHC_STROBE_DLL_CTRL_RESET(1 1) +#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT 3 + +#define ESDHC_STROBE_DLL_STATUS0x74 +#define ESDHC_STROBE_DLL_STS_REF_LOCK (1 1) +#define ESDHC_STROBE_DLL_STS_SLV_LOCK 0x1 + #define ESDHC_TUNING_CTRL 0xcc #define ESDHC_STD_TUNING_EN(1 24) /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ @@ -120,6 +131,11 @@ #define ESDHC_FLAG_ERR004536 BIT(7) /* The IP supports HS200 mode */ #define ESDHC_FLAG_HS200 BIT(8) +/* The IP supports HS400 mode */ +#define ESDHC_FLAG_HS400 BIT(9) + +/* A higher clock ferquency than this rate requires strobell dll control */ +#define ESDHC_STROBE_DLL_CLK_FREQ 1 struct esdhc_soc_data { u32 flags; @@ -156,6 +172,12 @@ static struct esdhc_soc_data usdhc_imx6sx_data = { | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200, }; +static struct esdhc_soc_data usdhc_imx7d_data = { + .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING + | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 + | ESDHC_FLAG_HS400, +}; + struct pltfm_imx_data { u32 scratchpad; struct pinctrl *pinctrl; @@ -199,6 +221,7 @@ static const struct of_device_id imx_esdhc_dt_ids[] = { { .compatible = fsl,imx6sx-usdhc, .data = usdhc_imx6sx_data, }, { .compatible = fsl,imx6sl-usdhc, .data = usdhc_imx6sl_data, }, { .compatible = fsl,imx6q-usdhc, .data = usdhc_imx6q_data, }, + { .compatible = fsl,imx7d-usdhc, .data = usdhc_imx7d_data, }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids); @@ -274,6 +297,9 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg) val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 | SDHCI_USE_SDR50_TUNING; + + if (imx_data-socdata-flags ESDHC_FLAG_HS400) + val |= SDHCI_SUPPORT_HS400; } } @@ -774,6 +800,7 @@ static int esdhc_change_pinstate(struct sdhci_host *host, break; case MMC_TIMING_UHS_SDR104: case MMC_TIMING_MMC_HS200: + case MMC_TIMING_MMC_HS400: pinctrl = imx_data-pins_200mhz; break; default: @@ -784,12 +811,57 @@ static int esdhc_change_pinstate(struct sdhci_host *host, return pinctrl_select_state(imx_data-pinctrl, pinctrl); } +/* + * For HS400 eMMC, there is a data_strobe line, this signal is generated + * by the device and used for data output and CRC status response output + * in HS400 mode. The frequency of this signal follows the frequency of + * CLK generated by host. Host receive the data which is aligned to the + * edge of data_strobe line. Due to the time delay between CLK line and + * data_strobe line, if the delay time is larger than one clock cycle, + * then CLK and data_strobe line will misaligned, read error shows up. + * So when the CLK is higher than 100MHz, each clock cycle is short enough, + * host should config the delay target. + */ +static void esdhc_set_strobe_dll(struct sdhci_host *host) +{ + u32 v; + + if (host-mmc-actual_clock ESDHC_STROBE_DLL_CLK_FREQ) { + /* force a reset on strobe dll */ + writel(ESDHC_STROBE_DLL_CTRL_RESET, + host-ioaddr + ESDHC_STROBE_DLL_CTRL); + /* +* enable strobe dll ctrl and adjust the delay target +* for the uSDHC loopback read clock +*/ + v = ESDHC_STROBE_DLL_CTRL_ENABLE | + (7 ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT); + writel(v, host-ioaddr +
[PATCH v5 3/6] mmc: sdhci-esdhc-imx: add compatible string in bingding doc
Add a required property fsl,imx7d-usdhc in binding doc. Add an optional property fsl,tuning-step in binding doc. Signed-off-by: Haibo Chen haibo.c...@freescale.com --- Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt | 6 ++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt index 211e778..dca56d6 100644 --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt @@ -15,6 +15,7 @@ Required properties: fsl,imx6q-usdhc fsl,imx6sl-usdhc fsl,imx6sx-usdhc + fsl,imx7d-usdhc Optional properties: - fsl,wp-controller : Indicate to use controller internal write protection @@ -27,6 +28,11 @@ Optional properties: transparent level shifters on the outputs of the controller. Two cells are required, first cell specifies minimum slot voltage (mV), second cell specifies maximum slot voltage (mV). Several ranges could be specified. +- fsl,tuning-step: Specify the increasing delay cell steps in tuning procedure. + The uSDHC use one delay cell as default increasing step to do tuning process. + This property allows user to change the tuning step to more than one delay + cells which is useful for some special boards or cards when the default + tuning step can't find the proper delay window within limited tuning retries. Examples: -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 5/6] mmc: sdhci-esdhc-imx: set back the burst_length_enable bit to 1
Currently we find that if a usdhc is choosed to boot system, then ROM code will set the burst length enable bit of this usdhc as 0. This will make performance drop a lot if this usdhc's burst length is configed. So this patch set back the burst_length_enable bit as 1, which is the default value, and means burst length is enabled for INCR. Signed-off-by: Haibo Chen haibo.c...@freescale.com --- drivers/mmc/host/sdhci-esdhc-imx.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 03c9f33..d7ec993 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -32,6 +32,7 @@ #include sdhci-esdhc.h #defineESDHC_CTRL_D3CD 0x08 +#define ESDHC_BURST_LEN_EN_INCR(1 27) /* VENDOR SPEC register */ #define ESDHC_VENDOR_SPEC 0xc0 #define ESDHC_VENDOR_SPEC_SDIO_QUIRK (1 1) @@ -1165,6 +1166,21 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) host-quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN; host-mmc-caps |= MMC_CAP_1_8V_DDR; + /* +* ROM code will change the bit burst_length_enable setting +* to zero if this usdhc is choosed to boot system. Change +* it back here, otherwise it will impact the performance a +* lot. This bit is used to enable/disable the burst length +* for the external AHB2AXI bridge, it's usefully especially +* for INCR transfer because without burst length indicator, +* the AHB2AXI bridge does not know the burst length in +* advance. And without burst length indicator, AHB INCR +* transfer can only be converted to singles on the AXI side. +*/ + writel(readl(host-ioaddr + SDHCI_HOST_CONTROL) + | ESDHC_BURST_LEN_EN_INCR, + host-ioaddr + SDHCI_HOST_CONTROL); + if (!(imx_data-socdata-flags ESDHC_FLAG_HS200)) host-quirks2 |= SDHCI_QUIRK2_BROKEN_HS200; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 6/6] mmc: sdhci-esdhc-imx: change default watermark level and burst length
By default, for all imx SoC types, the watermark level is 16, and the burst length is 8. But if the SDIO/SD/MMC I/O speed is fast enough, this default watermark level and burst length will be the performance bottleneck. For example, i.MX7D support eMMC HS400 mode, this mode can run in 8 bit, 200MHZ DDR mode. So the I/O speed improve a lot compare to SD3.0. The default burst length is 8, if we don't change this value, in HS400 mode, when we do eMMC read operation, we can find that the clock signal will stop for a period of time. This means the speed of data moving on AHB bus is slower than I/O speed. So we should improve the speed of data moving on AHB bus. This patch set the default burst length as 16, and set the default watermark level as 64. The test result is the clock signal has no stop during the eMMC HS400 operation. Signed-off-by: Haibo Chen haibo.c...@freescale.com --- drivers/mmc/host/sdhci-esdhc-imx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index d7ec993..1b31d36 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -1162,7 +1162,8 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) * to something insane. Change it back here. */ if (esdhc_is_usdhc(imx_data)) { - writel(0x08100810, host-ioaddr + ESDHC_WTMK_LVL); + writel(0x10401040, host-ioaddr + ESDHC_WTMK_LVL); + host-quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN; host-mmc-caps |= MMC_CAP_1_8V_DDR; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 2/6] mmc: sdhci-esdhc-imx: add tuning-step seting support
On Mon, Aug 10, 2015 at 04:18:04PM +0800, Haibo Chen wrote: tuning-step is the delay cell steps in tuning procedure. The default value of tuning-step is 1. Some boards or cards need another value to pass the tuning procedure. For example, imx7d-sdb board need the tuning-step value as 2, otherwise it can't pass the tuning procedure. So this patch add the tuning-step setting in driver, so that user can set the tuning-step value in dts. Fix a typo. For patch title: mmc: sdhci-esdhc-imx: add tuning-step seting support s/seting/setting Regards Dong Aisheng Signed-off-by: Haibo Chen haibo.c...@freescale.com --- drivers/mmc/host/sdhci-esdhc-imx.c | 9 + include/linux/platform_data/mmc-esdhc-imx.h | 1 + 2 files changed, 10 insertions(+) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 2a816ad..03c9f33 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -75,6 +75,7 @@ #define ESDHC_STD_TUNING_EN (1 24) /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ #define ESDHC_TUNING_START_TAP 0x1 +#define ESDHC_TUNING_STEP_SHIFT 16 /* pinctrl state */ #define ESDHC_PINCTRL_STATE_100MHZ state_100mhz @@ -474,6 +475,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) } else if (imx_data-socdata-flags ESDHC_FLAG_STD_TUNING) { u32 v = readl(host-ioaddr + SDHCI_ACMD12_ERR); u32 m = readl(host-ioaddr + ESDHC_MIX_CTRL); + u32 tuning_ctrl; if (val SDHCI_CTRL_TUNED_CLK) { v |= ESDHC_MIX_CTRL_SMPCLK_SEL; } else { @@ -484,6 +486,11 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) if (val SDHCI_CTRL_EXEC_TUNING) { v |= ESDHC_MIX_CTRL_EXE_TUNE; m |= ESDHC_MIX_CTRL_FBCLK_SEL; + tuning_ctrl = readl(host-ioaddr + ESDHC_TUNING_CTRL); + tuning_ctrl |= ESDHC_STD_TUNING_EN | ESDHC_TUNING_START_TAP; + if (imx_data-boarddata.tuning_step) + tuning_ctrl |= imx_data-boarddata.tuning_step ESDHC_TUNING_STEP_SHIFT; + writel(tuning_ctrl, host-ioaddr + ESDHC_TUNING_CTRL); } else { v = ~ESDHC_MIX_CTRL_EXE_TUNE; } @@ -965,6 +972,8 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev, if (gpio_is_valid(boarddata-wp_gpio)) boarddata-wp_type = ESDHC_WP_GPIO; + of_property_read_u32(np, fsl,tuning-step, boarddata-tuning_step); + if (of_find_property(np, no-1-8-v, NULL)) boarddata-support_vsel = false; else diff --git a/include/linux/platform_data/mmc-esdhc-imx.h b/include/linux/platform_data/mmc-esdhc-imx.h index e1571ef..95ccab3 100644 --- a/include/linux/platform_data/mmc-esdhc-imx.h +++ b/include/linux/platform_data/mmc-esdhc-imx.h @@ -45,5 +45,6 @@ struct esdhc_platform_data { int max_bus_width; bool support_vsel; unsigned int delay_line; + unsigned int tuning_step; /* The delay cell steps in tuning procedure */ }; #endif /* __ASM_ARCH_IMX_ESDHC_H */ -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 3/6] mmc: sdhci-esdhc-imx: add compatible string in bingding doc
On Mon, Aug 10, 2015 at 04:18:05PM +0800, Haibo Chen wrote: Add a required property fsl,imx7d-usdhc in binding doc. Add an optional property fsl,tuning-step in binding doc. Signed-off-by: Haibo Chen haibo.c...@freescale.com You missed my former comments. The patch title is too generous. Better to change to something like: mmc: sdhci-esdhc-imx: add imx7d support in bingding doc Regards Dong Aisheng --- Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt | 6 ++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt index 211e778..dca56d6 100644 --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt @@ -15,6 +15,7 @@ Required properties: fsl,imx6q-usdhc fsl,imx6sl-usdhc fsl,imx6sx-usdhc +fsl,imx7d-usdhc Optional properties: - fsl,wp-controller : Indicate to use controller internal write protection @@ -27,6 +28,11 @@ Optional properties: transparent level shifters on the outputs of the controller. Two cells are required, first cell specifies minimum slot voltage (mV), second cell specifies maximum slot voltage (mV). Several ranges could be specified. +- fsl,tuning-step: Specify the increasing delay cell steps in tuning procedure. + The uSDHC use one delay cell as default increasing step to do tuning process. + This property allows user to change the tuning step to more than one delay + cells which is useful for some special boards or cards when the default + tuning step can't find the proper delay window within limited tuning retries. Examples: -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6] mmc: dw_mmc: add quirk for broken data transfer over scheme
From: Addy Ke addy...@rock-chips.com This patch add a new quirk to add a s/w timer to notify the driver to terminate current transfer and report a data timeout to the core, if DTO interrupt does NOT come within the given time. dw_mmc call mmc_request_done func to finish transfer depends on DTO interrupt. If DTO interrupt does not come in sending data state, the current transfer will be blocked. We got the reply from synopsys: There are two counters but both use the same value of [31:8] bits. Data timeout counter doesn't wait for stop clock and you should get DRTO even when the clock is not stopped. Host Starvation timeout counter is triggered with stop clock condition. This means that host should get DRTO and DTO interrupt. But this case really exists, when driver reads tuning data from card on RK3288-pink2 board. I measured waveforms by oscilloscope and found that card clock was always on and data lines were always holded high level in sending data state. There are two possibility that data over interrupt doesn't come in reading data state on RK3X SoCs: - get command done interrupt, but doesn't get any data-related interrupt. - get data error interrupt, but doesn't get data over interrupt. Signed-off-by: Addy Ke addy...@rock-chips.com Address review comments from Jaehoon Chung. Signed-off-by: Heiko Stuebner he...@sntech.de --- Changes in v2: - fix some typo. - remove extra timeout value (250ms). - remove dw_mci_dto_start_monitor func. - use broken-dto for new quirk and change Subject for it. Changes in v3: - Remove dts for broken-dto, just add this quirk in dw_mci_rockchip_init Changes in v4: - fix bug that may cause 32 bit overflow by (drto_clks * 1000). - doesn't call mod_timer in writing data state, becase TMOUT register only for reading data. Changes in v5: - fix some typo. - add a buffer for drto_ms. - move drto_ms related code to a helper function. Changes in v6: - better spare time comment - let dw_mci_set_drto start the timer itself drivers/mmc/host/dw_mmc-rockchip.c | 3 ++ drivers/mmc/host/dw_mmc.c | 64 -- include/linux/mmc/dw_mmc.h | 4 +++ 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc- rockchip.c index de15121..bc76aa2 100644 --- a/drivers/mmc/host/dw_mmc-rockchip.c +++ b/drivers/mmc/host/dw_mmc-rockchip.c @@ -73,6 +73,9 @@ static int dw_mci_rockchip_init(struct dw_mci *host) /* It is slot 8 on Rockchip SoCs */ host-sdio_id0 = 8; + /* It needs this quirk on all Rockchip SoCs */ + host-pdata-quirks |= DW_MCI_QUIRK_BROKEN_DTO; + return 0; } diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 4e95ca9..459e68b 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1528,6 +1528,20 @@ static int dw_mci_data_complete(struct dw_mci *host, struct mmc_data *data) return data-error; } +static void dw_mci_set_drto(struct dw_mci *host) +{ + unsigned int drto_clks; + unsigned int drto_ms; + + drto_clks = mci_readl(host, TMOUT) 8; + drto_ms = DIV_ROUND_UP(drto_clks, host-bus_hz / 1000); + + /* add a bit spare time */ + drto_ms += 10; + + mod_timer(host-dto_timer, jiffies + msecs_to_jiffies(drto_ms)); +} + static void dw_mci_tasklet_func(unsigned long priv) { struct dw_mci *host = (struct dw_mci *)priv; @@ -1605,8 +1619,16 @@ static void dw_mci_tasklet_func(unsigned long priv) } if (!test_and_clear_bit(EVENT_XFER_COMPLETE, - host-pending_events)) + host-pending_events)) { + /* +* If all data-related interrupts don't come +* within the given time in reading data state. +*/ + if ((host-quirks DW_MCI_QUIRK_BROKEN_DTO) + (host-dir_status == DW_MCI_RECV_STATUS)) + dw_mci_set_drto(host); break; + } set_bit(EVENT_XFER_COMPLETE, host-completed_events); @@ -1639,8 +1661,17 @@ static void dw_mci_tasklet_func(unsigned long priv) case STATE_DATA_BUSY: if (!test_and_clear_bit(EVENT_DATA_COMPLETE, - host-pending_events)) + host-pending_events)) { + /* +* If data error interrupt comes but data over +* interrupt doesn't come within the given time. +* in reading data state. +*/ +
Re: [PATCH v6] mmc: dw_mmc: add quirk for broken data transfer over scheme
Hi, Heiko. Sorry, i had missed this patch. And thanks for reminding. I will check on today..and reply until tomorrow. Best Regards, Jaehoon Chung On 08/10/2015 08:12 PM, Heiko Stübner wrote: From: Addy Ke addy...@rock-chips.com This patch add a new quirk to add a s/w timer to notify the driver to terminate current transfer and report a data timeout to the core, if DTO interrupt does NOT come within the given time. dw_mmc call mmc_request_done func to finish transfer depends on DTO interrupt. If DTO interrupt does not come in sending data state, the current transfer will be blocked. We got the reply from synopsys: There are two counters but both use the same value of [31:8] bits. Data timeout counter doesn't wait for stop clock and you should get DRTO even when the clock is not stopped. Host Starvation timeout counter is triggered with stop clock condition. This means that host should get DRTO and DTO interrupt. But this case really exists, when driver reads tuning data from card on RK3288-pink2 board. I measured waveforms by oscilloscope and found that card clock was always on and data lines were always holded high level in sending data state. There are two possibility that data over interrupt doesn't come in reading data state on RK3X SoCs: - get command done interrupt, but doesn't get any data-related interrupt. - get data error interrupt, but doesn't get data over interrupt. Signed-off-by: Addy Ke addy...@rock-chips.com Address review comments from Jaehoon Chung. Signed-off-by: Heiko Stuebner he...@sntech.de --- Changes in v2: - fix some typo. - remove extra timeout value (250ms). - remove dw_mci_dto_start_monitor func. - use broken-dto for new quirk and change Subject for it. Changes in v3: - Remove dts for broken-dto, just add this quirk in dw_mci_rockchip_init Changes in v4: - fix bug that may cause 32 bit overflow by (drto_clks * 1000). - doesn't call mod_timer in writing data state, becase TMOUT register only for reading data. Changes in v5: - fix some typo. - add a buffer for drto_ms. - move drto_ms related code to a helper function. Changes in v6: - better spare time comment - let dw_mci_set_drto start the timer itself drivers/mmc/host/dw_mmc-rockchip.c | 3 ++ drivers/mmc/host/dw_mmc.c | 64 -- include/linux/mmc/dw_mmc.h | 4 +++ 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc- rockchip.c index de15121..bc76aa2 100644 --- a/drivers/mmc/host/dw_mmc-rockchip.c +++ b/drivers/mmc/host/dw_mmc-rockchip.c @@ -73,6 +73,9 @@ static int dw_mci_rockchip_init(struct dw_mci *host) /* It is slot 8 on Rockchip SoCs */ host-sdio_id0 = 8; + /* It needs this quirk on all Rockchip SoCs */ + host-pdata-quirks |= DW_MCI_QUIRK_BROKEN_DTO; + return 0; } diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 4e95ca9..459e68b 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1528,6 +1528,20 @@ static int dw_mci_data_complete(struct dw_mci *host, struct mmc_data *data) return data-error; } +static void dw_mci_set_drto(struct dw_mci *host) +{ + unsigned int drto_clks; + unsigned int drto_ms; + + drto_clks = mci_readl(host, TMOUT) 8; + drto_ms = DIV_ROUND_UP(drto_clks, host-bus_hz / 1000); + + /* add a bit spare time */ + drto_ms += 10; + + mod_timer(host-dto_timer, jiffies + msecs_to_jiffies(drto_ms)); +} + static void dw_mci_tasklet_func(unsigned long priv) { struct dw_mci *host = (struct dw_mci *)priv; @@ -1605,8 +1619,16 @@ static void dw_mci_tasklet_func(unsigned long priv) } if (!test_and_clear_bit(EVENT_XFER_COMPLETE, - host-pending_events)) + host-pending_events)) { + /* + * If all data-related interrupts don't come + * within the given time in reading data state. + */ + if ((host-quirks DW_MCI_QUIRK_BROKEN_DTO) + (host-dir_status == DW_MCI_RECV_STATUS)) + dw_mci_set_drto(host); break; + } set_bit(EVENT_XFER_COMPLETE, host-completed_events); @@ -1639,8 +1661,17 @@ static void dw_mci_tasklet_func(unsigned long priv) case STATE_DATA_BUSY: if (!test_and_clear_bit(EVENT_DATA_COMPLETE, - host-pending_events)) + host-pending_events)) { + /* +
Re: [PATCH] mmc: sdhci-of-esdhc: add workaround for pre divider initial value
On Fri, 2015-08-07 at 10:56 +0800, Yangbo Lu wrote: For eSDHC(version 2.3), the pre divider only could divide base clock by 2 at least. Add workaround for this to avoid unexpected issue. This works for me, I get my 50 MHz bus :) I would rather se you used the proper register than that SDHCI_SLOT_INT_STATUS hack. I replaced: temp = in_be32(host-ioaddr + SDHCI_SLOT_INT_STATUS); with temp = esdhc_readw(host, SDHCI_HOST_VERSION); which yields the same working result for me. With that change: Acked-by: Joakim Tjernlund joakim.tjernl...@transmode.se Signed-off-by: Yangbo Lu yangbo...@freescale.com --- drivers/mmc/host/sdhci-of-esdhc.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 797be75..46edf2c 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -208,6 +208,12 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) if (clock == 0) return; + /* Workaround to start pre_div at 2 for VNN VENDOR_V_23 */ + temp = in_be32(host-ioaddr + SDHCI_SLOT_INT_STATUS); + temp = (temp SDHCI_VENDOR_VER_MASK) SDHCI_VENDOR_VER_SHIFT; + if (temp VENDOR_V_23) + pre_div = 2; + /* Workaround to reduce the clock frequency for p1010 esdhc */ if (of_find_compatible_node(NULL, NULL, fsl,p1010-esdhc)) { if (clock 2000) -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mmc: atmel-mci: remove useless include
Definitions from linux/platform_data/atmel.h are not used, remove the include. Signed-off-by: Alexandre Belloni alexandre.bell...@free-electrons.com --- drivers/mmc/host/atmel-mci.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 9a39e0b7e583..bf62e429f7fc 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -29,7 +29,6 @@ #include linux/slab.h #include linux/stat.h #include linux/types.h -#include linux/platform_data/atmel.h #include linux/platform_data/mmc-atmel-mci.h #include linux/mmc/host.h -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html