[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <35692f1c-62a4-6c71-d67a-2a216e97e7d5@intel.com>
Date: Thu, 8 Oct 2020 13:58:31 +0300
From: Adrian Hunter <adrian.hunter@...el.com>
To: Ulf Hansson <ulf.hansson@...aro.org>,
muhammad.husaini.zulkifli@...el.com
Cc: Michal Simek <michal.simek@...inx.com>,
andriy.shevchenko@...el.com,
"linux-mmc@...r.kernel.org" <linux-mmc@...r.kernel.org>,
Linux ARM <linux-arm-kernel@...ts.infradead.org>,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
lakshmi.bai.raja.subramanian@...el.com,
Wan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad@...el.com>,
Arnd Bergmann <arnd@...db.de>
Subject: Re: [PATCH v4 4/4] mmc: sdhci-of-arasan: Enable UHS-1 support for
Keem Bay SOC
On 8/10/20 12:27 pm, Ulf Hansson wrote:
> On Thu, 8 Oct 2020 at 04:12, <muhammad.husaini.zulkifli@...el.com> wrote:
>>
>> From: Muhammad Husaini Zulkifli <muhammad.husaini.zulkifli@...el.com>
>>
>> Voltage switching sequence is needed to support UHS-1 interface.
>> There are 2 places to control the voltage.
>> 1) By setting the AON register using firmware driver calling
>> system-level platform management layer (SMC) to set the register.
>> 2) By controlling the GPIO expander value to drive either 1.8V or 3.3V
>> for power mux input.
>>
>> Signed-off-by: Muhammad Husaini Zulkifli <muhammad.husaini.zulkifli@...el.com>
>> Reviewed-by: Andy Shevchenko <andriy.shevchenko@...el.com>
>> Reviewed-by: Adrian Hunter <adrian.hunter@...el.com>
>> ---
>> drivers/mmc/host/sdhci-of-arasan.c | 126 +++++++++++++++++++++++++++++
>> 1 file changed, 126 insertions(+)
>>
>> diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
>> index 46aea6516133..ea2467b0073d 100644
>> --- a/drivers/mmc/host/sdhci-of-arasan.c
>> +++ b/drivers/mmc/host/sdhci-of-arasan.c
>> @@ -16,6 +16,7 @@
>> */
>>
>> #include <linux/clk-provider.h>
>> +#include <linux/gpio/consumer.h>
>> #include <linux/mfd/syscon.h>
>> #include <linux/module.h>
>> #include <linux/of_device.h>
>> @@ -23,6 +24,7 @@
>> #include <linux/regmap.h>
>> #include <linux/of.h>
>> #include <linux/firmware/xlnx-zynqmp.h>
>> +#include <linux/firmware/intel/keembay_firmware.h>
>>
>> #include "cqhci.h"
>> #include "sdhci-pltfm.h"
>> @@ -136,6 +138,7 @@ struct sdhci_arasan_clk_data {
>> * @soc_ctl_base: Pointer to regmap for syscon for soc_ctl registers.
>> * @soc_ctl_map: Map to get offsets into soc_ctl registers.
>> * @quirks: Arasan deviations from spec.
>> + * @uhs_gpio: Pointer to the uhs gpio.
>> */
>> struct sdhci_arasan_data {
>> struct sdhci_host *host;
>> @@ -150,6 +153,7 @@ struct sdhci_arasan_data {
>> struct regmap *soc_ctl_base;
>> const struct sdhci_arasan_soc_ctl_map *soc_ctl_map;
>> unsigned int quirks;
>> + struct gpio_desc *uhs_gpio;
>>
>> /* Controller does not have CD wired and will not function normally without */
>> #define SDHCI_ARASAN_QUIRK_FORCE_CDTEST BIT(0)
>> @@ -361,6 +365,112 @@ static int sdhci_arasan_voltage_switch(struct mmc_host *mmc,
>> return -EINVAL;
>> }
>>
>> +static int sdhci_arasan_keembay_voltage_switch(struct mmc_host *mmc,
>> + struct mmc_ios *ios)
>> +{
>> + struct sdhci_host *host = mmc_priv(mmc);
>> + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> + struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
>> + u16 ctrl_2, clk;
>> + int ret;
>> +
>> + switch (ios->signal_voltage) {
>> + case MMC_SIGNAL_VOLTAGE_180:
>> + clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
>> + clk &= ~SDHCI_CLOCK_CARD_EN;
>> + sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
>> +
>> + clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
>> + if (clk & SDHCI_CLOCK_CARD_EN)
>> + return -EAGAIN;
>> +
>> + sdhci_writeb(host, SDHCI_POWER_ON | SDHCI_POWER_180,
>> + SDHCI_POWER_CONTROL);
>> +
>> + /*
>> + * Set VDDIO_B voltage to Low for 1.8V
>> + * which is controlling by GPIO Expander.
>> + */
>> + gpiod_set_value_cansleep(sdhci_arasan->uhs_gpio, 0);
>> +
>> + /*
>> + * This is like a final gatekeeper. Need to ensure changed voltage
>> + * is settled before and after turn on this bit.
>> + */
>> + usleep_range(1000, 1100);
>> +
>> + ret = keembay_sd_voltage_selection(KEEMBAY_SET_1V8_VOLT);
>> + if (ret)
>> + return ret;
>> +
>> + usleep_range(1000, 1100);
>
> No, sorry, but I don't like this.
>
> This looks like a GPIO regulator with an extension of using the
> keembay_sd_voltage_selection() thingy. I think you can model these
> things behind a regulator and hook it up as a vqmmc supply in DT
> instead. BTW, this is the common way we deal with these things for mmc
> host drivers.
It seemed to me that would just result in calling regulator API instead of
GPIO API but the flow above would otherwise be unchanged i.e. no benefit
Powered by blists - more mailing lists