2024-01-15 13:08:32

by Lad, Prabhakar

[permalink] [raw]
Subject: [PATCH v5 0/4] Add missing port pins for RZ/Five SoC

From: Lad Prabhakar <[email protected]>

Hi All,

This patch series intends to incorporate the absent port pins P19 to P28,
which are exclusively available on the RZ/Five SoC.

Cheers,
Prabhakar

v4 -> v5:
* Made struct rzg2l_variable_pin_cfg variables u32
* Updated PIN_CFG_PIN_MAP_MASK macro to use GENMASK_ULL() as reported
by kernel test robot.

v3 -> v4:
* Rebased the changes on top Claudiu's patches
* patch 1/4 is new patch for using FIELD_PREP_CONST/FIELD_GET as
suggested by Geert
* patch 2/4 adjusted the code again using FIELD_PREP_CONST/FIELD_GET
* patch 3/4 fixed rzg2l_pinctrl_get_variable_pin_cfg() as pointed by Geert
* patch 4/4 is unchanged
* patches 1-3 have been boot tested on g2l family

v2->v3:
* Fixed build warnings for m68k as reported by Kernel test robot.

RFC -> v2:
* Fixed review comments pointed by Geert & Biju

RFC:
Link: https://lore.kernel.org/lkml/[email protected]/T/


Lad Prabhakar (4):
pinctrl: renesas: rzg2l: Improve code for readability
pinctrl: renesas: rzg2l: Include pinmap in RZG2L_GPIO_PORT_PACK()
macro
pinctrl: renesas: pinctrl-rzg2l: Add the missing port pins P19 to P28
riscv: dts: renesas: r9a07g043f: Update gpio-ranges property

arch/riscv/boot/dts/renesas/r9a07g043f.dtsi | 4 +
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 284 +++++++++++++++++---
2 files changed, 248 insertions(+), 40 deletions(-)

--
2.34.1



2024-01-15 13:08:45

by Lad, Prabhakar

[permalink] [raw]
Subject: [PATCH v5 1/4] pinctrl: renesas: rzg2l: Improve code for readability

From: Lad Prabhakar <[email protected]>

As the RZ/G2L pinctrl driver is extensively utilized by numerous SoCs and
has experienced substantial growth, enhance code readability by
incorporating FIELD_PREP_CONST/FIELD_GET macros wherever necessary.

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

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index e90d47136889..fee348b80892 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -5,6 +5,7 @@
* Copyright (C) 2021 Renesas Electronics Corporation.
*/

+#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/gpio/driver.h>
@@ -38,8 +39,6 @@
*/
#define MUX_PIN_ID_MASK GENMASK(15, 0)
#define MUX_FUNC_MASK GENMASK(31, 16)
-#define MUX_FUNC_OFFS 16
-#define MUX_FUNC(pinconf) (((pinconf) & MUX_FUNC_MASK) >> MUX_FUNC_OFFS)

/* PIN capabilities */
#define PIN_CFG_IOLH_A BIT(0)
@@ -81,8 +80,12 @@
* n indicates number of pins in the port, a is the register index
* and f is pin configuration capabilities supported.
*/
-#define RZG2L_GPIO_PORT_PACK(n, a, f) (((n) << 28) | ((a) << 20) | (f))
-#define RZG2L_GPIO_PORT_GET_PINCNT(x) (((x) & GENMASK(30, 28)) >> 28)
+#define PIN_CFG_PIN_CNT_MASK GENMASK(30, 28)
+#define PIN_CFG_PIN_REG_MASK GENMASK(27, 20)
+#define PIN_CFG_MASK GENMASK(19, 0)
+#define RZG2L_GPIO_PORT_PACK(n, a, f) (FIELD_PREP_CONST(PIN_CFG_PIN_CNT_MASK, (n)) | \
+ FIELD_PREP_CONST(PIN_CFG_PIN_REG_MASK, (a)) | \
+ FIELD_PREP_CONST(PIN_CFG_MASK, (f)))

/*
* BIT(31) indicates dedicated pin, p is the register index while
@@ -90,14 +93,18 @@
* (b * 8) and f is the pin configuration capabilities supported.
*/
#define RZG2L_SINGLE_PIN BIT(31)
+#define RZG2L_SINGLE_PIN_INDEX_MASK GENMASK(30, 24)
+#define RZG2L_SINGLE_PIN_BITS_MASK GENMASK(22, 20)
+
#define RZG2L_SINGLE_PIN_PACK(p, b, f) (RZG2L_SINGLE_PIN | \
- ((p) << 24) | ((b) << 20) | (f))
-#define RZG2L_SINGLE_PIN_GET_BIT(x) (((x) & GENMASK(22, 20)) >> 20)
+ FIELD_PREP_CONST(RZG2L_SINGLE_PIN_INDEX_MASK, (p)) | \
+ FIELD_PREP_CONST(RZG2L_SINGLE_PIN_BITS_MASK, (b)) | \
+ FIELD_PREP_CONST(PIN_CFG_MASK, (f)))

