All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andre Przywara <andre.przywara@arm.com>
To: Jagan Teki <jagan@amarulasolutions.com>, u-boot@lists.denx.de
Cc: Samuel Holland <samuel@sholland.org>,
	Jernej Skrabec <jernej.skrabec@gmail.com>,
	Icenowy Zheng <uwu@icenowy.me>,
	Maxim Kiselev <bigunclemax@gmail.com>,
	Sam Edwards <cfsworks@gmail.com>,
	Okhunjon Sobirjonov <okhunjon72@gmail.com>,
	linux-sunxi@lists.linux.dev, andre.przywara@arm.com,
	andre.przywara@foss.arm.com
Subject: [PATCH v2 06/22] pinctrl: sunxi: remove struct sunxi_gpio
Date: Thu, 28 Sep 2023 22:54:39 +0100	[thread overview]
Message-ID: <20230928215455.28094-7-andre.przywara@arm.com> (raw)
In-Reply-To: <20230928215455.28094-1-andre.przywara@arm.com>

So far every Allwinner SoC used the same basic pincontroller/GPIO
register frame, and just differed by the number of implemented banks and
pins, plus some special functionality from time to time. However the D1
and successors use a slightly different pinctrl register layout.
Use that opportunity to drop "struct sunxi_gpio", that described that
MMIO frame in a C struct. That approach is somewhat frowned upon in the
Linux world and rarely used there, though still popular with U-Boot.

Switching from a C struct to a "base address plus offset" approach allows
to switch between the two models more dynamically, without reverting to
preprocessor macros and #ifdef's.

Model the pinctrl MMIO register frame in the usual "base address +
offset" way, and replace a hard-to-parse CPP macro with a more readable
static function.
All the users get converted over. There are no functional changes at
this point, it just prepares the stages for the D1 and friends.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
 arch/arm/include/asm/arch-sunxi/gpio.h | 40 ++----------
 drivers/gpio/sunxi_gpio.c              | 88 ++++++++++++++++----------
 drivers/pinctrl/sunxi/pinctrl-sunxi.c  | 14 ++--
 3 files changed, 66 insertions(+), 76 deletions(-)

diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
index 4bc9e8ffcc9..e0fb5b5da63 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -31,13 +31,6 @@
 #define SUNXI_GPIO_H	7
 #define SUNXI_GPIO_I	8
 
-/*
- * This defines the number of GPIO banks for the _main_ GPIO controller.
- * You should fix up the padding in struct sunxi_gpio_reg below if you
- * change this.
- */
-#define SUNXI_GPIO_BANKS 9
-
 /*
  * sun6i/sun8i and later SoCs have an additional GPIO controller (R_PIO)
  * at a different register offset.
@@ -55,32 +48,11 @@
 #define SUNXI_GPIO_M	12
 #define SUNXI_GPIO_N	13
 
-struct sunxi_gpio {
-	u32 cfg[4];
-	u32 dat;
-	u32 drv[2];
-	u32 pull[2];
-};
-
-/* gpio interrupt control */
-struct sunxi_gpio_int {
-	u32 cfg[3];
-	u32 ctl;
-	u32 sta;
-	u32 deb;		/* interrupt debounce */
-};
-
-struct sunxi_gpio_reg {
-	struct sunxi_gpio gpio_bank[SUNXI_GPIO_BANKS];
-	u8 res[0xbc];
-	struct sunxi_gpio_int gpio_int;
-};
-
 #define SUN50I_H6_GPIO_POW_MOD_SEL	0x340
 #define SUN50I_H6_GPIO_POW_MOD_VAL	0x348
 
-/* GPIO bank sizes */
 #define SUNXI_GPIOS_PER_BANK	32
