2024-04-23 17:59:31

by Prabhakar

[permalink] [raw]
Subject: [PATCH v2 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.


RFC->v2
- Fixed review comments pointed by Rob
- Incorporated changes suggested by Claudiu
- Fixed build error reported for m68K
- Dropped IOLH groups as we will be passing register values
- Fixed configs for dedicated pins
- Added support for slew-rate and bias settings
- Added support for OEN

RFC: https://patchwork.kernel.org/project/linux-renesas-soc/cover/[email protected]/

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: Allow more bits for pin configuration
pinctrl: renesas: pinctrl-rzg2l: Allow parsing of variable
configuration for all architectures
pinctrl: renesas: pinctrl-rzg2l: Validate power registers for SD and
ETH
pinctrl: renesas: pinctrl-rzg2l: Add function pointers for
locking/unlocking the PFC register
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: Add support to configure the
slew-rate
pinctrl: renesas: pinctrl-rzg2l: Add support to set pulling up/down
the pins
pinctrl: renesas: pinctrl-rzg2l: Pass pincontrol device pointer to
pinconf_generic_parse_dt_config()
pinctrl: renesas: pinctrl-rzg2l: Add support for custom parameters
pinctrl: renesas: pinctrl-rzg2l: Add support for RZ/V2H SoC

.../pinctrl/renesas,rzg2l-pinctrl.yaml | 40 +-
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 640 ++++++++++++++++--
2 files changed, 617 insertions(+), 63 deletions(-)

--
2.34.1



2024-04-23 17:59:36

by Prabhakar

[permalink] [raw]
Subject: [PATCH v2 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]>
Reviewed-by: Rob Herring <[email protected]>
---
RFC->v2
- Updated commit message
- Collected RB tag from Rob
---
.../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-04-23 17:59:58

by Prabhakar

[permalink] [raw]
Subject: [PATCH v2 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. The RZ/V2H PFC varies slightly compared to the RZ/G2L
family:
- Additional bits need to be set during pinmuxing.
- The GPIO pin count is different.

Hence, a SoC-specific compatible string, 'renesas,r9a09g057-pinctrl', is
added for the RZ/V2H(P) SoC.

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

Pins are grouped into 4 groups:

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

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

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

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

The 'renesas,output-impedance' property, as documented, can be
[0, 1, 2, 3], indicating x1/x2/x3/x4 drive strength.

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

Also, allow bias-disable, bias-pull-down and bias-pull-up properties
as these can be used to configure the pins.

Signed-off-by: Lad Prabhakar <[email protected]>
---
RFC->v2
- Renamed renesas-rzv2h,output-impedance -> renesas,output-impedance
- Updated values for renesas,output-impedance
- Added bias properties
---
.../pinctrl/renesas,rzg2l-pinctrl.yaml | 25 ++++++++++++++++---
1 file changed, 21 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..089b3ce61bac 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,18 @@ additionalProperties:
output-high: true
output-low: true
line-name: true
+ bias-disable: true
+ bias-pull-down: true
+ bias-pull-up: true
+ renesas,output-impedance:
+ description: |
+ Output impedance for pins on RZ/V2H(P) SoC.
+ 0: Corresponds to x1
+ 1: Corresponds to x2
+ 2: Corresponds to x3
+ 3: Corresponds to x4
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1, 2, 3]

- type: object
additionalProperties:
--
2.34.1


2024-04-23 18:00:29

by Prabhakar

[permalink] [raw]
Subject: [PATCH v2 05/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 '0'.

Signed-off-by: Lad Prabhakar <[email protected]>
---
RFC->v2
- Update check to != 0 instead of -EINVAL
---
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index c944d94b9a36..bec4685b4681 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -2583,8 +2583,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)
+ cache->sd_ch[i] = readb(pctrl->base + SD_CH(regs->sd_ch, i));
+ if (regs->eth_poc)
+ cache->eth_poc[i] = readb(pctrl->base + ETH_POC(regs->eth_poc, i));
}

cache->qspi = readb(pctrl->base + QSPI);
@@ -2615,8 +2617,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)
+ writeb(cache->sd_ch[i], pctrl->base + SD_CH(regs->sd_ch, i));
+ if (regs->eth_poc)
+ writeb(cache->eth_poc[i], pctrl->base + ETH_POC(regs->eth_poc, i));
}

rzg2l_pinctrl_pm_setup_pfc(pctrl);
--
2.34.1


2024-04-23 18:00:50

by Prabhakar

[permalink] [raw]
Subject: [PATCH v2 06/13] pinctrl: renesas: pinctrl-rzg2l: Add function pointers for locking/unlocking the PFC register

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. Additionally, BIT(7) B0WI is
undocumented for the PWPR register on RZ/V2H(P) SoC. To accommodate these
differences across SoC variants, introduce the set_pfc_mode() and
pm_set_pfc() function pointers.

Note, in rzg2l_pinctrl_set_pfc_mode() the pwpr_pfc_unlock() call is now
called before PMC read/write and pwpr_pfc_lock() call is now called after
PMC read/write this is to keep changes minimal for RZ/V2H(P).

Signed-off-by: Lad Prabhakar <[email protected]>
---
RFC->v2
- Introduced function pointer for (un)lock
---
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 51 ++++++++++++++++---------
1 file changed, 34 insertions(+), 17 deletions(-)

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index bec4685b4681..0840fda7ca69 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -246,6 +246,8 @@ struct rzg2l_variable_pin_cfg {
u64 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 (*pwpr_pfc_unlock)(struct rzg2l_pinctrl *pctrl);
+ void (*pwpr_pfc_lock)(struct rzg2l_pinctrl *pctrl);
};

/**
@@ -462,7 +466,6 @@ static const struct rzg2l_variable_pin_cfg r9a07g043f_variable_pin_cfg[] = {
static void rzg2l_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;

@@ -473,27 +476,23 @@ static void rzg2l_pinctrl_set_pfc_mode(struct rzg2l_pinctrl *pctrl,
reg &= ~(PM_MASK << (pin * 2));
writew(reg, pctrl->base + PM(off));

+ pctrl->data->pwpr_pfc_unlock(pctrl);
+
/* Temporarily switch to GPIO mode with PMC register */
reg = readb(pctrl->base + PMC(off));
writeb(reg & ~BIT(pin), pctrl->base + PMC(off));