-#define RZG2L_PIN_CFG_TO_CAPS(cfg) ((cfg) & GENMASK(19, 0))
+#define RZG2L_PIN_CFG_TO_CAPS(cfg) ((cfg) & PIN_CFG_MASK)
#define RZG2L_PIN_CFG_TO_PORT_OFFSET(cfg) ((cfg) & RZG2L_SINGLE_PIN ? \
- (((cfg) & GENMASK(30, 24)) >> 24) : \
- (((cfg) & GENMASK(26, 20)) >> 20))
+ FIELD_GET(RZG2L_SINGLE_PIN_INDEX_MASK, (cfg)) : \
+ FIELD_GET(PIN_CFG_PIN_REG_MASK, (cfg)))

#define P(off) (0x0000 + (off))
#define PM(off) (0x0100 + (off) * 2)
@@ -432,8 +439,8 @@ static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev,
ret = of_property_read_u32_index(np, "pinmux", i, &value);
if (ret)
goto done;
- pins[i] = value & MUX_PIN_ID_MASK;
- psel_val[i] = MUX_FUNC(value);
+ pins[i] = FIELD_GET(MUX_PIN_ID_MASK, value);
+ psel_val[i] = FIELD_GET(MUX_FUNC_MASK, value);
}

if (parent) {
@@ -560,7 +567,7 @@ static int rzg2l_dt_node_to_map(struct pinctrl_dev *pctldev,
static int rzg2l_validate_gpio_pin(struct rzg2l_pinctrl *pctrl,
u32 cfg, u32 port, u8 bit)
{
- u8 pincount = RZG2L_GPIO_PORT_GET_PINCNT(cfg);
+ u8 pincount = FIELD_GET(PIN_CFG_PIN_CNT_MASK, cfg);
u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(cfg);
u32 data;

@@ -868,7 +875,7 @@ static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *pctldev,
off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data);
cfg = RZG2L_PIN_CFG_TO_CAPS(*pin_data);
if (*pin_data & RZG2L_SINGLE_PIN) {
- bit = RZG2L_SINGLE_PIN_GET_BIT(*pin_data);
+ bit = FIELD_GET(RZG2L_SINGLE_PIN_BITS_MASK, *pin_data);
} else {
bit = RZG2L_PIN_ID_TO_PIN(_pin);

@@ -972,7 +979,7 @@ static int rzg2l_pinctrl_pinconf_set(struct pinctrl_dev *pctldev,
off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data);
cfg = RZG2L_PIN_CFG_TO_CAPS(*pin_data);
if (*pin_data & RZG2L_SINGLE_PIN) {
- bit = RZG2L_SINGLE_PIN_GET_BIT(*pin_data);
+ bit = FIELD_GET(RZG2L_SINGLE_PIN_BITS_MASK, *pin_data);
} else {
bit = RZG2L_PIN_ID_TO_PIN(_pin);

@@ -1608,12 +1615,12 @@ static int rzg2l_gpio_get_gpioint(unsigned int virq, const struct rzg2l_pinctrl_
bit = virq % 8;

if (port >= data->n_ports ||
- bit >= RZG2L_GPIO_PORT_GET_PINCNT(data->port_pin_configs[port]))
+ bit >= FIELD_GET(PIN_CFG_PIN_CNT_MASK, data->port_pin_configs[port]))
return -EINVAL;

gpioint = bit;
for (i = 0; i < port; i++)
- gpioint += RZG2L_GPIO_PORT_GET_PINCNT(data->port_pin_configs[i]);
+ gpioint += FIELD_GET(PIN_CFG_PIN_CNT_MASK, data->port_pin_configs[i]);

return gpioint;
}
@@ -1788,7 +1795,7 @@ static void rzg2l_init_irq_valid_mask(struct gpio_chip *gc,
bit = offset % 8;

if (port >= pctrl->data->n_ports ||
- bit >= RZG2L_GPIO_PORT_GET_PINCNT(pctrl->data->port_pin_configs[port]))
+ bit >= FIELD_GET(PIN_CFG_PIN_CNT_MASK, pctrl->data->port_pin_configs[port]))
clear_bit(offset, valid_mask);
}
}
--
2.34.1


2024-01-15 13:09:07

by Lad, Prabhakar

[permalink] [raw]
Subject: [PATCH v5 2/4] pinctrl: renesas: rzg2l: Include pinmap in RZG2L_GPIO_PORT_PACK() macro

From: Lad Prabhakar <[email protected]>

Currently we assume all the port pins are sequential ie always PX_0 to
PX_n (n=1..7) exist, but on RZ/Five SoC we have additional pins P19_1 to
P28_5 which have holes in them, for example only one pin on port19 is
available and that is P19_1 and not P19_0. So to handle such cases
include pinmap for each port which would indicate the pin availability
on each port. As the pincount can be calculated based on pinmap drop this
from RZG2L_GPIO_PORT_PACK() macro.

Previously we had a max of 7 pins on each port but on RZ/Five Port-20
has 8 pins, so move the single pin configuration to BIT(63).

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

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index fee348b80892..066fcc515335 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -80,19 +80,20 @@
* n indicates number of pins in the port, a is the register index
* and f is pin configuration capabilities supported.
*/
-#define PIN_CFG_PIN_CNT_MASK GENMASK(30, 28)
+#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 RZG2L_GPIO_PORT_PACK(n, a, f) (FIELD_PREP_CONST(PIN_CFG_PIN_CNT_MASK, (n)) | \
+
+#define RZG2L_GPIO_PORT_PACK(n, a, f) ((((1ULL << (n)) - 1) << 28) | \
FIELD_PREP_CONST(PIN_CFG_PIN_REG_MASK, (a)) | \
FIELD_PREP_CONST(PIN_CFG_MASK, (f)))

