Linux Tegra architecture development
 help / color / mirror / Atom feed
* Re: [PATCH] ata: ahci_tegra: remove kcalloc
From: Rosen Penev @ 2026-03-25 23:29 UTC (permalink / raw)
  To: Jon Hunter
  Cc: Niklas Cassel, linux-ide, Damien Le Moal, Thierry Reding,
	open list:TEGRA ARCHITECTURE SUPPORT, open list
In-Reply-To: <63d71f4c-97c0-4c2f-ac92-0a643fcdf75f@nvidia.com>

On Wed, Mar 25, 2026 at 3:17 AM Jon Hunter <jonathanh@nvidia.com> wrote:
>
>
> On 25/03/2026 07:30, Niklas Cassel wrote:
> > Hello Rosen,
> >
> > subject is a bit misleading:
> > "remove kcalloc"
> > you are removing devm_kcalloc(), so device managed.
> >
> >
> > On Tue, Mar 24, 2026 at 02:16:29PM -0700, Rosen Penev wrote:
> >> Combine allocations into one by using a flexible array member.
> >>
> >> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> >> ---
> >>   drivers/ata/ahci_tegra.c | 15 ++++++---------
> >>   1 file changed, 6 insertions(+), 9 deletions(-)
> >>
> >> diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c
> >> index 44584eed6374..5972fe04ff3f 100644
> >> --- a/drivers/ata/ahci_tegra.c
> >> +++ b/drivers/ata/ahci_tegra.c
> >> @@ -175,8 +175,9 @@ struct tegra_ahci_priv {
> >>      struct reset_control       *sata_cold_rst;
> >>      /* Needs special handling, cannot use ahci_platform */
> >>      struct clk                 *sata_clk;
> >> -    struct regulator_bulk_data *supplies;
> >>      const struct tegra_ahci_soc *soc;
> >> +
> >> +    struct regulator_bulk_data supplies[];
> >
> > Personally I'm not a big fan of flexible array members, as there can be
> > only one. And if you use it you want to use counted_by().
> >
> > Yes, there are two device managed allocations. But is that so bad?
> >
> > Since it is device managed, it will get freed on device removal anyway.
>
> FWIW I am not a big fan of this either. It is not an obvious bang for
> the buck for me. The one downside I see is that it does leave the door
> open for someone accidentally putting another variable after the
> flexible array member. Yes we should catch this in review, but there
> really should be at least a comment saying this must be the final member
> of the struct.
That will eventually become a compile time error. Currently there are
a bunch of those cases that need to get fixed before that happens.
Hardening people are working on it.
>
> Jon
>
> --
> nvpublic
>

^ permalink raw reply

* [PATCH 1/4] dt-bindings: tegra: Add Tegra238 clock and reset definitions
From: Chun Ng @ 2026-03-25 21:26 UTC (permalink / raw)
  To: linux-tegra
  Cc: devicetree, linux-kernel, robh, krzk+dt, conor+dt, thierry.reding,
	jonathanh, chunn, ankitag
In-Reply-To: <20260325212628.1234082-1-chunn@nvidia.com>

Add device tree binding headers for Tegra238 that define the clock and
reset resource IDs used by the BPMP firmware. The IDs are defined by
hardware and are not software enumerations; 0 is reserved, so numbering
starts at 1. The reset header documents reserved ID ranges where no
reset line is present.

Signed-off-by: Chun Ng <chunn@nvidia.com>
---
 include/dt-bindings/clock/nvidia,tegra238.h | 279 ++++++++++++++++++++
 include/dt-bindings/reset/nvidia,tegra238.h | 125 +++++++++
 2 files changed, 404 insertions(+)
 create mode 100644 include/dt-bindings/clock/nvidia,tegra238.h
 create mode 100644 include/dt-bindings/reset/nvidia,tegra238.h

diff --git a/include/dt-bindings/clock/nvidia,tegra238.h b/include/dt-bindings/clock/nvidia,tegra238.h
new file mode 100644
index 000000000000..eb1cb01ab20a
--- /dev/null
+++ b/include/dt-bindings/clock/nvidia,tegra238.h
@@ -0,0 +1,279 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/* Copyright (c) 2021-2026, NVIDIA CORPORATION. All rights reserved. */
+
+#ifndef DT_BINDINGS_CLOCK_NVIDIA_TEGRA238_H
+#define DT_BINDINGS_CLOCK_NVIDIA_TEGRA238_H
+
+#define TEGRA238_CLK_ACLK			1
+#define TEGRA238_CLK_ACTMON			2
+#define TEGRA238_CLK_ADSP			3
+#define TEGRA238_CLK_ADSPNEON			4
+#define TEGRA238_CLK_AHUB			5
+#define TEGRA238_CLK_AON_APB			6
+#define TEGRA238_CLK_AON_CPU_NIC		7
+#define TEGRA238_CLK_AON_I2C_SLOW		8
+#define TEGRA238_CLK_AON_NIC			9
+#define TEGRA238_CLK_AON_TOUCH			10
+#define TEGRA238_CLK_APB2APE			11
+#define TEGRA238_CLK_APE			12
+#define TEGRA238_CLK_AUD_MCLK			13
+#define TEGRA238_CLK_AXI_CBB			14
+#define TEGRA238_CLK_AZA_2XBIT			15
+#define TEGRA238_CLK_AZA_BIT			16
+#define TEGRA238_CLK_BPMP_CPU			17
+#define TEGRA238_CLK_BPMP_CPU_NIC		18
+#define TEGRA238_CLK_CLK_32K			19
+#define TEGRA238_CLK_CLK_M			20
+#define TEGRA238_CLK_CSITE			21
+#define TEGRA238_CLK_DBGAPB			22
+#define TEGRA238_CLK_DISP			23
+#define TEGRA238_CLK_DISPHUBPLL			24
+#define TEGRA238_CLK_DISPPLL			25
+#define TEGRA238_CLK_DISP_ROOT			26
+#define TEGRA238_CLK_DMIC1			27
+#define TEGRA238_CLK_DMIC3			28
+#define TEGRA238_CLK_DMIC4			29
+#define TEGRA238_CLK_DMIC5			30
+#define TEGRA238_CLK_DPAUX			31
+#define TEGRA238_CLK_DP_LINK_REF		32
+#define TEGRA238_CLK_DSC			33
+#define TEGRA238_CLK_DSIPLL_CLKOUTA		34
+#define TEGRA238_CLK_DSIPLL_CLKOUTPN		35
+#define TEGRA238_CLK_DSIPLL_VCO			36
+#define TEGRA238_CLK_DSI_CORE			37
+#define TEGRA238_CLK_DSI_LP			38
+#define TEGRA238_CLK_DSI_PAD_INPUT		39
+#define TEGRA238_CLK_DSI_PIXEL			40
+#define TEGRA238_CLK_DSPK1			41
+#define TEGRA238_CLK_DSPK2			42
+#define TEGRA238_CLK_EMC			43
+#define TEGRA238_CLK_EMCHUB			44
+#define TEGRA238_CLK_EMCSA_EMC			45
+#define TEGRA238_CLK_EMCSA_MC			46
+#define TEGRA238_CLK_EMCSA_MPLL			47
+#define TEGRA238_CLK_EMCSB_EMC			48
+#define TEGRA238_CLK_EMCSB_MC			49
+#define TEGRA238_CLK_EMCSB_MPLL			50
+#define TEGRA238_CLK_EXTPERIPH1			51
+#define TEGRA238_CLK_EXTPERIPH2			52
+#define TEGRA238_CLK_EXTPERIPH3			53
+#define TEGRA238_CLK_EXTPERIPH4			54
+#define TEGRA238_CLK_FDE			55
+#define TEGRA238_CLK_FR_SE			56
+#define TEGRA238_CLK_FR_SEU1			57
+#define TEGRA238_CLK_FUSE			58
+#define TEGRA238_CLK_FUSE_BURN			59
+#define TEGRA238_CLK_FUSE_SERIAL		60
+#define TEGRA238_CLK_GPC0CLK			61
+#define TEGRA238_CLK_GPU_PWR			62
+#define TEGRA238_CLK_HOST1X			63
+#define TEGRA238_CLK_HUB			64
+#define TEGRA238_CLK_HUB_ROOT			65
+#define TEGRA238_CLK_I2C1			66
+#define TEGRA238_CLK_I2C2			67
+#define TEGRA238_CLK_I2C3			68
+#define TEGRA238_CLK_I2C4			69
+#define TEGRA238_CLK_I2C5			70
+#define TEGRA238_CLK_I2C6			71
+#define TEGRA238_CLK_I2C7			72
+#define TEGRA238_CLK_I2C8			73
+#define TEGRA238_CLK_I2C9			74
+#define TEGRA238_CLK_I2C_SLOW			75
+#define TEGRA238_CLK_I2S1			76
+#define TEGRA238_CLK_I2S1_SYNC_INPUT		77
+#define TEGRA238_CLK_I2S2			78
+#define TEGRA238_CLK_I2S2_SYNC_INPUT		79
+#define TEGRA238_CLK_I2S3			80
+#define TEGRA238_CLK_I2S3_SYNC_INPUT		81
+#define TEGRA238_CLK_I2S4			82
+#define TEGRA238_CLK_I2S4_SYNC_INPUT		83
+#define TEGRA238_CLK_I2S5			84
+#define TEGRA238_CLK_I2S5_SYNC_INPUT		85
+#define TEGRA238_CLK_I2S6			86
+#define TEGRA238_CLK_I2S6_SYNC_INPUT		87
+#define TEGRA238_CLK_JTAG_INTFC_PRE_CG		88
+#define TEGRA238_CLK_LA				89
+#define TEGRA238_CLK_LINKA_SYM_CLKOUT		90
+#define TEGRA238_CLK_LINKF_SYM_CLKOUT		91
+#define TEGRA238_CLK_MAUD			92
+#define TEGRA238_CLK_MCHUB			93
+#define TEGRA238_CLK_MIPI_CAL			94
+#define TEGRA238_CLK_MPHY_CORE_PLL_FIXED	95
+#define TEGRA238_CLK_MPHY_FORCE_LS_MODE		96
+#define TEGRA238_CLK_MPHY_L0_RX_ANA		97
+#define TEGRA238_CLK_MPHY_L0_RX_HS_SYMB_DIV	98
+#define TEGRA238_CLK_MPHY_L0_RX_LS_BIT		99
+#define TEGRA238_CLK_MPHY_L0_RX_LS_BIT_DIV	100
+#define TEGRA238_CLK_MPHY_L0_RX_LS_SYMB_DIV	101
+#define TEGRA238_CLK_MPHY_L0_RX_MUX_SYMB_DIV	102
+#define TEGRA238_CLK_MPHY_L0_RX_SYMB		103
+#define TEGRA238_CLK_MPHY_L0_TX_2X_SYMB		104
+#define TEGRA238_CLK_MPHY_L0_TX_HS_SYMB_DIV	105
+#define TEGRA238_CLK_MPHY_L0_TX_LS_3XBIT	106
+#define TEGRA238_CLK_MPHY_L0_TX_LS_3XBIT_DIV	107
+#define TEGRA238_CLK_MPHY_L0_TX_LS_SYMB_DIV	108
+#define TEGRA238_CLK_MPHY_L0_TX_MUX_SYMB_DIV	109
+#define TEGRA238_CLK_MPHY_L0_TX_PRE_SYMB	110
+#define TEGRA238_CLK_MPHY_L0_TX_SYMB		111
+#define TEGRA238_CLK_MPHY_L1_RX_ANA		112
+#define TEGRA238_CLK_MPHY_TX_1MHZ_REF		113
+#define TEGRA238_CLK_MSS_ENCRYPT		114
+#define TEGRA238_CLK_NAFLL_BPMP			115
+#define TEGRA238_CLK_NAFLL_CLUSTER0_CORE	116
+#define TEGRA238_CLK_NAFLL_CLUSTER0_DSU		117
+#define TEGRA238_CLK_NAFLL_FDE			118
+#define TEGRA238_CLK_NAFLL_GPC0			119
+#define TEGRA238_CLK_NAFLL_NVDEC		120
+#define TEGRA238_CLK_NAFLL_NVENC		121
+#define TEGRA238_CLK_NAFLL_OFA			122
+#define TEGRA238_CLK_NAFLL_SE			123
+#define TEGRA238_CLK_NAFLL_SEU1			124
+#define TEGRA238_CLK_NAFLL_TSEC			125
+#define TEGRA238_CLK_NAFLL_VIC			126
+#define TEGRA238_CLK_NVDEC			127
+#define TEGRA238_CLK_NVDISPLAY_P0		128
+#define TEGRA238_CLK_NVDISPLAY_P1		129
+#define TEGRA238_CLK_NVENC			130
+#define TEGRA238_CLK_OFA			131
+#define TEGRA238_CLK_OSC			132
+#define TEGRA238_CLK_PEX0_C0_CORE		133
+#define TEGRA238_CLK_PEX0_C1_CORE		134
+#define TEGRA238_CLK_PEX0_C2_CORE		135
+#define TEGRA238_CLK_PEX0_C3_CORE		136
+#define TEGRA238_CLK_PEX_SATA_USB_RX_BYP	137
+#define TEGRA238_CLK_PEX_USB_PAD_PLL0_MGMT	138
+#define TEGRA238_CLK_PEX_USB_PAD_PLL1_MGMT	139
+#define TEGRA238_CLK_PEX_USB_PAD_PLL2_MGMT	140
+#define TEGRA238_CLK_PEX_USB_PAD_PLL3_MGMT	141
+#define TEGRA238_CLK_PLLA			142
+#define TEGRA238_CLK_PLLA1			143
+#define TEGRA238_CLK_PLLA1_OUT1			144
+#define TEGRA238_CLK_PLLAON			145
+#define TEGRA238_CLK_PLLA_DISP			146
+#define TEGRA238_CLK_PLLA_DISPHUB		147
+#define TEGRA238_CLK_PLLA_DIV2			148
+#define TEGRA238_CLK_PLLA_OUT0			149
+#define TEGRA238_CLK_PLLC			150
+#define TEGRA238_CLK_PLLC2			151
+#define TEGRA238_CLK_PLLC4			152
+#define TEGRA238_CLK_PLLC4_MUXED		153
+#define TEGRA238_CLK_PLLC4_OUT1			154
+#define TEGRA238_CLK_PLLC4_OUT2			155
+#define TEGRA238_CLK_PLLC4_VCO_DIV2		156
+#define TEGRA238_CLK_PLLE			157
+#define TEGRA238_CLK_PLLE_HPS			158
+#define TEGRA238_CLK_PLLHUB			159
+#define TEGRA238_CLK_PLLP			160
+#define TEGRA238_CLK_PLLP_AUDIO			161
+#define TEGRA238_CLK_PLLP_DIV17			162
+#define TEGRA238_CLK_PLLP_OUT0			163
+#define TEGRA238_CLK_PLLP_OUT_JTAG		164
+#define TEGRA238_CLK_PLLREFE_VCOOUT		165
+#define TEGRA238_CLK_PLLREFE_VCOOUT_GATED	166
+#define TEGRA238_CLK_PPC			167
+#define TEGRA238_CLK_PRE_SF0			168
+#define TEGRA238_CLK_PRE_SOR0			169
+#define TEGRA238_CLK_PRE_SOR0_REF		170
+#define TEGRA238_CLK_PRE_SOR1			171
+#define TEGRA238_CLK_PRE_SOR1_REF		172
+#define TEGRA238_CLK_PWM1			173
+#define TEGRA238_CLK_PWM2			174
+#define TEGRA238_CLK_PWM3			175
+#define TEGRA238_CLK_PWM4			176
+#define TEGRA238_CLK_PWM5			177
+#define TEGRA238_CLK_PWM6			178
+#define TEGRA238_CLK_PWM7			179
+#define TEGRA238_CLK_PWM8			180
+#define TEGRA238_CLK_QSPI0_2X_PM		181
+#define TEGRA238_CLK_QSPI0_PM			182
+#define TEGRA238_CLK_RG0			183
+#define TEGRA238_CLK_RG1			184
+#define TEGRA238_CLK_SDMMC1			185
+#define TEGRA238_CLK_SDMMC4			186
+#define TEGRA238_CLK_SDMMC4_AXICIF		187
+#define TEGRA238_CLK_SDMMC_LEGACY_TM		188
+#define TEGRA238_CLK_SE				189
+#define TEGRA238_CLK_SEU1			190
+#define TEGRA238_CLK_SF0			191
+#define TEGRA238_CLK_SF0_POSTMUX		192
+#define TEGRA238_CLK_SF1			193
+#define TEGRA238_CLK_SF1_POSTMUX		194
+#define TEGRA238_CLK_SOC_THERM			195
+#define TEGRA238_CLK_SOR0			196
+#define TEGRA238_CLK_SOR0_PAD_CLKOUT		197
+#define TEGRA238_CLK_SOR0_PLL_REF		198
+#define TEGRA238_CLK_SOR0_REF			199
+#define TEGRA238_CLK_SOR1			200
+#define TEGRA238_CLK_SOR1_PAD_CLKOUT		201
+#define TEGRA238_CLK_SOR1_PLL_REF		202
+#define TEGRA238_CLK_SOR1_REF			203
+#define TEGRA238_CLK_SOR_SAFE			204
+#define TEGRA238_CLK_SPI1			205
+#define TEGRA238_CLK_SPI2			206
+#define TEGRA238_CLK_SPI3			207
+#define TEGRA238_CLK_SPI4			208
+#define TEGRA238_CLK_SPI5			209
+#define TEGRA238_CLK_SPPLL0_CLKOUTA		210
+#define TEGRA238_CLK_SPPLL0_CLKOUTB		211
+#define TEGRA238_CLK_SPPLL0_CLKOUTPN		212
+#define TEGRA238_CLK_SPPLL0_DIV10		213
+#define TEGRA238_CLK_SPPLL0_DIV25		214
+#define TEGRA238_CLK_SPPLL0_DIV27PN		215
+#define TEGRA238_CLK_SPPLL0_VCO			216
+#define TEGRA238_CLK_SPPLL1_CLKOUTPN		217
+#define TEGRA238_CLK_SPPLL1_DIV27PN		218
+#define TEGRA238_CLK_SPPLL1_VCO			219
+#define TEGRA238_CLK_SYNC_DMIC1			220
+#define TEGRA238_CLK_SYNC_DMIC3			221
+#define TEGRA238_CLK_SYNC_DMIC4			222
+#define TEGRA238_CLK_SYNC_DSPK1			223
+#define TEGRA238_CLK_SYNC_DSPK2			224
+#define TEGRA238_CLK_SYNC_I2S1			225
+#define TEGRA238_CLK_SYNC_I2S2			226
+#define TEGRA238_CLK_SYNC_I2S3			227
+#define TEGRA238_CLK_SYNC_I2S4			228
+#define TEGRA238_CLK_SYNC_I2S5			229
+#define TEGRA238_CLK_SYNC_I2S6			230
+#define TEGRA238_CLK_TACH0			231
+#define TEGRA238_CLK_TACH1			232
+#define TEGRA238_CLK_TSC			233
+#define TEGRA238_CLK_TSC_REF			234
+#define TEGRA238_CLK_TSEC			235
+#define TEGRA238_CLK_TSEC_PKA			236
+#define TEGRA238_CLK_TSENSE			237
+#define TEGRA238_CLK_UARTA			238
+#define TEGRA238_CLK_UARTB			239
+#define TEGRA238_CLK_UARTC			240
+#define TEGRA238_CLK_UARTD			241
+#define TEGRA238_CLK_UARTE			242
+#define TEGRA238_CLK_UARTF			243
+#define TEGRA238_CLK_UARTG			244
+#define TEGRA238_CLK_UARTH			245
+#define TEGRA238_CLK_UART_FST_MIPI_CAL		246
+#define TEGRA238_CLK_UFSDEV_REF			247
+#define TEGRA238_CLK_UFSHC			248
+#define TEGRA238_CLK_UPHY_PLL3			249
+#define TEGRA238_CLK_USB2_TRK			250
+#define TEGRA238_CLK_UTMIPLL_CLKOUT48		251
+#define TEGRA238_CLK_UTMIPLL_CLKOUT480		252
+#define TEGRA238_CLK_UTMIP_PLL			253
+#define TEGRA238_CLK_VIC			254
+#define TEGRA238_CLK_VPLL0			255
+#define TEGRA238_CLK_VPLL0_REF			256
+#define TEGRA238_CLK_VPLL1			257
+#define TEGRA238_CLK_XUSB_CORE_DEV		258
+#define TEGRA238_CLK_XUSB_CORE_HOST		259
+#define TEGRA238_CLK_XUSB_CORE_MUX		260
+#define TEGRA238_CLK_XUSB_CORE_SS		261
+#define TEGRA238_CLK_XUSB_FALCON		262
+#define TEGRA238_CLK_XUSB_FALCON_HOST		263
+#define TEGRA238_CLK_XUSB_FALCON_SS		264
+#define TEGRA238_CLK_XUSB_FS			265
+#define TEGRA238_CLK_XUSB_FS_DEV		266
+#define TEGRA238_CLK_XUSB_FS_HOST		267
+#define TEGRA238_CLK_XUSB_HS_HSICP		268
+#define TEGRA238_CLK_XUSB_SS			269
+#define TEGRA238_CLK_XUSB_SS_DEV		270
+#define TEGRA238_CLK_XUSB_SS_SUPERSPEED		271
+
+#endif /* DT_BINDINGS_CLOCK_NVIDIA_TEGRA238_H */
diff --git a/include/dt-bindings/reset/nvidia,tegra238.h b/include/dt-bindings/reset/nvidia,tegra238.h
new file mode 100644
index 000000000000..bf1eb27f1203
--- /dev/null
+++ b/include/dt-bindings/reset/nvidia,tegra238.h
@@ -0,0 +1,125 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/* Copyright (c) 2021-2026, NVIDIA CORPORATION. All rights reserved. */
+
+#ifndef DT_BINDINGS_RESET_NVIDIA_TEGRA238_H
+#define DT_BINDINGS_RESET_NVIDIA_TEGRA238_H
+
+#define TEGRA238_RESET_ACTMON			1
+#define TEGRA238_RESET_ADSP_ALL			2
+#define TEGRA238_RESET_DSI_CORE			3
+#define TEGRA238_RESET_XUSB_DEV			4
+#define TEGRA238_RESET_XUSB_HOST		5
+#define TEGRA238_RESET_XUSB_SS			6
+/* RESERVED 7 */
+#define TEGRA238_RESET_DPAUX			8
+#define TEGRA238_RESET_OFA			9
+/* RESERVED 10:15 */
+#define TEGRA238_RESET_NVDISPLAY		16
+/* RESERVED 17 */
+#define TEGRA238_RESET_GPCDMA			18
+#define TEGRA238_RESET_GPU			19
+#define TEGRA238_RESET_HDA			20
+#define TEGRA238_RESET_HDACODEC			21
+/* RESERVED 22:23 */
+#define TEGRA238_RESET_I2C1			24
+/* RESERVED 25:28 */
+#define TEGRA238_RESET_I2C2			29
+#define TEGRA238_RESET_I2C3			30
+#define TEGRA238_RESET_I2C4			31
+#define TEGRA238_RESET_I2C6			32
+#define TEGRA238_RESET_I2C7			33
+#define TEGRA238_RESET_I2C8			34
+#define TEGRA238_RESET_I2C9			35
+#define TEGRA238_RESET_ISP			36
+#define TEGRA238_RESET_MIPI_CAL			37
+#define TEGRA238_RESET_MPHY_CLK_CTL		38
+#define TEGRA238_RESET_MPHY_L0_RX		39
+#define TEGRA238_RESET_MPHY_L0_TX		40
+#define TEGRA238_RESET_MPHY_L1_RX		41
+#define TEGRA238_RESET_MPHY_L1_TX		42
+/* RESERVED 43 */
+#define TEGRA238_RESET_NVDEC			44
+/* RESERVED 45:58 */
+#define TEGRA238_RESET_NVENC			59
+/* RESERVED 60:63 */
+#define TEGRA238_RESET_LA			64
+#define TEGRA238_RESET_HWPM			65
+/* RESERVED 66 */
+#define TEGRA238_RESET_CEC			67
+#define TEGRA238_RESET_PWM1			68
+#define TEGRA238_RESET_PWM2			69
+#define TEGRA238_RESET_PWM3			70
+#define TEGRA238_RESET_PWM4			71
+#define TEGRA238_RESET_PWM5			72
+#define TEGRA238_RESET_PWM6			73
+#define TEGRA238_RESET_PWM7			74
+#define TEGRA238_RESET_PWM8			75
+#define TEGRA238_RESET_QSPI0			76
+/* RESERVED 77:81 */
+#define TEGRA238_RESET_SDMMC1			82
+#define TEGRA238_RESET_RSVD_83			83
+#define TEGRA238_RESET_RSVD_84			84
+#define TEGRA238_RESET_SDMMC4			85
+/* RESERVED 86:90 */
+#define TEGRA238_RESET_SPI1			91
+#define TEGRA238_RESET_SPI2			92
+#define TEGRA238_RESET_SPI3			93
+#define TEGRA238_RESET_SPI4			94
+#define TEGRA238_RESET_TACH0			95
+#define TEGRA238_RESET_TACH1			96
+#define TEGRA238_RESET_SPI5			97
+#define TEGRA238_RESET_TSEC			98
+/* RESERVED 99 */
+#define TEGRA238_RESET_UARTA			100
+#define TEGRA238_RESET_UARTB			101
+#define TEGRA238_RESET_UARTC			102
+#define TEGRA238_RESET_UARTD			103
+#define TEGRA238_RESET_UARTE			104
+#define TEGRA238_RESET_UARTF			105
+/* RESERVED 106 */
+#define TEGRA238_RESET_UARTH			107
+#define TEGRA238_RESET_UFSHC			108
+#define TEGRA238_RESET_UFSHC_AXI_M		109
+#define TEGRA238_RESET_UFSHC_LP_SEQ		110
+#define TEGRA238_RESET_RSVD_111			111
+/* RESERVED 112 */
+#define TEGRA238_RESET_VIC			113
+#define TEGRA238_RESET_XUSB_PADCTL		114
+/* RESERVED 115 */
+#define TEGRA238_RESET_PEX0_CORE_0		116
+#define TEGRA238_RESET_PEX0_CORE_1		117
+#define TEGRA238_RESET_PEX0_CORE_2		118
+#define TEGRA238_RESET_PEX0_CORE_3		119
+/* RESERVED 120 */
+#define TEGRA238_RESET_PEX0_CORE_0_APB		121
+#define TEGRA238_RESET_PEX0_CORE_1_APB		122
+#define TEGRA238_RESET_PEX0_CORE_2_APB		123
+#define TEGRA238_RESET_PEX0_CORE_3_APB		124
+/* RESERVED 125 */
+#define TEGRA238_RESET_PEX0_COMMON_APB		126
+#define TEGRA238_RESET_RSVD_127			127
+/* RESERVED 128:143 */
+#define TEGRA238_RESET_DMIC5			144
+#define TEGRA238_RESET_APE			145
+#define TEGRA238_RESET_PEX_USB_UPHY		146
+#define TEGRA238_RESET_PEX_USB_UPHY_L0		147
+#define TEGRA238_RESET_PEX_USB_UPHY_L1		148
+#define TEGRA238_RESET_PEX_USB_UPHY_L2		149
+#define TEGRA238_RESET_PEX_USB_UPHY_L3		150
+#define TEGRA238_RESET_PEX_USB_UPHY_L4		151
+#define TEGRA238_RESET_PEX_USB_UPHY_L5		152
+#define TEGRA238_RESET_PEX_USB_UPHY_L6		153
+#define TEGRA238_RESET_PEX_USB_UPHY_L7		154
+#define TEGRA238_RESET_PEX_USB_UPHY_PLL0	159
+#define TEGRA238_RESET_PEX_USB_UPHY_PLL1	160
+#define TEGRA238_RESET_PEX_USB_UPHY_PLL2	161
+#define TEGRA238_RESET_PEX_USB_UPHY_PLL3	162
+/* RESERVED 163:173 */
+#define TEGRA238_RESET_FDE			174
+#define TEGRA238_RESET_ADSP_CORE0		175
+#define TEGRA238_RESET_ADSP_CORE1		176
+#define TEGRA238_RESET_ADSP_CORE2		177
+#define TEGRA238_RESET_ADSP_CORE3		178
+#define TEGRA238_RESET_APE_TKE			179
+
+#endif /* DT_BINDINGS_RESET_NVIDIA_TEGRA238_H */
-- 
2.43.0


^ permalink raw reply related

* [PATCH 4/4] arm64: tegra: add e2426-1099+e2423-1099 support
From: Chun Ng @ 2026-03-25 21:26 UTC (permalink / raw)
  To: linux-tegra
  Cc: devicetree, linux-kernel, robh, krzk+dt, conor+dt, thierry.reding,
	jonathanh, chunn, ankitag
In-Reply-To: <20260325212628.1234082-1-chunn@nvidia.com>

Add the Tegra238 SoC device tree (tegra238.dtsi) and a minimal device
tree for the Tegra238 E2426-1099+E2423-1099 engineering reference
platform. The device-tree is not yet bootable and further enablement
will be added in follow-up patches.

Signed-off-by: Chun Ng <chunn@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/Makefile           |   2 +
 .../nvidia/tegra238-e2426-1099+e2423-1099.dts |  16 ++
 arch/arm64/boot/dts/nvidia/tegra238.dtsi      | 190 ++++++++++++++++++
 3 files changed, 208 insertions(+)
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra238-e2426-1099+e2423-1099.dts
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra238.dtsi

diff --git a/arch/arm64/boot/dts/nvidia/Makefile b/arch/arm64/boot/dts/nvidia/Makefile
index b139cbd14442..a5357809e222 100644
--- a/arch/arm64/boot/dts/nvidia/Makefile
+++ b/arch/arm64/boot/dts/nvidia/Makefile
@@ -13,6 +13,7 @@ DTC_FLAGS_tegra234-p3737-0000+p3701-0000 := -@
 DTC_FLAGS_tegra234-p3740-0002+p3701-0008 := -@
 DTC_FLAGS_tegra234-p3768-0000+p3767-0000 := -@
 DTC_FLAGS_tegra234-p3768-0000+p3767-0005 := -@
+DTC_FLAGS_tegra238-e2426-1099+e2423-1099 := -@
 DTC_FLAGS_tegra264-p3971-0089+p3834-0008 := -@
 
 dtb-$(CONFIG_ARCH_TEGRA_132_SOC) += tegra132-norrin.dtb
@@ -34,4 +35,5 @@ dtb-$(CONFIG_ARCH_TEGRA_234_SOC) += tegra234-p3737-0000+p3701-0008.dtb
 dtb-$(CONFIG_ARCH_TEGRA_234_SOC) += tegra234-p3740-0002+p3701-0008.dtb
 dtb-$(CONFIG_ARCH_TEGRA_234_SOC) += tegra234-p3768-0000+p3767-0000.dtb
 dtb-$(CONFIG_ARCH_TEGRA_234_SOC) += tegra234-p3768-0000+p3767-0005.dtb
+dtb-$(CONFIG_ARCH_TEGRA_238_SOC) += tegra238-e2426-1099+e2423-1099.dtb
 dtb-$(CONFIG_ARCH_TEGRA_264_SOC) += tegra264-p3971-0089+p3834-0008.dtb
diff --git a/arch/arm64/boot/dts/nvidia/tegra238-e2426-1099+e2423-1099.dts b/arch/arm64/boot/dts/nvidia/tegra238-e2426-1099+e2423-1099.dts
new file mode 100644
index 000000000000..d69ea2114e23
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra238-e2426-1099+e2423-1099.dts
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+
+/dts-v1/;
+
+#include "tegra238.dtsi"
+
+/ {
+	model = "NVIDIA Tegra238 E2426-1099+E2423-1099";
+	compatible = "nvidia,e2426-1099+e2423-1099", "nvidia,tegra238";
+
+	bus@0 {
+		uarta: serial@3100000 {
+			status = "okay";
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra238.dtsi b/arch/arm64/boot/dts/nvidia/tegra238.dtsi
new file mode 100644
index 000000000000..0570c3b20e62
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra238.dtsi
@@ -0,0 +1,190 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+
+#include <dt-bindings/clock/nvidia,tegra238.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/mailbox/tegra186-hsp.h>
+#include <dt-bindings/reset/nvidia,tegra238.h>
+
+/ {
+	compatible = "nvidia,tegra238";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	bus@0 {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges = <0x0 0x0 0x0 0x0 0x0 0x80000000>;
+
+		uarta: serial@3100000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0x0 0x3100000 0x0 0x10000>;
+			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&bpmp TEGRA238_CLK_UARTA>,
+				 <&bpmp TEGRA238_CLK_PLLP_OUT0>;
+			clock-names = "uartclk", "apb_pclk";
+			assigned-clocks = <&bpmp TEGRA238_CLK_UARTA>;
+			assigned-clock-parents = <&bpmp TEGRA238_CLK_PLLP_OUT0>;
+			resets = <&bpmp TEGRA238_RESET_UARTA>;
+			arm,primecell-periphid = <0x00051011>;
+			status = "disabled";
+		};
+
+		fuse@3810000 {
+			compatible = "nvidia,tegra234-efuse";
+			reg = <0x0 0x03810000 0x0 0x19000>;
+			clocks = <&bpmp TEGRA238_CLK_FUSE>;
+			clock-names = "fuse";
+		};
+
+		hsp_top0: tegra-hsp@3c00000 {
+			compatible = "nvidia,tegra234-hsp", "nvidia,tegra194-hsp";
+			reg = <0x0 0x03c00000 0x0 0x000a0000>;
+			interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "doorbell", "shared0";
+			#mbox-cells = <2>;
+		};
+
+		hsp_top1: tegra-hsp@3d00000 {
+			compatible = "nvidia,tegra186-hsp";
+			reg = <0x0 0x03d00000 0x0 0x000a0000>;
+			interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "shared0";
+			#mbox-cells = <2>;
+		};
+
+		aon_hsp: tegra-hsp@c150000 {
+			compatible = "nvidia,tegra186-hsp";
+			reg = <0x0 0x0c150000 0x0 0x00090000>;
+			interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "shared1";
+		};
+
+		gic: interrupt-controller@f400000 {
+			compatible = "arm,gic-v3";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			#redistributor-regions = <1>;
+			interrupt-controller;
+			reg = <0x0 0x0f400000 0x0 0x00010000	/* GICD */
+			       0x0 0x0f440000 0x0 0x00200000>;	/* GICR CPU 0-15 */
+		};
+
+		sram@40000000 {
+			compatible = "nvidia,tegra234-sysram", "mmio-sram";
+			reg = <0x0 0x40000000 0x0 0x72000>;
+			ranges = <0x0 0x0 0x40000000 0x72000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			no-memory-wc;
+
+			cpu_bpmp_tx: sram@70000 {
+				reg = <0x70000 0x1000>;
+				label = "cpu-bpmp-tx";
+				pool;
+			};
+
+			cpu_bpmp_rx: sram@71000 {
+				reg = <0x71000 0x1000>;
+				label = "cpu-bpmp-rx";
+				pool;
+			};
+		};
+	};
+
+	bpmp: bpmp {
+		compatible = "nvidia,tegra234-bpmp", "nvidia,tegra186-bpmp";
+		mboxes = <&hsp_top0 TEGRA_HSP_MBOX_TYPE_DB TEGRA_HSP_DB_MASTER_BPMP>;
+		shmem = <&cpu_bpmp_tx &cpu_bpmp_rx>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+		#power-domain-cells = <1>;
+
+		bpmp_i2c: i2c {
+			compatible = "nvidia,tegra186-bpmp-i2c";
+			nvidia,bpmp-bus-id = <5>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0_0: cpu@0 {
+			compatible = "arm,armv8";
+			device_type = "cpu";
+			reg = <0x000>;
+
+			enable-method = "psci";
+		};
+
+		cpu0_1: cpu@1 {
+			compatible = "arm,armv8";
+			device_type = "cpu";
+			reg = <0x100>;
+
+			enable-method = "psci";
+		};
+
+		cpu0_2: cpu@2 {
+			compatible = "arm,armv8";
+			device_type = "cpu";
+			reg = <0x200>;
+
+			enable-method = "psci";
+		};
+
+		cpu0_3: cpu@3 {
+			compatible = "arm,armv8";
+			device_type = "cpu";
+			reg = <0x300>;
+
+			enable-method = "psci";
+		};
+
+		cpu0_4: cpu@4 {
+			compatible = "arm,armv8";
+			device_type = "cpu";
+			reg = <0x400>;
+
+			enable-method = "psci";
+		};
+
+		cpu0_5: cpu@5 {
+			compatible = "arm,armv8";
+			device_type = "cpu";
+			reg = <0x500>;
+
+			enable-method = "psci";
+		};
+
+		cpu0_6: cpu@6 {
+			compatible = "arm,armv8";
+			device_type = "cpu";
+			reg = <0x600>;
+
+			enable-method = "psci";
+		};
+
+		cpu0_7: cpu@7 {
+			compatible = "arm,armv8";
+			device_type = "cpu";
+			reg = <0x700>;
+
+			enable-method = "psci";
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+};
-- 
2.43.0


^ permalink raw reply related

* [PATCH 3/4] dt-bindings: mailbox: tegra186-hsp: allow doorbell+shared or shared-only
From: Chun Ng @ 2026-03-25 21:26 UTC (permalink / raw)
  To: linux-tegra
  Cc: devicetree, linux-kernel, robh, krzk+dt, conor+dt, thierry.reding,
	jonathanh, chunn, ankitag
In-Reply-To: <20260325212628.1234082-1-chunn@nvidia.com>

On Tegra238, hsp_top0 mailbox has doorbell plus shared0, while hsp_top1
and aon_hsp mailboxes expose only a single shared interrupt (shared0 and
shared1 respectively) with no doorbell.

Update the schema to support Tegra238 by adding an extra oneOf options for:
- doorbell with one shared interrupt (shared0..shared15)
- single shared interrupt only (no doorbell)

Signed-off-by: Chun Ng <chunn@nvidia.com>
---
 .../devicetree/bindings/mailbox/nvidia,tegra186-hsp.yaml   | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.yaml b/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.yaml
index f833b845de0d..274480a04c70 100644
--- a/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.yaml
+++ b/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.yaml
@@ -82,6 +82,13 @@ properties:
       - items:
           - const: doorbell
 
+      - items:
+          - const: doorbell
+          - pattern: "^shared([0-9]|1[0-5])$"
+
+      - items:
+          - pattern: "^shared([0-9]|1[0-5])$"
+
       - items:
           - const: doorbell
           - pattern: "^shared([0-9]|1[0-5])$"
-- 
2.43.0


^ permalink raw reply related

* [PATCH 2/4] dt-bindings: tegra: Document E2426-1099+E2423-1099 platform
From: Chun Ng @ 2026-03-25 21:26 UTC (permalink / raw)
  To: linux-tegra
  Cc: devicetree, linux-kernel, robh, krzk+dt, conor+dt, thierry.reding,
	jonathanh, chunn, ankitag
In-Reply-To: <20260325212628.1234082-1-chunn@nvidia.com>

Document engineering platform E2426-1099+E2423-1099 for the
Tegra238 SoC.

Signed-off-by: Chun Ng <chunn@nvidia.com>
---
 Documentation/devicetree/bindings/arm/tegra.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/tegra.yaml b/Documentation/devicetree/bindings/arm/tegra.yaml
index 50a31dba7bec..96f19c3ca4a0 100644
--- a/Documentation/devicetree/bindings/arm/tegra.yaml
+++ b/Documentation/devicetree/bindings/arm/tegra.yaml
@@ -263,6 +263,10 @@ properties:
           - const: nvidia,p3768-0000+p3767-0005
           - const: nvidia,p3767-0005
           - const: nvidia,tegra234
+      - description: NVIDIA E2426-1099+E2423-1099 Engineering Reference Platform
+        items:
+          - const: nvidia,e2426-1099+e2423-1099
+          - const: nvidia,tegra238
       - description: NVIDIA P3971-0089+P3834-0008 Engineering Reference Platform
         items:
           - const: nvidia,p3971-0089+p3834-0008
-- 
2.43.0


^ permalink raw reply related

* [PATCH 0/4] arm64: tegra: add initial Tegra238 and E2426-1099+E2423-1099 support
From: Chun Ng @ 2026-03-25 21:26 UTC (permalink / raw)
  To: linux-tegra
  Cc: devicetree, linux-kernel, robh, krzk+dt, conor+dt, thierry.reding,
	jonathanh, chunn, ankitag

Hi all,

This series adds initial support for the NVIDIA Tegra238 SoC and the
E2426-1099+E2423-1099 engineering reference platform. The series follows
the pattern used for Tegra234 and other recent Tegra SoCs.

It introduces Tegra238 clock and reset binding headers, documents the
E2426-1099+E2423-1099 platform compatibles, relaxes the tegra186-hsp
binding schema for HSP configurations used on Tegra238, and adds the
initial Tegra238 SoC device tree plus board DTS.

The device tree added here is minimal scaffolding only. It is not yet
bootable, and further enablement will follow in later series.

The patch order puts bindings before implementation: clock/reset IDs
first, then platform documentation, then the HSP schema update required
by tegra238.dtsi, and finally the SoC and board device trees.

This series is based on linux-next commit 785f0eb2f85d
("Add linux-next specific files for 20260320").

Tested with:
- make ARCH=arm64 CHECK_DTBS=yes nvidia/tegra238-e2426-1099+e2423-1099.dtb
- make ARCH=arm64 dt_binding_check

Chun Ng (4):
  dt-bindings: tegra: Add Tegra238 clock and reset definitions
  dt-bindings: tegra: Document E2426-1099+E2423-1099 platform
  dt-bindings: mailbox: tegra186-hsp: allow doorbell+shared or
    shared-only
  arm64: tegra: add e2426-1099+e2423-1099 support

 .../devicetree/bindings/arm/tegra.yaml        |   4 +
 .../bindings/mailbox/nvidia,tegra186-hsp.yaml |   7 +
 arch/arm64/boot/dts/nvidia/Makefile           |   2 +
 .../nvidia/tegra238-e2426-1099+e2423-1099.dts |  16 +
 arch/arm64/boot/dts/nvidia/tegra238.dtsi      | 190 ++++++++++++
 include/dt-bindings/clock/nvidia,tegra238.h   | 279 ++++++++++++++++++
 include/dt-bindings/reset/nvidia,tegra238.h   | 125 ++++++++
 7 files changed, 623 insertions(+)
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra238-e2426-1099+e2423-1099.dts
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra238.dtsi
 create mode 100644 include/dt-bindings/clock/nvidia,tegra238.h
 create mode 100644 include/dt-bindings/reset/nvidia,tegra238.h


base-commit: 785f0eb2f85decbe7c1ef9ae922931f0194ffc2e
-- 
2.43.0


^ permalink raw reply

* Re: [PATCH 05/10] soc/tegra: pmc: Add support for SoC specific AOWAKE offsets
From: Jon Hunter @ 2026-03-25 19:33 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-tegra
In-Reply-To: <20260325192601.239554-6-jonathanh@nvidia.com>



On 25/03/2026 19:25, Jon Hunter wrote:
> For Tegra264, some of the AOWAKE registers have different register
> offsets. Prepare for adding the Tegra264 AOWAKE register by moving the
> offsets for the AOWAKE registers that are different for Tegra264 into
> the 'tegra_pmc_regs' structure and populate these offsets for the SoCs
> that support these registers.

I should have mentioned here that ...

"Finally, update the applicable AOWAKE macros to use the 
'tegra_pmc_regs' structure where necessary."


> 
> Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
> ---
>   drivers/soc/tegra/pmc.c | 86 +++++++++++++++++++++++++++++------------
>   1 file changed, 61 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
> index 55c1117b1741..42176abb96ea 100644
> --- a/drivers/soc/tegra/pmc.c
> +++ b/drivers/soc/tegra/pmc.c
> @@ -180,16 +180,18 @@
>   #define WAKE_AOWAKE_CNTRL(x) (0x000 + ((x) << 2))
>   #define WAKE_AOWAKE_CNTRL_LEVEL (1 << 3)
>   #define WAKE_AOWAKE_CNTRL_SR_CAPTURE_EN (1 << 1)
> -#define WAKE_AOWAKE_MASK_W(x) (0x180 + ((x) << 2))
> -#define WAKE_AOWAKE_STATUS_W(x) (0x30c + ((x) << 2))
> -#define WAKE_AOWAKE_STATUS_R(x) (0x48c + ((x) << 2))
> -#define WAKE_AOWAKE_TIER2_ROUTING(x) (0x4cc + ((x) << 2))
> -#define WAKE_AOWAKE_SW_STATUS_W_0	0x49c
> -#define WAKE_AOWAKE_SW_STATUS(x)	(0x4a0 + ((x) << 2))
> -#define WAKE_LATCH_SW			0x498
> -
> -#define WAKE_AOWAKE_CTRL 0x4f4
> -#define  WAKE_AOWAKE_CTRL_INTR_POLARITY BIT(0)
> +#define WAKE_AOWAKE_MASK_W(_pmc, x) \
> +	((_pmc)->soc->regs->aowake_mask_w + ((x) << 2))
> +#define WAKE_AOWAKE_STATUS_W(_pmc, x) \
> +	((_pmc)->soc->regs->aowake_status_w + ((x) << 2))
> +#define WAKE_AOWAKE_STATUS_R(_pmc, x) \
> +	((_pmc)->soc->regs->aowake_status_r + ((x) << 2))
> +#define WAKE_AOWAKE_TIER2_ROUTING(_pmc, x) \
> +	((_pmc)->soc->regs->aowake_tier2_routing + ((x) << 2))
> +#define WAKE_AOWAKE_SW_STATUS(_pmc, x) \
> +	((_pmc)->soc->regs->aowake_sw_status + ((x) << 2))
> +
> +#define WAKE_AOWAKE_CTRL_INTR_POLARITY BIT(0)
>   
>   #define SW_WAKE_ID		83 /* wake83 */
>   
> @@ -302,6 +304,14 @@ struct tegra_pmc_regs {
>   	unsigned int rst_source_mask;
>   	unsigned int rst_level_shift;
>   	unsigned int rst_level_mask;
> +	unsigned int aowake_mask_w;
> +	unsigned int aowake_status_w;
> +	unsigned int aowake_status_r;
> +	unsigned int aowake_tier2_routing;
> +	unsigned int aowake_sw_status_w;
> +	unsigned int aowake_sw_status;
> +	unsigned int aowake_latch_sw;
> +	unsigned int aowake_ctrl;
>   };
>   
>   struct tegra_wake_event {
> @@ -2629,20 +2639,20 @@ static int tegra186_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
>   	bit = data->hwirq % 32;
>   
>   	/* clear wake status */
> -	writel(0x1, pmc->wake + WAKE_AOWAKE_STATUS_W(data->hwirq));
> +	writel(0x1, pmc->wake + WAKE_AOWAKE_STATUS_W(pmc, data->hwirq));
>   
>   	/* route wake to tier 2 */
> -	value = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(offset));
> +	value = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(pmc, offset));
>   
>   	if (!on)
>   		value &= ~(1 << bit);
>   	else
>   		value |= 1 << bit;
>   
> -	writel(value, pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(offset));
> +	writel(value, pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(pmc, offset));
>   
>   	/* enable wakeup event */
> -	writel(!!on, pmc->wake + WAKE_AOWAKE_MASK_W(data->hwirq));
> +	writel(!!on, pmc->wake + WAKE_AOWAKE_MASK_W(pmc, data->hwirq));
>   
>   	return 0;
>   }
> @@ -3309,7 +3319,7 @@ static void wke_write_wake_levels(struct tegra_pmc *pmc)
>   
>   static void wke_clear_sw_wake_status(struct tegra_pmc *pmc)
>   {
> -	wke_32kwritel(pmc, 1, WAKE_AOWAKE_SW_STATUS_W_0);
> +	wke_32kwritel(pmc, 1, pmc->soc->regs->aowake_sw_status_w);
>   }
>   
>   static void wke_read_sw_wake_status(struct tegra_pmc *pmc)
> @@ -3322,7 +3332,7 @@ static void wke_read_sw_wake_status(struct tegra_pmc *pmc)
>   
>   	wke_clear_sw_wake_status(pmc);
>   
> -	wke_32kwritel(pmc, 1, WAKE_LATCH_SW);
> +	wke_32kwritel(pmc, 1, pmc->soc->regs->aowake_latch_sw);
>   
>   	/*
>   	 * WAKE_AOWAKE_SW_STATUS is edge triggered, so in order to
> @@ -3340,12 +3350,12 @@ static void wke_read_sw_wake_status(struct tegra_pmc *pmc)
>   	 */
>   	udelay(300);
>   
> -	wke_32kwritel(pmc, 0, WAKE_LATCH_SW);
> +	wke_32kwritel(pmc, 0, pmc->soc->regs->aowake_latch_sw);
>   
>   	bitmap_zero(pmc->wake_sw_status_map, pmc->soc->max_wake_events);
>   
>   	for (i = 0; i < pmc->soc->max_wake_vectors; i++) {
> -		status = readl(pmc->wake + WAKE_AOWAKE_SW_STATUS(i));
> +		status = readl(pmc->wake + WAKE_AOWAKE_SW_STATUS(pmc, i));
>   
>   		for_each_set_bit(wake, &status, 32)
>   			set_bit(wake + (i * 32), pmc->wake_sw_status_map);
> @@ -3359,11 +3369,12 @@ static void wke_clear_wake_status(struct tegra_pmc *pmc)
>   	u32 mask;
>   
>   	for (i = 0; i < pmc->soc->max_wake_vectors; i++) {
> -		mask = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(i));
> -		status = readl(pmc->wake + WAKE_AOWAKE_STATUS_R(i)) & mask;
> +		mask = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(pmc, i));
> +		status = readl(pmc->wake + WAKE_AOWAKE_STATUS_R(pmc, i)) & mask;
>   
>   		for_each_set_bit(wake, &status, 32)
> -			wke_32kwritel(pmc, 0x1, WAKE_AOWAKE_STATUS_W((i * 32) + wake));
> +			wke_32kwritel(pmc, 0x1, WAKE_AOWAKE_STATUS_W(pmc,
> +							(i * 32) + wake));
>   	}
>   }
>   
> @@ -3374,8 +3385,9 @@ static void tegra186_pmc_wake_syscore_resume(void *data)
>   	u32 mask;
>   
>   	for (i = 0; i < pmc->soc->max_wake_vectors; i++) {
> -		mask = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(i));
> -		pmc->wake_status[i] = readl(pmc->wake + WAKE_AOWAKE_STATUS_R(i)) & mask;
> +		mask = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(pmc, i));
> +		pmc->wake_status[i] = readl(pmc->wake +
> +					    WAKE_AOWAKE_STATUS_R(pmc, i)) & mask;
>   	}
>   
>   	/* Schedule IRQ work to process wake IRQs (if any) */
> @@ -4062,6 +4074,14 @@ static const struct tegra_pmc_regs tegra186_pmc_regs = {
>   	.rst_source_mask = 0x3c,
>   	.rst_level_shift = 0x0,
>   	.rst_level_mask = 0x3,
> +	.aowake_mask_w = 0x180,
> +	.aowake_status_w = 0x30c,
> +	.aowake_status_r = 0x48c,
> +	.aowake_tier2_routing = 0x4cc,
> +	.aowake_sw_status_w = 0x49c,
> +	.aowake_sw_status = 0x4a0,
> +	.aowake_latch_sw = 0x498,
> +	.aowake_ctrl = 0x4f4,
>   };
>   
>   static void tegra186_pmc_init(struct tegra_pmc *pmc)
> @@ -4094,14 +4114,14 @@ static void tegra186_pmc_setup_irq_polarity(struct tegra_pmc *pmc,
>   		return;
>   	}
>   
> -	value = readl(wake + WAKE_AOWAKE_CTRL);
> +	value = readl(wake + pmc->soc->regs->aowake_ctrl);
>   
>   	if (invert)
>   		value |= WAKE_AOWAKE_CTRL_INTR_POLARITY;
>   	else
>   		value &= ~WAKE_AOWAKE_CTRL_INTR_POLARITY;
>   
> -	writel(value, wake + WAKE_AOWAKE_CTRL);
> +	writel(value, wake + pmc->soc->regs->aowake_ctrl);
>   
>   	iounmap(wake);
>   }
> @@ -4281,6 +4301,14 @@ static const struct tegra_pmc_regs tegra194_pmc_regs = {
>   	.rst_source_mask = 0x7c,
>   	.rst_level_shift = 0x0,
>   	.rst_level_mask = 0x3,
> +	.aowake_mask_w = 0x180,
> +	.aowake_status_w = 0x30c,
> +	.aowake_status_r = 0x48c,
> +	.aowake_tier2_routing = 0x4cc,
> +	.aowake_sw_status_w = 0x49c,
> +	.aowake_sw_status = 0x4a0,
> +	.aowake_latch_sw = 0x498,
> +	.aowake_ctrl = 0x4f4,
>   };
>   
>   static const char * const tegra194_reset_sources[] = {
> @@ -4400,6 +4428,14 @@ static const struct tegra_pmc_regs tegra234_pmc_regs = {
>   	.rst_source_mask = 0xfc,
>   	.rst_level_shift = 0x0,
>   	.rst_level_mask = 0x3,
> +	.aowake_mask_w = 0x180,
> +	.aowake_status_w = 0x30c,
> +	.aowake_status_r = 0x48c,
> +	.aowake_tier2_routing = 0x4cc,
> +	.aowake_sw_status_w = 0x49c,
> +	.aowake_sw_status = 0x4a0,
> +	.aowake_latch_sw = 0x498,
> +	.aowake_ctrl = 0x4f4,
>   };
>   
>   static const char * const tegra234_reset_sources[] = {

-- 
nvpublic


^ permalink raw reply

* [PATCH 08/10] soc/tegra: pmc: Refactor IO pad voltage control
From: Jon Hunter @ 2026-03-25 19:25 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-tegra, Jon Hunter
In-Reply-To: <20260325192601.239554-1-jonathanh@nvidia.com>

For Tegra devices, only a subset of IO pads can be configured for 1.8V
or 3.3V. Therefore, in the 'tegra_io_pad_soc' structure for Tegra SoCs
either all or most of the 'voltage' entries are set to UINT_MAX to
indicate the IO pad voltage cannot be configured. So for the majority of
IO pads this configuration is not applicable. However, refactoring the
IO pad data to move this parameter into a separate structure does not
make sense because the benefits are marginal.

Support for the Tegra264 IO pads is currently missing and the control
for configuring the voltage for the IO pads for Tegra264 has changed.
Instead of having a single register that is used for setting the IO pad
voltage for all IO pads, there is now a register associated with the
specific IO pad. For Tegra264, there is now only one IO pad that can be
configured for 1.8V or 3.3V which is the sdmmc1-hv. While we could make
this work with by adding a new SoC flag, the implementation will be a
bit cumbersome. Therefore, it now seems reasonable to refactor the IO
pad code. Hence, introduce a new 'tegra_io_pad_vctrl' structure that
contains the register offset and bit for enabling/disabling 3.3V mode
and move the existing voltage control data for supported SoCs to this
structure. This has an added benefit of simplifying the code in the
functions tegra_io_pad_get_voltage and tegra_io_pad_set_voltage.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 drivers/soc/tegra/pmc.c | 467 ++++++++++++++++++++++------------------
 1 file changed, 259 insertions(+), 208 deletions(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 3899d8c76569..3dcc679baffa 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -294,10 +294,15 @@ struct tegra_io_pad_soc {
 	unsigned int dpd;
 	unsigned int request;
 	unsigned int status;
-	unsigned int voltage;
 	const char *name;
 };
 
+struct tegra_io_pad_vctrl {
+	enum tegra_io_pad id;
+	unsigned int offset;
+	unsigned int ena_3v3;
+};
+
 struct tegra_pmc_regs {
 	unsigned int scratch0;
 	unsigned int rst_status;
@@ -372,6 +377,8 @@ struct tegra_pmc_soc {
 
 	const struct tegra_io_pad_soc *io_pads;
 	unsigned int num_io_pads;
+	const struct tegra_io_pad_vctrl *io_pad_vctrls;
+	unsigned int num_io_pad_vctrls;
 
 	const struct pinctrl_pin_desc *pin_descs;
 	unsigned int num_pin_descs;
@@ -1699,6 +1706,18 @@ tegra_io_pad_find(struct tegra_pmc *pmc, enum tegra_io_pad id)
 	return NULL;
 }
 
+static const struct tegra_io_pad_vctrl *
+tegra_io_pad_vctrl_find(struct tegra_pmc *pmc, enum tegra_io_pad id)
+{
+	unsigned int i;
+
+	for (i = 0; i < pmc->soc->num_io_pad_vctrls; i++)
+		if (pmc->soc->io_pad_vctrls[i].id == id)
+			return &pmc->soc->io_pad_vctrls[i];
+
+	return NULL;
+}
+
 static int tegra_io_pad_prepare(struct tegra_pmc *pmc,
 				const struct tegra_io_pad_soc *pad,
 				unsigned long *request,
@@ -1894,43 +1913,30 @@ static int tegra_io_pad_is_powered(struct tegra_pmc *pmc, enum tegra_io_pad id)
 static int tegra_io_pad_set_voltage(struct tegra_pmc *pmc, enum tegra_io_pad id,
 				    int voltage)
 {
-	const struct tegra_io_pad_soc *pad;
+	const struct tegra_io_pad_vctrl *pad;
 	u32 value;
 
-	pad = tegra_io_pad_find(pmc, id);
+	pad = tegra_io_pad_vctrl_find(pmc, id);
 	if (!pad)
 		return -ENOENT;
 
-	if (pad->voltage == UINT_MAX)
-		return -ENOTSUPP;
-
 	mutex_lock(&pmc->powergates_lock);
 
-	if (pmc->soc->has_impl_33v_pwr) {
-		value = tegra_pmc_readl(pmc, PMC_IMPL_E_33V_PWR);
-
-		if (voltage == TEGRA_IO_PAD_VOLTAGE_1V8)
-			value &= ~BIT(pad->voltage);
-		else
-			value |= BIT(pad->voltage);
-
-		tegra_pmc_writel(pmc, value, PMC_IMPL_E_33V_PWR);
-	} else {
-		/* write-enable PMC_PWR_DET_VALUE[pad->voltage] */
+	if (!pmc->soc->has_impl_33v_pwr) {
+		/* write-enable PMC_PWR_DET_VALUE[pad->ena_3v3] */
 		value = tegra_pmc_readl(pmc, PMC_PWR_DET);
-		value |= BIT(pad->voltage);
+		value |= BIT(pad->ena_3v3);
 		tegra_pmc_writel(pmc, value, PMC_PWR_DET);
+	}
 
-		/* update I/O voltage */
-		value = tegra_pmc_readl(pmc, PMC_PWR_DET_VALUE);
+	value = tegra_pmc_readl(pmc, pad->offset);
 
-		if (voltage == TEGRA_IO_PAD_VOLTAGE_1V8)
-			value &= ~BIT(pad->voltage);
-		else
-			value |= BIT(pad->voltage);
+	if (voltage == TEGRA_IO_PAD_VOLTAGE_1V8)
+		value &= ~BIT(pad->ena_3v3);
+	else
+		value |= BIT(pad->ena_3v3);
 
-		tegra_pmc_writel(pmc, value, PMC_PWR_DET_VALUE);
-	}
+	tegra_pmc_writel(pmc, value, pad->offset);
 
 	mutex_unlock(&pmc->powergates_lock);
 
@@ -1941,22 +1947,16 @@ static int tegra_io_pad_set_voltage(struct tegra_pmc *pmc, enum tegra_io_pad id,
 
 static int tegra_io_pad_get_voltage(struct tegra_pmc *pmc, enum tegra_io_pad id)
 {
-	const struct tegra_io_pad_soc *pad;
+	const struct tegra_io_pad_vctrl *pad;
 	u32 value;
 
-	pad = tegra_io_pad_find(pmc, id);
+	pad = tegra_io_pad_vctrl_find(pmc, id);
 	if (!pad)
 		return -ENOENT;
 
-	if (pad->voltage == UINT_MAX)
-		return -ENOTSUPP;
+	value = tegra_pmc_readl(pmc, pad->offset);
 
-	if (pmc->soc->has_impl_33v_pwr)
-		value = tegra_pmc_readl(pmc, PMC_IMPL_E_33V_PWR);
-	else
-		value = tegra_pmc_readl(pmc, PMC_PWR_DET_VALUE);
-
-	if ((value & BIT(pad->voltage)) == 0)
+	if ((value & BIT(pad->ena_3v3)) == 0)
 		return TEGRA_IO_PAD_VOLTAGE_1V8;
 
 	return TEGRA_IO_PAD_VOLTAGE_3V3;
@@ -3710,16 +3710,22 @@ static const u8 tegra124_cpu_powergates[] = {
 	TEGRA_POWERGATE_CPU3,
 };
 
-#define TEGRA_IO_PAD(_id, _dpd, _request, _status, _voltage, _name)	\
+#define TEGRA_IO_PAD(_id, _dpd, _request, _status, _name)	\
 	((struct tegra_io_pad_soc) {					\
 		.id		= (_id),				\
 		.dpd		= (_dpd),				\
 		.request	= (_request),				\
 		.status		= (_status),				\
-		.voltage	= (_voltage),				\
 		.name		= (_name),				\
 	})
 
+#define TEGRA_IO_PAD_VCTRL(_id, _offset, _ena_3v3)			\
+	((struct tegra_io_pad_vctrl) {					\
+		.id		= (_id),				\
+		.offset		= (_offset),				\
+		.ena_3v3	= (_ena_3v3),				\
+	})
+
 #define TEGRA_IO_PIN_DESC(_id, _name)	\
 	((struct pinctrl_pin_desc) {	\
 		.number	= (_id),	\
@@ -3727,36 +3733,36 @@ static const u8 tegra124_cpu_powergates[] = {
 	})
 
 static const struct tegra_io_pad_soc tegra124_io_pads[] = {
-	TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO, 17, 0x1b8, 0x1bc, UINT_MAX, "audio"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_BB, 15, 0x1b8, 0x1bc, UINT_MAX, "bb"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CAM, 4, 0x1c0, 0x1c4, UINT_MAX, "cam"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_COMP, 22, 0x1b8, 0x1bc, UINT_MAX, "comp"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x1b8, 0x1bc, UINT_MAX, "csia"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x1b8, 0x1bc, UINT_MAX, "csib"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 12, 0x1c0, 0x1c4, UINT_MAX, "csie"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DSI, 2, 0x1b8, 0x1bc, UINT_MAX, "dsi"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DSIB, 7, 0x1c0, 0x1c4, UINT_MAX, "dsib"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DSIC, 8, 0x1c0, 0x1c4, UINT_MAX, "dsic"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DSID, 9, 0x1c0, 0x1c4, UINT_MAX, "dsid"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI, 28, 0x1b8, 0x1bc, UINT_MAX, "hdmi"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_HSIC, 19, 0x1b8, 0x1bc, UINT_MAX, "hsic"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_HV, 6, 0x1c0, 0x1c4, UINT_MAX, "hv"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_LVDS, 25, 0x1c0, 0x1c4, UINT_MAX, "lvds"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_MIPI_BIAS, 3, 0x1b8, 0x1bc, UINT_MAX, "mipi-bias"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_NAND, 13, 0x1b8, 0x1bc, UINT_MAX, "nand"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_BIAS, 4, 0x1b8, 0x1bc, UINT_MAX, "pex-bias"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK1, 5, 0x1b8, 0x1bc, UINT_MAX, "pex-clk1"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK2, 6, 0x1b8, 0x1bc, UINT_MAX, "pex-clk2"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CNTRL, 0, 0x1c0, 0x1c4, UINT_MAX, "pex-cntrl"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1, 1, 0x1c0, 0x1c4, UINT_MAX, "sdmmc1"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3, 2, 0x1c0, 0x1c4, UINT_MAX, "sdmmc3"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC4, 3, 0x1c0, 0x1c4, UINT_MAX, "sdmmc4"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SYS_DDC, 26, 0x1c0, 0x1c4, UINT_MAX, "sys_ddc"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_UART, 14, 0x1b8, 0x1bc, UINT_MAX, "uart"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_USB0, 9, 0x1b8, 0x1bc, UINT_MAX, "usb0"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_USB1, 10, 0x1b8, 0x1bc, UINT_MAX, "usb1"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_USB2, 11, 0x1b8, 0x1bc, UINT_MAX, "usb2"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_USB_BIAS, 12, 0x1b8, 0x1bc, UINT_MAX, "usb_bias"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO, 17, 0x1b8, 0x1bc, "audio"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_BB, 15, 0x1b8, 0x1bc, "bb"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CAM, 4, 0x1c0, 0x1c4, "cam"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_COMP, 22, 0x1b8, 0x1bc, "comp"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x1b8, 0x1bc, "csia"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x1b8, 0x1bc, "csib"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 12, 0x1c0, 0x1c4, "csie"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DSI, 2, 0x1b8, 0x1bc, "dsi"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DSIB, 7, 0x1c0, 0x1c4, "dsib"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DSIC, 8, 0x1c0, 0x1c4, "dsic"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DSID, 9, 0x1c0, 0x1c4, "dsid"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI, 28, 0x1b8, 0x1bc, "hdmi"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_HSIC, 19, 0x1b8, 0x1bc, "hsic"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_HV, 6, 0x1c0, 0x1c4, "hv"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_LVDS, 25, 0x1c0, 0x1c4, "lvds"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_MIPI_BIAS, 3, 0x1b8, 0x1bc, "mipi-bias"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_NAND, 13, 0x1b8, 0x1bc, "nand"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_BIAS, 4, 0x1b8, 0x1bc, "pex-bias"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK1, 5, 0x1b8, 0x1bc, "pex-clk1"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK2, 6, 0x1b8, 0x1bc, "pex-clk2"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CNTRL, 0, 0x1c0, 0x1c4, "pex-cntrl"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1, 1, 0x1c0, 0x1c4, "sdmmc1"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3, 2, 0x1c0, 0x1c4, "sdmmc3"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC4, 3, 0x1c0, 0x1c4, "sdmmc4"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SYS_DDC, 26, 0x1c0, 0x1c4, "sys_ddc"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_UART, 14, 0x1b8, 0x1bc, "uart"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_USB0, 9, 0x1b8, 0x1bc, "usb0"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_USB1, 10, 0x1b8, 0x1bc, "usb1"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_USB2, 11, 0x1b8, 0x1bc, "usb2"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_USB_BIAS, 12, 0x1b8, 0x1bc, "usb_bias"),
 };
 
 static const struct pinctrl_pin_desc tegra124_pin_descs[] = {
@@ -3857,46 +3863,60 @@ static const u8 tegra210_cpu_powergates[] = {
 };
 
 static const struct tegra_io_pad_soc tegra210_io_pads[] = {
-	TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO, 17, 0x1b8, 0x1bc, 5, "audio"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO_HV, 29, 0x1c0, 0x1c4, 18, "audio-hv"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CAM, 4, 0x1c0, 0x1c4, 10, "cam"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x1b8, 0x1bc, UINT_MAX, "csia"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x1b8, 0x1bc, UINT_MAX, "csib"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 10, 0x1c0, 0x1c4, UINT_MAX, "csic"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 11, 0x1c0, 0x1c4, UINT_MAX, "csid"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 12, 0x1c0, 0x1c4, UINT_MAX, "csie"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 13, 0x1c0, 0x1c4, UINT_MAX, "csif"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DBG, 25, 0x1b8, 0x1bc, 19, "dbg"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DEBUG_NONAO, 26, 0x1b8, 0x1bc, UINT_MAX, "debug-nonao"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DMIC, 18, 0x1c0, 0x1c4, 20, "dmic"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DP, 19, 0x1c0, 0x1c4, UINT_MAX, "dp"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DSI, 2, 0x1b8, 0x1bc, UINT_MAX, "dsi"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DSIB, 7, 0x1c0, 0x1c4, UINT_MAX, "dsib"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DSIC, 8, 0x1c0, 0x1c4, UINT_MAX, "dsic"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DSID, 9, 0x1c0, 0x1c4, UINT_MAX, "dsid"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_EMMC, 3, 0x1c0, 0x1c4, UINT_MAX, "emmc"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_EMMC2, 5, 0x1c0, 0x1c4, UINT_MAX, "emmc2"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_GPIO, 27, 0x1b8, 0x1bc, 21, "gpio"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI, 28, 0x1b8, 0x1bc, UINT_MAX, "hdmi"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_HSIC, 19, 0x1b8, 0x1bc, UINT_MAX, "hsic"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_LVDS, 25, 0x1c0, 0x1c4, UINT_MAX, "lvds"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_MIPI_BIAS, 3, 0x1b8, 0x1bc, UINT_MAX, "mipi-bias"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_BIAS, 4, 0x1b8, 0x1bc, UINT_MAX, "pex-bias"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK1, 5, 0x1b8, 0x1bc, UINT_MAX, "pex-clk1"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK2, 6, 0x1b8, 0x1bc, UINT_MAX, "pex-clk2"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CNTRL, UINT_MAX, UINT_MAX, UINT_MAX, 11, "pex-cntrl"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1, 1, 0x1c0, 0x1c4, 12, "sdmmc1"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3, 2, 0x1c0, 0x1c4, 13, "sdmmc3"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SPI, 14, 0x1c0, 0x1c4, 22, "spi"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SPI_HV, 15, 0x1c0, 0x1c4, 23, "spi-hv"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_UART, 14, 0x1b8, 0x1bc, 2, "uart"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_USB0, 9, 0x1b8, 0x1bc, UINT_MAX, "usb0"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_USB1, 10, 0x1b8, 0x1bc, UINT_MAX, "usb1"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_USB2, 11, 0x1b8, 0x1bc, UINT_MAX, "usb2"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_USB3, 18, 0x1b8, 0x1bc, UINT_MAX, "usb3"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_USB_BIAS, 12, 0x1b8, 0x1bc, UINT_MAX, "usb-bias"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO, 17, 0x1b8, 0x1bc, "audio"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO_HV, 29, 0x1c0, 0x1c4, "audio-hv"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CAM, 4, 0x1c0, 0x1c4, "cam"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x1b8, 0x1bc, "csia"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x1b8, 0x1bc, "csib"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 10, 0x1c0, 0x1c4, "csic"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 11, 0x1c0, 0x1c4, "csid"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 12, 0x1c0, 0x1c4, "csie"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 13, 0x1c0, 0x1c4, "csif"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DBG, 25, 0x1b8, 0x1bc, "dbg"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DEBUG_NONAO, 26, 0x1b8, 0x1bc, "debug-nonao"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DMIC, 18, 0x1c0, 0x1c4, "dmic"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DP, 19, 0x1c0, 0x1c4, "dp"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DSI, 2, 0x1b8, 0x1bc, "dsi"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DSIB, 7, 0x1c0, 0x1c4, "dsib"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DSIC, 8, 0x1c0, 0x1c4, "dsic"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DSID, 9, 0x1c0, 0x1c4, "dsid"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_EMMC, 3, 0x1c0, 0x1c4, "emmc"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_EMMC2, 5, 0x1c0, 0x1c4, "emmc2"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_GPIO, 27, 0x1b8, 0x1bc, "gpio"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI, 28, 0x1b8, 0x1bc, "hdmi"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_HSIC, 19, 0x1b8, 0x1bc, "hsic"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_LVDS, 25, 0x1c0, 0x1c4, "lvds"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_MIPI_BIAS, 3, 0x1b8, 0x1bc, "mipi-bias"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_BIAS, 4, 0x1b8, 0x1bc, "pex-bias"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK1, 5, 0x1b8, 0x1bc, "pex-clk1"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK2, 6, 0x1b8, 0x1bc, "pex-clk2"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CNTRL, UINT_MAX, UINT_MAX, UINT_MAX, "pex-cntrl"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1, 1, 0x1c0, 0x1c4, "sdmmc1"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3, 2, 0x1c0, 0x1c4, "sdmmc3"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SPI, 14, 0x1c0, 0x1c4, "spi"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SPI_HV, 15, 0x1c0, 0x1c4, "spi-hv"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_UART, 14, 0x1b8, 0x1bc, "uart"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_USB0, 9, 0x1b8, 0x1bc, "usb0"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_USB1, 10, 0x1b8, 0x1bc, "usb1"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_USB2, 11, 0x1b8, 0x1bc, "usb2"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_USB3, 18, 0x1b8, 0x1bc, "usb3"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_USB_BIAS, 12, 0x1b8, 0x1bc, "usb-bias"),
 };
 
+static const struct tegra_io_pad_vctrl tegra210_io_pad_vctrls[] = {
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_AUDIO, PMC_PWR_DET_VALUE, 5),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_AUDIO_HV, PMC_PWR_DET_VALUE, 18),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_CAM, PMC_PWR_DET_VALUE, 10),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_DBG, PMC_PWR_DET_VALUE, 19),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_DMIC, PMC_PWR_DET_VALUE, 20),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_GPIO, PMC_PWR_DET_VALUE, 21),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_PEX_CNTRL, PMC_PWR_DET_VALUE, 11),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SDMMC1, PMC_PWR_DET_VALUE, 12),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SDMMC3, PMC_PWR_DET_VALUE, 13),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SPI, PMC_PWR_DET_VALUE, 22),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SPI_HV, PMC_PWR_DET_VALUE, 23),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_UART, PMC_PWR_DET_VALUE, 2),
+};
 static const struct pinctrl_pin_desc tegra210_pin_descs[] = {
 	TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_AUDIO, "audio"),
 	TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_AUDIO_HV, "audio-hv"),
