From 769780f8a13c785657f469f65041ea6945bfa721 Mon Sep 17 00:00:00 2001 From: Aniruddha Rao Date: Mon, 27 Jul 2020 12:22:27 +0530 Subject: [PATCH] NVIDIA: SAUCE: mmc: tegra: use gpio for voltage switching on fpga Use dt property "nvidia,voltage-switch-gpio" parsed from DT to select voltage level and toggle it for switching voltage from 3.3V to 1.8V to support SD3.0 cards on FPGA. http://nvbugs/2836586 http://nvbugs/2849456 http://nvbugs/4333277 Signed-off-by: Aniruddha Rao (cherry-picked from commit b99819f98ef04c50b4a050a9f49e7e3c223868b1 and and edited by anrao to work in k5.9) Signed-off-by: Prathamesh Shete Signed-off-by: Laxman Dewangan Acked-by: Noah Wager Acked-by: Jacob Martin Signed-off-by: Noah Wager --- drivers/mmc/host/sdhci-tegra.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 15a817e40612..a13e7b2a5ad8 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include #include @@ -213,6 +215,7 @@ struct sdhci_tegra { u32 stream_id; bool skip_clk_rst; struct tegra_prod *prod_list; + int volt_switch_gpio; }; static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg) @@ -548,8 +551,20 @@ static int tegra_sdhci_set_padctrl(struct sdhci_host *host, int voltage, sdhci_writel(host, reg, SDHCI_TEGRA_SDMEM_COMP_PADCTRL); } - } else { + /* Toggle power gpio for switching voltage on FPGA */ + if (gpio_is_valid(tegra_host->volt_switch_gpio)) { + if (voltage == MMC_SIGNAL_VOLTAGE_330) { + gpio_set_value(tegra_host->volt_switch_gpio, 1); + dev_info(mmc_dev(host->mmc), + "3.3V set by voltage switch gpio\n"); + } else { + gpio_set_value(tegra_host->volt_switch_gpio, 0); + dev_info(mmc_dev(host->mmc), + "1.8V set by voltage switch gpio\n"); + } + return 0; + } /* Dual Voltage PADS Voltage selection */ if (!tegra_host->pad_control_available) return 0; @@ -1726,6 +1741,7 @@ static void sdhci_tegra_program_stream_id(struct sdhci_host *host) static int sdhci_tegra_probe(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; const struct sdhci_tegra_soc_data *soc_data; struct sdhci_host *host; struct sdhci_pltfm_host *pltfm_host; @@ -1874,6 +1890,20 @@ static int sdhci_tegra_probe(struct platform_device *pdev) usleep_range(2000, 4000); } + tegra_host->volt_switch_gpio = of_get_named_gpio(np, + "nvidia,voltage-switch-gpio", 0); + if (gpio_is_valid(tegra_host->volt_switch_gpio)) { + rc = gpio_request(tegra_host->volt_switch_gpio, "sdhci_power"); + if (rc) + dev_err(mmc_dev(host->mmc), + "failed to allocate gpio for voltage switch, " + "err: %d\n", rc); + gpio_direction_output(tegra_host->volt_switch_gpio, 1); + gpio_set_value(tegra_host->volt_switch_gpio, 1); + dev_info(mmc_dev(host->mmc), + "3.3V set initially by voltage switch gpio\n"); + } + rc = sdhci_tegra_add_host(host); if (rc) goto err_add_host;