/*
- * BIT(31) indicates dedicated pin, p is the register index while
+ * BIT(63) indicates dedicated pin, p is the register index while
* referencing to SR/IEN/IOLH/FILxx registers, b is the register bits
* (b * 8) and f is the pin configuration capabilities supported.
*/
-#define RZG2L_SINGLE_PIN BIT(31)
+#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)

@@ -196,12 +197,12 @@ struct rzg2l_hwcfg {

struct rzg2l_dedicated_configs {
const char *name;
- u32 config;
+ u64 config;
};

struct rzg2l_pinctrl_data {
const char * const *port_pins;
- const u32 *port_pin_configs;
+ const u64 *port_pin_configs;
unsigned int n_ports;
const struct rzg2l_dedicated_configs *dedicated_pins;
unsigned int n_port_pins;
@@ -302,7 +303,7 @@ static int rzg2l_pinctrl_set_mux(struct pinctrl_dev *pctldev,
pins = group->pins;

for (i = 0; i < group->num_pins; i++) {
- unsigned int *pin_data = pctrl->desc.pins[pins[i]].drv_data;
+ u64 *pin_data = pctrl->desc.pins[pins[i]].drv_data;
u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data);
u32 pin = RZG2L_PIN_ID_TO_PIN(pins[i]);

@@ -565,13 +566,13 @@ static int rzg2l_dt_node_to_map(struct pinctrl_dev *pctldev,
}

static int rzg2l_validate_gpio_pin(struct rzg2l_pinctrl *pctrl,
- u32 cfg, u32 port, u8 bit)
+ u64 cfg, u32 port, u8 bit)
{
- u8 pincount = FIELD_GET(PIN_CFG_PIN_CNT_MASK, cfg);
+ u8 pinmap = FIELD_GET(PIN_CFG_PIN_MAP_MASK, cfg);
u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(cfg);
- u32 data;
+ u64 data;

- if (bit >= pincount || port >= pctrl->data->n_port_pins)
+ if (!(pinmap & BIT(bit)) || port >= pctrl->data->n_port_pins)
return -EINVAL;

data = pctrl->data->port_pin_configs[port];
@@ -863,7 +864,7 @@ static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *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];
- unsigned int *pin_data = pin->drv_data;
+ u64 *pin_data = pin->drv_data;
unsigned int arg = 0;
u32 off, cfg;
int ret;
@@ -966,7 +967,7 @@ static int rzg2l_pinctrl_pinconf_set(struct pinctrl_dev *pctldev,
const struct pinctrl_pin_desc *pin = &pctrl->desc.pins[_pin];
const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg;
struct rzg2l_pinctrl_pin_settings settings = pctrl->settings[_pin];
- unsigned int *pin_data = pin->drv_data;
+ u64 *pin_data = pin->drv_data;
enum pin_config_param param;
unsigned int i, arg, index;
u32 cfg, off;
@@ -1171,7 +1172,7 @@ static int rzg2l_gpio_request(struct gpio_chip *chip, unsigned int offset)
{
struct rzg2l_pinctrl *pctrl = gpiochip_get_data(chip);
const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[offset];
- u32 *pin_data = pin_desc->drv_data;
+ u64 *pin_data = pin_desc->drv_data;
u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data);
u32 port = RZG2L_PIN_ID_TO_PORT(offset);
u8 bit = RZG2L_PIN_ID_TO_PIN(offset);
@@ -1203,7 +1204,7 @@ static void rzg2l_gpio_set_direction(struct rzg2l_pinctrl *pctrl, u32 offset,
bool output)
{
const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[offset];
- unsigned int *pin_data = pin_desc->drv_data;
+ u64 *pin_data = pin_desc->drv_data;
u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data);
u8 bit = RZG2L_PIN_ID_TO_PIN(offset);
unsigned long flags;
@@ -1224,7 +1225,7 @@ static int rzg2l_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
{
struct rzg2l_pinctrl *pctrl = gpiochip_get_data(chip);
const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[offset];
- unsigned int *pin_data = pin_desc->drv_data;
+ u64 *pin_data = pin_desc->drv_data;
u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data);
u8 bit = RZG2L_PIN_ID_TO_PIN(offset);

@@ -1255,7 +1256,7 @@ static void rzg2l_gpio_set(struct gpio_chip *chip, unsigned int offset,
{
struct rzg2l_pinctrl *pctrl = gpiochip_get_data(chip);
const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[offset];
- unsigned int *pin_data = pin_desc->drv_data;
+ u64 *pin_data = pin_desc->drv_data;
u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data);
u8 bit = RZG2L_PIN_ID_TO_PIN(offset);
unsigned long flags;
@@ -1288,7 +1289,7 @@ static int rzg2l_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
struct rzg2l_pinctrl *pctrl = gpiochip_get_data(chip);
const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[offset];
- unsigned int *pin_data = pin_desc->drv_data;
+ u64 *pin_data = pin_desc->drv_data;
u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data);
u8 bit = RZG2L_PIN_ID_TO_PIN(offset);
u16 reg16;
@@ -1373,7 +1374,7 @@ static const char * const rzg2l_gpio_names[] = {
"P48_0", "P48_1", "P48_2", "P48_3", "P48_4", "P48_5", "P48_6", "P48_7",
};

-static const u32 r9a07g044_gpio_configs[] = {
+static const u64 r9a07g044_gpio_configs[] = {
RZG2L_GPIO_PORT_PACK(2, 0x10, RZG2L_MPXED_PIN_FUNCS),
RZG2L_GPIO_PORT_PACK(2, 0x11, RZG2L_MPXED_PIN_FUNCS),
RZG2L_GPIO_PORT_PACK(2, 0x12, RZG2L_MPXED_PIN_FUNCS),
@@ -1425,7 +1426,7 @@ static const u32 r9a07g044_gpio_configs[] = {
RZG2L_GPIO_PORT_PACK(5, 0x40, RZG2L_MPXED_PIN_FUNCS),
};

-static const u32 r9a07g043_gpio_configs[] = {
+static const u64 r9a07g043_gpio_configs[] = {
RZG2L_GPIO_PORT_PACK(4, 0x10, RZG2L_MPXED_PIN_FUNCS),
RZG2L_GPIO_PORT_PACK(5, 0x11, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH0)),
RZG2L_GPIO_PORT_PACK(4, 0x12, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH0)),
@@ -1447,7 +1448,7 @@ static const u32 r9a07g043_gpio_configs[] = {
RZG2L_GPIO_PORT_PACK(6, 0x22, RZG2L_MPXED_PIN_FUNCS),
};

-static const u32 r9a08g045_gpio_configs[] = {
+static const u64 r9a08g045_gpio_configs[] = {
RZG2L_GPIO_PORT_PACK(4, 0x20, RZG3S_MPXED_PIN_FUNCS(A)), /* P0 */
RZG2L_GPIO_PORT_PACK(5, 0x30, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IOLH_C |
PIN_CFG_IO_VMC_ETH0)) |
@@ -1615,12 +1616,12 @@ static int rzg2l_gpio_get_gpioint(unsigned int virq, const struct rzg2l_pinctrl_
bit = virq % 8;

if (port >= data->n_ports ||
- bit >= FIELD_GET(PIN_CFG_PIN_CNT_MASK, data->port_pin_configs[port]))
+ bit >= hweight8(FIELD_GET(PIN_CFG_PIN_MAP_MASK, data->port_pin_configs[port])))
return -EINVAL;

gpioint = bit;
for (i = 0; i < port; i++)
- gpioint += FIELD_GET(PIN_CFG_PIN_CNT_MASK, data->port_pin_configs[i]);
+ gpioint += hweight8(FIELD_GET(PIN_CFG_PIN_MAP_MASK, data->port_pin_configs[i]));

return gpioint;
}
@@ -1631,7 +1632,7 @@ static void rzg2l_gpio_irq_disable(struct irq_data *d)
struct rzg2l_pinctrl *pctrl = container_of(gc, struct rzg2l_pinctrl, gpio_chip);
unsigned int hwirq = irqd_to_hwirq(d);
const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[hwirq];
- unsigned int *pin_data = pin_desc->drv_data;
+ u64 *pin_data = pin_desc->drv_data;
u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data);
u8 bit = RZG2L_PIN_ID_TO_PIN(hwirq);
unsigned long flags;
@@ -1658,7 +1659,7 @@ static void rzg2l_gpio_irq_enable(struct irq_data *d)
struct rzg2l_pinctrl *pctrl = container_of(gc, struct rzg2l_pinctrl, gpio_chip);
unsigned int hwirq = irqd_to_hwirq(d);
const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[hwirq];
- unsigned int *pin_data = pin_desc->drv_data;
+ u64 *pin_data = pin_desc->drv_data;
u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data);
u8 bit = RZG2L_PIN_ID_TO_PIN(hwirq);
unsigned long flags;
@@ -1795,7 +1796,8 @@ static void rzg2l_init_irq_valid_mask(struct gpio_chip *gc,
bit = offset % 8;

if (port >= pctrl->data->n_ports ||
- bit >= FIELD_GET(PIN_CFG_PIN_CNT_MASK, pctrl->data->port_pin_configs[port]))
+ bit >= hweight8(FIELD_GET(PIN_CFG_PIN_MAP_MASK,
+ pctrl->data->port_pin_configs[port])))
clear_bit(offset, valid_mask);
}
}
@@ -1877,7 +1879,7 @@ static int rzg2l_pinctrl_register(struct rzg2l_pinctrl *pctrl)
const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg;
struct pinctrl_pin_desc *pins;
unsigned int i, j;
- u32 *pin_data;
+ u64 *pin_data;
int ret;

pctrl->desc.name = DRV_NAME;
--
2.34.1


2024-01-15 13:09:16

by Lad, Prabhakar

[permalink] [raw]
Subject: [PATCH v5 3/4] pinctrl: renesas: pinctrl-rzg2l: Add the missing port pins P19 to P28

From: Lad Prabhakar <[email protected]>

Add the missing port pins P19 to P28 for RZ/Five SoC. These additional
pins provide expanded capabilities and are exclusive to the RZ/Five SoC.

Couple of port pins have different configuration and are not identical for
the complete port so introduce struct rzg2l_variable_pin_cfg to handle
such cases and introduce the PIN_CFG_VARIABLE macro. The actual pin config
is then assigned in rzg2l_pinctrl_get_variable_pin_cfg().

Add an additional check in rzg2l_gpio_get_gpioint() to only allow GPIO pins
which support interrupt facility.

While at define RZG2L_GPIO_PORT_PACK() using RZG2L_GPIO_PORT_SPARSE_PACK().

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

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index 066fcc515335..384d2ed12747 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -57,6 +57,8 @@
#define PIN_CFG_IOLH_C BIT(13)
#define PIN_CFG_SOFT_PS BIT(14)
#define PIN_CFG_OEN BIT(15)
+#define PIN_CFG_VARIABLE BIT(16)
+#define PIN_CFG_NOGPIO_INT BIT(17)

#define RZG2L_MPXED_COMMON_PIN_FUNCS(group) \
(PIN_CFG_IOLH_##group | \
@@ -76,17 +78,23 @@
PIN_CFG_FILNUM | \
PIN_CFG_FILCLKSEL)

-/*
- * n indicates number of pins in the port, a is the register index
- * and f is pin configuration capabilities supported.
- */
#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 RZG2L_GPIO_PORT_PACK(n, a, f) ((((1ULL << (n)) - 1) << 28) | \
- FIELD_PREP_CONST(PIN_CFG_PIN_REG_MASK, (a)) | \
- FIELD_PREP_CONST(PIN_CFG_MASK, (f)))
+/*
+ * m indicates the bitmap of supported pins, a is the register index
+ * and f is pin configuration capabilities supported.
+ */
+#define RZG2L_GPIO_PORT_SPARSE_PACK(m, a, f) (FIELD_PREP_CONST(PIN_CFG_PIN_MAP_MASK, (m)) | \
+ FIELD_PREP_CONST(PIN_CFG_PIN_REG_MASK, (a)) | \
+ FIELD_PREP_CONST(PIN_CFG_MASK, (f)))
+
+/*
+ * n indicates number of pins in the port, a is the register index
+ * and f is pin configuration capabilities supported.
+ */
+#define RZG2L_GPIO_PORT_PACK(n, a, f) RZG2L_GPIO_PORT_SPARSE_PACK((1ULL << (n)) - 1, (a), (f))

