* [PATCH v3 0/7] Tegra PMC pinctrl pad configuration @ 2018-07-12 12:00 Aapo Vienamo 2018-07-12 12:00 ` [PATCH v3 1/7] soc/tegra: pmc: Fix pad voltage configuration for Tegra186 Aapo Vienamo ` (6 more replies) 0 siblings, 7 replies; 15+ messages in thread From: Aapo Vienamo @ 2018-07-12 12:00 UTC (permalink / raw) To: Rob Herring, Mark Rutland, Thierry Reding, Jonathan Hunter, Mikko Perttunen, Laxman Dewangan Cc: Aapo Vienamo, devicetree, linux-tegra, linux-kernel Hi all, The Tegra Power Management Controller (PMC) can set pad power states and voltage configuration. This series implements pinctrl interfaces for configuring said pad properties. Changelog v3: - Don't expose tegra_io_pad_is_powered() - Remove tegra_io_pad_set_voltage() stub from pmc.h - Fixes i386 build failure reported by kbuild test robot v2: - Add Tegra186 AO_HV pad - Make the IO pad tables narrower - Add parens to TEGRA_IO_PAD() and TEGRA_IO_PIN_DESC() - Fix a typo in the dt-bindings docs - Remove old pmc pad voltage configuration APIs - Check return value of tegra_io_pad_find() in tegra_io_pad_pinconf_get()/_set() Aapo Vienamo (7): soc/tegra: pmc: Fix pad voltage configuration for Tegra186 soc/tegra: pmc: Factor out DPD register bit calculation soc/tegra: pmc: Implement tegra_io_pad_is_powered() soc/tegra: pmc: Use X macro to generate IO pad tables dt-bindings: Add Tegra PMC pad configuration bindings soc/tegra: pmc: Remove public pad voltage APIs soc/tegra: pmc: Implement pad configuration via pinctrl .../bindings/arm/tegra/nvidia,tegra186-pmc.txt | 84 ++++ .../bindings/arm/tegra/nvidia,tegra20-pmc.txt | 95 ++++ drivers/soc/tegra/pmc.c | 512 +++++++++++++++------ include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h | 18 + include/soc/tegra/pmc.h | 20 +- 5 files changed, 581 insertions(+), 148 deletions(-) create mode 100644 include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h -- 2.7.4 ^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v3 1/7] soc/tegra: pmc: Fix pad voltage configuration for Tegra186 2018-07-12 12:00 [PATCH v3 0/7] Tegra PMC pinctrl pad configuration Aapo Vienamo @ 2018-07-12 12:00 ` Aapo Vienamo 2018-07-12 12:00 ` [PATCH v3 2/7] soc/tegra: pmc: Factor out DPD register bit calculation Aapo Vienamo ` (5 subsequent siblings) 6 siblings, 0 replies; 15+ messages in thread From: Aapo Vienamo @ 2018-07-12 12:00 UTC (permalink / raw) To: Rob Herring, Mark Rutland, Thierry Reding, Jonathan Hunter, Mikko Perttunen, Laxman Dewangan Cc: Aapo Vienamo, devicetree, linux-tegra, linux-kernel Implement support for the PMC_IMPL_E_33V_PWR register which replaces PMC_PWR_DET register interface of the SoC generations preceding Tegra186. Also add the voltage bit offsets to the tegra186_io_pads[] table and the AO_HV pad. Signed-off-by: Aapo Vienamo <avienamo@nvidia.com> Acked-by: Jon Hunter <jonathanh@nvidia.com> --- drivers/soc/tegra/pmc.c | 55 ++++++++++++++++++++++++++++++++++--------------- include/soc/tegra/pmc.h | 1 + 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 2d6f3fc..f926332 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -65,6 +65,8 @@ #define PWRGATE_STATUS 0x38 +#define PMC_IMPL_E_33V_PWR 0x40 + #define PMC_PWR_DET 0x48 #define PMC_SCRATCH0_MODE_RECOVERY BIT(31) @@ -154,6 +156,7 @@ struct tegra_pmc_soc { bool has_tsense_reset; bool has_gpu_clamps; bool needs_mbist_war; + bool has_impl_33v_pwr; const struct tegra_io_pad_soc *io_pads; unsigned int num_io_pads; @@ -1073,20 +1076,29 @@ int tegra_io_pad_set_voltage(enum tegra_io_pad id, mutex_lock(&pmc->powergates_lock); - /* write-enable PMC_PWR_DET_VALUE[pad->voltage] */ - value = tegra_pmc_readl(PMC_PWR_DET); - value |= BIT(pad->voltage); - tegra_pmc_writel(value, PMC_PWR_DET); + if (pmc->soc->has_impl_33v_pwr) { + value = tegra_pmc_readl(PMC_IMPL_E_33V_PWR); + if (voltage == TEGRA_IO_PAD_1800000UV) + value &= ~BIT(pad->voltage); + else + value |= BIT(pad->voltage); + tegra_pmc_writel(value, PMC_IMPL_E_33V_PWR); + } else { + /* write-enable PMC_PWR_DET_VALUE[pad->voltage] */ + value = tegra_pmc_readl(PMC_PWR_DET); + value |= BIT(pad->voltage); + tegra_pmc_writel(value, PMC_PWR_DET); - /* update I/O voltage */ - value = tegra_pmc_readl(PMC_PWR_DET_VALUE); + /* update I/O voltage */ + value = tegra_pmc_readl(PMC_PWR_DET_VALUE); - if (voltage == TEGRA_IO_PAD_1800000UV) - value &= ~BIT(pad->voltage); - else - value |= BIT(pad->voltage); + if (voltage == TEGRA_IO_PAD_1800000UV) + value &= ~BIT(pad->voltage); + else + value |= BIT(pad->voltage); - tegra_pmc_writel(value, PMC_PWR_DET_VALUE); + tegra_pmc_writel(value, PMC_PWR_DET_VALUE); + } mutex_unlock(&pmc->powergates_lock); @@ -1108,7 +1120,10 @@ int tegra_io_pad_get_voltage(enum tegra_io_pad id) if (pad->voltage == UINT_MAX) return -ENOTSUPP; - value = tegra_pmc_readl(PMC_PWR_DET_VALUE); + if (pmc->soc->has_impl_33v_pwr) + value = tegra_pmc_readl(PMC_IMPL_E_33V_PWR); + else + value = tegra_pmc_readl(PMC_PWR_DET_VALUE); if ((value & BIT(pad->voltage)) == 0) return TEGRA_IO_PAD_1800000UV; @@ -1567,6 +1582,7 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = { .cpu_powergates = tegra30_cpu_powergates, .has_tsense_reset = true, .has_gpu_clamps = false, + .has_impl_33v_pwr = false, .num_io_pads = 0, .io_pads = NULL, .regs = &tegra20_pmc_regs, @@ -1609,6 +1625,7 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = { .cpu_powergates = tegra114_cpu_powergates, .has_tsense_reset = true, .has_gpu_clamps = false, + .has_impl_33v_pwr = false, .num_io_pads = 0, .io_pads = NULL, .regs = &tegra20_pmc_regs, @@ -1689,6 +1706,7 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = { .cpu_powergates = tegra124_cpu_powergates, .has_tsense_reset = true, .has_gpu_clamps = true, + .has_impl_33v_pwr = false, .num_io_pads = ARRAY_SIZE(tegra124_io_pads), .io_pads = tegra124_io_pads, .regs = &tegra20_pmc_regs, @@ -1778,6 +1796,7 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = { .cpu_powergates = tegra210_cpu_powergates, .has_tsense_reset = true, .has_gpu_clamps = true, + .has_impl_33v_pwr = false, .needs_mbist_war = true, .num_io_pads = ARRAY_SIZE(tegra210_io_pads), .io_pads = tegra210_io_pads, @@ -1806,7 +1825,7 @@ static const struct tegra_io_pad_soc tegra186_io_pads[] = { { .id = TEGRA_IO_PAD_HDMI_DP0, .dpd = 28, .voltage = UINT_MAX }, { .id = TEGRA_IO_PAD_HDMI_DP1, .dpd = 29, .voltage = UINT_MAX }, { .id = TEGRA_IO_PAD_PEX_CNTRL, .dpd = 32, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_SDMMC2_HV, .dpd = 34, .voltage = UINT_MAX }, + { .id = TEGRA_IO_PAD_SDMMC2_HV, .dpd = 34, .voltage = 5 }, { .id = TEGRA_IO_PAD_SDMMC4, .dpd = 36, .voltage = UINT_MAX }, { .id = TEGRA_IO_PAD_CAM, .dpd = 38, .voltage = UINT_MAX }, { .id = TEGRA_IO_PAD_DSIB, .dpd = 40, .voltage = UINT_MAX }, @@ -1818,12 +1837,13 @@ static const struct tegra_io_pad_soc tegra186_io_pads[] = { { .id = TEGRA_IO_PAD_CSIF, .dpd = 46, .voltage = UINT_MAX }, { .id = TEGRA_IO_PAD_SPI, .dpd = 47, .voltage = UINT_MAX }, { .id = TEGRA_IO_PAD_UFS, .dpd = 49, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_DMIC_HV, .dpd = 52, .voltage = UINT_MAX }, + { .id = TEGRA_IO_PAD_DMIC_HV, .dpd = 52, .voltage = 2 }, { .id = TEGRA_IO_PAD_EDP, .dpd = 53, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_SDMMC1_HV, .dpd = 55, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_SDMMC3_HV, .dpd = 56, .voltage = UINT_MAX }, + { .id = TEGRA_IO_PAD_SDMMC1_HV, .dpd = 55, .voltage = 4 }, + { .id = TEGRA_IO_PAD_SDMMC3_HV, .dpd = 56, .voltage = 6 }, { .id = TEGRA_IO_PAD_CONN, .dpd = 60, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_AUDIO_HV, .dpd = 61, .voltage = UINT_MAX }, + { .id = TEGRA_IO_PAD_AUDIO_HV, .dpd = 61, .voltage = 1 }, + { .id = TEGRA_IO_PAD_AO_HV, .dpd = UINT_MAX, .voltage = 0 }, }; static const struct tegra_pmc_regs tegra186_pmc_regs = { @@ -1876,6 +1896,7 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = { .cpu_powergates = NULL, .has_tsense_reset = false, .has_gpu_clamps = false, + .has_impl_33v_pwr = true, .num_io_pads = ARRAY_SIZE(tegra186_io_pads), .io_pads = tegra186_io_pads, .regs = &tegra186_pmc_regs, diff --git a/include/soc/tegra/pmc.h b/include/soc/tegra/pmc.h index c32bf91..445aa66 100644 --- a/include/soc/tegra/pmc.h +++ b/include/soc/tegra/pmc.h @@ -134,6 +134,7 @@ enum tegra_io_pad { TEGRA_IO_PAD_USB2, TEGRA_IO_PAD_USB3, TEGRA_IO_PAD_USB_BIAS, + TEGRA_IO_PAD_AO_HV, }; /* deprecated, use TEGRA_IO_PAD_{HDMI,LVDS} instead */ -- 2.7.4 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v3 2/7] soc/tegra: pmc: Factor out DPD register bit calculation 2018-07-12 12:00 [PATCH v3 0/7] Tegra PMC pinctrl pad configuration Aapo Vienamo 2018-07-12 12:00 ` [PATCH v3 1/7] soc/tegra: pmc: Fix pad voltage configuration for Tegra186 Aapo Vienamo @ 2018-07-12 12:00 ` Aapo Vienamo 2018-07-12 12:00 ` [PATCH v3 3/7] soc/tegra: pmc: Implement tegra_io_pad_is_powered() Aapo Vienamo ` (4 subsequent siblings) 6 siblings, 0 replies; 15+ messages in thread From: Aapo Vienamo @ 2018-07-12 12:00 UTC (permalink / raw) To: Rob Herring, Mark Rutland, Thierry Reding, Jonathan Hunter, Mikko Perttunen, Laxman Dewangan Cc: Aapo Vienamo, devicetree, linux-tegra, linux-kernel Factor out the the code to calculate the correct DPD register and bit number for a given pad. This logic will be needed to query the status register. Signed-off-by: Aapo Vienamo <avienamo@nvidia.com> Acked-by: Jon Hunter <jonathanh@nvidia.com> --- drivers/soc/tegra/pmc.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index f926332..393ca72 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -922,11 +922,12 @@ tegra_io_pad_find(struct tegra_pmc *pmc, enum tegra_io_pad id) return NULL; } -static int tegra_io_pad_prepare(enum tegra_io_pad id, unsigned long *request, - unsigned long *status, u32 *mask) +static int tegra_io_pad_get_dpd_register_bit(enum tegra_io_pad id, + unsigned long *request, + unsigned long *status, + u32 *mask) { const struct tegra_io_pad_soc *pad; - unsigned long rate, value; pad = tegra_io_pad_find(pmc, id); if (!pad) { @@ -947,6 +948,19 @@ static int tegra_io_pad_prepare(enum tegra_io_pad id, unsigned long *request, *request = pmc->soc->regs->dpd2_req; } + return 0; +} + +static int tegra_io_pad_prepare(enum tegra_io_pad id, unsigned long *request, + unsigned long *status, u32 *mask) +{ + unsigned long rate, value; + int err; + + err = tegra_io_pad_get_dpd_register_bit(id, request, status, mask); + if (err) + return err; + if (pmc->clk) { rate = clk_get_rate(pmc->clk); if (!rate) { -- 2.7.4 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v3 3/7] soc/tegra: pmc: Implement tegra_io_pad_is_powered() 2018-07-12 12:00 [PATCH v3 0/7] Tegra PMC pinctrl pad configuration Aapo Vienamo 2018-07-12 12:00 ` [PATCH v3 1/7] soc/tegra: pmc: Fix pad voltage configuration for Tegra186 Aapo Vienamo 2018-07-12 12:00 ` [PATCH v3 2/7] soc/tegra: pmc: Factor out DPD register bit calculation Aapo Vienamo @ 2018-07-12 12:00 ` Aapo Vienamo 2018-07-12 12:00 ` [PATCH v3 4/7] soc/tegra: pmc: Use X macro to generate IO pad tables Aapo Vienamo ` (3 subsequent siblings) 6 siblings, 0 replies; 15+ messages in thread From: Aapo Vienamo @ 2018-07-12 12:00 UTC (permalink / raw) To: Rob Herring, Mark Rutland, Thierry Reding, Jonathan Hunter, Mikko Perttunen, Laxman Dewangan Cc: Aapo Vienamo, devicetree, linux-tegra, linux-kernel Implement a function to query whether a pad is in deep power down mode. This will is needed by the pinctrl callbacks. Signed-off-by: Aapo Vienamo <avienamo@nvidia.com> Acked-by: Jon Hunter <jonathanh@nvidia.com> --- drivers/soc/tegra/pmc.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 393ca72..784c182 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -1075,6 +1075,22 @@ int tegra_io_pad_power_disable(enum tegra_io_pad id) } EXPORT_SYMBOL(tegra_io_pad_power_disable); +static int tegra_io_pad_is_powered(enum tegra_io_pad id) +{ + unsigned long request, status; + u32 mask; + u32 value; + int err; + + err = tegra_io_pad_get_dpd_register_bit(id, &request, &status, &mask); + if (err) + return err; + + value = tegra_pmc_readl(status); + + return !(value & mask); +} + int tegra_io_pad_set_voltage(enum tegra_io_pad id, enum tegra_io_pad_voltage voltage) { -- 2.7.4 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v3 4/7] soc/tegra: pmc: Use X macro to generate IO pad tables 2018-07-12 12:00 [PATCH v3 0/7] Tegra PMC pinctrl pad configuration Aapo Vienamo ` (2 preceding siblings ...) 2018-07-12 12:00 ` [PATCH v3 3/7] soc/tegra: pmc: Implement tegra_io_pad_is_powered() Aapo Vienamo @ 2018-07-12 12:00 ` Aapo Vienamo 2018-07-12 12:00 ` [PATCH v3 5/7] dt-bindings: Add Tegra PMC pad configuration bindings Aapo Vienamo ` (2 subsequent siblings) 6 siblings, 0 replies; 15+ messages in thread From: Aapo Vienamo @ 2018-07-12 12:00 UTC (permalink / raw) To: Rob Herring, Mark Rutland, Thierry Reding, Jonathan Hunter, Mikko Perttunen, Laxman Dewangan Cc: Aapo Vienamo, devicetree, linux-tegra, linux-kernel Refactor the IO pad tables into macro tables so that they can be reused to generate pinctrl pin descriptors. Also add a name field which is needed by pinctrl. Signed-off-by: Aapo Vienamo <avienamo@nvidia.com> --- drivers/soc/tegra/pmc.c | 233 ++++++++++++++++++++++++++---------------------- 1 file changed, 127 insertions(+), 106 deletions(-) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 784c182..38cb915 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -137,6 +137,7 @@ struct tegra_io_pad_soc { enum tegra_io_pad id; unsigned int dpd; unsigned int voltage; + const char *name; }; struct tegra_pmc_regs { @@ -1696,37 +1697,49 @@ static const u8 tegra124_cpu_powergates[] = { TEGRA_POWERGATE_CPU3, }; +#define TEGRA_IO_PAD(_id, _dpd, _voltage, _name) \ + ((struct tegra_io_pad_soc) { \ + .id = (_id), \ + .dpd = (_dpd), \ + .voltage = (_voltage), \ + .name = (_name), \ + }) + +#define TEGRA124_IO_PAD_TABLE(_pad) \ + /* .id .dpd .voltage .name */ \ + _pad(TEGRA_IO_PAD_AUDIO, 17, UINT_MAX, "audio"), \ + _pad(TEGRA_IO_PAD_BB, 15, UINT_MAX, "bb"), \ + _pad(TEGRA_IO_PAD_CAM, 36, UINT_MAX, "cam"), \ + _pad(TEGRA_IO_PAD_COMP, 22, UINT_MAX, "comp"), \ + _pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \ + _pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csb"), \ + _pad(TEGRA_IO_PAD_CSIE, 44, UINT_MAX, "cse"), \ + _pad(TEGRA_IO_PAD_DSI, 2, UINT_MAX, "dsi"), \ + _pad(TEGRA_IO_PAD_DSIB, 39, UINT_MAX, "dsib"), \ + _pad(TEGRA_IO_PAD_DSIC, 40, UINT_MAX, "dsic"), \ + _pad(TEGRA_IO_PAD_DSID, 41, UINT_MAX, "dsid"), \ + _pad(TEGRA_IO_PAD_HDMI, 28, UINT_MAX, "hdmi"), \ + _pad(TEGRA_IO_PAD_HSIC, 19, UINT_MAX, "hsic"), \ + _pad(TEGRA_IO_PAD_HV, 38, UINT_MAX, "hv"), \ + _pad(TEGRA_IO_PAD_LVDS, 57, UINT_MAX, "lvds"), \ + _pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \ + _pad(TEGRA_IO_PAD_NAND, 13, UINT_MAX, "nand"), \ + _pad(TEGRA_IO_PAD_PEX_BIAS, 4, UINT_MAX, "pex-bias"), \ + _pad(TEGRA_IO_PAD_PEX_CLK1, 5, UINT_MAX, "pex-clk1"), \ + _pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \ + _pad(TEGRA_IO_PAD_PEX_CNTRL, 32, UINT_MAX, "pex-cntrl"), \ + _pad(TEGRA_IO_PAD_SDMMC1, 33, UINT_MAX, "sdmmc1"), \ + _pad(TEGRA_IO_PAD_SDMMC3, 34, UINT_MAX, "sdmmc3"), \ + _pad(TEGRA_IO_PAD_SDMMC4, 35, UINT_MAX, "sdmmc4"), \ + _pad(TEGRA_IO_PAD_SYS_DDC, 58, UINT_MAX, "sys_ddc"), \ + _pad(TEGRA_IO_PAD_UART, 14, UINT_MAX, "uart"), \ + _pad(TEGRA_IO_PAD_USB0, 9, UINT_MAX, "usb0"), \ + _pad(TEGRA_IO_PAD_USB1, 10, UINT_MAX, "usb1"), \ + _pad(TEGRA_IO_PAD_USB2, 11, UINT_MAX, "usb2"), \ + _pad(TEGRA_IO_PAD_USB_BIAS, 12, UINT_MAX, "usb_bias") + static const struct tegra_io_pad_soc tegra124_io_pads[] = { - { .id = TEGRA_IO_PAD_AUDIO, .dpd = 17, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_BB, .dpd = 15, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_CAM, .dpd = 36, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_COMP, .dpd = 22, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_CSIA, .dpd = 0, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_CSIB, .dpd = 1, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_CSIE, .dpd = 44, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_DSI, .dpd = 2, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_DSIB, .dpd = 39, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_DSIC, .dpd = 40, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_DSID, .dpd = 41, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_HDMI, .dpd = 28, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_HSIC, .dpd = 19, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_HV, .dpd = 38, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_LVDS, .dpd = 57, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_MIPI_BIAS, .dpd = 3, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_NAND, .dpd = 13, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_PEX_BIAS, .dpd = 4, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_PEX_CLK1, .dpd = 5, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_PEX_CLK2, .dpd = 6, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_PEX_CNTRL, .dpd = 32, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_SDMMC1, .dpd = 33, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_SDMMC3, .dpd = 34, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_SDMMC4, .dpd = 35, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_SYS_DDC, .dpd = 58, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_UART, .dpd = 14, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_USB0, .dpd = 9, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_USB1, .dpd = 10, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_USB2, .dpd = 11, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_USB_BIAS, .dpd = 12, .voltage = UINT_MAX }, + TEGRA124_IO_PAD_TABLE(TEGRA_IO_PAD) }; static const struct tegra_pmc_soc tegra124_pmc_soc = { @@ -1778,45 +1791,49 @@ static const u8 tegra210_cpu_powergates[] = { TEGRA_POWERGATE_CPU3, }; +#define TEGRA210_IO_PAD_TABLE(_pad) \ + /* .id .dpd .voltage .name */ \ + _pad(TEGRA_IO_PAD_AUDIO, 17, 5, "audio"), \ + _pad(TEGRA_IO_PAD_AUDIO_HV, 61, 18, "audio-hv"), \ + _pad(TEGRA_IO_PAD_CAM, 36, 10, "cam"), \ + _pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \ + _pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csib"), \ + _pad(TEGRA_IO_PAD_CSIC, 42, UINT_MAX, "csic"), \ + _pad(TEGRA_IO_PAD_CSID, 43, UINT_MAX, "csid"), \ + _pad(TEGRA_IO_PAD_CSIE, 44, UINT_MAX, "csie"), \ + _pad(TEGRA_IO_PAD_CSIF, 45, UINT_MAX, "csif"), \ + _pad(TEGRA_IO_PAD_DBG, 25, 19, "dbg"), \ + _pad(TEGRA_IO_PAD_DEBUG_NONAO, 26, UINT_MAX, "debug-nonao"), \ + _pad(TEGRA_IO_PAD_DMIC, 50, 20, "dmic"), \ + _pad(TEGRA_IO_PAD_DP, 51, UINT_MAX, "dp"), \ + _pad(TEGRA_IO_PAD_DSI, 2, UINT_MAX, "dsi"), \ + _pad(TEGRA_IO_PAD_DSIB, 39, UINT_MAX, "dsib"), \ + _pad(TEGRA_IO_PAD_DSIC, 40, UINT_MAX, "dsic"), \ + _pad(TEGRA_IO_PAD_DSID, 41, UINT_MAX, "dsid"), \ + _pad(TEGRA_IO_PAD_EMMC, 35, UINT_MAX, "emmc"), \ + _pad(TEGRA_IO_PAD_EMMC2, 37, UINT_MAX, "emmc2"), \ + _pad(TEGRA_IO_PAD_GPIO, 27, 21, "gpio"), \ + _pad(TEGRA_IO_PAD_HDMI, 28, UINT_MAX, "hdmi"), \ + _pad(TEGRA_IO_PAD_HSIC, 19, UINT_MAX, "hsic"), \ + _pad(TEGRA_IO_PAD_LVDS, 57, UINT_MAX, "lvds"), \ + _pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \ + _pad(TEGRA_IO_PAD_PEX_BIAS, 4, UINT_MAX, "pex-bias"), \ + _pad(TEGRA_IO_PAD_PEX_CLK1, 5, UINT_MAX, "pex-clk1"), \ + _pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \ + _pad(TEGRA_IO_PAD_PEX_CNTRL, UINT_MAX, 11, "pex-cntrl"), \ + _pad(TEGRA_IO_PAD_SDMMC1, 33, 12, "sdmmc1"), \ + _pad(TEGRA_IO_PAD_SDMMC3, 34, 13, "sdmmc3"), \ + _pad(TEGRA_IO_PAD_SPI, 46, 22, "spi"), \ + _pad(TEGRA_IO_PAD_SPI_HV, 47, 23, "spi-hv"), \ + _pad(TEGRA_IO_PAD_UART, 14, 2, "uart"), \ + _pad(TEGRA_IO_PAD_USB0, 9, UINT_MAX, "usb0"), \ + _pad(TEGRA_IO_PAD_USB1, 10, UINT_MAX, "usb1"), \ + _pad(TEGRA_IO_PAD_USB2, 11, UINT_MAX, "usb2"), \ + _pad(TEGRA_IO_PAD_USB3, 18, UINT_MAX, "usb3"), \ + _pad(TEGRA_IO_PAD_USB_BIAS, 12, UINT_MAX, "usb-bias") + static const struct tegra_io_pad_soc tegra210_io_pads[] = { - { .id = TEGRA_IO_PAD_AUDIO, .dpd = 17, .voltage = 5 }, - { .id = TEGRA_IO_PAD_AUDIO_HV, .dpd = 61, .voltage = 18 }, - { .id = TEGRA_IO_PAD_CAM, .dpd = 36, .voltage = 10 }, - { .id = TEGRA_IO_PAD_CSIA, .dpd = 0, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_CSIB, .dpd = 1, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_CSIC, .dpd = 42, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_CSID, .dpd = 43, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_CSIE, .dpd = 44, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_CSIF, .dpd = 45, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_DBG, .dpd = 25, .voltage = 19 }, - { .id = TEGRA_IO_PAD_DEBUG_NONAO, .dpd = 26, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_DMIC, .dpd = 50, .voltage = 20 }, - { .id = TEGRA_IO_PAD_DP, .dpd = 51, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_DSI, .dpd = 2, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_DSIB, .dpd = 39, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_DSIC, .dpd = 40, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_DSID, .dpd = 41, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_EMMC, .dpd = 35, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_EMMC2, .dpd = 37, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_GPIO, .dpd = 27, .voltage = 21 }, - { .id = TEGRA_IO_PAD_HDMI, .dpd = 28, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_HSIC, .dpd = 19, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_LVDS, .dpd = 57, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_MIPI_BIAS, .dpd = 3, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_PEX_BIAS, .dpd = 4, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_PEX_CLK1, .dpd = 5, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_PEX_CLK2, .dpd = 6, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_PEX_CNTRL, .dpd = UINT_MAX, .voltage = 11 }, - { .id = TEGRA_IO_PAD_SDMMC1, .dpd = 33, .voltage = 12 }, - { .id = TEGRA_IO_PAD_SDMMC3, .dpd = 34, .voltage = 13 }, - { .id = TEGRA_IO_PAD_SPI, .dpd = 46, .voltage = 22 }, - { .id = TEGRA_IO_PAD_SPI_HV, .dpd = 47, .voltage = 23 }, - { .id = TEGRA_IO_PAD_UART, .dpd = 14, .voltage = 2 }, - { .id = TEGRA_IO_PAD_USB0, .dpd = 9, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_USB1, .dpd = 10, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_USB2, .dpd = 11, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_USB3, .dpd = 18, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_USB_BIAS, .dpd = 12, .voltage = UINT_MAX }, + TEGRA210_IO_PAD_TABLE(TEGRA_IO_PAD) }; static const struct tegra_pmc_soc tegra210_pmc_soc = { @@ -1835,45 +1852,49 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = { .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, }; +#define TEGRA186_IO_PAD_TABLE(_pad) \ + /* .id .dpd .voltage .name */ \ + _pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \ + _pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csib"), \ + _pad(TEGRA_IO_PAD_DSI, 2, UINT_MAX, "dsi"), \ + _pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \ + _pad(TEGRA_IO_PAD_PEX_CLK_BIAS, 4, UINT_MAX, "pex-clk-bias"), \ + _pad(TEGRA_IO_PAD_PEX_CLK3, 5, UINT_MAX, "pex-clk3"), \ + _pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \ + _pad(TEGRA_IO_PAD_PEX_CLK1, 7, UINT_MAX, "pex-clk1"), \ + _pad(TEGRA_IO_PAD_USB0, 9, UINT_MAX, "usb0"), \ + _pad(TEGRA_IO_PAD_USB1, 10, UINT_MAX, "usb1"), \ + _pad(TEGRA_IO_PAD_USB2, 11, UINT_MAX, "usb2"), \ + _pad(TEGRA_IO_PAD_USB_BIAS, 12, UINT_MAX, "usb-bias"), \ + _pad(TEGRA_IO_PAD_UART, 14, UINT_MAX, "uart"), \ + _pad(TEGRA_IO_PAD_AUDIO, 17, UINT_MAX, "audio"), \ + _pad(TEGRA_IO_PAD_HSIC, 19, UINT_MAX, "hsic"), \ + _pad(TEGRA_IO_PAD_DBG, 25, UINT_MAX, "dbg"), \ + _pad(TEGRA_IO_PAD_HDMI_DP0, 28, UINT_MAX, "hdmi-dp0"), \ + _pad(TEGRA_IO_PAD_HDMI_DP1, 29, UINT_MAX, "hdmi-dp1"), \ + _pad(TEGRA_IO_PAD_PEX_CNTRL, 32, UINT_MAX, "pex-cntrl"), \ + _pad(TEGRA_IO_PAD_SDMMC2_HV, 34, 5, "sdmmc2-hv"), \ + _pad(TEGRA_IO_PAD_SDMMC4, 36, UINT_MAX, "sdmmc4"), \ + _pad(TEGRA_IO_PAD_CAM, 38, UINT_MAX, "cam"), \ + _pad(TEGRA_IO_PAD_DSIB, 40, UINT_MAX, "dsib"), \ + _pad(TEGRA_IO_PAD_DSIC, 41, UINT_MAX, "dsic"), \ + _pad(TEGRA_IO_PAD_DSID, 42, UINT_MAX, "dsid"), \ + _pad(TEGRA_IO_PAD_CSIC, 43, UINT_MAX, "csic"), \ + _pad(TEGRA_IO_PAD_CSID, 44, UINT_MAX, "csid"), \ + _pad(TEGRA_IO_PAD_CSIE, 45, UINT_MAX, "csie"), \ + _pad(TEGRA_IO_PAD_CSIF, 46, UINT_MAX, "csif"), \ + _pad(TEGRA_IO_PAD_SPI, 47, UINT_MAX, "spi"), \ + _pad(TEGRA_IO_PAD_UFS, 49, UINT_MAX, "ufs"), \ + _pad(TEGRA_IO_PAD_DMIC_HV, 52, 2, "dmic-hv"), \ + _pad(TEGRA_IO_PAD_EDP, 53, UINT_MAX, "edp"), \ + _pad(TEGRA_IO_PAD_SDMMC1_HV, 55, 4, "sdmmc1-hv"), \ + _pad(TEGRA_IO_PAD_SDMMC3_HV, 56, 6, "sdmmc3-hv"), \ + _pad(TEGRA_IO_PAD_CONN, 60, UINT_MAX, "conn"), \ + _pad(TEGRA_IO_PAD_AUDIO_HV, 61, 1, "audio-hv"), \ + _pad(TEGRA_IO_PAD_AO_HV, UINT_MAX, 0, "ao-hv") + static const struct tegra_io_pad_soc tegra186_io_pads[] = { - { .id = TEGRA_IO_PAD_CSIA, .dpd = 0, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_CSIB, .dpd = 1, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_DSI, .dpd = 2, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_MIPI_BIAS, .dpd = 3, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_PEX_CLK_BIAS, .dpd = 4, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_PEX_CLK3, .dpd = 5, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_PEX_CLK2, .dpd = 6, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_PEX_CLK1, .dpd = 7, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_USB0, .dpd = 9, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_USB1, .dpd = 10, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_USB2, .dpd = 11, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_USB_BIAS, .dpd = 12, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_UART, .dpd = 14, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_AUDIO, .dpd = 17, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_HSIC, .dpd = 19, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_DBG, .dpd = 25, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_HDMI_DP0, .dpd = 28, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_HDMI_DP1, .dpd = 29, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_PEX_CNTRL, .dpd = 32, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_SDMMC2_HV, .dpd = 34, .voltage = 5 }, - { .id = TEGRA_IO_PAD_SDMMC4, .dpd = 36, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_CAM, .dpd = 38, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_DSIB, .dpd = 40, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_DSIC, .dpd = 41, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_DSID, .dpd = 42, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_CSIC, .dpd = 43, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_CSID, .dpd = 44, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_CSIE, .dpd = 45, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_CSIF, .dpd = 46, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_SPI, .dpd = 47, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_UFS, .dpd = 49, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_DMIC_HV, .dpd = 52, .voltage = 2 }, - { .id = TEGRA_IO_PAD_EDP, .dpd = 53, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_SDMMC1_HV, .dpd = 55, .voltage = 4 }, - { .id = TEGRA_IO_PAD_SDMMC3_HV, .dpd = 56, .voltage = 6 }, - { .id = TEGRA_IO_PAD_CONN, .dpd = 60, .voltage = UINT_MAX }, - { .id = TEGRA_IO_PAD_AUDIO_HV, .dpd = 61, .voltage = 1 }, - { .id = TEGRA_IO_PAD_AO_HV, .dpd = UINT_MAX, .voltage = 0 }, + TEGRA186_IO_PAD_TABLE(TEGRA_IO_PAD) }; static const struct tegra_pmc_regs tegra186_pmc_regs = { -- 2.7.4 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v3 5/7] dt-bindings: Add Tegra PMC pad configuration bindings 2018-07-12 12:00 [PATCH v3 0/7] Tegra PMC pinctrl pad configuration Aapo Vienamo ` (3 preceding siblings ...) 2018-07-12 12:00 ` [PATCH v3 4/7] soc/tegra: pmc: Use X macro to generate IO pad tables Aapo Vienamo @ 2018-07-12 12:00 ` Aapo Vienamo 2018-07-16 15:43 ` Rob Herring 2018-07-12 12:00 ` [PATCH v3 6/7] soc/tegra: pmc: Remove public pad voltage APIs Aapo Vienamo 2018-07-12 12:00 ` [PATCH v3 7/7] soc/tegra: pmc: Implement pad configuration via pinctrl Aapo Vienamo 6 siblings, 1 reply; 15+ messages in thread From: Aapo Vienamo @ 2018-07-12 12:00 UTC (permalink / raw) To: Rob Herring, Mark Rutland, Thierry Reding, Jonathan Hunter, Mikko Perttunen, Laxman Dewangan Cc: Aapo Vienamo, devicetree, linux-tegra, linux-kernel Document the pinctrl bindings used by the PMC driver for performing pad configuration. Both nvidia,tegra186-pmc.txt and nvidia,tegra20-pmc.txt are modified as they both cover SoC generations for which these bindings apply. Add a header defining Tegra PMC pad voltage configurations. Signed-off-by: Aapo Vienamo <avienamo@nvidia.com> Acked-by: Jon Hunter <jonathanh@nvidia.com> --- .../bindings/arm/tegra/nvidia,tegra186-pmc.txt | 84 +++++++++++++++++++ .../bindings/arm/tegra/nvidia,tegra20-pmc.txt | 95 ++++++++++++++++++++++ include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h | 18 ++++ 3 files changed, 197 insertions(+) create mode 100644 include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt index 5a3bf7c..9528f41 100644 --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt @@ -34,3 +34,87 @@ Board DTS: pmc@c360000 { nvidia,invert-interrupt; }; + +== Pad Control Nodes == + +The PMC can be used to set pad power state and voltage configuration. +The pad configuration is done via the pinctrl framework. The driver +implements power-source, low-power-enable, and low-power-disable pinconf +pin configuration node properties. Each pinctrl pin corresponds to a +single Tegra PMC pad. Thus, in the following sections of this document +pin refers to the pinctrl frameworks notion of a Tegra PMC pad. + +The pad configuration state nodes are placed under the pmc node and they +are referred to by the pinctrl client device properties. For more +information see the examples presented later and +Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt. + +The values accepted by power-source property are +TEGRA_IO_PAD_VOLTAGE_1V8 and TEGRA_IO_PAD_VOLTAGE_3V3, which are defined +in dt-bindings/pinctrl/pinctrl-tegra-io-pad.h. + +Following pinctrl pin name strings are present on Tegra186: +csia csib dsi mipi-bias +pex-clk-bias pex-clk3 pex-clk2 pex-clk1 +usb0 usb1 usb2 usb-bias +uart audio hsic dbg +hdmi-dp0 hdmi-dp1 pex-cntrl sdmmc2-hv +sdmmc4 cam dsib dsic +dsid csic csid csie +dsif spi ufs dmic-hv +edp sdmmc1-hv sdmmc3-hv conn +audio-hv ao-hv + +All of the listed Tegra186 pins except ao-hv support the +low-power-enable and low-power-disable properties. The power-source +property is supported following Tegra210 pins: sdmmc2-hv, dmic-hv, +sdmmc1-hv, sdmmc3-hv, audio-hv, ao-hv. + +Pad configuration state example: + pmc: pmc@7000e400 { + compatible = "nvidia,tegra186-pmc"; + reg = <0 0x0c360000 0 0x10000>, + <0 0x0c370000 0 0x10000>, + <0 0x0c380000 0 0x10000>, + <0 0x0c390000 0 0x10000>; + reg-names = "pmc", "wake", "aotag", "scratch"; + + ... + + sdmmc1_3v3: sdmmc1-3v3 { + pins = "sdmmc1-hv"; + power-source = <TEGRA_IO_PAD_VOLTAGE_3V3>; + }; + + sdmmc1_1v8: sdmmc1-1v8 { + pins = "sdmmc1-hv"; + power-source = <TEGRA_IO_PAD_VOLTAGE_1V8>; + }; + + hdmi_off: hdmi-off { + pins = "hdmi"; + low-power-enable; + } + + hdmi_on: hdmi-on { + pins = "hdmi"; + low-power-disable; + } + }; + +Pinctrl client example: + sdmmc1: sdhci@3400000 { + ... + pinctrl-names = "sdmmc-3v3", "sdmmc-1v8"; + pinctrl-0 = <&sdmmc1_3v3>; + pinctrl-1 = <&sdmmc1_1v8>; + }; + + ... + + sor0: sor@15540000 { + ... + pinctrl-0 = <&hdmi_off>; + pinctrl-1 = <&hdmi_on>; + pinctrl-names = "hdmi-on", "hdmi-off"; + }; diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt index a74b37b..d50a505 100644 --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt @@ -195,3 +195,98 @@ Example: power-domains = <&pd_audio>; ... }; + +== Pad Control Nodes == + +The PMC can be used to set pad power state and voltage configuration. +This functionality is present on SoCs from Tegra124 onwards. The pad +configuration is done via the pinctrl framework. The driver implements +power-source, low-power-enable, and low-power-disable pinconf pin +configuration node properties. Each pinctrl pin corresponds to a single +Tegra PMC pad. Thus, in the following sections of this document pin +refers to the pinctrl frameworks notion of a Tegra PMC pad. + +The pad configuration state nodes are placed under the pmc node and they +are referred to by the pinctrl client device properties. For more +information see the examples presented later and +Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt. + +The values accepted by power-source property are +TEGRA_IO_PAD_VOLTAGE_1V8 and TEGRA_IO_PAD_VOLTAGE_3V3, which are defined +in dt-bindings/pinctrl/pinctrl-tegra-io-pad.h. + +Following pinctrl pin name strings are present on Tegra124 and Tegra132: +audio bb cam comp +csia csb cse dsi +dsib dsic dsid hdmi +hsic hv lvds mipi-bias +nand pex-bias pex-clk1 pex-clk2 +pex-cntrl sdmmc1 sdmmc3 sdmmc4 +sys_ddc uart usb0 usb1 +usb2 usb_bias + +All of the listed Tegra124 and Tegra132 pins support the +low-power-enable and low-power-disable properties. None of the pins +support the power-source property. + +Following pinctrl pin name strings are present on Tegra210: +audio audio-hv cam csia +csib csic csid csie +csif dbg debug-nonao dmic +dp dsi dsib dsic +dsid emmc emmc2 gpio +hdmi hsic lvds mipi-bias +pex-bias pex-clk1 pex-clk2 pex-cntrl +sdmmc1 sdmmc3 spi spi-hv +uart usb0 usb1 usb2 +usb3 usb-bias + +All of the listed Tegra210 pins except pex-cntrl support the +low-power-enable and low-power-disable properties. The power-source +property is supported following Tegra210 pins: audio, audio-hv, cam, +dbg, dmic, gpio, pex-cntrl, sdmmc1, sdmmc3, spi, spi-hv, and uart. + +Pad configuration state example: + pmc: pmc@7000e400 { + compatible = "nvidia,tegra210-pmc"; + reg = <0x0 0x7000e400 0x0 0x400>; + clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>; + clock-names = "pclk", "clk32k_in"; + + ... + + sdmmc1_3v3: sdmmc1-3v3 { + pins = "sdmmc1"; + power-source = <TEGRA_IO_PAD_VOLTAGE_3V3>; + }; + + sdmmc1_1v8: sdmmc1-1v8 { + pins = "sdmmc1"; + power-source = <TEGRA_IO_PAD_VOLTAGE_1V8>; + }; + + hdmi_off: hdmi-off { + pins = "hdmi"; + low-power-enable; + } + + hdmi_on: hdmi-on { + pins = "hdmi"; + low-power-disable; + } + }; + +Pinctrl client example: + sdmmc1: sdhci@700b0000 { + ... + pinctrl-names = "sdmmc-3v3", "sdmmc-1v8"; + pinctrl-0 = <&sdmmc1_3v3>; + pinctrl-1 = <&sdmmc1_1v8>; + }; + ... + sor@54540000 { + ... + pinctrl-0 = <&hdmi_off>; + pinctrl-1 = <&hdmi_on>; + pinctrl-names = "hdmi-on", "hdmi-off"; + }; diff --git a/include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h b/include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h new file mode 100644 index 0000000..20f4340 --- /dev/null +++ b/include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * pinctrl-tegra-io-pad.h: Tegra I/O pad source voltage configuration constants + * pinctrl bindings. + * + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Author: Aapo Vienamo <avienamo@nvidia.com> + */ + +#ifndef _DT_BINDINGS_PINCTRL_TEGRA_IO_PAD_H +#define _DT_BINDINGS_PINCTRL_TEGRA_IO_PAD_H + +/* Voltage levels of the I/O pad's source rail */ +#define TEGRA_IO_PAD_VOLTAGE_1V8 0 +#define TEGRA_IO_PAD_VOLTAGE_3V3 1 + +#endif -- 2.7.4 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v3 5/7] dt-bindings: Add Tegra PMC pad configuration bindings 2018-07-12 12:00 ` [PATCH v3 5/7] dt-bindings: Add Tegra PMC pad configuration bindings Aapo Vienamo @ 2018-07-16 15:43 ` Rob Herring 2018-07-17 12:23 ` Aapo Vienamo 0 siblings, 1 reply; 15+ messages in thread From: Rob Herring @ 2018-07-16 15:43 UTC (permalink / raw) To: Aapo Vienamo Cc: Mark Rutland, Thierry Reding, Jonathan Hunter, Mikko Perttunen, Laxman Dewangan, devicetree, linux-tegra, linux-kernel On Thu, Jul 12, 2018 at 03:00:11PM +0300, Aapo Vienamo wrote: > Document the pinctrl bindings used by the PMC driver for performing pad > configuration. Both nvidia,tegra186-pmc.txt and nvidia,tegra20-pmc.txt > are modified as they both cover SoC generations for which these bindings > apply. > > Add a header defining Tegra PMC pad voltage configurations. > > Signed-off-by: Aapo Vienamo <avienamo@nvidia.com> > Acked-by: Jon Hunter <jonathanh@nvidia.com> > --- > .../bindings/arm/tegra/nvidia,tegra186-pmc.txt | 84 +++++++++++++++++++ > .../bindings/arm/tegra/nvidia,tegra20-pmc.txt | 95 ++++++++++++++++++++++ > include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h | 18 ++++ > 3 files changed, 197 insertions(+) > create mode 100644 include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h > > diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt > index 5a3bf7c..9528f41 100644 > --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt > +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt > @@ -34,3 +34,87 @@ Board DTS: > pmc@c360000 { > nvidia,invert-interrupt; > }; > + > +== Pad Control Nodes == > + > +The PMC can be used to set pad power state and voltage configuration. > +The pad configuration is done via the pinctrl framework. The driver > +implements power-source, low-power-enable, and low-power-disable pinconf > +pin configuration node properties. Each pinctrl pin corresponds to a > +single Tegra PMC pad. Thus, in the following sections of this document > +pin refers to the pinctrl frameworks notion of a Tegra PMC pad. "pinctrl framework" is Linux specific and doesn't belong in the binding. Neither does what a driver supports. Describe what the h/w supports. > + > +The pad configuration state nodes are placed under the pmc node and they > +are referred to by the pinctrl client device properties. For more Another driver detail not relevant. > +information see the examples presented later and examples don't document bindings. The documentation should be complete without examples. > +Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt. > + > +The values accepted by power-source property are > +TEGRA_IO_PAD_VOLTAGE_1V8 and TEGRA_IO_PAD_VOLTAGE_3V3, which are defined > +in dt-bindings/pinctrl/pinctrl-tegra-io-pad.h. You need to list out what properties the child nodes can have. power-source needs a vendor prefix. > + > +Following pinctrl pin name strings are present on Tegra186: > +csia csib dsi mipi-bias > +pex-clk-bias pex-clk3 pex-clk2 pex-clk1 > +usb0 usb1 usb2 usb-bias > +uart audio hsic dbg > +hdmi-dp0 hdmi-dp1 pex-cntrl sdmmc2-hv > +sdmmc4 cam dsib dsic > +dsid csic csid csie > +dsif spi ufs dmic-hv > +edp sdmmc1-hv sdmmc3-hv conn > +audio-hv ao-hv > + > +All of the listed Tegra186 pins except ao-hv support the > +low-power-enable and low-power-disable properties. The power-source > +property is supported following Tegra210 pins: sdmmc2-hv, dmic-hv, > +sdmmc1-hv, sdmmc3-hv, audio-hv, ao-hv. > + > +Pad configuration state example: > + pmc: pmc@7000e400 { > + compatible = "nvidia,tegra186-pmc"; > + reg = <0 0x0c360000 0 0x10000>, > + <0 0x0c370000 0 0x10000>, > + <0 0x0c380000 0 0x10000>, > + <0 0x0c390000 0 0x10000>; > + reg-names = "pmc", "wake", "aotag", "scratch"; > + > + ... > + > + sdmmc1_3v3: sdmmc1-3v3 { > + pins = "sdmmc1-hv"; > + power-source = <TEGRA_IO_PAD_VOLTAGE_3V3>; > + }; > + > + sdmmc1_1v8: sdmmc1-1v8 { > + pins = "sdmmc1-hv"; > + power-source = <TEGRA_IO_PAD_VOLTAGE_1V8>; > + }; > + > + hdmi_off: hdmi-off { > + pins = "hdmi"; > + low-power-enable; > + } > + > + hdmi_on: hdmi-on { > + pins = "hdmi"; > + low-power-disable; > + } > + }; > + > +Pinctrl client example: > + sdmmc1: sdhci@3400000 { > + ... > + pinctrl-names = "sdmmc-3v3", "sdmmc-1v8"; > + pinctrl-0 = <&sdmmc1_3v3>; > + pinctrl-1 = <&sdmmc1_1v8>; > + }; > + > + ... > + > + sor0: sor@15540000 { > + ... > + pinctrl-0 = <&hdmi_off>; > + pinctrl-1 = <&hdmi_on>; > + pinctrl-names = "hdmi-on", "hdmi-off"; > + }; > diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt > index a74b37b..d50a505 100644 > --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt > +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt > @@ -195,3 +195,98 @@ Example: > power-domains = <&pd_audio>; > ... > }; > + > +== Pad Control Nodes == Similar comments in this file. > + > +The PMC can be used to set pad power state and voltage configuration. > +This functionality is present on SoCs from Tegra124 onwards. The pad > +configuration is done via the pinctrl framework. The driver implements > +power-source, low-power-enable, and low-power-disable pinconf pin > +configuration node properties. Each pinctrl pin corresponds to a single > +Tegra PMC pad. Thus, in the following sections of this document pin > +refers to the pinctrl frameworks notion of a Tegra PMC pad. > + > +The pad configuration state nodes are placed under the pmc node and they > +are referred to by the pinctrl client device properties. For more > +information see the examples presented later and > +Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt. > + > +The values accepted by power-source property are > +TEGRA_IO_PAD_VOLTAGE_1V8 and TEGRA_IO_PAD_VOLTAGE_3V3, which are defined > +in dt-bindings/pinctrl/pinctrl-tegra-io-pad.h. > + > +Following pinctrl pin name strings are present on Tegra124 and Tegra132: > +audio bb cam comp > +csia csb cse dsi > +dsib dsic dsid hdmi > +hsic hv lvds mipi-bias > +nand pex-bias pex-clk1 pex-clk2 > +pex-cntrl sdmmc1 sdmmc3 sdmmc4 > +sys_ddc uart usb0 usb1 > +usb2 usb_bias > + > +All of the listed Tegra124 and Tegra132 pins support the > +low-power-enable and low-power-disable properties. None of the pins > +support the power-source property. > + > +Following pinctrl pin name strings are present on Tegra210: > +audio audio-hv cam csia > +csib csic csid csie > +csif dbg debug-nonao dmic > +dp dsi dsib dsic > +dsid emmc emmc2 gpio > +hdmi hsic lvds mipi-bias > +pex-bias pex-clk1 pex-clk2 pex-cntrl > +sdmmc1 sdmmc3 spi spi-hv > +uart usb0 usb1 usb2 > +usb3 usb-bias > + > +All of the listed Tegra210 pins except pex-cntrl support the > +low-power-enable and low-power-disable properties. The power-source > +property is supported following Tegra210 pins: audio, audio-hv, cam, > +dbg, dmic, gpio, pex-cntrl, sdmmc1, sdmmc3, spi, spi-hv, and uart. > + > +Pad configuration state example: > + pmc: pmc@7000e400 { > + compatible = "nvidia,tegra210-pmc"; > + reg = <0x0 0x7000e400 0x0 0x400>; > + clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>; > + clock-names = "pclk", "clk32k_in"; > + > + ... > + > + sdmmc1_3v3: sdmmc1-3v3 { > + pins = "sdmmc1"; > + power-source = <TEGRA_IO_PAD_VOLTAGE_3V3>; > + }; > + > + sdmmc1_1v8: sdmmc1-1v8 { > + pins = "sdmmc1"; > + power-source = <TEGRA_IO_PAD_VOLTAGE_1V8>; > + }; > + > + hdmi_off: hdmi-off { > + pins = "hdmi"; > + low-power-enable; > + } > + > + hdmi_on: hdmi-on { > + pins = "hdmi"; > + low-power-disable; > + } > + }; > + > +Pinctrl client example: > + sdmmc1: sdhci@700b0000 { > + ... > + pinctrl-names = "sdmmc-3v3", "sdmmc-1v8"; > + pinctrl-0 = <&sdmmc1_3v3>; > + pinctrl-1 = <&sdmmc1_1v8>; > + }; > + ... > + sor@54540000 { > + ... > + pinctrl-0 = <&hdmi_off>; > + pinctrl-1 = <&hdmi_on>; > + pinctrl-names = "hdmi-on", "hdmi-off"; > + }; > diff --git a/include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h b/include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h > new file mode 100644 > index 0000000..20f4340 > --- /dev/null > +++ b/include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h > @@ -0,0 +1,18 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * pinctrl-tegra-io-pad.h: Tegra I/O pad source voltage configuration constants > + * pinctrl bindings. > + * > + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. > + * > + * Author: Aapo Vienamo <avienamo@nvidia.com> > + */ > + > +#ifndef _DT_BINDINGS_PINCTRL_TEGRA_IO_PAD_H > +#define _DT_BINDINGS_PINCTRL_TEGRA_IO_PAD_H > + > +/* Voltage levels of the I/O pad's source rail */ > +#define TEGRA_IO_PAD_VOLTAGE_1V8 0 > +#define TEGRA_IO_PAD_VOLTAGE_3V3 1 > + > +#endif > -- > 2.7.4 > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v3 5/7] dt-bindings: Add Tegra PMC pad configuration bindings 2018-07-16 15:43 ` Rob Herring @ 2018-07-17 12:23 ` Aapo Vienamo 2018-07-17 14:22 ` Rob Herring 0 siblings, 1 reply; 15+ messages in thread From: Aapo Vienamo @ 2018-07-17 12:23 UTC (permalink / raw) To: Rob Herring Cc: Mark Rutland, Thierry Reding, Jonathan Hunter, Mikko Perttunen, Laxman Dewangan, devicetree, linux-tegra, linux-kernel On Mon, 16 Jul 2018 09:43:09 -0600 Rob Herring <robh@kernel.org> wrote: > On Thu, Jul 12, 2018 at 03:00:11PM +0300, Aapo Vienamo wrote: > > Document the pinctrl bindings used by the PMC driver for performing pad > > configuration. Both nvidia,tegra186-pmc.txt and nvidia,tegra20-pmc.txt > > are modified as they both cover SoC generations for which these bindings > > apply. > > > > Add a header defining Tegra PMC pad voltage configurations. > > > > Signed-off-by: Aapo Vienamo <avienamo@nvidia.com> > > Acked-by: Jon Hunter <jonathanh@nvidia.com> > > --- > > .../bindings/arm/tegra/nvidia,tegra186-pmc.txt | 84 +++++++++++++++++++ > > .../bindings/arm/tegra/nvidia,tegra20-pmc.txt | 95 ++++++++++++++++++++++ > > include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h | 18 ++++ > > 3 files changed, 197 insertions(+) > > create mode 100644 include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h > > > > diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt > > index 5a3bf7c..9528f41 100644 > > --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt > > +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt > > @@ -34,3 +34,87 @@ Board DTS: > > pmc@c360000 { > > nvidia,invert-interrupt; > > }; > > + > > +== Pad Control Nodes == > > + > > +The PMC can be used to set pad power state and voltage configuration. > > +The pad configuration is done via the pinctrl framework. The driver > > +implements power-source, low-power-enable, and low-power-disable pinconf > > +pin configuration node properties. Each pinctrl pin corresponds to a > > +single Tegra PMC pad. Thus, in the following sections of this document > > +pin refers to the pinctrl frameworks notion of a Tegra PMC pad. > > "pinctrl framework" is Linux specific and doesn't belong in the binding. > Neither does what a driver supports. Describe what the h/w supports. > > > + > > +The pad configuration state nodes are placed under the pmc node and they > > +are referred to by the pinctrl client device properties. For more > > Another driver detail not relevant. > > > +information see the examples presented later and > > examples don't document bindings. The documentation should be complete > without examples. > > > +Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt. > > + > > +The values accepted by power-source property are > > +TEGRA_IO_PAD_VOLTAGE_1V8 and TEGRA_IO_PAD_VOLTAGE_3V3, which are defined > > +in dt-bindings/pinctrl/pinctrl-tegra-io-pad.h. > > You need to list out what properties the child nodes can have. > > power-source needs a vendor prefix. Isn't it a generic pinctrl property? > > + > > +Following pinctrl pin name strings are present on Tegra186: > > +csia csib dsi mipi-bias > > +pex-clk-bias pex-clk3 pex-clk2 pex-clk1 > > +usb0 usb1 usb2 usb-bias > > +uart audio hsic dbg > > +hdmi-dp0 hdmi-dp1 pex-cntrl sdmmc2-hv > > +sdmmc4 cam dsib dsic > > +dsid csic csid csie > > +dsif spi ufs dmic-hv > > +edp sdmmc1-hv sdmmc3-hv conn > > +audio-hv ao-hv > > + > > +All of the listed Tegra186 pins except ao-hv support the > > +low-power-enable and low-power-disable properties. The power-source > > +property is supported following Tegra210 pins: sdmmc2-hv, dmic-hv, > > +sdmmc1-hv, sdmmc3-hv, audio-hv, ao-hv. > > + > > +Pad configuration state example: > > + pmc: pmc@7000e400 { > > + compatible = "nvidia,tegra186-pmc"; > > + reg = <0 0x0c360000 0 0x10000>, > > + <0 0x0c370000 0 0x10000>, > > + <0 0x0c380000 0 0x10000>, > > + <0 0x0c390000 0 0x10000>; > > + reg-names = "pmc", "wake", "aotag", "scratch"; > > + > > + ... > > + > > + sdmmc1_3v3: sdmmc1-3v3 { > > + pins = "sdmmc1-hv"; > > + power-source = <TEGRA_IO_PAD_VOLTAGE_3V3>; > > + }; > > + > > + sdmmc1_1v8: sdmmc1-1v8 { > > + pins = "sdmmc1-hv"; > > + power-source = <TEGRA_IO_PAD_VOLTAGE_1V8>; > > + }; > > + > > + hdmi_off: hdmi-off { > > + pins = "hdmi"; > > + low-power-enable; > > + } > > + > > + hdmi_on: hdmi-on { > > + pins = "hdmi"; > > + low-power-disable; > > + } > > + }; > > + > > +Pinctrl client example: > > + sdmmc1: sdhci@3400000 { > > + ... > > + pinctrl-names = "sdmmc-3v3", "sdmmc-1v8"; > > + pinctrl-0 = <&sdmmc1_3v3>; > > + pinctrl-1 = <&sdmmc1_1v8>; > > + }; > > + > > + ... > > + > > + sor0: sor@15540000 { > > + ... > > + pinctrl-0 = <&hdmi_off>; > > + pinctrl-1 = <&hdmi_on>; > > + pinctrl-names = "hdmi-on", "hdmi-off"; > > + }; > > diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt > > index a74b37b..d50a505 100644 > > --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt > > +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt > > @@ -195,3 +195,98 @@ Example: > > power-domains = <&pd_audio>; > > ... > > }; > > + > > +== Pad Control Nodes == > > Similar comments in this file. > > > + > > +The PMC can be used to set pad power state and voltage configuration. > > +This functionality is present on SoCs from Tegra124 onwards. The pad > > +configuration is done via the pinctrl framework. The driver implements > > +power-source, low-power-enable, and low-power-disable pinconf pin > > +configuration node properties. Each pinctrl pin corresponds to a single > > +Tegra PMC pad. Thus, in the following sections of this document pin > > +refers to the pinctrl frameworks notion of a Tegra PMC pad. > > + > > +The pad configuration state nodes are placed under the pmc node and they > > +are referred to by the pinctrl client device properties. For more > > +information see the examples presented later and > > +Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt. > > + > > +The values accepted by power-source property are > > +TEGRA_IO_PAD_VOLTAGE_1V8 and TEGRA_IO_PAD_VOLTAGE_3V3, which are defined > > +in dt-bindings/pinctrl/pinctrl-tegra-io-pad.h. > > + > > +Following pinctrl pin name strings are present on Tegra124 and Tegra132: > > +audio bb cam comp > > +csia csb cse dsi > > +dsib dsic dsid hdmi > > +hsic hv lvds mipi-bias > > +nand pex-bias pex-clk1 pex-clk2 > > +pex-cntrl sdmmc1 sdmmc3 sdmmc4 > > +sys_ddc uart usb0 usb1 > > +usb2 usb_bias > > + > > +All of the listed Tegra124 and Tegra132 pins support the > > +low-power-enable and low-power-disable properties. None of the pins > > +support the power-source property. > > + > > +Following pinctrl pin name strings are present on Tegra210: > > +audio audio-hv cam csia > > +csib csic csid csie > > +csif dbg debug-nonao dmic > > +dp dsi dsib dsic > > +dsid emmc emmc2 gpio > > +hdmi hsic lvds mipi-bias > > +pex-bias pex-clk1 pex-clk2 pex-cntrl > > +sdmmc1 sdmmc3 spi spi-hv > > +uart usb0 usb1 usb2 > > +usb3 usb-bias > > + > > +All of the listed Tegra210 pins except pex-cntrl support the > > +low-power-enable and low-power-disable properties. The power-source > > +property is supported following Tegra210 pins: audio, audio-hv, cam, > > +dbg, dmic, gpio, pex-cntrl, sdmmc1, sdmmc3, spi, spi-hv, and uart. > > + > > +Pad configuration state example: > > + pmc: pmc@7000e400 { > > + compatible = "nvidia,tegra210-pmc"; > > + reg = <0x0 0x7000e400 0x0 0x400>; > > + clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>; > > + clock-names = "pclk", "clk32k_in"; > > + > > + ... > > + > > + sdmmc1_3v3: sdmmc1-3v3 { > > + pins = "sdmmc1"; > > + power-source = <TEGRA_IO_PAD_VOLTAGE_3V3>; > > + }; > > + > > + sdmmc1_1v8: sdmmc1-1v8 { > > + pins = "sdmmc1"; > > + power-source = <TEGRA_IO_PAD_VOLTAGE_1V8>; > > + }; > > + > > + hdmi_off: hdmi-off { > > + pins = "hdmi"; > > + low-power-enable; > > + } > > + > > + hdmi_on: hdmi-on { > > + pins = "hdmi"; > > + low-power-disable; > > + } > > + }; > > + > > +Pinctrl client example: > > + sdmmc1: sdhci@700b0000 { > > + ... > > + pinctrl-names = "sdmmc-3v3", "sdmmc-1v8"; > > + pinctrl-0 = <&sdmmc1_3v3>; > > + pinctrl-1 = <&sdmmc1_1v8>; > > + }; > > + ... > > + sor@54540000 { > > + ... > > + pinctrl-0 = <&hdmi_off>; > > + pinctrl-1 = <&hdmi_on>; > > + pinctrl-names = "hdmi-on", "hdmi-off"; > > + }; > > diff --git a/include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h b/include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h > > new file mode 100644 > > index 0000000..20f4340 > > --- /dev/null > > +++ b/include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h > > @@ -0,0 +1,18 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > +/* > > + * pinctrl-tegra-io-pad.h: Tegra I/O pad source voltage configuration constants > > + * pinctrl bindings. > > + * > > + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. > > + * > > + * Author: Aapo Vienamo <avienamo@nvidia.com> > > + */ > > + > > +#ifndef _DT_BINDINGS_PINCTRL_TEGRA_IO_PAD_H > > +#define _DT_BINDINGS_PINCTRL_TEGRA_IO_PAD_H > > + > > +/* Voltage levels of the I/O pad's source rail */ > > +#define TEGRA_IO_PAD_VOLTAGE_1V8 0 > > +#define TEGRA_IO_PAD_VOLTAGE_3V3 1 > > + > > +#endif > > -- > > 2.7.4 > > -Aapo ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v3 5/7] dt-bindings: Add Tegra PMC pad configuration bindings 2018-07-17 12:23 ` Aapo Vienamo @ 2018-07-17 14:22 ` Rob Herring 2018-07-17 15:30 ` Aapo Vienamo 0 siblings, 1 reply; 15+ messages in thread From: Rob Herring @ 2018-07-17 14:22 UTC (permalink / raw) To: Aapo Vienamo Cc: Mark Rutland, Thierry Reding, Jon Hunter, Mikko Perttunen, Laxman Dewangan, devicetree, linux-tegra, linux-kernel On Tue, Jul 17, 2018 at 6:23 AM Aapo Vienamo <avienamo@nvidia.com> wrote: > > On Mon, 16 Jul 2018 09:43:09 -0600 > Rob Herring <robh@kernel.org> wrote: > > > On Thu, Jul 12, 2018 at 03:00:11PM +0300, Aapo Vienamo wrote: > > > Document the pinctrl bindings used by the PMC driver for performing pad > > > configuration. Both nvidia,tegra186-pmc.txt and nvidia,tegra20-pmc.txt > > > are modified as they both cover SoC generations for which these bindings > > > apply. > > > > > > Add a header defining Tegra PMC pad voltage configurations. > > > > > > Signed-off-by: Aapo Vienamo <avienamo@nvidia.com> > > > Acked-by: Jon Hunter <jonathanh@nvidia.com> > > > --- > > > .../bindings/arm/tegra/nvidia,tegra186-pmc.txt | 84 +++++++++++++++++++ > > > .../bindings/arm/tegra/nvidia,tegra20-pmc.txt | 95 ++++++++++++++++++++++ > > > include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h | 18 ++++ > > > 3 files changed, 197 insertions(+) > > > create mode 100644 include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h > > > > > > diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt > > > index 5a3bf7c..9528f41 100644 > > > --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt > > > +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt > > > @@ -34,3 +34,87 @@ Board DTS: > > > pmc@c360000 { > > > nvidia,invert-interrupt; > > > }; > > > + > > > +== Pad Control Nodes == > > > + > > > +The PMC can be used to set pad power state and voltage configuration. > > > +The pad configuration is done via the pinctrl framework. The driver > > > +implements power-source, low-power-enable, and low-power-disable pinconf > > > +pin configuration node properties. Each pinctrl pin corresponds to a > > > +single Tegra PMC pad. Thus, in the following sections of this document > > > +pin refers to the pinctrl frameworks notion of a Tegra PMC pad. > > > > "pinctrl framework" is Linux specific and doesn't belong in the binding. > > Neither does what a driver supports. Describe what the h/w supports. > > > > > + > > > +The pad configuration state nodes are placed under the pmc node and they > > > +are referred to by the pinctrl client device properties. For more > > > > Another driver detail not relevant. > > > > > +information see the examples presented later and > > > > examples don't document bindings. The documentation should be complete > > without examples. > > > > > +Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt. > > > + > > > +The values accepted by power-source property are > > > +TEGRA_IO_PAD_VOLTAGE_1V8 and TEGRA_IO_PAD_VOLTAGE_3V3, which are defined > > > +in dt-bindings/pinctrl/pinctrl-tegra-io-pad.h. > > > > You need to list out what properties the child nodes can have. > > > > power-source needs a vendor prefix. > > Isn't it a generic pinctrl property? I don't know offhand. Doesn't look like it if you have custom values. Rob ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v3 5/7] dt-bindings: Add Tegra PMC pad configuration bindings 2018-07-17 14:22 ` Rob Herring @ 2018-07-17 15:30 ` Aapo Vienamo 2018-07-20 11:16 ` Jon Hunter 0 siblings, 1 reply; 15+ messages in thread From: Aapo Vienamo @ 2018-07-17 15:30 UTC (permalink / raw) To: Rob Herring Cc: Mark Rutland, Thierry Reding, Jon Hunter, Mikko Perttunen, Laxman Dewangan, devicetree, linux-tegra, linux-kernel On Tue, 17 Jul 2018 08:22:07 -0600 Rob Herring <robh@kernel.org> wrote: > On Tue, Jul 17, 2018 at 6:23 AM Aapo Vienamo <avienamo@nvidia.com> wrote: > > > > On Mon, 16 Jul 2018 09:43:09 -0600 > > Rob Herring <robh@kernel.org> wrote: > > > > > On Thu, Jul 12, 2018 at 03:00:11PM +0300, Aapo Vienamo wrote: > > > > Document the pinctrl bindings used by the PMC driver for performing pad > > > > configuration. Both nvidia,tegra186-pmc.txt and nvidia,tegra20-pmc.txt > > > > are modified as they both cover SoC generations for which these bindings > > > > apply. > > > > > > > > Add a header defining Tegra PMC pad voltage configurations. > > > > > > > > Signed-off-by: Aapo Vienamo <avienamo@nvidia.com> > > > > Acked-by: Jon Hunter <jonathanh@nvidia.com> > > > > --- > > > > .../bindings/arm/tegra/nvidia,tegra186-pmc.txt | 84 +++++++++++++++++++ > > > > .../bindings/arm/tegra/nvidia,tegra20-pmc.txt | 95 ++++++++++++++++++++++ > > > > include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h | 18 ++++ > > > > 3 files changed, 197 insertions(+) > > > > create mode 100644 include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h > > > > > > > > diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt > > > > index 5a3bf7c..9528f41 100644 > > > > --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt > > > > +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt > > > > @@ -34,3 +34,87 @@ Board DTS: > > > > pmc@c360000 { > > > > nvidia,invert-interrupt; > > > > }; > > > > + > > > > +== Pad Control Nodes == > > > > + > > > > +The PMC can be used to set pad power state and voltage configuration. > > > > +The pad configuration is done via the pinctrl framework. The driver > > > > +implements power-source, low-power-enable, and low-power-disable pinconf > > > > +pin configuration node properties. Each pinctrl pin corresponds to a > > > > +single Tegra PMC pad. Thus, in the following sections of this document > > > > +pin refers to the pinctrl frameworks notion of a Tegra PMC pad. > > > > > > "pinctrl framework" is Linux specific and doesn't belong in the binding. > > > Neither does what a driver supports. Describe what the h/w supports. > > > > > > > + > > > > +The pad configuration state nodes are placed under the pmc node and they > > > > +are referred to by the pinctrl client device properties. For more > > > > > > Another driver detail not relevant. > > > > > > > +information see the examples presented later and > > > > > > examples don't document bindings. The documentation should be complete > > > without examples. > > > > > > > +Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt. > > > > + > > > > +The values accepted by power-source property are > > > > +TEGRA_IO_PAD_VOLTAGE_1V8 and TEGRA_IO_PAD_VOLTAGE_3V3, which are defined > > > > +in dt-bindings/pinctrl/pinctrl-tegra-io-pad.h. > > > > > > You need to list out what properties the child nodes can have. > > > > > > power-source needs a vendor prefix. > > > > Isn't it a generic pinctrl property? > > I don't know offhand. Doesn't look like it if you have custom values. It's listed under "Supported generic properties" in pinctrl-bindings.txt. The convention seems to be not to add a vendor prefix even though such custom macro values are used. The property is currently used by qcom,pmic-gpio, qcom,pmic-mpp, and renesas,pfc-pinctrl. I could not find a bindings document describing it with a vendor prefix. -Aapo ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v3 5/7] dt-bindings: Add Tegra PMC pad configuration bindings 2018-07-17 15:30 ` Aapo Vienamo @ 2018-07-20 11:16 ` Jon Hunter 2018-07-29 20:54 ` Linus Walleij 0 siblings, 1 reply; 15+ messages in thread From: Jon Hunter @ 2018-07-20 11:16 UTC (permalink / raw) To: Aapo Vienamo, Rob Herring, Linus Walleij Cc: Mark Rutland, Thierry Reding, Mikko Perttunen, Laxman Dewangan, devicetree, linux-tegra, linux-kernel Adding Linus ... On 17/07/18 16:30, Aapo Vienamo wrote: ... >>>>> +Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt. >>>>> + >>>>> +The values accepted by power-source property are >>>>> +TEGRA_IO_PAD_VOLTAGE_1V8 and TEGRA_IO_PAD_VOLTAGE_3V3, which are defined >>>>> +in dt-bindings/pinctrl/pinctrl-tegra-io-pad.h. >>>> >>>> You need to list out what properties the child nodes can have. >>>> >>>> power-source needs a vendor prefix. >>> >>> Isn't it a generic pinctrl property? >> >> I don't know offhand. Doesn't look like it if you have custom values. > > It's listed under "Supported generic properties" in > pinctrl-bindings.txt. The convention seems to be not to add a vendor > prefix even though such custom macro values are used. The property is > currently used by qcom,pmic-gpio, qcom,pmic-mpp, and renesas,pfc-pinctrl. > I could not find a bindings document describing it with a vendor prefix. Looking at other users of the 'power-source' property it is not clear to me if the values should/can be vendor specific or not. I see cases where some people use definitions and others use actual voltages. Linus, any recommendations here? Cheers Jon -- nvpublic ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v3 5/7] dt-bindings: Add Tegra PMC pad configuration bindings 2018-07-20 11:16 ` Jon Hunter @ 2018-07-29 20:54 ` Linus Walleij 0 siblings, 0 replies; 15+ messages in thread From: Linus Walleij @ 2018-07-29 20:54 UTC (permalink / raw) To: Jon Hunter Cc: avienamo, Rob Herring, Mark Rutland, thierry.reding, Mikko Perttunen, Laxman Dewangan, open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, linux-tegra, linux-kernel On Fri, Jul 20, 2018 at 1:16 PM Jon Hunter <jonathanh@nvidia.com> wrote: > Adding Linus ... OMG this sounds bad. > >> I don't know offhand. Doesn't look like it if you have custom values. > > > > It's listed under "Supported generic properties" in > > pinctrl-bindings.txt. The convention seems to be not to add a vendor > > prefix even though such custom macro values are used. The property is > > currently used by qcom,pmic-gpio, qcom,pmic-mpp, and renesas,pfc-pinctrl. > > I could not find a bindings document describing it with a vendor prefix. > > Looking at other users of the 'power-source' property it is not clear to > me if the values should/can be vendor specific or not. I see cases where > some people use definitions and others use actual voltages. > > Linus, any recommendations here? It's a bit of imperfect world here. I always imagines it was some kind of enumerator like source A, B or C... so 0, 1 defined in sime include/dt-bindings/* would make most sense to me. In general, use SI-units if you can, else use something that makes sense for the people writing the device tree. These enumerators seems to make sense. If nothing makes any sense, maybe a custom property makes it make sense. Yours, Linus Walleij ^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v3 6/7] soc/tegra: pmc: Remove public pad voltage APIs 2018-07-12 12:00 [PATCH v3 0/7] Tegra PMC pinctrl pad configuration Aapo Vienamo ` (4 preceding siblings ...) 2018-07-12 12:00 ` [PATCH v3 5/7] dt-bindings: Add Tegra PMC pad configuration bindings Aapo Vienamo @ 2018-07-12 12:00 ` Aapo Vienamo 2018-07-12 12:00 ` [PATCH v3 7/7] soc/tegra: pmc: Implement pad configuration via pinctrl Aapo Vienamo 6 siblings, 0 replies; 15+ messages in thread From: Aapo Vienamo @ 2018-07-12 12:00 UTC (permalink / raw) To: Rob Herring, Mark Rutland, Thierry Reding, Jonathan Hunter, Mikko Perttunen, Laxman Dewangan Cc: Aapo Vienamo, devicetree, linux-tegra, linux-kernel Make tegra_io_pad_set_voltage() and tegra_io_pad_get_voltage() static and remove the prototypes from pmc.h. Remove enum tegra_io_pad_voltage and use the defines from <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h> instead. These functions aren't used outside of the pmc driver and new use cases should use the pinctrl interface instead. Signed-off-by: Aapo Vienamo <avienamo@nvidia.com> Acked-by: Jon Hunter <jonathanh@nvidia.com> --- drivers/soc/tegra/pmc.c | 17 ++++++++--------- include/soc/tegra/pmc.h | 19 ------------------- 2 files changed, 8 insertions(+), 28 deletions(-) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 38cb915..7d3c3de 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -45,6 +45,8 @@ #include <soc/tegra/fuse.h> #include <soc/tegra/pmc.h> +#include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h> + #define PMC_CNTRL 0x0 #define PMC_CNTRL_INTR_POLARITY BIT(17) /* inverts INTR polarity */ #define PMC_CNTRL_CPU_PWRREQ_OE BIT(16) /* CPU pwr req enable */ @@ -1092,8 +1094,7 @@ static int tegra_io_pad_is_powered(enum tegra_io_pad id) return !(value & mask); } -int tegra_io_pad_set_voltage(enum tegra_io_pad id, - enum tegra_io_pad_voltage voltage) +static int tegra_io_pad_set_voltage(enum tegra_io_pad id, int voltage) { const struct tegra_io_pad_soc *pad; u32 value; @@ -1109,7 +1110,7 @@ int tegra_io_pad_set_voltage(enum tegra_io_pad id, if (pmc->soc->has_impl_33v_pwr) { value = tegra_pmc_readl(PMC_IMPL_E_33V_PWR); - if (voltage == TEGRA_IO_PAD_1800000UV) + if (voltage == TEGRA_IO_PAD_VOLTAGE_1V8) value &= ~BIT(pad->voltage); else value |= BIT(pad->voltage); @@ -1123,7 +1124,7 @@ int tegra_io_pad_set_voltage(enum tegra_io_pad id, /* update I/O voltage */ value = tegra_pmc_readl(PMC_PWR_DET_VALUE); - if (voltage == TEGRA_IO_PAD_1800000UV) + if (voltage == TEGRA_IO_PAD_VOLTAGE_3V3) value &= ~BIT(pad->voltage); else value |= BIT(pad->voltage); @@ -1137,9 +1138,8 @@ int tegra_io_pad_set_voltage(enum tegra_io_pad id, return 0; } -EXPORT_SYMBOL(tegra_io_pad_set_voltage); -int tegra_io_pad_get_voltage(enum tegra_io_pad id) +static int tegra_io_pad_get_voltage(enum tegra_io_pad id) { const struct tegra_io_pad_soc *pad; u32 value; @@ -1157,11 +1157,10 @@ int tegra_io_pad_get_voltage(enum tegra_io_pad id) value = tegra_pmc_readl(PMC_PWR_DET_VALUE); if ((value & BIT(pad->voltage)) == 0) - return TEGRA_IO_PAD_1800000UV; + return TEGRA_IO_PAD_VOLTAGE_1V8; - return TEGRA_IO_PAD_3300000UV; + return TEGRA_IO_PAD_VOLTAGE_3V3; } -EXPORT_SYMBOL(tegra_io_pad_get_voltage); /** * tegra_io_rail_power_on() - enable power to I/O rail diff --git a/include/soc/tegra/pmc.h b/include/soc/tegra/pmc.h index 445aa66..5624268 100644 --- a/include/soc/tegra/pmc.h +++ b/include/soc/tegra/pmc.h @@ -141,16 +141,6 @@ enum tegra_io_pad { #define TEGRA_IO_RAIL_HDMI TEGRA_IO_PAD_HDMI #define TEGRA_IO_RAIL_LVDS TEGRA_IO_PAD_LVDS -/** - * enum tegra_io_pad_voltage - voltage level of the I/O pad's source rail - * @TEGRA_IO_PAD_1800000UV: 1.8 V - * @TEGRA_IO_PAD_3300000UV: 3.3 V - */ -enum tegra_io_pad_voltage { - TEGRA_IO_PAD_1800000UV, - TEGRA_IO_PAD_3300000UV, -}; - #ifdef CONFIG_SOC_TEGRA_PMC int tegra_powergate_is_powered(unsigned int id); int tegra_powergate_power_on(unsigned int id); @@ -163,9 +153,6 @@ int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk, int tegra_io_pad_power_enable(enum tegra_io_pad id); int tegra_io_pad_power_disable(enum tegra_io_pad id); -int tegra_io_pad_set_voltage(enum tegra_io_pad id, - enum tegra_io_pad_voltage voltage); -int tegra_io_pad_get_voltage(enum tegra_io_pad id); /* deprecated, use tegra_io_pad_power_{enable,disable}() instead */ int tegra_io_rail_power_on(unsigned int id); @@ -213,12 +200,6 @@ static inline int tegra_io_pad_power_disable(enum tegra_io_pad id) return -ENOSYS; } -static inline int tegra_io_pad_set_voltage(enum tegra_io_pad id, - enum tegra_io_pad_voltage voltage) -{ - return -ENOSYS; -} - static inline int tegra_io_pad_get_voltage(enum tegra_io_pad id) { return -ENOSYS; -- 2.7.4 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v3 7/7] soc/tegra: pmc: Implement pad configuration via pinctrl 2018-07-12 12:00 [PATCH v3 0/7] Tegra PMC pinctrl pad configuration Aapo Vienamo ` (5 preceding siblings ...) 2018-07-12 12:00 ` [PATCH v3 6/7] soc/tegra: pmc: Remove public pad voltage APIs Aapo Vienamo @ 2018-07-12 12:00 ` Aapo Vienamo 2018-07-12 13:01 ` Jon Hunter 6 siblings, 1 reply; 15+ messages in thread From: Aapo Vienamo @ 2018-07-12 12:00 UTC (permalink / raw) To: Rob Herring, Mark Rutland, Thierry Reding, Jonathan Hunter, Mikko Perttunen, Laxman Dewangan Cc: Aapo Vienamo, devicetree, linux-tegra, linux-kernel Register a pinctrl device and implement get and set functions for PIN_CONFIG_LOW_POWER_MODE and PIN_CONFIG_POWER_SOURCE parameters. Signed-off-by: Aapo Vienamo <avienamo@nvidia.com> --- drivers/soc/tegra/pmc.c | 187 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 185 insertions(+), 2 deletions(-) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 7d3c3de..6bfd00d 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -33,6 +33,9 @@ #include <linux/of_address.h> #include <linux/of_clk.h> #include <linux/of_platform.h> +#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/pinconf.h> +#include <linux/pinctrl/pinconf-generic.h> #include <linux/platform_device.h> #include <linux/pm_domain.h> #include <linux/reboot.h> @@ -164,6 +167,9 @@ struct tegra_pmc_soc { const struct tegra_io_pad_soc *io_pads; unsigned int num_io_pads; + const struct pinctrl_pin_desc *pin_descs; + unsigned int num_pin_descs; + const struct tegra_pmc_regs *regs; void (*init)(struct tegra_pmc *pmc); void (*setup_irq_polarity)(struct tegra_pmc *pmc, @@ -222,6 +228,8 @@ struct tegra_pmc { DECLARE_BITMAP(powergates_available, TEGRA_POWERGATE_MAX); struct mutex powergates_lock; + + struct pinctrl_dev *pctl_dev; }; static struct tegra_pmc *pmc = &(struct tegra_pmc) { @@ -1398,6 +1406,142 @@ static void tegra_pmc_init_tsense_reset(struct tegra_pmc *pmc) of_node_put(np); } +static int tegra_io_pad_pinctrl_get_groups_count(struct pinctrl_dev *pctl_dev) +{ + return pmc->soc->num_io_pads; +} + +static const char *tegra_io_pad_pinctrl_get_group_name( + struct pinctrl_dev *pctl, unsigned int group) +{ + return pmc->soc->io_pads[group].name; +} + +static int tegra_io_pad_pinctrl_get_group_pins(struct pinctrl_dev *pctl_dev, + unsigned int group, + const unsigned int **pins, + unsigned int *num_pins) +{ + *pins = &pmc->soc->io_pads[group].id; + *num_pins = 1; + return 0; +} + +static const struct pinctrl_ops tegra_io_pad_pinctrl_ops = { + .get_groups_count = tegra_io_pad_pinctrl_get_groups_count, + .get_group_name = tegra_io_pad_pinctrl_get_group_name, + .get_group_pins = tegra_io_pad_pinctrl_get_group_pins, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .dt_free_map = pinconf_generic_dt_free_map, +}; + +static int tegra_io_pad_pinconf_get(struct pinctrl_dev *pctl_dev, + unsigned int pin, unsigned long *config) +{ + const struct tegra_io_pad_soc *pad = tegra_io_pad_find(pmc, pin); + enum pin_config_param param = pinconf_to_config_param(*config); + int ret; + u32 arg; + + if (!pad) + return -EINVAL; + + switch (param) { + case PIN_CONFIG_POWER_SOURCE: + ret = tegra_io_pad_get_voltage(pad->id); + if (ret < 0) + return ret; + arg = ret; + break; + case PIN_CONFIG_LOW_POWER_MODE: + ret = tegra_io_pad_is_powered(pad->id); + if (ret < 0) + return ret; + arg = !ret; + break; + default: + return -EINVAL; + } + + *config = pinconf_to_config_packed(param, arg); + + return 0; +} + +static int tegra_io_pad_pinconf_set(struct pinctrl_dev *pctl_dev, + unsigned int pin, unsigned long *configs, + unsigned int num_configs) +{ + const struct tegra_io_pad_soc *pad = tegra_io_pad_find(pmc, pin); + enum pin_config_param param; + unsigned int i; + int err; + u32 arg; + + if (!pad) + return -EINVAL; + + for (i = 0; i < num_configs; ++i) { + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); + + switch (param) { + case PIN_CONFIG_LOW_POWER_MODE: + if (arg) + err = tegra_io_pad_power_disable(pad->id); + else + err = tegra_io_pad_power_enable(pad->id); + if (err) + return err; + break; + case PIN_CONFIG_POWER_SOURCE: + if (arg != TEGRA_IO_PAD_VOLTAGE_1V8 && + arg != TEGRA_IO_PAD_VOLTAGE_3V3) + return -EINVAL; + err = tegra_io_pad_set_voltage(pad->id, arg); + if (err) + return err; + break; + default: + return -EINVAL; + } + } + + return 0; +} + +static const struct pinconf_ops tegra_io_pad_pinconf_ops = { + .pin_config_get = tegra_io_pad_pinconf_get, + .pin_config_set = tegra_io_pad_pinconf_set, + .is_generic = true, +}; + +static struct pinctrl_desc tegra_pmc_pctl_desc = { + .pctlops = &tegra_io_pad_pinctrl_ops, + .confops = &tegra_io_pad_pinconf_ops, +}; + +static int tegra_pmc_pinctrl_init(struct tegra_pmc *pmc) +{ + int err = 0; + + if (!pmc->soc->num_pin_descs) + return 0; + + tegra_pmc_pctl_desc.name = dev_name(pmc->dev); + tegra_pmc_pctl_desc.pins = pmc->soc->pin_descs; + tegra_pmc_pctl_desc.npins = pmc->soc->num_pin_descs; + + pmc->pctl_dev = devm_pinctrl_register(pmc->dev, &tegra_pmc_pctl_desc, + pmc); + if (IS_ERR(pmc->pctl_dev)) { + err = PTR_ERR(pmc->pctl_dev); + dev_err(pmc->dev, "unable to register pinctrl, %d\n", err); + } + + return err; +} + static int tegra_pmc_probe(struct platform_device *pdev) { void __iomem *base; @@ -1475,18 +1619,27 @@ static int tegra_pmc_probe(struct platform_device *pdev) err = register_restart_handler(&tegra_pmc_restart_handler); if (err) { - debugfs_remove(pmc->debugfs); dev_err(&pdev->dev, "unable to register restart handler, %d\n", err); - return err; + goto cleanup_debugfs; } + err = tegra_pmc_pinctrl_init(pmc); + if (err) + goto cleanup_restart_handler; + mutex_lock(&pmc->powergates_lock); iounmap(pmc->base); pmc->base = base; mutex_unlock(&pmc->powergates_lock); return 0; + +cleanup_restart_handler: + unregister_restart_handler(&tegra_pmc_restart_handler); +cleanup_debugfs: + debugfs_remove(pmc->debugfs); + return err; } #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM) @@ -1576,6 +1729,8 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = { .has_gpu_clamps = false, .num_io_pads = 0, .io_pads = NULL, + .num_pin_descs = 0, + .pin_descs = NULL, .regs = &tegra20_pmc_regs, .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, @@ -1615,6 +1770,8 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = { .has_impl_33v_pwr = false, .num_io_pads = 0, .io_pads = NULL, + .num_pin_descs = 0, + .pin_descs = NULL, .regs = &tegra20_pmc_regs, .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, @@ -1658,6 +1815,8 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = { .has_impl_33v_pwr = false, .num_io_pads = 0, .io_pads = NULL, + .num_pin_descs = 0, + .pin_descs = NULL, .regs = &tegra20_pmc_regs, .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, @@ -1704,6 +1863,12 @@ static const u8 tegra124_cpu_powergates[] = { .name = (_name), \ }) +#define TEGRA_IO_PIN_DESC(_id, _dpd, _voltage, _name) \ + ((struct pinctrl_pin_desc) { \ + .number = (_id), \ + .name = (_name) \ + }) + #define TEGRA124_IO_PAD_TABLE(_pad) \ /* .id .dpd .voltage .name */ \ _pad(TEGRA_IO_PAD_AUDIO, 17, UINT_MAX, "audio"), \ @@ -1741,6 +1906,10 @@ static const struct tegra_io_pad_soc tegra124_io_pads[] = { TEGRA124_IO_PAD_TABLE(TEGRA_IO_PAD) }; +static const struct pinctrl_pin_desc tegra124_pin_descs[] = { + TEGRA124_IO_PAD_TABLE(TEGRA_IO_PIN_DESC) +}; + static const struct tegra_pmc_soc tegra124_pmc_soc = { .num_powergates = ARRAY_SIZE(tegra124_powergates), .powergates = tegra124_powergates, @@ -1751,6 +1920,8 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = { .has_impl_33v_pwr = false, .num_io_pads = ARRAY_SIZE(tegra124_io_pads), .io_pads = tegra124_io_pads, + .num_pin_descs = ARRAY_SIZE(tegra124_pin_descs), + .pin_descs = tegra124_pin_descs, .regs = &tegra20_pmc_regs, .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, @@ -1835,6 +2006,10 @@ static const struct tegra_io_pad_soc tegra210_io_pads[] = { TEGRA210_IO_PAD_TABLE(TEGRA_IO_PAD) }; +static const struct pinctrl_pin_desc tegra210_pin_descs[] = { + TEGRA210_IO_PAD_TABLE(TEGRA_IO_PIN_DESC) +}; + static const struct tegra_pmc_soc tegra210_pmc_soc = { .num_powergates = ARRAY_SIZE(tegra210_powergates), .powergates = tegra210_powergates, @@ -1846,6 +2021,8 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = { .needs_mbist_war = true, .num_io_pads = ARRAY_SIZE(tegra210_io_pads), .io_pads = tegra210_io_pads, + .num_pin_descs = ARRAY_SIZE(tegra210_pin_descs), + .pin_descs = tegra210_pin_descs, .regs = &tegra20_pmc_regs, .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, @@ -1896,6 +2073,10 @@ static const struct tegra_io_pad_soc tegra186_io_pads[] = { TEGRA186_IO_PAD_TABLE(TEGRA_IO_PAD) }; +static const struct pinctrl_pin_desc tegra186_pin_descs[] = { + TEGRA186_IO_PAD_TABLE(TEGRA_IO_PIN_DESC) +}; + static const struct tegra_pmc_regs tegra186_pmc_regs = { .scratch0 = 0x2000, .dpd_req = 0x74, @@ -1949,6 +2130,8 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = { .has_impl_33v_pwr = true, .num_io_pads = ARRAY_SIZE(tegra186_io_pads), .io_pads = tegra186_io_pads, + .num_pin_descs = ARRAY_SIZE(tegra186_pin_descs), + .pin_descs = tegra186_pin_descs, .regs = &tegra186_pmc_regs, .init = NULL, .setup_irq_polarity = tegra186_pmc_setup_irq_polarity, -- 2.7.4 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v3 7/7] soc/tegra: pmc: Implement pad configuration via pinctrl 2018-07-12 12:00 ` [PATCH v3 7/7] soc/tegra: pmc: Implement pad configuration via pinctrl Aapo Vienamo @ 2018-07-12 13:01 ` Jon Hunter 0 siblings, 0 replies; 15+ messages in thread From: Jon Hunter @ 2018-07-12 13:01 UTC (permalink / raw) To: Aapo Vienamo, Rob Herring, Mark Rutland, Thierry Reding, Mikko Perttunen, Laxman Dewangan Cc: devicetree, linux-tegra, linux-kernel On 12/07/18 13:00, Aapo Vienamo wrote: > Register a pinctrl device and implement get and set functions for > PIN_CONFIG_LOW_POWER_MODE and PIN_CONFIG_POWER_SOURCE parameters. > > Signed-off-by: Aapo Vienamo <avienamo@nvidia.com> > --- > drivers/soc/tegra/pmc.c | 187 +++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 185 insertions(+), 2 deletions(-) > > diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c > index 7d3c3de..6bfd00d 100644 > --- a/drivers/soc/tegra/pmc.c > +++ b/drivers/soc/tegra/pmc.c > @@ -33,6 +33,9 @@ > #include <linux/of_address.h> > #include <linux/of_clk.h> > #include <linux/of_platform.h> > +#include <linux/pinctrl/pinctrl.h> > +#include <linux/pinctrl/pinconf.h> > +#include <linux/pinctrl/pinconf-generic.h> > #include <linux/platform_device.h> > #include <linux/pm_domain.h> > #include <linux/reboot.h> > @@ -164,6 +167,9 @@ struct tegra_pmc_soc { > const struct tegra_io_pad_soc *io_pads; > unsigned int num_io_pads; > > + const struct pinctrl_pin_desc *pin_descs; > + unsigned int num_pin_descs; > + > const struct tegra_pmc_regs *regs; > void (*init)(struct tegra_pmc *pmc); > void (*setup_irq_polarity)(struct tegra_pmc *pmc, > @@ -222,6 +228,8 @@ struct tegra_pmc { > DECLARE_BITMAP(powergates_available, TEGRA_POWERGATE_MAX); > > struct mutex powergates_lock; > + > + struct pinctrl_dev *pctl_dev; > }; > > static struct tegra_pmc *pmc = &(struct tegra_pmc) { > @@ -1398,6 +1406,142 @@ static void tegra_pmc_init_tsense_reset(struct tegra_pmc *pmc) > of_node_put(np); > } > > +static int tegra_io_pad_pinctrl_get_groups_count(struct pinctrl_dev *pctl_dev) > +{ > + return pmc->soc->num_io_pads; > +} > + > +static const char *tegra_io_pad_pinctrl_get_group_name( > + struct pinctrl_dev *pctl, unsigned int group) > +{ > + return pmc->soc->io_pads[group].name; > +} > + > +static int tegra_io_pad_pinctrl_get_group_pins(struct pinctrl_dev *pctl_dev, > + unsigned int group, > + const unsigned int **pins, > + unsigned int *num_pins) > +{ > + *pins = &pmc->soc->io_pads[group].id; > + *num_pins = 1; > + return 0; > +} > + > +static const struct pinctrl_ops tegra_io_pad_pinctrl_ops = { > + .get_groups_count = tegra_io_pad_pinctrl_get_groups_count, > + .get_group_name = tegra_io_pad_pinctrl_get_group_name, > + .get_group_pins = tegra_io_pad_pinctrl_get_group_pins, > + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, > + .dt_free_map = pinconf_generic_dt_free_map, > +}; > + > +static int tegra_io_pad_pinconf_get(struct pinctrl_dev *pctl_dev, > + unsigned int pin, unsigned long *config) > +{ > + const struct tegra_io_pad_soc *pad = tegra_io_pad_find(pmc, pin); > + enum pin_config_param param = pinconf_to_config_param(*config); > + int ret; > + u32 arg; > + > + if (!pad) > + return -EINVAL; > + > + switch (param) { > + case PIN_CONFIG_POWER_SOURCE: > + ret = tegra_io_pad_get_voltage(pad->id); > + if (ret < 0) > + return ret; > + arg = ret; > + break; > + case PIN_CONFIG_LOW_POWER_MODE: > + ret = tegra_io_pad_is_powered(pad->id); > + if (ret < 0) > + return ret; > + arg = !ret; > + break; > + default: > + return -EINVAL; > + } > + > + *config = pinconf_to_config_packed(param, arg); > + > + return 0; > +} > + > +static int tegra_io_pad_pinconf_set(struct pinctrl_dev *pctl_dev, > + unsigned int pin, unsigned long *configs, > + unsigned int num_configs) > +{ > + const struct tegra_io_pad_soc *pad = tegra_io_pad_find(pmc, pin); > + enum pin_config_param param; > + unsigned int i; > + int err; > + u32 arg; > + > + if (!pad) > + return -EINVAL; > + > + for (i = 0; i < num_configs; ++i) { > + param = pinconf_to_config_param(configs[i]); > + arg = pinconf_to_config_argument(configs[i]); > + > + switch (param) { > + case PIN_CONFIG_LOW_POWER_MODE: > + if (arg) > + err = tegra_io_pad_power_disable(pad->id); > + else > + err = tegra_io_pad_power_enable(pad->id); > + if (err) > + return err; > + break; > + case PIN_CONFIG_POWER_SOURCE: > + if (arg != TEGRA_IO_PAD_VOLTAGE_1V8 && > + arg != TEGRA_IO_PAD_VOLTAGE_3V3) > + return -EINVAL; > + err = tegra_io_pad_set_voltage(pad->id, arg); > + if (err) > + return err; > + break; > + default: > + return -EINVAL; > + } > + } > + > + return 0; > +} > + > +static const struct pinconf_ops tegra_io_pad_pinconf_ops = { > + .pin_config_get = tegra_io_pad_pinconf_get, > + .pin_config_set = tegra_io_pad_pinconf_set, > + .is_generic = true, > +}; > + > +static struct pinctrl_desc tegra_pmc_pctl_desc = { > + .pctlops = &tegra_io_pad_pinctrl_ops, > + .confops = &tegra_io_pad_pinconf_ops, > +}; > + > +static int tegra_pmc_pinctrl_init(struct tegra_pmc *pmc) > +{ > + int err = 0; > + > + if (!pmc->soc->num_pin_descs) > + return 0; > + > + tegra_pmc_pctl_desc.name = dev_name(pmc->dev); > + tegra_pmc_pctl_desc.pins = pmc->soc->pin_descs; > + tegra_pmc_pctl_desc.npins = pmc->soc->num_pin_descs; > + > + pmc->pctl_dev = devm_pinctrl_register(pmc->dev, &tegra_pmc_pctl_desc, > + pmc); > + if (IS_ERR(pmc->pctl_dev)) { > + err = PTR_ERR(pmc->pctl_dev); > + dev_err(pmc->dev, "unable to register pinctrl, %d\n", err); > + } > + > + return err; > +} > + > static int tegra_pmc_probe(struct platform_device *pdev) > { > void __iomem *base; > @@ -1475,18 +1619,27 @@ static int tegra_pmc_probe(struct platform_device *pdev) > > err = register_restart_handler(&tegra_pmc_restart_handler); > if (err) { > - debugfs_remove(pmc->debugfs); > dev_err(&pdev->dev, "unable to register restart handler, %d\n", > err); > - return err; > + goto cleanup_debugfs; > } > > + err = tegra_pmc_pinctrl_init(pmc); > + if (err) > + goto cleanup_restart_handler; > + > mutex_lock(&pmc->powergates_lock); > iounmap(pmc->base); > pmc->base = base; > mutex_unlock(&pmc->powergates_lock); > > return 0; > + > +cleanup_restart_handler: > + unregister_restart_handler(&tegra_pmc_restart_handler); > +cleanup_debugfs: > + debugfs_remove(pmc->debugfs); > + return err; > } > > #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM) > @@ -1576,6 +1729,8 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = { > .has_gpu_clamps = false, > .num_io_pads = 0, > .io_pads = NULL, > + .num_pin_descs = 0, > + .pin_descs = NULL, > .regs = &tegra20_pmc_regs, > .init = tegra20_pmc_init, > .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, > @@ -1615,6 +1770,8 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = { > .has_impl_33v_pwr = false, > .num_io_pads = 0, > .io_pads = NULL, > + .num_pin_descs = 0, > + .pin_descs = NULL, > .regs = &tegra20_pmc_regs, > .init = tegra20_pmc_init, > .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, > @@ -1658,6 +1815,8 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = { > .has_impl_33v_pwr = false, > .num_io_pads = 0, > .io_pads = NULL, > + .num_pin_descs = 0, > + .pin_descs = NULL, > .regs = &tegra20_pmc_regs, > .init = tegra20_pmc_init, > .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, > @@ -1704,6 +1863,12 @@ static const u8 tegra124_cpu_powergates[] = { > .name = (_name), \ > }) > > +#define TEGRA_IO_PIN_DESC(_id, _dpd, _voltage, _name) \ > + ((struct pinctrl_pin_desc) { \ > + .number = (_id), \ > + .name = (_name) \ > + }) > + > #define TEGRA124_IO_PAD_TABLE(_pad) \ > /* .id .dpd .voltage .name */ \ > _pad(TEGRA_IO_PAD_AUDIO, 17, UINT_MAX, "audio"), \ > @@ -1741,6 +1906,10 @@ static const struct tegra_io_pad_soc tegra124_io_pads[] = { > TEGRA124_IO_PAD_TABLE(TEGRA_IO_PAD) > }; > > +static const struct pinctrl_pin_desc tegra124_pin_descs[] = { > + TEGRA124_IO_PAD_TABLE(TEGRA_IO_PIN_DESC) > +}; > + > static const struct tegra_pmc_soc tegra124_pmc_soc = { > .num_powergates = ARRAY_SIZE(tegra124_powergates), > .powergates = tegra124_powergates, > @@ -1751,6 +1920,8 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = { > .has_impl_33v_pwr = false, > .num_io_pads = ARRAY_SIZE(tegra124_io_pads), > .io_pads = tegra124_io_pads, > + .num_pin_descs = ARRAY_SIZE(tegra124_pin_descs), > + .pin_descs = tegra124_pin_descs, > .regs = &tegra20_pmc_regs, > .init = tegra20_pmc_init, > .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, > @@ -1835,6 +2006,10 @@ static const struct tegra_io_pad_soc tegra210_io_pads[] = { > TEGRA210_IO_PAD_TABLE(TEGRA_IO_PAD) > }; > > +static const struct pinctrl_pin_desc tegra210_pin_descs[] = { > + TEGRA210_IO_PAD_TABLE(TEGRA_IO_PIN_DESC) > +}; > + > static const struct tegra_pmc_soc tegra210_pmc_soc = { > .num_powergates = ARRAY_SIZE(tegra210_powergates), > .powergates = tegra210_powergates, > @@ -1846,6 +2021,8 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = { > .needs_mbist_war = true, > .num_io_pads = ARRAY_SIZE(tegra210_io_pads), > .io_pads = tegra210_io_pads, > + .num_pin_descs = ARRAY_SIZE(tegra210_pin_descs), > + .pin_descs = tegra210_pin_descs, > .regs = &tegra20_pmc_regs, > .init = tegra20_pmc_init, > .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, > @@ -1896,6 +2073,10 @@ static const struct tegra_io_pad_soc tegra186_io_pads[] = { > TEGRA186_IO_PAD_TABLE(TEGRA_IO_PAD) > }; > > +static const struct pinctrl_pin_desc tegra186_pin_descs[] = { > + TEGRA186_IO_PAD_TABLE(TEGRA_IO_PIN_DESC) > +}; > + > static const struct tegra_pmc_regs tegra186_pmc_regs = { > .scratch0 = 0x2000, > .dpd_req = 0x74, > @@ -1949,6 +2130,8 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = { > .has_impl_33v_pwr = true, > .num_io_pads = ARRAY_SIZE(tegra186_io_pads), > .io_pads = tegra186_io_pads, > + .num_pin_descs = ARRAY_SIZE(tegra186_pin_descs), > + .pin_descs = tegra186_pin_descs, > .regs = &tegra186_pmc_regs, > .init = NULL, > .setup_irq_polarity = tegra186_pmc_setup_irq_polarity, > Acked-by: Jon Hunter <jonathanh@nvidia.com> Cheers Jon -- nvpublic ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2018-07-29 20:54 UTC | newest] Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2018-07-12 12:00 [PATCH v3 0/7] Tegra PMC pinctrl pad configuration Aapo Vienamo 2018-07-12 12:00 ` [PATCH v3 1/7] soc/tegra: pmc: Fix pad voltage configuration for Tegra186 Aapo Vienamo 2018-07-12 12:00 ` [PATCH v3 2/7] soc/tegra: pmc: Factor out DPD register bit calculation Aapo Vienamo 2018-07-12 12:00 ` [PATCH v3 3/7] soc/tegra: pmc: Implement tegra_io_pad_is_powered() Aapo Vienamo 2018-07-12 12:00 ` [PATCH v3 4/7] soc/tegra: pmc: Use X macro to generate IO pad tables Aapo Vienamo 2018-07-12 12:00 ` [PATCH v3 5/7] dt-bindings: Add Tegra PMC pad configuration bindings Aapo Vienamo 2018-07-16 15:43 ` Rob Herring 2018-07-17 12:23 ` Aapo Vienamo 2018-07-17 14:22 ` Rob Herring 2018-07-17 15:30 ` Aapo Vienamo 2018-07-20 11:16 ` Jon Hunter 2018-07-29 20:54 ` Linus Walleij 2018-07-12 12:00 ` [PATCH v3 6/7] soc/tegra: pmc: Remove public pad voltage APIs Aapo Vienamo 2018-07-12 12:00 ` [PATCH v3 7/7] soc/tegra: pmc: Implement pad configuration via pinctrl Aapo Vienamo 2018-07-12 13:01 ` Jon Hunter
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).