@@ -3965,6 +3985,8 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
 	.maybe_tz_only = true,
 	.num_io_pads = ARRAY_SIZE(tegra210_io_pads),
 	.io_pads = tegra210_io_pads,
+	.num_io_pad_vctrls = ARRAY_SIZE(tegra210_io_pad_vctrls),
+	.io_pad_vctrls = tegra210_io_pad_vctrls,
 	.num_pin_descs = ARRAY_SIZE(tegra210_pin_descs),
 	.pin_descs = tegra210_pin_descs,
 	.regs = &tegra20_pmc_regs,
@@ -3987,44 +4009,53 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
 };
 
 static const struct tegra_io_pad_soc tegra186_io_pads[] = {
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x74, 0x78, UINT_MAX, "csia"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x74, 0x78, UINT_MAX, "csib"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DSI, 2, 0x74, 0x78, UINT_MAX, "dsi"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_MIPI_BIAS, 3, 0x74, 0x78, UINT_MAX, "mipi-bias"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK_BIAS, 4, 0x74, 0x78, UINT_MAX, "pex-clk-bias"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK3, 5, 0x74, 0x78, UINT_MAX, "pex-clk3"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK2, 6, 0x74, 0x78, UINT_MAX, "pex-clk2"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK1, 7, 0x74, 0x78, UINT_MAX, "pex-clk1"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_USB0, 9, 0x74, 0x78, UINT_MAX, "usb0"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_USB1, 10, 0x74, 0x78, UINT_MAX, "usb1"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_USB2, 11, 0x74, 0x78, UINT_MAX, "usb2"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_USB_BIAS, 12, 0x74, 0x78, UINT_MAX, "usb-bias"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_UART, 14, 0x74, 0x78, UINT_MAX, "uart"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO, 17, 0x74, 0x78, UINT_MAX, "audio"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_HSIC, 19, 0x74, 0x78, UINT_MAX, "hsic"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DBG, 25, 0x74, 0x78, UINT_MAX, "dbg"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP0, 28, 0x74, 0x78, UINT_MAX, "hdmi-dp0"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP1, 29, 0x74, 0x78, UINT_MAX, "hdmi-dp1"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CNTRL, 0, 0x7c, 0x80, UINT_MAX, "pex-cntrl"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC2_HV, 2, 0x7c, 0x80, 5, "sdmmc2-hv"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC4, 4, 0x7c, 0x80, UINT_MAX, "sdmmc4"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CAM, 6, 0x7c, 0x80, UINT_MAX, "cam"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DSIB, 8, 0x7c, 0x80, UINT_MAX, "dsib"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DSIC, 9, 0x7c, 0x80, UINT_MAX, "dsic"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DSID, 10, 0x7c, 0x80, UINT_MAX, "dsid"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 11, 0x7c, 0x80, UINT_MAX, "csic"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 12, 0x7c, 0x80, UINT_MAX, "csid"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 13, 0x7c, 0x80, UINT_MAX, "csie"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 14, 0x7c, 0x80, UINT_MAX, "csif"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SPI, 15, 0x7c, 0x80, UINT_MAX, "spi"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_UFS, 17, 0x7c, 0x80, UINT_MAX, "ufs"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DMIC_HV, 20, 0x7c, 0x80, 2, "dmic-hv"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_EDP, 21, 0x7c, 0x80, UINT_MAX, "edp"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1_HV, 23, 0x7c, 0x80, 4, "sdmmc1-hv"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3_HV, 24, 0x7c, 0x80, 6, "sdmmc3-hv"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CONN, 28, 0x7c, 0x80, UINT_MAX, "conn"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO_HV, 29, 0x7c, 0x80, 1, "audio-hv"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_AO_HV, UINT_MAX, UINT_MAX, UINT_MAX, 0, "ao-hv"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x74, 0x78, "csia"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x74, 0x78, "csib"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DSI, 2, 0x74, 0x78, "dsi"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_MIPI_BIAS, 3, 0x74, 0x78, "mipi-bias"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK_BIAS, 4, 0x74, 0x78, "pex-clk-bias"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK3, 5, 0x74, 0x78, "pex-clk3"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK2, 6, 0x74, 0x78, "pex-clk2"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK1, 7, 0x74, 0x78, "pex-clk1"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_USB0, 9, 0x74, 0x78, "usb0"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_USB1, 10, 0x74, 0x78, "usb1"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_USB2, 11, 0x74, 0x78, "usb2"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_USB_BIAS, 12, 0x74, 0x78, "usb-bias"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_UART, 14, 0x74, 0x78, "uart"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO, 17, 0x74, 0x78, "audio"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_HSIC, 19, 0x74, 0x78, "hsic"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DBG, 25, 0x74, 0x78, "dbg"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP0, 28, 0x74, 0x78, "hdmi-dp0"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP1, 29, 0x74, 0x78, "hdmi-dp1"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CNTRL, 0, 0x7c, 0x80, "pex-cntrl"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC2_HV, 2, 0x7c, 0x80, "sdmmc2-hv"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC4, 4, 0x7c, 0x80, "sdmmc4"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CAM, 6, 0x7c, 0x80, "cam"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DSIB, 8, 0x7c, 0x80, "dsib"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DSIC, 9, 0x7c, 0x80, "dsic"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DSID, 10, 0x7c, 0x80, "dsid"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 11, 0x7c, 0x80, "csic"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 12, 0x7c, 0x80, "csid"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 13, 0x7c, 0x80, "csie"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 14, 0x7c, 0x80, "csif"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SPI, 15, 0x7c, 0x80, "spi"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_UFS, 17, 0x7c, 0x80, "ufs"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DMIC_HV, 20, 0x7c, 0x80, "dmic-hv"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_EDP, 21, 0x7c, 0x80, "edp"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1_HV, 23, 0x7c, 0x80, "sdmmc1-hv"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3_HV, 24, 0x7c, 0x80, "sdmmc3-hv"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CONN, 28, 0x7c, 0x80, "conn"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO_HV, 29, 0x7c, 0x80, "audio-hv"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_AO_HV, UINT_MAX, UINT_MAX, UINT_MAX, "ao-hv"),
+};
+
+static const struct tegra_io_pad_vctrl tegra186_io_pad_vctrls[] = {
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SDMMC2_HV, PMC_IMPL_E_33V_PWR, 5),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_DMIC_HV,  PMC_IMPL_E_33V_PWR, 2),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SDMMC1_HV, PMC_IMPL_E_33V_PWR, 4),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SDMMC3_HV, PMC_IMPL_E_33V_PWR, 6),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_AUDIO_HV, PMC_IMPL_E_33V_PWR, 1),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_AO_HV, PMC_IMPL_E_33V_PWR, 0),
 };
 
 static const struct pinctrl_pin_desc tegra186_pin_descs[] = {
@@ -4168,6 +4199,8 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = {
 	.maybe_tz_only = false,
 	.num_io_pads = ARRAY_SIZE(tegra186_io_pads),
 	.io_pads = tegra186_io_pads,
+	.num_io_pad_vctrls = ARRAY_SIZE(tegra186_io_pad_vctrls),
+	.io_pad_vctrls = tegra186_io_pad_vctrls,
 	.num_pin_descs = ARRAY_SIZE(tegra186_pin_descs),
 	.pin_descs = tegra186_pin_descs,
 	.regs = &tegra186_pmc_regs,
@@ -4192,55 +4225,62 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = {
 };
 
 static const struct tegra_io_pad_soc tegra194_io_pads[] = {
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x74, 0x78, UINT_MAX, "csia"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x74, 0x78, UINT_MAX, "csib"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_MIPI_BIAS, 3, 0x74, 0x78, UINT_MAX, "mipi-bias"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK_BIAS, 4, 0x74, 0x78, UINT_MAX, "pex-clk-bias"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK3, 5, 0x74, 0x78, UINT_MAX, "pex-clk3"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK2, 6, 0x74, 0x78, UINT_MAX, "pex-clk2"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK1, 7, 0x74, 0x78, UINT_MAX, "pex-clk1"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_EQOS, 8, 0x74, 0x78, UINT_MAX, "eqos"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK_2_BIAS, 9, 0x74, 0x78, UINT_MAX, "pex-clk-2-bias"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK_2, 10, 0x74, 0x78, UINT_MAX, "pex-clk-2"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DAP3, 11, 0x74, 0x78, UINT_MAX, "dap3"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DAP5, 12, 0x74, 0x78, UINT_MAX, "dap5"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_UART, 14, 0x74, 0x78, UINT_MAX, "uart"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PWR_CTL, 15, 0x74, 0x78, UINT_MAX, "pwr-ctl"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SOC_GPIO53, 16, 0x74, 0x78, UINT_MAX, "soc-gpio53"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO, 17, 0x74, 0x78, UINT_MAX, "audio"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_GP_PWM2, 18, 0x74, 0x78, UINT_MAX, "gp-pwm2"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_GP_PWM3, 19, 0x74, 0x78, UINT_MAX, "gp-pwm3"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SOC_GPIO12, 20, 0x74, 0x78, UINT_MAX, "soc-gpio12"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SOC_GPIO13, 21, 0x74, 0x78, UINT_MAX, "soc-gpio13"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SOC_GPIO10, 22, 0x74, 0x78, UINT_MAX, "soc-gpio10"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_UART4, 23, 0x74, 0x78, UINT_MAX, "uart4"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_UART5, 24, 0x74, 0x78, UINT_MAX, "uart5"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_DBG, 25, 0x74, 0x78, UINT_MAX, "dbg"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP3, 26, 0x74, 0x78, UINT_MAX, "hdmi-dp3"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP2, 27, 0x74, 0x78, UINT_MAX, "hdmi-dp2"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP0, 28, 0x74, 0x78, UINT_MAX, "hdmi-dp0"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP1, 29, 0x74, 0x78, UINT_MAX, "hdmi-dp1"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CNTRL, 0, 0x7c, 0x80, UINT_MAX, "pex-cntrl"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CTL2, 1, 0x7c, 0x80, UINT_MAX, "pex-ctl2"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_L0_RST, 2, 0x7c, 0x80, UINT_MAX, "pex-l0-rst"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_L1_RST, 3, 0x7c, 0x80, UINT_MAX, "pex-l1-rst"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC4, 4, 0x7c, 0x80, UINT_MAX, "sdmmc4"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_L5_RST, 5, 0x7c, 0x80, UINT_MAX, "pex-l5-rst"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CAM, 6, 0x7c, 0x80, UINT_MAX, "cam"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 11, 0x7c, 0x80, UINT_MAX, "csic"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 12, 0x7c, 0x80, UINT_MAX, "csid"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 13, 0x7c, 0x80, UINT_MAX, "csie"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 14, 0x7c, 0x80, UINT_MAX, "csif"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SPI, 15, 0x7c, 0x80, UINT_MAX, "spi"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_UFS, 17, 0x7c, 0x80, UINT_MAX, "ufs"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIG, 18, 0x7c, 0x80, UINT_MAX, "csig"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIH, 19, 0x7c, 0x80, UINT_MAX, "csih"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_EDP, 21, 0x7c, 0x80, UINT_MAX, "edp"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1_HV, 23, 0x7c, 0x80, 4, "sdmmc1-hv"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3_HV, 24, 0x7c, 0x80, 6, "sdmmc3-hv"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CONN, 28, 0x7c, 0x80, UINT_MAX, "conn"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO_HV, 29, 0x7c, 0x80, 1, "audio-hv"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_AO_HV, UINT_MAX, UINT_MAX, UINT_MAX, 0, "ao-hv"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x74, 0x78, "csia"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x74, 0x78, "csib"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_MIPI_BIAS, 3, 0x74, 0x78, "mipi-bias"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK_BIAS, 4, 0x74, 0x78, "pex-clk-bias"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK3, 5, 0x74, 0x78, "pex-clk3"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK2, 6, 0x74, 0x78, "pex-clk2"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK1, 7, 0x74, 0x78, "pex-clk1"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_EQOS, 8, 0x74, 0x78, "eqos"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK_2_BIAS, 9, 0x74, 0x78, "pex-clk-2-bias"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK_2, 10, 0x74, 0x78, "pex-clk-2"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DAP3, 11, 0x74, 0x78, "dap3"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DAP5, 12, 0x74, 0x78, "dap5"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_UART, 14, 0x74, 0x78, "uart"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PWR_CTL, 15, 0x74, 0x78, "pwr-ctl"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SOC_GPIO53, 16, 0x74, 0x78, "soc-gpio53"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO, 17, 0x74, 0x78, "audio"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_GP_PWM2, 18, 0x74, 0x78, "gp-pwm2"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_GP_PWM3, 19, 0x74, 0x78, "gp-pwm3"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SOC_GPIO12, 20, 0x74, 0x78, "soc-gpio12"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SOC_GPIO13, 21, 0x74, 0x78, "soc-gpio13"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SOC_GPIO10, 22, 0x74, 0x78, "soc-gpio10"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_UART4, 23, 0x74, 0x78, "uart4"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_UART5, 24, 0x74, 0x78, "uart5"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_DBG, 25, 0x74, 0x78, "dbg"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP3, 26, 0x74, 0x78, "hdmi-dp3"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP2, 27, 0x74, 0x78, "hdmi-dp2"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP0, 28, 0x74, 0x78, "hdmi-dp0"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP1, 29, 0x74, 0x78, "hdmi-dp1"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CNTRL, 0, 0x7c, 0x80, "pex-cntrl"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CTL2, 1, 0x7c, 0x80, "pex-ctl2"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_L0_RST, 2, 0x7c, 0x80, "pex-l0-rst"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_L1_RST, 3, 0x7c, 0x80, "pex-l1-rst"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC4, 4, 0x7c, 0x80, "sdmmc4"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_L5_RST, 5, 0x7c, 0x80, "pex-l5-rst"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CAM, 6, 0x7c, 0x80, "cam"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 11, 0x7c, 0x80, "csic"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 12, 0x7c, 0x80, "csid"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 13, 0x7c, 0x80, "csie"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 14, 0x7c, 0x80, "csif"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SPI, 15, 0x7c, 0x80, "spi"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_UFS, 17, 0x7c, 0x80, "ufs"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIG, 18, 0x7c, 0x80, "csig"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIH, 19, 0x7c, 0x80, "csih"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_EDP, 21, 0x7c, 0x80, "edp"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1_HV, 23, 0x7c, 0x80, "sdmmc1-hv"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3_HV, 24, 0x7c, 0x80, "sdmmc3-hv"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CONN, 28, 0x7c, 0x80, "conn"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO_HV, 29, 0x7c, 0x80, "audio-hv"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_AO_HV, UINT_MAX, UINT_MAX, UINT_MAX, "ao-hv"),
+};
+
+static const struct tegra_io_pad_vctrl tegra194_io_pad_vctrls[] = {
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SDMMC1_HV, PMC_IMPL_E_33V_PWR, 4),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SDMMC3_HV, PMC_IMPL_E_33V_PWR, 6),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_AUDIO_HV, PMC_IMPL_E_33V_PWR, 1),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_AO_HV, PMC_IMPL_E_33V_PWR, 0),
 };
 
 static const struct pinctrl_pin_desc tegra194_pin_descs[] = {
@@ -4363,6 +4403,8 @@ static const struct tegra_pmc_soc tegra194_pmc_soc = {
 	.maybe_tz_only = false,
 	.num_io_pads = ARRAY_SIZE(tegra194_io_pads),
 	.io_pads = tegra194_io_pads,
+	.num_io_pad_vctrls = ARRAY_SIZE(tegra194_io_pad_vctrls),
+	.io_pad_vctrls = tegra194_io_pad_vctrls,
 	.num_pin_descs = ARRAY_SIZE(tegra194_pin_descs),
 	.pin_descs = tegra194_pin_descs,
 	.regs = &tegra194_pmc_regs,
@@ -4387,21 +4429,28 @@ static const struct tegra_pmc_soc tegra194_pmc_soc = {
 };
 
 static const struct tegra_io_pad_soc tegra234_io_pads[] = {
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0xe0c0, 0xe0c4, UINT_MAX, "csia"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0xe0c0, 0xe0c4, UINT_MAX, "csib"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP0, 0, 0xe0d0, 0xe0d4, UINT_MAX, "hdmi-dp0"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 2, 0xe0c0, 0xe0c4, UINT_MAX, "csic"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 3, 0xe0c0, 0xe0c4, UINT_MAX, "csid"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 4, 0xe0c0, 0xe0c4, UINT_MAX, "csie"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 5, 0xe0c0, 0xe0c4, UINT_MAX, "csif"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_UFS, 0, 0xe064, 0xe068, UINT_MAX, "ufs"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_EDP, 1, 0xe05c, 0xe060, UINT_MAX, "edp"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1_HV, 0, 0xe054, 0xe058, 4, "sdmmc1-hv"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3_HV, UINT_MAX, UINT_MAX, UINT_MAX, 6, "sdmmc3-hv"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO_HV, UINT_MAX, UINT_MAX, UINT_MAX, 1, "audio-hv"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_AO_HV, UINT_MAX, UINT_MAX, UINT_MAX, 0, "ao-hv"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIG, 6, 0xe0c0, 0xe0c4, UINT_MAX, "csig"),
-	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIH, 7, 0xe0c0, 0xe0c4, UINT_MAX, "csih"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0xe0c0, 0xe0c4, "csia"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0xe0c0, 0xe0c4, "csib"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP0, 0, 0xe0d0, 0xe0d4, "hdmi-dp0"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 2, 0xe0c0, 0xe0c4, "csic"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 3, 0xe0c0, 0xe0c4, "csid"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 4, 0xe0c0, 0xe0c4, "csie"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 5, 0xe0c0, 0xe0c4, "csif"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_UFS, 0, 0xe064, 0xe068, "ufs"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_EDP, 1, 0xe05c, 0xe060, "edp"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1_HV, 0, 0xe054, 0xe058, "sdmmc1-hv"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3_HV, UINT_MAX, UINT_MAX, UINT_MAX, "sdmmc3-hv"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO_HV, UINT_MAX, UINT_MAX, UINT_MAX, "audio-hv"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_AO_HV, UINT_MAX, UINT_MAX, UINT_MAX, "ao-hv"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIG, 6, 0xe0c0, 0xe0c4, "csig"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIH, 7, 0xe0c0, 0xe0c4, "csih"),
+};
+
+static const struct tegra_io_pad_vctrl tegra234_io_pad_vctrls[] = {
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SDMMC1_HV, PMC_IMPL_E_33V_PWR, 4),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SDMMC3_HV, PMC_IMPL_E_33V_PWR, 6),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_AUDIO_HV, PMC_IMPL_E_33V_PWR, 1),
+	TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_AO_HV, PMC_IMPL_E_33V_PWR, 0),
 };
 
 static const struct pinctrl_pin_desc tegra234_pin_descs[] = {
@@ -4510,6 +4559,8 @@ static const struct tegra_pmc_soc tegra234_pmc_soc = {
 	.maybe_tz_only = false,
 	.num_io_pads = ARRAY_SIZE(tegra234_io_pads),
 	.io_pads = tegra234_io_pads,
+	.num_io_pad_vctrls = ARRAY_SIZE(tegra234_io_pad_vctrls),
+	.io_pad_vctrls = tegra234_io_pad_vctrls,
 	.num_pin_descs = ARRAY_SIZE(tegra234_pin_descs),
 	.pin_descs = tegra234_pin_descs,
 	.regs = &tegra234_pmc_regs,
-- 
2.43.0


^ permalink raw reply related

* [PATCH 09/10] soc/tegra: pmc: Rename has_impl_33v_pwr flag
From: Jon Hunter @ 2026-03-25 19:25 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-tegra, Jon Hunter
In-Reply-To: <20260325192601.239554-1-jonathanh@nvidia.com>

The flag 'has_impl_33v_pwr' is now only used to determine if we need to
set the write-enable bit before we can set the bit to select if 3.3V IO
is used or not. Therefore, rename the flag to 'has_io_pad_wren' to
indicate that the SoC supports the write-enable register.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 drivers/soc/tegra/pmc.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 3dcc679baffa..6f0808faf4b5 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -372,7 +372,7 @@ struct tegra_pmc_soc {
 	bool has_tsense_reset;
 	bool has_gpu_clamps;
 	bool needs_mbist_war;
-	bool has_impl_33v_pwr;
+	bool has_io_pad_wren;
 	bool maybe_tz_only;
 
 	const struct tegra_io_pad_soc *io_pads;
@@ -1922,7 +1922,7 @@ static int tegra_io_pad_set_voltage(struct tegra_pmc *pmc, enum tegra_io_pad id,
 
 	mutex_lock(&pmc->powergates_lock);
 
-	if (!pmc->soc->has_impl_33v_pwr) {
+	if (pmc->soc->has_io_pad_wren) {
 		/* write-enable PMC_PWR_DET_VALUE[pad->ena_3v3] */
 		value = tegra_pmc_readl(pmc, PMC_PWR_DET);
 		value |= BIT(pad->ena_3v3);
@@ -3536,7 +3536,7 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = {
 	.has_tsense_reset = false,
 	.has_gpu_clamps = false,
 	.needs_mbist_war = false,
-	.has_impl_33v_pwr = false,
+	.has_io_pad_wren = true,
 	.maybe_tz_only = false,
 	.num_io_pads = 0,
 	.io_pads = NULL,
@@ -3598,7 +3598,7 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = {
 	.has_tsense_reset = true,
 	.has_gpu_clamps = false,
 	.needs_mbist_war = false,
-	.has_impl_33v_pwr = false,
+	.has_io_pad_wren = true,
 	.maybe_tz_only = false,
 	.num_io_pads = 0,
 	.io_pads = NULL,
@@ -3656,7 +3656,7 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = {
 	.has_tsense_reset = true,
 	.has_gpu_clamps = false,
 	.needs_mbist_war = false,
-	.has_impl_33v_pwr = false,
+	.has_io_pad_wren = true,
 	.maybe_tz_only = false,
 	.num_io_pads = 0,
 	.io_pads = NULL,
@@ -3807,7 +3807,7 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = {
 	.has_tsense_reset = true,
 	.has_gpu_clamps = true,
 	.needs_mbist_war = false,
-	.has_impl_33v_pwr = false,
+	.has_io_pad_wren = true,
 	.maybe_tz_only = false,
 	.num_io_pads = ARRAY_SIZE(tegra124_io_pads),
 	.io_pads = tegra124_io_pads,
@@ -3981,7 +3981,7 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
 	.has_tsense_reset = true,
 	.has_gpu_clamps = true,
 	.needs_mbist_war = true,
-	.has_impl_33v_pwr = false,
+	.has_io_pad_wren = true,
 	.maybe_tz_only = true,
 	.num_io_pads = ARRAY_SIZE(tegra210_io_pads),
 	.io_pads = tegra210_io_pads,
@@ -4195,7 +4195,7 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = {
 	.has_tsense_reset = false,
 	.has_gpu_clamps = false,
 	.needs_mbist_war = false,
-	.has_impl_33v_pwr = true,
+	.has_io_pad_wren = false,
 	.maybe_tz_only = false,
 	.num_io_pads = ARRAY_SIZE(tegra186_io_pads),
 	.io_pads = tegra186_io_pads,
@@ -4399,7 +4399,7 @@ static const struct tegra_pmc_soc tegra194_pmc_soc = {
 	.has_tsense_reset = false,
 	.has_gpu_clamps = false,
 	.needs_mbist_war = false,
-	.has_impl_33v_pwr = true,
+	.has_io_pad_wren = false,
 	.maybe_tz_only = false,
 	.num_io_pads = ARRAY_SIZE(tegra194_io_pads),
 	.io_pads = tegra194_io_pads,
@@ -4555,7 +4555,7 @@ static const struct tegra_pmc_soc tegra234_pmc_soc = {
 	.has_tsense_reset = false,
 	.has_gpu_clamps = false,
 	.needs_mbist_war = false,
-	.has_impl_33v_pwr = true,
+	.has_io_pad_wren = false,
 	.maybe_tz_only = false,
 	.num_io_pads = ARRAY_SIZE(tegra234_io_pads),
 	.io_pads = tegra234_io_pads,
@@ -4704,7 +4704,7 @@ static const struct tegra_wake_event tegra264_wake_events[] = {
 };
 
 static const struct tegra_pmc_soc tegra264_pmc_soc = {
-	.has_impl_33v_pwr = true,
+	.has_io_pad_wren = false,
 	.regs = &tegra264_pmc_regs,
 	.init = tegra186_pmc_init,
 	.setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
-- 
2.43.0


^ permalink raw reply related

* [PATCH 10/10] soc/tegra: pmc: Add IO pads for Tegra264
From: Jon Hunter @ 2026-03-25 19:26 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-tegra, Jon Hunter
In-Reply-To: <20260325192601.239554-1-jonathanh@nvidia.com>

Populate the IO pads and pins for Tegra264. Tegra264 has internal 1.8V
and 0.6V regulators that must be enabled when selecting the 1.8V mode
for the sdmmc1-hv IO pad. To support this a new 'ena_1v8' member is
added to the 'tegra_io_pad_vctrl' structure to populate the bits that
need to be set to enable these internal regulators. Although this is
enabling 1.8V (bit 1) and 0.6V (bit 2) regulators, it is simply called
'ena_1v8' because these are both enabled for 1.8V operation. Note that
these internal regulators are disabled when not using 1.8V mode.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 drivers/soc/tegra/pmc.c | 66 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 64 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 6f0808faf4b5..eca56119b381 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -201,6 +201,9 @@
 #define  TEGRA_SMC_PMC_READ	0xaa
 #define  TEGRA_SMC_PMC_WRITE	0xbb
 
+/* Tegra264 and later */
+#define PMC_IMPL_SDMMC1_HV_PADCTL_0	0x41004
+
 struct pmc_clk {
 	struct clk_hw hw;
 	struct tegra_pmc *pmc;
@@ -301,6 +304,7 @@ struct tegra_io_pad_vctrl {
 	enum tegra_io_pad id;
 	unsigned int offset;
 	unsigned int ena_3v3;
+	unsigned int ena_1v8;
 };
 
 struct tegra_pmc_regs {
@@ -1931,11 +1935,18 @@ static int tegra_io_pad_set_voltage(struct tegra_pmc *pmc, enum tegra_io_pad id,
 
 	value = tegra_pmc_readl(pmc, pad->offset);
 
-	if (voltage == TEGRA_IO_PAD_VOLTAGE_1V8)
+	if (voltage == TEGRA_IO_PAD_VOLTAGE_1V8) {
 		value &= ~BIT(pad->ena_3v3);
-	else
+
+		if (pad->ena_1v8)
+			value |= pad->ena_1v8;
+	} else {
 		value |= BIT(pad->ena_3v3);
 
+		if (pad->ena_1v8)
+			value &= ~pad->ena_1v8;
+	}
+
 	tegra_pmc_writel(pmc, value, pad->offset);
 
 	mutex_unlock(&pmc->powergates_lock);
@@ -3724,6 +3735,7 @@ static const u8 tegra124_cpu_powergates[] = {
 		.id		= (_id),				\
 		.offset		= (_offset),				\
 		.ena_3v3	= (_ena_3v3),				\
+		.ena_1v8	= 0,					\
 	})
 
 #define TEGRA_IO_PIN_DESC(_id, _name)	\
@@ -4583,6 +4595,50 @@ static const struct tegra_pmc_soc tegra234_pmc_soc = {
 	.has_single_mmio_aperture = false,
 };
 
+#define TEGRA264_IO_PAD_VCTRL(_id, _offset, _ena_3v3, _ena_1v8)		\
+	((struct tegra_io_pad_vctrl) {					\
+		.id		= (_id),				\
+		.offset		= (_offset),				\
+		.ena_3v3	= (_ena_3v3),				\
+		.ena_1v8	= (_ena_1v8),				\
+	})
+
+static const struct tegra_io_pad_soc tegra264_io_pads[] = {
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x41020, 0x41024, "csia"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x41020, 0x41024, "csib"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP0, 0, 0x41050, 0x41054, "hdmi-dp0"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 2, 0x41020, 0x41024, "csic"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 3, 0x41020, 0x41024, "csid"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 4, 0x41020, 0x41024, "csie"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 5, 0x41020, 0x41024, "csif"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_UFS, 4, 0x41040, 0x41044, "ufs0"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_EDP, 0, 0x41028, 0x4102c, "edp"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1, 0, 0x41090, 0x41094, "sdmmc1"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1_HV, UINT_MAX, UINT_MAX, UINT_MAX, "sdmmc1-hv"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIG, 6, 0x41020, 0x41024, "csig"),
+	TEGRA_IO_PAD(TEGRA_IO_PAD_CSIH, 7, 0x41020, 0x41024, "csih"),
+};
+
+static const struct tegra_io_pad_vctrl tegra264_io_pad_vctrls[] = {
+	TEGRA264_IO_PAD_VCTRL(TEGRA_IO_PAD_SDMMC1_HV, PMC_IMPL_SDMMC1_HV_PADCTL_0, 0, 0x6),
+};
+
+static const struct pinctrl_pin_desc tegra264_pin_descs[] = {
+	TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIA, "csia"),
+	TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIB, "csib"),
+	TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_HDMI_DP0, "hdmi-dp0"),
+	TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIC, "csic"),
+	TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSID, "csid"),
+	TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIE, "csie"),
+	TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIF, "csif"),
+	TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_UFS, "ufs0"),
+	TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_EDP, "edp"),
+	TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SDMMC1, "sdmmc1"),
+	TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SDMMC1_HV, "sdmmc1-hv"),
+	TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIG, "csig"),
+	TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIH, "csih"),
+};
+
 static const struct tegra_pmc_regs tegra264_pmc_regs = {
 	.scratch0 = 0x684,
 	.rst_status = 0x4,
@@ -4705,6 +4761,12 @@ static const struct tegra_wake_event tegra264_wake_events[] = {
 
 static const struct tegra_pmc_soc tegra264_pmc_soc = {
 	.has_io_pad_wren = false,
+	.num_io_pads = ARRAY_SIZE(tegra264_io_pads),
+	.io_pads = tegra264_io_pads,
+	.num_io_pad_vctrls = ARRAY_SIZE(tegra264_io_pad_vctrls),
+	.io_pad_vctrls = tegra264_io_pad_vctrls,
+	.num_pin_descs = ARRAY_SIZE(tegra264_pin_descs),
+	.pin_descs = tegra264_pin_descs,
 	.regs = &tegra264_pmc_regs,
 	.init = tegra186_pmc_init,
 	.setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
-- 
2.43.0


^ permalink raw reply related

* [PATCH 07/10] soc/tegra: pmc: Add Tegra264 wake events
From: Jon Hunter @ 2026-03-25 19:25 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-tegra, Jon Hunter
In-Reply-To: <20260325192601.239554-1-jonathanh@nvidia.com>

Populate the various wake events for the Tegra264 device.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 drivers/soc/tegra/pmc.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 7a5262705d69..3899d8c76569 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -60,6 +60,7 @@
 #include <dt-bindings/gpio/tegra186-gpio.h>
 #include <dt-bindings/gpio/tegra194-gpio.h>
 #include <dt-bindings/gpio/tegra234-gpio.h>
+#include <dt-bindings/gpio/nvidia,tegra264-gpio.h>
 #include <dt-bindings/soc/tegra-pmc.h>
 
 #define PMC_CNTRL			0x0
@@ -4639,6 +4640,16 @@ static const char * const tegra264_reset_sources[] = {
 };
 
 static const struct tegra_wake_event tegra264_wake_events[] = {
+	TEGRA_WAKE_IRQ("pmu", 0, 727),
+	TEGRA_WAKE_GPIO("power", 5, 1, TEGRA264_AON_GPIO(AA, 5)),
+	TEGRA_WAKE_IRQ("rtc", 65, 548),
+	TEGRA_WAKE_IRQ("usb3-port-0", 79, 965),
+	TEGRA_WAKE_IRQ("usb3-port-1", 80, 965),
+	TEGRA_WAKE_IRQ("usb3-port-3", 82, 965),
+	TEGRA_WAKE_IRQ("usb2-port-0", 83, 965),
+	TEGRA_WAKE_IRQ("usb2-port-1", 84, 965),
+	TEGRA_WAKE_IRQ("usb2-port-2", 85, 965),
+	TEGRA_WAKE_IRQ("usb2-port-3", 86, 965),
 };
 
 static const struct tegra_pmc_soc tegra264_pmc_soc = {
-- 
2.43.0


^ permalink raw reply related

* [PATCH 06/10] soc/tegra: pmc: Add AOWAKE regs for Tegra264
From: Jon Hunter @ 2026-03-25 19:25 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-tegra, Jon Hunter
In-Reply-To: <20260325192601.239554-1-jonathanh@nvidia.com>

Populate the AOWAKE register offsets for Tegra264.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 drivers/soc/tegra/pmc.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 42176abb96ea..7a5262705d69 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -4538,6 +4538,14 @@ static const struct tegra_pmc_regs tegra264_pmc_regs = {
 	.rst_source_mask = 0x1fc,
 	.rst_level_shift = 0x0,
 	.rst_level_mask = 0x3,
+	.aowake_mask_w = 0x200,
+	.aowake_status_w = 0x410,
+	.aowake_status_r = 0x610,
+	.aowake_tier2_routing = 0x660,
+	.aowake_sw_status_w = 0x624,
+	.aowake_sw_status = 0x628,
+	.aowake_latch_sw = 0x620,
+	.aowake_ctrl = 0x68c,
 };
 
 static const char * const tegra264_reset_sources[] = {
-- 
2.43.0


^ permalink raw reply related

* [PATCH 04/10] soc/tegra: pmc: Remove unused AOWAKE definitions
From: Jon Hunter @ 2026-03-25 19:25 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-tegra, Jon Hunter
In-Reply-To: <20260325192601.239554-1-jonathanh@nvidia.com>

For Tegra264, the offsets for the AOWAKE registers have changed. Before
adding support for the Tegra264 AOWAKE register offsets, remove the
unused AOWAKE definitions.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 drivers/soc/tegra/pmc.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 6debaabdaa36..55c1117b1741 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -181,11 +181,8 @@
 #define WAKE_AOWAKE_CNTRL_LEVEL (1 << 3)
 #define WAKE_AOWAKE_CNTRL_SR_CAPTURE_EN (1 << 1)
 #define WAKE_AOWAKE_MASK_W(x) (0x180 + ((x) << 2))
-#define WAKE_AOWAKE_MASK_R(x) (0x300 + ((x) << 2))
 #define WAKE_AOWAKE_STATUS_W(x) (0x30c + ((x) << 2))
 #define WAKE_AOWAKE_STATUS_R(x) (0x48c + ((x) << 2))
-#define WAKE_AOWAKE_TIER0_ROUTING(x) (0x4b4 + ((x) << 2))
-#define WAKE_AOWAKE_TIER1_ROUTING(x) (0x4c0 + ((x) << 2))
 #define WAKE_AOWAKE_TIER2_ROUTING(x) (0x4cc + ((x) << 2))
 #define WAKE_AOWAKE_SW_STATUS_W_0	0x49c
 #define WAKE_AOWAKE_SW_STATUS(x)	(0x4a0 + ((x) << 2))
-- 
2.43.0


^ permalink raw reply related

* [PATCH 05/10] soc/tegra: pmc: Add support for SoC specific AOWAKE offsets
From: Jon Hunter @ 2026-03-25 19:25 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-tegra, Jon Hunter
In-Reply-To: <20260325192601.239554-1-jonathanh@nvidia.com>

For Tegra264, some of the AOWAKE registers have different register
offsets. Prepare for adding the Tegra264 AOWAKE register by moving the
offsets for the AOWAKE registers that are different for Tegra264 into
the 'tegra_pmc_regs' structure and populate these offsets for the SoCs
that support these registers.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 drivers/soc/tegra/pmc.c | 86 +++++++++++++++++++++++++++++------------
 1 file changed, 61 insertions(+), 25 deletions(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 55c1117b1741..42176abb96ea 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -180,16 +180,18 @@
 #define WAKE_AOWAKE_CNTRL(x) (0x000 + ((x) << 2))
 #define WAKE_AOWAKE_CNTRL_LEVEL (1 << 3)
 #define WAKE_AOWAKE_CNTRL_SR_CAPTURE_EN (1 << 1)
-#define WAKE_AOWAKE_MASK_W(x) (0x180 + ((x) << 2))
-#define WAKE_AOWAKE_STATUS_W(x) (0x30c + ((x) << 2))
-#define WAKE_AOWAKE_STATUS_R(x) (0x48c + ((x) << 2))
-#define WAKE_AOWAKE_TIER2_ROUTING(x) (0x4cc + ((x) << 2))
-#define WAKE_AOWAKE_SW_STATUS_W_0	0x49c
-#define WAKE_AOWAKE_SW_STATUS(x)	(0x4a0 + ((x) << 2))
-#define WAKE_LATCH_SW			0x498
-
-#define WAKE_AOWAKE_CTRL 0x4f4
-#define  WAKE_AOWAKE_CTRL_INTR_POLARITY BIT(0)
+#define WAKE_AOWAKE_MASK_W(_pmc, x) \
+	((_pmc)->soc->regs->aowake_mask_w + ((x) << 2))
+#define WAKE_AOWAKE_STATUS_W(_pmc, x) \
+	((_pmc)->soc->regs->aowake_status_w + ((x) << 2))
+#define WAKE_AOWAKE_STATUS_R(_pmc, x) \
+	((_pmc)->soc->regs->aowake_status_r + ((x) << 2))
+#define WAKE_AOWAKE_TIER2_ROUTING(_pmc, x) \
+	((_pmc)->soc->regs->aowake_tier2_routing + ((x) << 2))
+#define WAKE_AOWAKE_SW_STATUS(_pmc, x) \
+	((_pmc)->soc->regs->aowake_sw_status + ((x) << 2))
+
+#define WAKE_AOWAKE_CTRL_INTR_POLARITY BIT(0)
 
 #define SW_WAKE_ID		83 /* wake83 */
 
@@ -302,6 +304,14 @@ struct tegra_pmc_regs {
 	unsigned int rst_source_mask;
 	unsigned int rst_level_shift;
 	unsigned int rst_level_mask;
+	unsigned int aowake_mask_w;
+	unsigned int aowake_status_w;
+	unsigned int aowake_status_r;
+	unsigned int aowake_tier2_routing;
+	unsigned int aowake_sw_status_w;
+	unsigned int aowake_sw_status;
+	unsigned int aowake_latch_sw;
+	unsigned int aowake_ctrl;
 };
 
 struct tegra_wake_event {
@@ -2629,20 +2639,20 @@ static int tegra186_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
 	bit = data->hwirq % 32;
 
 	/* clear wake status */
-	writel(0x1, pmc->wake + WAKE_AOWAKE_STATUS_W(data->hwirq));
+	writel(0x1, pmc->wake + WAKE_AOWAKE_STATUS_W(pmc, data->hwirq));
 
 	/* route wake to tier 2 */
-	value = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(offset));
+	value = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(pmc, offset));
 
 	if (!on)
 		value &= ~(1 << bit);
 	else
 		value |= 1 << bit;
 
-	writel(value, pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(offset));
+	writel(value, pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(pmc, offset));
 
 	/* enable wakeup event */
-	writel(!!on, pmc->wake + WAKE_AOWAKE_MASK_W(data->hwirq));
+	writel(!!on, pmc->wake + WAKE_AOWAKE_MASK_W(pmc, data->hwirq));
 
 	return 0;
 }
@@ -3309,7 +3319,7 @@ static void wke_write_wake_levels(struct tegra_pmc *pmc)
 
 static void wke_clear_sw_wake_status(struct tegra_pmc *pmc)
 {
-	wke_32kwritel(pmc, 1, WAKE_AOWAKE_SW_STATUS_W_0);
+	wke_32kwritel(pmc, 1, pmc->soc->regs->aowake_sw_status_w);
 }
 
 static void wke_read_sw_wake_status(struct tegra_pmc *pmc)
@@ -3322,7 +3332,7 @@ static void wke_read_sw_wake_status(struct tegra_pmc *pmc)
 
 	wke_clear_sw_wake_status(pmc);
 
-	wke_32kwritel(pmc, 1, WAKE_LATCH_SW);
+	wke_32kwritel(pmc, 1, pmc->soc->regs->aowake_latch_sw);
 
 	/*
 	 * WAKE_AOWAKE_SW_STATUS is edge triggered, so in order to
@@ -3340,12 +3350,12 @@ static void wke_read_sw_wake_status(struct tegra_pmc *pmc)
 	 */
 	udelay(300);
 
-	wke_32kwritel(pmc, 0, WAKE_LATCH_SW);
+	wke_32kwritel(pmc, 0, pmc->soc->regs->aowake_latch_sw);
 
 	bitmap_zero(pmc->wake_sw_status_map, pmc->soc->max_wake_events);
 
 	for (i = 0; i < pmc->soc->max_wake_vectors; i++) {
-		status = readl(pmc->wake + WAKE_AOWAKE_SW_STATUS(i));
+		status = readl(pmc->wake + WAKE_AOWAKE_SW_STATUS(pmc, i));
 
 		for_each_set_bit(wake, &status, 32)
 			set_bit(wake + (i * 32), pmc->wake_sw_status_map);
@@ -3359,11 +3369,12 @@ static void wke_clear_wake_status(struct tegra_pmc *pmc)
 	u32 mask;
 
 	for (i = 0; i < pmc->soc->max_wake_vectors; i++) {
-		mask = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(i));
-		status = readl(pmc->wake + WAKE_AOWAKE_STATUS_R(i)) & mask;
+		mask = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(pmc, i));
+		status = readl(pmc->wake + WAKE_AOWAKE_STATUS_R(pmc, i)) & mask;
 
 		for_each_set_bit(wake, &status, 32)
-			wke_32kwritel(pmc, 0x1, WAKE_AOWAKE_STATUS_W((i * 32) + wake));
+			wke_32kwritel(pmc, 0x1, WAKE_AOWAKE_STATUS_W(pmc,
+							(i * 32) + wake));
 	}
 }
 
@@ -3374,8 +3385,9 @@ static void tegra186_pmc_wake_syscore_resume(void *data)
 	u32 mask;
 
 	for (i = 0; i < pmc->soc->max_wake_vectors; i++) {
-		mask = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(i));
-		pmc->wake_status[i] = readl(pmc->wake + WAKE_AOWAKE_STATUS_R(i)) & mask;
+		mask = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(pmc, i));
+		pmc->wake_status[i] = readl(pmc->wake +
+					    WAKE_AOWAKE_STATUS_R(pmc, i)) & mask;
 	}
 
 	/* Schedule IRQ work to process wake IRQs (if any) */
@@ -4062,6 +4074,14 @@ static const struct tegra_pmc_regs tegra186_pmc_regs = {
 	.rst_source_mask = 0x3c,
 	.rst_level_shift = 0x0,
 	.rst_level_mask = 0x3,
+	.aowake_mask_w = 0x180,
+	.aowake_status_w = 0x30c,
+	.aowake_status_r = 0x48c,
+	.aowake_tier2_routing = 0x4cc,
+	.aowake_sw_status_w = 0x49c,
+	.aowake_sw_status = 0x4a0,
+	.aowake_latch_sw = 0x498,
+	.aowake_ctrl = 0x4f4,
 };
 
 static void tegra186_pmc_init(struct tegra_pmc *pmc)
@@ -4094,14 +4114,14 @@ static void tegra186_pmc_setup_irq_polarity(struct tegra_pmc *pmc,
 		return;
 	}
 
-	value = readl(wake + WAKE_AOWAKE_CTRL);
+	value = readl(wake + pmc->soc->regs->aowake_ctrl);
 
 	if (invert)
 		value |= WAKE_AOWAKE_CTRL_INTR_POLARITY;
 	else
 		value &= ~WAKE_AOWAKE_CTRL_INTR_POLARITY;
 
-	writel(value, wake + WAKE_AOWAKE_CTRL);
+	writel(value, wake + pmc->soc->regs->aowake_ctrl);
 
 	iounmap(wake);
 }
@@ -4281,6 +4301,14 @@ static const struct tegra_pmc_regs tegra194_pmc_regs = {
 	.rst_source_mask = 0x7c,
 	.rst_level_shift = 0x0,
 	.rst_level_mask = 0x3,
+	.aowake_mask_w = 0x180,
+	.aowake_status_w = 0x30c,
+	.aowake_status_r = 0x48c,
+	.aowake_tier2_routing = 0x4cc,
+	.aowake_sw_status_w = 0x49c,
+	.aowake_sw_status = 0x4a0,
+	.aowake_latch_sw = 0x498,
+	.aowake_ctrl = 0x4f4,
 };
 
 static const char * const tegra194_reset_sources[] = {
@@ -4400,6 +4428,14 @@ static const struct tegra_pmc_regs tegra234_pmc_regs = {
 	.rst_source_mask = 0xfc,
 	.rst_level_shift = 0x0,
 	.rst_level_mask = 0x3,
+	.aowake_mask_w = 0x180,
+	.aowake_status_w = 0x30c,
+	.aowake_status_r = 0x48c,
+	.aowake_tier2_routing = 0x4cc,
+	.aowake_sw_status_w = 0x49c,
+	.aowake_sw_status = 0x4a0,
+	.aowake_latch_sw = 0x498,
+	.aowake_ctrl = 0x4f4,
 };
 
 static const char * const tegra234_reset_sources[] = {
-- 
2.43.0


^ permalink raw reply related

* [PATCH 03/10] soc/tegra: pmc: Add kerneldoc for wake-up variables
From: Jon Hunter @ 2026-03-25 19:25 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-tegra, Jon Hunter
In-Reply-To: <20260325192601.239554-1-jonathanh@nvidia.com>

Commit e6d96073af68 ("soc/tegra: pmc: Fix unsafe generic_handle_irq()
call") added the variables 'wake_work' and 'wake_status' to the
'tegra_pmc' structure but did not add the associated kerneldoc for these
new variables. Add the kerneldoc for these variables.

Fixes: e6d96073af68 ("soc/tegra: pmc: Fix unsafe generic_handle_irq() call")
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 drivers/soc/tegra/pmc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index b889c44f8fdd..6debaabdaa36 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -439,6 +439,8 @@ struct tegra_pmc_soc {
  *     cntrl register associated with each wake during system suspend.
  * @reboot_notifier: PMC reboot notifier handler
  * @syscore: syscore suspend/resume callbacks
+ * @wake_work: IRQ work handler for processing wake-up events.
+ * @wake_status: Status of wake-up events.
  */
 struct tegra_pmc {
 	struct device *dev;
-- 
2.43.0


^ permalink raw reply related

* [PATCH 02/10] soc/tegra: pmc: Correct function names in kerneldoc
From: Jon Hunter @ 2026-03-25 19:25 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-tegra, Jon Hunter
In-Reply-To: <20260325192601.239554-1-jonathanh@nvidia.com>

Commit 70f752ebb08c ("soc/tegra: pmc: Add PMC contextual functions")
added the functions devm_tegra_pmc_get() and
tegra_pmc_io_pad_power_enable(), but the names of the functions in the
associated kerneldoc is incorrect. Update the kerneldoc for these
functions to correct their names.

Fixes: 70f752ebb08c ("soc/tegra: pmc: Add PMC contextual functions")
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 drivers/soc/tegra/pmc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 8268a41c471a..b889c44f8fdd 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -1005,7 +1005,7 @@ static struct tegra_pmc *tegra_pmc_get(struct device *dev)
 }
 
 /**
- * tegra_pmc_get() - find the PMC for a given device
+ * devm_tegra_pmc_get() - find the PMC for a given device
  * @dev: device for which to find the PMC
  *
  * Returns a pointer to the PMC on success or an ERR_PTR()-encoded error code
@@ -1747,7 +1747,7 @@ static void tegra_io_pad_unprepare(struct tegra_pmc *pmc)
 }
 
 /**
- * tegra_io_pad_power_enable() - enable power to I/O pad
+ * tegra_pmc_io_pad_power_enable() - enable power to I/O pad
  * @pmc: power management controller
  * @id: Tegra I/O pad ID for which to enable power
  *
-- 
2.43.0


^ permalink raw reply related

* [PATCH 00/10] soc/tegra: pmc: Fixes and updates for Tegra264
From: Jon Hunter @ 2026-03-25 19:25 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-tegra, Jon Hunter

This includes some minor kerneldoc fixes and some updates for
Tegra264 to enable wake-up and IO pad support.

Jon Hunter (10):
  soc/tegra: pmc: Add kerneldoc for reboot notifier
  soc/tegra: pmc: Correct function names in kerneldoc
  soc/tegra: pmc: Add kerneldoc for wake-up variables
  soc/tegra: pmc: Remove unused AOWAKE definitions
  soc/tegra: pmc: Add support for SoC specific AOWAKE offsets
  soc/tegra: pmc: Add AOWAKE regs for Tegra264
  soc/tegra: pmc: Add Tegra264 wake events
  soc/tegra: pmc: Refactor IO pad voltage control
  soc/tegra: pmc: Rename has_impl_33v_pwr flag
  soc/tegra: pmc: Add IO pads for Tegra264

 drivers/soc/tegra/pmc.c | 662 +++++++++++++++++++++++++---------------
 1 file changed, 415 insertions(+), 247 deletions(-)

-- 
2.43.0


^ permalink raw reply

* [PATCH 01/10] soc/tegra: pmc: Add kerneldoc for reboot notifier
From: Jon Hunter @ 2026-03-25 19:25 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-tegra, Jon Hunter
In-Reply-To: <20260325192601.239554-1-jonathanh@nvidia.com>

Commit 48b7f802fb78 ("soc/tegra: pmc: Embed reboot notifier in PMC
context") added the reboot_notifier structure to the PMC SoC structure
but did not update the kerneldoc accordingly. Add this missing kerneldoc
description to fix this.

Fixes: 48b7f802fb78 ("soc/tegra: pmc: Embed reboot notifier in PMC context")
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 drivers/soc/tegra/pmc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index a1a2966512d1..8268a41c471a 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -437,6 +437,7 @@ struct tegra_pmc_soc {
  * @wake_sw_status_map: Bitmap to hold raw status of wakes without mask
  * @wake_cntrl_level_map: Bitmap to hold wake levels to be programmed in
  *     cntrl register associated with each wake during system suspend.
+ * @reboot_notifier: PMC reboot notifier handler
  * @syscore: syscore suspend/resume callbacks
  */
 struct tegra_pmc {
-- 
2.43.0


^ permalink raw reply related

* Re: (subset) [PATCH v3 00/14] ASoC: tegra: Add error logging for probe and callback failures
From: Mark Brown @ 2026-03-25 13:18 UTC (permalink / raw)
  To: Liam Girdwood, Thierry Reding, Jonathan Hunter, Sheetal
  Cc: Jaroslav Kysela, Takashi Iwai, Mohan Kumar, Kuninori Morimoto,
	linux-sound, linux-tegra, linux-kernel
In-Reply-To: <20260325101437.3059693-1-sheetal@nvidia.com>

On Wed, 25 Mar 2026 10:14:23 +0000, Sheetal wrote:
> ASoC: tegra: Add error logging for probe and callback failures
> 
> Log errors in probe and runtime error paths across Tegra audio drivers.
> Use dev_err_probe() in probe paths and dev_err() in runtime callbacks.
> Skip redundant logging where the underlying API already reports errors.
> 
> Changes in v3:
> - Split single patch into per-driver patch series for easier review
>   and incremental merging.
> - Drop dev_err() from tegra_ahub_put_value_enum() since the error path
>   is userspace-triggerable and would allow log spamming.
> - Drop dev_err() from tegra210_mixer_set_audio_cif() since the driver
>   advertises S8 format support but this function doesn't handle it,
>   creating a userspace-triggerable log spam path.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-7.1

Thanks!

[01/14] ASoC: tegra: Use dev_err_probe() in tegra186_asrc probe
        https://git.kernel.org/broonie/sound/c/884f3101d1ed
[02/14] ASoC: tegra: Use dev_err_probe() in tegra186_dspk probe
        https://git.kernel.org/broonie/sound/c/6205ca05227f
[04/14] ASoC: tegra: Add error logging in tegra210_adx driver
        https://git.kernel.org/broonie/sound/c/50e51b84a4b3
[05/14] ASoC: tegra: Use dev_err_probe() in tegra210_ahub probe
        https://git.kernel.org/broonie/sound/c/802d0d6c25b3
[06/14] ASoC: tegra: Add error logging in tegra210_amx driver
        https://git.kernel.org/broonie/sound/c/d310c08db2d8
[07/14] ASoC: tegra: Use dev_err_probe() in tegra210_dmic probe
        https://git.kernel.org/broonie/sound/c/ca069c3403ec
[08/14] ASoC: tegra: Add error logging in tegra210_i2s driver
        https://git.kernel.org/broonie/sound/c/67b7bcdd9798
[10/14] ASoC: tegra: Use dev_err_probe() in tegra210_mixer probe
        https://git.kernel.org/broonie/sound/c/3d027d4b93b9
[11/14] ASoC: tegra: Use dev_err_probe() in tegra210_mvc probe
        https://git.kernel.org/broonie/sound/c/f2067c1dba07
[12/14] ASoC: tegra: Use dev_err_probe() in tegra210_sfc probe
        https://git.kernel.org/broonie/sound/c/856ffd8f4aae
[13/14] ASoC: tegra: Use dev_err_probe() in tegra_asoc_machine probe
        https://git.kernel.org/broonie/sound/c/fa11e1cb2b77
[14/14] ASoC: tegra: Use dev_err_probe() in tegra_audio_graph_card probe
        https://git.kernel.org/broonie/sound/c/f7d9eb0291ef

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


^ permalink raw reply

* Re: [PATCH v3 2/9] dt-bindings: dma: nvidia,tegra186-gpc-dma: Make reset optional
From: Rob Herring (Arm) @ 2026-03-25 16:37 UTC (permalink / raw)
  To: Akhil R
  Cc: Vinod Koul, Laxman Dewangan, Thierry Reding, Conor Dooley,
	Philipp Zabel, Frank Li, Jonathan Hunter, dmaengine,
	Krzysztof Kozlowski, devicetree, linux-kernel, linux-tegra
In-Reply-To: <20260316171823.61800-3-akhilrajeev@nvidia.com>


On Mon, 16 Mar 2026 22:48:16 +0530, Akhil R wrote:
> On Tegra264, GPCDMA reset control is not exposed to Linux and is handled
> by the boot firmware.
> 
> Although the reset was not exposed in Tegra234 as well, the firmware
> supported a dummy reset which just returns success on reset without doing
> an actual reset. This is also not supported in Tegra264. Therefore mark
> 'reset' and 'reset-names' properties as required only for devices prior
> to Tegra264.
> 
> This also necessitates that the Tegra264 compatible be standalone and
> cannot have the fallback compatible of Tegra186. Since there is no
> functional impact, we keep reset as required for Tegra234 to avoid
> breaking the ABI.
> 
> Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
> ---
>  .../bindings/dma/nvidia,tegra186-gpc-dma.yaml | 25 +++++++++++++------
>  1 file changed, 18 insertions(+), 7 deletions(-)
> 

Acked-by: Rob Herring (Arm) <robh@kernel.org>


^ permalink raw reply

* Re: [PATCH v3 1/9] dt-bindings: dma: nvidia,tegra186-gpc-dma: Add iommu-map property
From: Rob Herring (Arm) @ 2026-03-25 16:35 UTC (permalink / raw)
  To: Akhil R
  Cc: devicetree, linux-kernel, Frank Li, Jonathan Hunter, Vinod Koul,
	Krzysztof Kozlowski, Conor Dooley, Laxman Dewangan, dmaengine,
	Thierry Reding, Philipp Zabel, linux-tegra
In-Reply-To: <20260316171823.61800-2-akhilrajeev@nvidia.com>


On Mon, 16 Mar 2026 22:48:15 +0530, Akhil R wrote:
> Add iommu-map property to specify separate stream IDs for each DMA
> channel. This enables each channel to be in its own IOMMU domain,
> keeping memory isolated from other devices sharing the same DMA
> controller.
> 
> Define the constraints such that if the channel and stream IDs are
> contiguous, a single entry can map all the channels. If the channels
> or stream IDs are non-contiguous, support multiple entries.
> 
> Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
> ---
>  .../devicetree/bindings/dma/nvidia,tegra186-gpc-dma.yaml | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 

Acked-by: Rob Herring (Arm) <robh@kernel.org>


^ permalink raw reply

* Re: [PATCH 03/10] i2c: sun6i-p2wi: Replace dev_err() with dev_err_probe() in probe function
From: Chen-Yu Tsai @ 2026-03-25 16:01 UTC (permalink / raw)
  To: Atharv Dubey
  Cc: Till Harbaum, Andi Shyti, Laxman Dewangan, Dmitry Osipenko,
	Thierry Reding, Jonathan Hunter, Jernej Skrabec, Samuel Holland,
	Pierre-Yves MORDRET, Alain Volmat, Maxime Coquelin,
	Alexandre Torgue, Patrice Chotard, Orson Zhai, Baolin Wang,
	Chunyan Zhang, Jean Delvare, linux-i2c, linux-kernel, linux-tegra,
	linux-arm-kernel, linux-sunxi, linux-stm32, Enrico Zanda
In-Reply-To: <20260324-deverr-v1-3-7e591cce33a3@gmail.com>

On Wed, Mar 25, 2026 at 2:27 AM Atharv Dubey <atharvd440@gmail.com> wrote:
>
> From: Enrico Zanda <e.zanda1@gmail.com>
>
> This simplifies the code while improving log.
>
> Signed-off-by: Enrico Zanda <e.zanda1@gmail.com>
> Signed-off-by: Atharv Dubey <atharvd440@gmail.com>
> ---
>  drivers/i2c/busses/i2c-sun6i-p2wi.c | 55 ++++++++++++++-----------------------
>  1 file changed, 20 insertions(+), 35 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-sun6i-p2wi.c b/drivers/i2c/busses/i2c-sun6i-p2wi.c
> index fb5280b8cf7f..dffbe776a195 100644
> --- a/drivers/i2c/busses/i2c-sun6i-p2wi.c
> +++ b/drivers/i2c/busses/i2c-sun6i-p2wi.c
> @@ -194,22 +194,16 @@ static int p2wi_probe(struct platform_device *pdev)
>         int ret;
>
>         of_property_read_u32(np, "clock-frequency", &clk_freq);
> -       if (clk_freq > P2WI_MAX_FREQ) {
> -               dev_err(dev,
> -                       "required clock-frequency (%u Hz) is too high (max = 6MHz)",
> -                       clk_freq);
> -               return -EINVAL;
> -       }
> +       if (clk_freq > P2WI_MAX_FREQ)
> +               return dev_err_probe(dev, -EINVAL,
> +                                    "required clock-frequency (%u Hz) is too high (max = 6MHz)",
> +                                    clk_freq);
>
> -       if (clk_freq == 0) {
> -               dev_err(dev, "clock-frequency is set to 0 in DT\n");
> -               return -EINVAL;
> -       }
> +       if (clk_freq == 0)
> +               return dev_err_probe(dev, -EINVAL, "clock-frequency is set to 0 in DT\n");
>
> -       if (of_get_child_count(np) > 1) {
> -               dev_err(dev, "P2WI only supports one target device\n");
> -               return -EINVAL;
> -       }
> +       if (of_get_child_count(np) > 1)
> +               return dev_err_probe(dev, -EINVAL, "P2WI only supports one target device\n");
>
>         p2wi = devm_kzalloc(dev, sizeof(struct p2wi), GFP_KERNEL);
>         if (!p2wi)
> @@ -226,11 +220,9 @@ static int p2wi_probe(struct platform_device *pdev)
>         childnp = of_get_next_available_child(np, NULL);
>         if (childnp) {
>                 ret = of_property_read_u32(childnp, "reg", &target_addr);
> -               if (ret) {
> -                       dev_err(dev, "invalid target address on node %pOF\n",
> -                               childnp);
> -                       return -EINVAL;
> -               }
> +               if (ret)
> +                       return dev_err_probe(dev, -EINVAL,
> +                                            "invalid target address on node %pOF\n", childnp);
>
>                 p2wi->target_addr = target_addr;
>         }
> @@ -245,26 +237,20 @@ static int p2wi_probe(struct platform_device *pdev)
>                 return irq;
>
>         p2wi->clk = devm_clk_get_enabled(dev, NULL);
> -       if (IS_ERR(p2wi->clk)) {
> -               ret = PTR_ERR(p2wi->clk);
> -               dev_err(dev, "failed to enable clk: %d\n", ret);
> -               return ret;
> -       }
> +       if (IS_ERR(p2wi->clk))
> +               return dev_err_probe(dev, PTR_ERR(p2wi->clk),
> +                                    "failed to enable clk\n");
>
>         parent_clk_freq = clk_get_rate(p2wi->clk);
>
>         p2wi->rstc = devm_reset_control_get_exclusive(dev, NULL);
> -       if (IS_ERR(p2wi->rstc)) {
> -               dev_err(dev, "failed to retrieve reset controller: %pe\n",
> -                       p2wi->rstc);
> -               return PTR_ERR(p2wi->rstc);
> -       }
> +       if (IS_ERR(p2wi->rstc))
> +               return dev_err_probe(dev, PTR_ERR(p2wi->rstc),
> +                                    "failed to retrieve reset controller\n");
>
>         ret = reset_control_deassert(p2wi->rstc);
> -       if (ret) {
> -               dev_err(dev, "failed to deassert reset line: %d\n", ret);
> -               return ret;
> -       }
> +       if (ret)
> +               return dev_err_probe(dev, ret, "failed to deassert reset line\n");

You could also simplify this whole block with
devm_reset_control_get_exclusive_deasserted().

Either way,

Reviewed-by: Chen-Yu Tsai <wens@kernel.org>


>         init_completion(&p2wi->complete);
>         p2wi->adapter.dev.parent = dev;
> @@ -276,8 +262,7 @@ static int p2wi_probe(struct platform_device *pdev)
>
>         ret = devm_request_irq(dev, irq, p2wi_interrupt, 0, pdev->name, p2wi);
>         if (ret) {
> -               dev_err(dev, "can't register interrupt handler irq%d: %d\n",
> -                       irq, ret);
> +               dev_err_probe(dev, ret, "can't register interrupt handler irq%d\n", irq);
>                 goto err_reset_assert;
>         }
>
>
> --
> 2.43.0
>

^ permalink raw reply

* Re: [PATCH v2] soc/tegra: pmc: Add PMC support for Tegra410
From: Jon Hunter @ 2026-03-25 15:45 UTC (permalink / raw)
  To: Kartik Rajput, thierry.reding, jirislaby, pshete, chleroy,
	linux-tegra, linux-kernel
In-Reply-To: <20260324082847.550771-1-kkartik@nvidia.com>


On 24/03/2026 08:28, Kartik Rajput wrote:
> Tegra410 uses PMC driver only to retrieve system reset reason using PMC
> sysfs. Tegra410 uses ACPI to probe PMC, unlike device-tree boot it does
> not use the early initialisation sequence.
> 
> Add PMC support for Tegra410, which uses the PMC driver to retrieve
> the system reset reason via PMC sysfs.
> 
> Signed-off-by: Kartik Rajput <kkartik@nvidia.com>
> ---
> Changes in v2:
> 	* Updated commit message.
> ---
>   drivers/soc/tegra/pmc.c | 128 ++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 128 insertions(+)
> 
> diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
> index a1a2966512d1..f17dcfd0aeae 100644
> --- a/drivers/soc/tegra/pmc.c
> +++ b/drivers/soc/tegra/pmc.c
> @@ -11,6 +11,7 @@
>   
>   #define pr_fmt(fmt) "tegra-pmc: " fmt
>   
> +#include <linux/acpi.h>
>   #include <linux/arm-smccc.h>
>   #include <linux/clk.h>
>   #include <linux/clk-provider.h>
> @@ -3095,12 +3096,30 @@ static void tegra_pmc_reset_suspend_mode(void *data)
>   	pmc->suspend_mode = TEGRA_SUSPEND_NOT_READY;
>   }
>   
> +static int tegra_pmc_acpi_probe(struct platform_device *pdev)
> +{
> +	pmc->soc = device_get_match_data(&pdev->dev);
> +	pmc->dev = &pdev->dev;
> +
> +	pmc->base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(pmc->base))
> +		return PTR_ERR(pmc->base);
> +
> +	tegra_pmc_reset_sysfs_init(pmc);
> +	platform_set_drvdata(pdev, pmc);
> +
> +	return 0;
> +}
> +
>   static int tegra_pmc_probe(struct platform_device *pdev)
>   {
>   	void __iomem *base;
>   	struct resource *res;
>   	int err;
>   
> +	if (is_acpi_node(dev_fwnode(&pdev->dev)))
> +		return tegra_pmc_acpi_probe(pdev);
> +
>   	/*
>   	 * Early initialisation should have configured an initial
>   	 * register mapping and setup the soc data pointer. If these
> @@ -4615,6 +4634,108 @@ static const struct tegra_pmc_soc tegra264_pmc_soc = {
>   	.max_wake_vectors = 4,
>   };
>   
> +static const char * const tegra410_reset_sources[] = {
> +	"SYS_RESET_N",		/* 0x0 */
> +	"CSDC_RTC_XTAL",
> +	"VREFRO_POWER_BAD",
> +	"FMON_32K",
> +	"FMON_OSC",
> +	"POD_RTC",
> +	"POD_IO",
> +	"POD_PLUS_IO_SPLL",
> +	"POD_PLUS_IO_VMON",	/* 0x8 */
> +	"POD_PLUS_SOC",
> +	"VMON_PLUS_UV",
> +	"VMON_PLUS_OV",
> +	"FUSECRC_FAULT",
> +	"OSC_FAULT",
> +	"BPMP_BOOT_FAULT",
> +	"SCPM_BPMP_CORE_CLK",
> +	"SCPM_PSC_SE_CLK",	/* 0x10 */
> +	"VMON_SOC_MIN",
> +	"VMON_SOC_MAX",
> +	"NVJTAG_SEL_MONITOR",
> +	"L0_RST_REQ_N",
> +	"NV_THERM_FAULT",
> +	"PSC_SW",
> +	"POD_C2C_LPI_0",
> +	"POD_C2C_LPI_1",	/* 0x18 */
> +	"BPMP_FMON",
> +	"FMON_SPLL_OUT",
> +	"L1_RST_REQ_N",
> +	"OCP_RECOVERY",
> +	"AO_WDT_POR",
> +	"BPMP_WDT_POR",
> +	"RAS_WDT_POR",
> +	"TOP_0_WDT_POR",	/* 0x20 */
> +	"TOP_1_WDT_POR",
> +	"TOP_2_WDT_POR",
> +	"PSC_WDT_POR",
> +	"OOBHUB_WDT_POR",
> +	"MSS_SEQ_WDT_POR",
> +	"SW_MAIN",
> +	"L0L1_RST_OUT_N",
> +	"HSM",			/* 0x28 */
> +	"CSITE_SW",
> +	"AO_WDT_DBG",
> +	"BPMP_WDT_DBG",
> +	"RAS_WDT_DBG",
> +	"TOP_0_WDT_DBG",
> +	"TOP_1_WDT_DBG",
> +	"TOP_2_WDT_DBG",
> +	"PSC_WDT_DBG",		/* 0x30 */
> +	"TSC_0_WDT_DBG",
> +	"TSC_1_WDT_DBG",
> +	"OOBHUB_WDT_DBG",
> +	"MSS_SEQ_WDT_DBG",
> +	"L2_RST_REQ_N",
> +	"L2_RST_OUT_N",
> +	"SC7"
> +};
> +
> +static const struct tegra_pmc_regs tegra410_pmc_regs = {
> +	.rst_status = 0x8,
> +	.rst_source_shift = 0x2,
> +	.rst_source_mask = 0xfc,
> +	.rst_level_shift = 0x0,
> +	.rst_level_mask = 0x3,
> +};
> +
> +static const struct tegra_pmc_soc tegra410_pmc_soc = {
> +	.supports_core_domain = false,

Not needed since there are no powergates

> +	.num_powergates = 0,
> +	.powergates = NULL,
> +	.num_cpu_powergates = 0,
> +	.cpu_powergates = NULL,
> +	.has_tsense_reset = false,

Not needed as you have a different probe function.

> +	.has_gpu_clamps = false,

It should not be necessary to explicitly set this because this is only 
used if there are powergates.

> +	.needs_mbist_war = false,

Same with this.

> +	.has_impl_33v_pwr = false,

This is only needed for if you have IO pads.

> +	.maybe_tz_only = false,

Only used in early init and so also not needed.

> +	.num_io_pads = 0,
> +	.io_pads = NULL,
> +	.num_pin_descs = 0,
> +	.pin_descs = NULL,
> +	.regs = &tegra410_pmc_regs,
> +	.init = NULL,
> +	.setup_irq_polarity = NULL,
> +	.set_wake_filters = NULL,
> +	.irq_set_wake = NULL,
> +	.irq_set_type = NULL,
> +	.reset_sources = tegra410_reset_sources,
> +	.num_reset_sources = ARRAY_SIZE(tegra410_reset_sources),
> +	.reset_levels = tegra186_reset_levels,
> +	.num_reset_levels = ARRAY_SIZE(tegra186_reset_levels),
> +	.num_wake_events = 0,
> +	.wake_events = NULL,
> +	.max_wake_events = 0,
> +	.max_wake_vectors = 0,
> +	.pmc_clks_data = NULL,
> +	.num_pmc_clks = 0,
> +	.has_blink_output = false,

Not needed as there are no clocks.

> +	.has_single_mmio_aperture = false,

Not needed as you have a ACPI specific probe function.

In general, I think that we should only init things here and need to be 
explicitly initialised.

Jon

-- 
nvpublic


^ permalink raw reply

* Re: [PATCH V3 2/3] dt-bindings: net: Fix Tegra234 MGBE PTP clock
From: Jon Hunter @ 2026-03-25 14:26 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Andrew Lunn, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Thierry Reding
  Cc: netdev, devicetree, linux-tegra
In-Reply-To: <5a0d431e-785c-4aef-8282-2a921865bb9e@kernel.org>


On 25/03/2026 14:09, Krzysztof Kozlowski wrote:
> On 25/03/2026 15:07, Krzysztof Kozlowski wrote:
>> On 25/03/2026 14:58, Jon Hunter wrote:
>>> The PTP clock for the Tegra234 MGBE device is incorrectly named
>>> 'ptp-ref' and should be 'ptp_ref'. This is causing the following
>>> warning to be observed on Tegra234 platforms that use this device:
> 
>                             ^^^^^^^^^^^^^ Tegra234 (see further)
>>>
>>>   ERR KERN tegra-mgbe 6800000.ethernet eth0: Invalid PTP clock rate
>>>   WARNING KERN tegra-mgbe 6800000.ethernet eth0: PTP init failed
>>>
>>> Although this constitutes an ABI breakage in the binding for this
>>> device, PTP support has clearly never worked and so fix this now
>>> so we can correct the device-tree for this device. Note that the
>>
>> I don't understand that explanation.
>>
>> Driver dwmac-tegra.c: ptp-ref
>> Binding: ptp-ref
>> DTS: ptp-ref
>>
>> but you say that nothing was working correctly?
>>
>> Judging by these three - driver+binding+dts - obvious fix is no fix
>> because everything was fine, so please clarify the exact problem.
> 
> Correction - I missed in grep - there are ptp_ref users: tegra186 and
> tegra194, but how tegra234 could not work if it has correctly in DTS
> ptp-ref?

The problem lies in 
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c which uses the 
name 'ptp_ref' which does not match 'ptp-ref'. This is where the warning 
is coming from. So basic ethernet does work, but stmmac_platform.c 
driver is complaining that the PTP clock is not found.

Yes Tegra186 and Tegra194 are not impacted by this, only Tegra234.

Jon

-- 
nvpublic


^ permalink raw reply

* Re: [PATCH v2 1/7] dt-bindings: pwm: Document Tegra194 and Tegra264 controllers
From: Thierry Reding @ 2026-03-25 14:22 UTC (permalink / raw)
  To: Mikko Perttunen
  Cc: Thierry Reding, Uwe Kleine-König, Jonathan Hunter,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-pwm,
	linux-tegra, linux-kernel, devicetree, Thierry Reding
In-Reply-To: <20260325-t264-pwm-v2-1-998d885984b3@nvidia.com>

[-- Attachment #1: Type: text/plain, Size: 2074 bytes --]

On Wed, Mar 25, 2026 at 07:16:59PM +0900, Mikko Perttunen wrote:
> From: Thierry Reding <treding@nvidia.com>
> 
> The PWM controller found on Tegra264 is largely compatible with the one
> on prior generations, but it comes with some extra features, hence a new
> compatible string is needed.
> 
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
> ---
>  Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.yaml b/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.yaml
> index 41cea4979132..15706d2a808d 100644
> --- a/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.yaml
> +++ b/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.yaml
> @@ -16,6 +16,8 @@ properties:
>        - enum:
>            - nvidia,tegra20-pwm
>            - nvidia,tegra186-pwm
> +          - nvidia,tegra194-pwm
> +          - nvidia,tegra264-pwm

I think this was lost during the earlier conversation we had on the
split of these patches. Krzysztof had pointed out that tegra194-pwm is
now a duplicate entry. I don't know exactly how it ended up like this,
but I'm pretty sure what I meant was:

	- items:
	    - const: tegra264-pwm
	    - const: tegra194-pwm

This mirrors the fact that this is in fact backwards-compatible with
Tegra194 but also has additional features that we need the Tegra264
compatible string for.

Krzysztof also requested that we drop the latter part of, or reword, the
commit message because we always want the compatible string to be added,
regardless of backwards-compatibility, etc.

So I think maybe something like this would be better for the commit
message:

  The PWM controller found on Tegra264 is largely compatible with the one
  on prior generations, but it comes with some extra features. The new
  Tegra264-specific compatible string can be used to distinguish between
  the feature sets.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox