[RFC PATCH v1 1/1] mmc: sprd: add MMC host driver for Spreadtrum SoC
This patch adds MMC host driver for Spreadtrum SoC. The following coding style may be not meet kernel coding style. I am not sure this kind of coding style is better or worse. 1) A macro that represent some bits of a register is added a prefix __, for example: #define SDHOST_16_HOST_CTRL_2 0x3E #define __TIMING_MODE_SDR12 0x #define __TIMING_MODE_SDR25 0x0001 #define __TIMING_MODE_SDR50 0x0002 I think it is more useful to distinguish a register from a bit of this register. 2) A function in order to operate a register is also added a prefix _. If the functions(A) call other function(B), we added a prefix __ before B, for example: static inline void _sdhost_enable_int(struct sdhost_host *host, u32 mask) { __local_writel(mask, host, SDHOST_32_INT_ST_EN); __local_writel(mask, host, SDHOST_32_INT_SIG_EN); } I think this make the relationship of the function call more explicit. Signed-off-by: Billows Wu(WuHongtao) wuh...@gmail.com --- drivers/mmc/host/Kconfig |6 + drivers/mmc/host/Makefile |1 + drivers/mmc/host/sprd_sdhost.c | 1183 drivers/mmc/host/sprd_sdhost.h | 592 drivers/mmc/host/sprd_sdhost_debugfs.c | 213 ++ drivers/mmc/host/sprd_sdhost_debugfs.h | 27 + 6 files changed, 2022 insertions(+) create mode 100644 drivers/mmc/host/sprd_sdhost.c create mode 100644 drivers/mmc/host/sprd_sdhost.h create mode 100644 drivers/mmc/host/sprd_sdhost_debugfs.c create mode 100644 drivers/mmc/host/sprd_sdhost_debugfs.h diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index fd9a58e..c43d938 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -264,6 +264,12 @@ config MMC_SDHCI_SPEAR If you have a controller with this interface, say Y or M here. +config SPRD_MMC_SDHOST + tristate Spreadtrum SDIO host Controller support + help + This selects the SDIO Host Controller in spreadtrum platform + + If you have a controller with this interface, say Y or M here. If unsure, say N. config MMC_SDHCI_S3C_DMA diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index e928d61..e00227f 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -74,6 +74,7 @@ obj-$(CONFIG_MMC_SDHCI_BCM2835) += sdhci-bcm2835.o obj-$(CONFIG_MMC_SDHCI_IPROC) += sdhci-iproc.o obj-$(CONFIG_MMC_SDHCI_MSM)+= sdhci-msm.o obj-$(CONFIG_MMC_SDHCI_ST) += sdhci-st.o +obj-$(CONFIG_SPRD_MMC_SDHOST) += sprd_sdhost.o sprd_sdhost_debugfs.o ifeq ($(CONFIG_CB710_DEBUG),y) CFLAGS-cb710-mmc+= -DDEBUG diff --git a/drivers/mmc/host/sprd_sdhost.c b/drivers/mmc/host/sprd_sdhost.c new file mode 100644 index 000..18c9449 --- /dev/null +++ b/drivers/mmc/host/sprd_sdhost.c @@ -0,0 +1,1183 @@ +/* + * linux/drivers/mmc/host/sprd_sdhost.c - Secure Digital Host Controller + * Interface driver + * + * Copyright (C) 2015 Spreadtrum corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + */ + +#include linux/delay.h +#include linux/dma-mapping.h +#include linux/highmem.h +#include linux/io.h +#include linux/module.h +#include linux/of.h +#include linux/of_device.h +#include linux/of_gpio.h +#include linux/platform_device.h +#include linux/pm_runtime.h +#include linux/regulator/consumer.h +#include linux/slab.h +#include linux/scatterlist.h + +#include sprd_sdhost.h +#include sprd_sdhost_debugfs.h + +#define DRIVER_NAME sdhost +#define SDHOST_CAPS \ + (MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED | \ + MMC_CAP_ERASE | MMC_CAP_UHS_SDR50 | \ + MMC_CAP_CMD23 | MMC_CAP_HW_RESET) + +struct sdhost_caps_data { + char *name; + u32 ocr_avail; + u32 caps; + u32 caps2; + u32 pm_caps; + u32 base_clk; + u32 signal_default_voltage; +}; + +struct sdhost_caps_data caps_info_map[] = { + { + .name = sd, + .ocr_avail = MMC_VDD_29_30 | MMC_VDD_30_31, + .caps = SDHOST_CAPS, + .caps2 = MMC_CAP2_HC_ERASE_SZ, + .base_clk = 19200, + .signal_default_voltage = 300, + }, + { + .name = wifi, + .ocr_avail = MMC_VDD_165_195 | MMC_VDD_29_30 | + MMC_VDD_30_31 | MMC_VDD_32_33 | MMC_VDD_33_34, + .caps = SDHOST_CAPS | MMC_CAP_POWER_OFF_CARD | + MMC_CAP_UHS_SDR12, + .base_clk = 7600, + }, + { + .name = emmc, + .ocr_avail = MMC_VDD_29_30 | MMC_VDD_30_31, + .caps =
Re: [PATCH v3 1/6] mmc: sdhci-esdhc-imx: add imx7d support and support HS400
On Wed, Jul 29, 2015 at 05:03:52PM +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 | 66 ++ 1 file changed, 66 insertions(+) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index c6b9f64..b441eed 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,8 @@ #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_SUP_HS400 BIT(9) struct esdhc_soc_data { u32 flags; @@ -156,6 +169,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_SUP_HS400, +}; + struct pltfm_imx_data { u32 scratchpad; struct pinctrl *pinctrl; @@ -199,6 +218,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 +294,10 @@ 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; + + /* imx7d does not have a support_hs400 register, fake one */ You could remove this line. It's bit, not register and i think no need such comment. + if (imx_data-socdata-flags ESDHC_FLAG_SUP_HS400) + val |= SDHCI_SUPPORT_HS400; } } @@ -774,6 +798,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,6 +809,30 @@ static int esdhc_change_pinstate(struct sdhci_host *host, return pinctrl_select_state(imx_data-pinctrl, pinctrl); } +static void esdhc_set_strobe_dll(struct sdhci_host *host) It would be good if we can add some comments for this function for better understand. +{ + u32 v; + + /* 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 + ESDHC_STROBE_DLL_CTRL); + /* wait 1us to make sure strobe dll status register stable */ + udelay(1); + v = readl(host-ioaddr + ESDHC_STROBE_DLL_STATUS); + if (!(v ESDHC_STROBE_DLL_STS_REF_LOCK)) + dev_warn(mmc_dev(host-mmc), + warning! HS400 strobe DLL status REF not lock!\n); + if (!(v ESDHC_STROBE_DLL_STS_SLV_LOCK)) + dev_warn(mmc_dev(host-mmc), + warning! HS400 strobe DLL status SLV not lock!\n); +} + static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing) { struct
Re: [PATCH v3 4/6] mmc: sdhci-esdhc-imx: add compatible string in bingding doc
On Wed, Jul 29, 2015 at 05:03:55PM +0800, Haibo Chen wrote: Add a required property fsl,imx7d-usdhc in binding doc. Add an optional property fsl,tuning-step in binding doc. Better change to: mmc: sdhci-esdhc-imx: add imx7d support in bingding doc Signed-off-by: Haibo Chen haibo.c...@freescale.com --- Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt index 211e778..c6624bc 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,7 @@ 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. we could add more explain about this property for better understanding: e.g. The uSDHC is using 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 reties. Examples: -- 1.9.1 Regards Dong Aisheng -- 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 v3 6/6] mmc: sdhci-esdhc-imx: set back the burst_length_enable bit to 1
On Wed, Jul 29, 2015 at 05:03:57PM +0800, Haibo Chen wrote: 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 16. 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 | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 37d0095..dd945e5 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 #define ESDHC_CTRL_D3CD 0x08 +#define ESDHC_BURST_LEN_EN_INCR (1 27) /* VENDOR SPEC register */ #define ESDHC_VENDOR_SPEC0xc0 #define ESDHC_VENDOR_SPEC_SDIO_QUIRK(1 1) @@ -1158,6 +1159,16 @@ 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 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 if the burst length is 16. Can you clarify a bit more on why performance drops a lot if burst length is 16? Caused by the burst length setting did not work due to ROM disabled it? Regards Dong Aisheng + */ + 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
Re: [PATCH v3 5/6] mmc: sdhci-esdhc-imx: config watermark level and burst length
On Fri, Jul 31, 2015 at 10:51:41PM +0800, Dong Aisheng wrote: On Wed, Jul 29, 2015 at 05:03:56PM +0800, Haibo Chen wrote: 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. For imx7d usdhc, this patch set the burst length as 16, and set watermark level as 64. The test result is the clock signal has no stop during the eMMC HS400 operation. For other imx usdhc, remain the default value: burst length as 8, watermark level as 16. Signed-off-by: Haibo Chen haibo.c...@freescale.com --- drivers/mmc/host/sdhci-esdhc-imx.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 158f93b..37d0095 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -239,6 +239,11 @@ static inline int is_imx6q_usdhc(struct pltfm_imx_data *data) return data-socdata == usdhc_imx6q_data; } +static inline int is_imx7d_usdhc(struct pltfm_imx_data *data) +{ + return data-socdata == usdhc_imx7d_data; +} Can we using flag to check instead of adding more is_imx_usdhc()? No, not more flags. Do the job properly and parameterise the differences. static inline int esdhc_is_usdhc(struct pltfm_imx_data *data) { return !!(data-socdata-flags ESDHC_FLAG_USDHC); @@ -1145,7 +1150,11 @@ 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); + if (is_imx7d_usdhc(imx_data)) + writel(0x10401040, host-ioaddr + ESDHC_WTMK_LVL); + else + writel(0x08100810, host-ioaddr + ESDHC_WTMK_LVL); So the value to be written to this register should come from the driver data, which is already used as a struct esdhc_soc_data to extrapolate out the differences. Going down the flag path will lead you to an even more of a stinking shitpile than sdhci already is - if another version of the SoC requires a different value there, what are you going to do? Add yet another flag for the next value? What are you going to do when you have 16 different values? Use 16 different flags? Clearly that path is insane. -- FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up according to speedtest.net. -- 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 v3 5/6] mmc: sdhci-esdhc-imx: config watermark level and burst length
On Wed, Jul 29, 2015 at 05:03:56PM +0800, Haibo Chen wrote: 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. For imx7d usdhc, this patch set the burst length as 16, and set watermark level as 64. The test result is the clock signal has no stop during the eMMC HS400 operation. For other imx usdhc, remain the default value: burst length as 8, watermark level as 16. Signed-off-by: Haibo Chen haibo.c...@freescale.com --- drivers/mmc/host/sdhci-esdhc-imx.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 158f93b..37d0095 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -239,6 +239,11 @@ static inline int is_imx6q_usdhc(struct pltfm_imx_data *data) return data-socdata == usdhc_imx6q_data; } +static inline int is_imx7d_usdhc(struct pltfm_imx_data *data) +{ + return data-socdata == usdhc_imx7d_data; +} Can we using flag to check instead of adding more is_imx_usdhc()? + static inline int esdhc_is_usdhc(struct pltfm_imx_data *data) { return !!(data-socdata-flags ESDHC_FLAG_USDHC); @@ -1145,7 +1150,11 @@ 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); + if (is_imx7d_usdhc(imx_data)) + writel(0x10401040, host-ioaddr + ESDHC_WTMK_LVL); + else + writel(0x08100810, host-ioaddr + ESDHC_WTMK_LVL); + host-quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN; host-mmc-caps |= MMC_CAP_1_8V_DDR; Regards Dong Aisheng -- 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 01/17] mmc: host: omap_hsmmc: use devm_regulator_get_optional() for vmmc
Hi Grygorii, On Wednesday 29 July 2015 05:39 PM, Grygorii Strashko wrote: On 07/29/2015 02:09 PM, Kishon Vijay Abraham I wrote: Since vmmc can be optional for some platforms, use devm_regulator_get_optional() for vmmc. Now return error only in the case of -EPROBE_DEFER and for all other cases set host-vcc to NULL. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c |8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 4d12032..b673e59 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -344,11 +344,13 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) struct regulator *reg; int ocr_value = 0; -reg = devm_regulator_get(host-dev, vmmc); +reg = devm_regulator_get_optional(host-dev, vmmc); if (IS_ERR(reg)) { -dev_err(host-dev, unable to get vmmc regulator %ld\n, +if (PTR_ERR(reg) == -EPROBE_DEFER) +return -EPROBE_DEFER; +host-vcc = NULL; +dev_dbg(host-dev, unable to get vmmc regulator %ld\n, PTR_ERR(reg)); -return PTR_ERR(reg); I think, It could be unsafe to just drop this return. regulator_get_optional may return: 1 valid pointer on regulator : success; 2 ERR_PTR(-ENODEV) : regulator is not assigned, can proceed. 3 ERR_PTR(-EPROBE_DEFER) : regulator is assigned, but not ready yet, retry. 4 ERR_PTR(other error codes: regulator is assigned, but can't be retrieved, failure, can't proceed So, It's allowed to continue with host-vcc = NULL; only in case [2], while in case [4] probe should fail. You are right. Will fix it and resend the patch. Thanks Kishon -- 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 v3 3/6] ARM: dts: imx7d-sdb: add eMMC5.0 support
On Wed, Jul 29, 2015 at 05:03:54PM +0800, Haibo Chen wrote: imx7d-sdb board has a eMMC5.0 on usdhc3. This eMMC support HS400. This patch add usdhc3 support for HS400 It seems this patch should be after [PATCH v3 4/6] mmc: sdhci-esdhc-imx: add compatible string in bingding doc Regards Dong Aisheng 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 v3 5/6] mmc: sdhci-esdhc-imx: config watermark level and burst length
On Wed, Jul 29, 2015 at 05:03:56PM +0800, Haibo Chen wrote: 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. For imx7d usdhc, this patch set the burst length as 16, and set watermark level as 64. The test result is the clock signal has no stop during the eMMC HS400 operation. For other imx usdhc, remain the default value: burst length as 8, watermark level as 16. Add please change patch title a bit since this patch change is actually for mx7d: mmc: sdhci-esdhc-imx: change watermark level and burst length for imx7d Regards Dong Aisheng Signed-off-by: Haibo Chen haibo.c...@freescale.com --- drivers/mmc/host/sdhci-esdhc-imx.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 158f93b..37d0095 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -239,6 +239,11 @@ static inline int is_imx6q_usdhc(struct pltfm_imx_data *data) return data-socdata == usdhc_imx6q_data; } +static inline int is_imx7d_usdhc(struct pltfm_imx_data *data) +{ + return data-socdata == usdhc_imx7d_data; +} + static inline int esdhc_is_usdhc(struct pltfm_imx_data *data) { return !!(data-socdata-flags ESDHC_FLAG_USDHC); @@ -1145,7 +1150,11 @@ 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); + if (is_imx7d_usdhc(imx_data)) + writel(0x10401040, host-ioaddr + ESDHC_WTMK_LVL); + else + writel(0x08100810, 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: [SHDCI] Heavy (thousands) DMA leaks
Hi Jiri, I will check this issue ASAP, thanks for report this! Best Regards Haibo Chen -Original Message- From: Jiri Slaby [mailto:jsl...@suse.cz] Sent: Thursday, July 30, 2015 5:32 PM To: Chen Haibo-B51421 Cc: Ulf Hansson; linux-mmc@vger.kernel.org; Linux kernel mailing list Subject: [SHDCI] Heavy (thousands) DMA leaks Hi, after commit 348487cb28e66b032bae1b38424d81bf5b08 Author: Haibo Chen haibo.c...@freescale.com Date: Tue Dec 9 17:04:05 2014 +0800 mmc: sdhci: use pipeline mmc requests to improve performance I see heavy DMA leaks which result in warnings of the dma api debug code: WARNING: CPU: 0 PID: 0 at lib/dma-debug.c:509 add_dma_entry+0x138/0x150() DMA-API: exceeded 7 overlapping mappings of cacheline 0x0b20ec00 And mainly this one upon sdhci module removal. It is over 4000 leaked mappings during one card transfer. mmc0: card e624 removed [ cut here ] WARNING: CPU: 2 PID: 1263 at lib/dma-debug.c:974 dma_debug_device_change+0x158/0x1c0() pci :02:00.0: DMA-API: device driver has pending DMA allocations while released from device [count=4041] One of leaked entries details: [device address=0xddff] [size=65536 bytes] [mapped with DMA_FROM_DEVICE] [mapped as scather- gather] Modules linked in: CPU: 2 PID: 1263 Comm: bash Tainted: GW 4.2.0-rc4 #12 Hardware name: LENOVO 23252SG/23252SG, BIOS G2ET33WW (1.13 ) 07/24/2012 81cc5e32 8800d03c3b68 81820938 8800d03c3bb8 8800d03c3ba8 810b827a 000100260021 88030e50 0fc9 88030d95aeb8 88030e4ddd68 Call Trace: [81820938] dump_stack+0x4c/0x6e [810b827a] warn_slowpath_common+0x8a/0xc0 [810b82f6] warn_slowpath_fmt+0x46/0x50 [813248c8] dma_debug_device_change+0x158/0x1c0 [810d4e9d] notifier_call_chain+0x4d/0x80 [810d51fd] __blocking_notifier_call_chain+0x4d/0x70 [810d5236] blocking_notifier_call_chain+0x16/0x20 [814db395] __device_release_driver+0x105/0x130 [814db3e3] device_release_driver+0x23/0x30 [814d95ca] unbind_store+0xba/0xe0 [8123c638] ? kernfs_fop_write+0xe8/0x170 [814d8ac4] drv_attr_store+0x24/0x30 [8123ce4a] sysfs_kf_write+0x3a/0x50 [8123c670] kernfs_fop_write+0x120/0x170 [811ce9e8] __vfs_write+0x28/0xe0 [811d1209] ? __sb_start_write+0x49/0xe0 [810e3ba5] ? local_clock+0x25/0x30 [811cf041] vfs_write+0xa1/0x170 [810e43c4] ? vtime_account_user+0x54/0x60 [811cfce6] SyS_write+0x46/0xa0 [81180f83] ? context_tracking_user_exit+0x13/0x20 [8182a017] entry_SYSCALL_64_fastpath+0x12/0x6a ---[ end trace 398181ad32332b33 ]--- Mapped at: [81324492] debug_dma_map_sg+0x122/0x140 [81616dd3] sdhci_pre_dma_transfer+0xc3/0x1b0 [81616f02] sdhci_pre_req+0x42/0x70 [81601492] mmc_pre_req+0x42/0x60 [8160290e] mmc_start_req+0x3e/0x400 I already fixed one symptom -- memory corruption. Could you revisit the commit once again, as there is surely at least one more bug? thanks, -- js suse labs -- 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 v3 1/2] mmc: sdhci: fix abort due to missing runtime PM
Hi Ulf, What is the status on that? -- Stefan On 2015-05-21 09:15, Stefan Agner wrote: When using i.MX ESDHC driver, while entering suspend while the device is in runtime PM, the sdhci_(suspend|resume)_host function are called with disabled clocks. Since this functions access the SDHC host registers, this leads to an external abort on Vybrid SoC: [ 37.772967] Unhandled fault: imprecise external abort (0x1c06) at 0x76f5f000 [ 37.780304] Internal error: : 1c06 [#1] ARM [ 37.784670] Modules linked in: [ 37.787908] CPU: 0 PID: 428 Comm: sh Not tainted 3.18.0-rc5-00119-geefd097-dirty #1540 [ 37.796142] task: 8e246c00 ti: 8ca6c000 task.ti: 8ca6c000 [ 37.801785] PC is at esdhc_writel_le+0x40/0xec [ 37.806431] LR is at sdhci_set_card_detection+0xe0/0xe4 [ 37.811877] pc : [803f0584]lr : [803eaaa0]psr: 400f0013 [ 37.811877] sp : 8ca6dd28 ip : 0001 fp : 8ca6dd3c [ 37.823766] r10: 807a233c r9 : r8 : 8e8b7210 [ 37.829194] r7 : 802d8a08 r6 : 8082e928 r5 : r4 : 0002 [ 37.835974] r3 : 8ea34e90 r2 : 0038 r1 : r0 : 8ea32ac0 ... Clocks need to be enabled to access the registers. Fix the issue by add runtime PM enabled pltfm implementation of suspend/resume which take care of clocks by using the runtime PM API properly. Signed-off-by: Stefan Agner ste...@agner.ch --- Changes since v2: - Implement a generic pltfm suspend/resume function instead of a local function in sdhci-esdhc-imx.c - Convert sdhci-pxav3 to use the runtime PM enabled pltfm suspend/resume function too drivers/mmc/host/sdhci-esdhc-imx.c | 2 +- drivers/mmc/host/sdhci-pltfm.c | 36 drivers/mmc/host/sdhci-pltfm.h | 2 ++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 82f512d..7b7b3a3 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -1132,7 +1132,7 @@ static int sdhci_esdhc_runtime_resume(struct device *dev) #endif static const struct dev_pm_ops sdhci_esdhc_pmops = { - SET_SYSTEM_SLEEP_PM_OPS(sdhci_pltfm_suspend, sdhci_pltfm_resume) + SET_SYSTEM_SLEEP_PM_OPS(sdhci_pltfm_rpm_suspend, sdhci_pltfm_rpm_resume) SET_RUNTIME_PM_OPS(sdhci_esdhc_runtime_suspend, sdhci_esdhc_runtime_resume, NULL) }; diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c index a207f5a..38c03cd 100644 --- a/drivers/mmc/host/sdhci-pltfm.c +++ b/drivers/mmc/host/sdhci-pltfm.c @@ -31,6 +31,7 @@ #include linux/err.h #include linux/module.h #include linux/of.h +#include linux/pm_runtime.h #ifdef CONFIG_PPC #include asm/machdep.h #endif @@ -256,6 +257,41 @@ const struct dev_pm_ops sdhci_pltfm_pmops = { .resume = sdhci_pltfm_resume, }; EXPORT_SYMBOL_GPL(sdhci_pltfm_pmops); + +int sdhci_pltfm_rpm_suspend(struct device *dev) +{ + int ret; + struct sdhci_host *host = dev_get_drvdata(dev); + + pm_runtime_get_sync(dev); + ret = sdhci_suspend_host(host); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + if (ret) + return ret; + + return pm_runtime_force_suspend(dev); +} +EXPORT_SYMBOL_GPL(sdhci_pltfm_rpm_suspend); + +int sdhci_pltfm_rpm_resume(struct device *dev) +{ + int ret; + struct sdhci_host *host = dev_get_drvdata(dev); + + ret = pm_runtime_force_resume(dev); + + if (ret) + return ret; + + pm_runtime_get_sync(dev); + ret = sdhci_resume_host(host); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + + return ret; +} +EXPORT_SYMBOL_GPL(sdhci_pltfm_rpm_resume); #endif /* CONFIG_PM */ static int __init sdhci_pltfm_drv_init(void) diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h index 04bc248..ac5f6ea 100644 --- a/drivers/mmc/host/sdhci-pltfm.h +++ b/drivers/mmc/host/sdhci-pltfm.h @@ -114,6 +114,8 @@ static inline void *sdhci_pltfm_priv(struct sdhci_pltfm_host *host) extern int sdhci_pltfm_suspend(struct device *dev); extern int sdhci_pltfm_resume(struct device *dev); extern const struct dev_pm_ops sdhci_pltfm_pmops; +extern int sdhci_pltfm_rpm_suspend(struct device *dev); +extern int sdhci_pltfm_rpm_resume(struct device *dev); #define SDHCI_PLTFM_PMOPS (sdhci_pltfm_pmops) #else #define SDHCI_PLTFM_PMOPS NULL -- 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