/*
* BIT(63) indicates dedicated pin, p is the register index while
@@ -200,6 +208,18 @@ struct rzg2l_dedicated_configs {
u64 config;
};

+/**
+ * struct rzg2l_variable_pin_cfg - pin data cfg
+ * @cfg: port pin configuration
+ * @port: port number
+ * @pin: port pin
+ */
+struct rzg2l_variable_pin_cfg {
+ u32 cfg:20;
+ u32 port:5;
+ u32 pin:3;
+};
+
struct rzg2l_pinctrl_data {
const char * const *port_pins;
const u64 *port_pin_configs;
@@ -208,6 +228,8 @@ struct rzg2l_pinctrl_data {
unsigned int n_port_pins;
unsigned int n_dedicated_pins;
const struct rzg2l_hwcfg *hwcfg;
+ const struct rzg2l_variable_pin_cfg *variable_pin_cfg;
+ unsigned int n_variable_pin_cfg;
};

/**
@@ -243,6 +265,143 @@ 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,
+ u8 pin)
+{
+ unsigned int i;
+
+ for (i = 0; i < pctrl->data->n_variable_pin_cfg; i++) {
+ if (pctrl->data->variable_pin_cfg[i].port == port &&
+ pctrl->data->variable_pin_cfg[i].pin == pin)
+ return (pincfg & ~PIN_CFG_VARIABLE) | pctrl->data->variable_pin_cfg[i].cfg;
+ }
+
+ return 0;
+}
+
+static const struct rzg2l_variable_pin_cfg r9a07g043f_variable_pin_cfg[] = {
+ {
+ .port = 20,
+ .pin = 0,
+ .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD |
+ PIN_CFG_FILONOFF | PIN_CFG_FILNUM | PIN_CFG_FILCLKSEL |
+ PIN_CFG_IEN | PIN_CFG_NOGPIO_INT,
+ },
+ {
+ .port = 20,
+ .pin = 1,
+ .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD |
+ PIN_CFG_FILONOFF | PIN_CFG_FILNUM | PIN_CFG_FILCLKSEL |
+ PIN_CFG_IEN | PIN_CFG_NOGPIO_INT,
+ },
+ {
+ .port = 20,
+ .pin = 2,
+ .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD |
+ PIN_CFG_FILONOFF | PIN_CFG_FILNUM | PIN_CFG_FILCLKSEL |
+ PIN_CFG_IEN | PIN_CFG_NOGPIO_INT,
+ },
+ {
+ .port = 20,
+ .pin = 3,
+ .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD |
+ PIN_CFG_IEN | PIN_CFG_NOGPIO_INT,
+ },
+ {
+ .port = 20,
+ .pin = 4,
+ .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD |
+ PIN_CFG_IEN | PIN_CFG_NOGPIO_INT,
+ },
+ {
+ .port = 20,
+ .pin = 5,
+ .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD |
+ PIN_CFG_IEN | PIN_CFG_NOGPIO_INT,
+ },
+ {
+ .port = 20,
+ .pin = 6,
+ .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD |
+ PIN_CFG_IEN | PIN_CFG_NOGPIO_INT,
+ },
+ {
+ .port = 20,
+ .pin = 7,
+ .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD |
+ PIN_CFG_IEN | PIN_CFG_NOGPIO_INT,
+ },
+ {
+ .port = 23,
+ .pin = 1,
+ .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD |
+ PIN_CFG_NOGPIO_INT
+ },
+ {
+ .port = 23,
+ .pin = 2,
+ .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD |
+ PIN_CFG_NOGPIO_INT,
+ },
+ {
+ .port = 23,
+ .pin = 3,
+ .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD |
+ PIN_CFG_NOGPIO_INT,
+ },
+ {
+ .port = 23,
+ .pin = 4,
+ .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD |
+ PIN_CFG_NOGPIO_INT,
+ },
+ {
+ .port = 23,
+ .pin = 5,
+ .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_NOGPIO_INT,
+ },
+ {
+ .port = 24,
+ .pin = 0,
+ .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_NOGPIO_INT,
+ },
+ {
+ .port = 24,
+ .pin = 1,
+ .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD |
+ PIN_CFG_NOGPIO_INT,
+ },
+ {
+ .port = 24,
+ .pin = 2,
+ .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD |
+ PIN_CFG_NOGPIO_INT,
+ },
+ {
+ .port = 24,
+ .pin = 3,
+ .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD |
+ PIN_CFG_NOGPIO_INT,
+ },
+ {
+ .port = 24,
+ .pin = 4,
+ .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD |
+ PIN_CFG_NOGPIO_INT,
+ },
+ {
+ .port = 24,
+ .pin = 5,
+ .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD |
+ PIN_CFG_FILONOFF | PIN_CFG_FILNUM | PIN_CFG_FILCLKSEL |
+ PIN_CFG_NOGPIO_INT,
+ },
+};
+#endif
+
static void rzg2l_pinctrl_set_pfc_mode(struct rzg2l_pinctrl *pctrl,
u8 pin, u8 off, u8 func)
{
@@ -1446,6 +1605,25 @@ static const u64 r9a07g043_gpio_configs[] = {
RZG2L_GPIO_PORT_PACK(2, 0x20, RZG2L_MPXED_PIN_FUNCS),
RZG2L_GPIO_PORT_PACK(4, 0x21, RZG2L_MPXED_PIN_FUNCS),
RZG2L_GPIO_PORT_PACK(6, 0x22, RZG2L_MPXED_PIN_FUNCS),
+#ifdef CONFIG_RISCV
+ /* Below additional port pins (P19 - P28) are exclusively available on RZ/Five SoC only */
+ RZG2L_GPIO_PORT_SPARSE_PACK(0x2, 0x06, PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD |
+ PIN_CFG_FILONOFF | PIN_CFG_FILNUM | PIN_CFG_FILCLKSEL |
+ PIN_CFG_IEN | PIN_CFG_NOGPIO_INT), /* P19 */
+ RZG2L_GPIO_PORT_PACK(8, 0x07, PIN_CFG_VARIABLE), /* P20 */
+ RZG2L_GPIO_PORT_SPARSE_PACK(0x2, 0x08, PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD |
+ PIN_CFG_IEN | PIN_CFG_NOGPIO_INT), /* P21 */
+ RZG2L_GPIO_PORT_PACK(4, 0x09, PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD |
+ PIN_CFG_IEN | PIN_CFG_NOGPIO_INT), /* P22 */
+ RZG2L_GPIO_PORT_SPARSE_PACK(0x3e, 0x0a, PIN_CFG_VARIABLE), /* P23 */
+ RZG2L_GPIO_PORT_PACK(6, 0x0b, PIN_CFG_VARIABLE), /* P24 */
+ RZG2L_GPIO_PORT_SPARSE_PACK(0x2, 0x0c, PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_FILONOFF |
+ PIN_CFG_FILNUM | PIN_CFG_FILCLKSEL |
+ PIN_CFG_NOGPIO_INT), /* P25 */
+ 0x0, /* P26 */
+ 0x0, /* P27 */
+ RZG2L_GPIO_PORT_PACK(6, 0x0f, RZG2L_MPXED_PIN_FUNCS | PIN_CFG_NOGPIO_INT), /* P28 */
+#endif
};

