2024-03-26 22:30:13

by Prabhakar

[permalink] [raw]
Subject: [RFC PATCH 00/13] Add PFC support for Renesas RZ/V2H(P) SoC

From: Lad Prabhakar <[email protected]>

Hi All,

This patch series aims to add PFC (Pin Function Controller) support for
Renesas RZ/V2H(P) SoC. The PFC block on RZ/V2H(P) is almost similar to
one found on the RZ/G2L family with couple of differences. To able to
re-use the use the existing driver for RZ/V2H(P) SoC function pointers
are introduced based on the SoC changes.

Sending this patch series as an RFC mainly as we are introducing a
SoC specific 'renesas-rzv2h,output-impedance' property to configure
the output impedance on the pins. Drive strength setting on RZ/V2H(P)
depends on the different power rails which are coming out from the PMIC
(connected via i2c). These power rails (required for drive strength) can
be 1.2/1.8/3.3V. Pin are grouped into 4 groups,

Group1: Impedance
- 150/75/38/25 ohms (at 3.3 V)
- 130/65/33/22 ohms (at 1.8 V)

Group2: Impedance
- 50/40/33/25 ohms (at 1.8 V)

Group3: Impedance
- 150/75/37.5/25 ohms (at 3.3 V)
- 130/65/33/22 ohms (at 1.8 V)

Group4: Impedance
- 110/55/30/20 ohms (at 1.8 V)
- 150/75/38/25 ohms (at 1.2 V)

The existing property 'output-impedance-ohms' cannot be used to specify
the output impedance setting on the pin mainly because,
1] The regulator information will not be available very earlier in boot process
2] The power rails info will be coming from the PMIC connected to I2C chip, as
i2c will also require configuring the PFC there will be an interdependence
of this two nodes.
3] We cannot use 'power-source' property for each pin as DTB's dont use up all
the pins on SoC and when dumping the pinconf-pins from debugfs we wont be
able to print the output-impedance of pins which are unused.

Due to above cons 'renesas-rzv2h,output-impedance' property is introduced where
it allows user to specify values [ x1 x2 x4 x6 ] which internally configures
the IOLH bits to value [ 0 1 2 3 ] respectively, and does not depend on the
actual voltage setting.

Cheers,
Prabhakar

Lad Prabhakar (13):
dt-bindings: pinctrl: renesas,rzg2l-pinctrl: Remove the check from the
object
dt-bindings: pinctrl: renesas: Document RZ/V2H(P) SoC
pinctrl: renesas: pinctrl-rzg2l: Remove extra space in function
parameter
pinctrl: renesas: pinctrl-rzg2l: Allow more bits for pin configuration
pinctrl: renesas: pinctrl-rzg2l: Allow parsing of variable
configuration for all architectures
pinctrl: renesas: pinctrl-rzg2l: Make cfg to u64 in struct
rzg2l_variable_pin_cfg
pinctrl: renesas: pinctrl-rzg2l: Validate power registers for SD and
ETH
pinctrl: renesas: pinctrl-rzg2l: Add function pointers for writing to
PFC
pinctrl: renesas: pinctrl-rzg2l: Add function pointer for writing to
PMC register
pinctrl: renesas: pinctrl-rzg2l: Add function pointers for
reading/writing OEN register
pinctrl: renesas: pinctrl-rzg2l: Pass pincontrol device pointer to
pinconf_generic_parse_dt_config()
pinctrl: renesas: pinctrl-rzg2l: Add support to pass custom params
pinctrl: renesas: pinctrl-rzg2l: Add support for RZ/V2H SoC

.../pinctrl/renesas,rzg2l-pinctrl.yaml | 37 +-
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 566 +++++++++++++++++-
2 files changed, 560 insertions(+), 43 deletions(-)

--
2.34.1



2024-03-26 22:30:26

by Prabhakar

[permalink] [raw]
Subject: [RFC PATCH 01/13] dt-bindings: pinctrl: renesas,rzg2l-pinctrl: Remove the check from the object

From: Lad Prabhakar <[email protected]>

Drop the bogus check from object as this didn't really add restriction check.

Signed-off-by: Lad Prabhakar <[email protected]>
---
.../bindings/pinctrl/renesas,rzg2l-pinctrl.yaml | 15 ---------------
1 file changed, 15 deletions(-)

diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml
index 4d5a957fa232..881e992adca3 100644
--- a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml
@@ -79,21 +79,6 @@ additionalProperties:
- $ref: pincfg-node.yaml#
- $ref: pinmux-node.yaml#

- - if:
- properties:
- compatible:
- contains:
- enum:
- - renesas,r9a08g045-pinctrl
- then:
- properties:
- drive-strength: false
- output-impedance-ohms: false
- slew-rate: false
- else:
- properties:
- drive-strength-microamp: false
-
description:
Pin controller client devices use pin configuration subnodes (children
and grandchildren) for desired pin configuration.
--
2.34.1


2024-03-26 22:30:49

by Prabhakar

[permalink] [raw]
Subject: [RFC PATCH 02/13] dt-bindings: pinctrl: renesas: Document RZ/V2H(P) SoC

From: Lad Prabhakar <[email protected]>

Add documentation for the pin controller found on the Renesas RZ/V2H(P)
(R9A09G057) SoC. Compared to RZ/G2L family of SoCs there are slight
differences on the RZ/V2H(P) SoC for pinmuxing.

Also add 'renesas-rzv2h,output-impedance' property. Drive strength
setting on RZ/V2H(P) depends on the different power rails which are
coming out from the PMIC (connected via i2c). These power rails
(required for drive strength) can be 1.2/1.8/3.3V.

Pin are grouped into 4 groups,

Group1: Impedance
- 150/75/38/25 ohms (at 3.3 V)
- 130/65/33/22 ohms (at 1.8 V)

Group2: Impedance
- 50/40/33/25 ohms (at 1.8 V)

Group3: Impedance
- 150/75/37.5/25 ohms (at 3.3 V)
- 130/65/33/22 ohms (at 1.8 V)

Group4: Impedance
- 110/55/30/20 ohms (at 1.8 V)
- 150/75/38/25 ohms (at 1.2 V)

'renesas-rzv2h,output-impedance' property as documented which can be
[1, 2, 4, 6] indicates x Value strength.

As the power rail information cannot be available very early in the
boot process as 'renesas-rzv2h,output-impedance' property is added
instead of reusing output-impedance-ohms property.

Signed-off-by: Lad Prabhakar <[email protected]>
---
.../pinctrl/renesas,rzg2l-pinctrl.yaml | 22 +++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml
index 881e992adca3..77f4fc7f4a21 100644
--- a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml
@@ -26,6 +26,7 @@ properties:
- renesas,r9a07g043-pinctrl # RZ/G2UL{Type-1,Type-2} and RZ/Five
- renesas,r9a07g044-pinctrl # RZ/G2{L,LC}
- renesas,r9a08g045-pinctrl # RZ/G3S
+ - renesas,r9a09g057-pinctrl # RZ/V2H(P)

- items:
- enum:
@@ -66,10 +67,14 @@ properties:
maxItems: 1

resets:
- items:
- - description: GPIO_RSTN signal
- - description: GPIO_PORT_RESETN signal
- - description: GPIO_SPARE_RESETN signal
+ oneOf:
+ - items:
+ - description: GPIO_RSTN signal
+ - description: GPIO_PORT_RESETN signal
+ - description: GPIO_SPARE_RESETN signal
+ - items:
+ - description: PFC main reset
+ - description: Reset for the control register related to WDTUDFCA and WDTUDFFCM pins

additionalProperties:
anyOf:
@@ -111,6 +116,15 @@ additionalProperties:
output-high: true
output-low: true
line-name: true
+ renesas-rzv2h,output-impedance:
+ description: |
+ Output impedance for pins on RZ/V2H(P) SoC.
+ x1: Corresponds to 0 in IOLH register.
+ x2: Corresponds to 1 in IOLH register.
+ x4: Corresponds to 2 in IOLH register.
+ x6: Corresponds to 3 in IOLH register.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [1, 2, 4, 6]

- type: object
additionalProperties:
--
2.34.1


2024-03-26 22:31:19

by Prabhakar

[permalink] [raw]
Subject: [RFC PATCH 04/13] pinctrl: renesas: pinctrl-rzg2l: Allow more bits for pin configuration

From: Lad Prabhakar <[email protected]>

The pin configuration bits have been growing for every new SoCs being
added for the pinctrl-rzg2l driver which would mean updating the macros
every time for each new configuration. To avoid this allocate additional
bits for pin configuration by relocating the known fixed bits to the very
end of the configuration.

Signed-off-by: Lad Prabhakar <[email protected]>
---
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index fccac6d199cd..f2c71462de92 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -78,9 +78,9 @@
PIN_CFG_FILNUM | \
PIN_CFG_FILCLKSEL)

-#define PIN_CFG_PIN_MAP_MASK GENMASK_ULL(35, 28)
-#define PIN_CFG_PIN_REG_MASK GENMASK(27, 20)
-#define PIN_CFG_MASK GENMASK(19, 0)
+#define PIN_CFG_PIN_MAP_MASK GENMASK_ULL(62, 55)
+#define PIN_CFG_PIN_REG_MASK GENMASK(54, 47)
+#define PIN_CFG_MASK GENMASK(46, 0)

/*
* m indicates the bitmap of supported pins, a is the register index
@@ -102,8 +102,8 @@
* (b * 8) and f is the pin configuration capabilities supported.
*/
#define RZG2L_SINGLE_PIN BIT_ULL(63)
-#define RZG2L_SINGLE_PIN_INDEX_MASK GENMASK(30, 24)
-#define RZG2L_SINGLE_PIN_BITS_MASK GENMASK(22, 20)
+#define RZG2L_SINGLE_PIN_INDEX_MASK GENMASK(62, 56)
+#define RZG2L_SINGLE_PIN_BITS_MASK GENMASK(55, 53)

#define RZG2L_SINGLE_PIN_PACK(p, b, f) (RZG2L_SINGLE_PIN | \
FIELD_PREP_CONST(RZG2L_SINGLE_PIN_INDEX_MASK, (p)) | \
--
2.34.1


2024-03-26 22:31:30

by Prabhakar

[permalink] [raw]
Subject: [RFC PATCH 03/13] pinctrl: renesas: pinctrl-rzg2l: Remove extra space in function parameter

From: Lad Prabhakar <[email protected]>

Remove unnecessary space in rzg2l_pinctrl_pm_setup_pfc() function
parameter.

Signed-off-by: Lad Prabhakar <[email protected]>
---
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index eb5a8c654260..fccac6d199cd 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -2502,7 +2502,7 @@ static void rzg2l_pinctrl_pm_setup_dedicated_regs(struct rzg2l_pinctrl *pctrl, b
}
}