- /* Set the PWPR register to allow PFC register to write */
- writel(0x0, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=0 */
- writel(PWPR_PFCWE, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=1 */
-
/* 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));

- /* Set the PWPR register to be write-protected */
- writel(0x0, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=0 */
- writel(PWPR_B0WI, pctrl->base + regs->pwpr); /* B0WI=1, PFCWE=0 */
-
/* Switch to Peripheral pin function with PMC register */
reg = readb(pctrl->base + PMC(off));
writeb(reg | BIT(pin), pctrl->base + PMC(off));

+ pctrl->data->pwpr_pfc_lock(pctrl);
+
spin_unlock_irqrestore(&pctrl->lock, flags);
};

@@ -2519,12 +2518,8 @@ static void rzg2l_pinctrl_pm_setup_dedicated_regs(struct rzg2l_pinctrl *pctrl, b
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;
- const struct rzg2l_register_offsets *regs = &hwcfg->regs;

- /* Set the PWPR register to allow PFC register to write. */
- writel(0x0, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=0 */
- writel(PWPR_PFCWE, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=1 */
+ pctrl->data->pwpr_pfc_unlock(pctrl);

/* Restore port registers. */
for (u32 port = 0; port < nports; port++) {
@@ -2567,9 +2562,7 @@ static void rzg2l_pinctrl_pm_setup_pfc(struct rzg2l_pinctrl *pctrl)
}
}

- /* Set the PWPR register to be write-protected. */
- writel(0x0, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=0 */
- writel(PWPR_B0WI, pctrl->base + regs->pwpr); /* B0WI=1, PFCWE=0 */
+ pctrl->data->pwpr_pfc_lock(pctrl);
}

static int rzg2l_pinctrl_suspend_noirq(struct device *dev)
@@ -2631,6 +2624,24 @@ static int rzg2l_pinctrl_resume_noirq(struct device *dev)
return 0;
}

+static void rzg2l_pwpr_pfc_unlock(struct rzg2l_pinctrl *pctrl)
+{
+ const struct rzg2l_register_offsets *regs = &pctrl->data->hwcfg->regs;
+
+ /* Set the PWPR register to allow PFC register to write */
+ writel(0x0, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=0 */
+ writel(PWPR_PFCWE, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=1 */
+}
+
+static void rzg2l_pwpr_pfc_lock(struct rzg2l_pinctrl *pctrl)
+{
+ const struct rzg2l_register_offsets *regs = &pctrl->data->hwcfg->regs;
+
+ /* Set the PWPR register to be write-protected */
+ writel(0x0, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=0 */
+ writel(PWPR_B0WI, pctrl->base + regs->pwpr); /* B0WI=1, PFCWE=0 */
+}
+
static const struct rzg2l_hwcfg rzg2l_hwcfg = {
.regs = {
.pwpr = 0x3014,
@@ -2688,6 +2699,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
+ .pwpr_pfc_unlock = &rzg2l_pwpr_pfc_unlock,
+ .pwpr_pfc_lock = &rzg2l_pwpr_pfc_lock,
};

static struct rzg2l_pinctrl_data r9a07g044_data = {
@@ -2699,6 +2712,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,
+ .pwpr_pfc_unlock = &rzg2l_pwpr_pfc_unlock,
+ .pwpr_pfc_lock = &rzg2l_pwpr_pfc_lock,
};

static struct rzg2l_pinctrl_data r9a08g045_data = {
@@ -2709,6 +2724,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,
+ .pwpr_pfc_unlock = &rzg2l_pwpr_pfc_unlock,
+ .pwpr_pfc_lock = &rzg2l_pwpr_pfc_lock,
};

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


2024-04-23 18:01:02

by Prabhakar

[permalink] [raw]
Subject: [PATCH v2 07/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
pwpr_pfc_unlock/pwpr_pfc_lock.

Signed-off-by: Lad Prabhakar <[email protected]>
---
RFC->v2
- No change
---
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 0840fda7ca69..e6d986b84be6 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 (*pwpr_pfc_unlock)(struct rzg2l_pinctrl *pctrl);
void (*pwpr_pfc_lock)(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)
{
@@ -1410,7 +1416,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);

@@ -2701,6 +2707,7 @@ static struct rzg2l_pinctrl_data r9a07g043_data = {
#endif
.pwpr_pfc_unlock = &rzg2l_pwpr_pfc_unlock,
.pwpr_pfc_lock = &rzg2l_pwpr_pfc_lock,
+ .pmc_writeb = &rzg2l_pmc_writeb,
};

static struct rzg2l_pinctrl_data r9a07g044_data = {
@@ -2714,6 +2721,7 @@ static struct rzg2l_pinctrl_data r9a07g044_data = {
.hwcfg = &rzg2l_hwcfg,
.pwpr_pfc_unlock = &rzg2l_pwpr_pfc_unlock,
.pwpr_pfc_lock = &rzg2l_pwpr_pfc_lock,
+ .pmc_writeb = &rzg2l_pmc_writeb,
};

static struct rzg2l_pinctrl_data r9a08g045_data = {
@@ -2726,6 +2734,7 @@ static struct rzg2l_pinctrl_data r9a08g045_data = {
.hwcfg = &rzg3s_hwcfg,
.pwpr_pfc_unlock = &rzg2l_pwpr_pfc_unlock,
.pwpr_pfc_lock = &rzg2l_pwpr_pfc_lock,
+ .pmc_writeb = &rzg2l_pmc_writeb,
};

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


2024-04-23 18:01:22

by Prabhakar

[permalink] [raw]
Subject: [PATCH v2 09/13] pinctrl: renesas: pinctrl-rzg2l: Add support to configure the slew-rate

From: Lad Prabhakar <[email protected]>

Add support to configure slew-rate property of the pin.

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

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index 64648a951323..102fa75c71d3 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -120,6 +120,7 @@
#define PFC(off) (0x0400 + (off) * 4)
#define PIN(off) (0x0800 + (off))
#define IOLH(off) (0x1000 + (off) * 8)
+#define SR(off) (0x1400 + (off) * 8)
#define IEN(off) (0x1800 + (off) * 8)
#define ISEL(off) (0x2C00 + (off) * 8)
#define SD_CH(off, ch) ((off) + (ch) * 4)
@@ -138,6 +139,7 @@
#define PFC_MASK 0x07
#define IEN_MASK 0x01
#define IOLH_MASK 0x03
+#define SR_MASK 0x01

#define PM_INPUT 0x1
#define PM_OUTPUT 0x2
@@ -1130,6 +1132,13 @@ static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *pctldev,
arg = ret;
break;

+ case PIN_CONFIG_SLEW_RATE:
+ if (!(cfg & PIN_CFG_SR))
+ return -EINVAL;
+
+ arg = rzg2l_read_pin_config(pctrl, SR(off), bit, SR_MASK);
+ break;
+
case PIN_CONFIG_DRIVE_STRENGTH: {
unsigned int index;

@@ -1236,6 +1245,15 @@ static int rzg2l_pinctrl_pinconf_set(struct pinctrl_dev *pctldev,
settings.power_source = pinconf_to_config_argument(_configs[i]);
break;

+ case PIN_CONFIG_SLEW_RATE:
+ arg = pinconf_to_config_argument(_configs[i]);
+
+ if (!(cfg & PIN_CFG_SR) || arg > 1)
+ return -EINVAL;
+
+ rzg2l_rmw_pin_config(pctrl, SR(off), bit, SR_MASK, arg);
+ break;
+
case PIN_CONFIG_DRIVE_STRENGTH:
arg = pinconf_to_config_argument(_configs[i]);

--
2.34.1


2024-04-23 18:01:42

by Prabhakar

[permalink] [raw]
Subject: [PATCH v2 10/13] pinctrl: renesas: pinctrl-rzg2l: Add support to set pulling up/down the pins

From: Lad Prabhakar <[email protected]>

Add support to configure bias-disable, bias-pull-up and bias-pull-down
properties of the pin.

Two new function pointers get_bias_param() and get_bias_val() are
introduced as the values in PUPD register differ when compared to
RZ/G2L family and RZ/V2H(P) SoC,

Value | RZ/G2L | RZ/V2H
---------------------------------
00b: | Bias Disabled | Pull up/down disabled
01b: | Pull-up | Pull up/down disabled
10b: | Pull-down | Pull-down
11b: | Prohibited | Pull-up

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

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index 102fa75c71d3..c144bf43522b 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -122,6 +122,7 @@
#define IOLH(off) (0x1000 + (off) * 8)
#define SR(off) (0x1400 + (off) * 8)
#define IEN(off) (0x1800 + (off) * 8)
+#define PUPD(off) (0x1C00 + (off) * 8)
#define ISEL(off) (0x2C00 + (off) * 8)
#define SD_CH(off, ch) ((off) + (ch) * 4)
#define ETH_POC(off, ch) ((off) + (ch) * 4)
@@ -140,6 +141,7 @@
#define IEN_MASK 0x01
#define IOLH_MASK 0x03
#define SR_MASK 0x01
+#define PUPD_MASK 0x03

#define PM_INPUT 0x1
#define PM_OUTPUT 0x2
@@ -265,6 +267,8 @@ struct rzg2l_pinctrl_data {
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);
+ int (*get_bias_param)(u8 val);
+ int (*get_bias_val)(enum pin_config_param param);
};

/**
@@ -1081,6 +1085,38 @@ static int rzg2l_write_oen(struct rzg2l_pinctrl *pctrl, u32 caps, u32 offset, u8
return 0;
}

+static int rzg2l_get_bias_param(u8 val)
+{
+ switch (val) {
+ case 0:
+ return PIN_CONFIG_BIAS_DISABLE;
+ case 1:
+ return PIN_CONFIG_BIAS_PULL_UP;
+ case 2:
+ return PIN_CONFIG_BIAS_PULL_DOWN;
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static int rzg2l_get_bias_val(enum pin_config_param param)
+{
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ return 0;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ return 1;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ return 2;
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *pctldev,
unsigned int _pin,
unsigned long *config)
@@ -1139,6 +1175,25 @@ static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *pctldev,
arg = rzg2l_read_pin_config(pctrl, SR(off), bit, SR_MASK);
break;

+ case PIN_CONFIG_BIAS_DISABLE:
+ case PIN_CONFIG_BIAS_PULL_UP:
+ case PIN_CONFIG_BIAS_PULL_DOWN: {
+ if (!(cfg & PIN_CFG_PUPD))
+ return -EINVAL;
+
+ ret = pctrl->data->get_bias_param(rzg2l_read_pin_config(pctrl,
+ PUPD(off),
+ bit, PUPD_MASK));
+ if (ret < 0)
+ return ret;
+
+ if (ret != param)
+ return -EINVAL;
+ /* for PIN_CONFIG_BIAS_PULL_UP/DOWN when enabled we just return 1 */
+ arg = 1;
+ break;
+ }
+
case PIN_CONFIG_DRIVE_STRENGTH: {
unsigned int index;

@@ -1254,6 +1309,20 @@ static int rzg2l_pinctrl_pinconf_set(struct pinctrl_dev *pctldev,
rzg2l_rmw_pin_config(pctrl, SR(off), bit, SR_MASK, arg);
break;

+ case PIN_CONFIG_BIAS_DISABLE:
+ case PIN_CONFIG_BIAS_PULL_UP:
+ case PIN_CONFIG_BIAS_PULL_DOWN: {
+ if (!(cfg & PIN_CFG_PUPD))
+ return -EINVAL;
+
+ ret = pctrl->data->get_bias_val(param);
+ if (ret < 0)
+ return ret;
+
+ rzg2l_rmw_pin_config(pctrl, PUPD(off), bit, PUPD_MASK, ret);
+ break;
+ }
+
case PIN_CONFIG_DRIVE_STRENGTH:
arg = pinconf_to_config_argument(_configs[i]);

@@ -2746,6 +2815,8 @@ static struct rzg2l_pinctrl_data r9a07g044_data = {
.pmc_writeb = &rzg2l_pmc_writeb,
.read_oen = &rzg2l_read_oen,
.write_oen = &rzg2l_write_oen,
+ .get_bias_param = &rzg2l_get_bias_param,
+ .get_bias_val = &rzg2l_get_bias_val,
};

static struct rzg2l_pinctrl_data r9a08g045_data = {
@@ -2761,6 +2832,8 @@ static struct rzg2l_pinctrl_data r9a08g045_data = {
.pmc_writeb = &rzg2l_pmc_writeb,
.read_oen = &rzg2l_read_oen,
.write_oen = &rzg2l_write_oen,
+ .get_bias_param = &rzg2l_get_bias_param,
+ .get_bias_val = &rzg2l_get_bias_val,
};

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


2024-04-23 18:03:27

by Prabhakar

[permalink] [raw]
Subject: [PATCH v2 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]>
---
RFC->v2
- No change
---
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 c144bf43522b..f3c5e8982623 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -612,7 +612,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-04-23 18:05:04

by Prabhakar

[permalink] [raw]
Subject: [PATCH v2 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]>
---
RFC->v2
- Renamed renesas-rzv2h,output-impedance -> renesas,output-impedance
- Dropped IOLH groups
- Fixed dedicated pin configs
- Updated r9a09g057_variable_pin_cfg
- Added support OEN
- Added support for bias settings
- Added function pointers for pwpr (un)lock
- Added support for slew-rate
---
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 419 +++++++++++++++++++++++-
1 file changed, 415 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index 7e3ed18e0745..ee0dcdd7921a 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -59,6 +59,10 @@
#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_RZV2H BIT(21)

#define RZG2L_MPXED_COMMON_PIN_FUNCS(group) \
(PIN_CFG_IOLH_##group | \
@@ -73,6 +77,10 @@
#define RZG3S_MPXED_PIN_FUNCS(group) (RZG2L_MPXED_COMMON_PIN_FUNCS(group) | \
PIN_CFG_SOFT_PS)

+#define RZV2H_MPXED_PIN_FUNCS (RZG2L_MPXED_COMMON_PIN_FUNCS(RZV2H) | \
+ PIN_CFG_OPEN_DRAIN | \
+ PIN_CFG_SR)
+
#define RZG2L_MPXED_ETH_PIN_FUNCS(x) ((x) | \
PIN_CFG_FILONOFF | \
PIN_CFG_FILNUM | \
@@ -128,13 +136,15 @@
#define ETH_POC(off, ch) ((off) + (ch) * 4)
#define QSPI (0x3008)
#define ETH_MODE (0x3018)
+#define PFC_OEN (0x3C40) /* known on RZ/V2H(P) only */

#define PVDD_2500 2 /* I/O domain voltage 2.5V */
#define PVDD_1800 1 /* I/O domain voltage <= 1.8V */
#define PVDD_3300 0 /* I/O domain voltage >= 3.3V */

#define PWPR_B0WI BIT(7) /* Bit Write Disable */
-#define PWPR_PFCWE BIT(6) /* PFC Register Write Enable */
+#define PWPR_PFCWE BIT(6) /* PFC (and PMC on RZ/V2H) Register Write Enable */
+#define PWPR_REGWE_B BIT(5) /* OEN Register Write Enable, known only in RZ/V2H(P) */

#define PM_MASK 0x03
#define PFC_MASK 0x07
@@ -153,6 +163,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,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 { \
@@ -330,6 +353,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;
@@ -354,6 +379,39 @@ 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 = 11,
+ .pin = 0,
+ .cfg = RZV2H_MPXED_PIN_FUNCS | PIN_CFG_SCHMIT_CTRL,
+ },
+ {
+ .port = 11,
+ .pin = 1,
+ .cfg = RZV2H_MPXED_PIN_FUNCS | PIN_CFG_SCHMIT_CTRL | PIN_CFG_IEN,
+ },
+ {
+ .port = 11,
+ .pin = 2,
+ .cfg = RZV2H_MPXED_PIN_FUNCS | PIN_CFG_SCHMIT_CTRL | PIN_CFG_IEN,
+ },
+ {
+ .port = 11,
+ .pin = 3,
+ .cfg = RZV2H_MPXED_PIN_FUNCS | PIN_CFG_SCHMIT_CTRL | PIN_CFG_IEN,
+ },
+ {
+ .port = 11,
+ .pin = 4,
+ .cfg = RZV2H_MPXED_PIN_FUNCS | PIN_CFG_SCHMIT_CTRL | PIN_CFG_IEN,
+ },
+ {
+ .port = 11,
+ .pin = 5,
+ .cfg = RZV2H_MPXED_PIN_FUNCS | PIN_CFG_SCHMIT_CTRL | PIN_CFG_IEN,
+ },
+};
+
#ifdef CONFIG_RISCV
static const struct rzg2l_variable_pin_cfg r9a07g043f_variable_pin_cfg[] = {
{
@@ -480,6 +538,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_PFCWE, pctrl->base + regs->pwpr);
+ writeb(val, addr);
+ writeb(pwpr & ~PWPR_PFCWE, 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)
{
@@ -1120,14 +1191,107 @@ static int rzg2l_get_bias_val(enum pin_config_param param)
return -EINVAL;
}

+static int rzv2h_get_bias_param(u8 val)
+{
+ switch (val) {
+ case 0:
+ case 1:
+ return PIN_CONFIG_BIAS_DISABLE;
+ case 2:
+ return PIN_CONFIG_BIAS_PULL_DOWN;
+ case 3:
+ return PIN_CONFIG_BIAS_PULL_UP;
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static int rzv2h_get_bias_val(enum pin_config_param param)
+{
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ return 0;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ return 2;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ return 3;
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static u8 rzv2h_pin_to_oen_bit(struct rzg2l_pinctrl *pctrl, u32 offset)
+{
+ static const char * const pin_names[] = { "ET0_TXC_TXCLK", "ET1_TXC_TXCLK",
+ "XSPI0_RESET0N", "XSPI0_CS0N",
+ "XSPI0_CKN", "XSPI0_CKP" };
+ const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[offset];
+ u8 bit_array[] = { 0, 1, 2, 3, 4, 5 };
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(bit_array); i++) {
+ if (!strcmp(pin_desc->name, pin_names[i]))
+ return bit_array[i];
+ }
+
+ /* Should not happen. */
+ return 0;
+}
+
+static u32 rzv2h_read_oen(struct rzg2l_pinctrl *pctrl, u32 caps, u32 offset, u8 pin)
+{
+ u8 bit;
+
+ if (!(caps & PIN_CFG_OEN))
+ return 0;
+
+ bit = rzv2h_pin_to_oen_bit(pctrl, offset);
+
+ return !(readb(pctrl->base + PFC_OEN) & BIT(bit));
+}
+
+static int rzv2h_write_oen(struct rzg2l_pinctrl *pctrl, u32 caps, u32 offset, u8 pin, u8 oen)
+{
+ const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg;
+ const struct rzg2l_register_offsets *regs = &hwcfg->regs;
+ unsigned long flags;
+ u8 val, bit;
+ u8 pwpr;
+
+ if (!(caps & PIN_CFG_OEN))
+ return -EINVAL;
+
+ bit = rzv2h_pin_to_oen_bit(pctrl, offset);
+ spin_lock_irqsave(&pctrl->lock, flags);
+ val = readb(pctrl->base + PFC_OEN);
+ if (oen)
+ val &= ~BIT(bit);
+ else
+ val |= BIT(bit);
+
+ raw_spin_lock(&pctrl->pwpr_lock);
+ pwpr = readb(pctrl->base + regs->pwpr);
+ writeb(pwpr | PWPR_REGWE_B, pctrl->base + regs->pwpr);
+ writeb(val, pctrl->base + PFC_OEN);
+ writeb(pwpr & ~PWPR_REGWE_B, pctrl->base + regs->pwpr);
+ raw_spin_unlock(&pctrl->pwpr_lock);
+ spin_unlock_irqrestore(&pctrl->lock, flags);
+
+ return 0;
+}
+
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;
@@ -1240,6 +1404,14 @@ static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *pctldev,
break;
}

+ case RENESAS_RZV2H_PIN_CONFIG_OUTPUT_IMPEDANCE: {
+ if (!(cfg & PIN_CFG_IOLH_RZV2H))
+ return -EINVAL;
+
+ arg = rzg2l_read_pin_config(pctrl, IOLH(off), bit, IOLH_MASK);
+ break;
+ }
+
default:
return -ENOTSUPP;
}
@@ -1259,9 +1431,8 @@ 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 off;
+ u32 off, param;
u64 cfg;
int ret;
u8 bit;
@@ -1367,6 +1538,17 @@ 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_RZV2H))
+ return -EINVAL;
+
+ if (arg > 3)
+ return -EINVAL;
+ rzg2l_rmw_pin_config(pctrl, IOLH(off), bit, IOLH_MASK, arg);
+ break;
+
default:
return -EOPNOTSUPP;
}
@@ -1814,6 +1996,39 @@ 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 | PIN_CFG_SCHMIT_CTRL), /* P0 */
+ RZG2L_GPIO_PORT_PACK(6, 0x21, RZV2H_MPXED_PIN_FUNCS | PIN_CFG_SCHMIT_CTRL), /* P1 */
+ RZG2L_GPIO_PORT_PACK(2, 0x22, RZG2L_MPXED_COMMON_PIN_FUNCS(RZV2H) |
+ PIN_CFG_OPEN_DRAIN), /* P2 */
+ RZG2L_GPIO_PORT_PACK(8, 0x23, RZV2H_MPXED_PIN_FUNCS | PIN_CFG_SCHMIT_CTRL), /* P3 */
+ RZG2L_GPIO_PORT_PACK(8, 0x24, RZV2H_MPXED_PIN_FUNCS | PIN_CFG_SCHMIT_CTRL), /* P4 */
+ RZG2L_GPIO_PORT_PACK(8, 0x25, RZV2H_MPXED_PIN_FUNCS | PIN_CFG_SCHMIT_CTRL), /* P5 */
+ RZG2L_GPIO_PORT_PACK(8, 0x26, RZV2H_MPXED_PIN_FUNCS | PIN_CFG_SCHMIT_CTRL |
+ PIN_CFG_ELC), /* P6 */
+ RZG2L_GPIO_PORT_PACK(8, 0x27, RZV2H_MPXED_PIN_FUNCS | PIN_CFG_SCHMIT_CTRL), /* P7 */
+ RZG2L_GPIO_PORT_PACK(8, 0x28, RZV2H_MPXED_PIN_FUNCS | PIN_CFG_SCHMIT_CTRL |
+ PIN_CFG_ELC), /* P8 */
+ RZG2L_GPIO_PORT_PACK(8, 0x29, RZV2H_MPXED_PIN_FUNCS | PIN_CFG_SCHMIT_CTRL), /* P9 */
+ RZG2L_GPIO_PORT_PACK(8, 0x2a, RZV2H_MPXED_PIN_FUNCS | 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];
@@ -1940,6 +2155,138 @@ 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_RZV2H | PIN_CFG_SR |
+ PIN_CFG_IEN)) },
+ { "TDO", RZG2L_SINGLE_PIN_PACK(0x3, 2, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR)) },
+ { "WDTUDFCA", RZG2L_SINGLE_PIN_PACK(0x5, 0, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD | PIN_CFG_OPEN_DRAIN)) },
+ { "WDTUDFCM", RZG2L_SINGLE_PIN_PACK(0x5, 1, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD | PIN_CFG_OPEN_DRAIN)) },
+ { "SCIF_RXD", RZG2L_SINGLE_PIN_PACK(0x6, 0, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "SCIF_TXD", RZG2L_SINGLE_PIN_PACK(0x6, 1, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "XSPI0_CKP", RZG2L_SINGLE_PIN_PACK(0x7, 0, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD | PIN_CFG_OEN)) },
+ { "XSPI0_CKN", RZG2L_SINGLE_PIN_PACK(0x7, 1, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD | PIN_CFG_OEN)) },
+ { "XSPI0_CS0N", RZG2L_SINGLE_PIN_PACK(0x7, 2, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD | PIN_CFG_OEN)) },
+ { "XSPI0_DS", RZG2L_SINGLE_PIN_PACK(0x7, 3, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "XSPI0_RESET0N", RZG2L_SINGLE_PIN_PACK(0x7, 4, (PIN_CFG_IOLH_RZV2H | 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_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "XSPI0_IO1", RZG2L_SINGLE_PIN_PACK(0x8, 1, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "XSPI0_IO2", RZG2L_SINGLE_PIN_PACK(0x8, 2, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "XSPI0_IO3", RZG2L_SINGLE_PIN_PACK(0x8, 3, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "XSPI0_IO4", RZG2L_SINGLE_PIN_PACK(0x8, 4, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "XSPI0_IO5", RZG2L_SINGLE_PIN_PACK(0x8, 5, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "XSPI0_IO6", RZG2L_SINGLE_PIN_PACK(0x8, 6, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "XSPI0_IO7", RZG2L_SINGLE_PIN_PACK(0x8, 7, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "SD0CLK", RZG2L_SINGLE_PIN_PACK(0x9, 0, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR)) },
+ { "SD0CMD", RZG2L_SINGLE_PIN_PACK(0x9, 1, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD0RSTN", RZG2L_SINGLE_PIN_PACK(0x9, 2, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR)) },
+ { "SD0DAT0", RZG2L_SINGLE_PIN_PACK(0xa, 0, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD0DAT1", RZG2L_SINGLE_PIN_PACK(0xa, 1, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD0DAT2", RZG2L_SINGLE_PIN_PACK(0xa, 2, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD0DAT3", RZG2L_SINGLE_PIN_PACK(0xa, 3, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD0DAT4", RZG2L_SINGLE_PIN_PACK(0xa, 4, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD0DAT5", RZG2L_SINGLE_PIN_PACK(0xa, 5, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD0DAT6", RZG2L_SINGLE_PIN_PACK(0xa, 6, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD0DAT7", RZG2L_SINGLE_PIN_PACK(0xa, 7, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD1CLK", RZG2L_SINGLE_PIN_PACK(0xb, 0, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR)) },
+ { "SD1CMD", RZG2L_SINGLE_PIN_PACK(0xb, 1, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD1DAT0", RZG2L_SINGLE_PIN_PACK(0xc, 0, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD1DAT1", RZG2L_SINGLE_PIN_PACK(0xc, 1, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD1DAT2", RZG2L_SINGLE_PIN_PACK(0xc, 2, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "SD1DAT3", RZG2L_SINGLE_PIN_PACK(0xc, 3, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "PCIE0_RSTOUTB", RZG2L_SINGLE_PIN_PACK(0xe, 0, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR)) },
+ { "PCIE1_RSTOUTB", RZG2L_SINGLE_PIN_PACK(0xe, 1, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR)) },
+ { "ET0_MDIO", RZG2L_SINGLE_PIN_PACK(0xf, 0, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "ET0_MDC", RZG2L_SINGLE_PIN_PACK(0xf, 1, (PIN_CFG_IOLH_RZV2H | 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_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET0_TXER", RZG2L_SINGLE_PIN_PACK(0x10, 2, (PIN_CFG_IOLH_RZV2H | 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_RZV2H | 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_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET0_TXD1", RZG2L_SINGLE_PIN_PACK(0x11, 1, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET0_TXD2", RZG2L_SINGLE_PIN_PACK(0x11, 2, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET0_TXD3", RZG2L_SINGLE_PIN_PACK(0x11, 3, (PIN_CFG_IOLH_RZV2H | 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_RZV2H | PIN_CFG_SR |
+ PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ { "ET1_MDC", RZG2L_SINGLE_PIN_PACK(0x12, 1, (PIN_CFG_IOLH_RZV2H | 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_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET1_TXER", RZG2L_SINGLE_PIN_PACK(0x13, 2, (PIN_CFG_IOLH_RZV2H | 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_RZV2H | 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_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET1_TXD1", RZG2L_SINGLE_PIN_PACK(0x14, 1, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET1_TXD2", RZG2L_SINGLE_PIN_PACK(0x14, 2, (PIN_CFG_IOLH_RZV2H | PIN_CFG_SR |
+ PIN_CFG_PUPD)) },
+ { "ET1_TXD3", RZG2L_SINGLE_PIN_PACK(0x14, 3, (PIN_CFG_IOLH_RZV2H | 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];
@@ -2476,6 +2823,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;
@@ -2498,6 +2848,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);

@@ -2747,6 +3098,32 @@ static void rzg2l_pwpr_pfc_lock(struct rzg2l_pinctrl *pctrl)
writel(PWPR_B0WI, pctrl->base + regs->pwpr); /* B0WI=1, PFCWE=0 */
}

+static void rzv2h_pwpr_pfc_unlock(struct rzg2l_pinctrl *pctrl)
+{
+ const struct rzg2l_register_offsets *regs = &pctrl->data->hwcfg->regs;
+ u8 pwpr;
+
+ /*
+ * lock is acquired in pfc unlock call back and then released in
+ * pfc lock callback
+ */
+ raw_spin_lock(&pctrl->pwpr_lock);
+ /* Set the PWPR register to allow PFC and PMC register to write */
+ pwpr = readb(pctrl->base + regs->pwpr);
+ writeb(PWPR_PFCWE | pwpr, pctrl->base + regs->pwpr);
+}
+
+static void rzv2h_pwpr_pfc_lock(struct rzg2l_pinctrl *pctrl)
+{
+ const struct rzg2l_register_offsets *regs = &pctrl->data->hwcfg->regs;
+ u8 pwpr;
+
+ /* 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);
+}
+
static const struct rzg2l_hwcfg rzg2l_hwcfg = {
.regs = {
.pwpr = 0x3014,
@@ -2792,6 +3169,12 @@ 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,
+ },
+};
+
static struct rzg2l_pinctrl_data r9a07g043_data = {
.port_pins = rzg2l_gpio_names,
.port_pin_configs = r9a07g043_gpio_configs,
@@ -2846,6 +3229,30 @@ static struct rzg2l_pinctrl_data r9a08g045_data = {
.get_bias_val = &rzg2l_get_bias_val,
};

+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
+ .pwpr_pfc_unlock = &rzv2h_pwpr_pfc_unlock,
+ .pwpr_pfc_lock = &rzv2h_pwpr_pfc_lock,
+ .pmc_writeb = &rzv2h_pmc_writeb,
+ .read_oen = &rzv2h_read_oen,
+ .write_oen = &rzv2h_write_oen,
+ .get_bias_param = &rzv2h_get_bias_param,
+ .get_bias_val = &rzv2h_get_bias_val,
+};
+
static const struct of_device_id rzg2l_pinctrl_of_table[] = {
{
.compatible = "renesas,r9a07g043-pinctrl",
@@ -2859,6 +3266,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-04-23 18:12:24

by Biju Das

[permalink] [raw]
Subject: RE: [PATCH v2 06/13] pinctrl: renesas: pinctrl-rzg2l: Add function pointers for locking/unlocking the PFC register

Hi Prabhakar,

Thanks for the patch.

> -----Original Message-----
> From: Prabhakar <[email protected]>
> Sent: Tuesday, April 23, 2024 6:59 PM
> Subject: [PATCH v2 06/13] pinctrl: renesas: pinctrl-rzg2l: Add function pointers for
> locking/unlocking the PFC register
>
> 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. Additionally, BIT(7) B0WI is undocumented for the PWPR register on RZ/V2H(P) SoC. To
> accommodate these differences across SoC variants, introduce the set_pfc_mode() and
> pm_set_pfc() function pointers.
>
> Note, in rzg2l_pinctrl_set_pfc_mode() the pwpr_pfc_unlock() call is now called before PMC
> read/write and pwpr_pfc_lock() call is now called after PMC read/write this is to keep changes
> minimal for RZ/V2H(P).
>
> Signed-off-by: Lad Prabhakar <[email protected]>
> ---
> RFC->v2
> - Introduced function pointer for (un)lock
> ---
> drivers/pinctrl/renesas/pinctrl-rzg2l.c | 51 ++++++++++++++++---------
> 1 file changed, 34 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> index bec4685b4681..0840fda7ca69 100644
> --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> @@ -246,6 +246,8 @@ struct rzg2l_variable_pin_cfg {
> u64 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 (*pwpr_pfc_unlock)(struct rzg2l_pinctrl *pctrl);
> + void (*pwpr_pfc_lock)(struct rzg2l_pinctrl *pctrl);
> };
>
> /**
> @@ -462,7 +466,6 @@ static const struct rzg2l_variable_pin_cfg r9a07g043f_variable_pin_cfg[] =
> { static void rzg2l_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;
>
> @@ -473,27 +476,23 @@ static void rzg2l_pinctrl_set_pfc_mode(struct rzg2l_pinctrl *pctrl,
> reg &= ~(PM_MASK << (pin * 2));
> writew(reg, pctrl->base + PM(off));
>
> + pctrl->data->pwpr_pfc_unlock(pctrl);
> +
> /* Temporarily switch to GPIO mode with PMC register */
> reg = readb(pctrl->base + PMC(off));
> writeb(reg & ~BIT(pin), pctrl->base + PMC(off));
>
> - /* Set the PWPR register to allow PFC register to write */
> - writel(0x0, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=0 */
> - writel(PWPR_PFCWE, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=1 */
> -
> /* 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));
>
> - /* Set the PWPR register to be write-protected */
> - writel(0x0, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=0 */
> - writel(PWPR_B0WI, pctrl->base + regs->pwpr); /* B0WI=1, PFCWE=0 */
> -
> /* Switch to Peripheral pin function with PMC register */
> reg = readb(pctrl->base + PMC(off));
> writeb(reg | BIT(pin), pctrl->base + PMC(off));
>
> + pctrl->data->pwpr_pfc_lock(pctrl);
> +
> spin_unlock_irqrestore(&pctrl->lock, flags); };
>
> @@ -2519,12 +2518,8 @@ static void rzg2l_pinctrl_pm_setup_dedicated_regs(struct rzg2l_pinctrl
> *pctrl, b 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;
> - const struct rzg2l_register_offsets *regs = &hwcfg->regs;
>
> - /* Set the PWPR register to allow PFC register to write. */
> - writel(0x0, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=0 */
> - writel(PWPR_PFCWE, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=1 */
> + pctrl->data->pwpr_pfc_unlock(pctrl);
>
> /* Restore port registers. */
> for (u32 port = 0; port < nports; port++) { @@ -2567,9 +2562,7 @@ static void
> rzg2l_pinctrl_pm_setup_pfc(struct rzg2l_pinctrl *pctrl)
> }
> }
>
> - /* Set the PWPR register to be write-protected. */
> - writel(0x0, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=0 */
> - writel(PWPR_B0WI, pctrl->base + regs->pwpr); /* B0WI=1, PFCWE=0 */
> + pctrl->data->pwpr_pfc_lock(pctrl);
> }
>
> static int rzg2l_pinctrl_suspend_noirq(struct device *dev) @@ -2631,6 +2624,24 @@ static int
> rzg2l_pinctrl_resume_noirq(struct device *dev)
> return 0;
> }
>
> +static void rzg2l_pwpr_pfc_unlock(struct rzg2l_pinctrl *pctrl) {
> + const struct rzg2l_register_offsets *regs = &pctrl->data->hwcfg->regs;
> +
> + /* Set the PWPR register to allow PFC register to write */
> + writel(0x0, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=0 */
> + writel(PWPR_PFCWE, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=1 */
> +}
> +
> +static void rzg2l_pwpr_pfc_lock(struct rzg2l_pinctrl *pctrl) {
> + const struct rzg2l_register_offsets *regs = &pctrl->data->hwcfg->regs;
> +
> + /* Set the PWPR register to be write-protected */
> + writel(0x0, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=0 */
> + writel(PWPR_B0WI, pctrl->base + regs->pwpr); /* B0WI=1, PFCWE=0 */
> +}
> +
> static const struct rzg2l_hwcfg rzg2l_hwcfg = {
> .regs = {
> .pwpr = 0x3014,
> @@ -2688,6 +2699,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
> + .pwpr_pfc_unlock = &rzg2l_pwpr_pfc_unlock,
> + .pwpr_pfc_lock = &rzg2l_pwpr_pfc_lock,
> };
>
> static struct rzg2l_pinctrl_data r9a07g044_data = { @@ -2699,6 +2712,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,
> + .pwpr_pfc_unlock = &rzg2l_pwpr_pfc_unlock,
> + .pwpr_pfc_lock = &rzg2l_pwpr_pfc_lock,
> };
>
> static struct rzg2l_pinctrl_data r9a08g045_data = { @@ -2709,6 +2724,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,
> + .pwpr_pfc_unlock = &rzg2l_pwpr_pfc_unlock,
> + .pwpr_pfc_lock = &rzg2l_pwpr_pfc_lock,

Some memory can be saved by avoiding duplication of data by using
a single pointer for structure containing function pointers??

struct rzg2l_pinctrl_fns {
void (*pwpr_pfc_unlock)(struct rzg2l_pinctrl *pctrl);
void (*pwpr_pfc_lock)(struct rzg2l_pinctrl *pctrl);
}

Cheers,
Biju

> };
>
> static const struct of_device_id rzg2l_pinctrl_of_table[] = {
> --
> 2.34.1


2024-04-23 18:13:18

by Prabhakar

[permalink] [raw]
Subject: [PATCH v2 08/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(P) 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(P) and to reuse the existing code for RZ/V2H(P),
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]>
---
RFC->v2
- No change
---
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 e6d986b84be6..64648a951323 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -261,6 +261,8 @@ struct rzg2l_pinctrl_data {
void (*pwpr_pfc_unlock)(struct rzg2l_pinctrl *pctrl);
void (*pwpr_pfc_lock)(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);
};

/**
@@ -1116,7 +1118,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;
@@ -1225,7 +1227,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;
@@ -2708,6 +2710,8 @@ static struct rzg2l_pinctrl_data r9a07g043_data = {
.pwpr_pfc_unlock = &rzg2l_pwpr_pfc_unlock,
.pwpr_pfc_lock = &rzg2l_pwpr_pfc_lock,
.pmc_writeb = &rzg2l_pmc_writeb,
+ .read_oen = &rzg2l_read_oen,
+ .write_oen = &rzg2l_write_oen,
};

static struct rzg2l_pinctrl_data r9a07g044_data = {
@@ -2722,6 +2726,8 @@ static struct rzg2l_pinctrl_data r9a07g044_data = {
.pwpr_pfc_unlock = &rzg2l_pwpr_pfc_unlock,
.pwpr_pfc_lock = &rzg2l_pwpr_pfc_lock,
.pmc_writeb = &rzg2l_pmc_writeb,
+ .read_oen = &rzg2l_read_oen,
+ .write_oen = &rzg2l_write_oen,
};

static struct rzg2l_pinctrl_data r9a08g045_data = {
@@ -2735,6 +2741,8 @@ static struct rzg2l_pinctrl_data r9a08g045_data = {
.pwpr_pfc_unlock = &rzg2l_pwpr_pfc_unlock,
.pwpr_pfc_lock = &rzg2l_pwpr_pfc_lock,
.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-04-23 18:14:36

by Prabhakar

[permalink] [raw]
Subject: [PATCH v2 04/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]>
---
RFC->v2
- No change
---
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 9bb9cc63f9df..c944d94b9a36 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,
@@ -2299,13 +2299,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-04-23 18:15:31

by Prabhakar

[permalink] [raw]
Subject: [PATCH v2 12/13] pinctrl: renesas: pinctrl-rzg2l: Add support for custom parameters

From: Lad Prabhakar <[email protected]>

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

Signed-off-by: Lad Prabhakar <[email protected]>
---
RFC->v2
- No change
---
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 f3c5e8982623..7e3ed18e0745 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -262,6 +262,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 (*pwpr_pfc_unlock)(struct rzg2l_pinctrl *pctrl);
void (*pwpr_pfc_lock)(struct rzg2l_pinctrl *pctrl);
void (*pmc_writeb)(struct rzg2l_pinctrl *pctrl, u8 val, void __iomem *addr);
@@ -2374,6 +2377,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-04-23 18:16:40

by Prabhakar

[permalink] [raw]
Subject: [PATCH v2 03/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.

Also update the size of 'cfg' to 'u64' to allow more configuration bits in
the 'struct rzg2l_variable_pin_cfg'.

Signed-off-by: Lad Prabhakar <[email protected]>
---
RFC->v2
- Merged the macros and rzg2l_variable_pin_cfg changes into single patch
- Updated types for the config changes
---
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 30 ++++++++++++++-----------
1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index dbcf009837ef..9bb9cc63f9df 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_ULL(54, 47)
+#define PIN_CFG_MASK GENMASK_ULL(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_ULL(62, 56)
+#define RZG2L_SINGLE_PIN_BITS_MASK GENMASK_ULL(55, 53)

#define RZG2L_SINGLE_PIN_PACK(p, b, f) (RZG2L_SINGLE_PIN | \
FIELD_PREP_CONST(RZG2L_SINGLE_PIN_INDEX_MASK, (p)) | \
@@ -241,9 +241,9 @@ struct rzg2l_dedicated_configs {
* @pin: port pin
*/
struct rzg2l_variable_pin_cfg {
- u32 cfg:20;
- u32 port:5;
- u32 pin:3;
+ u64 cfg:46;
+ u64 port:5;
+ u64 pin:3;
};

struct rzg2l_pinctrl_data {
@@ -1082,7 +1082,8 @@ static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *pctldev,
const struct pinctrl_pin_desc *pin = &pctrl->desc.pins[_pin];
u64 *pin_data = pin->drv_data;
unsigned int arg = 0;
- u32 off, cfg;
+ u32 off;
+ u64 cfg;
int ret;
u8 bit;

@@ -1186,7 +1187,8 @@ static int rzg2l_pinctrl_pinconf_set(struct pinctrl_dev *pctldev,
u64 *pin_data = pin->drv_data;
enum pin_config_param param;
unsigned int i, arg, index;
- u32 cfg, off;
+ u32 off;
+ u64 cfg;
int ret;
u8 bit;

@@ -2414,9 +2416,9 @@ static void rzg2l_pinctrl_pm_setup_regs(struct rzg2l_pinctrl *pctrl, bool suspen

for (u32 port = 0; port < nports; port++) {
bool has_iolh, has_ien;
- u32 off, caps;
+ u64 cfg, caps;
u8 pincnt;
- u64 cfg;
+ u32 off;

cfg = pctrl->data->port_pin_configs[port];
off = RZG2L_PIN_CFG_TO_PORT_OFFSET(cfg);
@@ -2460,12 +2462,14 @@ static void rzg2l_pinctrl_pm_setup_regs(struct rzg2l_pinctrl *pctrl, bool suspen
static void rzg2l_pinctrl_pm_setup_dedicated_regs(struct rzg2l_pinctrl *pctrl, bool suspend)
{
struct rzg2l_pinctrl_reg_cache *cache = pctrl->dedicated_cache;
+ u64 caps;
+ u32 i;

/*
* Make sure entries in pctrl->data->n_dedicated_pins[] having the same
* port offset are close together.
*/
- for (u32 i = 0, caps = 0; i < pctrl->data->n_dedicated_pins; i++) {
+ for (i = 0, caps = 0; i < pctrl->data->n_dedicated_pins; i++) {
bool has_iolh, has_ien;
u32 off, next_off = 0;
u64 cfg, next_cfg;
--
2.34.1


2024-04-24 09:08:01

by Geert Uytterhoeven

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

Hi Prabhakar,

Thanks for your patch!

On Tue, Apr 23, 2024 at 7:59 PM Prabhakar <[email protected]> wrote:
> From: Lad Prabhakar <[email protected]>
>
> Add documentation for the pin controller found on the Renesas RZ/V2H(P)
> (R9A09G057) SoC. The RZ/V2H PFC varies slightly compared to the RZ/G2L
> family:
> - Additional bits need to be set during pinmuxing.
> - The GPIO pin count is different.
>
> Hence, a SoC-specific compatible string, 'renesas,r9a09g057-pinctrl', is
> added for the RZ/V2H(P) SoC.
>
> Also, add the 'renesas,output-impedance' property. The drive strength
> setting on RZ/V2H(P) depends on the different power rails coming out from
> the PMIC (connected via I2C). These power rails (required for drive
> strength) can be 1.2V, 1.8V, or 3.3V.
>
> Pins are grouped into 4 groups:
>
> Group 1: Impedance
> - 150/75/38/25 ohms (at 3.3V)
> - 130/65/33/22 ohms (at 1.8V)
>
> Group 2: Impedance
> - 50/40/33/25 ohms (at 1.8V)
>
> Group 3: Impedance
> - 150/75/37.5/25 ohms (at 3.3V)
> - 130/65/33/22 ohms (at 1.8V)
>
> Group 4: Impedance
> - 110/55/30/20 ohms (at 1.8V)
> - 150/75/38/25 ohms (at 1.2V)
>
> The 'renesas,output-impedance' property, as documented, can be
> [0, 1, 2, 3], indicating x1/x2/x3/x4 drive strength.

The documentation says "x1/x2/x4/x6" for all but Group 4 (P20/P21).
Still, the actual values don't seem to match the magnification factors...

> As power rail information may not be available very early in the boot
> process, the 'renesas,output-impedance' property is added instead of
> reusing the 'output-impedance-ohms' property.
>
> Also, allow bias-disable, bias-pull-down and bias-pull-up properties
> as these can be used to configure the pins.
>
> Signed-off-by: Lad Prabhakar <[email protected]>

> --- a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml
> +++ b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml
> @@ -111,6 +116,18 @@ additionalProperties:
> output-high: true
> output-low: true
> line-name: true
> + bias-disable: true
> + bias-pull-down: true
> + bias-pull-up: true
> + renesas,output-impedance:
> + description: |
> + Output impedance for pins on RZ/V2H(P) SoC.
> + 0: Corresponds to x1
> + 1: Corresponds to x2
> + 2: Corresponds to x3
> + 3: Corresponds to x4

Hence I'd drop the multiplication factors, and just say the meaning
of the value is pin-dependent?

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

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-04-25 09:50:16

by Prabhakar

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

Hi Geert,

Thank you for the review.

On Wed, Apr 24, 2024 at 10:06 AM Geert Uytterhoeven
<[email protected]> wrote:
>
> Hi Prabhakar,
>
> Thanks for your patch!
>
> On Tue, Apr 23, 2024 at 7:59 PM Prabhakar <prabhakar.csengg@gmailcom> wrote:
> > From: Lad Prabhakar <[email protected]>
> >
> > Add documentation for the pin controller found on the Renesas RZ/V2H(P)
> > (R9A09G057) SoC. The RZ/V2H PFC varies slightly compared to the RZ/G2L
> > family:
> > - Additional bits need to be set during pinmuxing.
> > - The GPIO pin count is different.
> >
> > Hence, a SoC-specific compatible string, 'renesas,r9a09g057-pinctrl', is
> > added for the RZ/V2H(P) SoC.
> >
> > Also, add the 'renesas,output-impedance' property. The drive strength
> > setting on RZ/V2H(P) depends on the different power rails coming out from
> > the PMIC (connected via I2C). These power rails (required for drive
> > strength) can be 1.2V, 1.8V, or 3.3V.
> >
> > Pins are grouped into 4 groups:
> >
> > Group 1: Impedance
> > - 150/75/38/25 ohms (at 3.3V)
> > - 130/65/33/22 ohms (at 1.8V)
> >
> > Group 2: Impedance
> > - 50/40/33/25 ohms (at 1.8V)
> >
> > Group 3: Impedance
> > - 150/75/37.5/25 ohms (at 3.3V)
> > - 130/65/33/22 ohms (at 1.8V)
> >
> > Group 4: Impedance
> > - 110/55/30/20 ohms (at 1.8V)
> > - 150/75/38/25 ohms (at 1.2V)
> >
> > The 'renesas,output-impedance' property, as documented, can be
> > [0, 1, 2, 3], indicating x1/x2/x3/x4 drive strength.
>
> The documentation says "x1/x2/x4/x6" for all but Group 4 (P20/P21).
> Still, the actual values don't seem to match the magnification factors...
>
> > As power rail information may not be available very early in the boot
> > process, the 'renesas,output-impedance' property is added instead of
> > reusing the 'output-impedance-ohms' property.
> >
> > Also, allow bias-disable, bias-pull-down and bias-pull-up properties
> > as these can be used to configure the pins.
> >
> > Signed-off-by: Lad Prabhakar <[email protected]>
>
> > --- a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml
> > +++ b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml
> > @@ -111,6 +116,18 @@ additionalProperties:
> > output-high: true
> > output-low: true
> > line-name: true
> > + bias-disable: true
> > + bias-pull-down: true
> > + bias-pull-up: true
> > + renesas,output-impedance:
> > + description: |
> > + Output impedance for pins on RZ/V2H(P) SoC.
> > + 0: Corresponds to x1
> > + 1: Corresponds to x2
> > + 2: Corresponds to x3
> > + 3: Corresponds to x4
>
> Hence I'd drop the multiplication factors, and just say the meaning
> of the value is pin-dependent?
>
Agreed, I will update the description "Output impedance for pins on
RZ/V2H(P) SoC. 0/1/2/3 corresponds to register bit values that can be
set in PFC_IOLH_mn register which adjusts the drive strength value and
is pin-dependent"

Cheers,
Prabhakar

> > + $ref: /schemas/types.yaml#/definitions/uint32
> > + enum: [0, 1, 2, 3]
> >
> > - type: object
> > additionalProperties:
>
> Gr{oetje,eeting}s,
>
> Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
>
> 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-04-25 11:41:07

by Prabhakar

[permalink] [raw]
Subject: Re: [PATCH v2 06/13] pinctrl: renesas: pinctrl-rzg2l: Add function pointers for locking/unlocking the PFC register

Hi Biju,

Thank you for the review.

On Tue, Apr 23, 2024 at 7:12 PM Biju Das <[email protected]> wrote:
>
> Hi Prabhakar,
>
> Thanks for the patch.
>
> > -----Original Message-----
> > From: Prabhakar <[email protected]>
> > Sent: Tuesday, April 23, 2024 6:59 PM
> > Subject: [PATCH v2 06/13] pinctrl: renesas: pinctrl-rzg2l: Add function pointers for
> > locking/unlocking the PFC register
> >
> > 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. Additionally, BIT(7) B0WI is undocumented for the PWPR register on RZ/V2H(P) SoC. To
> > accommodate these differences across SoC variants, introduce the set_pfc_mode() and
> > pm_set_pfc() function pointers.
> >
> > Note, in rzg2l_pinctrl_set_pfc_mode() the pwpr_pfc_unlock() call is now called before PMC
> > read/write and pwpr_pfc_lock() call is now called after PMC read/write this is to keep changes
> > minimal for RZ/V2H(P).
> >
> > Signed-off-by: Lad Prabhakar <[email protected]>
> > ---
> > RFC->v2
> > - Introduced function pointer for (un)lock
> > ---
> > drivers/pinctrl/renesas/pinctrl-rzg2l.c | 51 ++++++++++++++++---------
> > 1 file changed, 34 insertions(+), 17 deletions(-)
> >
> > diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> > index bec4685b4681..0840fda7ca69 100644
> > --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> > +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> > @@ -246,6 +246,8 @@ struct rzg2l_variable_pin_cfg {
> > u64 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 (*pwpr_pfc_unlock)(struct rzg2l_pinctrl *pctrl);
> > + void (*pwpr_pfc_lock)(struct rzg2l_pinctrl *pctrl);
> > };
> >
> > /**
> > @@ -462,7 +466,6 @@ static const struct rzg2l_variable_pin_cfg r9a07g043f_variable_pin_cfg[] =
> > { static void rzg2l_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;
> >
> > @@ -473,27 +476,23 @@ static void rzg2l_pinctrl_set_pfc_mode(struct rzg2l_pinctrl *pctrl,
> > reg &= ~(PM_MASK << (pin * 2));
> > writew(reg, pctrl->base + PM(off));
> >
> > + pctrl->data->pwpr_pfc_unlock(pctrl);
> > +
> > /* Temporarily switch to GPIO mode with PMC register */
> > reg = readb(pctrl->base + PMC(off));
> > writeb(reg & ~BIT(pin), pctrl->base + PMC(off));
> >
> > - /* Set the PWPR register to allow PFC register to write */
> > - writel(0x0, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=0 */
> > - writel(PWPR_PFCWE, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=1 */
> > -
> > /* 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));
> >
> > - /* Set the PWPR register to be write-protected */
> > - writel(0x0, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=0 */
> > - writel(PWPR_B0WI, pctrl->base + regs->pwpr); /* B0WI=1, PFCWE=0 */
> > -
> > /* Switch to Peripheral pin function with PMC register */
> > reg = readb(pctrl->base + PMC(off));
> > writeb(reg | BIT(pin), pctrl->base + PMC(off));
> >
> > + pctrl->data->pwpr_pfc_lock(pctrl);
> > +
> > spin_unlock_irqrestore(&pctrl->lock, flags); };
> >
> > @@ -2519,12 +2518,8 @@ static void rzg2l_pinctrl_pm_setup_dedicated_regs(struct rzg2l_pinctrl
> > *pctrl, b 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;
> > - const struct rzg2l_register_offsets *regs = &hwcfg->regs;
> >
> > - /* Set the PWPR register to allow PFC register to write. */
> > - writel(0x0, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=0 */
> > - writel(PWPR_PFCWE, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=1 */
> > + pctrl->data->pwpr_pfc_unlock(pctrl);
> >
> > /* Restore port registers. */
> > for (u32 port = 0; port < nports; port++) { @@ -2567,9 +2562,7 @@ static void
> > rzg2l_pinctrl_pm_setup_pfc(struct rzg2l_pinctrl *pctrl)
> > }
> > }
> >
> > - /* Set the PWPR register to be write-protected. */
> > - writel(0x0, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=0 */
> > - writel(PWPR_B0WI, pctrl->base + regs->pwpr); /* B0WI=1, PFCWE=0 */
> > + pctrl->data->pwpr_pfc_lock(pctrl);
> > }
> >
> > static int rzg2l_pinctrl_suspend_noirq(struct device *dev) @@ -2631,6 +2624,24 @@ static int
> > rzg2l_pinctrl_resume_noirq(struct device *dev)
> > return 0;
> > }
> >
> > +static void rzg2l_pwpr_pfc_unlock(struct rzg2l_pinctrl *pctrl) {
> > + const struct rzg2l_register_offsets *regs = &pctrl->data->hwcfg->regs;
> > +
> > + /* Set the PWPR register to allow PFC register to write */
> > + writel(0x0, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=0 */
> > + writel(PWPR_PFCWE, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=1 */
> > +}
> > +
> > +static void rzg2l_pwpr_pfc_lock(struct rzg2l_pinctrl *pctrl) {
> > + const struct rzg2l_register_offsets *regs = &pctrl->data->hwcfg->regs;
> > +
> > + /* Set the PWPR register to be write-protected */
> > + writel(0x0, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=0 */
> > + writel(PWPR_B0WI, pctrl->base + regs->pwpr); /* B0WI=1, PFCWE=0 */
> > +}
> > +
> > static const struct rzg2l_hwcfg rzg2l_hwcfg = {
> > .regs = {
> > .pwpr = 0x3014,
> > @@ -2688,6 +2699,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
> > + .pwpr_pfc_unlock = &rzg2l_pwpr_pfc_unlock,
> > + .pwpr_pfc_lock = &rzg2l_pwpr_pfc_lock,
> > };
> >
> > static struct rzg2l_pinctrl_data r9a07g044_data = { @@ -2699,6 +2712,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,
> > + .pwpr_pfc_unlock = &rzg2l_pwpr_pfc_unlock,
> > + .pwpr_pfc_lock = &rzg2l_pwpr_pfc_lock,
> > };
> >
> > static struct rzg2l_pinctrl_data r9a08g045_data = { @@ -2709,6 +2724,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,
> > + .pwpr_pfc_unlock = &rzg2l_pwpr_pfc_unlock,
> > + .pwpr_pfc_lock = &rzg2l_pwpr_pfc_lock,
>
> Some memory can be saved by avoiding duplication of data by using
> a single pointer for structure containing function pointers??
>
> struct rzg2l_pinctrl_fns {
> void (*pwpr_pfc_unlock)(struct rzg2l_pinctrl *pctrl);
> void (*pwpr_pfc_lock)(struct rzg2l_pinctrl *pctrl);
> }
>
Ok makes sense, I will do that in the next version.

Cheers,
Prabhakar