Commit 1f89aa90 authored by Claudiu Beznea's avatar Claudiu Beznea Committed by Geert Uytterhoeven
Browse files

pinctrl: renesas: rzg2l: Adapt for different SD/PWPR register offsets



SD, PWPR power registers have different offsets b/w RZ/G2L and RZ/G3S.
Add a per SoC configuration data structure that is initialized with the
proper register offsets for individual SoCs.  The rzg2l_hwcfg structure
will be extended further in later commits.

Signed-off-by: default avatarClaudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Reviewed-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/r/20230929053915.1530607-16-claudiu.beznea@bp.renesas.com


Signed-off-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
parent 77e18969
Loading
Loading
Loading
Loading
+42 −10
Original line number Diff line number Diff line
@@ -98,8 +98,7 @@
#define IOLH(off)		(0x1000 + (off) * 8)
#define IEN(off)		(0x1800 + (off) * 8)
#define ISEL(off)		(0x2C00 + (off) * 8)
#define PWPR			(0x3014)
#define SD_CH(n)		(0x3000 + (n) * 4)
#define SD_CH(off, ch)		((off) + (ch) * 4)
#define QSPI			(0x3008)

#define PVDD_1800		1	/* I/O domain voltage <= 1.8V */
@@ -124,6 +123,24 @@
#define RZG2L_TINT_IRQ_START_INDEX	9
#define RZG2L_PACK_HWIRQ(t, i)		(((t) << 16) | (i))

/**
 * struct rzg2l_register_offsets - specific register offsets
 * @pwpr: PWPR register offset
 * @sd_ch: SD_CH register offset
 */
struct rzg2l_register_offsets {
	u16 pwpr;
	u16 sd_ch;
};

/**
 * struct rzg2l_hwcfg - hardware configuration data structure
 * @regs: hardware specific register offsets
 */
struct rzg2l_hwcfg {
	const struct rzg2l_register_offsets regs;
};

struct rzg2l_dedicated_configs {
	const char *name;
	u32 config;
@@ -136,6 +153,7 @@ struct rzg2l_pinctrl_data {
	const struct rzg2l_dedicated_configs *dedicated_pins;
	unsigned int n_port_pins;
	unsigned int n_dedicated_pins;
	const struct rzg2l_hwcfg *hwcfg;
};

struct rzg2l_pinctrl {
@@ -163,6 +181,7 @@ static const unsigned int iolh_groupb_oi[] = { 100, 66, 50, 33 };
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;

@@ -178,8 +197,8 @@ static void rzg2l_pinctrl_set_pfc_mode(struct rzg2l_pinctrl *pctrl,
	writeb(reg & ~BIT(pin), pctrl->base + PMC(off));

	/* Set the PWPR register to allow PFC register to write */
	writel(0x0, pctrl->base + PWPR);        /* B0WI=0, PFCWE=0 */
	writel(PWPR_PFCWE, pctrl->base + PWPR);  /* B0WI=0, PFCWE=1 */
	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));
@@ -187,8 +206,8 @@ static void rzg2l_pinctrl_set_pfc_mode(struct rzg2l_pinctrl *pctrl,
	writel(reg | (func << (pin * 4)), pctrl->base + PFC(off));

	/* Set the PWPR register to be write-protected */
	writel(0x0, pctrl->base + PWPR);        /* B0WI=0, PFCWE=0 */
	writel(PWPR_B0WI, pctrl->base + PWPR);  /* B0WI=1, PFCWE=0 */
	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));
@@ -523,6 +542,8 @@ static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *pctldev,
{
	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 rzg2l_register_offsets *regs = &hwcfg->regs;
	const struct pinctrl_pin_desc *pin = &pctrl->desc.pins[_pin];
	unsigned int *pin_data = pin->drv_data;
	unsigned int arg = 0;
@@ -558,9 +579,9 @@ static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *pctldev,
		u32 pwr_reg = 0x0;

		if (cfg & PIN_CFG_IO_VMC_SD0)
			pwr_reg = SD_CH(0);
			pwr_reg = SD_CH(regs->sd_ch, 0);
		else if (cfg & PIN_CFG_IO_VMC_SD1)
			pwr_reg = SD_CH(1);
			pwr_reg = SD_CH(regs->sd_ch, 1);
		else if (cfg & PIN_CFG_IO_VMC_QSPI)
			pwr_reg = QSPI;
		else
@@ -612,6 +633,8 @@ static int rzg2l_pinctrl_pinconf_set(struct pinctrl_dev *pctldev,
	struct rzg2l_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
	const struct pinctrl_pin_desc *pin = &pctrl->desc.pins[_pin];
	unsigned int *pin_data = pin->drv_data;
	const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg;
	const struct rzg2l_register_offsets *regs = &hwcfg->regs;
	enum pin_config_param param;
	unsigned long flags;
	void __iomem *addr;
@@ -655,9 +678,9 @@ static int rzg2l_pinctrl_pinconf_set(struct pinctrl_dev *pctldev,
				return -EINVAL;

			if (cfg & PIN_CFG_IO_VMC_SD0)
				pwr_reg = SD_CH(0);
				pwr_reg = SD_CH(regs->sd_ch, 0);
			else if (cfg & PIN_CFG_IO_VMC_SD1)
				pwr_reg = SD_CH(1);
				pwr_reg = SD_CH(regs->sd_ch, 1);
			else if (cfg & PIN_CFG_IO_VMC_QSPI)
				pwr_reg = QSPI;
			else
@@ -1532,6 +1555,13 @@ static int rzg2l_pinctrl_probe(struct platform_device *pdev)
	return 0;
}

static const struct rzg2l_hwcfg rzg2l_hwcfg = {
	.regs = {
		.pwpr = 0x3014,
		.sd_ch = 0x3000,
	},
};

static struct rzg2l_pinctrl_data r9a07g043_data = {
	.port_pins = rzg2l_gpio_names,
	.port_pin_configs = r9a07g043_gpio_configs,
@@ -1539,6 +1569,7 @@ static struct rzg2l_pinctrl_data r9a07g043_data = {
	.dedicated_pins = rzg2l_dedicated_pins.common,
	.n_port_pins = ARRAY_SIZE(r9a07g043_gpio_configs) * RZG2L_PINS_PER_PORT,
	.n_dedicated_pins = ARRAY_SIZE(rzg2l_dedicated_pins.common),
	.hwcfg = &rzg2l_hwcfg,
};

static struct rzg2l_pinctrl_data r9a07g044_data = {
@@ -1549,6 +1580,7 @@ static struct rzg2l_pinctrl_data r9a07g044_data = {
	.n_port_pins = ARRAY_SIZE(r9a07g044_gpio_configs) * RZG2L_PINS_PER_PORT,
	.n_dedicated_pins = ARRAY_SIZE(rzg2l_dedicated_pins.common) +
		ARRAY_SIZE(rzg2l_dedicated_pins.rzg2l_pins),
	.hwcfg = &rzg2l_hwcfg,
};

static const struct of_device_id rzg2l_pinctrl_of_table[] = {