static const u64 r9a08g045_gpio_configs[] = {
@@ -1606,12 +1784,18 @@ static const struct rzg2l_dedicated_configs rzg3s_dedicated_pins[] = {
PIN_CFG_IO_VMC_SD1)) },
};

-static int rzg2l_gpio_get_gpioint(unsigned int virq, const struct rzg2l_pinctrl_data *data)
+static int rzg2l_gpio_get_gpioint(unsigned int virq, struct rzg2l_pinctrl *pctrl)
{
+ const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[virq];
+ const struct rzg2l_pinctrl_data *data = pctrl->data;
+ u64 *pin_data = pin_desc->drv_data;
unsigned int gpioint;
unsigned int i;
u32 port, bit;

+ if (*pin_data & PIN_CFG_NOGPIO_INT)
+ return -EINVAL;
+
port = virq / 8;
bit = virq % 8;

@@ -1721,7 +1905,7 @@ static int rzg2l_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
unsigned long flags;
int gpioint, irq;

- gpioint = rzg2l_gpio_get_gpioint(child, pctrl->data);
+ gpioint = rzg2l_gpio_get_gpioint(child, pctrl);
if (gpioint < 0)
return gpioint;

@@ -1907,6 +2091,13 @@ 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];
}

@@ -2058,6 +2249,10 @@ static struct rzg2l_pinctrl_data r9a07g043_data = {
.n_port_pins = ARRAY_SIZE(r9a07g043_gpio_configs) * RZG2L_PINS_PER_PORT,
.n_dedicated_pins = ARRAY_SIZE(rzg2l_dedicated_pins.common),
.hwcfg = &rzg2l_hwcfg,
+#ifdef CONFIG_RISCV
+ .variable_pin_cfg = r9a07g043f_variable_pin_cfg,
+ .n_variable_pin_cfg = ARRAY_SIZE(r9a07g043f_variable_pin_cfg),
+#endif
};