+#define SUNXI_PINCTRL_BANK_SIZE 0x24
 
 #define SUNXI_GPIO_NEXT(__gpio) \
 	((__gpio##_START) + SUNXI_GPIOS_PER_BANK)
@@ -200,19 +172,19 @@ enum sunxi_gpio_number {
 #define SUNXI_GPIO_AXP0_GPIO_COUNT	6
 
 struct sunxi_gpio_plat {
-	struct sunxi_gpio	*regs;
+	void			*regs;
 	char			bank_name[3];
 };
 
 /* prototypes for the non-DM GPIO/pinctrl functions, used in the SPL */
-void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val);
+void sunxi_gpio_set_cfgbank(void *bank_base, int pin_offset, u32 val);
 void sunxi_gpio_set_cfgpin(u32 pin, u32 val);
-int sunxi_gpio_get_cfgbank(struct sunxi_gpio *pio, int bank_offset);
+int sunxi_gpio_get_cfgbank(void *bank_base, int pin_offset);
 int sunxi_gpio_get_cfgpin(u32 pin);
 void sunxi_gpio_set_drv(u32 pin, u32 val);
-void sunxi_gpio_set_drv_bank(struct sunxi_gpio *pio, u32 bank_offset, u32 val);
+void sunxi_gpio_set_drv_bank(void *bank_base, u32 pin_offset, u32 val);
 void sunxi_gpio_set_pull(u32 pin, u32 val);
-void sunxi_gpio_set_pull_bank(struct sunxi_gpio *pio, int bank_offset, u32 val);
+void sunxi_gpio_set_pull_bank(void *bank_base, int pin_offset, u32 val);
 int sunxi_name_to_gpio(const char *name);
 
 #if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
index a4b336943b6..fe3f6ed0938 100644
--- a/drivers/gpio/sunxi_gpio.c
+++ b/drivers/gpio/sunxi_gpio.c
@@ -29,45 +29,61 @@
  * =======================================================================
  */
 
-#define BANK_TO_GPIO(bank)	(((bank) < SUNXI_GPIO_L) ? \
-	&((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank] : \
-	&((struct sunxi_gpio_reg *)SUNXI_R_PIO_BASE)->gpio_bank[(bank) - SUNXI_GPIO_L])
-
 #define GPIO_BANK(pin)		((pin) >> 5)
 #define GPIO_NUM(pin)		((pin) & 0x1f)
 
+#define GPIO_CFG_REG_OFFSET	0x00
 #define GPIO_CFG_INDEX(pin)	(((pin) & 0x1f) >> 3)
 #define GPIO_CFG_OFFSET(pin)	((((pin) & 0x1f) & 0x7) << 2)
 
+#define GPIO_DAT_REG_OFFSET	0x10
+
+#define GPIO_DRV_REG_OFFSET	0x14
 #define GPIO_DRV_INDEX(pin)	(((pin) & 0x1f) >> 4)
 #define GPIO_DRV_OFFSET(pin)	((((pin) & 0x1f) & 0xf) << 1)
 
+#define GPIO_PULL_REG_OFFSET	0x1c
 #define GPIO_PULL_INDEX(pin)	(((pin) & 0x1f) >> 4)
 #define GPIO_PULL_OFFSET(pin)	((((pin) & 0x1f) & 0xf) << 1)
 
-void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val)
+static void* BANK_TO_GPIO(int bank)
+{
+	void *pio_base;
+
+	if (bank < SUNXI_GPIO_L) {
+		pio_base = (void *)(uintptr_t)SUNXI_PIO_BASE;
+	} else {
+		pio_base = (void *)(uintptr_t)SUNXI_R_PIO_BASE;
+		bank -= SUNXI_GPIO_L;
+	}
+
+	return pio_base + bank * SUNXI_PINCTRL_BANK_SIZE;
+}
+
+void sunxi_gpio_set_cfgbank(void *bank_base, int pin_offset, u32 val)
 {
-	u32 index = GPIO_CFG_INDEX(bank_offset);
-	u32 offset = GPIO_CFG_OFFSET(bank_offset);
+	u32 index = GPIO_CFG_INDEX(pin_offset);
+	u32 offset = GPIO_CFG_OFFSET(pin_offset);
 
-	clrsetbits_le32(&pio->cfg[index], 0xf << offset, val << offset);
+	clrsetbits_le32(bank_base + GPIO_CFG_REG_OFFSET + index * 4,
+			0xfU << offset, val << offset);
 }
 
 void sunxi_gpio_set_cfgpin(u32 pin, u32 val)
 {
 	u32 bank = GPIO_BANK(pin);
-	struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
+	void *pio = BANK_TO_GPIO(bank);
 
-	sunxi_gpio_set_cfgbank(pio, pin, val);
+	sunxi_gpio_set_cfgbank(pio, GPIO_NUM(pin), val);
 }
 
-int sunxi_gpio_get_cfgbank(struct sunxi_gpio *pio, int bank_offset)
+int sunxi_gpio_get_cfgbank(void *bank_base, int pin_offset)
 {
-	u32 index = GPIO_CFG_INDEX(bank_offset);
-	u32 offset = GPIO_CFG_OFFSET(bank_offset);
+	u32 index = GPIO_CFG_INDEX(pin_offset);
+	u32 offset = GPIO_CFG_OFFSET(pin_offset);
 	u32 cfg;
 
-	cfg = readl(&pio->cfg[index]);
+	cfg = readl(bank_base + GPIO_CFG_REG_OFFSET + index * 4);
 	cfg >>= offset;
 
 	return cfg & 0xf;
@@ -76,54 +92,56 @@ int sunxi_gpio_get_cfgbank(struct sunxi_gpio *pio, int bank_offset)
 int sunxi_gpio_get_cfgpin(u32 pin)
 {
 	u32 bank = GPIO_BANK(pin);
-	struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
+	void *bank_base = BANK_TO_GPIO(bank);
 
-	return sunxi_gpio_get_cfgbank(pio, pin);
+	return sunxi_gpio_get_cfgbank(bank_base, GPIO_NUM(pin));
 }
 
-static void sunxi_gpio_set_output_bank(struct sunxi_gpio *pio,
-				       int pin, bool set)
+static void sunxi_gpio_set_output_bank(void *bank_base, int pin, bool set)
 {
 	u32 mask = 1U << pin;
 
-	clrsetbits_le32(&pio->dat, set ? 0 : mask, set ? mask : 0);
+	clrsetbits_le32(bank_base + GPIO_DAT_REG_OFFSET,
+			set ? 0 : mask, set ? mask : 0);
 }
 
-static int sunxi_gpio_get_output_bank(struct sunxi_gpio *pio, int pin)
+static int sunxi_gpio_get_output_bank(void *bank_base, int pin)
 {
-	return !!(readl(&pio->dat) & (1U << pin));
+	return !!(readl(bank_base + GPIO_DAT_REG_OFFSET) & (1U << pin));
 }
 
 void sunxi_gpio_set_drv(u32 pin, u32 val)
 {
 	u32 bank = GPIO_BANK(pin);
-	struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
+	void *bank_base = BANK_TO_GPIO(bank);
 
-	sunxi_gpio_set_drv_bank(pio, pin, val);
+	sunxi_gpio_set_drv_bank(bank_base, GPIO_NUM(pin), val);
 }
 
-void sunxi_gpio_set_drv_bank(struct sunxi_gpio *pio, u32 bank_offset, u32 val)
+void sunxi_gpio_set_drv_bank(void *bank_base, u32 pin_offset, u32 val)
 {
-	u32 index = GPIO_DRV_INDEX(bank_offset);
-	u32 offset = GPIO_DRV_OFFSET(bank_offset);
+	u32 index = GPIO_DRV_INDEX(pin_offset);
+	u32 offset = GPIO_DRV_OFFSET(pin_offset);
 
-	clrsetbits_le32(&pio->drv[index], 0x3 << offset, val << offset);
+	clrsetbits_le32(bank_base + GPIO_DRV_REG_OFFSET + index * 4,
+			0x3U << offset, val << offset);
 }
 
 void sunxi_gpio_set_pull(u32 pin, u32 val)
 {
 	u32 bank = GPIO_BANK(pin);
-	struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
+	void *bank_base = BANK_TO_GPIO(bank);
 
-	sunxi_gpio_set_pull_bank(pio, pin, val);
+	sunxi_gpio_set_pull_bank(bank_base, GPIO_NUM(pin), val);
 }
 
-void sunxi_gpio_set_pull_bank(struct sunxi_gpio *pio, int bank_offset, u32 val)
+void sunxi_gpio_set_pull_bank(void *bank_base, int pin_offset, u32 val)
 {
-	u32 index = GPIO_PULL_INDEX(bank_offset);
-	u32 offset = GPIO_PULL_OFFSET(bank_offset);
+	u32 index = GPIO_PULL_INDEX(pin_offset);
+	u32 offset = GPIO_PULL_OFFSET(pin_offset);
 
-	clrsetbits_le32(&pio->pull[index], 0x3 << offset, val << offset);
+	clrsetbits_le32(bank_base + GPIO_PULL_REG_OFFSET + index * 4,
+			0x3U << offset, val << offset);
 }
 
 
@@ -133,7 +151,7 @@ void sunxi_gpio_set_pull_bank(struct sunxi_gpio *pio, int bank_offset, u32 val)
 static void sunxi_gpio_set_output(u32 pin, bool set)
 {
 	u32 bank = GPIO_BANK(pin);
-	struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
+	void *pio = BANK_TO_GPIO(bank);
 
 	sunxi_gpio_set_output_bank(pio, GPIO_NUM(pin), set);
 }
@@ -141,7 +159,7 @@ static void sunxi_gpio_set_output(u32 pin, bool set)
 static int sunxi_gpio_get_output(u32 pin)
 {
 	u32 bank = GPIO_BANK(pin);
-	struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
+	void *pio = BANK_TO_GPIO(bank);
 
 	return sunxi_gpio_get_output_bank(pio, GPIO_NUM(pin));
 }
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
index e5102180902..946447e9136 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -35,7 +35,7 @@ struct sunxi_pinctrl_desc {
 };
 
 struct sunxi_pinctrl_plat {
-	struct sunxi_gpio __iomem *base;
+	void __iomem *base;
 };
 
 static int sunxi_pinctrl_get_pins_count(struct udevice *dev)
@@ -86,8 +86,8 @@ static int sunxi_pinctrl_pinmux_set(struct udevice *dev, uint pin_selector,
 	      sunxi_pinctrl_get_function_name(dev, func_selector),
 	      desc->functions[func_selector].mux);
 
-	sunxi_gpio_set_cfgbank(plat->base + bank, pin,
-			       desc->functions[func_selector].mux);
+	sunxi_gpio_set_cfgbank(plat->base + bank * SUNXI_PINCTRL_BANK_SIZE,
+			       pin, desc->functions[func_selector].mux);
 
 	return 0;
 }
@@ -102,7 +102,7 @@ static const struct pinconf_param sunxi_pinctrl_pinconf_params[] = {
 static int sunxi_pinctrl_pinconf_set_pull(struct sunxi_pinctrl_plat *plat,
 					  uint bank, uint pin, uint bias)
 {
-	struct sunxi_gpio *regs = &plat->base[bank];
+	void *regs = plat->base + bank * SUNXI_PINCTRL_BANK_SIZE;
 
 	sunxi_gpio_set_pull_bank(regs, pin, bias);
 
@@ -112,7 +112,7 @@ static int sunxi_pinctrl_pinconf_set_pull(struct sunxi_pinctrl_plat *plat,
 static int sunxi_pinctrl_pinconf_set_drive(struct sunxi_pinctrl_plat *plat,
 					   uint bank, uint pin, uint drive)
 {
-	struct sunxi_gpio *regs = &plat->base[bank];
+	void *regs = plat->base + bank * SUNXI_PINCTRL_BANK_SIZE;
 
 	if (drive < 10 || drive > 40)
 		return -EINVAL;
@@ -148,7 +148,7 @@ static int sunxi_pinctrl_get_pin_muxing(struct udevice *dev, uint pin_selector,
 	struct sunxi_pinctrl_plat *plat = dev_get_plat(dev);
 	int bank = pin_selector / SUNXI_GPIOS_PER_BANK;
 	int pin	 = pin_selector % SUNXI_GPIOS_PER_BANK;
-	int mux  = sunxi_gpio_get_cfgbank(plat->base + bank, pin);
+	int mux  = sunxi_gpio_get_cfgbank(plat->base + bank * SUNXI_PINCTRL_BANK_SIZE, pin);
 
 	switch (mux) {
 	case SUNXI_GPIO_INPUT:
@@ -206,7 +206,7 @@ static int sunxi_pinctrl_bind(struct udevice *dev)
 		if (!gpio_plat)
 			return -ENOMEM;
 
-		gpio_plat->regs = plat->base + i;
+		gpio_plat->regs = plat->base + i * SUNXI_PINCTRL_BANK_SIZE;
 		gpio_plat->bank_name[0] = 'P';
 		gpio_plat->bank_name[1] = 'A' + desc->first_bank + i;
 		gpio_plat->bank_name[2] = '\0';
-- 
2.35.8


  parent reply	other threads:[~2023-09-28 21:56 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-28 21:54 [PATCH v2 00/22] sunxi: Allwinner T113s support Andre Przywara
2023-09-28 21:54 ` [PATCH v2 01/22] sunxi: remove CONFIG_SATAPWR Andre Przywara
2023-10-19 23:51   ` Samuel Holland
2023-10-21 23:27     ` Andre Przywara
2023-10-22  3:34       ` Samuel Holland
2023-09-28 21:54 ` [PATCH v2 02/22] net: sunxi_emac: chase DT nodes to find PHY regulator Andre Przywara
2023-10-20  0:01   ` Samuel Holland
2023-10-21 23:33     ` Andre Przywara
2023-09-28 21:54 ` [PATCH v2 03/22] sunxi: remove CONFIG_MACPWR Andre Przywara
2023-10-21  4:35   ` Samuel Holland
2023-09-28 21:54 ` [PATCH v2 04/22] pinctrl: sunxi: move pinctrl code Andre Przywara
2023-10-19  0:18   ` Andre Przywara
2023-10-21  8:21   ` Samuel Holland
2023-09-28 21:54 ` [PATCH v2 05/22] pinctrl: sunxi: add GPIO in/out wrappers Andre Przywara
2023-10-21  8:30   ` Samuel Holland
2023-10-21 23:46     ` Andre Przywara
2023-09-28 21:54 ` Andre Przywara [this message]
2023-10-21  8:37   ` [PATCH v2 06/22] pinctrl: sunxi: remove struct sunxi_gpio Samuel Holland
2023-09-28 21:54 ` [PATCH v2 07/22] pinctrl: sunxi: remove GPIO_EXTRA_HEADER Andre Przywara
2023-10-21  8:57   ` Samuel Holland
2023-09-28 21:54 ` [PATCH v2 08/22] pinctrl: sunxi: move PIO_BASE into sunxi_gpio.h Andre Przywara
2023-09-28 21:54 ` [PATCH v2 09/22] pinctrl: sunxi: add new D1 pinctrl support Andre Przywara
2023-10-22  3:31   ` Samuel Holland
2023-09-28 21:54 ` [PATCH v2 10/22] sunxi: introduce NCAT2 generation model Andre Przywara
2023-10-22  3:40   ` Samuel Holland
2023-09-28 21:54 ` [PATCH v2 11/22] pinctrl: sunxi: add Allwinner D1 pinctrl description Andre Przywara
2023-10-21  4:34   ` Samuel Holland
2023-09-28 21:54 ` [PATCH v2 12/22] clk: sunxi: Add support for the D1 CCU Andre Przywara
2023-10-19 23:53   ` Samuel Holland
2023-09-28 21:54 ` [PATCH v2 13/22] sunxi: clock: D1/R528: Enable PLL LDO during PLL1 setup Andre Przywara
2023-09-28 21:54 ` [PATCH v2 14/22] sunxi: clock: support D1/R528 PLL6 clock Andre Przywara
2023-09-28 21:54 ` [PATCH v2 15/22] Kconfig: sunxi: prepare for using drivers/ram/sunxi Andre Przywara
2023-10-22  3:44   ` Samuel Holland
2023-09-28 21:54 ` [PATCH v2 16/22] sunxi: add R528/T113-s3/D1(s) DRAM initialisation code Andre Przywara
2023-10-22  3:52   ` Samuel Holland
2023-10-22 22:40     ` Andre Przywara
2023-10-23  2:58       ` Samuel Holland
2023-09-28 21:54 ` [PATCH v2 17/22] sunxi: add Allwinner R528/T113 SoC support Andre Przywara
2023-09-28 21:54 ` [PATCH v2 18/22] sunxi: R528: add SMHC2 pin pull ups support Andre Przywara
2023-09-28 21:54 ` [PATCH v2 19/22] sunxi: refactor serial base addresses to avoid asm/arch/cpu.h Andre Przywara
2023-09-28 21:54 ` [PATCH v2 20/22] riscv: dts: allwinner: Add the D1/D1s SoC devicetree Andre Przywara
2023-09-28 21:54 ` [PATCH v2 21/22] ARM: dts: sunxi: add Allwinner T113-s SoC .dtsi Andre Przywara
2023-09-28 21:54 ` [PATCH v2 22/22] sunxi: add MangoPi MQ-R board support Andre Przywara

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230928215455.28094-7-andre.przywara@arm.com \
    --to=andre.przywara@arm.com \
    --cc=andre.przywara@foss.arm.com \
    --cc=bigunclemax@gmail.com \
    --cc=cfsworks@gmail.com \
    --cc=jagan@amarulasolutions.com \
    --cc=jernej.skrabec@gmail.com \
    --cc=linux-sunxi@lists.linux.dev \
    --cc=okhunjon72@gmail.com \
    --cc=samuel@sholland.org \
    --cc=u-boot@lists.denx.de \
    --cc=uwu@icenowy.me \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.