From 1e0c857e5914818f13f5fcc6eeacc29b21357f55 Mon Sep 17 00:00:00 2001 From: Nan Li Date: Thu, 10 Oct 2019 15:31:59 +0800 Subject: [PATCH] sd: add sd power cycle for sd3.0 [1/1] PD#SWPL-14953 Problem: SD card 3.0 mode requires power cycle. if not, the initialization of SD card will be affected. Solution: add SD power cycle supported. Verify: sm1_ac200 Change-Id: Ic8aecadf3b63660adb74ff4ecf0a5d38037b579f Signed-off-by: Nan Li --- arch/arm/boot/dts/amlogic/mesonsm1.dtsi | 18 ++++++- arch/arm64/boot/dts/amlogic/mesonsm1.dtsi | 18 ++++++- drivers/amlogic/mmc/aml_sd_emmc.c | 1 + drivers/amlogic/mmc/aml_sd_emmc_v3.c | 4 ++ drivers/amlogic/mmc/amlsd.c | 60 +++++++++++++++++------ 5 files changed, 84 insertions(+), 17 deletions(-) diff --git a/arch/arm/boot/dts/amlogic/mesonsm1.dtsi b/arch/arm/boot/dts/amlogic/mesonsm1.dtsi index 7eb5c90e5c7d..86741df69d75 100644 --- a/arch/arm/boot/dts/amlogic/mesonsm1.dtsi +++ b/arch/arm/boot/dts/amlogic/mesonsm1.dtsi @@ -1504,7 +1504,8 @@ "sd_to_ao_uart_pins", "ao_to_sd_uart_pins", "sd_to_ao_jtag_pins", - "ao_to_sd_jtag_pins"; + "ao_to_sd_jtag_pins", + "sd_all_pd_pins"; pinctrl-0 = <&sd_all_pins>; pinctrl-1 = <&sd_clk_cmd_pins>; @@ -1519,6 +1520,7 @@ pinctrl-7 = <&sd_all_pins &sd_to_ao_uart_pins>; pinctrl-8 = <&sd_to_ao_uart_clr_pins &ao_to_sd_uart_pins>; + pinctrl-9 = <&sd_all_pd_pins>; clocks = <&clkc CLKID_SD_EMMC_B>, <&clkc CLKID_SD_EMMC_B_P0_COMP>, @@ -1955,6 +1957,20 @@ }; }; + sd_all_pd_pins:sd_all_pd_pins { + mux { + groups = "GPIOC_0", + "GPIOC_1", + "GPIOC_2", + "GPIOC_3", + "GPIOC_4", + "GPIOC_5"; + function = "gpio_periphs"; + bias-pull-down; + output-low; + }; + }; + sd_1bit_pins:sd_1bit_pins { mux { groups = "sdcard_d0_c", diff --git a/arch/arm64/boot/dts/amlogic/mesonsm1.dtsi b/arch/arm64/boot/dts/amlogic/mesonsm1.dtsi index a30340a64395..ebc6b5dbb600 100644 --- a/arch/arm64/boot/dts/amlogic/mesonsm1.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesonsm1.dtsi @@ -1503,7 +1503,8 @@ "sd_to_ao_uart_pins", "ao_to_sd_uart_pins", "sd_to_ao_jtag_pins", - "ao_to_sd_jtag_pins"; + "ao_to_sd_jtag_pins", + "sd_all_pd_pins"; pinctrl-0 = <&sd_all_pins>; pinctrl-1 = <&sd_clk_cmd_pins>; @@ -1518,6 +1519,7 @@ pinctrl-7 = <&sd_all_pins &sd_to_ao_uart_pins>; pinctrl-8 = <&sd_to_ao_uart_clr_pins &ao_to_sd_uart_pins>; + pinctrl-8 = <&sd_all_pd_pins>; clocks = <&clkc CLKID_SD_EMMC_B>, <&clkc CLKID_SD_EMMC_B_P0_COMP>, @@ -1954,6 +1956,20 @@ }; }; + sd_all_pd_pins:sd_all_pd_pins { + mux { + groups = "GPIOC_0", + "GPIOC_1", + "GPIOC_2", + "GPIOC_3", + "GPIOC_4", + "GPIOC_5"; + function = "gpio_periphs"; + bias-pull-down; + output-low; + }; + }; + sd_1bit_pins:sd_1bit_pins { mux { groups = "sdcard_d0_c", diff --git a/drivers/amlogic/mmc/aml_sd_emmc.c b/drivers/amlogic/mmc/aml_sd_emmc.c index 227007118457..32e6f58797a5 100644 --- a/drivers/amlogic/mmc/aml_sd_emmc.c +++ b/drivers/amlogic/mmc/aml_sd_emmc.c @@ -3256,6 +3256,7 @@ static int meson_mmc_probe(struct platform_device *pdev) mmc->f_max = pdata->f_max; mmc->max_current_180 = 300; /* 300 mA in 1.8V */ mmc->max_current_330 = 300; /* 300 mA in 3.3V */ + pdata->signal_voltage = 0xff; if (aml_card_type_sdio(pdata)) { /* if sdio_wifi */ /* mmc->host_rescan_disable = true;*/ diff --git a/drivers/amlogic/mmc/aml_sd_emmc_v3.c b/drivers/amlogic/mmc/aml_sd_emmc_v3.c index 16b1335870a5..264da6a4b08c 100644 --- a/drivers/amlogic/mmc/aml_sd_emmc_v3.c +++ b/drivers/amlogic/mmc/aml_sd_emmc_v3.c @@ -472,6 +472,10 @@ static void aml_sd_emmc_set_power_v3(struct amlsd_platform *pdata, pdata->pwr_on(pdata); break; case MMC_POWER_UP: + if (aml_card_type_non_sdio(pdata)) { + of_amlsd_pwr_off(pdata); + of_amlsd_pwr_on(pdata); + } break; case MMC_POWER_OFF: writel(0, host->base + SD_EMMC_DELAY1_V3); diff --git a/drivers/amlogic/mmc/amlsd.c b/drivers/amlogic/mmc/amlsd.c index 9ea8262db1d9..693bfa947bab 100644 --- a/drivers/amlogic/mmc/amlsd.c +++ b/drivers/amlogic/mmc/amlsd.c @@ -335,18 +335,6 @@ void of_amlsd_pwr_prepare(struct amlsd_platform *pdata) { } -void of_amlsd_pwr_on(struct amlsd_platform *pdata) -{ - if (pdata->gpio_power) - gpio_set_value(pdata->gpio_power, pdata->power_level); -} - -void of_amlsd_pwr_off(struct amlsd_platform *pdata) -{ - if (pdata->gpio_power) - gpio_set_value(pdata->gpio_power, !pdata->power_level); -} - #ifdef CARD_DETECT_IRQ void of_amlsd_irq_init(struct amlsd_platform *pdata) { @@ -383,7 +371,8 @@ int of_amlsd_init(struct amlsd_platform *pdata) } #endif if (pdata->gpio_power) { - if (pdata->power_level) { + if (pdata->power_level && + !aml_card_type_non_sdio(pdata)) { ret = gpio_request_one(pdata->gpio_power, GPIOF_OUT_INIT_LOW, MODULE_NAME); CHECK_RET(ret); @@ -431,14 +420,14 @@ static struct pinctrl * __must_check aml_devm_pinctrl_get_select( s = pinctrl_lookup_state(p, name); if (IS_ERR(s)) { pr_err("lookup %s fail\n", name); - devm_pinctrl_put(p); + aml_devm_pinctrl_put(host); return ERR_CAST(s); } ret = pinctrl_select_state(p, s); if (ret < 0) { pr_err("select %s fail\n", name); - devm_pinctrl_put(p); + aml_devm_pinctrl_put(host); return ERR_PTR(ret); } if ((host->mem->start == host->data->port_b_base) @@ -475,6 +464,47 @@ static struct pinctrl * __must_check aml_devm_pinctrl_get_select( } #endif /* SD_EMMC_PIN_CTRL */ +#define sd3_pwr_dbg 1 +void of_amlsd_pwr_on(struct amlsd_platform *pdata) +{ +#if sd3_pwr_dbg + struct pinctrl *p = NULL; + struct amlsd_host *host = pdata->host; +#endif + + if (pdata->gpio_power) { + gpio_set_value(pdata->gpio_power, pdata->power_level); +#if sd3_pwr_dbg + if (aml_card_type_non_sdio(pdata)) { + mutex_lock(&host->pinmux_lock); + p = aml_devm_pinctrl_get_select(host, "sd_all_pins"); + mutex_unlock(&host->pinmux_lock); + } +#endif + } +} + +void of_amlsd_pwr_off(struct amlsd_platform *pdata) +{ +#if sd3_pwr_dbg + struct pinctrl *p = NULL; + struct amlsd_host *host = pdata->host; +#endif + + if (pdata->gpio_power) { + gpio_set_value(pdata->gpio_power, !pdata->power_level); + +#if sd3_pwr_dbg + if (aml_card_type_non_sdio(pdata)) { + mutex_lock(&host->pinmux_lock); + p = aml_devm_pinctrl_get_select(host, "sd_all_pd_pins"); + mutex_unlock(&host->pinmux_lock); + mdelay(200); //pull down need 200ms. + } +#endif + } +} + void of_amlsd_xfer_pre(struct amlsd_platform *pdata) { struct amlsd_host *host = pdata->host;