static struct rzg2l_pinctrl_data r9a07g044_data = {
--
2.34.1


2024-01-15 13:09:20

by Lad, Prabhakar

[permalink] [raw]
Subject: [PATCH v5 4/4] riscv: dts: renesas: r9a07g043f: Update gpio-ranges property

From: Lad Prabhakar <[email protected]>

On RZ/Five we have additional pins compared to the RZ/G2UL SoC so update
the gpio-ranges property in RZ/Five SoC DTSI.

Signed-off-by: Lad Prabhakar <[email protected]>
---
arch/riscv/boot/dts/renesas/r9a07g043f.dtsi | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi b/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi
index d2272a0bfb61..aa3b1d2b999d 100644
--- a/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi
+++ b/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi
@@ -46,6 +46,10 @@ cpu0_intc: interrupt-controller {
};
};

+&pinctrl {
+ gpio-ranges = <&pinctrl 0 0 232>;
+};
+
&soc {
dma-noncoherent;
interrupt-parent = <&plic>;
--
2.34.1


2024-01-15 14:07:34

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v5 4/4] riscv: dts: renesas: r9a07g043f: Update gpio-ranges property

On Mon, Jan 15, 2024 at 2:08 PM Prabhakar <[email protected]> wrote:
> From: Lad Prabhakar <[email protected]>
>
> On RZ/Five we have additional pins compared to the RZ/G2UL SoC so update
> the gpio-ranges property in RZ/Five SoC DTSI.
>
> Signed-off-by: Lad Prabhakar <[email protected]>