-static void rzg2l_pinctrl_pm_setup_pfc(struct rzg2l_pinctrl *pctrl)
+static void rzg2l_pinctrl_pm_setup_pfc(struct rzg2l_pinctrl *pctrl)
{
u32 nports = pctrl->data->n_port_pins / RZG2L_PINS_PER_PORT;
const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg;
--
2.34.1


2024-03-26 22:31:58

by Prabhakar

[permalink] [raw]
Subject: [RFC PATCH 06/13] pinctrl: renesas: pinctrl-rzg2l: Make cfg to u64 in struct rzg2l_variable_pin_cfg

From: Lad Prabhakar <[email protected]>

Now that we have updated the macro PIN_CFG_MASK to allow for the maximum
configuration bits, update the size of 'cfg' to 'u64' in the
'struct rzg2l_variable_pin_cfg'.

Signed-off-by: Lad Prabhakar <[email protected]>
---
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index da3a54b7b06a..348fdccaff72 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -241,7 +241,7 @@ struct rzg2l_dedicated_configs {
* @pin: port pin
*/
struct rzg2l_variable_pin_cfg {
- u32 cfg:20;
+ u64 cfg:46;
u32 port:5;
u32 pin:3;
};
--
2.34.1


2024-03-26 22:32:18

by Prabhakar

[permalink] [raw]
Subject: [RFC PATCH 07/13] pinctrl: renesas: pinctrl-rzg2l: Validate power registers for SD and ETH

From: Lad Prabhakar <[email protected]>

On RZ/V2H(P) SoC, the power registers for SD and ETH do not exist,
resulting in invalid register offsets. Ensure that the register offsets
are valid before any read/write operations are performed. If the power
registers are not available, both SD and ETH will be set to -EINVAL.

Signed-off-by: Lad Prabhakar <[email protected]>
---
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index 348fdccaff72..705372faaeff 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -184,8 +184,8 @@
*/
struct rzg2l_register_offsets {
u16 pwpr;
- u16 sd_ch;
- u16 eth_poc;
+ int sd_ch;
+ int eth_poc;
};

/**
@@ -2567,8 +2567,10 @@ static int rzg2l_pinctrl_suspend_noirq(struct device *dev)
rzg2l_pinctrl_pm_setup_dedicated_regs(pctrl, true);

for (u8 i = 0; i < 2; i++) {
- cache->sd_ch[i] = readb(pctrl->base + SD_CH(regs->sd_ch, i));
- cache->eth_poc[i] = readb(pctrl->base + ETH_POC(regs->eth_poc, i));
+ if (regs->sd_ch != -EINVAL)
+ cache->sd_ch[i] = readb(pctrl->base + SD_CH(regs->sd_ch, i));
+ if (regs->eth_poc != -EINVAL)
+ cache->eth_poc[i] = readb(pctrl->base + ETH_POC(regs->eth_poc, i));
}

cache->qspi = readb(pctrl->base + QSPI);
@@ -2599,8 +2601,10 @@ static int rzg2l_pinctrl_resume_noirq(struct device *dev)
writeb(cache->qspi, pctrl->base + QSPI);
writeb(cache->eth_mode, pctrl->base + ETH_MODE);
for (u8 i = 0; i < 2; i++) {
- writeb(cache->sd_ch[i], pctrl->base + SD_CH(regs->sd_ch, i));
- writeb(cache->eth_poc[i], pctrl->base + ETH_POC(regs->eth_poc, i));
+ if (regs->sd_ch != -EINVAL)
+ writeb(cache->sd_ch[i], pctrl->base + SD_CH(regs->sd_ch, i));
+ if (regs->eth_poc != -EINVAL)
+ writeb(cache->eth_poc[i], pctrl->base + ETH_POC(regs->eth_poc, i));
}

rzg2l_pinctrl_pm_setup_pfc(pctrl);
--
2.34.1


2024-03-26 22:32:36

by Prabhakar

[permalink] [raw]
Subject: [RFC PATCH 08/13] pinctrl: renesas: pinctrl-rzg2l: Add function pointers for writing to PFC

From: Lad Prabhakar <[email protected]>

On the RZ/G2L SoC, the PFCWE bit controls writing to PFC registers.
However, on the RZ/V2H(P) SoC, the PFCWE (REGWE_A on RZ/V2H) bit controls
writing to both PFC and PMC registers. To accommodate these differences
across SoC variants, introduce set_pfc_mode() and pm_set_pfc() function
pointers.

Signed-off-by: Lad Prabhakar <[email protected]>
---
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index 705372faaeff..4cdebdbd8a04 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -246,6 +246,8 @@ struct rzg2l_variable_pin_cfg {
u32 pin:3;
};

+struct rzg2l_pinctrl;
+
struct rzg2l_pinctrl_data {
const char * const *port_pins;
const u64 *port_pin_configs;
@@ -256,6 +258,8 @@ struct rzg2l_pinctrl_data {
const struct rzg2l_hwcfg *hwcfg;
const struct rzg2l_variable_pin_cfg *variable_pin_cfg;
unsigned int n_variable_pin_cfg;
+ void (*set_pfc_mode)(struct rzg2l_pinctrl *pctrl, u8 pin, u8 off, u8 func);
+ void (*pm_set_pfc)(struct rzg2l_pinctrl *pctrl);
};

/**
@@ -526,7 +530,7 @@ static int rzg2l_pinctrl_set_mux(struct pinctrl_dev *pctldev,
dev_dbg(pctrl->dev, "port:%u pin: %u off:%x PSEL:%u\n",
RZG2L_PIN_ID_TO_PORT(pins[i]), pin, off, psel_val[i] - hwcfg->func_base);

- rzg2l_pinctrl_set_pfc_mode(pctrl, pin, off, psel_val[i] - hwcfg->func_base);
+ pctrl->data->set_pfc_mode(pctrl, pin, off, psel_val[i] - hwcfg->func_base);
}

return 0;
@@ -2607,7 +2611,7 @@ static int rzg2l_pinctrl_resume_noirq(struct device *dev)
writeb(cache->eth_poc[i], pctrl->base + ETH_POC(regs->eth_poc, i));
}

- rzg2l_pinctrl_pm_setup_pfc(pctrl);
+ pctrl->data->pm_set_pfc(pctrl);
rzg2l_pinctrl_pm_setup_regs(pctrl, false);
rzg2l_pinctrl_pm_setup_dedicated_regs(pctrl, false);
rzg2l_gpio_irq_restore(pctrl);
@@ -2672,6 +2676,8 @@ static struct rzg2l_pinctrl_data r9a07g043_data = {
.variable_pin_cfg = r9a07g043f_variable_pin_cfg,
.n_variable_pin_cfg = ARRAY_SIZE(r9a07g043f_variable_pin_cfg),
#endif
+ .set_pfc_mode = &rzg2l_pinctrl_set_pfc_mode,
+ .pm_set_pfc = &rzg2l_pinctrl_pm_setup_pfc,
};

static struct rzg2l_pinctrl_data r9a07g044_data = {
@@ -2683,6 +2689,8 @@ static struct rzg2l_pinctrl_data r9a07g044_data = {
.n_dedicated_pins = ARRAY_SIZE(rzg2l_dedicated_pins.common) +
ARRAY_SIZE(rzg2l_dedicated_pins.rzg2l_pins),
.hwcfg = &rzg2l_hwcfg,
+ .set_pfc_mode = &rzg2l_pinctrl_set_pfc_mode,
+ .pm_set_pfc = &rzg2l_pinctrl_pm_setup_pfc,
};

static struct rzg2l_pinctrl_data r9a08g045_data = {
@@ -2693,6 +2701,8 @@ static struct rzg2l_pinctrl_data r9a08g045_data = {
.n_port_pins = ARRAY_SIZE(r9a08g045_gpio_configs) * RZG2L_PINS_PER_PORT,
.n_dedicated_pins = ARRAY_SIZE(rzg3s_dedicated_pins),
.hwcfg = &rzg3s_hwcfg,
+ .set_pfc_mode = &rzg2l_pinctrl_set_pfc_mode,
+ .pm_set_pfc = &rzg2l_pinctrl_pm_setup_pfc,
};

static const struct of_device_id rzg2l_pinctrl_of_table[] = {
--
2.34.1


2024-03-26 22:32:53

by Prabhakar

[permalink] [raw]
Subject: [RFC PATCH 09/13] pinctrl: renesas: pinctrl-rzg2l: Add function pointer for writing to PMC register

From: Lad Prabhakar <[email protected]>

This patch introduces a function pointer, pmc_writeb(), in the
struct rzg2l_pinctrl_data to facilitate writing to the PMC register. On
the RZ/V2H(P) SoC, unlocking the PWPR.REGWE_A bit before writing to PMC
registers is required, whereas this is not the case for the existing
RZ/G2L family. This addition enables the reuse of existing code for
RZ/V2H(P). Additionally, this patch populates this function pointer with
appropriate data for existing SoCs.

Note that this functionality is only handled in rzg2l_gpio_request(), as
PMC unlock/lock during PFC setup will be taken care of in the
set_pfc_mode/pm_set_pfc callbacks.

Signed-off-by: Lad Prabhakar <[email protected]>
---
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index 4cdebdbd8a04..3de97d5e198a 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -260,6 +260,7 @@ struct rzg2l_pinctrl_data {
unsigned int n_variable_pin_cfg;
void (*set_pfc_mode)(struct rzg2l_pinctrl *pctrl, u8 pin, u8 off, u8 func);
void (*pm_set_pfc)(struct rzg2l_pinctrl *pctrl);
+ void (*pmc_writeb)(struct rzg2l_pinctrl *pctrl, u8 val, void __iomem *addr);
};

/**
@@ -463,6 +464,11 @@ static const struct rzg2l_variable_pin_cfg r9a07g043f_variable_pin_cfg[] = {
};
#endif

+static void rzg2l_pmc_writeb(struct rzg2l_pinctrl *pctrl, u8 val, void __iomem *addr)
+{
+ writeb(val, addr);
+}
+
static void rzg2l_pinctrl_set_pfc_mode(struct rzg2l_pinctrl *pctrl,
u8 pin, u8 off, u8 func)
{
@@ -1413,7 +1419,7 @@ static int rzg2l_gpio_request(struct gpio_chip *chip, unsigned int offset)
/* Select GPIO mode in PMC Register */
reg8 = readb(pctrl->base + PMC(off));
reg8 &= ~BIT(bit);
- writeb(reg8, pctrl->base + PMC(off));
+ pctrl->data->pmc_writeb(pctrl, reg8, pctrl->base + PMC(off));

spin_unlock_irqrestore(&pctrl->lock, flags);

@@ -2678,6 +2684,7 @@ static struct rzg2l_pinctrl_data r9a07g043_data = {
#endif
.set_pfc_mode = &rzg2l_pinctrl_set_pfc_mode,
.pm_set_pfc = &rzg2l_pinctrl_pm_setup_pfc,
+ .pmc_writeb = &rzg2l_pmc_writeb,
};

static struct rzg2l_pinctrl_data r9a07g044_data = {
@@ -2691,6 +2698,7 @@ static struct rzg2l_pinctrl_data r9a07g044_data = {
.hwcfg = &rzg2l_hwcfg,
.set_pfc_mode = &rzg2l_pinctrl_set_pfc_mode,
.pm_set_pfc = &rzg2l_pinctrl_pm_setup_pfc,
+ .pmc_writeb = &rzg2l_pmc_writeb,
};

static struct rzg2l_pinctrl_data r9a08g045_data = {
@@ -2703,6 +2711,7 @@ static struct rzg2l_pinctrl_data r9a08g045_data = {
.hwcfg = &rzg3s_hwcfg,
.set_pfc_mode = &rzg2l_pinctrl_set_pfc_mode,
.pm_set_pfc = &rzg2l_pinctrl_pm_setup_pfc,
+ .pmc_writeb = &rzg2l_pmc_writeb,
};

static const struct of_device_id rzg2l_pinctrl_of_table[] = {
--
2.34.1


2024-03-26 22:33:41

by Prabhakar

[permalink] [raw]
Subject: [RFC PATCH 11/13] pinctrl: renesas: pinctrl-rzg2l: Pass pincontrol device pointer to pinconf_generic_parse_dt_config()

From: Lad Prabhakar <[email protected]>

Pass pincontrol device pointer to pinconf_generic_parse_dt_config() in
prepration for passing custom params.

Signed-off-by: Lad Prabhakar <[email protected]>
---
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index 9bc110b00cbb..d64a441b4f55 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -611,7 +611,7 @@ static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev,
return -EINVAL;
}

- ret = pinconf_generic_parse_dt_config(np, NULL, &configs, &num_configs);
+ ret = pinconf_generic_parse_dt_config(np, pctldev, &configs, &num_configs);
if (ret < 0)
return ret;

--
2.34.1


2024-03-26 22:33:45

by Prabhakar

[permalink] [raw]
Subject: [RFC PATCH 05/13] pinctrl: renesas: pinctrl-rzg2l: Allow parsing of variable configuration for all architectures

From: Lad Prabhakar <[email protected]>

Enable parsing of variable configuration for all architectures. This patch
is in preparation for adding support for the RZ/V2H SoC, which utilizes the
ARM64 architecture and features port pins with variable configuration.

Signed-off-by: Lad Prabhakar <[email protected]>
---
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index f2c71462de92..da3a54b7b06a 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -322,7 +322,6 @@ struct rzg2l_pinctrl {

static const u16 available_ps[] = { 1800, 2500, 3300 };

-#ifdef CONFIG_RISCV
static u64 rzg2l_pinctrl_get_variable_pin_cfg(struct rzg2l_pinctrl *pctrl,
u64 pincfg,
unsigned int port,
@@ -339,6 +338,7 @@ static u64 rzg2l_pinctrl_get_variable_pin_cfg(struct rzg2l_pinctrl *pctrl,
return 0;
}

+#ifdef CONFIG_RISCV
static const struct rzg2l_variable_pin_cfg r9a07g043f_variable_pin_cfg[] = {
{
.port = 20,
@@ -2285,13 +2285,11 @@ static int rzg2l_pinctrl_register(struct rzg2l_pinctrl *pctrl)
if (i && !(i % RZG2L_PINS_PER_PORT))
j++;
pin_data[i] = pctrl->data->port_pin_configs[j];
-#ifdef CONFIG_RISCV
if (pin_data[i] & PIN_CFG_VARIABLE)
pin_data[i] = rzg2l_pinctrl_get_variable_pin_cfg(pctrl,
pin_data[i],
j,
i % RZG2L_PINS_PER_PORT);
-#endif
pins[i].drv_data = &pin_data[i];
}

--
2.34.1


2024-03-26 22:36:19

by Prabhakar

[permalink] [raw]
Subject: [RFC PATCH 10/13] pinctrl: renesas: pinctrl-rzg2l: Add function pointers for reading/writing OEN register

From: Lad Prabhakar <[email protected]>

This patch introduces function pointers, read_oen() and write_oen(), in the
struct rzg2l_pinctrl_data to facilitate reading and writing to the PFC_OEN
register. On the RZ/V2H SoC, unlocking the PWPR.REGWE_B bit before writing
to the PFC_OEN register is necessary, and the PFC_OEN register has more
bits compared to the RZ/G2L family. To handle these differences between
RZ/G2L and RZ/V2H and to reuse the existing code for RZ/V2H, these function
pointers are introduced.

Additionally, this patch populates these function pointers with appropriate
data for existing SoCs.

Signed-off-by: Lad Prabhakar <[email protected]>
---
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index 3de97d5e198a..9bc110b00cbb 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -261,6 +261,8 @@ struct rzg2l_pinctrl_data {
void (*set_pfc_mode)(struct rzg2l_pinctrl *pctrl, u8 pin, u8 off, u8 func);
void (*pm_set_pfc)(struct rzg2l_pinctrl *pctrl);
void (*pmc_writeb)(struct rzg2l_pinctrl *pctrl, u8 val, void __iomem *addr);
+ u32 (*read_oen)(struct rzg2l_pinctrl *pctrl, u32 caps, u32 offset, u8 pin);
+ int (*write_oen)(struct rzg2l_pinctrl *pctrl, u32 caps, u32 offset, u8 pin, u8 oen);
};

/**
@@ -1120,7 +1122,7 @@ static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *pctldev,
break;

case PIN_CONFIG_OUTPUT_ENABLE:
- arg = rzg2l_read_oen(pctrl, cfg, _pin, bit);
+ arg = pctrl->data->read_oen(pctrl, cfg, _pin, bit);
if (!arg)
return -EINVAL;
break;
@@ -1228,7 +1230,7 @@ static int rzg2l_pinctrl_pinconf_set(struct pinctrl_dev *pctldev,

case PIN_CONFIG_OUTPUT_ENABLE:
arg = pinconf_to_config_argument(_configs[i]);
- ret = rzg2l_write_oen(pctrl, cfg, _pin, bit, !!arg);
+ ret = pctrl->data->write_oen(pctrl, cfg, _pin, bit, !!arg);
if (ret)
return ret;
break;
@@ -2685,6 +2687,8 @@ static struct rzg2l_pinctrl_data r9a07g043_data = {
.set_pfc_mode = &rzg2l_pinctrl_set_pfc_mode,
.pm_set_pfc = &rzg2l_pinctrl_pm_setup_pfc,
.pmc_writeb = &rzg2l_pmc_writeb,
+ .read_oen = &rzg2l_read_oen,
+ .write_oen = &rzg2l_write_oen,
};

static struct rzg2l_pinctrl_data r9a07g044_data = {
@@ -2699,6 +2703,8 @@ static struct rzg2l_pinctrl_data r9a07g044_data = {
.set_pfc_mode = &rzg2l_pinctrl_set_pfc_mode,
.pm_set_pfc = &rzg2l_pinctrl_pm_setup_pfc,
.pmc_writeb = &rzg2l_pmc_writeb,
+ .read_oen = &rzg2l_read_oen,
+ .write_oen = &rzg2l_write_oen,
};

static struct rzg2l_pinctrl_data r9a08g045_data = {
@@ -2712,6 +2718,8 @@ static struct rzg2l_pinctrl_data r9a08g045_data = {
.set_pfc_mode = &rzg2l_pinctrl_set_pfc_mode,
.pm_set_pfc = &rzg2l_pinctrl_pm_setup_pfc,
.pmc_writeb = &rzg2l_pmc_writeb,
+ .read_oen = &rzg2l_read_oen,
+ .write_oen = &rzg2l_write_oen,
};

static const struct of_device_id rzg2l_pinctrl_of_table[] = {
--
2.34.1


2024-03-26 22:37:20

by Prabhakar

[permalink] [raw]
Subject: [RFC PATCH 12/13] pinctrl: renesas: pinctrl-rzg2l: Add support to pass custom params

From: Lad Prabhakar <[email protected]>

In prepration for passing custom params for RZ/V2H(P) SoC assign the
custom params that is being passed of struct rzg2l_pinctrl_data.

Signed-off-by: Lad Prabhakar <[email protected]>
---
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index d64a441b4f55..6f0c85bb97a8 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -258,6 +258,9 @@ struct rzg2l_pinctrl_data {
const struct rzg2l_hwcfg *hwcfg;
const struct rzg2l_variable_pin_cfg *variable_pin_cfg;
unsigned int n_variable_pin_cfg;
+ unsigned int num_custom_params;
+ const struct pinconf_generic_params *custom_params;
+ const struct pin_config_item *custom_conf_items;
void (*set_pfc_mode)(struct rzg2l_pinctrl *pctrl, u8 pin, u8 off, u8 func);
void (*pm_set_pfc)(struct rzg2l_pinctrl *pctrl);
void (*pmc_writeb)(struct rzg2l_pinctrl *pctrl, u8 val, void __iomem *addr);
@@ -2278,6 +2281,13 @@ static int rzg2l_pinctrl_register(struct rzg2l_pinctrl *pctrl)
pctrl->desc.pmxops = &rzg2l_pinctrl_pmxops;
pctrl->desc.confops = &rzg2l_pinctrl_confops;
pctrl->desc.owner = THIS_MODULE;
+ if (pctrl->data->num_custom_params) {
+ pctrl->desc.num_custom_params = pctrl->data->num_custom_params;
+ pctrl->desc.custom_params = pctrl->data->custom_params;
+#ifdef CONFIG_DEBUG_FS
+ pctrl->desc.custom_conf_items = pctrl->data->custom_conf_items;
+#endif
+ }

pins = devm_kcalloc(pctrl->dev, pctrl->desc.npins, sizeof(*pins), GFP_KERNEL);
if (!pins)
--
2.34.1


2024-03-26 22:38:03

by Prabhakar

[permalink] [raw]
Subject: [RFC PATCH 13/13] pinctrl: renesas: pinctrl-rzg2l: Add support for RZ/V2H SoC

From: Lad Prabhakar <[email protected]>

Add pinctrl driver support for RZ/V2H(P) SoC.

Signed-off-by: Lad Prabhakar <[email protected]>
---
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 483 +++++++++++++++++++++++-
1 file changed, 481 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index 6f0c85bb97a8..716c11ca5a8f 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -59,6 +59,13 @@
#define PIN_CFG_OEN BIT(15)
#define PIN_CFG_VARIABLE BIT(16)
#define PIN_CFG_NOGPIO_INT BIT(17)
+#define PIN_CFG_OPEN_DRAIN BIT(18)
+#define PIN_CFG_SCHMIT_CTRL BIT(19)
+#define PIN_CFG_ELC BIT(20)
+#define PIN_CFG_IOLH_1 BIT(21)
+#define PIN_CFG_IOLH_2 BIT(22)
+#define PIN_CFG_IOLH_3 BIT(23)
+#define PIN_CFG_IOLH_4 BIT(24)

#define RZG2L_MPXED_COMMON_PIN_FUNCS(group) \
(PIN_CFG_IOLH_##group | \
@@ -70,6 +77,10 @@
#define RZG2L_MPXED_PIN_FUNCS (RZG2L_MPXED_COMMON_PIN_FUNCS(A) | \
PIN_CFG_SR)

+#define RZV2H_MPXED_PIN_FUNCS(group) (RZG2L_MPXED_COMMON_PIN_FUNCS(group) | \
+ PIN_CFG_OPEN_DRAIN | \
+ PIN_CFG_SR)
+
#define RZG3S_MPXED_PIN_FUNCS(group) (RZG2L_MPXED_COMMON_PIN_FUNCS(group) | \
PIN_CFG_SOFT_PS)

@@ -133,6 +144,8 @@

#define PWPR_B0WI BIT(7) /* Bit Write Disable */
#define PWPR_PFCWE BIT(6) /* PFC Register Write Enable */
+#define PWPR_REGWE_A BIT(6) /* PFC and PMC Register Write Enable */
+#define PWPR_REGWE_B BIT(5) /* OEN Register Write Enable */

#define PM_MASK 0x03
#define PFC_MASK 0x07
@@ -149,6 +162,19 @@
#define RZG2L_TINT_IRQ_START_INDEX 9
#define RZG2L_PACK_HWIRQ(t, i) (((t) << 16) | (i))

+/* Custom pinconf parameters */
+#define RENESAS_RZV2H_PIN_CONFIG_OUTPUT_IMPEDANCE (PIN_CONFIG_END + 1)
+
+static const struct pinconf_generic_params renesas_rzv2h_custom_bindings[] = {
+ { "renesas-rzv2h,output-impedance", RENESAS_RZV2H_PIN_CONFIG_OUTPUT_IMPEDANCE, 1 },
+};
+
+#ifdef CONFIG_DEBUG_FS
+static const struct pin_config_item renesas_rzv2h_conf_items[] = {
+ PCONFDUMP(RENESAS_RZV2H_PIN_CONFIG_OUTPUT_IMPEDANCE, "output-impedance", "x", true),
+};
+#endif
+
/* Read/write 8 bits register */
#define RZG2L_PCTRL_REG_ACCESS8(_read, _addr, _val) \
do { \
@@ -324,6 +350,8 @@ struct rzg2l_pinctrl {
spinlock_t lock; /* lock read/write registers */
struct mutex mutex; /* serialize adding groups and functions */

+ raw_spinlock_t pwpr_lock; /* serialize PWPR register access */
+
struct rzg2l_pinctrl_pin_settings *settings;
struct rzg2l_pinctrl_reg_cache *cache;
struct rzg2l_pinctrl_reg_cache *dedicated_cache;
@@ -348,6 +376,79 @@ static u64 rzg2l_pinctrl_get_variable_pin_cfg(struct rzg2l_pinctrl *pctrl,
return 0;
}

+static const struct rzg2l_variable_pin_cfg r9a09g057_variable_pin_cfg[] = {
+ {
+ .port = 9,
+ .pin = 0,
+ .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL,
+ },
+ {
+ .port = 9,
+ .pin = 1,
+ .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL,
+ },
+ {
+ .port = 9,
+ .pin = 2,
+ .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL,
+ },
+ {
+ .port = 9,
+ .pin = 3,
+ .cfg = RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL,
+ },
+ {
+ .port = 9,
+ .pin = 4,
+ .cfg = RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL,
+ },
+ {
+ .port = 9,
+ .pin = 5,
+ .cfg = RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL,
+ },
+ {
+ .port = 9,
+ .pin = 6,
+ .cfg = RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL,
+ },
+ {
+ .port = 9,
+ .pin = 7,
+ .cfg = RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL,
+ },
+ {
+ .port = 11,
+ .pin = 0,
+ .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL,
+ },
+ {
+ .port = 11,
+ .pin = 1,
+ .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL | PIN_CFG_IEN,
+ },
+ {
+ .port = 11,
+ .pin = 2,
+ .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL | PIN_CFG_IEN,
+ },
+ {
+ .port = 11,
+ .pin = 3,
+ .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL | PIN_CFG_IEN,
+ },
+ {
+ .port = 11,
+ .pin = 4,
+ .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL | PIN_CFG_IEN,
+ },
+ {
+ .port = 11,
+ .pin = 5,
+ .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL | PIN_CFG_IEN,
+ },
+};
+
#ifdef CONFIG_RISCV
static const struct rzg2l_variable_pin_cfg r9a07g043f_variable_pin_cfg[] = {
{
@@ -474,6 +575,19 @@ static void rzg2l_pmc_writeb(struct rzg2l_pinctrl *pctrl, u8 val, void __iomem *
writeb(val, addr);
}

+static void rzv2h_pmc_writeb(struct rzg2l_pinctrl *pctrl, u8 val, void __iomem *addr)
+{
+ const struct rzg2l_register_offsets *regs = &pctrl->data->hwcfg->regs;
+ u8 pwpr;
+
+ raw_spin_lock(&pctrl->pwpr_lock);
+ pwpr = readb(pctrl->base + regs->pwpr);
+ writeb(pwpr | PWPR_REGWE_A, pctrl->base + regs->pwpr);
+ writeb(val, addr);
+ writeb(pwpr & ~PWPR_REGWE_A, pctrl->base + regs->pwpr);
+ raw_spin_unlock(&pctrl->pwpr_lock);
+}
+
static void rzg2l_pinctrl_set_pfc_mode(struct rzg2l_pinctrl *pctrl,
u8 pin, u8 off, u8 func)
{
@@ -512,6 +626,47 @@ static void rzg2l_pinctrl_set_pfc_mode(struct rzg2l_pinctrl *pctrl,
spin_unlock_irqrestore(&pctrl->lock, flags);
};

+static void rzv2h_pinctrl_set_pfc_mode(struct rzg2l_pinctrl *pctrl,
+ u8 pin, u8 off, u8 func)
+{
+ const struct rzg2l_register_offsets *regs = &pctrl->data->hwcfg->regs;
+ unsigned long flags;
+ u32 reg;
+ u8 pwpr;
+
+ spin_lock_irqsave(&pctrl->lock, flags);
+
+ /* Set pin to 'Non-use (Hi-Z input protection)' */
+ reg = readw(pctrl->base + PM(off));
+ reg &= ~(PM_MASK << (pin * 2));
+ writew(reg, pctrl->base + PM(off));
+
+ /* Set the PWPR register to allow PFC and PMC register to write */
+ raw_spin_lock(&pctrl->pwpr_lock);
+ pwpr = readb(pctrl->base + regs->pwpr);
+ writeb(PWPR_PFCWE | pwpr, pctrl->base + regs->pwpr);
+
+ /* Temporarily switch to GPIO mode with PMC register */
+ reg = readb(pctrl->base + PMC(off));
+ writeb(reg & ~BIT(pin), pctrl->base + PMC(off));
+
+ /* Select Pin function mode with PFC register */
+ reg = readl(pctrl->base + PFC(off));
+ reg &= ~(PFC_MASK << (pin * 4));
+ writel(reg | (func << (pin * 4)), pctrl->base + PFC(off));
+
+ /* Switch to Peripheral pin function with PMC register */
+ reg = readb(pctrl->base + PMC(off));
+ writeb(reg | BIT(pin), pctrl->base + PMC(off));
+
+ /* Set the PWPR register to be write-protected */
+ pwpr = readb(pctrl->base + regs->pwpr);
+ writeb(pwpr & ~PWPR_PFCWE, pctrl->base + regs->pwpr);
+ raw_spin_unlock(&pctrl->pwpr_lock);
+
+ spin_unlock_irqrestore(&pctrl->lock, flags);
+};
+
static int rzg2l_pinctrl_set_mux(struct pinctrl_dev *pctldev,
unsigned int func_selector,
unsigned int group_selector)
@@ -1087,14 +1242,26 @@ static int rzg2l_write_oen(struct rzg2l_pinctrl *pctrl, u32 caps, u32 offset, u8
return 0;
}

+static u32 rzv2h_read_oen(struct rzg2l_pinctrl *pctrl, u32 caps, u32 offset, u8 pin)
+{
+ /* stub */
+ return 0;
+}
+
+static int rzv2h_write_oen(struct rzg2l_pinctrl *pctrl, u32 caps, u32 offset, u8 pin, u8 oen)
+{
+ /* stub */
+ return -EINVAL;
+}
+
static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *pctldev,
unsigned int _pin,
unsigned long *config)
{
struct rzg2l_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
- enum pin_config_param param = pinconf_to_config_param(*config);
const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg;
const struct pinctrl_pin_desc *pin = &pctrl->desc.pins[_pin];
+ u32 param = pinconf_to_config_param(*config);
u64 *pin_data = pin->drv_data;
unsigned int arg = 0;
u32 off, cfg;
@@ -1180,6 +1347,30 @@ static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *pctldev,
break;
}

+ case RENESAS_RZV2H_PIN_CONFIG_OUTPUT_IMPEDANCE: {
+ u8 val;
+
+ if (!(cfg & (PIN_CFG_IOLH_1 | PIN_CFG_IOLH_2 | PIN_CFG_IOLH_3 | PIN_CFG_IOLH_4)))
+ return -EINVAL;
+
+ val = rzg2l_read_pin_config(pctrl, IOLH(off), bit, IOLH_MASK);
+ switch (val) {
+ case 0:
+ arg = 1;
+ break;
+ case 1:
+ arg = 2;
+ break;
+ case 2:
+ arg = 4;
+ break;
+ default:
+ arg = 6;
+ break;
+ }
+ break;
+ }
+
default:
return -ENOTSUPP;
}
@@ -1199,9 +1390,9 @@ static int rzg2l_pinctrl_pinconf_set(struct pinctrl_dev *pctldev,
const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg;
struct rzg2l_pinctrl_pin_settings settings = pctrl->settings[_pin];
u64 *pin_data = pin->drv_data;
- enum pin_config_param param;
unsigned int i, arg, index;
u32 cfg, off;
+ u32 param;
int ret;
u8 bit;

@@ -1283,6 +1474,32 @@ static int rzg2l_pinctrl_pinconf_set(struct pinctrl_dev *pctldev,
rzg2l_rmw_pin_config(pctrl, IOLH(off), bit, IOLH_MASK, index);
break;

+ case RENESAS_RZV2H_PIN_CONFIG_OUTPUT_IMPEDANCE:
+ arg = pinconf_to_config_argument(_configs[i]);
+
+ if (!(cfg & (PIN_CFG_IOLH_1 | PIN_CFG_IOLH_2 |
+ PIN_CFG_IOLH_3 | PIN_CFG_IOLH_4)))
+ return -EINVAL;
+
+ switch (arg) {
+ case 1:
+ index = 0;
+ break;
+ case 2:
+ index = 1;
+ break;
+ case 4:
+ index = 2;
+ break;
+ case 6:
+ index = 3;
+ break;
+ default:
+ return -EINVAL;
+ }
+ rzg2l_rmw_pin_config(pctrl, IOLH(off), bit, IOLH_MASK, index);
+ break;
+
default:
return -EOPNOTSUPP;
}
@@ -1730,6 +1947,38 @@ static const u64 r9a08g045_gpio_configs[] = {
RZG2L_GPIO_PORT_PACK(6, 0x2a, RZG3S_MPXED_PIN_FUNCS(A)), /* P18 */
};

+static const char * const rzv2h_gpio_names[] = {
+ "P00", "P01", "P02", "P03", "P04", "P05", "P06", "P07",
+ "P10", "P11", "P12", "P13", "P14", "P15", "P16", "P17",
+ "P20", "P21", "P22", "P23", "P24", "P25", "P26", "P27",
+ "P30", "P31", "P32", "P33", "P34", "P35", "P36", "P37",
+ "P40", "P41", "P42", "P43", "P44", "P45", "P46", "P47",
+ "P50", "P51", "P52", "P53", "P54", "P55", "P56", "P57",
+ "P60", "P61", "P62", "P63", "P64", "P65", "P66", "P67",
+ "P70", "P71", "P72", "P73", "P74", "P75", "P76", "P77",
+ "P80", "P81", "P82", "P83", "P84", "P85", "P86", "P87",
+ "P90", "P91", "P92", "P93", "P94", "P95", "P96", "P97",
+ "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7",
+ "PB0", "PB1", "PB2", "PB3", "PB4", "PB5", "PB6", "PB7",
+};
+
+static const u64 r9a09g057_gpio_configs[] = {
+ RZG2L_GPIO_PORT_PACK(8, 0x20, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* P0 */
+ RZG2L_GPIO_PORT_PACK(6, 0x21, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* P1 */
+ RZG2L_GPIO_PORT_PACK(2, 0x22, RZV2H_MPXED_PIN_FUNCS(4)), /* P2 */
+ RZG2L_GPIO_PORT_PACK(8, 0x23, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* P3 */
+ RZG2L_GPIO_PORT_PACK(8, 0x24, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* P4 */
+ RZG2L_GPIO_PORT_PACK(8, 0x25, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* P5 */
+ RZG2L_GPIO_PORT_PACK(8, 0x26, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL |
+ PIN_CFG_ELC), /* P6 */
+ RZG2L_GPIO_PORT_PACK(8, 0x27, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* P7 */
+ RZG2L_GPIO_PORT_PACK(8, 0x28, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL |
+ PIN_CFG_ELC), /* P8 */
+ RZG2L_GPIO_PORT_PACK(8, 0x29, PIN_CFG_VARIABLE), /* P9 */
+ RZG2L_GPIO_PORT_PACK(8, 0x2a, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* PA */
+ RZG2L_GPIO_PORT_PACK(6, 0x2b, PIN_CFG_VARIABLE), /* PB */
+};
+
static const struct {
struct rzg2l_dedicated_configs common[35];
struct rzg2l_dedicated_configs rzg2l_pins[7];
@@ -1856,6 +2105,139 @@ static const struct rzg2l_dedicated_configs rzg3s_dedicated_pins[] = {
PIN_CFG_IO_VMC_SD1)) },
};

+static struct rzg2l_dedicated_configs rzv2h_dedicated_pins[] = {
+ { "NMI", RZG2L_SINGLE_PIN_PACK(0x1, 0, (PIN_CFG_FILONOFF | PIN_CFG_FILNUM |
+ PIN_CFG_FILCLKSEL)) },
+ { "TMS_SWDIO", RZG2L_SINGLE_PIN_PACK(0x3, 0, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
+ PIN_CFG_IEN)) },
+ { "TDO", RZG2L_SINGLE_PIN_PACK(0x3, 2, (PIN_CFG_IOLH_1 | PIN_CFG_SR)) },
+ { "WDTUDFCA", RZG2L_SINGLE_PIN_PACK(0x5, 0, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "WDTUDFCM", RZG2L_SINGLE_PIN_PACK(0x5, 1, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "SCIF_RXD", RZG2L_SINGLE_PIN_PACK(0x6, 0, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "SCIF_TXD", RZG2L_SINGLE_PIN_PACK(0x6, 1, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "XSPI0_CKP", RZG2L_SINGLE_PIN_PACK(0x7, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD | PIN_CFG_OEN)) },
+ { "XSPI0_CKN", RZG2L_SINGLE_PIN_PACK(0x7, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD | PIN_CFG_OEN)) },
+ { "XSPI0_CS0N", RZG2L_SINGLE_PIN_PACK(0x7, 2, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
+ PIN_CFG_PUPD | PIN_CFG_OEN)) },
+ { "XSPI0_DS", RZG2L_SINGLE_PIN_PACK(0x7, 3, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "XSPI0_RESET0N", RZG2L_SINGLE_PIN_PACK(0x7, 4, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
+ PIN_CFG_PUPD | PIN_CFG_OEN)) },
+ { "XSPI0_RSTO0N", RZG2L_SINGLE_PIN_PACK(0x7, 5, (PIN_CFG_PUPD)) },
+ { "XSPI0_INT0N", RZG2L_SINGLE_PIN_PACK(0x7, 6, (PIN_CFG_PUPD)) },
+ { "XSPI0_ECS0N", RZG2L_SINGLE_PIN_PACK(0x7, 7, (PIN_CFG_PUPD)) },
+ { "XSPI0_IO0", RZG2L_SINGLE_PIN_PACK(0x8, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "XSPI0_IO1", RZG2L_SINGLE_PIN_PACK(0x8, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "XSPI0_IO2", RZG2L_SINGLE_PIN_PACK(0x8, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "XSPI0_IO3", RZG2L_SINGLE_PIN_PACK(0x8, 3, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "XSPI0_IO4", RZG2L_SINGLE_PIN_PACK(0x8, 4, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "XSPI0_IO5", RZG2L_SINGLE_PIN_PACK(0x8, 5, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "XSPI0_IO6", RZG2L_SINGLE_PIN_PACK(0x8, 6, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "XSPI0_IO7", RZG2L_SINGLE_PIN_PACK(0x8, 7, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "SD0CLK", RZG2L_SINGLE_PIN_PACK(0x9, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR)) },
+ { "SD0CMD", RZG2L_SINGLE_PIN_PACK(0x9, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR)) },
+ { "SD0RSTN", RZG2L_SINGLE_PIN_PACK(0x9, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD0DAT0", RZG2L_SINGLE_PIN_PACK(0xa, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD0DAT1", RZG2L_SINGLE_PIN_PACK(0xa, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD0DAT2", RZG2L_SINGLE_PIN_PACK(0xa, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD0DAT3", RZG2L_SINGLE_PIN_PACK(0xa, 3, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD0DAT4", RZG2L_SINGLE_PIN_PACK(0xa, 4, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD0DAT5", RZG2L_SINGLE_PIN_PACK(0xa, 5, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD0DAT6", RZG2L_SINGLE_PIN_PACK(0xa, 6, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_IOLH_2 | PIN_CFG_PUPD)) },
+ { "SD0DAT7", RZG2L_SINGLE_PIN_PACK(0xa, 7, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD1_CLK", RZG2L_SINGLE_PIN_PACK(0xb, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR)) },
+ { "SD1_CMD", RZG2L_SINGLE_PIN_PACK(0xb, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD1_DAT0", RZG2L_SINGLE_PIN_PACK(0xc, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD1_DAT1", RZG2L_SINGLE_PIN_PACK(0xc, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD1_DAT2", RZG2L_SINGLE_PIN_PACK(0xc, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD1_DAT3", RZG2L_SINGLE_PIN_PACK(0xc, 3, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "PCIE0_RSTOUTB", RZG2L_SINGLE_PIN_PACK(0xe, 0, (PIN_CFG_IOLH_1 | PIN_CFG_SR)) },
+ { "PCIE1_RSTOUTB", RZG2L_SINGLE_PIN_PACK(0xe, 1, (PIN_CFG_IOLH_1 | PIN_CFG_SR)) },
+ { "ET0_MDIO", RZG2L_SINGLE_PIN_PACK(0xf, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "ET0_MDC", RZG2L_SINGLE_PIN_PACK(0xf, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET0_RXCTL_RXDV", RZG2L_SINGLE_PIN_PACK(0x10, 0, (PIN_CFG_PUPD)) },
+ { "ET0_TXCTL_TXEN", RZG2L_SINGLE_PIN_PACK(0x10, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET0_TXER", RZG2L_SINGLE_PIN_PACK(0x10, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET0_RXER", RZG2L_SINGLE_PIN_PACK(0x10, 3, (PIN_CFG_PUPD)) },
+ { "ET0_RXC_RXCLK", RZG2L_SINGLE_PIN_PACK(0x10, 4, (PIN_CFG_PUPD)) },
+ { "ET0_TXC_TXCLK", RZG2L_SINGLE_PIN_PACK(0x10, 5, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD | PIN_CFG_OEN)) },
+ { "ET0_CRS", RZG2L_SINGLE_PIN_PACK(0x10, 6, (PIN_CFG_PUPD)) },
+ { "ET0_COL", RZG2L_SINGLE_PIN_PACK(0x10, 7, (PIN_CFG_PUPD)) },
+ { "ET0_TXD0", RZG2L_SINGLE_PIN_PACK(0x11, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET0_TXD1", RZG2L_SINGLE_PIN_PACK(0x11, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET0_TXD2", RZG2L_SINGLE_PIN_PACK(0x11, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET0_TXD3", RZG2L_SINGLE_PIN_PACK(0x11, 3, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET0_RXD0", RZG2L_SINGLE_PIN_PACK(0x11, 4, (PIN_CFG_PUPD)) },
+ { "ET0_RXD1", RZG2L_SINGLE_PIN_PACK(0x11, 5, (PIN_CFG_PUPD)) },
+ { "ET0_RXD2", RZG2L_SINGLE_PIN_PACK(0x11, 6, (PIN_CFG_PUPD)) },
+ { "ET0_RXD3", RZG2L_SINGLE_PIN_PACK(0x11, 7, (PIN_CFG_PUPD)) },
+ { "ET1_MDIO", RZG2L_SINGLE_PIN_PACK(0x12, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_SR | PIN_CFG_IEN |
+ PIN_CFG_PUPD)) },
+ { "ET1_MDC", RZG2L_SINGLE_PIN_PACK(0x12, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET1_RXCTL_RXDV", RZG2L_SINGLE_PIN_PACK(0x13, 0, (PIN_CFG_PUPD)) },
+ { "ET1_TXCTL_TXEN", RZG2L_SINGLE_PIN_PACK(0x13, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET1_TXER", RZG2L_SINGLE_PIN_PACK(0x13, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET1_RXER", RZG2L_SINGLE_PIN_PACK(0x13, 3, (PIN_CFG_PUPD)) },
+ { "ET1_RXC_RXCLK", RZG2L_SINGLE_PIN_PACK(0x13, 4, (PIN_CFG_PUPD)) },
+ { "ET1_TXC_TXCLK", RZG2L_SINGLE_PIN_PACK(0x13, 5, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD | PIN_CFG_OEN)) },
+ { "ET1_CRS", RZG2L_SINGLE_PIN_PACK(0x13, 6, (PIN_CFG_PUPD)) },
+ { "ET1_COL", RZG2L_SINGLE_PIN_PACK(0x13, 7, (PIN_CFG_PUPD)) },
+ { "ET1_TXD0", RZG2L_SINGLE_PIN_PACK(0x14, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET1_TXD1", RZG2L_SINGLE_PIN_PACK(0x14, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET1_TXD2", RZG2L_SINGLE_PIN_PACK(0x14, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET1_TXD3", RZG2L_SINGLE_PIN_PACK(0x14, 3, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET1_RXD0", RZG2L_SINGLE_PIN_PACK(0x14, 4, (PIN_CFG_PUPD)) },
+ { "ET1_RXD1", RZG2L_SINGLE_PIN_PACK(0x14, 5, (PIN_CFG_PUPD)) },
+ { "ET1_RXD2", RZG2L_SINGLE_PIN_PACK(0x14, 6, (PIN_CFG_PUPD)) },
+ { "ET1_RXD3", RZG2L_SINGLE_PIN_PACK(0x14, 7, (PIN_CFG_PUPD)) },
+};
+
static int rzg2l_gpio_get_gpioint(unsigned int virq, struct rzg2l_pinctrl *pctrl)
{
const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[virq];
@@ -2380,6 +2762,9 @@ static int rzg2l_pinctrl_probe(struct platform_device *pdev)
BUILD_BUG_ON(ARRAY_SIZE(r9a08g045_gpio_configs) * RZG2L_PINS_PER_PORT >
ARRAY_SIZE(rzg2l_gpio_names));

+ BUILD_BUG_ON(ARRAY_SIZE(r9a09g057_gpio_configs) * RZG2L_PINS_PER_PORT >
+ ARRAY_SIZE(rzv2h_gpio_names));
+
pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
if (!pctrl)
return -ENOMEM;
@@ -2402,6 +2787,7 @@ static int rzg2l_pinctrl_probe(struct platform_device *pdev)

spin_lock_init(&pctrl->lock);
spin_lock_init(&pctrl->bitmap_lock);
+ raw_spin_lock_init(&pctrl->pwpr_lock);
mutex_init(&pctrl->mutex);
atomic_set(&pctrl->wakeup_path, 0);

@@ -2578,6 +2964,65 @@ static void rzg2l_pinctrl_pm_setup_pfc(struct rzg2l_pinctrl *pctrl)
writel(PWPR_B0WI, pctrl->base + regs->pwpr); /* B0WI=1, PFCWE=0 */
}

+static void rzv2h_pinctrl_pm_setup_pfc(struct rzg2l_pinctrl *pctrl)
+{
+ u32 nports = pctrl->data->n_port_pins / RZG2L_PINS_PER_PORT;
+ const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg;
+ const struct rzg2l_register_offsets *regs = &hwcfg->regs;
+ u8 pwpr;
+
+ /* Set the PWPR register to allow PFC + PMC register to write. */
+ raw_spin_lock(&pctrl->pwpr_lock);
+ pwpr = readb(pctrl->base + regs->pwpr);
+ writeb(pwpr | PWPR_REGWE_A, pctrl->base + regs->pwpr); /* REGWE_A=1 */
+
+ /* Restore port registers. */
+ for (u32 port = 0; port < nports; port++) {
+ unsigned long pinmap;
+ u8 pmc = 0, max_pin;
+ u32 off, pfc = 0;
+ u64 cfg;
+ u16 pm;
+ u8 pin;
+
+ cfg = pctrl->data->port_pin_configs[port];
+ off = RZG2L_PIN_CFG_TO_PORT_OFFSET(cfg);
+ pinmap = FIELD_GET(PIN_CFG_PIN_MAP_MASK, cfg);
+ max_pin = fls(pinmap);
+
+ pm = readw(pctrl->base + PM(off));
+ for_each_set_bit(pin, &pinmap, max_pin) {
+ struct rzg2l_pinctrl_reg_cache *cache = pctrl->cache;
+
+ /* Nothing to do if PFC was not configured before. */
+ if (!(cache->pmc[port] & BIT(pin)))
+ continue;
+
+ /* Set pin to 'Non-use (Hi-Z input protection)' */
+ pm &= ~(PM_MASK << (pin * 2));
+ writew(pm, pctrl->base + PM(off));
+
+ /* Temporarily switch to GPIO mode with PMC register */
+ pmc &= ~BIT(pin);
+ writeb(pmc, pctrl->base + PMC(off));
+
+ /* Select Pin function mode. */
+ pfc &= ~(PFC_MASK << (pin * 4));
+ pfc |= (cache->pfc[port] & (PFC_MASK << (pin * 4)));
+ writel(pfc, pctrl->base + PFC(off));
+
+ /* Switch to Peripheral pin function. */
+ pmc |= BIT(pin);
+ writeb(pmc, pctrl->base + PMC(off));
+ }
+ }
+
+ /* Set the PWPR register to be write-protected. */
+ pwpr = readb(pctrl->base + regs->pwpr);
+ writeb(pwpr & ~PWPR_REGWE_A, pctrl->base + regs->pwpr); /* REGWE_A=0 */
+ raw_spin_unlock(&pctrl->pwpr_lock);
+}
+
static int rzg2l_pinctrl_suspend_noirq(struct device *dev)
{
struct rzg2l_pinctrl *pctrl = dev_get_drvdata(dev);
@@ -2682,6 +3127,14 @@ static const struct rzg2l_hwcfg rzg3s_hwcfg = {
.oen_max_port = 7, /* P7_1 is the maximum OEN port. */
};

+static const struct rzg2l_hwcfg rzv2h_hwcfg = {
+ .regs = {
+ .pwpr = 0x3c04,
+ .sd_ch = 0x0,
+ .eth_poc = 0x0,
+ },
+};
+
static struct rzg2l_pinctrl_data r9a07g043_data = {
.port_pins = rzg2l_gpio_names,
.port_pin_configs = r9a07g043_gpio_configs,
@@ -2732,6 +3185,28 @@ static struct rzg2l_pinctrl_data r9a08g045_data = {
.write_oen = &rzg2l_write_oen,
};

+static struct rzg2l_pinctrl_data r9a09g057_data = {
+ .port_pins = rzv2h_gpio_names,
+ .port_pin_configs = r9a09g057_gpio_configs,
+ .n_ports = ARRAY_SIZE(r9a09g057_gpio_configs),
+ .dedicated_pins = rzv2h_dedicated_pins,
+ .n_port_pins = ARRAY_SIZE(r9a09g057_gpio_configs) * RZG2L_PINS_PER_PORT,
+ .n_dedicated_pins = ARRAY_SIZE(rzv2h_dedicated_pins),
+ .hwcfg = &rzv2h_hwcfg,
+ .variable_pin_cfg = r9a09g057_variable_pin_cfg,
+ .n_variable_pin_cfg = ARRAY_SIZE(r9a09g057_variable_pin_cfg),
+ .num_custom_params = ARRAY_SIZE(renesas_rzv2h_custom_bindings),
+ .custom_params = renesas_rzv2h_custom_bindings,
+#ifdef CONFIG_DEBUG_FS
+ .custom_conf_items = renesas_rzv2h_conf_items,
+#endif
+ .set_pfc_mode = &rzv2h_pinctrl_set_pfc_mode,
+ .pm_set_pfc = &rzv2h_pinctrl_pm_setup_pfc,
+ .pmc_writeb = &rzv2h_pmc_writeb,
+ .read_oen = &rzv2h_read_oen,
+ .write_oen = &rzv2h_write_oen,
+};
+
static const struct of_device_id rzg2l_pinctrl_of_table[] = {
{
.compatible = "renesas,r9a07g043-pinctrl",
@@ -2745,6 +3220,10 @@ static const struct of_device_id rzg2l_pinctrl_of_table[] = {
.compatible = "renesas,r9a08g045-pinctrl",
.data = &r9a08g045_data,
},
+ {
+ .compatible = "renesas,r9a09g057-pinctrl",
+ .data = &r9a09g057_data,
+ },
{ /* sentinel */ }
};

--
2.34.1


2024-03-27 08:01:15

by Dan Carpenter

[permalink] [raw]
Subject: Re: [RFC PATCH 07/13] pinctrl: renesas: pinctrl-rzg2l: Validate power registers for SD and ETH

On Tue, Mar 26, 2024 at 10:28:38PM +0000, Prabhakar wrote:
> From: Lad Prabhakar <[email protected]>
>
> On RZ/V2H(P) SoC, the power registers for SD and ETH do not exist,
> resulting in invalid register offsets. Ensure that the register offsets
> are valid before any read/write operations are performed. If the power
^^^^^^^^^^^^
> registers are not available, both SD and ETH will be set to -EINVAL.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Where does this happen? It doesn't seem to be a part of this patchset.
-EINVAL seems weird here, but it's hard to judge without actually seeing
it.

regards,
dan carpenter


2024-03-27 08:13:58

by Prabhakar

[permalink] [raw]
Subject: Re: [RFC PATCH 07/13] pinctrl: renesas: pinctrl-rzg2l: Validate power registers for SD and ETH

Hi Dan,

Thank you for the review.

On Wed, Mar 27, 2024 at 7:58 AM Dan Carpenter <dan.carpenter@linaroorg> wrote:
>
> On Tue, Mar 26, 2024 at 10:28:38PM +0000, Prabhakar wrote:
> > From: Lad Prabhakar <[email protected]>
> >
> > On RZ/V2H(P) SoC, the power registers for SD and ETH do not exist,
> > resulting in invalid register offsets. Ensure that the register offsets
> > are valid before any read/write operations are performed. If the power
> ^^^^^^^^^^^^
> > registers are not available, both SD and ETH will be set to -EINVAL.
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> Where does this happen? It doesn't seem to be a part of this patchset.
> -EINVAL seems weird here, but it's hard to judge without actually seeing
> it.
>
Good catch, in patch 13/13 it should be below instead of sd_ch and
eth_poc assigned to 0.

+static const struct rzg2l_hwcfg rzv2h_hwcfg = {
+ .regs = {
+ .pwpr = 0x3c04,
+ .sd_ch = -EINVAL,
+ .eth_poc = -EINVAL,
+ },
+};

Cheers,
Prabhakar

2024-03-27 17:17:12

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [RFC PATCH 01/13] dt-bindings: pinctrl: renesas,rzg2l-pinctrl: Remove the check from the object


On Tue, 26 Mar 2024 22:28:32 +0000, Prabhakar wrote:
> From: Lad Prabhakar <[email protected]>
>
> Drop the bogus check from object as this didn't really add restriction check.
>
> Signed-off-by: Lad Prabhakar <[email protected]>
> ---
> .../bindings/pinctrl/renesas,rzg2l-pinctrl.yaml | 15 ---------------
> 1 file changed, 15 deletions(-)
>

Reviewed-by: Rob Herring <[email protected]>


2024-03-27 17:24:50

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [RFC PATCH 02/13] dt-bindings: pinctrl: renesas: Document RZ/V2H(P) SoC

On Tue, Mar 26, 2024 at 10:28:33PM +0000, Prabhakar wrote:
> From: Lad Prabhakar <[email protected]>
>
> Add documentation for the pin controller found on the Renesas RZ/V2H(P)
> (R9A09G057) SoC. Compared to RZ/G2L family of SoCs there are slight
> differences on the RZ/V2H(P) SoC for pinmuxing.
>
> Also add 'renesas-rzv2h,output-impedance' property. Drive strength
> setting on RZ/V2H(P) depends on the different power rails which are
> coming out from the PMIC (connected via i2c). These power rails
> (required for drive strength) can be 1.2/1.8/3.3V.
>
> Pin are grouped into 4 groups,
>
> Group1: Impedance
> - 150/75/38/25 ohms (at 3.3 V)
> - 130/65/33/22 ohms (at 1.8 V)
>
> Group2: Impedance
> - 50/40/33/25 ohms (at 1.8 V)
>
> Group3: Impedance
> - 150/75/37.5/25 ohms (at 3.3 V)
> - 130/65/33/22 ohms (at 1.8 V)
>
> Group4: Impedance
> - 110/55/30/20 ohms (at 1.8 V)
> - 150/75/38/25 ohms (at 1.2 V)
>
> 'renesas-rzv2h,output-impedance' property as documented which can be
> [1, 2, 4, 6] indicates x Value strength.

Looks like the values are x1, x1.5, x3ish, x6...

>
> As the power rail information cannot be available very early in the
> boot process as 'renesas-rzv2h,output-impedance' property is added
> instead of reusing output-impedance-ohms property.
>
> Signed-off-by: Lad Prabhakar <[email protected]>
> ---
> .../pinctrl/renesas,rzg2l-pinctrl.yaml | 22 +++++++++++++++----
> 1 file changed, 18 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml
> index 881e992adca3..77f4fc7f4a21 100644
> --- a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml
> +++ b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml
> @@ -26,6 +26,7 @@ properties:
> - renesas,r9a07g043-pinctrl # RZ/G2UL{Type-1,Type-2} and RZ/Five
> - renesas,r9a07g044-pinctrl # RZ/G2{L,LC}
> - renesas,r9a08g045-pinctrl # RZ/G3S
> + - renesas,r9a09g057-pinctrl # RZ/V2H(P)
>
> - items:
> - enum:
> @@ -66,10 +67,14 @@ properties:
> maxItems: 1
>
> resets:
> - items:
> - - description: GPIO_RSTN signal
> - - description: GPIO_PORT_RESETN signal
> - - description: GPIO_SPARE_RESETN signal
> + oneOf:
> + - items:
> + - description: GPIO_RSTN signal
> + - description: GPIO_PORT_RESETN signal
> + - description: GPIO_SPARE_RESETN signal
> + - items:
> + - description: PFC main reset
> + - description: Reset for the control register related to WDTUDFCA and WDTUDFFCM pins
>
> additionalProperties:
> anyOf:
> @@ -111,6 +116,15 @@ additionalProperties:
> output-high: true
> output-low: true
> line-name: true
> + renesas-rzv2h,output-impedance:

'renesas-rzv2h' is not a vendor.

That should give you a warning if you actually used this somewhere.

> + description: |
> + Output impedance for pins on RZ/V2H(P) SoC.
> + x1: Corresponds to 0 in IOLH register.
> + x2: Corresponds to 1 in IOLH register.
> + x4: Corresponds to 2 in IOLH register.
> + x6: Corresponds to 3 in IOLH register.

Why not just use 0-3 for the values?


> + $ref: /schemas/types.yaml#/definitions/uint32
> + enum: [1, 2, 4, 6]
>
> - type: object
> additionalProperties:
> --
> 2.34.1
>

2024-03-27 19:07:38

by Prabhakar

[permalink] [raw]
Subject: Re: [RFC PATCH 02/13] dt-bindings: pinctrl: renesas: Document RZ/V2H(P) SoC

Hi Rob,

Thank you for the review.

On Wed, Mar 27, 2024 at 5:24 PM Rob Herring <[email protected]> wrote:
>
> On Tue, Mar 26, 2024 at 10:28:33PM +0000, Prabhakar wrote:
> > From: Lad Prabhakar <[email protected]>
> >
> > Add documentation for the pin controller found on the Renesas RZ/V2H(P)
> > (R9A09G057) SoC. Compared to RZ/G2L family of SoCs there are slight
> > differences on the RZ/V2H(P) SoC for pinmuxing.
> >
> > Also add 'renesas-rzv2h,output-impedance' property. Drive strength
> > setting on RZ/V2H(P) depends on the different power rails which are
> > coming out from the PMIC (connected via i2c). These power rails
> > (required for drive strength) can be 1.2/1.8/3.3V.
> >
> > Pin are grouped into 4 groups,
> >
> > Group1: Impedance
> > - 150/75/38/25 ohms (at 3.3 V)
> > - 130/65/33/22 ohms (at 1.8 V)
> >
> > Group2: Impedance
> > - 50/40/33/25 ohms (at 1.8 V)
> >
> > Group3: Impedance
> > - 150/75/37.5/25 ohms (at 3.3 V)
> > - 130/65/33/22 ohms (at 1.8 V)
> >
> > Group4: Impedance
> > - 110/55/30/20 ohms (at 1.8 V)
> > - 150/75/38/25 ohms (at 1.2 V)
> >
> > 'renesas-rzv2h,output-impedance' property as documented which can be
> > [1, 2, 4, 6] indicates x Value strength.
>
> Looks like the values are x1, x1.5, x3ish, x6...
>
> >
> > As the power rail information cannot be available very early in the
> > boot process as 'renesas-rzv2h,output-impedance' property is added
> > instead of reusing output-impedance-ohms property.
> >
> > Signed-off-by: Lad Prabhakar <[email protected]>
> > ---
> > .../pinctrl/renesas,rzg2l-pinctrl.yaml | 22 +++++++++++++++----
> > 1 file changed, 18 insertions(+), 4 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml
> > index 881e992adca3..77f4fc7f4a21 100644
> > --- a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml
> > +++ b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml
> > @@ -26,6 +26,7 @@ properties:
> > - renesas,r9a07g043-pinctrl # RZ/G2UL{Type-1,Type-2} and RZ/Five
> > - renesas,r9a07g044-pinctrl # RZ/G2{L,LC}
> > - renesas,r9a08g045-pinctrl # RZ/G3S
> > + - renesas,r9a09g057-pinctrl # RZ/V2H(P)
> >
> > - items:
> > - enum:
> > @@ -66,10 +67,14 @@ properties:
> > maxItems: 1
> >
> > resets:
> > - items:
> > - - description: GPIO_RSTN signal
> > - - description: GPIO_PORT_RESETN signal
> > - - description: GPIO_SPARE_RESETN signal
> > + oneOf:
> > + - items:
> > + - description: GPIO_RSTN signal
> > + - description: GPIO_PORT_RESETN signal
> > + - description: GPIO_SPARE_RESETN signal
> > + - items:
> > + - description: PFC main reset
> > + - description: Reset for the control register related to WDTUDFCA and WDTUDFFCM pins
> >
> > additionalProperties:
> > anyOf:
> > @@ -111,6 +116,15 @@ additionalProperties:
> > output-high: true
> > output-low: true
> > line-name: true
> > + renesas-rzv2h,output-impedance:
>
> 'renesas-rzv2h' is not a vendor.
>
I will update this to "renesas,output-impedance".

> That should give you a warning if you actually used this somewhere.
>
I did run dtbs_check with this property in the DTS and haven't seen
any warning. Also now I included this property in the example node in
the binding doc and seen no warnings reported by dt_binding_check too.

> > + description: |
> > + Output impedance for pins on RZ/V2H(P) SoC.
> > + x1: Corresponds to 0 in IOLH register.
> > + x2: Corresponds to 1 in IOLH register.
> > + x4: Corresponds to 2 in IOLH register.
> > + x6: Corresponds to 3 in IOLH register.
>
> Why not just use 0-3 for the values?
>
Fine by me. I'll update this in the next version.

Cheers,
Prabhakar

2024-03-28 08:04:14

by Claudiu

[permalink] [raw]
Subject: Re: [RFC PATCH 08/13] pinctrl: renesas: pinctrl-rzg2l: Add function pointers for writing to PFC

Hi, Prabhakar,

On 27.03.2024 00:28, Prabhakar wrote:
> From: Lad Prabhakar <[email protected]>
>
> On the RZ/G2L SoC, the PFCWE bit controls writing to PFC registers.
> However, on the RZ/V2H(P) SoC, the PFCWE (REGWE_A on RZ/V2H) bit controls
> writing to both PFC and PMC registers. To accommodate these differences
> across SoC variants, introduce set_pfc_mode() and pm_set_pfc() function
> pointers.

I think the overall code can be simplified if you add 1 function that does
the lock/unlock for PWPR. See patch 13.

>
> Signed-off-by: Lad Prabhakar <[email protected]>
> ---
> drivers/pinctrl/renesas/pinctrl-rzg2l.c | 14 ++++++++++++--
> 1 file changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> index 705372faaeff..4cdebdbd8a04 100644
> --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> @@ -246,6 +246,8 @@ struct rzg2l_variable_pin_cfg {
> u32 pin:3;
> };
>
> +struct rzg2l_pinctrl;
> +
> struct rzg2l_pinctrl_data {
> const char * const *port_pins;
> const u64 *port_pin_configs;
> @@ -256,6 +258,8 @@ struct rzg2l_pinctrl_data {
> const struct rzg2l_hwcfg *hwcfg;
> const struct rzg2l_variable_pin_cfg *variable_pin_cfg;
> unsigned int n_variable_pin_cfg;
> + void (*set_pfc_mode)(struct rzg2l_pinctrl *pctrl, u8 pin, u8 off, u8 func);
> + void (*pm_set_pfc)(struct rzg2l_pinctrl *pctrl);
> };
>
> /**
> @@ -526,7 +530,7 @@ static int rzg2l_pinctrl_set_mux(struct pinctrl_dev *pctldev,
> dev_dbg(pctrl->dev, "port:%u pin: %u off:%x PSEL:%u\n",
> RZG2L_PIN_ID_TO_PORT(pins[i]), pin, off, psel_val[i] - hwcfg->func_base);
>
> - rzg2l_pinctrl_set_pfc_mode(pctrl, pin, off, psel_val[i] - hwcfg->func_base);
> + pctrl->data->set_pfc_mode(pctrl, pin, off, psel_val[i] - hwcfg->func_base);
> }
>
> return 0;
> @@ -2607,7 +2611,7 @@ static int rzg2l_pinctrl_resume_noirq(struct device *dev)
> writeb(cache->eth_poc[i], pctrl->base + ETH_POC(regs->eth_poc, i));
> }
>
> - rzg2l_pinctrl_pm_setup_pfc(pctrl);
> + pctrl->data->pm_set_pfc(pctrl);
> rzg2l_pinctrl_pm_setup_regs(pctrl, false);
> rzg2l_pinctrl_pm_setup_dedicated_regs(pctrl, false);
> rzg2l_gpio_irq_restore(pctrl);
> @@ -2672,6 +2676,8 @@ static struct rzg2l_pinctrl_data r9a07g043_data = {
> .variable_pin_cfg = r9a07g043f_variable_pin_cfg,
> .n_variable_pin_cfg = ARRAY_SIZE(r9a07g043f_variable_pin_cfg),
> #endif
> + .set_pfc_mode = &rzg2l_pinctrl_set_pfc_mode,
> + .pm_set_pfc = &rzg2l_pinctrl_pm_setup_pfc,
> };
>
> static struct rzg2l_pinctrl_data r9a07g044_data = {
> @@ -2683,6 +2689,8 @@ static struct rzg2l_pinctrl_data r9a07g044_data = {
> .n_dedicated_pins = ARRAY_SIZE(rzg2l_dedicated_pins.common) +
> ARRAY_SIZE(rzg2l_dedicated_pins.rzg2l_pins),
> .hwcfg = &rzg2l_hwcfg,
> + .set_pfc_mode = &rzg2l_pinctrl_set_pfc_mode,
> + .pm_set_pfc = &rzg2l_pinctrl_pm_setup_pfc,
> };
>
> static struct rzg2l_pinctrl_data r9a08g045_data = {
> @@ -2693,6 +2701,8 @@ static struct rzg2l_pinctrl_data r9a08g045_data = {
> .n_port_pins = ARRAY_SIZE(r9a08g045_gpio_configs) * RZG2L_PINS_PER_PORT,
> .n_dedicated_pins = ARRAY_SIZE(rzg3s_dedicated_pins),
> .hwcfg = &rzg3s_hwcfg,
> + .set_pfc_mode = &rzg2l_pinctrl_set_pfc_mode,
> + .pm_set_pfc = &rzg2l_pinctrl_pm_setup_pfc,
> };
>
> static const struct of_device_id rzg2l_pinctrl_of_table[] = {

2024-03-28 08:05:48

by Claudiu

[permalink] [raw]
Subject: Re: [RFC PATCH 13/13] pinctrl: renesas: pinctrl-rzg2l: Add support for RZ/V2H SoC

Hi, Prabhakar,

On 27.03.2024 00:28, Prabhakar wrote:
> From: Lad Prabhakar <[email protected]>
>
> Add pinctrl driver support for RZ/V2H(P) SoC.
>
> Signed-off-by: Lad Prabhakar <[email protected]>
> ---
> drivers/pinctrl/renesas/pinctrl-rzg2l.c | 483 +++++++++++++++++++++++-
> 1 file changed, 481 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> index 6f0c85bb97a8..716c11ca5a8f 100644
> --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> @@ -59,6 +59,13 @@
> #define PIN_CFG_OEN BIT(15)
> #define PIN_CFG_VARIABLE BIT(16)
> #define PIN_CFG_NOGPIO_INT BIT(17)
> +#define PIN_CFG_OPEN_DRAIN BIT(18)
> +#define PIN_CFG_SCHMIT_CTRL BIT(19)
> +#define PIN_CFG_ELC BIT(20)
> +#define PIN_CFG_IOLH_1 BIT(21)
> +#define PIN_CFG_IOLH_2 BIT(22)
> +#define PIN_CFG_IOLH_3 BIT(23)
> +#define PIN_CFG_IOLH_4 BIT(24)
>
> #define RZG2L_MPXED_COMMON_PIN_FUNCS(group) \
> (PIN_CFG_IOLH_##group | \
> @@ -70,6 +77,10 @@
> #define RZG2L_MPXED_PIN_FUNCS (RZG2L_MPXED_COMMON_PIN_FUNCS(A) | \
> PIN_CFG_SR)
>
> +#define RZV2H_MPXED_PIN_FUNCS(group) (RZG2L_MPXED_COMMON_PIN_FUNCS(group) | \
> + PIN_CFG_OPEN_DRAIN | \
> + PIN_CFG_SR)
> +
> #define RZG3S_MPXED_PIN_FUNCS(group) (RZG2L_MPXED_COMMON_PIN_FUNCS(group) | \
> PIN_CFG_SOFT_PS)
>
> @@ -133,6 +144,8 @@
>
> #define PWPR_B0WI BIT(7) /* Bit Write Disable */
> #define PWPR_PFCWE BIT(6) /* PFC Register Write Enable */
> +#define PWPR_REGWE_A BIT(6) /* PFC and PMC Register Write Enable */
> +#define PWPR_REGWE_B BIT(5) /* OEN Register Write Enable */
>
> #define PM_MASK 0x03
> #define PFC_MASK 0x07
> @@ -149,6 +162,19 @@
> #define RZG2L_TINT_IRQ_START_INDEX 9
> #define RZG2L_PACK_HWIRQ(t, i) (((t) << 16) | (i))
>
> +/* Custom pinconf parameters */
> +#define RENESAS_RZV2H_PIN_CONFIG_OUTPUT_IMPEDANCE (PIN_CONFIG_END + 1)
> +
> +static const struct pinconf_generic_params renesas_rzv2h_custom_bindings[] = {
> + { "renesas-rzv2h,output-impedance", RENESAS_RZV2H_PIN_CONFIG_OUTPUT_IMPEDANCE, 1 },
> +};
> +
> +#ifdef CONFIG_DEBUG_FS
> +static const struct pin_config_item renesas_rzv2h_conf_items[] = {
> + PCONFDUMP(RENESAS_RZV2H_PIN_CONFIG_OUTPUT_IMPEDANCE, "output-impedance", "x", true),
> +};
> +#endif
> +
> /* Read/write 8 bits register */
> #define RZG2L_PCTRL_REG_ACCESS8(_read, _addr, _val) \
> do { \
> @@ -324,6 +350,8 @@ struct rzg2l_pinctrl {
> spinlock_t lock; /* lock read/write registers */
> struct mutex mutex; /* serialize adding groups and functions */
>
> + raw_spinlock_t pwpr_lock; /* serialize PWPR register access */
> +
> struct rzg2l_pinctrl_pin_settings *settings;
> struct rzg2l_pinctrl_reg_cache *cache;
> struct rzg2l_pinctrl_reg_cache *dedicated_cache;
> @@ -348,6 +376,79 @@ static u64 rzg2l_pinctrl_get_variable_pin_cfg(struct rzg2l_pinctrl *pctrl,
> return 0;
> }
>
> +static const struct rzg2l_variable_pin_cfg r9a09g057_variable_pin_cfg[] = {
> + {
> + .port = 9,
> + .pin = 0,
> + .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL,
> + },
> + {
> + .port = 9,
> + .pin = 1,
> + .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL,
> + },
> + {
> + .port = 9,
> + .pin = 2,
> + .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL,
> + },
> + {
> + .port = 9,
> + .pin = 3,
> + .cfg = RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL,
> + },
> + {
> + .port = 9,
> + .pin = 4,
> + .cfg = RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL,
> + },
> + {
> + .port = 9,
> + .pin = 5,
> + .cfg = RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL,
> + },
> + {
> + .port = 9,
> + .pin = 6,
> + .cfg = RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL,
> + },
> + {
> + .port = 9,
> + .pin = 7,
> + .cfg = RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL,
> + },
> + {
> + .port = 11,
> + .pin = 0,
> + .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL,
> + },
> + {
> + .port = 11,
> + .pin = 1,
> + .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL | PIN_CFG_IEN,
> + },
> + {
> + .port = 11,
> + .pin = 2,
> + .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL | PIN_CFG_IEN,
> + },
> + {
> + .port = 11,
> + .pin = 3,
> + .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL | PIN_CFG_IEN,
> + },
> + {
> + .port = 11,
> + .pin = 4,
> + .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL | PIN_CFG_IEN,
> + },
> + {
> + .port = 11,
> + .pin = 5,
> + .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL | PIN_CFG_IEN,
> + },
> +};
> +
> #ifdef CONFIG_RISCV
> static const struct rzg2l_variable_pin_cfg r9a07g043f_variable_pin_cfg[] = {
> {
> @@ -474,6 +575,19 @@ static void rzg2l_pmc_writeb(struct rzg2l_pinctrl *pctrl, u8 val, void __iomem *
> writeb(val, addr);
> }
>
> +static void rzv2h_pmc_writeb(struct rzg2l_pinctrl *pctrl, u8 val, void __iomem *addr)
> +{
> + const struct rzg2l_register_offsets *regs = &pctrl->data->hwcfg->regs;
> + u8 pwpr;
> +
> + raw_spin_lock(&pctrl->pwpr_lock);
> + pwpr = readb(pctrl->base + regs->pwpr);
> + writeb(pwpr | PWPR_REGWE_A, pctrl->base + regs->pwpr);

What about having a device specific function that locks/unlocks the PWPR,
this part ^ being the lock.



> + writeb(val, addr);

And this starting here:

> + writeb(pwpr & ~PWPR_REGWE_A, pctrl->base + regs->pwpr);
> + raw_spin_unlock(&pctrl->pwpr_lock);

ending here: the unlock function. It should generate les diffs at least in
this patch.

And you can add, were needed:

if (pctrl->pwpr_lock_function)
pctrl->pwpr_lock_function();

write(val, addr);

if (pctrl->pwpr_unlock_function)
pctrl->pwpr_unlock_function();


With this you can avoid adding rzv2h_pinctrl_set_pfc_mode() which is alomst
identical w/ rzg2l_pinctrl_set_pfc_mode(), or adding
rzv2h_pinctrl_pm_setup_pfc() almost identical with
rzg2l_pinctrl_pm_setup_pfc().

> +}
> +
> static void rzg2l_pinctrl_set_pfc_mode(struct rzg2l_pinctrl *pctrl,
> u8 pin, u8 off, u8 func)
> {
> @@ -512,6 +626,47 @@ static void rzg2l_pinctrl_set_pfc_mode(struct rzg2l_pinctrl *pctrl,
> spin_unlock_irqrestore(&pctrl->lock, flags);
> };
>
> +static void rzv2h_pinctrl_set_pfc_mode(struct rzg2l_pinctrl *pctrl,
> + u8 pin, u8 off, u8 func)
> +{
> + const struct rzg2l_register_offsets *regs = &pctrl->data->hwcfg->regs;
> + unsigned long flags;
> + u32 reg;
> + u8 pwpr;
> +
> + spin_lock_irqsave(&pctrl->lock, flags);
> +
> + /* Set pin to 'Non-use (Hi-Z input protection)' */
> + reg = readw(pctrl->base + PM(off));
> + reg &= ~(PM_MASK << (pin * 2));
> + writew(reg, pctrl->base + PM(off));
> +
> + /* Set the PWPR register to allow PFC and PMC register to write */
> + raw_spin_lock(&pctrl->pwpr_lock);
> + pwpr = readb(pctrl->base + regs->pwpr);
> + writeb(PWPR_PFCWE | pwpr, pctrl->base + regs->pwpr);
> +
> + /* Temporarily switch to GPIO mode with PMC register */
> + reg = readb(pctrl->base + PMC(off));
> + writeb(reg & ~BIT(pin), pctrl->base + PMC(off));
> +
> + /* Select Pin function mode with PFC register */
> + reg = readl(pctrl->base + PFC(off));
> + reg &= ~(PFC_MASK << (pin * 4));
> + writel(reg | (func << (pin * 4)), pctrl->base + PFC(off));
> +
> + /* Switch to Peripheral pin function with PMC register */
> + reg = readb(pctrl->base + PMC(off));
> + writeb(reg | BIT(pin), pctrl->base + PMC(off));
> +
> + /* Set the PWPR register to be write-protected */
> + pwpr = readb(pctrl->base + regs->pwpr);
> + writeb(pwpr & ~PWPR_PFCWE, pctrl->base + regs->pwpr);
> + raw_spin_unlock(&pctrl->pwpr_lock);
> +
> + spin_unlock_irqrestore(&pctrl->lock, flags);
> +};
> +
> static int rzg2l_pinctrl_set_mux(struct pinctrl_dev *pctldev,
> unsigned int func_selector,
> unsigned int group_selector)
> @@ -1087,14 +1242,26 @@ static int rzg2l_write_oen(struct rzg2l_pinctrl *pctrl, u32 caps, u32 offset, u8
> return 0;
> }
>
> +static u32 rzv2h_read_oen(struct rzg2l_pinctrl *pctrl, u32 caps, u32 offset, u8 pin)
> +{
> + /* stub */
> + return 0;
> +}
> +
> +static int rzv2h_write_oen(struct rzg2l_pinctrl *pctrl, u32 caps, u32 offset, u8 pin, u8 oen)
> +{
> + /* stub */
> + return -EINVAL;
> +}
> +

What about chekcing:
if (pctrl->data->read_oen)
ret = pctrl->data->read_oen()

if (pctrl->data->write_oen)
ret = pctrl->data->write_oen()

Accross the driver. This will avoid adding stubs each time suppor for a new
IP is added.

> static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *pctldev,
> unsigned int _pin,
> unsigned long *config)
> {
> struct rzg2l_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
> - enum pin_config_param param = pinconf_to_config_param(*config);
> const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg;
> const struct pinctrl_pin_desc *pin = &pctrl->desc.pins[_pin];
> + u32 param = pinconf_to_config_param(*config);
> u64 *pin_data = pin->drv_data;
> unsigned int arg = 0;
> u32 off, cfg;
> @@ -1180,6 +1347,30 @@ static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *pctldev,
> break;
> }
>
> + case RENESAS_RZV2H_PIN_CONFIG_OUTPUT_IMPEDANCE: {
> + u8 val;
> +
> + if (!(cfg & (PIN_CFG_IOLH_1 | PIN_CFG_IOLH_2 | PIN_CFG_IOLH_3 | PIN_CFG_IOLH_4)))
> + return -EINVAL;
> +
> + val = rzg2l_read_pin_config(pctrl, IOLH(off), bit, IOLH_MASK);
> + switch (val) {
> + case 0:
> + arg = 1;
> + break;
> + case 1:
> + arg = 2;
> + break;
> + case 2:
> + arg = 4;
> + break;
> + default:
> + arg = 6;
> + break;
> + }
> + break;
> + }
> +
> default:
> return -ENOTSUPP;
> }
> @@ -1199,9 +1390,9 @@ static int rzg2l_pinctrl_pinconf_set(struct pinctrl_dev *pctldev,
> const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg;
> struct rzg2l_pinctrl_pin_settings settings = pctrl->settings[_pin];
> u64 *pin_data = pin->drv_data;
> - enum pin_config_param param;
> unsigned int i, arg, index;
> u32 cfg, off;
> + u32 param;
> int ret;
> u8 bit;
>
> @@ -1283,6 +1474,32 @@ static int rzg2l_pinctrl_pinconf_set(struct pinctrl_dev *pctldev,
> rzg2l_rmw_pin_config(pctrl, IOLH(off), bit, IOLH_MASK, index);
> break;
>
> + case RENESAS_RZV2H_PIN_CONFIG_OUTPUT_IMPEDANCE:
> + arg = pinconf_to_config_argument(_configs[i]);
> +
> + if (!(cfg & (PIN_CFG_IOLH_1 | PIN_CFG_IOLH_2 |
> + PIN_CFG_IOLH_3 | PIN_CFG_IOLH_4)))
> + return -EINVAL;
> +
> + switch (arg) {
> + case 1:
> + index = 0;
> + break;
> + case 2:
> + index = 1;
> + break;
> + case 4:
> + index = 2;
> + break;
> + case 6:
> + index = 3;
> + break;
> + default:
> + return -EINVAL;
> + }
> + rzg2l_rmw_pin_config(pctrl, IOLH(off), bit, IOLH_MASK, index);
> + break;
> +
> default:
> return -EOPNOTSUPP;
> }
> @@ -1730,6 +1947,38 @@ static const u64 r9a08g045_gpio_configs[] = {
> RZG2L_GPIO_PORT_PACK(6, 0x2a, RZG3S_MPXED_PIN_FUNCS(A)), /* P18 */
> };
>
> +static const char * const rzv2h_gpio_names[] = {
> + "P00", "P01", "P02", "P03", "P04", "P05", "P06", "P07",
> + "P10", "P11", "P12", "P13", "P14", "P15", "P16", "P17",
> + "P20", "P21", "P22", "P23", "P24", "P25", "P26", "P27",
> + "P30", "P31", "P32", "P33", "P34", "P35", "P36", "P37",
> + "P40", "P41", "P42", "P43", "P44", "P45", "P46", "P47",
> + "P50", "P51", "P52", "P53", "P54", "P55", "P56", "P57",
> + "P60", "P61", "P62", "P63", "P64", "P65", "P66", "P67",
> + "P70", "P71", "P72", "P73", "P74", "P75", "P76", "P77",
> + "P80", "P81", "P82", "P83", "P84", "P85", "P86", "P87",
> + "P90", "P91", "P92", "P93", "P94", "P95", "P96", "P97",
> + "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7",
> + "PB0", "PB1", "PB2", "PB3", "PB4", "PB5", "PB6", "PB7",
> +};
> +
> +static const u64 r9a09g057_gpio_configs[] = {
> + RZG2L_GPIO_PORT_PACK(8, 0x20, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* P0 */
> + RZG2L_GPIO_PORT_PACK(6, 0x21, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* P1 */
> + RZG2L_GPIO_PORT_PACK(2, 0x22, RZV2H_MPXED_PIN_FUNCS(4)), /* P2 */
> + RZG2L_GPIO_PORT_PACK(8, 0x23, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* P3 */
> + RZG2L_GPIO_PORT_PACK(8, 0x24, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* P4 */
> + RZG2L_GPIO_PORT_PACK(8, 0x25, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* P5 */
> + RZG2L_GPIO_PORT_PACK(8, 0x26, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL |
> + PIN_CFG_ELC), /* P6 */
> + RZG2L_GPIO_PORT_PACK(8, 0x27, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* P7 */
> + RZG2L_GPIO_PORT_PACK(8, 0x28, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL |
> + PIN_CFG_ELC), /* P8 */
> + RZG2L_GPIO_PORT_PACK(8, 0x29, PIN_CFG_VARIABLE), /* P9 */
> + RZG2L_GPIO_PORT_PACK(8, 0x2a, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* PA */
> + RZG2L_GPIO_PORT_PACK(6, 0x2b, PIN_CFG_VARIABLE), /* PB */
> +};
> +
> static const struct {
> struct rzg2l_dedicated_configs common[35];
> struct rzg2l_dedicated_configs rzg2l_pins[7];
> @@ -1856,6 +2105,139 @@ static const struct rzg2l_dedicated_configs rzg3s_dedicated_pins[] = {
> PIN_CFG_IO_VMC_SD1)) },
> };
>
> +static struct rzg2l_dedicated_configs rzv2h_dedicated_pins[] = {
> + { "NMI", RZG2L_SINGLE_PIN_PACK(0x1, 0, (PIN_CFG_FILONOFF | PIN_CFG_FILNUM |
> + PIN_CFG_FILCLKSEL)) },
> + { "TMS_SWDIO", RZG2L_SINGLE_PIN_PACK(0x3, 0, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
> + PIN_CFG_IEN)) },
> + { "TDO", RZG2L_SINGLE_PIN_PACK(0x3, 2, (PIN_CFG_IOLH_1 | PIN_CFG_SR)) },
> + { "WDTUDFCA", RZG2L_SINGLE_PIN_PACK(0x5, 0, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "WDTUDFCM", RZG2L_SINGLE_PIN_PACK(0x5, 1, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "SCIF_RXD", RZG2L_SINGLE_PIN_PACK(0x6, 0, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "SCIF_TXD", RZG2L_SINGLE_PIN_PACK(0x6, 1, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "XSPI0_CKP", RZG2L_SINGLE_PIN_PACK(0x7, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD | PIN_CFG_OEN)) },
> + { "XSPI0_CKN", RZG2L_SINGLE_PIN_PACK(0x7, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD | PIN_CFG_OEN)) },
> + { "XSPI0_CS0N", RZG2L_SINGLE_PIN_PACK(0x7, 2, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
> + PIN_CFG_PUPD | PIN_CFG_OEN)) },
> + { "XSPI0_DS", RZG2L_SINGLE_PIN_PACK(0x7, 3, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "XSPI0_RESET0N", RZG2L_SINGLE_PIN_PACK(0x7, 4, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
> + PIN_CFG_PUPD | PIN_CFG_OEN)) },
> + { "XSPI0_RSTO0N", RZG2L_SINGLE_PIN_PACK(0x7, 5, (PIN_CFG_PUPD)) },
> + { "XSPI0_INT0N", RZG2L_SINGLE_PIN_PACK(0x7, 6, (PIN_CFG_PUPD)) },
> + { "XSPI0_ECS0N", RZG2L_SINGLE_PIN_PACK(0x7, 7, (PIN_CFG_PUPD)) },
> + { "XSPI0_IO0", RZG2L_SINGLE_PIN_PACK(0x8, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "XSPI0_IO1", RZG2L_SINGLE_PIN_PACK(0x8, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "XSPI0_IO2", RZG2L_SINGLE_PIN_PACK(0x8, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "XSPI0_IO3", RZG2L_SINGLE_PIN_PACK(0x8, 3, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "XSPI0_IO4", RZG2L_SINGLE_PIN_PACK(0x8, 4, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "XSPI0_IO5", RZG2L_SINGLE_PIN_PACK(0x8, 5, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "XSPI0_IO6", RZG2L_SINGLE_PIN_PACK(0x8, 6, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "XSPI0_IO7", RZG2L_SINGLE_PIN_PACK(0x8, 7, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "SD0CLK", RZG2L_SINGLE_PIN_PACK(0x9, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR)) },
> + { "SD0CMD", RZG2L_SINGLE_PIN_PACK(0x9, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR)) },
> + { "SD0RSTN", RZG2L_SINGLE_PIN_PACK(0x9, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> + { "SD0DAT0", RZG2L_SINGLE_PIN_PACK(0xa, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> + { "SD0DAT1", RZG2L_SINGLE_PIN_PACK(0xa, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> + { "SD0DAT2", RZG2L_SINGLE_PIN_PACK(0xa, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> + { "SD0DAT3", RZG2L_SINGLE_PIN_PACK(0xa, 3, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> + { "SD0DAT4", RZG2L_SINGLE_PIN_PACK(0xa, 4, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> + { "SD0DAT5", RZG2L_SINGLE_PIN_PACK(0xa, 5, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> + { "SD0DAT6", RZG2L_SINGLE_PIN_PACK(0xa, 6, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_IOLH_2 | PIN_CFG_PUPD)) },
> + { "SD0DAT7", RZG2L_SINGLE_PIN_PACK(0xa, 7, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> + { "SD1_CLK", RZG2L_SINGLE_PIN_PACK(0xb, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR)) },
> + { "SD1_CMD", RZG2L_SINGLE_PIN_PACK(0xb, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> + { "SD1_DAT0", RZG2L_SINGLE_PIN_PACK(0xc, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> + { "SD1_DAT1", RZG2L_SINGLE_PIN_PACK(0xc, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> + { "SD1_DAT2", RZG2L_SINGLE_PIN_PACK(0xc, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> + { "SD1_DAT3", RZG2L_SINGLE_PIN_PACK(0xc, 3, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> + { "PCIE0_RSTOUTB", RZG2L_SINGLE_PIN_PACK(0xe, 0, (PIN_CFG_IOLH_1 | PIN_CFG_SR)) },
> + { "PCIE1_RSTOUTB", RZG2L_SINGLE_PIN_PACK(0xe, 1, (PIN_CFG_IOLH_1 | PIN_CFG_SR)) },
> + { "ET0_MDIO", RZG2L_SINGLE_PIN_PACK(0xf, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> + { "ET0_MDC", RZG2L_SINGLE_PIN_PACK(0xf, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "ET0_RXCTL_RXDV", RZG2L_SINGLE_PIN_PACK(0x10, 0, (PIN_CFG_PUPD)) },
> + { "ET0_TXCTL_TXEN", RZG2L_SINGLE_PIN_PACK(0x10, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "ET0_TXER", RZG2L_SINGLE_PIN_PACK(0x10, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "ET0_RXER", RZG2L_SINGLE_PIN_PACK(0x10, 3, (PIN_CFG_PUPD)) },
> + { "ET0_RXC_RXCLK", RZG2L_SINGLE_PIN_PACK(0x10, 4, (PIN_CFG_PUPD)) },
> + { "ET0_TXC_TXCLK", RZG2L_SINGLE_PIN_PACK(0x10, 5, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD | PIN_CFG_OEN)) },
> + { "ET0_CRS", RZG2L_SINGLE_PIN_PACK(0x10, 6, (PIN_CFG_PUPD)) },
> + { "ET0_COL", RZG2L_SINGLE_PIN_PACK(0x10, 7, (PIN_CFG_PUPD)) },
> + { "ET0_TXD0", RZG2L_SINGLE_PIN_PACK(0x11, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "ET0_TXD1", RZG2L_SINGLE_PIN_PACK(0x11, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "ET0_TXD2", RZG2L_SINGLE_PIN_PACK(0x11, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "ET0_TXD3", RZG2L_SINGLE_PIN_PACK(0x11, 3, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "ET0_RXD0", RZG2L_SINGLE_PIN_PACK(0x11, 4, (PIN_CFG_PUPD)) },
> + { "ET0_RXD1", RZG2L_SINGLE_PIN_PACK(0x11, 5, (PIN_CFG_PUPD)) },
> + { "ET0_RXD2", RZG2L_SINGLE_PIN_PACK(0x11, 6, (PIN_CFG_PUPD)) },
> + { "ET0_RXD3", RZG2L_SINGLE_PIN_PACK(0x11, 7, (PIN_CFG_PUPD)) },
> + { "ET1_MDIO", RZG2L_SINGLE_PIN_PACK(0x12, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_SR | PIN_CFG_IEN |
> + PIN_CFG_PUPD)) },
> + { "ET1_MDC", RZG2L_SINGLE_PIN_PACK(0x12, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "ET1_RXCTL_RXDV", RZG2L_SINGLE_PIN_PACK(0x13, 0, (PIN_CFG_PUPD)) },
> + { "ET1_TXCTL_TXEN", RZG2L_SINGLE_PIN_PACK(0x13, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "ET1_TXER", RZG2L_SINGLE_PIN_PACK(0x13, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "ET1_RXER", RZG2L_SINGLE_PIN_PACK(0x13, 3, (PIN_CFG_PUPD)) },
> + { "ET1_RXC_RXCLK", RZG2L_SINGLE_PIN_PACK(0x13, 4, (PIN_CFG_PUPD)) },
> + { "ET1_TXC_TXCLK", RZG2L_SINGLE_PIN_PACK(0x13, 5, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD | PIN_CFG_OEN)) },
> + { "ET1_CRS", RZG2L_SINGLE_PIN_PACK(0x13, 6, (PIN_CFG_PUPD)) },
> + { "ET1_COL", RZG2L_SINGLE_PIN_PACK(0x13, 7, (PIN_CFG_PUPD)) },
> + { "ET1_TXD0", RZG2L_SINGLE_PIN_PACK(0x14, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "ET1_TXD1", RZG2L_SINGLE_PIN_PACK(0x14, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "ET1_TXD2", RZG2L_SINGLE_PIN_PACK(0x14, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "ET1_TXD3", RZG2L_SINGLE_PIN_PACK(0x14, 3, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> + PIN_CFG_PUPD)) },
> + { "ET1_RXD0", RZG2L_SINGLE_PIN_PACK(0x14, 4, (PIN_CFG_PUPD)) },
> + { "ET1_RXD1", RZG2L_SINGLE_PIN_PACK(0x14, 5, (PIN_CFG_PUPD)) },
> + { "ET1_RXD2", RZG2L_SINGLE_PIN_PACK(0x14, 6, (PIN_CFG_PUPD)) },
> + { "ET1_RXD3", RZG2L_SINGLE_PIN_PACK(0x14, 7, (PIN_CFG_PUPD)) },
> +};
> +
> static int rzg2l_gpio_get_gpioint(unsigned int virq, struct rzg2l_pinctrl *pctrl)
> {
> const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[virq];
> @@ -2380,6 +2762,9 @@ static int rzg2l_pinctrl_probe(struct platform_device *pdev)
> BUILD_BUG_ON(ARRAY_SIZE(r9a08g045_gpio_configs) * RZG2L_PINS_PER_PORT >
> ARRAY_SIZE(rzg2l_gpio_names));
>
> + BUILD_BUG_ON(ARRAY_SIZE(r9a09g057_gpio_configs) * RZG2L_PINS_PER_PORT >
> + ARRAY_SIZE(rzv2h_gpio_names));
> +
> pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
> if (!pctrl)
> return -ENOMEM;
> @@ -2402,6 +2787,7 @@ static int rzg2l_pinctrl_probe(struct platform_device *pdev)
>
> spin_lock_init(&pctrl->lock);
> spin_lock_init(&pctrl->bitmap_lock);
> + raw_spin_lock_init(&pctrl->pwpr_lock);
> mutex_init(&pctrl->mutex);
> atomic_set(&pctrl->wakeup_path, 0);
>
> @@ -2578,6 +2964,65 @@ static void rzg2l_pinctrl_pm_setup_pfc(struct rzg2l_pinctrl *pctrl)
> writel(PWPR_B0WI, pctrl->base + regs->pwpr); /* B0WI=1, PFCWE=0 */
> }
>
> +static void rzv2h_pinctrl_pm_setup_pfc(struct rzg2l_pinctrl *pctrl)

Have you managed to test this?

> +{
> + u32 nports = pctrl->data->n_port_pins / RZG2L_PINS_PER_PORT;
> + const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg;
> + const struct rzg2l_register_offsets *regs = &hwcfg->regs;
> + u8 pwpr;
> +
> + /* Set the PWPR register to allow PFC + PMC register to write. */
> + raw_spin_lock(&pctrl->pwpr_lock);
> + pwpr = readb(pctrl->base + regs->pwpr);
> + writeb(pwpr | PWPR_REGWE_A, pctrl->base + regs->pwpr); /* REGWE_A=1 */
> +
> + /* Restore port registers. */
> + for (u32 port = 0; port < nports; port++) {
> + unsigned long pinmap;
> + u8 pmc = 0, max_pin;
> + u32 off, pfc = 0;
> + u64 cfg;
> + u16 pm;
> + u8 pin;
> +
> + cfg = pctrl->data->port_pin_configs[port];
> + off = RZG2L_PIN_CFG_TO_PORT_OFFSET(cfg);
> + pinmap = FIELD_GET(PIN_CFG_PIN_MAP_MASK, cfg);
> + max_pin = fls(pinmap);
> +
> + pm = readw(pctrl->base + PM(off));
> + for_each_set_bit(pin, &pinmap, max_pin) {
> + struct rzg2l_pinctrl_reg_cache *cache = pctrl->cache;
> +
> + /* Nothing to do if PFC was not configured before. */
> + if (!(cache->pmc[port] & BIT(pin)))
> + continue;
> +
> + /* Set pin to 'Non-use (Hi-Z input protection)' */
> + pm &= ~(PM_MASK << (pin * 2));
> + writew(pm, pctrl->base + PM(off));
> +
> + /* Temporarily switch to GPIO mode with PMC register */
> + pmc &= ~BIT(pin);
> + writeb(pmc, pctrl->base + PMC(off));
> +
> + /* Select Pin function mode. */
> + pfc &= ~(PFC_MASK << (pin * 4));
> + pfc |= (cache->pfc[port] & (PFC_MASK << (pin * 4)));
> + writel(pfc, pctrl->base + PFC(off));
> +
> + /* Switch to Peripheral pin function. */
> + pmc |= BIT(pin);
> + writeb(pmc, pctrl->base + PMC(off));
> + }
> + }
> +
> + /* Set the PWPR register to be write-protected. */
> + pwpr = readb(pctrl->base + regs->pwpr);
> + writeb(pwpr & ~PWPR_REGWE_A, pctrl->base + regs->pwpr); /* REGWE_A=0 */
> + raw_spin_unlock(&pctrl->pwpr_lock);
> +}
> +
> static int rzg2l_pinctrl_suspend_noirq(struct device *dev)
> {
> struct rzg2l_pinctrl *pctrl = dev_get_drvdata(dev);
> @@ -2682,6 +3127,14 @@ static const struct rzg2l_hwcfg rzg3s_hwcfg = {
> .oen_max_port = 7, /* P7_1 is the maximum OEN port. */
> };
>
> +static const struct rzg2l_hwcfg rzv2h_hwcfg = {
> + .regs = {
> + .pwpr = 0x3c04,
> + .sd_ch = 0x0,
> + .eth_poc = 0x0,
> + },
> +};
> +
> static struct rzg2l_pinctrl_data r9a07g043_data = {
> .port_pins = rzg2l_gpio_names,
> .port_pin_configs = r9a07g043_gpio_configs,
> @@ -2732,6 +3185,28 @@ static struct rzg2l_pinctrl_data r9a08g045_data = {
> .write_oen = &rzg2l_write_oen,
> };
>
> +static struct rzg2l_pinctrl_data r9a09g057_data = {
> + .port_pins = rzv2h_gpio_names,
> + .port_pin_configs = r9a09g057_gpio_configs,
> + .n_ports = ARRAY_SIZE(r9a09g057_gpio_configs),
> + .dedicated_pins = rzv2h_dedicated_pins,
> + .n_port_pins = ARRAY_SIZE(r9a09g057_gpio_configs) * RZG2L_PINS_PER_PORT,
> + .n_dedicated_pins = ARRAY_SIZE(rzv2h_dedicated_pins),
> + .hwcfg = &rzv2h_hwcfg,
> + .variable_pin_cfg = r9a09g057_variable_pin_cfg,
> + .n_variable_pin_cfg = ARRAY_SIZE(r9a09g057_variable_pin_cfg),
> + .num_custom_params = ARRAY_SIZE(renesas_rzv2h_custom_bindings),
> + .custom_params = renesas_rzv2h_custom_bindings,
> +#ifdef CONFIG_DEBUG_FS
> + .custom_conf_items = renesas_rzv2h_conf_items,
> +#endif
> + .set_pfc_mode = &rzv2h_pinctrl_set_pfc_mode,
> + .pm_set_pfc = &rzv2h_pinctrl_pm_setup_pfc,
> + .pmc_writeb = &rzv2h_pmc_writeb,
> + .read_oen = &rzv2h_read_oen,
> + .write_oen = &rzv2h_write_oen,
> +};
> +
> static const struct of_device_id rzg2l_pinctrl_of_table[] = {
> {
> .compatible = "renesas,r9a07g043-pinctrl",
> @@ -2745,6 +3220,10 @@ static const struct of_device_id rzg2l_pinctrl_of_table[] = {
> .compatible = "renesas,r9a08g045-pinctrl",
> .data = &r9a08g045_data,
> },
> + {
> + .compatible = "renesas,r9a09g057-pinctrl",
> + .data = &r9a09g057_data,
> + },
> { /* sentinel */ }
> };
>

2024-03-28 08:14:39

by Claudiu

[permalink] [raw]
Subject: Re: [RFC PATCH 08/13] pinctrl: renesas: pinctrl-rzg2l: Add function pointers for writing to PFC



On 28.03.2024 10:02, claudiu beznea wrote:
> Hi, Prabhakar,
>
> On 27.03.2024 00:28, Prabhakar wrote:
>> From: Lad Prabhakar <[email protected]>
>>
>> On the RZ/G2L SoC, the PFCWE bit controls writing to PFC registers.
>> However, on the RZ/V2H(P) SoC, the PFCWE (REGWE_A on RZ/V2H) bit controls
>> writing to both PFC and PMC registers. To accommodate these differences
>> across SoC variants, introduce set_pfc_mode() and pm_set_pfc() function
>> pointers.
>
> I think the overall code can be simplified if you add 1 function that does
> the lock/unlock for PWPR. See patch 13.

I meant to say one function for lock and one for unlock.

>
>>
>> Signed-off-by: Lad Prabhakar <[email protected]>
>> ---
>> drivers/pinctrl/renesas/pinctrl-rzg2l.c | 14 ++++++++++++--
>> 1 file changed, 12 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
>> index 705372faaeff..4cdebdbd8a04 100644
>> --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
>> +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
>> @@ -246,6 +246,8 @@ struct rzg2l_variable_pin_cfg {
>> u32 pin:3;
>> };
>>
>> +struct rzg2l_pinctrl;
>> +
>> struct rzg2l_pinctrl_data {
>> const char * const *port_pins;
>> const u64 *port_pin_configs;
>> @@ -256,6 +258,8 @@ struct rzg2l_pinctrl_data {
>> const struct rzg2l_hwcfg *hwcfg;
>> const struct rzg2l_variable_pin_cfg *variable_pin_cfg;
>> unsigned int n_variable_pin_cfg;
>> + void (*set_pfc_mode)(struct rzg2l_pinctrl *pctrl, u8 pin, u8 off, u8 func);
>> + void (*pm_set_pfc)(struct rzg2l_pinctrl *pctrl);
>> };
>>
>> /**
>> @@ -526,7 +530,7 @@ static int rzg2l_pinctrl_set_mux(struct pinctrl_dev *pctldev,
>> dev_dbg(pctrl->dev, "port:%u pin: %u off:%x PSEL:%u\n",
>> RZG2L_PIN_ID_TO_PORT(pins[i]), pin, off, psel_val[i] - hwcfg->func_base);
>>
>> - rzg2l_pinctrl_set_pfc_mode(pctrl, pin, off, psel_val[i] - hwcfg->func_base);
>> + pctrl->data->set_pfc_mode(pctrl, pin, off, psel_val[i] - hwcfg->func_base);
>> }
>>
>> return 0;
>> @@ -2607,7 +2611,7 @@ static int rzg2l_pinctrl_resume_noirq(struct device *dev)
>> writeb(cache->eth_poc[i], pctrl->base + ETH_POC(regs->eth_poc, i));
>> }
>>
>> - rzg2l_pinctrl_pm_setup_pfc(pctrl);
>> + pctrl->data->pm_set_pfc(pctrl);
>> rzg2l_pinctrl_pm_setup_regs(pctrl, false);
>> rzg2l_pinctrl_pm_setup_dedicated_regs(pctrl, false);
>> rzg2l_gpio_irq_restore(pctrl);
>> @@ -2672,6 +2676,8 @@ static struct rzg2l_pinctrl_data r9a07g043_data = {
>> .variable_pin_cfg = r9a07g043f_variable_pin_cfg,
>> .n_variable_pin_cfg = ARRAY_SIZE(r9a07g043f_variable_pin_cfg),
>> #endif
>> + .set_pfc_mode = &rzg2l_pinctrl_set_pfc_mode,
>> + .pm_set_pfc = &rzg2l_pinctrl_pm_setup_pfc,
>> };
>>
>> static struct rzg2l_pinctrl_data r9a07g044_data = {
>> @@ -2683,6 +2689,8 @@ static struct rzg2l_pinctrl_data r9a07g044_data = {
>> .n_dedicated_pins = ARRAY_SIZE(rzg2l_dedicated_pins.common) +
>> ARRAY_SIZE(rzg2l_dedicated_pins.rzg2l_pins),
>> .hwcfg = &rzg2l_hwcfg,
>> + .set_pfc_mode = &rzg2l_pinctrl_set_pfc_mode,
>> + .pm_set_pfc = &rzg2l_pinctrl_pm_setup_pfc,
>> };
>>
>> static struct rzg2l_pinctrl_data r9a08g045_data = {
>> @@ -2693,6 +2701,8 @@ static struct rzg2l_pinctrl_data r9a08g045_data = {
>> .n_port_pins = ARRAY_SIZE(r9a08g045_gpio_configs) * RZG2L_PINS_PER_PORT,
>> .n_dedicated_pins = ARRAY_SIZE(rzg3s_dedicated_pins),
>> .hwcfg = &rzg3s_hwcfg,
>> + .set_pfc_mode = &rzg2l_pinctrl_set_pfc_mode,
>> + .pm_set_pfc = &rzg2l_pinctrl_pm_setup_pfc,
>> };
>>
>> static const struct of_device_id rzg2l_pinctrl_of_table[] = {

2024-03-28 08:16:54

by Claudiu

[permalink] [raw]
Subject: Re: [RFC PATCH 07/13] pinctrl: renesas: pinctrl-rzg2l: Validate power registers for SD and ETH

Hi, Prabhakar,

On 27.03.2024 00:28, Prabhakar wrote:
> From: Lad Prabhakar <[email protected]>
>
> On RZ/V2H(P) SoC, the power registers for SD and ETH do not exist,
> resulting in invalid register offsets. Ensure that the register offsets
> are valid before any read/write operations are performed. If the power
> registers are not available, both SD and ETH will be set to -EINVAL.
>
> Signed-off-by: Lad Prabhakar <[email protected]>
> ---
> drivers/pinctrl/renesas/pinctrl-rzg2l.c | 16 ++++++++++------
> 1 file changed, 10 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> index 348fdccaff72..705372faaeff 100644
> --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> @@ -184,8 +184,8 @@
> */
> struct rzg2l_register_offsets {
> u16 pwpr;
> - u16 sd_ch;
> - u16 eth_poc;
> + int sd_ch;
> + int eth_poc;
> };
>
> /**
> @@ -2567,8 +2567,10 @@ static int rzg2l_pinctrl_suspend_noirq(struct device *dev)
> rzg2l_pinctrl_pm_setup_dedicated_regs(pctrl, true);
>
> for (u8 i = 0; i < 2; i++) {
> - cache->sd_ch[i] = readb(pctrl->base + SD_CH(regs->sd_ch, i));
> - cache->eth_poc[i] = readb(pctrl->base + ETH_POC(regs->eth_poc, i));
> + if (regs->sd_ch != -EINVAL)

As of my knowledge, the current users of this driver uses SD and ETH
offsets different from zero. To avoid populating these values for all the
SoCs and avoid increasing the size of these fields I think you can add
checks like these:

if (regs->sd_ch)
// set sd_ch


Same for the rest.

> + cache->sd_ch[i] = readb(pctrl->base + SD_CH(regs->sd_ch, i));
> + if (regs->eth_poc != -EINVAL)
> + cache->eth_poc[i] = readb(pctrl->base + ETH_POC(regs->eth_poc, i));
> }
>
> cache->qspi = readb(pctrl->base + QSPI);
> @@ -2599,8 +2601,10 @@ static int rzg2l_pinctrl_resume_noirq(struct device *dev)
> writeb(cache->qspi, pctrl->base + QSPI);
> writeb(cache->eth_mode, pctrl->base + ETH_MODE);
> for (u8 i = 0; i < 2; i++) {
> - writeb(cache->sd_ch[i], pctrl->base + SD_CH(regs->sd_ch, i));
> - writeb(cache->eth_poc[i], pctrl->base + ETH_POC(regs->eth_poc, i));
> + if (regs->sd_ch != -EINVAL)
> + writeb(cache->sd_ch[i], pctrl->base + SD_CH(regs->sd_ch, i));
> + if (regs->eth_poc != -EINVAL)
> + writeb(cache->eth_poc[i], pctrl->base + ETH_POC(regs->eth_poc, i));
> }
>
> rzg2l_pinctrl_pm_setup_pfc(pctrl);

2024-03-28 14:14:23

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [RFC PATCH 06/13] pinctrl: renesas: pinctrl-rzg2l: Make cfg to u64 in struct rzg2l_variable_pin_cfg

Hi Prabhakar,

On Tue, Mar 26, 2024 at 11:30 PM Prabhakar <[email protected]> wrote:
> From: Lad Prabhakar <[email protected]>
>
> Now that we have updated the macro PIN_CFG_MASK to allow for the maximum
> configuration bits, update the size of 'cfg' to 'u64' in the
> 'struct rzg2l_variable_pin_cfg'.
>
> Signed-off-by: Lad Prabhakar <[email protected]>

Thanks for your patch!

> --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> @@ -241,7 +241,7 @@ struct rzg2l_dedicated_configs {
> * @pin: port pin
> */
> struct rzg2l_variable_pin_cfg {
> - u32 cfg:20;
> + u64 cfg:46;
> u32 port:5;
> u32 pin:3;

Doesn't this store the 46 cfg bits in a 64-bit word, and the 8 port
and pin bits in a different 32-bit word? Worse, you'll get 4 bytes
of padding at the end of the structure.
Changing the port and pin to u64 should make sure everything is
stored together in a single 64-bit word.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68korg

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2024-03-28 19:41:07

by Prabhakar

[permalink] [raw]
Subject: Re: [RFC PATCH 07/13] pinctrl: renesas: pinctrl-rzg2l: Validate power registers for SD and ETH

Hi Claudiu,

Thank you for the review.

On Thu, Mar 28, 2024 at 8:01 AM claudiu beznea <[email protected]> wrote:
>
> Hi, Prabhakar,
>
> On 27.03.2024 00:28, Prabhakar wrote:
> > From: Lad Prabhakar <[email protected]>
> >
> > On RZ/V2H(P) SoC, the power registers for SD and ETH do not exist,
> > resulting in invalid register offsets. Ensure that the register offsets
> > are valid before any read/write operations are performed. If the power
> > registers are not available, both SD and ETH will be set to -EINVAL.
> >
> > Signed-off-by: Lad Prabhakar <[email protected]>
> > ---
> > drivers/pinctrl/renesas/pinctrl-rzg2l.c | 16 ++++++++++------
> > 1 file changed, 10 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> > index 348fdccaff72..705372faaeff 100644
> > --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> > +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> > @@ -184,8 +184,8 @@
> > */
> > struct rzg2l_register_offsets {
> > u16 pwpr;
> > - u16 sd_ch;
> > - u16 eth_poc;
> > + int sd_ch;
> > + int eth_poc;
> > };
> >
> > /**
> > @@ -2567,8 +2567,10 @@ static int rzg2l_pinctrl_suspend_noirq(struct device *dev)
> > rzg2l_pinctrl_pm_setup_dedicated_regs(pctrl, true);
> >
> > for (u8 i = 0; i < 2; i++) {
> > - cache->sd_ch[i] = readb(pctrl->base + SD_CH(regs->sd_ch, i));
> > - cache->eth_poc[i] = readb(pctrl->base + ETH_POC(regs->eth_poc, i));
> > + if (regs->sd_ch != -EINVAL)
>
> As of my knowledge, the current users of this driver uses SD and ETH
> offsets different from zero. To avoid populating these values for all the
> SoCs and avoid increasing the size of these fields I think you can add
> checks like these:
>
> if (regs->sd_ch)
> // set sd_ch
>
Agreed.

>
> Same for the rest.
>
OK.

Cheers,
Prabhakar

2024-03-28 19:53:25

by Prabhakar

[permalink] [raw]
Subject: Re: [RFC PATCH 08/13] pinctrl: renesas: pinctrl-rzg2l: Add function pointers for writing to PFC

Hi Claudiu,

Thank you for the review.

On Thu, Mar 28, 2024 at 8:13 AM claudiu beznea <[email protected]> wrote:
>
>
>
> On 28.03.2024 10:02, claudiu beznea wrote:
> > Hi, Prabhakar,
> >
> > On 27.03.2024 00:28, Prabhakar wrote:
> >> From: Lad Prabhakar <[email protected]>
> >>
> >> On the RZ/G2L SoC, the PFCWE bit controls writing to PFC registers.
> >> However, on the RZ/V2H(P) SoC, the PFCWE (REGWE_A on RZ/V2H) bit controls
> >> writing to both PFC and PMC registers. To accommodate these differences
> >> across SoC variants, introduce set_pfc_mode() and pm_set_pfc() function
> >> pointers.
> >
> > I think the overall code can be simplified if you add 1 function that does
> > the lock/unlock for PWPR. See patch 13.
>
> I meant to say one function for lock and one for unlock.
>
I agree, let me remodel it that way.

Cheers,
Prabhakar

2024-03-28 19:57:48

by Prabhakar

[permalink] [raw]
Subject: Re: [RFC PATCH 13/13] pinctrl: renesas: pinctrl-rzg2l: Add support for RZ/V2H SoC

Hi Claudiu,

Thank you for the review.

On Thu, Mar 28, 2024 at 8:04 AM claudiu beznea <[email protected]> wrote:
>
> Hi, Prabhakar,
>
> On 27.03.2024 00:28, Prabhakar wrote:
> > From: Lad Prabhakar <[email protected]>
> >
> > Add pinctrl driver support for RZ/V2H(P) SoC.
> >
> > Signed-off-by: Lad Prabhakar <[email protected]>
> > ---
> > drivers/pinctrl/renesas/pinctrl-rzg2l.c | 483 +++++++++++++++++++++++-
> > 1 file changed, 481 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> > index 6f0c85bb97a8..716c11ca5a8f 100644
> > --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> > +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> > @@ -59,6 +59,13 @@
> > #define PIN_CFG_OEN BIT(15)
> > #define PIN_CFG_VARIABLE BIT(16)
> > #define PIN_CFG_NOGPIO_INT BIT(17)
> > +#define PIN_CFG_OPEN_DRAIN BIT(18)
> > +#define PIN_CFG_SCHMIT_CTRL BIT(19)
> > +#define PIN_CFG_ELC BIT(20)
> > +#define PIN_CFG_IOLH_1 BIT(21)
> > +#define PIN_CFG_IOLH_2 BIT(22)
> > +#define PIN_CFG_IOLH_3 BIT(23)
> > +#define PIN_CFG_IOLH_4 BIT(24)
> >
> > #define RZG2L_MPXED_COMMON_PIN_FUNCS(group) \
> > (PIN_CFG_IOLH_##group | \
> > @@ -70,6 +77,10 @@
> > #define RZG2L_MPXED_PIN_FUNCS (RZG2L_MPXED_COMMON_PIN_FUNCS(A) | \
> > PIN_CFG_SR)
> >
> > +#define RZV2H_MPXED_PIN_FUNCS(group) (RZG2L_MPXED_COMMON_PIN_FUNCS(group) | \
> > + PIN_CFG_OPEN_DRAIN | \
> > + PIN_CFG_SR)
> > +
> > #define RZG3S_MPXED_PIN_FUNCS(group) (RZG2L_MPXED_COMMON_PIN_FUNCS(group) | \
> > PIN_CFG_SOFT_PS)
> >
> > @@ -133,6 +144,8 @@
> >
> > #define PWPR_B0WI BIT(7) /* Bit Write Disable */
> > #define PWPR_PFCWE BIT(6) /* PFC Register Write Enable */
> > +#define PWPR_REGWE_A BIT(6) /* PFC and PMC Register Write Enable */
> > +#define PWPR_REGWE_B BIT(5) /* OEN Register Write Enable */
> >
> > #define PM_MASK 0x03
> > #define PFC_MASK 0x07
> > @@ -149,6 +162,19 @@
> > #define RZG2L_TINT_IRQ_START_INDEX 9
> > #define RZG2L_PACK_HWIRQ(t, i) (((t) << 16) | (i))
> >
> > +/* Custom pinconf parameters */
> > +#define RENESAS_RZV2H_PIN_CONFIG_OUTPUT_IMPEDANCE (PIN_CONFIG_END + 1)
> > +
> > +static const struct pinconf_generic_params renesas_rzv2h_custom_bindings[] = {
> > + { "renesas-rzv2h,output-impedance", RENESAS_RZV2H_PIN_CONFIG_OUTPUT_IMPEDANCE, 1 },
> > +};
> > +
> > +#ifdef CONFIG_DEBUG_FS
> > +static const struct pin_config_item renesas_rzv2h_conf_items[] = {
> > + PCONFDUMP(RENESAS_RZV2H_PIN_CONFIG_OUTPUT_IMPEDANCE, "output-impedance", "x", true),
> > +};
> > +#endif
> > +
> > /* Read/write 8 bits register */
> > #define RZG2L_PCTRL_REG_ACCESS8(_read, _addr, _val) \
> > do { \
> > @@ -324,6 +350,8 @@ struct rzg2l_pinctrl {
> > spinlock_t lock; /* lock read/write registers */
> > struct mutex mutex; /* serialize adding groups and functions */
> >
> > + raw_spinlock_t pwpr_lock; /* serialize PWPR register access */
> > +
> > struct rzg2l_pinctrl_pin_settings *settings;
> > struct rzg2l_pinctrl_reg_cache *cache;
> > struct rzg2l_pinctrl_reg_cache *dedicated_cache;
> > @@ -348,6 +376,79 @@ static u64 rzg2l_pinctrl_get_variable_pin_cfg(struct rzg2l_pinctrl *pctrl,
> > return 0;
> > }
> >
> > +static const struct rzg2l_variable_pin_cfg r9a09g057_variable_pin_cfg[] = {
> > + {
> > + .port = 9,
> > + .pin = 0,
> > + .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL,
> > + },
> > + {
> > + .port = 9,
> > + .pin = 1,
> > + .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL,
> > + },
> > + {
> > + .port = 9,
> > + .pin = 2,
> > + .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL,
> > + },
> > + {
> > + .port = 9,
> > + .pin = 3,
> > + .cfg = RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL,
> > + },
> > + {
> > + .port = 9,
> > + .pin = 4,
> > + .cfg = RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL,
> > + },
> > + {
> > + .port = 9,
> > + .pin = 5,
> > + .cfg = RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL,
> > + },
> > + {
> > + .port = 9,
> > + .pin = 6,
> > + .cfg = RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL,
> > + },
> > + {
> > + .port = 9,
> > + .pin = 7,
> > + .cfg = RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL,
> > + },
> > + {
> > + .port = 11,
> > + .pin = 0,
> > + .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL,
> > + },
> > + {
> > + .port = 11,
> > + .pin = 1,
> > + .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL | PIN_CFG_IEN,
> > + },
> > + {
> > + .port = 11,
> > + .pin = 2,
> > + .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL | PIN_CFG_IEN,
> > + },
> > + {
> > + .port = 11,
> > + .pin = 3,
> > + .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL | PIN_CFG_IEN,
> > + },
> > + {
> > + .port = 11,
> > + .pin = 4,
> > + .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL | PIN_CFG_IEN,
> > + },
> > + {
> > + .port = 11,
> > + .pin = 5,
> > + .cfg = RZV2H_MPXED_PIN_FUNCS(2) | PIN_CFG_SCHMIT_CTRL | PIN_CFG_IEN,
> > + },
> > +};
> > +
> > #ifdef CONFIG_RISCV
> > static const struct rzg2l_variable_pin_cfg r9a07g043f_variable_pin_cfg[] = {
> > {
> > @@ -474,6 +575,19 @@ static void rzg2l_pmc_writeb(struct rzg2l_pinctrl *pctrl, u8 val, void __iomem *
> > writeb(val, addr);
> > }
> >
> > +static void rzv2h_pmc_writeb(struct rzg2l_pinctrl *pctrl, u8 val, void __iomem *addr)
> > +{
> > + const struct rzg2l_register_offsets *regs = &pctrl->data->hwcfg->regs;
> > + u8 pwpr;
> > +
> > + raw_spin_lock(&pctrl->pwpr_lock);
> > + pwpr = readb(pctrl->base + regs->pwpr);
> > + writeb(pwpr | PWPR_REGWE_A, pctrl->base + regs->pwpr);
>
> What about having a device specific function that locks/unlocks the PWPR,
> this part ^ being the lock.
>
>
OK, ill have SoC specific function to lock/unlock.
>
> > + writeb(val, addr);
>
> And this starting here:
>
> > + writeb(pwpr & ~PWPR_REGWE_A, pctrl->base + regs->pwpr);
> > + raw_spin_unlock(&pctrl->pwpr_lock);
>
> ending here: the unlock function. It should generate les diffs at least in
> this patch.
>
> And you can add, were needed:
>
> if (pctrl->pwpr_lock_function)
> pctrl->pwpr_lock_function();
>
> write(val, addr);
>
> if (pctrl->pwpr_unlock_function)
> pctrl->pwpr_unlock_function();
>
>
> With this you can avoid adding rzv2h_pinctrl_set_pfc_mode() which is alomst
> identical w/ rzg2l_pinctrl_set_pfc_mode(), or adding
> rzv2h_pinctrl_pm_setup_pfc() almost identical with
> rzg2l_pinctrl_pm_setup_pfc().
>
Agreed.

> > +}
> > +
> > static void rzg2l_pinctrl_set_pfc_mode(struct rzg2l_pinctrl *pctrl,
> > u8 pin, u8 off, u8 func)
> > {
> > @@ -512,6 +626,47 @@ static void rzg2l_pinctrl_set_pfc_mode(struct rzg2l_pinctrl *pctrl,
> > spin_unlock_irqrestore(&pctrl->lock, flags);
> > };
> >
> > +static void rzv2h_pinctrl_set_pfc_mode(struct rzg2l_pinctrl *pctrl,
> > + u8 pin, u8 off, u8 func)
> > +{
> > + const struct rzg2l_register_offsets *regs = &pctrl->data->hwcfg->regs;
> > + unsigned long flags;
> > + u32 reg;
> > + u8 pwpr;
> > +
> > + spin_lock_irqsave(&pctrl->lock, flags);
> > +
> > + /* Set pin to 'Non-use (Hi-Z input protection)' */
> > + reg = readw(pctrl->base + PM(off));
> > + reg &= ~(PM_MASK << (pin * 2));
> > + writew(reg, pctrl->base + PM(off));
> > +
> > + /* Set the PWPR register to allow PFC and PMC register to write */
> > + raw_spin_lock(&pctrl->pwpr_lock);
> > + pwpr = readb(pctrl->base + regs->pwpr);
> > + writeb(PWPR_PFCWE | pwpr, pctrl->base + regs->pwpr);
> > +
> > + /* Temporarily switch to GPIO mode with PMC register */
> > + reg = readb(pctrl->base + PMC(off));
> > + writeb(reg & ~BIT(pin), pctrl->base + PMC(off));
> > +
> > + /* Select Pin function mode with PFC register */
> > + reg = readl(pctrl->base + PFC(off));
> > + reg &= ~(PFC_MASK << (pin * 4));
> > + writel(reg | (func << (pin * 4)), pctrl->base + PFC(off));
> > +
> > + /* Switch to Peripheral pin function with PMC register */
> > + reg = readb(pctrl->base + PMC(off));
> > + writeb(reg | BIT(pin), pctrl->base + PMC(off));
> > +
> > + /* Set the PWPR register to be write-protected */
> > + pwpr = readb(pctrl->base + regs->pwpr);
> > + writeb(pwpr & ~PWPR_PFCWE, pctrl->base + regs->pwpr);
> > + raw_spin_unlock(&pctrl->pwpr_lock);
> > +
> > + spin_unlock_irqrestore(&pctrl->lock, flags);
> > +};
> > +
> > static int rzg2l_pinctrl_set_mux(struct pinctrl_dev *pctldev,
> > unsigned int func_selector,
> > unsigned int group_selector)
> > @@ -1087,14 +1242,26 @@ static int rzg2l_write_oen(struct rzg2l_pinctrl *pctrl, u32 caps, u32 offset, u8
> > return 0;
> > }
> >
> > +static u32 rzv2h_read_oen(struct rzg2l_pinctrl *pctrl, u32 caps, u32 offset, u8 pin)
> > +{
> > + /* stub */
> > + return 0;
> > +}
> > +
> > +static int rzv2h_write_oen(struct rzg2l_pinctrl *pctrl, u32 caps, u32 offset, u8 pin, u8 oen)
> > +{
> > + /* stub */
> > + return -EINVAL;
> > +}
> > +
>
> What about chekcing:
> if (pctrl->data->read_oen)
> ret = pctrl->data->read_oen()
>
> if (pctrl->data->write_oen)
> ret = pctrl->data->write_oen()
>
> Accross the driver. This will avoid adding stubs each time suppor for a new
> IP is added.
>
I plan to fill this up in a non-rfc series.

> > static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *pctldev,
> > unsigned int _pin,
> > unsigned long *config)
> > {
> > struct rzg2l_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
> > - enum pin_config_param param = pinconf_to_config_param(*config);
> > const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg;
> > const struct pinctrl_pin_desc *pin = &pctrl->desc.pins[_pin];
> > + u32 param = pinconf_to_config_param(*config);
> > u64 *pin_data = pin->drv_data;
> > unsigned int arg = 0;
> > u32 off, cfg;
> > @@ -1180,6 +1347,30 @@ static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *pctldev,
> > break;
> > }
> >
> > + case RENESAS_RZV2H_PIN_CONFIG_OUTPUT_IMPEDANCE: {
> > + u8 val;
> > +
> > + if (!(cfg & (PIN_CFG_IOLH_1 | PIN_CFG_IOLH_2 | PIN_CFG_IOLH_3 | PIN_CFG_IOLH_4)))
> > + return -EINVAL;
> > +
> > + val = rzg2l_read_pin_config(pctrl, IOLH(off), bit, IOLH_MASK);
> > + switch (val) {
> > + case 0:
> > + arg = 1;
> > + break;
> > + case 1:
> > + arg = 2;
> > + break;
> > + case 2:
> > + arg = 4;
> > + break;
> > + default:
> > + arg = 6;
> > + break;
> > + }
> > + break;
> > + }
> > +
> > default:
> > return -ENOTSUPP;
> > }
> > @@ -1199,9 +1390,9 @@ static int rzg2l_pinctrl_pinconf_set(struct pinctrl_dev *pctldev,
> > const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg;
> > struct rzg2l_pinctrl_pin_settings settings = pctrl->settings[_pin];
> > u64 *pin_data = pin->drv_data;
> > - enum pin_config_param param;
> > unsigned int i, arg, index;
> > u32 cfg, off;
> > + u32 param;
> > int ret;
> > u8 bit;
> >
> > @@ -1283,6 +1474,32 @@ static int rzg2l_pinctrl_pinconf_set(struct pinctrl_dev *pctldev,
> > rzg2l_rmw_pin_config(pctrl, IOLH(off), bit, IOLH_MASK, index);
> > break;
> >
> > + case RENESAS_RZV2H_PIN_CONFIG_OUTPUT_IMPEDANCE:
> > + arg = pinconf_to_config_argument(_configs[i]);
> > +
> > + if (!(cfg & (PIN_CFG_IOLH_1 | PIN_CFG_IOLH_2 |
> > + PIN_CFG_IOLH_3 | PIN_CFG_IOLH_4)))
> > + return -EINVAL;
> > +
> > + switch (arg) {
> > + case 1:
> > + index = 0;
> > + break;
> > + case 2:
> > + index = 1;
> > + break;
> > + case 4:
> > + index = 2;
> > + break;
> > + case 6:
> > + index = 3;
> > + break;
> > + default:
> > + return -EINVAL;
> > + }
> > + rzg2l_rmw_pin_config(pctrl, IOLH(off), bit, IOLH_MASK, index);
> > + break;
> > +
> > default:
> > return -EOPNOTSUPP;
> > }
> > @@ -1730,6 +1947,38 @@ static const u64 r9a08g045_gpio_configs[] = {
> > RZG2L_GPIO_PORT_PACK(6, 0x2a, RZG3S_MPXED_PIN_FUNCS(A)), /* P18 */
> > };
> >
> > +static const char * const rzv2h_gpio_names[] = {
> > + "P00", "P01", "P02", "P03", "P04", "P05", "P06", "P07",
> > + "P10", "P11", "P12", "P13", "P14", "P15", "P16", "P17",
> > + "P20", "P21", "P22", "P23", "P24", "P25", "P26", "P27",
> > + "P30", "P31", "P32", "P33", "P34", "P35", "P36", "P37",
> > + "P40", "P41", "P42", "P43", "P44", "P45", "P46", "P47",
> > + "P50", "P51", "P52", "P53", "P54", "P55", "P56", "P57",
> > + "P60", "P61", "P62", "P63", "P64", "P65", "P66", "P67",
> > + "P70", "P71", "P72", "P73", "P74", "P75", "P76", "P77",
> > + "P80", "P81", "P82", "P83", "P84", "P85", "P86", "P87",
> > + "P90", "P91", "P92", "P93", "P94", "P95", "P96", "P97",
> > + "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7",
> > + "PB0", "PB1", "PB2", "PB3", "PB4", "PB5", "PB6", "PB7",
> > +};
> > +
> > +static const u64 r9a09g057_gpio_configs[] = {
> > + RZG2L_GPIO_PORT_PACK(8, 0x20, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* P0 */
> > + RZG2L_GPIO_PORT_PACK(6, 0x21, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* P1 */
> > + RZG2L_GPIO_PORT_PACK(2, 0x22, RZV2H_MPXED_PIN_FUNCS(4)), /* P2 */
> > + RZG2L_GPIO_PORT_PACK(8, 0x23, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* P3 */
> > + RZG2L_GPIO_PORT_PACK(8, 0x24, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* P4 */
> > + RZG2L_GPIO_PORT_PACK(8, 0x25, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* P5 */
> > + RZG2L_GPIO_PORT_PACK(8, 0x26, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL |
> > + PIN_CFG_ELC), /* P6 */
> > + RZG2L_GPIO_PORT_PACK(8, 0x27, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* P7 */
> > + RZG2L_GPIO_PORT_PACK(8, 0x28, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL |
> > + PIN_CFG_ELC), /* P8 */
> > + RZG2L_GPIO_PORT_PACK(8, 0x29, PIN_CFG_VARIABLE), /* P9 */
> > + RZG2L_GPIO_PORT_PACK(8, 0x2a, RZV2H_MPXED_PIN_FUNCS(3) | PIN_CFG_SCHMIT_CTRL), /* PA */
> > + RZG2L_GPIO_PORT_PACK(6, 0x2b, PIN_CFG_VARIABLE), /* PB */
> > +};
> > +
> > static const struct {
> > struct rzg2l_dedicated_configs common[35];
> > struct rzg2l_dedicated_configs rzg2l_pins[7];
> > @@ -1856,6 +2105,139 @@ static const struct rzg2l_dedicated_configs rzg3s_dedicated_pins[] = {
> > PIN_CFG_IO_VMC_SD1)) },
> > };
> >
> > +static struct rzg2l_dedicated_configs rzv2h_dedicated_pins[] = {
> > + { "NMI", RZG2L_SINGLE_PIN_PACK(0x1, 0, (PIN_CFG_FILONOFF | PIN_CFG_FILNUM |
> > + PIN_CFG_FILCLKSEL)) },
> > + { "TMS_SWDIO", RZG2L_SINGLE_PIN_PACK(0x3, 0, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
> > + PIN_CFG_IEN)) },
> > + { "TDO", RZG2L_SINGLE_PIN_PACK(0x3, 2, (PIN_CFG_IOLH_1 | PIN_CFG_SR)) },
> > + { "WDTUDFCA", RZG2L_SINGLE_PIN_PACK(0x5, 0, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "WDTUDFCM", RZG2L_SINGLE_PIN_PACK(0x5, 1, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "SCIF_RXD", RZG2L_SINGLE_PIN_PACK(0x6, 0, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "SCIF_TXD", RZG2L_SINGLE_PIN_PACK(0x6, 1, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "XSPI0_CKP", RZG2L_SINGLE_PIN_PACK(0x7, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD | PIN_CFG_OEN)) },
> > + { "XSPI0_CKN", RZG2L_SINGLE_PIN_PACK(0x7, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD | PIN_CFG_OEN)) },
> > + { "XSPI0_CS0N", RZG2L_SINGLE_PIN_PACK(0x7, 2, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
> > + PIN_CFG_PUPD | PIN_CFG_OEN)) },
> > + { "XSPI0_DS", RZG2L_SINGLE_PIN_PACK(0x7, 3, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "XSPI0_RESET0N", RZG2L_SINGLE_PIN_PACK(0x7, 4, (PIN_CFG_IOLH_1 | PIN_CFG_SR |
> > + PIN_CFG_PUPD | PIN_CFG_OEN)) },
> > + { "XSPI0_RSTO0N", RZG2L_SINGLE_PIN_PACK(0x7, 5, (PIN_CFG_PUPD)) },
> > + { "XSPI0_INT0N", RZG2L_SINGLE_PIN_PACK(0x7, 6, (PIN_CFG_PUPD)) },
> > + { "XSPI0_ECS0N", RZG2L_SINGLE_PIN_PACK(0x7, 7, (PIN_CFG_PUPD)) },
> > + { "XSPI0_IO0", RZG2L_SINGLE_PIN_PACK(0x8, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "XSPI0_IO1", RZG2L_SINGLE_PIN_PACK(0x8, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "XSPI0_IO2", RZG2L_SINGLE_PIN_PACK(0x8, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "XSPI0_IO3", RZG2L_SINGLE_PIN_PACK(0x8, 3, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "XSPI0_IO4", RZG2L_SINGLE_PIN_PACK(0x8, 4, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "XSPI0_IO5", RZG2L_SINGLE_PIN_PACK(0x8, 5, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "XSPI0_IO6", RZG2L_SINGLE_PIN_PACK(0x8, 6, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "XSPI0_IO7", RZG2L_SINGLE_PIN_PACK(0x8, 7, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "SD0CLK", RZG2L_SINGLE_PIN_PACK(0x9, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR)) },
> > + { "SD0CMD", RZG2L_SINGLE_PIN_PACK(0x9, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR)) },
> > + { "SD0RSTN", RZG2L_SINGLE_PIN_PACK(0x9, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> > + { "SD0DAT0", RZG2L_SINGLE_PIN_PACK(0xa, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> > + { "SD0DAT1", RZG2L_SINGLE_PIN_PACK(0xa, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> > + { "SD0DAT2", RZG2L_SINGLE_PIN_PACK(0xa, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> > + { "SD0DAT3", RZG2L_SINGLE_PIN_PACK(0xa, 3, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> > + { "SD0DAT4", RZG2L_SINGLE_PIN_PACK(0xa, 4, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> > + { "SD0DAT5", RZG2L_SINGLE_PIN_PACK(0xa, 5, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> > + { "SD0DAT6", RZG2L_SINGLE_PIN_PACK(0xa, 6, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_IOLH_2 | PIN_CFG_PUPD)) },
> > + { "SD0DAT7", RZG2L_SINGLE_PIN_PACK(0xa, 7, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> > + { "SD1_CLK", RZG2L_SINGLE_PIN_PACK(0xb, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR)) },
> > + { "SD1_CMD", RZG2L_SINGLE_PIN_PACK(0xb, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> > + { "SD1_DAT0", RZG2L_SINGLE_PIN_PACK(0xc, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> > + { "SD1_DAT1", RZG2L_SINGLE_PIN_PACK(0xc, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> > + { "SD1_DAT2", RZG2L_SINGLE_PIN_PACK(0xc, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> > + { "SD1_DAT3", RZG2L_SINGLE_PIN_PACK(0xc, 3, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> > + { "PCIE0_RSTOUTB", RZG2L_SINGLE_PIN_PACK(0xe, 0, (PIN_CFG_IOLH_1 | PIN_CFG_SR)) },
> > + { "PCIE1_RSTOUTB", RZG2L_SINGLE_PIN_PACK(0xe, 1, (PIN_CFG_IOLH_1 | PIN_CFG_SR)) },
> > + { "ET0_MDIO", RZG2L_SINGLE_PIN_PACK(0xf, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_IEN | PIN_CFG_PUPD)) },
> > + { "ET0_MDC", RZG2L_SINGLE_PIN_PACK(0xf, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "ET0_RXCTL_RXDV", RZG2L_SINGLE_PIN_PACK(0x10, 0, (PIN_CFG_PUPD)) },
> > + { "ET0_TXCTL_TXEN", RZG2L_SINGLE_PIN_PACK(0x10, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "ET0_TXER", RZG2L_SINGLE_PIN_PACK(0x10, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "ET0_RXER", RZG2L_SINGLE_PIN_PACK(0x10, 3, (PIN_CFG_PUPD)) },
> > + { "ET0_RXC_RXCLK", RZG2L_SINGLE_PIN_PACK(0x10, 4, (PIN_CFG_PUPD)) },
> > + { "ET0_TXC_TXCLK", RZG2L_SINGLE_PIN_PACK(0x10, 5, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD | PIN_CFG_OEN)) },
> > + { "ET0_CRS", RZG2L_SINGLE_PIN_PACK(0x10, 6, (PIN_CFG_PUPD)) },
> > + { "ET0_COL", RZG2L_SINGLE_PIN_PACK(0x10, 7, (PIN_CFG_PUPD)) },
> > + { "ET0_TXD0", RZG2L_SINGLE_PIN_PACK(0x11, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "ET0_TXD1", RZG2L_SINGLE_PIN_PACK(0x11, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "ET0_TXD2", RZG2L_SINGLE_PIN_PACK(0x11, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "ET0_TXD3", RZG2L_SINGLE_PIN_PACK(0x11, 3, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "ET0_RXD0", RZG2L_SINGLE_PIN_PACK(0x11, 4, (PIN_CFG_PUPD)) },
> > + { "ET0_RXD1", RZG2L_SINGLE_PIN_PACK(0x11, 5, (PIN_CFG_PUPD)) },
> > + { "ET0_RXD2", RZG2L_SINGLE_PIN_PACK(0x11, 6, (PIN_CFG_PUPD)) },
> > + { "ET0_RXD3", RZG2L_SINGLE_PIN_PACK(0x11, 7, (PIN_CFG_PUPD)) },
> > + { "ET1_MDIO", RZG2L_SINGLE_PIN_PACK(0x12, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_SR | PIN_CFG_IEN |
> > + PIN_CFG_PUPD)) },
> > + { "ET1_MDC", RZG2L_SINGLE_PIN_PACK(0x12, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "ET1_RXCTL_RXDV", RZG2L_SINGLE_PIN_PACK(0x13, 0, (PIN_CFG_PUPD)) },
> > + { "ET1_TXCTL_TXEN", RZG2L_SINGLE_PIN_PACK(0x13, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "ET1_TXER", RZG2L_SINGLE_PIN_PACK(0x13, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "ET1_RXER", RZG2L_SINGLE_PIN_PACK(0x13, 3, (PIN_CFG_PUPD)) },
> > + { "ET1_RXC_RXCLK", RZG2L_SINGLE_PIN_PACK(0x13, 4, (PIN_CFG_PUPD)) },
> > + { "ET1_TXC_TXCLK", RZG2L_SINGLE_PIN_PACK(0x13, 5, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD | PIN_CFG_OEN)) },
> > + { "ET1_CRS", RZG2L_SINGLE_PIN_PACK(0x13, 6, (PIN_CFG_PUPD)) },
> > + { "ET1_COL", RZG2L_SINGLE_PIN_PACK(0x13, 7, (PIN_CFG_PUPD)) },
> > + { "ET1_TXD0", RZG2L_SINGLE_PIN_PACK(0x14, 0, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "ET1_TXD1", RZG2L_SINGLE_PIN_PACK(0x14, 1, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "ET1_TXD2", RZG2L_SINGLE_PIN_PACK(0x14, 2, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "ET1_TXD3", RZG2L_SINGLE_PIN_PACK(0x14, 3, (PIN_CFG_IOLH_2 | PIN_CFG_SR |
> > + PIN_CFG_PUPD)) },
> > + { "ET1_RXD0", RZG2L_SINGLE_PIN_PACK(0x14, 4, (PIN_CFG_PUPD)) },
> > + { "ET1_RXD1", RZG2L_SINGLE_PIN_PACK(0x14, 5, (PIN_CFG_PUPD)) },
> > + { "ET1_RXD2", RZG2L_SINGLE_PIN_PACK(0x14, 6, (PIN_CFG_PUPD)) },
> > + { "ET1_RXD3", RZG2L_SINGLE_PIN_PACK(0x14, 7, (PIN_CFG_PUPD)) },
> > +};
> > +
> > static int rzg2l_gpio_get_gpioint(unsigned int virq, struct rzg2l_pinctrl *pctrl)
> > {
> > const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[virq];
> > @@ -2380,6 +2762,9 @@ static int rzg2l_pinctrl_probe(struct platform_device *pdev)
> > BUILD_BUG_ON(ARRAY_SIZE(r9a08g045_gpio_configs) * RZG2L_PINS_PER_PORT >
> > ARRAY_SIZE(rzg2l_gpio_names));
> >
> > + BUILD_BUG_ON(ARRAY_SIZE(r9a09g057_gpio_configs) * RZG2L_PINS_PER_PORT >
> > + ARRAY_SIZE(rzv2h_gpio_names));
> > +
> > pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
> > if (!pctrl)
> > return -ENOMEM;
> > @@ -2402,6 +2787,7 @@ static int rzg2l_pinctrl_probe(struct platform_device *pdev)
> >
> > spin_lock_init(&pctrl->lock);
> > spin_lock_init(&pctrl->bitmap_lock);
> > + raw_spin_lock_init(&pctrl->pwpr_lock);
> > mutex_init(&pctrl->mutex);
> > atomic_set(&pctrl->wakeup_path, 0);
> >
> > @@ -2578,6 +2964,65 @@ static void rzg2l_pinctrl_pm_setup_pfc(struct rzg2l_pinctrl *pctrl)
> > writel(PWPR_B0WI, pctrl->base + regs->pwpr); /* B0WI=1, PFCWE=0 */
> > }
> >
> > +static void rzv2h_pinctrl_pm_setup_pfc(struct rzg2l_pinctrl *pctrl)
>
> Have you managed to test this?
>
No S2R isn't tested and is just added for completeness, I wonder if we
should have a SoC specific flag "pm_supported" for this, as apart from
RZ/G3S nothing has been tested I believe?

Cheers,
Prabhakar

2024-03-28 19:58:04

by Prabhakar

[permalink] [raw]
Subject: Re: [RFC PATCH 06/13] pinctrl: renesas: pinctrl-rzg2l: Make cfg to u64 in struct rzg2l_variable_pin_cfg

Hi Geert,

Thank you for the review.

On Thu, Mar 28, 2024 at 2:14 PM Geert Uytterhoeven <[email protected]> wrote:
>
> Hi Prabhakar,
>
> On Tue, Mar 26, 2024 at 11:30 PM Prabhakar <[email protected]> wrote:
> > From: Lad Prabhakar <[email protected]>
> >
> > Now that we have updated the macro PIN_CFG_MASK to allow for the maximum
> > configuration bits, update the size of 'cfg' to 'u64' in the
> > 'struct rzg2l_variable_pin_cfg'.
> >
> > Signed-off-by: Lad Prabhakar <[email protected]>
>
> Thanks for your patch!
>
> > --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> > +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> > @@ -241,7 +241,7 @@ struct rzg2l_dedicated_configs {
> > * @pin: port pin
> > */
> > struct rzg2l_variable_pin_cfg {
> > - u32 cfg:20;
> > + u64 cfg:46;
> > u32 port:5;
> > u32 pin:3;
>
> Doesn't this store the 46 cfg bits in a 64-bit word, and the 8 port
> and pin bits in a different 32-bit word? Worse, you'll get 4 bytes
> of padding at the end of the structure.
Agreed.

> Changing the port and pin to u64 should make sure everything is
> stored together in a single 64-bit word.
>
I'll change the port and pin to u64 .

Cheers,
Prabhakar

2024-03-29 07:13:32

by Claudiu

[permalink] [raw]
Subject: Re: [RFC PATCH 13/13] pinctrl: renesas: pinctrl-rzg2l: Add support for RZ/V2H SoC



On 28.03.2024 21:51, Lad, Prabhakar wrote:
>>> +static void rzv2h_pinctrl_pm_setup_pfc(struct rzg2l_pinctrl *pctrl)
>> Have you managed to test this?
>>
> No S2R isn't tested and is just added for completeness, I wonder if we
> should have a SoC specific flag "pm_supported" for this, as apart from
> RZ/G3S nothing has been tested I believe?

Yes, only RZ/G3S PM has been tested.