Optimize voltage switch for the SD controller
Subsystems (4)
cover Optimize voltage switch for the SD controller
This patch set is used to optimize voltage switch for the Spreadtrum SD host controller.
Any comments are welcome. Thanks.
Baolin Wang (3):
mmc: sdhci-sprd: Add start_signal_voltage_switch ops
dt-bindings: mmc: sprd: Add pinctrl support
mmc: sdhci-sprd: Add pin control support for voltage switch
.../devicetree/bindings/mmc/sdhci-sprd.txt | 7 ++ drivers/mmc/host/sdhci-sprd.c | 78 ++++++++++++++++++++ 2 files changed, 85 insertions(+)
Signature · 1 line
1.7.9.5
PATCH 1/3 mmc: sdhci-sprd: Add start_signal_voltage_switch ops
For Spreadtrum SD host controller, we can not use standard SD registers to change and detect the I/O voltage signals, since our voltage regulator for I/O is fixed in hardware, and no signals were connected to the SD controller. Thus add Spreadtrum specific voltage switch ops to change voltage instead of using standard SD host registers.
--- drivers/mmc/host/sdhci-sprd.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
drivers/mmc/host/sdhci-sprd.c +24 -0
@@ -403,6 +403,22 @@ static void sdhci_sprd_request(struct mmc_host *mmc, struct mmc_request *mrq)sdhci_request (mmc, mrq); } +static int sdhci_sprd_voltage_switch (struct mmc_host *mmc,struct mmc_ios *ios) +{ +int ret; + +if (!IS_ERR (mmc->supply.vqmmc)) { + ret =mmc_regulator_set_vqmmc (mmc, ios); +if (ret) { +pr_err ("%s: Switching signalling voltage failed\n" , +mmc_hostname (mmc)); +return ret; + } + } + +return 0 ; +} +static void sdhci_sprd_hs400_enhanced_strobe (struct mmc_host *mmc,struct mmc_ios *ios) {
@@ -470,6 +486,14 @@ static int sdhci_sprd_probe(struct platform_device *pdev) host->mmc_host_ops.request = sdhci_sprd_request; host->mmc_host_ops.hs400_enhanced_strobe = sdhci_sprd_hs400_enhanced_strobe; +/* +* We can not use the standard ops to change and detect the voltage +* signal for Spreadtrum SD host controller, since our voltage regulator +* for I/O is fixed in hardware, that means we do not need control +* the standard SD host controller to change the I/O voltage. +*/ + host->mmc_host_ops.start_signal_voltage_switch = + sdhci_sprd_voltage_switch; host->mmc->caps =MMC_CAP_SD_HIGHSPEED |MMC_CAP_MMC_HIGHSPEED |MMC_CAP_ERASE |MMC_CAP_CMD23 ;
Signature · 1 line
1.7.9.5
Re: [PATCH 1/3] mmc: sdhci-sprd: Add start_signal_voltage_switch ops
Quoted 7 lines · Baolin Wang
For Spreadtrum SD host controller, we can not use standard SD registers to change and detect the I/O voltage signals, since our voltage regulator for I/O is fixed in hardware, and no signals were connected to the SD controller. Thus add Spreadtrum specific voltage switch ops to change voltage instead of using standard SD host registers.
Signed-off-by Baolin Wang <[email protected]>
Quoted 47 lines
--- drivers/mmc/host/sdhci-sprd.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)drivers/mmc/host/sdhci-sprd.c +24
-0@@ -403,6 +403,22 @@ static void sdhci_sprd_request(struct mmc_host *mmc, struct mmc_request *mrq)sdhci_request (mmc, mrq); } +static int sdhci_sprd_voltage_switch (struct mmc_host *mmc,struct mmc_ios *ios) +{ +int ret; + +if (!IS_ERR (mmc->supply.vqmmc)) { + ret =mmc_regulator_set_vqmmc (mmc, ios); +if (ret) { +pr_err ("%s: Switching signalling voltage failed\n" , +mmc_hostname (mmc)); +return ret; + } + } + +return 0 ; +} +static void sdhci_sprd_hs400_enhanced_strobe (struct mmc_host *mmc,struct mmc_ios *ios) {@@ -470,6 +486,14 @@ static int sdhci_sprd_probe(struct platform_device *pdev) host->mmc_host_ops.request = sdhci_sprd_request; host->mmc_host_ops.hs400_enhanced_strobe = sdhci_sprd_hs400_enhanced_strobe; +/* +* We can not use the standard ops to change and detect the voltage +* signal for Spreadtrum SD host controller, since our voltage regulator +* for I/O is fixed in hardware, that means we do not need control +* the standard SD host controller to change the I/O voltage. +*/ + host->mmc_host_ops.start_signal_voltage_switch = + sdhci_sprd_voltage_switch; host->mmc->caps =MMC_CAP_SD_HIGHSPEED |MMC_CAP_MMC_HIGHSPEED |MMC_CAP_ERASE |MMC_CAP_CMD23 ;
PATCH 2/3 dt-bindings: mmc: sprd: Add pinctrl support
In reply to Baolin WangWhen changing SD card voltage signal for Spreadtrum SD host controller, it also need to switch related pin's state. Thus add pinctrl properties' description in documentation.
--- .../devicetree/bindings/mmc/sdhci-sprd.txt | 7 +++++++ 1 file changed, 7 insertions(+)
Documentation/devicetree/bindings/mmc/sdhci-sprd.txt +7 -0
@@ -19,6 +19,9 @@ Required properties: Optional properties: - assigned-clocks: the same with "sdio" clock - assigned-clock-parents: the default parent of "sdio" clock +- pinctrl-names: should be "default", "state_uhs" +- pinctrl-0: should contain default/high speed pin control +- pinctrl-1: should contain uhs mode pin control PHY DLL delays are used to delay the data valid window, and align the window to sampling clock. PHY DLL delays can be configured by following properties,
@@ -50,6 +53,10 @@ sdio0: sdio@20600000 { assigned-clocks = <&ap_clk CLK_EMMC_2X>; assigned-clock-parents = <&rpll CLK_RPLL_390M>; + pinctrl-names = "default", "state_uhs"; + pinctrl-0 = <&sd0_pins_default>; + pinctrl-1 = <&sd0_pins_uhs>; + sprd,phy-delay-sd-uhs-sdr104 = <0x3f 0x7f 0x2e 0x2e>; bus-width = <8>; non-removable;
Signature · 1 line
1.7.9.5
PATCH 3/3 mmc: sdhci-sprd: Add pin control support for voltage switch
In reply to Baolin WangFor Spreadtrum SD card voltage switching, besides regulator setting, it also need switch related pin's state to output corresponding voltage.
This patch adds pin control operation to support voltage switch.
--- drivers/mmc/host/sdhci-sprd.c | 54 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+)
drivers/mmc/host/sdhci-sprd.c +54 -0
@@ -12,6 +12,7 @@#include <linux/of.h> #include <linux/of_device.h> #include <linux/of_gpio.h> +#include <linux/pinctrl/consumer.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/regulator/consumer.h>
@@ -72,6 +73,9 @@ struct sdhci_sprd_host {struct clk *clk_sdio;struct clk *clk_enable;struct clk *clk_2x_enable; +struct pinctrl *pinctrl; +struct pinctrl_state *pins_uhs; +struct pinctrl_state *pins_default;u32 base_rate;int flags;/* backup of host attribute */ u32 phy_delay[MMC_TIMING_MMC_HS400 +2 ];
@@ -405,6 +409,8 @@ static void sdhci_sprd_request(struct mmc_host *mmc, struct mmc_request *mrq)static int sdhci_sprd_voltage_switch (struct mmc_host *mmc,struct mmc_ios *ios) { +struct sdhci_host *host =mmc_priv (mmc); +struct sdhci_sprd_host *sprd_host =TO_SPRD_HOST (host);int ret;if (!IS_ERR (mmc->supply.vqmmc)) {
@@ -416,6 +422,37 @@ static int sdhci_sprd_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios) } } +if (IS_ERR (sprd_host->pinctrl)) +return 0 ; + +switch (ios->signal_voltage) { +case MMC_SIGNAL_VOLTAGE_180 : + ret =pinctrl_select_state (sprd_host->pinctrl, + sprd_host->pins_uhs); +if (ret) { +pr_err ("%s: failed to select uhs pin state\n" , +mmc_hostname (mmc)); +return ret; + } +break ; + +default : +/* fall-through */ +case MMC_SIGNAL_VOLTAGE_330 : + ret =pinctrl_select_state (sprd_host->pinctrl, + sprd_host->pins_default); +if (ret) { +pr_err ("%s: failed to select default pin state\n" , +mmc_hostname (mmc)); +return ret; + } +break ; + } + +/* Wait for 300 ~ 500 us for pin state stable */ +usleep_range (300 ,500 ); +sdhci_reset (host,SDHCI_RESET_CMD |SDHCI_RESET_DATA ); +return 0 ; }
@@ -504,6 +541,23 @@ static int sdhci_sprd_probe(struct platform_device *pdev) sprd_host =TO_SPRD_HOST (host);sdhci_sprd_phy_param_parse (sprd_host, pdev->dev.of_node); + sprd_host->pinctrl =devm_pinctrl_get (&pdev->dev); +if (!IS_ERR (sprd_host->pinctrl)) { + sprd_host->pins_uhs = +pinctrl_lookup_state (sprd_host->pinctrl,"state_uhs" ); +if (IS_ERR (sprd_host->pins_uhs)) { + ret =PTR_ERR (sprd_host->pins_uhs); + goto pltfm_free; + } + + sprd_host->pins_default = +pinctrl_lookup_state (sprd_host->pinctrl,"default" ); +if (IS_ERR (sprd_host->pins_default)) { + ret =PTR_ERR (sprd_host->pins_default); + goto pltfm_free; + } + } + clk =devm_clk_get (&pdev->dev,"sdio" );if (IS_ERR (clk)) { ret =PTR_ERR (clk);
Signature · 1 line
1.7.9.5
Re: [PATCH 3/3] mmc: sdhci-sprd: Add pin control support for voltage switch
Quoted 6 lines · Baolin Wang
For Spreadtrum SD card voltage switching, besides regulator setting, it also need switch related pin's state to output corresponding voltage.
This patch adds pin control operation to support voltage switch.
Signed-off-by Baolin Wang <[email protected]>
Quoted 98 lines
--- drivers/mmc/host/sdhci-sprd.c | 54 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+)drivers/mmc/host/sdhci-sprd.c +54
-0@@ -12,6 +12,7 @@#include <linux/of.h> #include <linux/of_device.h> #include <linux/of_gpio.h> +#include <linux/pinctrl/consumer.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/regulator/consumer.h> @@ -72,6 +73,9 @@ struct sdhci_sprd_host {struct clk *clk_sdio;struct clk *clk_enable;struct clk *clk_2x_enable; +struct pinctrl *pinctrl; +struct pinctrl_state *pins_uhs; +struct pinctrl_state *pins_default;u32 base_rate;int flags;/* backup of host attribute */ u32 phy_delay[MMC_TIMING_MMC_HS400 +2 ];@@ -405,6 +409,8 @@ static void sdhci_sprd_request(struct mmc_host *mmc, struct mmc_request *mrq)static int sdhci_sprd_voltage_switch (struct mmc_host *mmc,struct mmc_ios *ios) { +struct sdhci_host *host =mmc_priv (mmc); +struct sdhci_sprd_host *sprd_host =TO_SPRD_HOST (host);int ret;if (!IS_ERR (mmc->supply.vqmmc)) {@@ -416,6 +422,37 @@ static int sdhci_sprd_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios) } } +if (IS_ERR (sprd_host->pinctrl)) +return 0 ; + +switch (ios->signal_voltage) { +case MMC_SIGNAL_VOLTAGE_180 : + ret =pinctrl_select_state (sprd_host->pinctrl, + sprd_host->pins_uhs); +if (ret) { +pr_err ("%s: failed to select uhs pin state\n" , +mmc_hostname (mmc)); +return ret; + } +break ; + +default : +/* fall-through */ +case MMC_SIGNAL_VOLTAGE_330 : + ret =pinctrl_select_state (sprd_host->pinctrl, + sprd_host->pins_default); +if (ret) { +pr_err ("%s: failed to select default pin state\n" , +mmc_hostname (mmc)); +return ret; + } +break ; + } + +/* Wait for 300 ~ 500 us for pin state stable */ +usleep_range (300 ,500 ); +sdhci_reset (host,SDHCI_RESET_CMD |SDHCI_RESET_DATA ); +return 0 ; }@@ -504,6 +541,23 @@ static int sdhci_sprd_probe(struct platform_device *pdev) sprd_host =TO_SPRD_HOST (host);sdhci_sprd_phy_param_parse (sprd_host, pdev->dev.of_node); + sprd_host->pinctrl =devm_pinctrl_get (&pdev->dev); +if (!IS_ERR (sprd_host->pinctrl)) { + sprd_host->pins_uhs = +pinctrl_lookup_state (sprd_host->pinctrl,"state_uhs" ); +if (IS_ERR (sprd_host->pins_uhs)) { + ret =PTR_ERR (sprd_host->pins_uhs); + goto pltfm_free; + } + + sprd_host->pins_default = +pinctrl_lookup_state (sprd_host->pinctrl,"default" ); +if (IS_ERR (sprd_host->pins_default)) { + ret =PTR_ERR (sprd_host->pins_default); + goto pltfm_free; + } + } + clk =devm_clk_get (&pdev->dev,"sdio" );if (IS_ERR (clk)) { ret =PTR_ERR (clk);
Quoted 11 lines · Baolin Wang
This patch set is used to optimize voltage switch for the Spreadtrum SD host controller.
Any comments are welcome. Thanks.
Baolin Wang (3):
mmc: sdhci-sprd: Addstart_signal_voltage_switchops
dt-bindings: mmc: sprd: Add pinctrl support
mmc: sdhci-sprd: Add pin control support for voltage switch
Quoted 7 lines
.../devicetree/bindings/mmc/sdhci-sprd.txt | 7 ++ drivers/mmc/host/sdhci-sprd.c | 78 ++++++++++++++++++++ 2 files changed, 85 insertions(+)--
1.7.9.5
Applied for next, thanks!
Kind regards
Uffe