My
Reviewed-by: Geert Uytterhoeven <[email protected]>
on v3 is still valid.

> --- a/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi
> +++ b/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi
> @@ -46,6 +46,10 @@ cpu0_intc: interrupt-controller {
> };
> };
>
> +&pinctrl {
> + gpio-ranges = <&pinctrl 0 0 232>;
> +};
> +
> &soc {
> dma-noncoherent;
> interrupt-parent = <&plic>;

I believe this has a hard dependency on the pinctrl driver changes, due to
the following check in in rzg2l_gpio_register():

if (of_args.args[0] != 0 || of_args.args[1] != 0 ||
of_args.args[2] != pctrl->data->n_port_pins) {
dev_err(pctrl->dev, "gpio-ranges does not match selected SOC\n");
return -EINVAL;
}

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-01-29 08:16:28

by Lad, Prabhakar

[permalink] [raw]
Subject: Re: [PATCH v5 0/4] Add missing port pins for RZ/Five SoC

Hi Geert,

On Mon, Jan 15, 2024 at 1:08 PM Prabhakar <[email protected]> wrote:
>
> From: Lad Prabhakar <[email protected]>
>
> Hi All,
>
> This patch series intends to incorporate the absent port pins P19 to P28,
> which are exclusively available on the RZ/Five SoC.
>
> Cheers,
> Prabhakar
>
> v4 -> v5:
> * Made struct rzg2l_variable_pin_cfg variables u32
> * Updated PIN_CFG_PIN_MAP_MASK macro to use GENMASK_ULL() as reported
> by kernel test robot.
>
> v3 -> v4:
> * Rebased the changes on top Claudiu's patches
> * patch 1/4 is new patch for using FIELD_PREP_CONST/FIELD_GET as
> suggested by Geert
> * patch 2/4 adjusted the code again using FIELD_PREP_CONST/FIELD_GET
> * patch 3/4 fixed rzg2l_pinctrl_get_variable_pin_cfg() as pointed by Geert
> * patch 4/4 is unchanged
> * patches 1-3 have been boot tested on g2l family
>
> v2->v3:
> * Fixed build warnings for m68k as reported by Kernel test robot.
>
> RFC -> v2:
> * Fixed review comments pointed by Geert & Biju
>
> RFC:
> Link: https://lore.kernel.org/lkml/[email protected]/T/
>
>
> Lad Prabhakar (4):
> pinctrl: renesas: rzg2l: Improve code for readability
> pinctrl: renesas: rzg2l: Include pinmap in RZG2L_GPIO_PORT_PACK()
> macro
> pinctrl: renesas: pinctrl-rzg2l: Add the missing port pins P19 to P28
> riscv: dts: renesas: r9a07g043f: Update gpio-ranges property
>
> arch/riscv/boot/dts/renesas/r9a07g043f.dtsi | 4 +
> drivers/pinctrl/renesas/pinctrl-rzg2l.c | 284 +++++++++++++++++---
> 2 files changed, 248 insertions(+), 40 deletions(-)
>
With recent changes to pinctrl-rzg2l.c this patch series (patch #2)
does not apply cleanly anymore. Shall I resend it?

Cheers,
Prabhakar

2024-01-29 08:26:03

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v5 0/4] Add missing port pins for RZ/Five SoC

Hi Prabhakar,

On Mon, Jan 29, 2024 at 9:16 AM Lad, Prabhakar
<[email protected]> wrote:
> On Mon, Jan 15, 2024 at 1:08 PM Prabhakar <prabhakar.csengg@gmailcom> wrote:
> > From: Lad Prabhakar <[email protected]>
> > This patch series intends to incorporate the absent port pins P19 to P28,
> > which are exclusively available on the RZ/Five SoC.
> >
> > Cheers,
> > Prabhakar
> >
> > v4 -> v5:
> > * Made struct rzg2l_variable_pin_cfg variables u32
> > * Updated PIN_CFG_PIN_MAP_MASK macro to use GENMASK_ULL() as reported
> > by kernel test robot.

> > Lad Prabhakar (4):
> > pinctrl: renesas: rzg2l: Improve code for readability
> > pinctrl: renesas: rzg2l: Include pinmap in RZG2L_GPIO_PORT_PACK()
> > macro
> > pinctrl: renesas: pinctrl-rzg2l: Add the missing port pins P19 to P28
> > riscv: dts: renesas: r9a07g043f: Update gpio-ranges property
> >
> > arch/riscv/boot/dts/renesas/r9a07g043f.dtsi | 4 +
> > drivers/pinctrl/renesas/pinctrl-rzg2l.c | 284 +++++++++++++++++---
> > 2 files changed, 248 insertions(+), 40 deletions(-)
> >
> With recent changes to pinctrl-rzg2l.c this patch series (patch #2)
> does not apply cleanly anymore. Shall I resend it?

Yes please. That would save me from resolving the conflict when
I get to this series.
Thanks!

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