* [PATCH v3 0/3] Add pin control driver for BCM2712 SoC
@ 2025-08-11 14:46 Andrea della Porta
2025-08-11 14:46 ` [PATCH v3 1/3] dt-bindings: pinctrl: Add support for Broadcom STB pin controller Andrea della Porta
` (2 more replies)
0 siblings, 3 replies; 20+ messages in thread
From: Andrea della Porta @ 2025-08-11 14:46 UTC (permalink / raw)
To: linus.walleij, robh, krzk+dt, conor+dt, florian.fainelli,
wahrenst, linux-gpio, devicetree, linux-arm-kernel,
Catalin Marinas, Will Deacon, iivanov, svarbanov, mbrugger,
Jonathan Bell, Phil Elwell
Cc: Andrea della Porta
*important note* - For clarity's sake, here's the revision list from which
this patchset derives:
V3 (this patchset, split-up to deal exclusively with pin controller stuff)
V2 (missing v2 in the mail subject): https://lore.kernel.org/all/cover.1752584387.git.andrea.porta@suse.com/
V1 (original by Ivan): https://lore.kernel.org/all/20240731062814.215833-1-iivanov@suse.de/
Also, in V3 the patchset has been split into two:
- patches 1, 2 and 7 from V2 form the new revision V3 to deal with
core pinctrl stuff only.
- all remaining patches will respawn as a new patchset that adds new DT
nodes for the peripherals that use the pinctrl. As a consequence, it
will require the above mentioned V3 patchset as a prerequisite.
---
Hi,
The following patches add a pin control driver for the BCM2712 SoC.
Device driver is follow up version on what Andrea posted in April [1].
It is based on sources from here [2]. I just made few cosmetic changes
and addressed review comments from earlier submission. I don't have
documentation for this controller.
A separate patchset will add peripheral nodes that rely on the SoC pin
controller to setup and config the pins.
All this have been tested as kernel was directly booted RPi5 via
kernel= config.txt option and cmdline.txt file with following content
(Note I am using Tumbleweed RPi raw images)
# cat /boot/efi/cmdline.txt
root=/dev/mmcblk0p3 rootwait rw systemd.show_status=1 console=tty ignore_loglevel earlycon console=ttyAMA10,115200
With all these patches Bluetooth and Wifi are working fine (tm) with
firmware files provided by openSUSE Tumbleweed.
All comments and suggestions are welcome!
Happy hacking!
Ivan and Andrea
[1] https://lore.kernel.org/lkml/f6601f73-cb22-4ba3-88c5-241be8421fc3@broadcom.com/
[2] https://github.com/raspberrypi/linux/blob/rpi-6.6.y/drivers/pinctrl/bcm/pinctrl-bcm2712.c
[3] https://lore.kernel.org/lkml/20240605120712.3523290-1-florian.fainelli@broadcom.com/#t
[4] https://lore.kernel.org/all/bfc60a7e-54d2-48a6-a288-4fe76d66507a@gmx.net/
CHANGES in V3:
--- PATCHES ---
- The V2 patchset has been split into two. This patchset (V3) contains reworked
patches 1,2,7 from V2 while the remaining (again, reworked) patches will
respawn as an entirely new patchset.
--- DT BINDINGS ---
- brcm,bcm2712c0-pinctrl.yaml: emmc_* pins are specific and do not provide
other alternate function, so the function property can be dropped for those
pins.
- brcm,bcm2712c0-pinctrl.yaml: fixed the schema ID reflecting the current
filename.
--- DRIVER ---
- pinctrl-brcmstb.c: wrapped a couple of lines exceeding 100 columns.
Andrea della Porta (1):
arm64: defconfig: Enable BCM2712 on-chip pin controller driver
Ivan T. Ivanov (2):
dt-bindings: pinctrl: Add support for Broadcom STB pin controller
pinctrl: bcm: Add STB family pin controller driver
.../pinctrl/brcm,bcm2712c0-pinctrl.yaml | 135 ++
arch/arm64/configs/defconfig | 1 +
drivers/pinctrl/bcm/Kconfig | 13 +
drivers/pinctrl/bcm/Makefile | 1 +
drivers/pinctrl/bcm/pinctrl-brcmstb.c | 1197 +++++++++++++++++
5 files changed, 1347 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm2712c0-pinctrl.yaml
create mode 100644 drivers/pinctrl/bcm/pinctrl-brcmstb.c
--
2.35.3
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v3 1/3] dt-bindings: pinctrl: Add support for Broadcom STB pin controller
2025-08-11 14:46 [PATCH v3 0/3] Add pin control driver for BCM2712 SoC Andrea della Porta
@ 2025-08-11 14:46 ` Andrea della Porta
2025-08-18 17:20 ` Rob Herring
2025-08-11 14:46 ` [PATCH v3 2/3] pinctrl: bcm: Add STB family pin controller driver Andrea della Porta
2025-08-11 14:46 ` [PATCH v3 3/3] arm64: defconfig: Enable BCM2712 on-chip " Andrea della Porta
2 siblings, 1 reply; 20+ messages in thread
From: Andrea della Porta @ 2025-08-11 14:46 UTC (permalink / raw)
To: linus.walleij, robh, krzk+dt, conor+dt, florian.fainelli,
wahrenst, linux-gpio, devicetree, linux-arm-kernel,
Catalin Marinas, Will Deacon, iivanov, svarbanov, mbrugger,
Jonathan Bell, Phil Elwell
Cc: Andrea della Porta
From: "Ivan T. Ivanov" <iivanov@suse.de>
The STB pin controller represents a family whose silicon instances
are found e.g. on BCM2712 SoC.
In particular, on RaspberryPi 5, there are two separate instantiations
of the same IP block which differ in the number of pins that are
associated and the pinmux functions for each of those pins. The
-aon- variant stands for 'Always On'.
Depending on the revision of the BCM2712 (CO or D0), the pin
controller instance has slight differences in the register layout.
Signed-off-by: Ivan T. Ivanov <iivanov@suse.de>
Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
---
.../pinctrl/brcm,bcm2712c0-pinctrl.yaml | 135 ++++++++++++++++++
1 file changed, 135 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm2712c0-pinctrl.yaml
diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm2712c0-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm2712c0-pinctrl.yaml
new file mode 100644
index 000000000000..28d66336aa2e
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm2712c0-pinctrl.yaml
@@ -0,0 +1,135 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/brcm,bcm2712c0-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom STB family pin controller
+
+maintainers:
+ - Ivan T. Ivanov <iivanov@suse.de>
+ - A. della Porta <andrea.porta@suse.com>
+
+description:
+ Broadcom's STB family of memory-mapped pin controllers.
+ This includes the pin controllers inside the BCM2712 SoC which
+ are instances of the STB family and has two silicon variants,
+ C0 and D0, which differs slightly in terms of registers layout.
+ The -aon- (Always On) variant is the same IP block but differs
+ in the number of pins that are associated and the pinmux functions
+ for each of those pins.
+
+allOf:
+ - $ref: pinctrl.yaml#
+
+properties:
+ compatible:
+ enum:
+ - brcm,bcm2712c0-pinctrl
+ - brcm,bcm2712c0-aon-pinctrl
+ - brcm,bcm2712d0-pinctrl
+ - brcm,bcm2712d0-aon-pinctrl
+
+ reg:
+ maxItems: 1
+
+patternProperties:
+ '-state$':
+ oneOf:
+ - $ref: '#/$defs/brcmstb-pinctrl-state'
+ - patternProperties:
+ '-pins$':
+ $ref: '#/$defs/brcmstb-pinctrl-state'
+ additionalProperties: false
+
+$defs:
+ brcmstb-pinctrl-state:
+ allOf:
+ - $ref: pincfg-node.yaml#
+ - $ref: pinmux-node.yaml#
+
+ description:
+ Pin controller client devices use pin configuration subnodes (children
+ and grandchildren) for desired pin configuration.
+ Client device subnodes use below standard properties.
+
+ properties:
+ pins:
+ description:
+ List of gpio pins affected by the properties specified in this
+ subnode (either this or "groups" must be specified).
+ items:
+ pattern: '^((aon_)?s?gpio[0-6]?[0-9])|(emmc_(clk|cmd|dat[0-7]|ds))$'
+
+ function:
+ enum: [ gpio, alt1, alt2, alt3, alt4, alt5, alt6, alt7, alt8,
+ aon_cpu_standbyb, aon_fp_4sec_resetb, aon_gpclk, aon_pwm,
+ arm_jtag, aud_fs_clk0, avs_pmu_bsc, bsc_m0, bsc_m1, bsc_m2,
+ bsc_m3, clk_observe, ctl_hdmi_5v, enet0, enet0_mii, enet0_rgmii,
+ ext_sc_clk, fl0, fl1, gpclk0, gpclk1, gpclk2, hdmi_tx0_auto_i2c,
+ hdmi_tx0_bsc, hdmi_tx1_auto_i2c, hdmi_tx1_bsc, i2s_in, i2s_out,
+ ir_in, mtsif, mtsif_alt, mtsif_alt1, pdm, pkt, pm_led_out, sc0,
+ sd0, sd2, sd_card_a, sd_card_b, sd_card_c, sd_card_d, sd_card_e,
+ sd_card_f, sd_card_g, spdif_out, spi_m, spi_s, sr_edm_sense, te0,
+ te1, tsio, uart0, uart1, uart2, usb_pwr, usb_vbus, uui, vc_i2c0,
+ vc_i2c3, vc_i2c4, vc_i2c5, vc_i2csl, vc_pcm, vc_pwm0, vc_pwm1,
+ vc_spi0, vc_spi3, vc_spi4, vc_spi5, vc_uart0, vc_uart2, vc_uart3,
+ vc_uart4 ]
+
+ description:
+ Specify the alternative function to be configured for the specified
+ pins.
+
+ bias-disable: true
+ bias-pull-down: true
+ bias-pull-up: true
+
+ required:
+ - pins
+
+ if:
+ properties:
+ pins:
+ not:
+ contains:
+ pattern: "^emmc_(clk|cmd|dat[0-7]|ds)$"
+ then:
+ required:
+ - function
+ else:
+ properties:
+ function: false
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - reg
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ brcm_pinctrl: pinctrl@7d504100 {
+ compatible = "brcm,bcm2712c0-pinctrl";
+ reg = <0x7d504100 0x30>;
+
+ bt-shutdown-default-state {
+ function = "gpio";
+ pins = "gpio29";
+ };
+
+ uarta-default-state {
+ rts-tx-pins {
+ function = "uart0";
+ pins = "gpio24", "gpio26";
+ bias-disable;
+ };
+
+ cts-rx-pins {
+ function = "uart0";
+ pins = "gpio25", "gpio27";
+ bias-pull-up;
+ };
+ };
+ };
--
2.35.3
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 2/3] pinctrl: bcm: Add STB family pin controller driver
2025-08-11 14:46 [PATCH v3 0/3] Add pin control driver for BCM2712 SoC Andrea della Porta
2025-08-11 14:46 ` [PATCH v3 1/3] dt-bindings: pinctrl: Add support for Broadcom STB pin controller Andrea della Porta
@ 2025-08-11 14:46 ` Andrea della Porta
2025-08-19 7:40 ` Stanimir Varbanov
` (3 more replies)
2025-08-11 14:46 ` [PATCH v3 3/3] arm64: defconfig: Enable BCM2712 on-chip " Andrea della Porta
2 siblings, 4 replies; 20+ messages in thread
From: Andrea della Porta @ 2025-08-11 14:46 UTC (permalink / raw)
To: linus.walleij, robh, krzk+dt, conor+dt, florian.fainelli,
wahrenst, linux-gpio, devicetree, linux-arm-kernel,
Catalin Marinas, Will Deacon, iivanov, svarbanov, mbrugger,
Jonathan Bell, Phil Elwell
Cc: Andrea della Porta
From: "Ivan T. Ivanov" <iivanov@suse.de>
This driver provide pin muxing and configuration functionality
for BCM2712 SoC used by RPi5. According to [1] this chip is an
instance of the one used in Broadcom STB product line.
[1] https://lore.kernel.org/lkml/f6601f73-cb22-4ba3-88c5-241be8421fc3@broadcom.com/
Cc: Jonathan Bell <jonathan@raspberrypi.com>
Cc: Phil Elwell <phil@raspberrypi.com>
Signed-off-by: Ivan T. Ivanov <iivanov@suse.de>
Reviewed-by: Phil Elwell <phil@raspberrypi.com>
Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
---
drivers/pinctrl/bcm/Kconfig | 13 +
drivers/pinctrl/bcm/Makefile | 1 +
drivers/pinctrl/bcm/pinctrl-brcmstb.c | 1197 +++++++++++++++++++++++++
3 files changed, 1211 insertions(+)
create mode 100644 drivers/pinctrl/bcm/pinctrl-brcmstb.c
diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
index 35b51ce4298e..2e1b8d444f58 100644
--- a/drivers/pinctrl/bcm/Kconfig
+++ b/drivers/pinctrl/bcm/Kconfig
@@ -3,6 +3,19 @@
# Broadcom pinctrl drivers
#
+config PINCTRL_BRCMSTB
+ tristate "Broadcom STB product line pin controller driver"
+ depends on OF && (ARCH_BRCMSTB || COMPILE_TEST)
+ select PINMUX
+ select PINCONF
+ select GENERIC_PINCONF
+ help
+ This driver provide pin muxing and configuration functionality
+ for Broadcom STB product line chipsets. BCM2712 SoC is one of these
+ chipsets.
+
+ If M is selected the module will be called pinctrl-brcmstb.
+
config PINCTRL_BCM281XX
bool "Broadcom BCM281xx pinctrl driver"
depends on OF && (ARCH_BCM_MOBILE || COMPILE_TEST)
diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
index 82b868ec1471..5f790c14cc4c 100644
--- a/drivers/pinctrl/bcm/Makefile
+++ b/drivers/pinctrl/bcm/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_PINCTRL_BCM6358) += pinctrl-bcm6358.o
obj-$(CONFIG_PINCTRL_BCM6362) += pinctrl-bcm6362.o
obj-$(CONFIG_PINCTRL_BCM6368) += pinctrl-bcm6368.o
obj-$(CONFIG_PINCTRL_BCM63268) += pinctrl-bcm63268.o
+obj-$(CONFIG_PINCTRL_BRCMSTB) += pinctrl-brcmstb.o
obj-$(CONFIG_PINCTRL_IPROC_GPIO) += pinctrl-iproc-gpio.o
obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o
obj-$(CONFIG_PINCTRL_NS) += pinctrl-ns.o
diff --git a/drivers/pinctrl/bcm/pinctrl-brcmstb.c b/drivers/pinctrl/bcm/pinctrl-brcmstb.c
new file mode 100644
index 000000000000..534bd8908630
--- /dev/null
+++ b/drivers/pinctrl/bcm/pinctrl-brcmstb.c
@@ -0,0 +1,1197 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for Broadcom brcmstb GPIO units (pinctrl only)
+ *
+ * Copyright (C) 2024-2025 Ivan T. Ivanov, Andrea della Porta
+ * Copyright (C) 2021-3 Raspberry Pi Ltd.
+ * Copyright (C) 2012 Chris Boot, Simon Arlott, Stephen Warren
+ *
+ * Based heavily on the BCM2835 GPIO & pinctrl driver, which was inspired by:
+ * pinctrl-nomadik.c, please see original file for copyright information
+ * pinctrl-tegra.c, please see original file for copyright information
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/platform_device.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#define BRCMSTB_PULL_NONE 0
+#define BRCMSTB_PULL_DOWN 1
+#define BRCMSTB_PULL_UP 2
+#define BRCMSTB_PULL_MASK 0x3
+
+#define BRCMSTB_FSEL_COUNT 9
+#define BRCMSTB_FSEL_MASK 0xf
+
+#define FUNC(f) \
+ [func_##f] = #f
+
+#define PIN(i, f1, f2, f3, f4, f5, f6, f7, f8) \
+ [i] = { \
+ .funcs = { \
+ func_##f1, \
+ func_##f2, \
+ func_##f3, \
+ func_##f4, \
+ func_##f5, \
+ func_##f6, \
+ func_##f7, \
+ func_##f8, \
+ }, \
+ }
+
+#define MUX_BIT_VALID 0x8000
+#define PAD_BIT_INVALID 0xffff
+
+#define BIT_TO_REG(b) (((b) >> 5) << 2)
+#define BIT_TO_SHIFT(b) ((b) & 0x1f)
+
+#define MUX_BIT(muxreg, muxshift) \
+ (MUX_BIT_VALID + ((muxreg) << 5) + ((muxshift) << 2))
+#define PAD_BIT(padreg, padshift) \
+ (((padreg) << 5) + ((padshift) << 1))
+
+#define GPIO_REGS(n, muxreg, muxshift, padreg, padshift) \
+ [n] = { MUX_BIT(muxreg, muxshift), PAD_BIT(padreg, padshift) }
+
+#define EMMC_REGS(n, padreg, padshift) \
+ [n] = { 0, PAD_BIT(padreg, padshift) }
+
+#define AGPIO_REGS(n, muxreg, muxshift, padreg, padshift) \
+ GPIO_REGS(n, muxreg, muxshift, padreg, padshift)
+
+#define SGPIO_REGS(n, muxreg, muxshift) \
+ [(n) + 32] = { MUX_BIT(muxreg, muxshift), PAD_BIT_INVALID }
+
+#define GPIO_PIN(n) PINCTRL_PIN(n, "gpio" #n)
+#define AGPIO_PIN(n) PINCTRL_PIN(n, "aon_gpio" #n)
+#define SGPIO_PIN(n) PINCTRL_PIN((n) + 32, "aon_sgpio" #n)
+
+struct pin_regs {
+ u16 mux_bit;
+ u16 pad_bit;
+};
+
+struct brcmstb_pin_funcs {
+ u8 funcs[BRCMSTB_FSEL_COUNT - 1];
+};
+
+struct brcmstb_pinctrl {
+ struct device *dev;
+ void __iomem *base;
+ struct pinctrl_dev *pctl_dev;
+ struct pinctrl_desc pctl_desc;
+ const struct pin_regs *pin_regs;
+ const struct brcmstb_pin_funcs *pin_funcs;
+ const char *const *gpio_groups;
+ struct pinctrl_gpio_range gpio_range;
+ /* Protect FSEL registers */
+ spinlock_t fsel_lock;
+};
+
+struct brcmstb_pdata {
+ const struct pinctrl_desc *pctl_desc;
+ const struct pinctrl_gpio_range *gpio_range;
+ const struct pin_regs *pin_regs;
+ const struct brcmstb_pin_funcs *pin_funcs;
+};
+
+enum brcmstb_funcs {
+ func_gpio,
+ func_alt1,
+ func_alt2,
+ func_alt3,
+ func_alt4,
+ func_alt5,
+ func_alt6,
+ func_alt7,
+ func_alt8,
+ func_aon_cpu_standbyb,
+ func_aon_fp_4sec_resetb,
+ func_aon_gpclk,
+ func_aon_pwm,
+ func_arm_jtag,
+ func_aud_fs_clk0,
+ func_avs_pmu_bsc,
+ func_bsc_m0,
+ func_bsc_m1,
+ func_bsc_m2,
+ func_bsc_m3,
+ func_clk_observe,
+ func_ctl_hdmi_5v,
+ func_enet0,
+ func_enet0_mii,
+ func_enet0_rgmii,
+ func_ext_sc_clk,
+ func_fl0,
+ func_fl1,
+ func_gpclk0,
+ func_gpclk1,
+ func_gpclk2,
+ func_hdmi_tx0_auto_i2c,
+ func_hdmi_tx0_bsc,
+ func_hdmi_tx1_auto_i2c,
+ func_hdmi_tx1_bsc,
+ func_i2s_in,
+ func_i2s_out,
+ func_ir_in,
+ func_mtsif,
+ func_mtsif_alt,
+ func_mtsif_alt1,
+ func_pdm,
+ func_pkt,
+ func_pm_led_out,
+ func_sc0,
+ func_sd0,
+ func_sd2,
+ func_sd_card_a,
+ func_sd_card_b,
+ func_sd_card_c,
+ func_sd_card_d,
+ func_sd_card_e,
+ func_sd_card_f,
+ func_sd_card_g,
+ func_spdif_out,
+ func_spi_m,
+ func_spi_s,
+ func_sr_edm_sense,
+ func_te0,
+ func_te1,
+ func_tsio,
+ func_uart0,
+ func_uart1,
+ func_uart2,
+ func_usb_pwr,
+ func_usb_vbus,
+ func_uui,
+ func_vc_i2c0,
+ func_vc_i2c3,
+ func_vc_i2c4,
+ func_vc_i2c5,
+ func_vc_i2csl,
+ func_vc_pcm,
+ func_vc_pwm0,
+ func_vc_pwm1,
+ func_vc_spi0,
+ func_vc_spi3,
+ func_vc_spi4,
+ func_vc_spi5,
+ func_vc_uart0,
+ func_vc_uart2,
+ func_vc_uart3,
+ func_vc_uart4,
+ func__,
+ func_count = func__
+};
+
+static const struct pin_regs bcm2712_c0_gpio_pin_regs[] = {
+ GPIO_REGS(0, 0, 0, 7, 7),
+ GPIO_REGS(1, 0, 1, 7, 8),
+ GPIO_REGS(2, 0, 2, 7, 9),
+ GPIO_REGS(3, 0, 3, 7, 10),
+ GPIO_REGS(4, 0, 4, 7, 11),
+ GPIO_REGS(5, 0, 5, 7, 12),
+ GPIO_REGS(6, 0, 6, 7, 13),
+ GPIO_REGS(7, 0, 7, 7, 14),
+ GPIO_REGS(8, 1, 0, 8, 0),
+ GPIO_REGS(9, 1, 1, 8, 1),
+ GPIO_REGS(10, 1, 2, 8, 2),
+ GPIO_REGS(11, 1, 3, 8, 3),
+ GPIO_REGS(12, 1, 4, 8, 4),
+ GPIO_REGS(13, 1, 5, 8, 5),
+ GPIO_REGS(14, 1, 6, 8, 6),
+ GPIO_REGS(15, 1, 7, 8, 7),
+ GPIO_REGS(16, 2, 0, 8, 8),
+ GPIO_REGS(17, 2, 1, 8, 9),
+ GPIO_REGS(18, 2, 2, 8, 10),
+ GPIO_REGS(19, 2, 3, 8, 11),
+ GPIO_REGS(20, 2, 4, 8, 12),
+ GPIO_REGS(21, 2, 5, 8, 13),
+ GPIO_REGS(22, 2, 6, 8, 14),
+ GPIO_REGS(23, 2, 7, 9, 0),
+ GPIO_REGS(24, 3, 0, 9, 1),
+ GPIO_REGS(25, 3, 1, 9, 2),
+ GPIO_REGS(26, 3, 2, 9, 3),
+ GPIO_REGS(27, 3, 3, 9, 4),
+ GPIO_REGS(28, 3, 4, 9, 5),
+ GPIO_REGS(29, 3, 5, 9, 6),
+ GPIO_REGS(30, 3, 6, 9, 7),
+ GPIO_REGS(31, 3, 7, 9, 8),
+ GPIO_REGS(32, 4, 0, 9, 9),
+ GPIO_REGS(33, 4, 1, 9, 10),
+ GPIO_REGS(34, 4, 2, 9, 11),
+ GPIO_REGS(35, 4, 3, 9, 12),
+ GPIO_REGS(36, 4, 4, 9, 13),
+ GPIO_REGS(37, 4, 5, 9, 14),
+ GPIO_REGS(38, 4, 6, 10, 0),
+ GPIO_REGS(39, 4, 7, 10, 1),
+ GPIO_REGS(40, 5, 0, 10, 2),
+ GPIO_REGS(41, 5, 1, 10, 3),
+ GPIO_REGS(42, 5, 2, 10, 4),
+ GPIO_REGS(43, 5, 3, 10, 5),
+ GPIO_REGS(44, 5, 4, 10, 6),
+ GPIO_REGS(45, 5, 5, 10, 7),
+ GPIO_REGS(46, 5, 6, 10, 8),
+ GPIO_REGS(47, 5, 7, 10, 9),
+ GPIO_REGS(48, 6, 0, 10, 10),
+ GPIO_REGS(49, 6, 1, 10, 11),
+ GPIO_REGS(50, 6, 2, 10, 12),
+ GPIO_REGS(51, 6, 3, 10, 13),
+ GPIO_REGS(52, 6, 4, 10, 14),
+ GPIO_REGS(53, 6, 5, 11, 0),
+ EMMC_REGS(54, 11, 1), /* EMMC_CMD */
+ EMMC_REGS(55, 11, 2), /* EMMC_DS */
+ EMMC_REGS(56, 11, 3), /* EMMC_CLK */
+ EMMC_REGS(57, 11, 4), /* EMMC_DAT0 */
+ EMMC_REGS(58, 11, 5), /* EMMC_DAT1 */
+ EMMC_REGS(59, 11, 6), /* EMMC_DAT2 */
+ EMMC_REGS(60, 11, 7), /* EMMC_DAT3 */
+ EMMC_REGS(61, 11, 8), /* EMMC_DAT4 */
+ EMMC_REGS(62, 11, 9), /* EMMC_DAT5 */
+ EMMC_REGS(63, 11, 10), /* EMMC_DAT6 */
+ EMMC_REGS(64, 11, 11), /* EMMC_DAT7 */
+};
+
+static struct pin_regs bcm2712_c0_aon_gpio_pin_regs[] = {
+ AGPIO_REGS(0, 3, 0, 6, 10),
+ AGPIO_REGS(1, 3, 1, 6, 11),
+ AGPIO_REGS(2, 3, 2, 6, 12),
+ AGPIO_REGS(3, 3, 3, 6, 13),
+ AGPIO_REGS(4, 3, 4, 6, 14),
+ AGPIO_REGS(5, 3, 5, 7, 0),
+ AGPIO_REGS(6, 3, 6, 7, 1),
+ AGPIO_REGS(7, 3, 7, 7, 2),
+ AGPIO_REGS(8, 4, 0, 7, 3),
+ AGPIO_REGS(9, 4, 1, 7, 4),
+ AGPIO_REGS(10, 4, 2, 7, 5),
+ AGPIO_REGS(11, 4, 3, 7, 6),
+ AGPIO_REGS(12, 4, 4, 7, 7),
+ AGPIO_REGS(13, 4, 5, 7, 8),
+ AGPIO_REGS(14, 4, 6, 7, 9),
+ AGPIO_REGS(15, 4, 7, 7, 10),
+ AGPIO_REGS(16, 5, 0, 7, 11),
+ SGPIO_REGS(0, 0, 0),
+ SGPIO_REGS(1, 0, 1),
+ SGPIO_REGS(2, 0, 2),
+ SGPIO_REGS(3, 0, 3),
+ SGPIO_REGS(4, 1, 0),
+ SGPIO_REGS(5, 2, 0),
+};
+
+static const struct pinctrl_pin_desc bcm2712_c0_gpio_pins[] = {
+ GPIO_PIN(0),
+ GPIO_PIN(1),
+ GPIO_PIN(2),
+ GPIO_PIN(3),
+ GPIO_PIN(4),
+ GPIO_PIN(5),
+ GPIO_PIN(6),
+ GPIO_PIN(7),
+ GPIO_PIN(8),
+ GPIO_PIN(9),
+ GPIO_PIN(10),
+ GPIO_PIN(11),
+ GPIO_PIN(12),
+ GPIO_PIN(13),
+ GPIO_PIN(14),
+ GPIO_PIN(15),
+ GPIO_PIN(16),
+ GPIO_PIN(17),
+ GPIO_PIN(18),
+ GPIO_PIN(19),
+ GPIO_PIN(20),
+ GPIO_PIN(21),
+ GPIO_PIN(22),
+ GPIO_PIN(23),
+ GPIO_PIN(24),
+ GPIO_PIN(25),
+ GPIO_PIN(26),
+ GPIO_PIN(27),
+ GPIO_PIN(28),
+ GPIO_PIN(29),
+ GPIO_PIN(30),
+ GPIO_PIN(31),
+ GPIO_PIN(32),
+ GPIO_PIN(33),
+ GPIO_PIN(34),
+ GPIO_PIN(35),
+ GPIO_PIN(36),
+ GPIO_PIN(37),
+ GPIO_PIN(38),
+ GPIO_PIN(39),
+ GPIO_PIN(40),
+ GPIO_PIN(41),
+ GPIO_PIN(42),
+ GPIO_PIN(43),
+ GPIO_PIN(44),
+ GPIO_PIN(45),
+ GPIO_PIN(46),
+ GPIO_PIN(47),
+ GPIO_PIN(48),
+ GPIO_PIN(49),
+ GPIO_PIN(50),
+ GPIO_PIN(51),
+ GPIO_PIN(52),
+ GPIO_PIN(53),
+ PINCTRL_PIN(54, "emmc_cmd"),
+ PINCTRL_PIN(55, "emmc_ds"),
+ PINCTRL_PIN(56, "emmc_clk"),
+ PINCTRL_PIN(57, "emmc_dat0"),
+ PINCTRL_PIN(58, "emmc_dat1"),
+ PINCTRL_PIN(59, "emmc_dat2"),
+ PINCTRL_PIN(60, "emmc_dat3"),
+ PINCTRL_PIN(61, "emmc_dat4"),
+ PINCTRL_PIN(62, "emmc_dat5"),
+ PINCTRL_PIN(63, "emmc_dat6"),
+ PINCTRL_PIN(64, "emmc_dat7"),
+};
+
+static struct pinctrl_pin_desc bcm2712_c0_aon_gpio_pins[] = {
+ AGPIO_PIN(0), AGPIO_PIN(1), AGPIO_PIN(2), AGPIO_PIN(3),
+ AGPIO_PIN(4), AGPIO_PIN(5), AGPIO_PIN(6), AGPIO_PIN(7),
+ AGPIO_PIN(8), AGPIO_PIN(9), AGPIO_PIN(10), AGPIO_PIN(11),
+ AGPIO_PIN(12), AGPIO_PIN(13), AGPIO_PIN(14), AGPIO_PIN(15),
+ AGPIO_PIN(16), SGPIO_PIN(0), SGPIO_PIN(1), SGPIO_PIN(2),
+ SGPIO_PIN(3), SGPIO_PIN(4), SGPIO_PIN(5),
+};
+
+static const struct pin_regs bcm2712_d0_gpio_pin_regs[] = {
+ GPIO_REGS(1, 0, 0, 4, 5),
+ GPIO_REGS(2, 0, 1, 4, 6),
+ GPIO_REGS(3, 0, 2, 4, 7),
+ GPIO_REGS(4, 0, 3, 4, 8),
+ GPIO_REGS(10, 0, 4, 4, 9),
+ GPIO_REGS(11, 0, 5, 4, 10),
+ GPIO_REGS(12, 0, 6, 4, 11),
+ GPIO_REGS(13, 0, 7, 4, 12),
+ GPIO_REGS(14, 1, 0, 4, 13),
+ GPIO_REGS(15, 1, 1, 4, 14),
+ GPIO_REGS(18, 1, 2, 5, 0),
+ GPIO_REGS(19, 1, 3, 5, 1),
+ GPIO_REGS(20, 1, 4, 5, 2),
+ GPIO_REGS(21, 1, 5, 5, 3),
+ GPIO_REGS(22, 1, 6, 5, 4),
+ GPIO_REGS(23, 1, 7, 5, 5),
+ GPIO_REGS(24, 2, 0, 5, 6),
+ GPIO_REGS(25, 2, 1, 5, 7),
+ GPIO_REGS(26, 2, 2, 5, 8),
+ GPIO_REGS(27, 2, 3, 5, 9),
+ GPIO_REGS(28, 2, 4, 5, 10),
+ GPIO_REGS(29, 2, 5, 5, 11),
+ GPIO_REGS(30, 2, 6, 5, 12),
+ GPIO_REGS(31, 2, 7, 5, 13),
+ GPIO_REGS(32, 3, 0, 5, 14),
+ GPIO_REGS(33, 3, 1, 6, 0),
+ GPIO_REGS(34, 3, 2, 6, 1),
+ GPIO_REGS(35, 3, 3, 6, 2),
+ EMMC_REGS(36, 6, 3), /* EMMC_CMD */
+ EMMC_REGS(37, 6, 4), /* EMMC_DS */
+ EMMC_REGS(38, 6, 5), /* EMMC_CLK */
+ EMMC_REGS(39, 6, 6), /* EMMC_DAT0 */
+ EMMC_REGS(40, 6, 7), /* EMMC_DAT1 */
+ EMMC_REGS(41, 6, 8), /* EMMC_DAT2 */
+ EMMC_REGS(42, 6, 9), /* EMMC_DAT3 */
+ EMMC_REGS(43, 6, 10), /* EMMC_DAT4 */
+ EMMC_REGS(44, 6, 11), /* EMMC_DAT5 */
+ EMMC_REGS(45, 6, 12), /* EMMC_DAT6 */
+ EMMC_REGS(46, 6, 13), /* EMMC_DAT7 */
+};
+
+static struct pin_regs bcm2712_d0_aon_gpio_pin_regs[] = {
+ AGPIO_REGS(0, 3, 0, 5, 9),
+ AGPIO_REGS(1, 3, 1, 5, 10),
+ AGPIO_REGS(2, 3, 2, 5, 11),
+ AGPIO_REGS(3, 3, 3, 5, 12),
+ AGPIO_REGS(4, 3, 4, 5, 13),
+ AGPIO_REGS(5, 3, 5, 5, 14),
+ AGPIO_REGS(6, 3, 6, 6, 0),
+ AGPIO_REGS(8, 3, 7, 6, 1),
+ AGPIO_REGS(9, 4, 0, 6, 2),
+ AGPIO_REGS(12, 4, 1, 6, 3),
+ AGPIO_REGS(13, 4, 2, 6, 4),
+ AGPIO_REGS(14, 4, 3, 6, 5),
+ SGPIO_REGS(0, 0, 0),
+ SGPIO_REGS(1, 0, 1),
+ SGPIO_REGS(2, 0, 2),
+ SGPIO_REGS(3, 0, 3),
+ SGPIO_REGS(4, 1, 0),
+ SGPIO_REGS(5, 2, 0),
+};
+
+static const struct pinctrl_pin_desc bcm2712_d0_gpio_pins[] = {
+ GPIO_PIN(1),
+ GPIO_PIN(2),
+ GPIO_PIN(3),
+ GPIO_PIN(4),
+ GPIO_PIN(10),
+ GPIO_PIN(11),
+ GPIO_PIN(12),
+ GPIO_PIN(13),
+ GPIO_PIN(14),
+ GPIO_PIN(15),
+ GPIO_PIN(18),
+ GPIO_PIN(19),
+ GPIO_PIN(20),
+ GPIO_PIN(21),
+ GPIO_PIN(22),
+ GPIO_PIN(23),
+ GPIO_PIN(24),
+ GPIO_PIN(25),
+ GPIO_PIN(26),
+ GPIO_PIN(27),
+ GPIO_PIN(28),
+ GPIO_PIN(29),
+ GPIO_PIN(30),
+ GPIO_PIN(31),
+ GPIO_PIN(32),
+ GPIO_PIN(33),
+ GPIO_PIN(34),
+ GPIO_PIN(35),
+ PINCTRL_PIN(36, "emmc_cmd"),
+ PINCTRL_PIN(37, "emmc_ds"),
+ PINCTRL_PIN(38, "emmc_clk"),
+ PINCTRL_PIN(39, "emmc_dat0"),
+ PINCTRL_PIN(40, "emmc_dat1"),
+ PINCTRL_PIN(41, "emmc_dat2"),
+ PINCTRL_PIN(42, "emmc_dat3"),
+ PINCTRL_PIN(43, "emmc_dat4"),
+ PINCTRL_PIN(44, "emmc_dat5"),
+ PINCTRL_PIN(45, "emmc_dat6"),
+ PINCTRL_PIN(46, "emmc_dat7"),
+};
+
+static struct pinctrl_pin_desc bcm2712_d0_aon_gpio_pins[] = {
+ AGPIO_PIN(0), AGPIO_PIN(1), AGPIO_PIN(2), AGPIO_PIN(3), AGPIO_PIN(4),
+ AGPIO_PIN(5), AGPIO_PIN(6), AGPIO_PIN(8), AGPIO_PIN(9), AGPIO_PIN(12),
+ AGPIO_PIN(13), AGPIO_PIN(14), SGPIO_PIN(0), SGPIO_PIN(1), SGPIO_PIN(2),
+ SGPIO_PIN(3), SGPIO_PIN(4), SGPIO_PIN(5),
+};
+
+static const char * const brcmstb_func_names[] = {
+ FUNC(gpio),
+ FUNC(alt1),
+ FUNC(alt2),
+ FUNC(alt3),
+ FUNC(alt4),
+ FUNC(alt5),
+ FUNC(alt6),
+ FUNC(alt7),
+ FUNC(alt8),
+ FUNC(aon_cpu_standbyb),
+ FUNC(aon_fp_4sec_resetb),
+ FUNC(aon_gpclk),
+ FUNC(aon_pwm),
+ FUNC(arm_jtag),
+ FUNC(aud_fs_clk0),
+ FUNC(avs_pmu_bsc),
+ FUNC(bsc_m0),
+ FUNC(bsc_m1),
+ FUNC(bsc_m2),
+ FUNC(bsc_m3),
+ FUNC(clk_observe),
+ FUNC(ctl_hdmi_5v),
+ FUNC(enet0),
+ FUNC(enet0_mii),
+ FUNC(enet0_rgmii),
+ FUNC(ext_sc_clk),
+ FUNC(fl0),
+ FUNC(fl1),
+ FUNC(gpclk0),
+ FUNC(gpclk1),
+ FUNC(gpclk2),
+ FUNC(hdmi_tx0_auto_i2c),
+ FUNC(hdmi_tx0_bsc),
+ FUNC(hdmi_tx1_auto_i2c),
+ FUNC(hdmi_tx1_bsc),
+ FUNC(i2s_in),
+ FUNC(i2s_out),
+ FUNC(ir_in),
+ FUNC(mtsif),
+ FUNC(mtsif_alt),
+ FUNC(mtsif_alt1),
+ FUNC(pdm),
+ FUNC(pkt),
+ FUNC(pm_led_out),
+ FUNC(sc0),
+ FUNC(sd0),
+ FUNC(sd2),
+ FUNC(sd_card_a),
+ FUNC(sd_card_b),
+ FUNC(sd_card_c),
+ FUNC(sd_card_d),
+ FUNC(sd_card_e),
+ FUNC(sd_card_f),
+ FUNC(sd_card_g),
+ FUNC(spdif_out),
+ FUNC(spi_m),
+ FUNC(spi_s),
+ FUNC(sr_edm_sense),
+ FUNC(te0),
+ FUNC(te1),
+ FUNC(tsio),
+ FUNC(uart0),
+ FUNC(uart1),
+ FUNC(uart2),
+ FUNC(usb_pwr),
+ FUNC(usb_vbus),
+ FUNC(uui),
+ FUNC(vc_i2c0),
+ FUNC(vc_i2c3),
+ FUNC(vc_i2c4),
+ FUNC(vc_i2c5),
+ FUNC(vc_i2csl),
+ FUNC(vc_pcm),
+ FUNC(vc_pwm0),
+ FUNC(vc_pwm1),
+ FUNC(vc_spi0),
+ FUNC(vc_spi3),
+ FUNC(vc_spi4),
+ FUNC(vc_spi5),
+ FUNC(vc_uart0),
+ FUNC(vc_uart2),
+ FUNC(vc_uart3),
+ FUNC(vc_uart4),
+};
+
+static const struct brcmstb_pin_funcs bcm2712_c0_aon_gpio_pin_funcs[] = {
+ PIN(0, ir_in, vc_spi0, vc_uart3, vc_i2c3, te0, vc_i2c0, _, _),
+ PIN(1, vc_pwm0, vc_spi0, vc_uart3, vc_i2c3, te1, aon_pwm, vc_i2c0, vc_pwm1),
+ PIN(2, vc_pwm0, vc_spi0, vc_uart3, ctl_hdmi_5v, fl0, aon_pwm, ir_in, vc_pwm1),
+ PIN(3, ir_in, vc_spi0, vc_uart3, aon_fp_4sec_resetb, fl1, sd_card_g, aon_gpclk, _),
+ PIN(4, gpclk0, vc_spi0, vc_i2csl, aon_gpclk, pm_led_out, aon_pwm, sd_card_g, vc_pwm0),
+ PIN(5, gpclk1, ir_in, vc_i2csl, clk_observe, aon_pwm, sd_card_g, vc_pwm0, _),
+ PIN(6, uart1, vc_uart4, gpclk2, ctl_hdmi_5v, vc_uart0, vc_spi3, _, _),
+ PIN(7, uart1, vc_uart4, gpclk0, aon_pwm, vc_uart0, vc_spi3, _, _),
+ PIN(8, uart1, vc_uart4, vc_i2csl, ctl_hdmi_5v, vc_uart0, vc_spi3, _, _),
+ PIN(9, uart1, vc_uart4, vc_i2csl, aon_pwm, vc_uart0, vc_spi3, _, _),
+ PIN(10, tsio, ctl_hdmi_5v, sc0, spdif_out, vc_spi5, usb_pwr, aon_gpclk, sd_card_f),
+ PIN(11, tsio, uart0, sc0, aud_fs_clk0, vc_spi5, usb_vbus, vc_uart2, sd_card_f),
+ PIN(12, tsio, uart0, vc_uart0, tsio, vc_spi5, usb_pwr, vc_uart2, sd_card_f),
+ PIN(13, bsc_m1, uart0, vc_uart0, uui, vc_spi5, arm_jtag, vc_uart2, vc_i2c3),
+ PIN(14, bsc_m1, uart0, vc_uart0, uui, vc_spi5, arm_jtag, vc_uart2, vc_i2c3),
+ PIN(15, ir_in, aon_fp_4sec_resetb, vc_uart0, pm_led_out, ctl_hdmi_5v, aon_pwm, aon_gpclk,
+ _),
+ PIN(16, aon_cpu_standbyb, gpclk0, pm_led_out, ctl_hdmi_5v, vc_pwm0, usb_pwr, aud_fs_clk0,
+ _),
+};
+
+static const struct brcmstb_pin_funcs bcm2712_c0_gpio_pin_funcs[] = {
+ PIN(0, bsc_m3, vc_i2c0, gpclk0, enet0, vc_pwm1, vc_spi0, ir_in, _),
+ PIN(1, bsc_m3, vc_i2c0, gpclk1, enet0, vc_pwm1, sr_edm_sense, vc_spi0, vc_uart3),
+ PIN(2, pdm, i2s_in, gpclk2, vc_spi4, pkt, vc_spi0, vc_uart3, _),
+ PIN(3, pdm, i2s_in, vc_spi4, pkt, vc_spi0, vc_uart3, _, _),
+ PIN(4, pdm, i2s_in, arm_jtag, vc_spi4, pkt, vc_spi0, vc_uart3, _),
+ PIN(5, pdm, vc_i2c3, arm_jtag, sd_card_e, vc_spi4, pkt, vc_pcm, vc_i2c5),
+ PIN(6, pdm, vc_i2c3, arm_jtag, sd_card_e, vc_spi4, pkt, vc_pcm, vc_i2c5),
+ PIN(7, i2s_out, spdif_out, arm_jtag, sd_card_e, vc_i2c3, enet0_rgmii, vc_pcm, vc_spi4),
+ PIN(8, i2s_out, aud_fs_clk0, arm_jtag, sd_card_e, vc_i2c3, enet0_mii, vc_pcm, vc_spi4),
+ PIN(9, i2s_out, aud_fs_clk0, arm_jtag, sd_card_e, enet0_mii, sd_card_c, vc_spi4, _),
+ PIN(10, bsc_m3, mtsif_alt1, i2s_in, i2s_out, vc_spi5, enet0_mii, sd_card_c, vc_spi4),
+ PIN(11, bsc_m3, mtsif_alt1, i2s_in, i2s_out, vc_spi5, enet0_mii, sd_card_c, vc_spi4),
+ PIN(12, spi_s, mtsif_alt1, i2s_in, i2s_out, vc_spi5, vc_i2csl, sd0, sd_card_d),
+ PIN(13, spi_s, mtsif_alt1, i2s_out, usb_vbus, vc_spi5, vc_i2csl, sd0, sd_card_d),
+ PIN(14, spi_s, vc_i2csl, enet0_rgmii, arm_jtag, vc_spi5, vc_pwm0, vc_i2c4, sd_card_d),
+ PIN(15, spi_s, vc_i2csl, vc_spi3, arm_jtag, vc_pwm0, vc_i2c4, gpclk0, _),
+ PIN(16, sd_card_b, i2s_out, vc_spi3, i2s_in, sd0, enet0_rgmii, gpclk1, _),
+ PIN(17, sd_card_b, i2s_out, vc_spi3, i2s_in, ext_sc_clk, sd0, enet0_rgmii, gpclk2),
+ PIN(18, sd_card_b, i2s_out, vc_spi3, i2s_in, sd0, enet0_rgmii, vc_pwm1, _),
+ PIN(19, sd_card_b, usb_pwr, vc_spi3, pkt, spdif_out, sd0, ir_in, vc_pwm1),
+ PIN(20, sd_card_b, uui, vc_uart0, arm_jtag, uart2, usb_pwr, vc_pcm, vc_uart4),
+ PIN(21, usb_pwr, uui, vc_uart0, arm_jtag, uart2, sd_card_b, vc_pcm, vc_uart4),
+ PIN(22, usb_pwr, enet0, vc_uart0, mtsif, uart2, usb_vbus, vc_pcm, vc_i2c5),
+ PIN(23, usb_vbus, enet0, vc_uart0, mtsif, uart2, i2s_out, vc_pcm, vc_i2c5),
+ PIN(24, mtsif, pkt, uart0, enet0_rgmii, enet0_rgmii, vc_i2c4, vc_uart3, _),
+ PIN(25, mtsif, pkt, sc0, uart0, enet0_rgmii, enet0_rgmii, vc_i2c4, vc_uart3),
+ PIN(26, mtsif, pkt, sc0, uart0, enet0_rgmii, vc_uart4, vc_spi5, _),
+ PIN(27, mtsif, pkt, sc0, uart0, enet0_rgmii, vc_uart4, vc_spi5, _),
+ PIN(28, mtsif, pkt, sc0, enet0_rgmii, vc_uart4, vc_spi5, _, _),
+ PIN(29, mtsif, pkt, sc0, enet0_rgmii, vc_uart4, vc_spi5, _, _),
+ PIN(30, mtsif, pkt, sc0, sd2, enet0_rgmii, gpclk0, vc_pwm0, _),
+ PIN(31, mtsif, pkt, sc0, sd2, enet0_rgmii, vc_spi3, vc_pwm0, _),
+ PIN(32, mtsif, pkt, sc0, sd2, enet0_rgmii, vc_spi3, vc_uart3, _),
+ PIN(33, mtsif, pkt, sd2, enet0_rgmii, vc_spi3, vc_uart3, _, _),
+ PIN(34, mtsif, pkt, ext_sc_clk, sd2, enet0_rgmii, vc_spi3, vc_i2c5, _),
+ PIN(35, mtsif, pkt, sd2, enet0_rgmii, vc_spi3, vc_i2c5, _, _),
+ PIN(36, sd0, mtsif, sc0, i2s_in, vc_uart3, vc_uart2, _, _),
+ PIN(37, sd0, mtsif, sc0, vc_spi0, i2s_in, vc_uart3, vc_uart2, _),
+ PIN(38, sd0, mtsif_alt, sc0, vc_spi0, i2s_in, vc_uart3, vc_uart2, _),
+ PIN(39, sd0, mtsif_alt, sc0, vc_spi0, vc_uart3, vc_uart2, _, _),
+ PIN(40, sd0, mtsif_alt, sc0, vc_spi0, bsc_m3, _, _, _),
+ PIN(41, sd0, mtsif_alt, sc0, vc_spi0, bsc_m3, _, _, _),
+ PIN(42, vc_spi0, mtsif_alt, vc_i2c0, sd_card_a, mtsif_alt1, arm_jtag, pdm, spi_m),
+ PIN(43, vc_spi0, mtsif_alt, vc_i2c0, sd_card_a, mtsif_alt1, arm_jtag, pdm, spi_m),
+ PIN(44, vc_spi0, mtsif_alt, enet0, sd_card_a, mtsif_alt1, arm_jtag, pdm, spi_m),
+ PIN(45, vc_spi0, mtsif_alt, enet0, sd_card_a, mtsif_alt1, arm_jtag, pdm, spi_m),
+ PIN(46, vc_spi0, mtsif_alt, sd_card_a, mtsif_alt1, arm_jtag, pdm, spi_m, _),
+ PIN(47, enet0, mtsif_alt, i2s_out, mtsif_alt1, arm_jtag, _, _, _),
+ PIN(48, sc0, usb_pwr, spdif_out, mtsif, _, _, _, _),
+ PIN(49, sc0, usb_pwr, aud_fs_clk0, mtsif, _, _, _, _),
+ PIN(50, sc0, usb_vbus, sc0, _, _, _, _, _),
+ PIN(51, sc0, enet0, sc0, sr_edm_sense, _, _, _, _),
+ PIN(52, sc0, enet0, vc_pwm1, _, _, _, _, _),
+ PIN(53, sc0, enet0_rgmii, ext_sc_clk, _, _, _, _, _),
+};
+
+static const struct brcmstb_pin_funcs bcm2712_d0_aon_gpio_pin_funcs[] = {
+ PIN(0, ir_in, vc_spi0, vc_uart0, vc_i2c3, uart0, vc_i2c0, _, _),
+ PIN(1, vc_pwm0, vc_spi0, vc_uart0, vc_i2c3, uart0, aon_pwm, vc_i2c0, vc_pwm1),
+ PIN(2, vc_pwm0, vc_spi0, vc_uart0, ctl_hdmi_5v, uart0, aon_pwm, ir_in, vc_pwm1),
+ PIN(3, ir_in, vc_spi0, vc_uart0, uart0, sd_card_g, aon_gpclk, _, _),
+ PIN(4, gpclk0, vc_spi0, pm_led_out, aon_pwm, sd_card_g, vc_pwm0, _, _),
+ PIN(5, gpclk1, ir_in, aon_pwm, sd_card_g, vc_pwm0, _, _, _),
+ PIN(6, uart1, vc_uart2, ctl_hdmi_5v, gpclk2, vc_spi3, _, _, _),
+ PIN(7, _, _, _, _, _, _, _, _), /* non-existent on D0 silicon */
+ PIN(8, uart1, vc_uart2, ctl_hdmi_5v, vc_spi0, vc_spi3, _, _, _),
+ PIN(9, uart1, vc_uart2, vc_uart0, aon_pwm, vc_spi0, vc_uart2, vc_spi3, _),
+ PIN(10, _, _, _, _, _, _, _, _), /* non-existent on D0 silicon */
+ PIN(11, _, _, _, _, _, _, _, _), /* non-existent on D0 silicon */
+ PIN(12, uart1, vc_uart2, vc_uart0, vc_spi0, usb_pwr, vc_uart2, vc_spi3, _),
+ PIN(13, bsc_m1, vc_uart0, uui, vc_spi0, arm_jtag, vc_uart2, vc_i2c3, _),
+ PIN(14, bsc_m1, aon_gpclk, vc_uart0, uui, vc_spi0, arm_jtag, vc_uart2, vc_i2c3),
+};
+
+static const struct brcmstb_pin_funcs bcm2712_d0_gpio_pin_funcs[] = {
+ PIN(1, vc_i2c0, usb_pwr, gpclk0, sd_card_e, vc_spi3, sr_edm_sense, vc_spi0, vc_uart0),
+ PIN(2, vc_i2c0, usb_pwr, gpclk1, sd_card_e, vc_spi3, clk_observe, vc_spi0, vc_uart0),
+ PIN(3, vc_i2c3, usb_vbus, gpclk2, sd_card_e, vc_spi3, vc_spi0, vc_uart0, _),
+ PIN(4, vc_i2c3, vc_pwm1, vc_spi3, sd_card_e, vc_spi3, vc_spi0, vc_uart0, _),
+ PIN(10, bsc_m3, vc_pwm1, vc_spi3, sd_card_e, vc_spi3, gpclk0, _, _),
+ PIN(11, bsc_m3, vc_spi3, clk_observe, sd_card_c, gpclk1, _, _, _),
+ PIN(12, spi_s, vc_spi3, sd_card_c, sd_card_d, _, _, _, _),
+ PIN(13, spi_s, vc_spi3, sd_card_c, sd_card_d, _, _, _, _),
+ PIN(14, spi_s, uui, arm_jtag, vc_pwm0, vc_i2c0, sd_card_d, _, _),
+ PIN(15, spi_s, uui, arm_jtag, vc_pwm0, vc_i2c0, gpclk0, _, _),
+ PIN(18, sd_card_f, vc_pwm1, _, _, _, _, _, _),
+ PIN(19, sd_card_f, usb_pwr, vc_pwm1, _, _, _, _, _),
+ PIN(20, vc_i2c3, uui, vc_uart0, arm_jtag, vc_uart2, _, _, _),
+ PIN(21, vc_i2c3, uui, vc_uart0, arm_jtag, vc_uart2, _, _, _),
+ PIN(22, sd_card_f, vc_uart0, vc_i2c3, _, _, _, _, _),
+ PIN(23, vc_uart0, vc_i2c3, _, _, _, _, _, _),
+ PIN(24, sd_card_b, vc_spi0, arm_jtag, uart0, usb_pwr, vc_uart2, vc_uart0, _),
+ PIN(25, sd_card_b, vc_spi0, arm_jtag, uart0, usb_pwr, vc_uart2, vc_uart0, _),
+ PIN(26, sd_card_b, vc_spi0, arm_jtag, uart0, usb_vbus, vc_uart2, vc_spi0, _),
+ PIN(27, sd_card_b, vc_spi0, arm_jtag, uart0, vc_uart2, vc_spi0, _, _),
+ PIN(28, sd_card_b, vc_spi0, arm_jtag, vc_i2c0, vc_spi0, _, _, _),
+ PIN(29, arm_jtag, vc_i2c0, vc_spi0, _, _, _, _, _),
+ PIN(30, sd2, gpclk0, vc_pwm0, _, _, _, _, _),
+ PIN(31, sd2, vc_spi3, vc_pwm0, _, _, _, _, _),
+ PIN(32, sd2, vc_spi3, vc_uart3, _, _, _, _, _),
+ PIN(33, sd2, vc_spi3, vc_uart3, _, _, _, _, _),
+ PIN(34, sd2, vc_spi3, vc_i2c5, _, _, _, _, _),
+ PIN(35, sd2, vc_spi3, vc_i2c5, _, _, _, _, _),
+};
+
+static inline u32 brcmstb_reg_rd(struct brcmstb_pinctrl *pc, unsigned int reg)
+{
+ return readl(pc->base + reg);
+}
+
+static inline void brcmstb_reg_wr(struct brcmstb_pinctrl *pc, unsigned int reg,
+ u32 val)
+{
+ writel(val, pc->base + reg);
+}
+
+static enum brcmstb_funcs brcmstb_pinctrl_fsel_get(struct brcmstb_pinctrl *pc,
+ unsigned int pin)
+{
+ u32 bit = pc->pin_regs[pin].mux_bit;
+ enum brcmstb_funcs func;
+ int fsel;
+ u32 val;
+
+ if (!bit)
+ return func_gpio;
+
+ bit &= ~MUX_BIT_VALID;
+
+ val = brcmstb_reg_rd(pc, BIT_TO_REG(bit));
+ fsel = (val >> BIT_TO_SHIFT(bit)) & BRCMSTB_FSEL_MASK;
+ func = pc->pin_funcs[pin].funcs[fsel];
+
+ if (func >= func_count)
+ func = (enum brcmstb_funcs)fsel;
+
+ dev_dbg(pc->dev, "get %04x: %08x (%u => %s)\n",
+ BIT_TO_REG(bit), val, pin,
+ brcmstb_func_names[func]);
+
+ return func;
+}
+
+static int brcmstb_pinctrl_fsel_set(struct brcmstb_pinctrl *pc,
+ unsigned int pin, enum brcmstb_funcs func)
+{
+ u32 bit = pc->pin_regs[pin].mux_bit, val;
+ const u8 *pin_funcs;
+ unsigned long flags;
+ int fsel;
+ int cur;
+ int i;
+
+ if (!bit || func >= func_count)
+ return -EINVAL;
+
+ bit &= ~MUX_BIT_VALID;
+
+ fsel = BRCMSTB_FSEL_COUNT;
+
+ if (func >= BRCMSTB_FSEL_COUNT) {
+ /* Convert to an fsel number */
+ pin_funcs = pc->pin_funcs[pin].funcs;
+ for (i = 1; i < BRCMSTB_FSEL_COUNT; i++) {
+ if (pin_funcs[i - 1] == func) {
+ fsel = i;
+ break;
+ }
+ }
+ } else {
+ fsel = (enum brcmstb_funcs)func;
+ }
+
+ if (fsel >= BRCMSTB_FSEL_COUNT)
+ return -EINVAL;
+
+ spin_lock_irqsave(&pc->fsel_lock, flags);
+
+ val = brcmstb_reg_rd(pc, BIT_TO_REG(bit));
+ cur = (val >> BIT_TO_SHIFT(bit)) & BRCMSTB_FSEL_MASK;
+
+ dev_dbg(pc->dev, "read %04x: %08x (%u => %s)\n",
+ BIT_TO_REG(bit), val, pin,
+ brcmstb_func_names[cur]);
+
+ if (cur != fsel) {
+ val &= ~(BRCMSTB_FSEL_MASK << BIT_TO_SHIFT(bit));
+ val |= fsel << BIT_TO_SHIFT(bit);
+
+ dev_dbg(pc->dev, "write %04x: %08x (%u <= %s)\n",
+ BIT_TO_REG(bit), val, pin,
+ brcmstb_func_names[fsel]);
+ brcmstb_reg_wr(pc, BIT_TO_REG(bit), val);
+ }
+
+ spin_unlock_irqrestore(&pc->fsel_lock, flags);
+
+ return 0;
+}
+
+static int brcmstb_pctl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+ struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+
+ return pc->pctl_desc.npins;
+}
+
+static const char *brcmstb_pctl_get_group_name(struct pinctrl_dev *pctldev,
+ unsigned int selector)
+{
+ struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+
+ return pc->gpio_groups[selector];
+}
+
+static int brcmstb_pctl_get_group_pins(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ const unsigned int **pins,
+ unsigned int *num_pins)
+{
+ struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+
+ *pins = &pc->pctl_desc.pins[selector].number;
+ *num_pins = 1;
+
+ return 0;
+}
+
+static void brcmstb_pctl_pin_dbg_show(struct pinctrl_dev *pctldev,
+ struct seq_file *s, unsigned int offset)
+{
+ struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+ enum brcmstb_funcs fsel = brcmstb_pinctrl_fsel_get(pc, offset);
+ const char *fname = brcmstb_func_names[fsel];
+
+ seq_printf(s, "function %s", fname);
+}
+
+static void brcmstb_pctl_dt_free_map(struct pinctrl_dev *pctldev,
+ struct pinctrl_map *maps,
+ unsigned int num_maps)
+{
+ int i;
+
+ for (i = 0; i < num_maps; i++)
+ if (maps[i].type == PIN_MAP_TYPE_CONFIGS_PIN)
+ kfree(maps[i].data.configs.configs);
+
+ kfree(maps);
+}
+
+static const struct pinctrl_ops brcmstb_pctl_ops = {
+ .get_groups_count = brcmstb_pctl_get_groups_count,
+ .get_group_name = brcmstb_pctl_get_group_name,
+ .get_group_pins = brcmstb_pctl_get_group_pins,
+ .pin_dbg_show = brcmstb_pctl_pin_dbg_show,
+ .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+ .dt_free_map = brcmstb_pctl_dt_free_map,
+};
+
+static int brcmstb_pmx_free(struct pinctrl_dev *pctldev, unsigned int offset)
+{
+ struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+
+ /* disable by setting to GPIO */
+ return brcmstb_pinctrl_fsel_set(pc, offset, func_gpio);
+}
+
+static int brcmstb_pmx_get_functions_count(struct pinctrl_dev *pctldev)
+{
+ return func_count;
+}
+
+static const char *brcmstb_pmx_get_function_name(struct pinctrl_dev *pctldev,
+ unsigned int selector)
+{
+ return (selector < func_count) ? brcmstb_func_names[selector] : NULL;
+}
+
+static int brcmstb_pmx_get_function_groups(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ const char *const **groups,
+ unsigned *const num_groups)
+{
+ struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+
+ *groups = pc->gpio_groups;
+ *num_groups = pc->pctl_desc.npins;
+
+ return 0;
+}
+
+static int brcmstb_pmx_set(struct pinctrl_dev *pctldev,
+ unsigned int func_selector,
+ unsigned int group_selector)
+{
+ struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+ const struct pinctrl_desc *pctldesc = &pc->pctl_desc;
+ const struct pinctrl_pin_desc *pindesc;
+
+ if (group_selector >= pctldesc->npins)
+ return -EINVAL;
+
+ pindesc = &pctldesc->pins[group_selector];
+ return brcmstb_pinctrl_fsel_set(pc, pindesc->number, func_selector);
+}
+
+static int brcmstb_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned int pin)
+{
+ struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+
+ return brcmstb_pinctrl_fsel_set(pc, pin, func_gpio);
+}
+
+static void brcmstb_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned int offset)
+{
+ struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+
+ /* disable by setting to GPIO */
+ (void)brcmstb_pinctrl_fsel_set(pc, offset, func_gpio);
+}
+
+static const struct pinmux_ops brcmstb_pmx_ops = {
+ .free = brcmstb_pmx_free,
+ .get_functions_count = brcmstb_pmx_get_functions_count,
+ .get_function_name = brcmstb_pmx_get_function_name,
+ .get_function_groups = brcmstb_pmx_get_function_groups,
+ .set_mux = brcmstb_pmx_set,
+ .gpio_request_enable = brcmstb_pmx_gpio_request_enable,
+ .gpio_disable_free = brcmstb_pmx_gpio_disable_free,
+};
+
+static unsigned int brcmstb_pull_config_get(struct brcmstb_pinctrl *pc,
+ unsigned int pin)
+{
+ u32 bit = pc->pin_regs[pin].pad_bit, val;
+
+ if (bit == PAD_BIT_INVALID)
+ return BRCMSTB_PULL_NONE;
+
+ val = brcmstb_reg_rd(pc, BIT_TO_REG(bit));
+ return (val >> BIT_TO_SHIFT(bit)) & BRCMSTB_PULL_MASK;
+}
+
+static int brcmstb_pull_config_set(struct brcmstb_pinctrl *pc,
+ unsigned int pin, unsigned int arg)
+{
+ u32 bit = pc->pin_regs[pin].pad_bit, val;
+ unsigned long flags;
+
+ if (bit == PAD_BIT_INVALID) {
+ dev_warn(pc->dev, "Can't set pulls for %s\n",
+ pc->gpio_groups[pin]);
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&pc->fsel_lock, flags);
+
+ val = brcmstb_reg_rd(pc, BIT_TO_REG(bit));
+ val &= ~(BRCMSTB_PULL_MASK << BIT_TO_SHIFT(bit));
+ val |= (arg << BIT_TO_SHIFT(bit));
+ brcmstb_reg_wr(pc, BIT_TO_REG(bit), val);
+
+ spin_unlock_irqrestore(&pc->fsel_lock, flags);
+
+ return 0;
+}
+
+static int brcmstb_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
+ unsigned long *config)
+{
+ struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+ enum pin_config_param param = pinconf_to_config_param(*config);
+ u32 arg;
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ arg = (brcmstb_pull_config_get(pc, pin) == BRCMSTB_PULL_NONE);
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ arg = (brcmstb_pull_config_get(pc, pin) == BRCMSTB_PULL_DOWN);
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ arg = (brcmstb_pull_config_get(pc, pin) == BRCMSTB_PULL_UP);
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ *config = pinconf_to_config_packed(param, arg);
+
+ return 0;
+}
+
+static int brcmstb_pinconf_set(struct pinctrl_dev *pctldev,
+ unsigned int pin, unsigned long *configs,
+ unsigned int num_configs)
+{
+ struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+ int ret = 0;
+ u32 param;
+ int i;
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ ret = brcmstb_pull_config_set(pc, pin, BRCMSTB_PULL_NONE);
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ ret = brcmstb_pull_config_set(pc, pin, BRCMSTB_PULL_DOWN);
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ ret = brcmstb_pull_config_set(pc, pin, BRCMSTB_PULL_UP);
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+ }
+
+ return ret;
+}
+
+static const struct pinconf_ops brcmstb_pinconf_ops = {
+ .is_generic = true,
+ .pin_config_get = brcmstb_pinconf_get,
+ .pin_config_set = brcmstb_pinconf_set,
+};
+
+static const struct pinctrl_desc bcm2712_c0_pinctrl_desc = {
+ .name = "pinctrl-bcm2712",
+ .pins = bcm2712_c0_gpio_pins,
+ .npins = ARRAY_SIZE(bcm2712_c0_gpio_pins),
+ .pctlops = &brcmstb_pctl_ops,
+ .pmxops = &brcmstb_pmx_ops,
+ .confops = &brcmstb_pinconf_ops,
+ .owner = THIS_MODULE,
+};
+
+static const struct pinctrl_desc bcm2712_c0_aon_pinctrl_desc = {
+ .name = "aon-pinctrl-bcm2712",
+ .pins = bcm2712_c0_aon_gpio_pins,
+ .npins = ARRAY_SIZE(bcm2712_c0_aon_gpio_pins),
+ .pctlops = &brcmstb_pctl_ops,
+ .pmxops = &brcmstb_pmx_ops,
+ .confops = &brcmstb_pinconf_ops,
+ .owner = THIS_MODULE,
+};
+
+static const struct pinctrl_desc bcm2712_d0_pinctrl_desc = {
+ .name = "pinctrl-bcm2712",
+ .pins = bcm2712_d0_gpio_pins,
+ .npins = ARRAY_SIZE(bcm2712_d0_gpio_pins),
+ .pctlops = &brcmstb_pctl_ops,
+ .pmxops = &brcmstb_pmx_ops,
+ .confops = &brcmstb_pinconf_ops,
+ .owner = THIS_MODULE,
+};
+
+static const struct pinctrl_desc bcm2712_d0_aon_pinctrl_desc = {
+ .name = "aon-pinctrl-bcm2712",
+ .pins = bcm2712_d0_aon_gpio_pins,
+ .npins = ARRAY_SIZE(bcm2712_d0_aon_gpio_pins),
+ .pctlops = &brcmstb_pctl_ops,
+ .pmxops = &brcmstb_pmx_ops,
+ .confops = &brcmstb_pinconf_ops,
+ .owner = THIS_MODULE,
+};
+
+static const struct pinctrl_gpio_range bcm2712_c0_pinctrl_gpio_range = {
+ .name = "pinctrl-bcm2712",
+ .npins = ARRAY_SIZE(bcm2712_c0_gpio_pins),
+};
+
+static const struct pinctrl_gpio_range bcm2712_c0_aon_pinctrl_gpio_range = {
+ .name = "aon-pinctrl-bcm2712",
+ .npins = ARRAY_SIZE(bcm2712_c0_aon_gpio_pins),
+};
+
+static const struct pinctrl_gpio_range bcm2712_d0_pinctrl_gpio_range = {
+ .name = "pinctrl-bcm2712",
+ .npins = ARRAY_SIZE(bcm2712_d0_gpio_pins),
+};
+
+static const struct pinctrl_gpio_range bcm2712_d0_aon_pinctrl_gpio_range = {
+ .name = "aon-pinctrl-bcm2712",
+ .npins = ARRAY_SIZE(bcm2712_d0_aon_gpio_pins),
+};
+
+static const struct brcmstb_pdata bcm2712_c0_pdata = {
+ .pctl_desc = &bcm2712_c0_pinctrl_desc,
+ .gpio_range = &bcm2712_c0_pinctrl_gpio_range,
+ .pin_regs = bcm2712_c0_gpio_pin_regs,
+ .pin_funcs = bcm2712_c0_gpio_pin_funcs,
+};
+
+static const struct brcmstb_pdata bcm2712_c0_aon_pdata = {
+ .pctl_desc = &bcm2712_c0_aon_pinctrl_desc,
+ .gpio_range = &bcm2712_c0_aon_pinctrl_gpio_range,
+ .pin_regs = bcm2712_c0_aon_gpio_pin_regs,
+ .pin_funcs = bcm2712_c0_aon_gpio_pin_funcs,
+};
+
+static const struct brcmstb_pdata bcm2712_d0_pdata = {
+ .pctl_desc = &bcm2712_d0_pinctrl_desc,
+ .gpio_range = &bcm2712_d0_pinctrl_gpio_range,
+ .pin_regs = bcm2712_d0_gpio_pin_regs,
+ .pin_funcs = bcm2712_d0_gpio_pin_funcs,
+};
+
+static const struct brcmstb_pdata bcm2712_d0_aon_pdata = {
+ .pctl_desc = &bcm2712_d0_aon_pinctrl_desc,
+ .gpio_range = &bcm2712_d0_aon_pinctrl_gpio_range,
+ .pin_regs = bcm2712_d0_aon_gpio_pin_regs,
+ .pin_funcs = bcm2712_d0_aon_gpio_pin_funcs,
+};
+
+static const struct of_device_id brcmstb_pinctrl_match[] = {
+ {
+ .compatible = "brcm,bcm2712c0-pinctrl",
+ .data = &bcm2712_c0_pdata
+ },
+ {
+ .compatible = "brcm,bcm2712c0-aon-pinctrl",
+ .data = &bcm2712_c0_aon_pdata
+ },
+
+ {
+ .compatible = "brcm,bcm2712d0-pinctrl",
+ .data = &bcm2712_d0_pdata
+ },
+ {
+ .compatible = "brcm,bcm2712d0-aon-pinctrl",
+ .data = &bcm2712_d0_aon_pdata
+ },
+ { /* sentinel */ }
+};
+
+static int brcmstb_pinctrl_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ const struct brcmstb_pdata *pdata;
+ const struct of_device_id *match;
+ struct brcmstb_pinctrl *pc;
+ const char **names;
+ int num_pins, i;
+
+ match = of_match_node(brcmstb_pinctrl_match, np);
+ pdata = match->data;
+
+ pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
+ if (!pc)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, pc);
+ pc->dev = dev;
+ spin_lock_init(&pc->fsel_lock);
+
+ pc->base = devm_of_iomap(dev, np, 0, NULL);
+ if (IS_ERR(pc->base))
+ return dev_err_probe(&pdev->dev, PTR_ERR(pc->base),
+ "Could not get IO memory\n");
+
+ pc->pctl_desc = *pdata->pctl_desc;
+ num_pins = pc->pctl_desc.npins;
+ names = devm_kmalloc_array(dev, num_pins, sizeof(const char *),
+ GFP_KERNEL);
+ if (!names)
+ return -ENOMEM;
+
+ for (i = 0; i < num_pins; i++)
+ names[i] = pc->pctl_desc.pins[i].name;
+
+ pc->gpio_groups = names;
+ pc->pin_regs = pdata->pin_regs;
+ pc->pin_funcs = pdata->pin_funcs;
+ pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
+ if (IS_ERR(pc->pctl_dev))
+ return dev_err_probe(&pdev->dev, PTR_ERR(pc->pctl_dev),
+ "Failed to register pinctrl device\n");
+
+ pc->gpio_range = *pdata->gpio_range;
+ pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
+
+ return 0;
+}
+
+static struct platform_driver brcmstb_pinctrl_driver = {
+ .probe = brcmstb_pinctrl_probe,
+ .driver = {
+ .name = "pinctrl-brcmstb",
+ .of_match_table = brcmstb_pinctrl_match,
+ .suppress_bind_attrs = true,
+ },
+};
+module_platform_driver(brcmstb_pinctrl_driver);
+
+MODULE_AUTHOR("Phil Elwell");
+MODULE_AUTHOR("Jonathan Bell");
+MODULE_AUTHOR("Ivan T. Ivanov");
+MODULE_AUTHOR("Andrea della Porta");
+MODULE_DESCRIPTION("Broadcom brcmstb pinctrl driver");
+MODULE_LICENSE("GPL");
--
2.35.3
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 3/3] arm64: defconfig: Enable BCM2712 on-chip pin controller driver
2025-08-11 14:46 [PATCH v3 0/3] Add pin control driver for BCM2712 SoC Andrea della Porta
2025-08-11 14:46 ` [PATCH v3 1/3] dt-bindings: pinctrl: Add support for Broadcom STB pin controller Andrea della Porta
2025-08-11 14:46 ` [PATCH v3 2/3] pinctrl: bcm: Add STB family pin controller driver Andrea della Porta
@ 2025-08-11 14:46 ` Andrea della Porta
2025-08-19 7:25 ` Stanimir Varbanov
2 siblings, 1 reply; 20+ messages in thread
From: Andrea della Porta @ 2025-08-11 14:46 UTC (permalink / raw)
To: linus.walleij, robh, krzk+dt, conor+dt, florian.fainelli,
wahrenst, linux-gpio, devicetree, linux-arm-kernel,
Catalin Marinas, Will Deacon, iivanov, svarbanov, mbrugger,
Jonathan Bell, Phil Elwell
Cc: Andrea della Porta
Select the on-chip pin controller driver for BCM2712 SoC.
On RapsberryPi 5 devices it is primarily needed to operate the
bluetooth and WiFi devices, to configure the uSD interface
and the power button.
Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
---
arch/arm64/configs/defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 58f87d09366c..fafcd7851eb2 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -592,6 +592,7 @@ CONFIG_SPI_TEGRA114=m
CONFIG_SPI_SPIDEV=m
CONFIG_SPMI=y
CONFIG_SPMI_MTK_PMIF=m
+CONFIG_PINCTRL_BRCMSTB=y
CONFIG_PINCTRL_DA9062=m
CONFIG_PINCTRL_MAX77620=y
CONFIG_PINCTRL_RK805=m
--
2.35.3
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v3 1/3] dt-bindings: pinctrl: Add support for Broadcom STB pin controller
2025-08-11 14:46 ` [PATCH v3 1/3] dt-bindings: pinctrl: Add support for Broadcom STB pin controller Andrea della Porta
@ 2025-08-18 17:20 ` Rob Herring
2025-08-27 9:58 ` Andrea della Porta
0 siblings, 1 reply; 20+ messages in thread
From: Rob Herring @ 2025-08-18 17:20 UTC (permalink / raw)
To: Andrea della Porta
Cc: linus.walleij, krzk+dt, conor+dt, florian.fainelli, wahrenst,
linux-gpio, devicetree, linux-arm-kernel, Catalin Marinas,
Will Deacon, iivanov, svarbanov, mbrugger, Jonathan Bell,
Phil Elwell
On Mon, Aug 11, 2025 at 04:46:51PM +0200, Andrea della Porta wrote:
> From: "Ivan T. Ivanov" <iivanov@suse.de>
>
> The STB pin controller represents a family whose silicon instances
> are found e.g. on BCM2712 SoC.
>
> In particular, on RaspberryPi 5, there are two separate instantiations
> of the same IP block which differ in the number of pins that are
> associated and the pinmux functions for each of those pins. The
> -aon- variant stands for 'Always On'.
>
> Depending on the revision of the BCM2712 (CO or D0), the pin
> controller instance has slight differences in the register layout.
>
> Signed-off-by: Ivan T. Ivanov <iivanov@suse.de>
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> ---
> .../pinctrl/brcm,bcm2712c0-pinctrl.yaml | 135 ++++++++++++++++++
> 1 file changed, 135 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm2712c0-pinctrl.yaml
>
> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm2712c0-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm2712c0-pinctrl.yaml
> new file mode 100644
> index 000000000000..28d66336aa2e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm2712c0-pinctrl.yaml
> @@ -0,0 +1,135 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm2712c0-pinctrl.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Broadcom STB family pin controller
> +
> +maintainers:
> + - Ivan T. Ivanov <iivanov@suse.de>
> + - A. della Porta <andrea.porta@suse.com>
Why is your first name abbrievated here?
> +
> +description:
> + Broadcom's STB family of memory-mapped pin controllers.
> + This includes the pin controllers inside the BCM2712 SoC which
> + are instances of the STB family and has two silicon variants,
> + C0 and D0, which differs slightly in terms of registers layout.
> + The -aon- (Always On) variant is the same IP block but differs
> + in the number of pins that are associated and the pinmux functions
> + for each of those pins.
Wrap lines at 80. If there are paragraphs, then blank line in between
and use the '>' modifier.
> +
> +allOf:
> + - $ref: pinctrl.yaml#
> +
> +properties:
> + compatible:
> + enum:
> + - brcm,bcm2712c0-pinctrl
> + - brcm,bcm2712c0-aon-pinctrl
> + - brcm,bcm2712d0-pinctrl
> + - brcm,bcm2712d0-aon-pinctrl
> +
> + reg:
> + maxItems: 1
> +
> +patternProperties:
> + '-state$':
> + oneOf:
> + - $ref: '#/$defs/brcmstb-pinctrl-state'
> + - patternProperties:
> + '-pins$':
> + $ref: '#/$defs/brcmstb-pinctrl-state'
> + additionalProperties: false
> +
> +$defs:
> + brcmstb-pinctrl-state:
> + allOf:
> + - $ref: pincfg-node.yaml#
> + - $ref: pinmux-node.yaml#
> +
> + description:
> + Pin controller client devices use pin configuration subnodes (children
> + and grandchildren) for desired pin configuration.
> + Client device subnodes use below standard properties.
Paragraphs here?
> +
> + properties:
> + pins:
> + description:
> + List of gpio pins affected by the properties specified in this
> + subnode (either this or "groups" must be specified).
> + items:
> + pattern: '^((aon_)?s?gpio[0-6]?[0-9])|(emmc_(clk|cmd|dat[0-7]|ds))$'
> +
> + function:
> + enum: [ gpio, alt1, alt2, alt3, alt4, alt5, alt6, alt7, alt8,
> + aon_cpu_standbyb, aon_fp_4sec_resetb, aon_gpclk, aon_pwm,
> + arm_jtag, aud_fs_clk0, avs_pmu_bsc, bsc_m0, bsc_m1, bsc_m2,
> + bsc_m3, clk_observe, ctl_hdmi_5v, enet0, enet0_mii, enet0_rgmii,
> + ext_sc_clk, fl0, fl1, gpclk0, gpclk1, gpclk2, hdmi_tx0_auto_i2c,
> + hdmi_tx0_bsc, hdmi_tx1_auto_i2c, hdmi_tx1_bsc, i2s_in, i2s_out,
> + ir_in, mtsif, mtsif_alt, mtsif_alt1, pdm, pkt, pm_led_out, sc0,
> + sd0, sd2, sd_card_a, sd_card_b, sd_card_c, sd_card_d, sd_card_e,
> + sd_card_f, sd_card_g, spdif_out, spi_m, spi_s, sr_edm_sense, te0,
> + te1, tsio, uart0, uart1, uart2, usb_pwr, usb_vbus, uui, vc_i2c0,
> + vc_i2c3, vc_i2c4, vc_i2c5, vc_i2csl, vc_pcm, vc_pwm0, vc_pwm1,
> + vc_spi0, vc_spi3, vc_spi4, vc_spi5, vc_uart0, vc_uart2, vc_uart3,
> + vc_uart4 ]
> +
> + description:
> + Specify the alternative function to be configured for the specified
> + pins.
Be consistent with putting 'description' first or last.
> +
> + bias-disable: true
> + bias-pull-down: true
> + bias-pull-up: true
> +
> + required:
> + - pins
> +
> + if:
> + properties:
> + pins:
> + not:
> + contains:
> + pattern: "^emmc_(clk|cmd|dat[0-7]|ds)$"
> + then:
> + required:
> + - function
> + else:
> + properties:
> + function: false
> +
> + additionalProperties: false
> +
> +required:
> + - compatible
> + - reg
> +
> +unevaluatedProperties: false
> +
> +examples:
> + - |
> + brcm_pinctrl: pinctrl@7d504100 {
> + compatible = "brcm,bcm2712c0-pinctrl";
> + reg = <0x7d504100 0x30>;
> +
> + bt-shutdown-default-state {
> + function = "gpio";
> + pins = "gpio29";
> + };
> +
> + uarta-default-state {
> + rts-tx-pins {
> + function = "uart0";
> + pins = "gpio24", "gpio26";
> + bias-disable;
> + };
> +
> + cts-rx-pins {
> + function = "uart0";
> + pins = "gpio25", "gpio27";
> + bias-pull-up;
> + };
> + };
> + };
> --
> 2.35.3
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 3/3] arm64: defconfig: Enable BCM2712 on-chip pin controller driver
2025-08-11 14:46 ` [PATCH v3 3/3] arm64: defconfig: Enable BCM2712 on-chip " Andrea della Porta
@ 2025-08-19 7:25 ` Stanimir Varbanov
2025-08-21 9:35 ` Andrea della Porta
0 siblings, 1 reply; 20+ messages in thread
From: Stanimir Varbanov @ 2025-08-19 7:25 UTC (permalink / raw)
To: Andrea della Porta, linus.walleij, robh, krzk+dt, conor+dt,
florian.fainelli, wahrenst, linux-gpio, devicetree,
linux-arm-kernel, Catalin Marinas, Will Deacon, iivanov,
svarbanov, mbrugger, Jonathan Bell, Phil Elwell
Hi Andrea,
On 8/11/25 5:46 PM, Andrea della Porta wrote:
> Select the on-chip pin controller driver for BCM2712 SoC.
>
> On RapsberryPi 5 devices it is primarily needed to operate the
> bluetooth and WiFi devices, to configure the uSD interface
> and the power button.
>
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> ---
> arch/arm64/configs/defconfig | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index 58f87d09366c..fafcd7851eb2 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -592,6 +592,7 @@ CONFIG_SPI_TEGRA114=m
> CONFIG_SPI_SPIDEV=m
> CONFIG_SPMI=y
> CONFIG_SPMI_MTK_PMIF=m
> +CONFIG_PINCTRL_BRCMSTB=y
Have you tried as module and part of initramfs?
~Stan
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 2/3] pinctrl: bcm: Add STB family pin controller driver
2025-08-11 14:46 ` [PATCH v3 2/3] pinctrl: bcm: Add STB family pin controller driver Andrea della Porta
@ 2025-08-19 7:40 ` Stanimir Varbanov
2025-08-19 8:14 ` Andrea della Porta
2025-08-19 9:18 ` Stefan Wahren
` (2 subsequent siblings)
3 siblings, 1 reply; 20+ messages in thread
From: Stanimir Varbanov @ 2025-08-19 7:40 UTC (permalink / raw)
To: Andrea della Porta, linus.walleij, robh, krzk+dt, conor+dt,
florian.fainelli, wahrenst, linux-gpio, devicetree,
linux-arm-kernel, Catalin Marinas, Will Deacon, iivanov,
svarbanov, mbrugger, Jonathan Bell, Phil Elwell
Hi Andrea,
On 8/11/25 5:46 PM, Andrea della Porta wrote:
> From: "Ivan T. Ivanov" <iivanov@suse.de>
>
> This driver provide pin muxing and configuration functionality
> for BCM2712 SoC used by RPi5. According to [1] this chip is an
> instance of the one used in Broadcom STB product line.
>
> [1] https://lore.kernel.org/lkml/f6601f73-cb22-4ba3-88c5-241be8421fc3@broadcom.com/
>
> Cc: Jonathan Bell <jonathan@raspberrypi.com>
> Cc: Phil Elwell <phil@raspberrypi.com>
> Signed-off-by: Ivan T. Ivanov <iivanov@suse.de>
> Reviewed-by: Phil Elwell <phil@raspberrypi.com>
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> ---
> drivers/pinctrl/bcm/Kconfig | 13 +
> drivers/pinctrl/bcm/Makefile | 1 +
> drivers/pinctrl/bcm/pinctrl-brcmstb.c | 1197 +++++++++++++++++++++++++
> 3 files changed, 1211 insertions(+)
> create mode 100644 drivers/pinctrl/bcm/pinctrl-brcmstb.c
>
<snip>
> +static int brcmstb_pinctrl_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct device_node *np = dev->of_node;
> + const struct brcmstb_pdata *pdata;
> + const struct of_device_id *match;
> + struct brcmstb_pinctrl *pc;
> + const char **names;
> + int num_pins, i;
> +
> + match = of_match_node(brcmstb_pinctrl_match, np);
The 'match' variable is needless, you can drop it.
> + pdata = match->data;
> +
<snip>
~Stan
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 2/3] pinctrl: bcm: Add STB family pin controller driver
2025-08-19 7:40 ` Stanimir Varbanov
@ 2025-08-19 8:14 ` Andrea della Porta
2025-08-19 8:19 ` Stanimir Varbanov
0 siblings, 1 reply; 20+ messages in thread
From: Andrea della Porta @ 2025-08-19 8:14 UTC (permalink / raw)
To: Stanimir Varbanov
Cc: Andrea della Porta, linus.walleij, robh, krzk+dt, conor+dt,
florian.fainelli, wahrenst, linux-gpio, devicetree,
linux-arm-kernel, Catalin Marinas, Will Deacon, iivanov, mbrugger,
Jonathan Bell, Phil Elwell
Hi Stanimir,
On 10:40 Tue 19 Aug , Stanimir Varbanov wrote:
> Hi Andrea,
>
> On 8/11/25 5:46 PM, Andrea della Porta wrote:
> > From: "Ivan T. Ivanov" <iivanov@suse.de>
> >
> > This driver provide pin muxing and configuration functionality
> > for BCM2712 SoC used by RPi5. According to [1] this chip is an
> > instance of the one used in Broadcom STB product line.
> >
> > [1] https://lore.kernel.org/lkml/f6601f73-cb22-4ba3-88c5-241be8421fc3@broadcom.com/
> >
> > Cc: Jonathan Bell <jonathan@raspberrypi.com>
> > Cc: Phil Elwell <phil@raspberrypi.com>
> > Signed-off-by: Ivan T. Ivanov <iivanov@suse.de>
> > Reviewed-by: Phil Elwell <phil@raspberrypi.com>
> > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> > ---
> > drivers/pinctrl/bcm/Kconfig | 13 +
> > drivers/pinctrl/bcm/Makefile | 1 +
> > drivers/pinctrl/bcm/pinctrl-brcmstb.c | 1197 +++++++++++++++++++++++++
> > 3 files changed, 1211 insertions(+)
> > create mode 100644 drivers/pinctrl/bcm/pinctrl-brcmstb.c
> >
>
> <snip>
>
> > +static int brcmstb_pinctrl_probe(struct platform_device *pdev)
> > +{
> > + struct device *dev = &pdev->dev;
> > + struct device_node *np = dev->of_node;
> > + const struct brcmstb_pdata *pdata;
> > + const struct of_device_id *match;
> > + struct brcmstb_pinctrl *pc;
> > + const char **names;
> > + int num_pins, i;
> > +
> > + match = of_match_node(brcmstb_pinctrl_match, np);
>
> The 'match' variable is needless, you can drop it.
you mean something like this?
pdata = of_match_node(brcmstb_pinctrl_match, np)->data;
I thought that kind of compact code was not really the way to go,
at least taking a look at other driver exmaples: there's only one
avoiding the intermediate variable and many others using it (although
in some cases they also check for null, so in that case is fully
justified). Anyway, I've no preference on that so I can proceed with
your suggestion, unless anyone has something against it.
Many thanks,
Andrea
>
> > + pdata = match->data;
> > +
>
> <snip>
>
> ~Stan
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 2/3] pinctrl: bcm: Add STB family pin controller driver
2025-08-19 8:14 ` Andrea della Porta
@ 2025-08-19 8:19 ` Stanimir Varbanov
2025-08-19 8:40 ` Andrea della Porta
0 siblings, 1 reply; 20+ messages in thread
From: Stanimir Varbanov @ 2025-08-19 8:19 UTC (permalink / raw)
To: Andrea della Porta, Stanimir Varbanov
Cc: linus.walleij, robh, krzk+dt, conor+dt, florian.fainelli,
wahrenst, linux-gpio, devicetree, linux-arm-kernel,
Catalin Marinas, Will Deacon, iivanov, mbrugger, Jonathan Bell,
Phil Elwell
On 8/19/25 11:14 AM, Andrea della Porta wrote:
> Hi Stanimir,
>
> On 10:40 Tue 19 Aug , Stanimir Varbanov wrote:
>> Hi Andrea,
>>
>> On 8/11/25 5:46 PM, Andrea della Porta wrote:
>>> From: "Ivan T. Ivanov" <iivanov@suse.de>
>>>
>>> This driver provide pin muxing and configuration functionality
>>> for BCM2712 SoC used by RPi5. According to [1] this chip is an
>>> instance of the one used in Broadcom STB product line.
>>>
>>> [1] https://lore.kernel.org/lkml/f6601f73-cb22-4ba3-88c5-241be8421fc3@broadcom.com/
>>>
>>> Cc: Jonathan Bell <jonathan@raspberrypi.com>
>>> Cc: Phil Elwell <phil@raspberrypi.com>
>>> Signed-off-by: Ivan T. Ivanov <iivanov@suse.de>
>>> Reviewed-by: Phil Elwell <phil@raspberrypi.com>
>>> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
>>> ---
>>> drivers/pinctrl/bcm/Kconfig | 13 +
>>> drivers/pinctrl/bcm/Makefile | 1 +
>>> drivers/pinctrl/bcm/pinctrl-brcmstb.c | 1197 +++++++++++++++++++++++++
>>> 3 files changed, 1211 insertions(+)
>>> create mode 100644 drivers/pinctrl/bcm/pinctrl-brcmstb.c
>>>
>>
>> <snip>
>>
>>> +static int brcmstb_pinctrl_probe(struct platform_device *pdev)
>>> +{
>>> + struct device *dev = &pdev->dev;
>>> + struct device_node *np = dev->of_node;
>>> + const struct brcmstb_pdata *pdata;
>>> + const struct of_device_id *match;
>>> + struct brcmstb_pinctrl *pc;
>>> + const char **names;
>>> + int num_pins, i;
>>> +
>>> + match = of_match_node(brcmstb_pinctrl_match, np);
>>
>> The 'match' variable is needless, you can drop it.
>
> you mean something like this?
>
> pdata = of_match_node(brcmstb_pinctrl_match, np)->data;
>
No, I meant:
pdata = of_device_get_match_data(dev)
Also as a bonus you could move brcmstb_pinctrl_match[] array after .probe.
~Stan
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 2/3] pinctrl: bcm: Add STB family pin controller driver
2025-08-19 8:19 ` Stanimir Varbanov
@ 2025-08-19 8:40 ` Andrea della Porta
0 siblings, 0 replies; 20+ messages in thread
From: Andrea della Porta @ 2025-08-19 8:40 UTC (permalink / raw)
To: Stanimir Varbanov
Cc: Andrea della Porta, linus.walleij, robh, krzk+dt, conor+dt,
florian.fainelli, wahrenst, linux-gpio, devicetree,
linux-arm-kernel, Catalin Marinas, Will Deacon, iivanov, mbrugger,
Jonathan Bell, Phil Elwell
Hi Stanmir,
On 11:19 Tue 19 Aug , Stanimir Varbanov wrote:
>
>
> On 8/19/25 11:14 AM, Andrea della Porta wrote:
> > Hi Stanimir,
> >
> > On 10:40 Tue 19 Aug , Stanimir Varbanov wrote:
> >> Hi Andrea,
> >>
> >> On 8/11/25 5:46 PM, Andrea della Porta wrote:
> >>> From: "Ivan T. Ivanov" <iivanov@suse.de>
> >>>
> >>> This driver provide pin muxing and configuration functionality
> >>> for BCM2712 SoC used by RPi5. According to [1] this chip is an
> >>> instance of the one used in Broadcom STB product line.
> >>>
> >>> [1] https://lore.kernel.org/lkml/f6601f73-cb22-4ba3-88c5-241be8421fc3@broadcom.com/
> >>>
> >>> Cc: Jonathan Bell <jonathan@raspberrypi.com>
> >>> Cc: Phil Elwell <phil@raspberrypi.com>
> >>> Signed-off-by: Ivan T. Ivanov <iivanov@suse.de>
> >>> Reviewed-by: Phil Elwell <phil@raspberrypi.com>
> >>> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> >>> ---
> >>> drivers/pinctrl/bcm/Kconfig | 13 +
> >>> drivers/pinctrl/bcm/Makefile | 1 +
> >>> drivers/pinctrl/bcm/pinctrl-brcmstb.c | 1197 +++++++++++++++++++++++++
> >>> 3 files changed, 1211 insertions(+)
> >>> create mode 100644 drivers/pinctrl/bcm/pinctrl-brcmstb.c
> >>>
> >>
> >> <snip>
> >>
> >>> +static int brcmstb_pinctrl_probe(struct platform_device *pdev)
> >>> +{
> >>> + struct device *dev = &pdev->dev;
> >>> + struct device_node *np = dev->of_node;
> >>> + const struct brcmstb_pdata *pdata;
> >>> + const struct of_device_id *match;
> >>> + struct brcmstb_pinctrl *pc;
> >>> + const char **names;
> >>> + int num_pins, i;
> >>> +
> >>> + match = of_match_node(brcmstb_pinctrl_match, np);
> >>
> >> The 'match' variable is needless, you can drop it.
> >
> > you mean something like this?
> >
> > pdata = of_match_node(brcmstb_pinctrl_match, np)->data;
> >
>
> No, I meant:
>
> pdata = of_device_get_match_data(dev)
>
> Also as a bonus you could move brcmstb_pinctrl_match[] array after .probe.a
Right. Thanks!
Andrea
>
> ~Stan
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 2/3] pinctrl: bcm: Add STB family pin controller driver
2025-08-11 14:46 ` [PATCH v3 2/3] pinctrl: bcm: Add STB family pin controller driver Andrea della Porta
2025-08-19 7:40 ` Stanimir Varbanov
@ 2025-08-19 9:18 ` Stefan Wahren
2025-08-21 15:36 ` Andrea della Porta
2025-08-27 16:31 ` Florian Fainelli
2025-08-19 9:37 ` Linus Walleij
2025-08-24 9:57 ` Stefan Wahren
3 siblings, 2 replies; 20+ messages in thread
From: Stefan Wahren @ 2025-08-19 9:18 UTC (permalink / raw)
To: Andrea della Porta, linus.walleij, robh, krzk+dt, conor+dt,
florian.fainelli, linux-gpio, devicetree, linux-arm-kernel,
Catalin Marinas, Will Deacon, iivanov, svarbanov, mbrugger,
Jonathan Bell, Phil Elwell
Hi Andrea,
Am 11.08.25 um 16:46 schrieb Andrea della Porta:
> From: "Ivan T. Ivanov" <iivanov@suse.de>
>
> This driver provide pin muxing and configuration functionality
> for BCM2712 SoC used by RPi5. According to [1] this chip is an
> instance of the one used in Broadcom STB product line.
i'm not sure about the whole driver naming. The cover letter describe it
as "pin control driver for BCM2712 SoC", but this patch is described as
"STB family pin controller driver". So as a reviewer, I'm a little bit
confused of the domain of this driver. Is it for a single SoC or really
for a whole family of many SoCs?
I'm asking because all the other BCM pinctrl drivers are mostly SoC
specific and not really general for a product line.
In the former case, I would expect a driver name like pinctrl-bcm2712 to
make it more clear.
Best regards
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 2/3] pinctrl: bcm: Add STB family pin controller driver
2025-08-11 14:46 ` [PATCH v3 2/3] pinctrl: bcm: Add STB family pin controller driver Andrea della Porta
2025-08-19 7:40 ` Stanimir Varbanov
2025-08-19 9:18 ` Stefan Wahren
@ 2025-08-19 9:37 ` Linus Walleij
2025-08-21 15:46 ` Andrea della Porta
2025-08-24 9:57 ` Stefan Wahren
3 siblings, 1 reply; 20+ messages in thread
From: Linus Walleij @ 2025-08-19 9:37 UTC (permalink / raw)
To: Andrea della Porta
Cc: robh, krzk+dt, conor+dt, florian.fainelli, wahrenst, linux-gpio,
devicetree, linux-arm-kernel, Catalin Marinas, Will Deacon,
iivanov, svarbanov, mbrugger, Jonathan Bell, Phil Elwell,
Bartosz Golaszewski
Hi Andrea/Ivan,
thanks for your patch!
I'll make a bit of detailed review below, the big question I have
is if it is possible to split the files a bit, like:
pinctrl-brcmstb.c <- STB core
pinctrl-brcmstb.h <- STB API
pinctrl-brcmstb-bcm2717.c <- All BCM2712 specifics
This would make it easier to reuse the base file with other STB
chips, right?
On Mon, Aug 11, 2025 at 4:45 PM Andrea della Porta
<andrea.porta@suse.com> wrote:
> +#define FUNC(f) \
> + [func_##f] = #f
> +
> +#define PIN(i, f1, f2, f3, f4, f5, f6, f7, f8) \
> + [i] = { \
> + .funcs = { \
> + func_##f1, \
> + func_##f2, \
> + func_##f3, \
> + func_##f4, \
> + func_##f5, \
> + func_##f6, \
> + func_##f7, \
> + func_##f8, \
> + }, \
> + }
These macros have a bit too generic names. Prefix with BRCMSTB_* or
something please.
> +#define MUX_BIT_VALID 0x8000
> +#define PAD_BIT_INVALID 0xffff
> +
> +#define BIT_TO_REG(b) (((b) >> 5) << 2)
> +#define BIT_TO_SHIFT(b) ((b) & 0x1f)
> +
> +#define MUX_BIT(muxreg, muxshift) \
> + (MUX_BIT_VALID + ((muxreg) << 5) + ((muxshift) << 2))
> +#define PAD_BIT(padreg, padshift) \
> + (((padreg) << 5) + ((padshift) << 1))
> +
> +#define GPIO_REGS(n, muxreg, muxshift, padreg, padshift) \
> + [n] = { MUX_BIT(muxreg, muxshift), PAD_BIT(padreg, padshift) }
> +
> +#define EMMC_REGS(n, padreg, padshift) \
> + [n] = { 0, PAD_BIT(padreg, padshift) }
> +
> +#define AGPIO_REGS(n, muxreg, muxshift, padreg, padshift) \
> + GPIO_REGS(n, muxreg, muxshift, padreg, padshift)
> +
> +#define SGPIO_REGS(n, muxreg, muxshift) \
> + [(n) + 32] = { MUX_BIT(muxreg, muxshift), PAD_BIT_INVALID }
> +
> +#define GPIO_PIN(n) PINCTRL_PIN(n, "gpio" #n)
> +#define AGPIO_PIN(n) PINCTRL_PIN(n, "aon_gpio" #n)
> +#define SGPIO_PIN(n) PINCTRL_PIN((n) + 32, "aon_sgpio" #n)
These are also pretty generically named, but this is OK because they
don't intrude on the pinctrl namespace as much.
> +static inline u32 brcmstb_reg_rd(struct brcmstb_pinctrl *pc, unsigned int reg)
> +{
> + return readl(pc->base + reg);
> +}
> +
> +static inline void brcmstb_reg_wr(struct brcmstb_pinctrl *pc, unsigned int reg,
> + u32 val)
> +{
> + writel(val, pc->base + reg);
> +}
This looks like unnecessary indirection. Can't you just use readl/writel?
> +static int brcmstb_pinctrl_fsel_set(struct brcmstb_pinctrl *pc,
> + unsigned int pin, enum brcmstb_funcs func)
> +{
> + u32 bit = pc->pin_regs[pin].mux_bit, val;
> + const u8 *pin_funcs;
> + unsigned long flags;
> + int fsel;
> + int cur;
> + int i;
> +
> + if (!bit || func >= func_count)
> + return -EINVAL;
> +
> + bit &= ~MUX_BIT_VALID;
> +
> + fsel = BRCMSTB_FSEL_COUNT;
> +
> + if (func >= BRCMSTB_FSEL_COUNT) {
> + /* Convert to an fsel number */
> + pin_funcs = pc->pin_funcs[pin].funcs;
> + for (i = 1; i < BRCMSTB_FSEL_COUNT; i++) {
> + if (pin_funcs[i - 1] == func) {
> + fsel = i;
> + break;
> + }
> + }
> + } else {
> + fsel = (enum brcmstb_funcs)func;
> + }
> +
> + if (fsel >= BRCMSTB_FSEL_COUNT)
> + return -EINVAL;
> +
> + spin_lock_irqsave(&pc->fsel_lock, flags);
Please use lock guards instead, we do that in all new code:
#include <linux/cleanup.h>
guard(spinlock_irqsave)(&pc->fsel_lock);
The framework handles the flags variable and the freeing,
look at other drivers using guard() for guidance.
> +static int brcmstb_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
> + struct pinctrl_gpio_range *range,
> + unsigned int pin)
> +{
> + struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
> +
> + return brcmstb_pinctrl_fsel_set(pc, pin, func_gpio);
> +}
> +
> +static void brcmstb_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
> + struct pinctrl_gpio_range *range,
> + unsigned int offset)
> +{
> + struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
> +
> + /* disable by setting to GPIO */
> + (void)brcmstb_pinctrl_fsel_set(pc, offset, func_gpio);
> +}
> +
> +static const struct pinmux_ops brcmstb_pmx_ops = {
> + .free = brcmstb_pmx_free,
> + .get_functions_count = brcmstb_pmx_get_functions_count,
> + .get_function_name = brcmstb_pmx_get_function_name,
> + .get_function_groups = brcmstb_pmx_get_function_groups,
> + .set_mux = brcmstb_pmx_set,
> + .gpio_request_enable = brcmstb_pmx_gpio_request_enable,
> + .gpio_disable_free = brcmstb_pmx_gpio_disable_free,
> +};
With regards to the GPIO "shotcut" functions:
please familiarize yourself with Bartosz recent patch set:
https://lore.kernel.org/linux-gpio/20250815-pinctrl-gpio-pinfuncs-v5-0-955de9fd91db@linaro.org/T/#t
This makes it possible for the pinctrl core to know about
functions that are used for GPIO, so you can mark your
pin controller as "strict". using the new .function_is_gpio()
callback.
I plan to merge Bartosz series soon and if your pin controller
is aware about which functions are GPIO functions, this makes
things better.
> +static int brcmstb_pull_config_set(struct brcmstb_pinctrl *pc,
> + unsigned int pin, unsigned int arg)
> +{
> + u32 bit = pc->pin_regs[pin].pad_bit, val;
> + unsigned long flags;
> +
> + if (bit == PAD_BIT_INVALID) {
> + dev_warn(pc->dev, "Can't set pulls for %s\n",
> + pc->gpio_groups[pin]);
> + return -EINVAL;
> + }
> +
> + spin_lock_irqsave(&pc->fsel_lock, flags);
Use a guard()
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 3/3] arm64: defconfig: Enable BCM2712 on-chip pin controller driver
2025-08-19 7:25 ` Stanimir Varbanov
@ 2025-08-21 9:35 ` Andrea della Porta
0 siblings, 0 replies; 20+ messages in thread
From: Andrea della Porta @ 2025-08-21 9:35 UTC (permalink / raw)
To: Stanimir Varbanov
Cc: Andrea della Porta, linus.walleij, robh, krzk+dt, conor+dt,
florian.fainelli, wahrenst, linux-gpio, devicetree,
linux-arm-kernel, Catalin Marinas, Will Deacon, iivanov, mbrugger,
Jonathan Bell, Phil Elwell
Hi Stanimir,
On 10:25 Tue 19 Aug , Stanimir Varbanov wrote:
> Hi Andrea,
>
> On 8/11/25 5:46 PM, Andrea della Porta wrote:
> > Select the on-chip pin controller driver for BCM2712 SoC.
> >
> > On RapsberryPi 5 devices it is primarily needed to operate the
> > bluetooth and WiFi devices, to configure the uSD interface
> > and the power button.
> >
> > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> > ---
> > arch/arm64/configs/defconfig | 1 +
> > 1 file changed, 1 insertion(+)
> >
> > diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> > index 58f87d09366c..fafcd7851eb2 100644
> > --- a/arch/arm64/configs/defconfig
> > +++ b/arch/arm64/configs/defconfig
> > @@ -592,6 +592,7 @@ CONFIG_SPI_TEGRA114=m
> > CONFIG_SPI_SPIDEV=m
> > CONFIG_SPMI=y
> > CONFIG_SPMI_MTK_PMIF=m
> > +CONFIG_PINCTRL_BRCMSTB=y
>
> Have you tried as module and part of initramfs?
Yes, it works.
Thanks,
Andrea
>
> ~Stan
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 2/3] pinctrl: bcm: Add STB family pin controller driver
2025-08-19 9:18 ` Stefan Wahren
@ 2025-08-21 15:36 ` Andrea della Porta
2025-08-27 16:32 ` Florian Fainelli
2025-08-27 16:31 ` Florian Fainelli
1 sibling, 1 reply; 20+ messages in thread
From: Andrea della Porta @ 2025-08-21 15:36 UTC (permalink / raw)
To: Stefan Wahren
Cc: Andrea della Porta, linus.walleij, robh, krzk+dt, conor+dt,
florian.fainelli, linux-gpio, devicetree, linux-arm-kernel,
Catalin Marinas, Will Deacon, iivanov, svarbanov, mbrugger,
Jonathan Bell, Phil Elwell
Hi Stefan,
On 11:18 Tue 19 Aug , Stefan Wahren wrote:
> Hi Andrea,
>
> Am 11.08.25 um 16:46 schrieb Andrea della Porta:
> > From: "Ivan T. Ivanov" <iivanov@suse.de>
> >
> > This driver provide pin muxing and configuration functionality
> > for BCM2712 SoC used by RPi5. According to [1] this chip is an
> > instance of the one used in Broadcom STB product line.
> i'm not sure about the whole driver naming. The cover letter describe it as
> "pin control driver for BCM2712 SoC", but this patch is described as "STB
> family pin controller driver". So as a reviewer, I'm a little bit confused
> of the domain of this driver. Is it for a single SoC or really for a whole
> family of many SoCs?
It seems that this is indeed a whole family of which BCM2712 is the (first?)
incarnation. I'm not really aware whether there exist other physical
implementations but I'll amend the comment accordingly.
Please also see:
https://lore.kernel.org/lkml/d6ab66cf-09ac-4f53-9102-11f207d16db5@broadcom.com/
Many thanks,
Andrea
>
> I'm asking because all the other BCM pinctrl drivers are mostly SoC specific
> and not really general for a product line.
>
> In the former case, I would expect a driver name like pinctrl-bcm2712 to
> make it more clear.
>
> Best regards
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 2/3] pinctrl: bcm: Add STB family pin controller driver
2025-08-19 9:37 ` Linus Walleij
@ 2025-08-21 15:46 ` Andrea della Porta
0 siblings, 0 replies; 20+ messages in thread
From: Andrea della Porta @ 2025-08-21 15:46 UTC (permalink / raw)
To: Linus Walleij
Cc: Andrea della Porta, robh, krzk+dt, conor+dt, florian.fainelli,
wahrenst, linux-gpio, devicetree, linux-arm-kernel,
Catalin Marinas, Will Deacon, iivanov, svarbanov, mbrugger,
Jonathan Bell, Phil Elwell, Bartosz Golaszewski
Hi Linus,
On 11:37 Tue 19 Aug , Linus Walleij wrote:
> Hi Andrea/Ivan,
>
> thanks for your patch!
>
> I'll make a bit of detailed review below, the big question I have
> is if it is possible to split the files a bit, like:
>
> pinctrl-brcmstb.c <- STB core
> pinctrl-brcmstb.h <- STB API
> pinctrl-brcmstb-bcm2717.c <- All BCM2712 specifics
I'm trying to find a suitable way to do that. The difficulty is
that AFAIK this is the only chipset using this driver so I'm
not sure what parts are generic and what are specific to BCM2712.
I'll do my best.
>
> This would make it easier to reuse the base file with other STB
> chips, right?
Sure, provided we have a clear separation of common vs specific,
like stated above.
>
> On Mon, Aug 11, 2025 at 4:45 PM Andrea della Porta
> <andrea.porta@suse.com> wrote:
>
> > +#define FUNC(f) \
> > + [func_##f] = #f
> > +
> > +#define PIN(i, f1, f2, f3, f4, f5, f6, f7, f8) \
> > + [i] = { \
> > + .funcs = { \
> > + func_##f1, \
> > + func_##f2, \
> > + func_##f3, \
> > + func_##f4, \
> > + func_##f5, \
> > + func_##f6, \
> > + func_##f7, \
> > + func_##f8, \
> > + }, \
> > + }
>
> These macros have a bit too generic names. Prefix with BRCMSTB_* or
> something please.
Ack.
>
> > +#define MUX_BIT_VALID 0x8000
> > +#define PAD_BIT_INVALID 0xffff
> > +
> > +#define BIT_TO_REG(b) (((b) >> 5) << 2)
> > +#define BIT_TO_SHIFT(b) ((b) & 0x1f)
> > +
> > +#define MUX_BIT(muxreg, muxshift) \
> > + (MUX_BIT_VALID + ((muxreg) << 5) + ((muxshift) << 2))
> > +#define PAD_BIT(padreg, padshift) \
> > + (((padreg) << 5) + ((padshift) << 1))
> > +
> > +#define GPIO_REGS(n, muxreg, muxshift, padreg, padshift) \
> > + [n] = { MUX_BIT(muxreg, muxshift), PAD_BIT(padreg, padshift) }
> > +
> > +#define EMMC_REGS(n, padreg, padshift) \
> > + [n] = { 0, PAD_BIT(padreg, padshift) }
> > +
> > +#define AGPIO_REGS(n, muxreg, muxshift, padreg, padshift) \
> > + GPIO_REGS(n, muxreg, muxshift, padreg, padshift)
> > +
> > +#define SGPIO_REGS(n, muxreg, muxshift) \
> > + [(n) + 32] = { MUX_BIT(muxreg, muxshift), PAD_BIT_INVALID }
> > +
> > +#define GPIO_PIN(n) PINCTRL_PIN(n, "gpio" #n)
> > +#define AGPIO_PIN(n) PINCTRL_PIN(n, "aon_gpio" #n)
> > +#define SGPIO_PIN(n) PINCTRL_PIN((n) + 32, "aon_sgpio" #n)
>
> These are also pretty generically named, but this is OK because they
> don't intrude on the pinctrl namespace as much.
If no one else has something against that, I'll leaving those as they are,
then.
>
> > +static inline u32 brcmstb_reg_rd(struct brcmstb_pinctrl *pc, unsigned int reg)
> > +{
> > + return readl(pc->base + reg);
> > +}
> > +
> > +static inline void brcmstb_reg_wr(struct brcmstb_pinctrl *pc, unsigned int reg,
> > + u32 val)
> > +{
> > + writel(val, pc->base + reg);
> > +}
>
> This looks like unnecessary indirection. Can't you just use readl/writel?
Sure, moreover there's just a small bunch of invokation for those functions...
>
> > +static int brcmstb_pinctrl_fsel_set(struct brcmstb_pinctrl *pc,
> > + unsigned int pin, enum brcmstb_funcs func)
> > +{
> > + u32 bit = pc->pin_regs[pin].mux_bit, val;
> > + const u8 *pin_funcs;
> > + unsigned long flags;
> > + int fsel;
> > + int cur;
> > + int i;
> > +
> > + if (!bit || func >= func_count)
> > + return -EINVAL;
> > +
> > + bit &= ~MUX_BIT_VALID;
> > +
> > + fsel = BRCMSTB_FSEL_COUNT;
> > +
> > + if (func >= BRCMSTB_FSEL_COUNT) {
> > + /* Convert to an fsel number */
> > + pin_funcs = pc->pin_funcs[pin].funcs;
> > + for (i = 1; i < BRCMSTB_FSEL_COUNT; i++) {
> > + if (pin_funcs[i - 1] == func) {
> > + fsel = i;
> > + break;
> > + }
> > + }
> > + } else {
> > + fsel = (enum brcmstb_funcs)func;
> > + }
> > +
> > + if (fsel >= BRCMSTB_FSEL_COUNT)
> > + return -EINVAL;
> > +
> > + spin_lock_irqsave(&pc->fsel_lock, flags);
>
> Please use lock guards instead, we do that in all new code:
>
> #include <linux/cleanup.h>
>
> guard(spinlock_irqsave)(&pc->fsel_lock);
>
> The framework handles the flags variable and the freeing,
> look at other drivers using guard() for guidance.
Ack.
>
> > +static int brcmstb_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
> > + struct pinctrl_gpio_range *range,
> > + unsigned int pin)
> > +{
> > + struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
> > +
> > + return brcmstb_pinctrl_fsel_set(pc, pin, func_gpio);
> > +}
> > +
> > +static void brcmstb_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
> > + struct pinctrl_gpio_range *range,
> > + unsigned int offset)
> > +{
> > + struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
> > +
> > + /* disable by setting to GPIO */
> > + (void)brcmstb_pinctrl_fsel_set(pc, offset, func_gpio);
> > +}
> > +
> > +static const struct pinmux_ops brcmstb_pmx_ops = {
> > + .free = brcmstb_pmx_free,
> > + .get_functions_count = brcmstb_pmx_get_functions_count,
> > + .get_function_name = brcmstb_pmx_get_function_name,
> > + .get_function_groups = brcmstb_pmx_get_function_groups,
> > + .set_mux = brcmstb_pmx_set,
> > + .gpio_request_enable = brcmstb_pmx_gpio_request_enable,
> > + .gpio_disable_free = brcmstb_pmx_gpio_disable_free,
> > +};
>
> With regards to the GPIO "shotcut" functions:
> please familiarize yourself with Bartosz recent patch set:
> https://lore.kernel.org/linux-gpio/20250815-pinctrl-gpio-pinfuncs-v5-0-955de9fd91db@linaro.org/T/#t
>
> This makes it possible for the pinctrl core to know about
> functions that are used for GPIO, so you can mark your
> pin controller as "strict". using the new .function_is_gpio()
> callback.
>
> I plan to merge Bartosz series soon and if your pin controller
> is aware about which functions are GPIO functions, this makes
> things better.
Sure, very nice!
>
> > +static int brcmstb_pull_config_set(struct brcmstb_pinctrl *pc,
> > + unsigned int pin, unsigned int arg)
> > +{
> > + u32 bit = pc->pin_regs[pin].pad_bit, val;
> > + unsigned long flags;
> > +
> > + if (bit == PAD_BIT_INVALID) {
> > + dev_warn(pc->dev, "Can't set pulls for %s\n",
> > + pc->gpio_groups[pin]);
> > + return -EINVAL;
> > + }
> > +
> > + spin_lock_irqsave(&pc->fsel_lock, flags);
>
> Use a guard()
Ack.
Many thanks,
Andrea
>
> Yours,
> Linus Walleij
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 2/3] pinctrl: bcm: Add STB family pin controller driver
2025-08-11 14:46 ` [PATCH v3 2/3] pinctrl: bcm: Add STB family pin controller driver Andrea della Porta
` (2 preceding siblings ...)
2025-08-19 9:37 ` Linus Walleij
@ 2025-08-24 9:57 ` Stefan Wahren
2025-08-27 14:00 ` Andrea della Porta
3 siblings, 1 reply; 20+ messages in thread
From: Stefan Wahren @ 2025-08-24 9:57 UTC (permalink / raw)
To: Andrea della Porta, linus.walleij, robh, krzk+dt, conor+dt,
florian.fainelli, linux-gpio, devicetree, linux-arm-kernel,
Catalin Marinas, Will Deacon, iivanov, svarbanov, mbrugger,
Jonathan Bell, Phil Elwell
Hi Andrea,
Am 11.08.25 um 16:46 schrieb Andrea della Porta:
> From: "Ivan T. Ivanov" <iivanov@suse.de>
>
> This driver provide pin muxing and configuration functionality
> for BCM2712 SoC used by RPi5. According to [1] this chip is an
> instance of the one used in Broadcom STB product line.
>
> [1] https://lore.kernel.org/lkml/f6601f73-cb22-4ba3-88c5-241be8421fc3@broadcom.com/
>
> Cc: Jonathan Bell <jonathan@raspberrypi.com>
> Cc: Phil Elwell <phil@raspberrypi.com>
> Signed-off-by: Ivan T. Ivanov <iivanov@suse.de>
> Reviewed-by: Phil Elwell <phil@raspberrypi.com>
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> ---
> drivers/pinctrl/bcm/Kconfig | 13 +
> drivers/pinctrl/bcm/Makefile | 1 +
> drivers/pinctrl/bcm/pinctrl-brcmstb.c | 1197 +++++++++++++++++++++++++
> 3 files changed, 1211 insertions(+)
> create mode 100644 drivers/pinctrl/bcm/pinctrl-brcmstb.c
>
> diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
> index 35b51ce4298e..2e1b8d444f58 100644
> --- a/drivers/pinctrl/bcm/Kconfig
> +++ b/drivers/pinctrl/bcm/Kconfig
> @@ -3,6 +3,19 @@
> # Broadcom pinctrl drivers
> #
>
> +config PINCTRL_BRCMSTB
> + tristate "Broadcom STB product line pin controller driver"
> + depends on OF && (ARCH_BRCMSTB || COMPILE_TEST)
> + select PINMUX
> + select PINCONF
> + select GENERIC_PINCONF
> + help
> + This driver provide pin muxing and configuration functionality
> + for Broadcom STB product line chipsets. BCM2712 SoC is one of these
> + chipsets.
> +
> + If M is selected the module will be called pinctrl-brcmstb.
> +
> config PINCTRL_BCM281XX
> bool "Broadcom BCM281xx pinctrl driver"
> depends on OF && (ARCH_BCM_MOBILE || COMPILE_TEST)
> diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
> index 82b868ec1471..5f790c14cc4c 100644
> --- a/drivers/pinctrl/bcm/Makefile
> +++ b/drivers/pinctrl/bcm/Makefile
> @@ -11,6 +11,7 @@ obj-$(CONFIG_PINCTRL_BCM6358) += pinctrl-bcm6358.o
> obj-$(CONFIG_PINCTRL_BCM6362) += pinctrl-bcm6362.o
> obj-$(CONFIG_PINCTRL_BCM6368) += pinctrl-bcm6368.o
> obj-$(CONFIG_PINCTRL_BCM63268) += pinctrl-bcm63268.o
> +obj-$(CONFIG_PINCTRL_BRCMSTB) += pinctrl-brcmstb.o
> obj-$(CONFIG_PINCTRL_IPROC_GPIO) += pinctrl-iproc-gpio.o
> obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o
> obj-$(CONFIG_PINCTRL_NS) += pinctrl-ns.o
> diff --git a/drivers/pinctrl/bcm/pinctrl-brcmstb.c b/drivers/pinctrl/bcm/pinctrl-brcmstb.c
> new file mode 100644
> index 000000000000..534bd8908630
> --- /dev/null
> +++ b/drivers/pinctrl/bcm/pinctrl-brcmstb.c
> @@ -0,0 +1,1197 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Driver for Broadcom brcmstb GPIO units (pinctrl only)
> + *
> + * Copyright (C) 2024-2025 Ivan T. Ivanov, Andrea della Porta
> + * Copyright (C) 2021-3 Raspberry Pi Ltd.
> + * Copyright (C) 2012 Chris Boot, Simon Arlott, Stephen Warren
> + *
> + * Based heavily on the BCM2835 GPIO & pinctrl driver, which was inspired by:
> + * pinctrl-nomadik.c, please see original file for copyright information
> + * pinctrl-tegra.c, please see original file for copyright information
> + */
> +
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/pinctrl/pinconf.h>
> +#include <linux/pinctrl/pinctrl.h>
> +#include <linux/pinctrl/pinmux.h>
> +#include <linux/pinctrl/pinconf-generic.h>
> +#include <linux/platform_device.h>
> +#include <linux/seq_file.h>
> +#include <linux/slab.h>
> +#include <linux/spinlock.h>
> +
> +#define BRCMSTB_PULL_NONE 0
> +#define BRCMSTB_PULL_DOWN 1
> +#define BRCMSTB_PULL_UP 2
> +#define BRCMSTB_PULL_MASK 0x3
> +
> +#define BRCMSTB_FSEL_COUNT 9
> +#define BRCMSTB_FSEL_MASK 0xf
> +
> +#define FUNC(f) \
> + [func_##f] = #f
> +
> +#define PIN(i, f1, f2, f3, f4, f5, f6, f7, f8) \
> + [i] = { \
> + .funcs = { \
> + func_##f1, \
> + func_##f2, \
> + func_##f3, \
> + func_##f4, \
> + func_##f5, \
> + func_##f6, \
> + func_##f7, \
> + func_##f8, \
> + }, \
> + }
> +
> +#define MUX_BIT_VALID 0x8000
> +#define PAD_BIT_INVALID 0xffff
> +
> +#define BIT_TO_REG(b) (((b) >> 5) << 2)
> +#define BIT_TO_SHIFT(b) ((b) & 0x1f)
> +
> +#define MUX_BIT(muxreg, muxshift) \
> + (MUX_BIT_VALID + ((muxreg) << 5) + ((muxshift) << 2))
> +#define PAD_BIT(padreg, padshift) \
> + (((padreg) << 5) + ((padshift) << 1))
> +
> +#define GPIO_REGS(n, muxreg, muxshift, padreg, padshift) \
> + [n] = { MUX_BIT(muxreg, muxshift), PAD_BIT(padreg, padshift) }
> +
> +#define EMMC_REGS(n, padreg, padshift) \
> + [n] = { 0, PAD_BIT(padreg, padshift) }
> +
> +#define AGPIO_REGS(n, muxreg, muxshift, padreg, padshift) \
> + GPIO_REGS(n, muxreg, muxshift, padreg, padshift)
> +
> +#define SGPIO_REGS(n, muxreg, muxshift) \
> + [(n) + 32] = { MUX_BIT(muxreg, muxshift), PAD_BIT_INVALID }
> +
> +#define GPIO_PIN(n) PINCTRL_PIN(n, "gpio" #n)
> +#define AGPIO_PIN(n) PINCTRL_PIN(n, "aon_gpio" #n)
> +#define SGPIO_PIN(n) PINCTRL_PIN((n) + 32, "aon_sgpio" #n)
It would be great, if there is comment explaining the difference between
a AGPIO_PIN and a SGPIO_PIN?
In case AGPIO_PIN stands for AON_GPIO_PIN, i would prefer the latter.
> +
> +struct pin_regs {
> + u16 mux_bit;
> + u16 pad_bit;
> +};
> +
> +struct brcmstb_pin_funcs {
> + u8 funcs[BRCMSTB_FSEL_COUNT - 1];
> +};
> +
> +struct brcmstb_pinctrl {
> + struct device *dev;
> + void __iomem *base;
> + struct pinctrl_dev *pctl_dev;
> + struct pinctrl_desc pctl_desc;
> + const struct pin_regs *pin_regs;
> + const struct brcmstb_pin_funcs *pin_funcs;
> + const char *const *gpio_groups;
> + struct pinctrl_gpio_range gpio_range;
> + /* Protect FSEL registers */
> + spinlock_t fsel_lock;
> +};
> +
> +struct brcmstb_pdata {
> + const struct pinctrl_desc *pctl_desc;
> + const struct pinctrl_gpio_range *gpio_range;
> + const struct pin_regs *pin_regs;
> + const struct brcmstb_pin_funcs *pin_funcs;
> +};
> +
> +enum brcmstb_funcs {
> + func_gpio,
> + func_alt1,
> + func_alt2,
> + func_alt3,
> + func_alt4,
> + func_alt5,
> + func_alt6,
> + func_alt7,
> + func_alt8,
> + func_aon_cpu_standbyb,
> + func_aon_fp_4sec_resetb,
> + func_aon_gpclk,
> + func_aon_pwm,
> + func_arm_jtag,
> + func_aud_fs_clk0,
> + func_avs_pmu_bsc,
> + func_bsc_m0,
> + func_bsc_m1,
> + func_bsc_m2,
> + func_bsc_m3,
> + func_clk_observe,
> + func_ctl_hdmi_5v,
> + func_enet0,
> + func_enet0_mii,
> + func_enet0_rgmii,
> + func_ext_sc_clk,
> + func_fl0,
> + func_fl1,
> + func_gpclk0,
> + func_gpclk1,
> + func_gpclk2,
> + func_hdmi_tx0_auto_i2c,
> + func_hdmi_tx0_bsc,
> + func_hdmi_tx1_auto_i2c,
> + func_hdmi_tx1_bsc,
> + func_i2s_in,
> + func_i2s_out,
> + func_ir_in,
> + func_mtsif,
> + func_mtsif_alt,
> + func_mtsif_alt1,
> + func_pdm,
> + func_pkt,
> + func_pm_led_out,
> + func_sc0,
> + func_sd0,
> + func_sd2,
> + func_sd_card_a,
> + func_sd_card_b,
> + func_sd_card_c,
> + func_sd_card_d,
> + func_sd_card_e,
> + func_sd_card_f,
> + func_sd_card_g,
> + func_spdif_out,
> + func_spi_m,
> + func_spi_s,
> + func_sr_edm_sense,
> + func_te0,
> + func_te1,
> + func_tsio,
> + func_uart0,
> + func_uart1,
> + func_uart2,
> + func_usb_pwr,
> + func_usb_vbus,
> + func_uui,
> + func_vc_i2c0,
> + func_vc_i2c3,
> + func_vc_i2c4,
> + func_vc_i2c5,
> + func_vc_i2csl,
> + func_vc_pcm,
> + func_vc_pwm0,
> + func_vc_pwm1,
> + func_vc_spi0,
> + func_vc_spi3,
> + func_vc_spi4,
> + func_vc_spi5,
> + func_vc_uart0,
> + func_vc_uart2,
> + func_vc_uart3,
> + func_vc_uart4,
> + func__,
> + func_count = func__
> +};
I'm very sceptical that this enum is generic. I would tend use to
bcm2712_funcs here.
> +
> +static const struct pin_regs bcm2712_c0_gpio_pin_regs[] = {
> + GPIO_REGS(0, 0, 0, 7, 7),
> + GPIO_REGS(1, 0, 1, 7, 8),
> + GPIO_REGS(2, 0, 2, 7, 9),
> + GPIO_REGS(3, 0, 3, 7, 10),
> + GPIO_REGS(4, 0, 4, 7, 11),
> + GPIO_REGS(5, 0, 5, 7, 12),
> + GPIO_REGS(6, 0, 6, 7, 13),
> + GPIO_REGS(7, 0, 7, 7, 14),
> + GPIO_REGS(8, 1, 0, 8, 0),
> + GPIO_REGS(9, 1, 1, 8, 1),
> + GPIO_REGS(10, 1, 2, 8, 2),
> + GPIO_REGS(11, 1, 3, 8, 3),
> + GPIO_REGS(12, 1, 4, 8, 4),
> + GPIO_REGS(13, 1, 5, 8, 5),
> + GPIO_REGS(14, 1, 6, 8, 6),
> + GPIO_REGS(15, 1, 7, 8, 7),
> + GPIO_REGS(16, 2, 0, 8, 8),
> + GPIO_REGS(17, 2, 1, 8, 9),
> + GPIO_REGS(18, 2, 2, 8, 10),
> + GPIO_REGS(19, 2, 3, 8, 11),
> + GPIO_REGS(20, 2, 4, 8, 12),
> + GPIO_REGS(21, 2, 5, 8, 13),
> + GPIO_REGS(22, 2, 6, 8, 14),
> + GPIO_REGS(23, 2, 7, 9, 0),
> + GPIO_REGS(24, 3, 0, 9, 1),
> + GPIO_REGS(25, 3, 1, 9, 2),
> + GPIO_REGS(26, 3, 2, 9, 3),
> + GPIO_REGS(27, 3, 3, 9, 4),
> + GPIO_REGS(28, 3, 4, 9, 5),
> + GPIO_REGS(29, 3, 5, 9, 6),
> + GPIO_REGS(30, 3, 6, 9, 7),
> + GPIO_REGS(31, 3, 7, 9, 8),
> + GPIO_REGS(32, 4, 0, 9, 9),
> + GPIO_REGS(33, 4, 1, 9, 10),
> + GPIO_REGS(34, 4, 2, 9, 11),
> + GPIO_REGS(35, 4, 3, 9, 12),
> + GPIO_REGS(36, 4, 4, 9, 13),
> + GPIO_REGS(37, 4, 5, 9, 14),
> + GPIO_REGS(38, 4, 6, 10, 0),
> + GPIO_REGS(39, 4, 7, 10, 1),
> + GPIO_REGS(40, 5, 0, 10, 2),
> + GPIO_REGS(41, 5, 1, 10, 3),
> + GPIO_REGS(42, 5, 2, 10, 4),
> + GPIO_REGS(43, 5, 3, 10, 5),
> + GPIO_REGS(44, 5, 4, 10, 6),
> + GPIO_REGS(45, 5, 5, 10, 7),
> + GPIO_REGS(46, 5, 6, 10, 8),
> + GPIO_REGS(47, 5, 7, 10, 9),
> + GPIO_REGS(48, 6, 0, 10, 10),
> + GPIO_REGS(49, 6, 1, 10, 11),
> + GPIO_REGS(50, 6, 2, 10, 12),
> + GPIO_REGS(51, 6, 3, 10, 13),
> + GPIO_REGS(52, 6, 4, 10, 14),
> + GPIO_REGS(53, 6, 5, 11, 0),
> + EMMC_REGS(54, 11, 1), /* EMMC_CMD */
> + EMMC_REGS(55, 11, 2), /* EMMC_DS */
> + EMMC_REGS(56, 11, 3), /* EMMC_CLK */
> + EMMC_REGS(57, 11, 4), /* EMMC_DAT0 */
> + EMMC_REGS(58, 11, 5), /* EMMC_DAT1 */
> + EMMC_REGS(59, 11, 6), /* EMMC_DAT2 */
> + EMMC_REGS(60, 11, 7), /* EMMC_DAT3 */
> + EMMC_REGS(61, 11, 8), /* EMMC_DAT4 */
> + EMMC_REGS(62, 11, 9), /* EMMC_DAT5 */
> + EMMC_REGS(63, 11, 10), /* EMMC_DAT6 */
> + EMMC_REGS(64, 11, 11), /* EMMC_DAT7 */
> +};
> +
> +static struct pin_regs bcm2712_c0_aon_gpio_pin_regs[] = {
> + AGPIO_REGS(0, 3, 0, 6, 10),
> + AGPIO_REGS(1, 3, 1, 6, 11),
> + AGPIO_REGS(2, 3, 2, 6, 12),
> + AGPIO_REGS(3, 3, 3, 6, 13),
> + AGPIO_REGS(4, 3, 4, 6, 14),
> + AGPIO_REGS(5, 3, 5, 7, 0),
> + AGPIO_REGS(6, 3, 6, 7, 1),
> + AGPIO_REGS(7, 3, 7, 7, 2),
> + AGPIO_REGS(8, 4, 0, 7, 3),
> + AGPIO_REGS(9, 4, 1, 7, 4),
> + AGPIO_REGS(10, 4, 2, 7, 5),
> + AGPIO_REGS(11, 4, 3, 7, 6),
> + AGPIO_REGS(12, 4, 4, 7, 7),
> + AGPIO_REGS(13, 4, 5, 7, 8),
> + AGPIO_REGS(14, 4, 6, 7, 9),
> + AGPIO_REGS(15, 4, 7, 7, 10),
> + AGPIO_REGS(16, 5, 0, 7, 11),
> + SGPIO_REGS(0, 0, 0),
> + SGPIO_REGS(1, 0, 1),
> + SGPIO_REGS(2, 0, 2),
> + SGPIO_REGS(3, 0, 3),
> + SGPIO_REGS(4, 1, 0),
> + SGPIO_REGS(5, 2, 0),
> +};
> +
> +static const struct pinctrl_pin_desc bcm2712_c0_gpio_pins[] = {
> + GPIO_PIN(0),
> + GPIO_PIN(1),
> + GPIO_PIN(2),
> + GPIO_PIN(3),
> + GPIO_PIN(4),
> + GPIO_PIN(5),
> + GPIO_PIN(6),
> + GPIO_PIN(7),
> + GPIO_PIN(8),
> + GPIO_PIN(9),
> + GPIO_PIN(10),
> + GPIO_PIN(11),
> + GPIO_PIN(12),
> + GPIO_PIN(13),
> + GPIO_PIN(14),
> + GPIO_PIN(15),
> + GPIO_PIN(16),
> + GPIO_PIN(17),
> + GPIO_PIN(18),
> + GPIO_PIN(19),
> + GPIO_PIN(20),
> + GPIO_PIN(21),
> + GPIO_PIN(22),
> + GPIO_PIN(23),
> + GPIO_PIN(24),
> + GPIO_PIN(25),
> + GPIO_PIN(26),
> + GPIO_PIN(27),
> + GPIO_PIN(28),
> + GPIO_PIN(29),
> + GPIO_PIN(30),
> + GPIO_PIN(31),
> + GPIO_PIN(32),
> + GPIO_PIN(33),
> + GPIO_PIN(34),
> + GPIO_PIN(35),
> + GPIO_PIN(36),
> + GPIO_PIN(37),
> + GPIO_PIN(38),
> + GPIO_PIN(39),
> + GPIO_PIN(40),
> + GPIO_PIN(41),
> + GPIO_PIN(42),
> + GPIO_PIN(43),
> + GPIO_PIN(44),
> + GPIO_PIN(45),
> + GPIO_PIN(46),
> + GPIO_PIN(47),
> + GPIO_PIN(48),
> + GPIO_PIN(49),
> + GPIO_PIN(50),
> + GPIO_PIN(51),
> + GPIO_PIN(52),
> + GPIO_PIN(53),
> + PINCTRL_PIN(54, "emmc_cmd"),
> + PINCTRL_PIN(55, "emmc_ds"),
> + PINCTRL_PIN(56, "emmc_clk"),
> + PINCTRL_PIN(57, "emmc_dat0"),
> + PINCTRL_PIN(58, "emmc_dat1"),
> + PINCTRL_PIN(59, "emmc_dat2"),
> + PINCTRL_PIN(60, "emmc_dat3"),
> + PINCTRL_PIN(61, "emmc_dat4"),
> + PINCTRL_PIN(62, "emmc_dat5"),
> + PINCTRL_PIN(63, "emmc_dat6"),
> + PINCTRL_PIN(64, "emmc_dat7"),
> +};
> +
> +static struct pinctrl_pin_desc bcm2712_c0_aon_gpio_pins[] = {
> + AGPIO_PIN(0), AGPIO_PIN(1), AGPIO_PIN(2), AGPIO_PIN(3),
> + AGPIO_PIN(4), AGPIO_PIN(5), AGPIO_PIN(6), AGPIO_PIN(7),
> + AGPIO_PIN(8), AGPIO_PIN(9), AGPIO_PIN(10), AGPIO_PIN(11),
> + AGPIO_PIN(12), AGPIO_PIN(13), AGPIO_PIN(14), AGPIO_PIN(15),
> + AGPIO_PIN(16), SGPIO_PIN(0), SGPIO_PIN(1), SGPIO_PIN(2),
> + SGPIO_PIN(3), SGPIO_PIN(4), SGPIO_PIN(5),
> +};
> +
> +static const struct pin_regs bcm2712_d0_gpio_pin_regs[] = {
> + GPIO_REGS(1, 0, 0, 4, 5),
> + GPIO_REGS(2, 0, 1, 4, 6),
> + GPIO_REGS(3, 0, 2, 4, 7),
> + GPIO_REGS(4, 0, 3, 4, 8),
> + GPIO_REGS(10, 0, 4, 4, 9),
> + GPIO_REGS(11, 0, 5, 4, 10),
> + GPIO_REGS(12, 0, 6, 4, 11),
> + GPIO_REGS(13, 0, 7, 4, 12),
> + GPIO_REGS(14, 1, 0, 4, 13),
> + GPIO_REGS(15, 1, 1, 4, 14),
> + GPIO_REGS(18, 1, 2, 5, 0),
> + GPIO_REGS(19, 1, 3, 5, 1),
> + GPIO_REGS(20, 1, 4, 5, 2),
> + GPIO_REGS(21, 1, 5, 5, 3),
> + GPIO_REGS(22, 1, 6, 5, 4),
> + GPIO_REGS(23, 1, 7, 5, 5),
> + GPIO_REGS(24, 2, 0, 5, 6),
> + GPIO_REGS(25, 2, 1, 5, 7),
> + GPIO_REGS(26, 2, 2, 5, 8),
> + GPIO_REGS(27, 2, 3, 5, 9),
> + GPIO_REGS(28, 2, 4, 5, 10),
> + GPIO_REGS(29, 2, 5, 5, 11),
> + GPIO_REGS(30, 2, 6, 5, 12),
> + GPIO_REGS(31, 2, 7, 5, 13),
> + GPIO_REGS(32, 3, 0, 5, 14),
> + GPIO_REGS(33, 3, 1, 6, 0),
> + GPIO_REGS(34, 3, 2, 6, 1),
> + GPIO_REGS(35, 3, 3, 6, 2),
> + EMMC_REGS(36, 6, 3), /* EMMC_CMD */
> + EMMC_REGS(37, 6, 4), /* EMMC_DS */
> + EMMC_REGS(38, 6, 5), /* EMMC_CLK */
> + EMMC_REGS(39, 6, 6), /* EMMC_DAT0 */
> + EMMC_REGS(40, 6, 7), /* EMMC_DAT1 */
> + EMMC_REGS(41, 6, 8), /* EMMC_DAT2 */
> + EMMC_REGS(42, 6, 9), /* EMMC_DAT3 */
> + EMMC_REGS(43, 6, 10), /* EMMC_DAT4 */
> + EMMC_REGS(44, 6, 11), /* EMMC_DAT5 */
> + EMMC_REGS(45, 6, 12), /* EMMC_DAT6 */
> + EMMC_REGS(46, 6, 13), /* EMMC_DAT7 */
> +};
> +
> +static struct pin_regs bcm2712_d0_aon_gpio_pin_regs[] = {
> + AGPIO_REGS(0, 3, 0, 5, 9),
> + AGPIO_REGS(1, 3, 1, 5, 10),
> + AGPIO_REGS(2, 3, 2, 5, 11),
> + AGPIO_REGS(3, 3, 3, 5, 12),
> + AGPIO_REGS(4, 3, 4, 5, 13),
> + AGPIO_REGS(5, 3, 5, 5, 14),
> + AGPIO_REGS(6, 3, 6, 6, 0),
> + AGPIO_REGS(8, 3, 7, 6, 1),
> + AGPIO_REGS(9, 4, 0, 6, 2),
> + AGPIO_REGS(12, 4, 1, 6, 3),
> + AGPIO_REGS(13, 4, 2, 6, 4),
> + AGPIO_REGS(14, 4, 3, 6, 5),
> + SGPIO_REGS(0, 0, 0),
> + SGPIO_REGS(1, 0, 1),
> + SGPIO_REGS(2, 0, 2),
> + SGPIO_REGS(3, 0, 3),
> + SGPIO_REGS(4, 1, 0),
> + SGPIO_REGS(5, 2, 0),
> +};
> +
> +static const struct pinctrl_pin_desc bcm2712_d0_gpio_pins[] = {
> + GPIO_PIN(1),
> + GPIO_PIN(2),
> + GPIO_PIN(3),
> + GPIO_PIN(4),
> + GPIO_PIN(10),
> + GPIO_PIN(11),
> + GPIO_PIN(12),
> + GPIO_PIN(13),
> + GPIO_PIN(14),
> + GPIO_PIN(15),
> + GPIO_PIN(18),
> + GPIO_PIN(19),
> + GPIO_PIN(20),
> + GPIO_PIN(21),
> + GPIO_PIN(22),
> + GPIO_PIN(23),
> + GPIO_PIN(24),
> + GPIO_PIN(25),
> + GPIO_PIN(26),
> + GPIO_PIN(27),
> + GPIO_PIN(28),
> + GPIO_PIN(29),
> + GPIO_PIN(30),
> + GPIO_PIN(31),
> + GPIO_PIN(32),
> + GPIO_PIN(33),
> + GPIO_PIN(34),
> + GPIO_PIN(35),
> + PINCTRL_PIN(36, "emmc_cmd"),
> + PINCTRL_PIN(37, "emmc_ds"),
> + PINCTRL_PIN(38, "emmc_clk"),
> + PINCTRL_PIN(39, "emmc_dat0"),
> + PINCTRL_PIN(40, "emmc_dat1"),
> + PINCTRL_PIN(41, "emmc_dat2"),
> + PINCTRL_PIN(42, "emmc_dat3"),
> + PINCTRL_PIN(43, "emmc_dat4"),
> + PINCTRL_PIN(44, "emmc_dat5"),
> + PINCTRL_PIN(45, "emmc_dat6"),
> + PINCTRL_PIN(46, "emmc_dat7"),
> +};
> +
> +static struct pinctrl_pin_desc bcm2712_d0_aon_gpio_pins[] = {
> + AGPIO_PIN(0), AGPIO_PIN(1), AGPIO_PIN(2), AGPIO_PIN(3), AGPIO_PIN(4),
> + AGPIO_PIN(5), AGPIO_PIN(6), AGPIO_PIN(8), AGPIO_PIN(9), AGPIO_PIN(12),
> + AGPIO_PIN(13), AGPIO_PIN(14), SGPIO_PIN(0), SGPIO_PIN(1), SGPIO_PIN(2),
> + SGPIO_PIN(3), SGPIO_PIN(4), SGPIO_PIN(5),
> +};
> +
> +static const char * const brcmstb_func_names[] = {
> + FUNC(gpio),
> + FUNC(alt1),
> + FUNC(alt2),
> + FUNC(alt3),
> + FUNC(alt4),
> + FUNC(alt5),
> + FUNC(alt6),
> + FUNC(alt7),
> + FUNC(alt8),
> + FUNC(aon_cpu_standbyb),
> + FUNC(aon_fp_4sec_resetb),
> + FUNC(aon_gpclk),
> + FUNC(aon_pwm),
> + FUNC(arm_jtag),
> + FUNC(aud_fs_clk0),
> + FUNC(avs_pmu_bsc),
> + FUNC(bsc_m0),
> + FUNC(bsc_m1),
> + FUNC(bsc_m2),
> + FUNC(bsc_m3),
> + FUNC(clk_observe),
> + FUNC(ctl_hdmi_5v),
> + FUNC(enet0),
> + FUNC(enet0_mii),
> + FUNC(enet0_rgmii),
> + FUNC(ext_sc_clk),
> + FUNC(fl0),
> + FUNC(fl1),
> + FUNC(gpclk0),
> + FUNC(gpclk1),
> + FUNC(gpclk2),
> + FUNC(hdmi_tx0_auto_i2c),
> + FUNC(hdmi_tx0_bsc),
> + FUNC(hdmi_tx1_auto_i2c),
> + FUNC(hdmi_tx1_bsc),
> + FUNC(i2s_in),
> + FUNC(i2s_out),
> + FUNC(ir_in),
> + FUNC(mtsif),
> + FUNC(mtsif_alt),
> + FUNC(mtsif_alt1),
> + FUNC(pdm),
> + FUNC(pkt),
> + FUNC(pm_led_out),
> + FUNC(sc0),
> + FUNC(sd0),
> + FUNC(sd2),
> + FUNC(sd_card_a),
> + FUNC(sd_card_b),
> + FUNC(sd_card_c),
> + FUNC(sd_card_d),
> + FUNC(sd_card_e),
> + FUNC(sd_card_f),
> + FUNC(sd_card_g),
> + FUNC(spdif_out),
> + FUNC(spi_m),
> + FUNC(spi_s),
> + FUNC(sr_edm_sense),
> + FUNC(te0),
> + FUNC(te1),
> + FUNC(tsio),
> + FUNC(uart0),
> + FUNC(uart1),
> + FUNC(uart2),
> + FUNC(usb_pwr),
> + FUNC(usb_vbus),
> + FUNC(uui),
> + FUNC(vc_i2c0),
> + FUNC(vc_i2c3),
> + FUNC(vc_i2c4),
> + FUNC(vc_i2c5),
> + FUNC(vc_i2csl),
> + FUNC(vc_pcm),
> + FUNC(vc_pwm0),
> + FUNC(vc_pwm1),
> + FUNC(vc_spi0),
> + FUNC(vc_spi3),
> + FUNC(vc_spi4),
> + FUNC(vc_spi5),
> + FUNC(vc_uart0),
> + FUNC(vc_uart2),
> + FUNC(vc_uart3),
> + FUNC(vc_uart4),
> +};
> +
> +static const struct brcmstb_pin_funcs bcm2712_c0_aon_gpio_pin_funcs[] = {
> + PIN(0, ir_in, vc_spi0, vc_uart3, vc_i2c3, te0, vc_i2c0, _, _),
> + PIN(1, vc_pwm0, vc_spi0, vc_uart3, vc_i2c3, te1, aon_pwm, vc_i2c0, vc_pwm1),
> + PIN(2, vc_pwm0, vc_spi0, vc_uart3, ctl_hdmi_5v, fl0, aon_pwm, ir_in, vc_pwm1),
> + PIN(3, ir_in, vc_spi0, vc_uart3, aon_fp_4sec_resetb, fl1, sd_card_g, aon_gpclk, _),
> + PIN(4, gpclk0, vc_spi0, vc_i2csl, aon_gpclk, pm_led_out, aon_pwm, sd_card_g, vc_pwm0),
> + PIN(5, gpclk1, ir_in, vc_i2csl, clk_observe, aon_pwm, sd_card_g, vc_pwm0, _),
> + PIN(6, uart1, vc_uart4, gpclk2, ctl_hdmi_5v, vc_uart0, vc_spi3, _, _),
> + PIN(7, uart1, vc_uart4, gpclk0, aon_pwm, vc_uart0, vc_spi3, _, _),
> + PIN(8, uart1, vc_uart4, vc_i2csl, ctl_hdmi_5v, vc_uart0, vc_spi3, _, _),
> + PIN(9, uart1, vc_uart4, vc_i2csl, aon_pwm, vc_uart0, vc_spi3, _, _),
> + PIN(10, tsio, ctl_hdmi_5v, sc0, spdif_out, vc_spi5, usb_pwr, aon_gpclk, sd_card_f),
> + PIN(11, tsio, uart0, sc0, aud_fs_clk0, vc_spi5, usb_vbus, vc_uart2, sd_card_f),
> + PIN(12, tsio, uart0, vc_uart0, tsio, vc_spi5, usb_pwr, vc_uart2, sd_card_f),
> + PIN(13, bsc_m1, uart0, vc_uart0, uui, vc_spi5, arm_jtag, vc_uart2, vc_i2c3),
> + PIN(14, bsc_m1, uart0, vc_uart0, uui, vc_spi5, arm_jtag, vc_uart2, vc_i2c3),
> + PIN(15, ir_in, aon_fp_4sec_resetb, vc_uart0, pm_led_out, ctl_hdmi_5v, aon_pwm, aon_gpclk,
> + _),
> + PIN(16, aon_cpu_standbyb, gpclk0, pm_led_out, ctl_hdmi_5v, vc_pwm0, usb_pwr, aud_fs_clk0,
> + _),
I think it's okay to violate the 80 char limit in these both cases to
improve readability.
> +};
> +
...
> +
> +static int brcmstb_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
> + unsigned long *config)
> +{
> + struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
> + enum pin_config_param param = pinconf_to_config_param(*config);
> + u32 arg;
> +
> + switch (param) {
> + case PIN_CONFIG_BIAS_DISABLE:
> + arg = (brcmstb_pull_config_get(pc, pin) == BRCMSTB_PULL_NONE);
> + break;
> + case PIN_CONFIG_BIAS_PULL_DOWN:
> + arg = (brcmstb_pull_config_get(pc, pin) == BRCMSTB_PULL_DOWN);
> + break;
> + case PIN_CONFIG_BIAS_PULL_UP:
> + arg = (brcmstb_pull_config_get(pc, pin) == BRCMSTB_PULL_UP);
I'm not sure this is correct. I would expect that "arg" contains the
resistance in Ohm for PULL_DOWN & PULL_UP.
Best regards
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 1/3] dt-bindings: pinctrl: Add support for Broadcom STB pin controller
2025-08-18 17:20 ` Rob Herring
@ 2025-08-27 9:58 ` Andrea della Porta
0 siblings, 0 replies; 20+ messages in thread
From: Andrea della Porta @ 2025-08-27 9:58 UTC (permalink / raw)
To: Rob Herring
Cc: Andrea della Porta, linus.walleij, krzk+dt, conor+dt,
florian.fainelli, wahrenst, linux-gpio, devicetree,
linux-arm-kernel, Catalin Marinas, Will Deacon, iivanov,
svarbanov, mbrugger, Jonathan Bell, Phil Elwell
Hi Rob,
On 12:20 Mon 18 Aug , Rob Herring wrote:
> On Mon, Aug 11, 2025 at 04:46:51PM +0200, Andrea della Porta wrote:
> > From: "Ivan T. Ivanov" <iivanov@suse.de>
> >
> > The STB pin controller represents a family whose silicon instances
> > are found e.g. on BCM2712 SoC.
> >
> > In particular, on RaspberryPi 5, there are two separate instantiations
> > of the same IP block which differ in the number of pins that are
> > associated and the pinmux functions for each of those pins. The
> > -aon- variant stands for 'Always On'.
> >
> > Depending on the revision of the BCM2712 (CO or D0), the pin
> > controller instance has slight differences in the register layout.
> >
> > Signed-off-by: Ivan T. Ivanov <iivanov@suse.de>
> > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> > ---
> > .../pinctrl/brcm,bcm2712c0-pinctrl.yaml | 135 ++++++++++++++++++
> > 1 file changed, 135 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm2712c0-pinctrl.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm2712c0-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm2712c0-pinctrl.yaml
> > new file mode 100644
> > index 000000000000..28d66336aa2e
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm2712c0-pinctrl.yaml
> > @@ -0,0 +1,135 @@
> > +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm2712c0-pinctrl.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Broadcom STB family pin controller
> > +
> > +maintainers:
> > + - Ivan T. Ivanov <iivanov@suse.de>
> > + - A. della Porta <andrea.porta@suse.com>
>
> Why is your first name abbrievated here?
The heuristic inside get_maintainer.pl does not correctly recognize names like
"Andrea della Porta", reporting something like:
della Porta <andrea.porta@suse.com>
and missing both the first name and the double quotes surrounding the
name/surname pair.
Something like "Andrea d. Porta" would be reported correctly but it's not an
option in my case since 'della' is not a middle name that can abbreviated,
it's just integral part of the surname.
The easy workaround I've found (the hard one being fixing get_maintainer.pl
script, of course, but I'm not a Perl guru) is to just let the name be
abbreviated.
>
> > +
> > +description:
> > + Broadcom's STB family of memory-mapped pin controllers.
> > + This includes the pin controllers inside the BCM2712 SoC which
> > + are instances of the STB family and has two silicon variants,
> > + C0 and D0, which differs slightly in terms of registers layout.
> > + The -aon- (Always On) variant is the same IP block but differs
> > + in the number of pins that are associated and the pinmux functions
> > + for each of those pins.
>
> Wrap lines at 80. If there are paragraphs, then blank line in between
> and use the '>' modifier.
I'm not seeing any lines exceeding 80 chars here. Ack for the
blank lines between paragraphs plus >.
>
> > +
> > +allOf:
> > + - $ref: pinctrl.yaml#
> > +
> > +properties:
> > + compatible:
> > + enum:
> > + - brcm,bcm2712c0-pinctrl
> > + - brcm,bcm2712c0-aon-pinctrl
> > + - brcm,bcm2712d0-pinctrl
> > + - brcm,bcm2712d0-aon-pinctrl
> > +
> > + reg:
> > + maxItems: 1
> > +
> > +patternProperties:
> > + '-state$':
> > + oneOf:
> > + - $ref: '#/$defs/brcmstb-pinctrl-state'
> > + - patternProperties:
> > + '-pins$':
> > + $ref: '#/$defs/brcmstb-pinctrl-state'
> > + additionalProperties: false
> > +
> > +$defs:
> > + brcmstb-pinctrl-state:
> > + allOf:
> > + - $ref: pincfg-node.yaml#
> > + - $ref: pinmux-node.yaml#
> > +
> > + description:
> > + Pin controller client devices use pin configuration subnodes (children
> > + and grandchildren) for desired pin configuration.
> > + Client device subnodes use below standard properties.
>
> Paragraphs here?
Ack.
>
> > +
> > + properties:
> > + pins:
> > + description:
> > + List of gpio pins affected by the properties specified in this
> > + subnode (either this or "groups" must be specified).
> > + items:
> > + pattern: '^((aon_)?s?gpio[0-6]?[0-9])|(emmc_(clk|cmd|dat[0-7]|ds))$'
> > +
> > + function:
> > + enum: [ gpio, alt1, alt2, alt3, alt4, alt5, alt6, alt7, alt8,
> > + aon_cpu_standbyb, aon_fp_4sec_resetb, aon_gpclk, aon_pwm,
> > + arm_jtag, aud_fs_clk0, avs_pmu_bsc, bsc_m0, bsc_m1, bsc_m2,
> > + bsc_m3, clk_observe, ctl_hdmi_5v, enet0, enet0_mii, enet0_rgmii,
> > + ext_sc_clk, fl0, fl1, gpclk0, gpclk1, gpclk2, hdmi_tx0_auto_i2c,
> > + hdmi_tx0_bsc, hdmi_tx1_auto_i2c, hdmi_tx1_bsc, i2s_in, i2s_out,
> > + ir_in, mtsif, mtsif_alt, mtsif_alt1, pdm, pkt, pm_led_out, sc0,
> > + sd0, sd2, sd_card_a, sd_card_b, sd_card_c, sd_card_d, sd_card_e,
> > + sd_card_f, sd_card_g, spdif_out, spi_m, spi_s, sr_edm_sense, te0,
> > + te1, tsio, uart0, uart1, uart2, usb_pwr, usb_vbus, uui, vc_i2c0,
> > + vc_i2c3, vc_i2c4, vc_i2c5, vc_i2csl, vc_pcm, vc_pwm0, vc_pwm1,
> > + vc_spi0, vc_spi3, vc_spi4, vc_spi5, vc_uart0, vc_uart2, vc_uart3,
> > + vc_uart4 ]
> > +
> > + description:
> > + Specify the alternative function to be configured for the specified
> > + pins.
>
> Be consistent with putting 'description' first or last.
Ack.
Many thanks,
Andrea
>
> > +
> > + bias-disable: true
> > + bias-pull-down: true
> > + bias-pull-up: true
> > +
> > + required:
> > + - pins
> > +
> > + if:
> > + properties:
> > + pins:
> > + not:
> > + contains:
> > + pattern: "^emmc_(clk|cmd|dat[0-7]|ds)$"
> > + then:
> > + required:
> > + - function
> > + else:
> > + properties:
> > + function: false
> > +
> > + additionalProperties: false
> > +
> > +required:
> > + - compatible
> > + - reg
> > +
> > +unevaluatedProperties: false
> > +
> > +examples:
> > + - |
> > + brcm_pinctrl: pinctrl@7d504100 {
> > + compatible = "brcm,bcm2712c0-pinctrl";
> > + reg = <0x7d504100 0x30>;
> > +
> > + bt-shutdown-default-state {
> > + function = "gpio";
> > + pins = "gpio29";
> > + };
> > +
> > + uarta-default-state {
> > + rts-tx-pins {
> > + function = "uart0";
> > + pins = "gpio24", "gpio26";
> > + bias-disable;
> > + };
> > +
> > + cts-rx-pins {
> > + function = "uart0";
> > + pins = "gpio25", "gpio27";
> > + bias-pull-up;
> > + };
> > + };
> > + };
> > --
> > 2.35.3
> >
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 2/3] pinctrl: bcm: Add STB family pin controller driver
2025-08-24 9:57 ` Stefan Wahren
@ 2025-08-27 14:00 ` Andrea della Porta
0 siblings, 0 replies; 20+ messages in thread
From: Andrea della Porta @ 2025-08-27 14:00 UTC (permalink / raw)
To: Stefan Wahren
Cc: Andrea della Porta, linus.walleij, robh, krzk+dt, conor+dt,
florian.fainelli, linux-gpio, devicetree, linux-arm-kernel,
Catalin Marinas, Will Deacon, iivanov, svarbanov, mbrugger,
Jonathan Bell, Phil Elwell
Hi Stefan,
On 11:57 Sun 24 Aug , Stefan Wahren wrote:
> Hi Andrea,
>
> Am 11.08.25 um 16:46 schrieb Andrea della Porta:
> > From: "Ivan T. Ivanov" <iivanov@suse.de>
> >
> > This driver provide pin muxing and configuration functionality
> > for BCM2712 SoC used by RPi5. According to [1] this chip is an
> > instance of the one used in Broadcom STB product line.
[...]
> > +#define AGPIO_PIN(n) PINCTRL_PIN(n, "aon_gpio" #n)
> > +#define SGPIO_PIN(n) PINCTRL_PIN((n) + 32, "aon_sgpio" #n)
> It would be great, if there is comment explaining the difference between a
> AGPIO_PIN and a SGPIO_PIN?
>
> In case AGPIO_PIN stands for AON_GPIO_PIN, i would prefer the latter.
I need to dig more on the SGPIO type, more on that as soon as I'll
find some more details. No problem in using more explanatory label,
of_course.
> > +
> > +struct pin_regs {
> > + u16 mux_bit;
> > + u16 pad_bit;
> > +};
> > +
[...]
> > +enum brcmstb_funcs {
> > + func_gpio,
> > + func_alt1,
> > + func_alt2,
> > + func_alt3,
> > + func_alt4,
> > + func_alt5,
> > + func_alt6,
> > + func_alt7,
> > + func_alt8,
> > + func_aon_cpu_standbyb,
> > + func_aon_fp_4sec_resetb,
> > + func_aon_gpclk,
> > + func_aon_pwm,
> > + func_arm_jtag,
> > + func_aud_fs_clk0,
> > + func_avs_pmu_bsc,
> > + func_bsc_m0,
> > + func_bsc_m1,
> > + func_bsc_m2,
> > + func_bsc_m3,
> > + func_clk_observe,
> > + func_ctl_hdmi_5v,
> > + func_enet0,
> > + func_enet0_mii,
> > + func_enet0_rgmii,
> > + func_ext_sc_clk,
> > + func_fl0,
> > + func_fl1,
> > + func_gpclk0,
> > + func_gpclk1,
> > + func_gpclk2,
> > + func_hdmi_tx0_auto_i2c,
> > + func_hdmi_tx0_bsc,
> > + func_hdmi_tx1_auto_i2c,
> > + func_hdmi_tx1_bsc,
> > + func_i2s_in,
> > + func_i2s_out,
> > + func_ir_in,
> > + func_mtsif,
> > + func_mtsif_alt,
> > + func_mtsif_alt1,
> > + func_pdm,
> > + func_pkt,
> > + func_pm_led_out,
> > + func_sc0,
> > + func_sd0,
> > + func_sd2,
> > + func_sd_card_a,
> > + func_sd_card_b,
> > + func_sd_card_c,
> > + func_sd_card_d,
> > + func_sd_card_e,
> > + func_sd_card_f,
> > + func_sd_card_g,
> > + func_spdif_out,
> > + func_spi_m,
> > + func_spi_s,
> > + func_sr_edm_sense,
> > + func_te0,
> > + func_te1,
> > + func_tsio,
> > + func_uart0,
> > + func_uart1,
> > + func_uart2,
> > + func_usb_pwr,
> > + func_usb_vbus,
> > + func_uui,
> > + func_vc_i2c0,
> > + func_vc_i2c3,
> > + func_vc_i2c4,
> > + func_vc_i2c5,
> > + func_vc_i2csl,
> > + func_vc_pcm,
> > + func_vc_pwm0,
> > + func_vc_pwm1,
> > + func_vc_spi0,
> > + func_vc_spi3,
> > + func_vc_spi4,
> > + func_vc_spi5,
> > + func_vc_uart0,
> > + func_vc_uart2,
> > + func_vc_uart3,
> > + func_vc_uart4,
> > + func__,
> > + func_count = func__
> > +};
> I'm very sceptical that this enum is generic. I would tend use to
> bcm2712_funcs here.
Ack.
> > +
> > +static const struct pin_regs bcm2712_c0_gpio_pin_regs[] = {
> > + GPIO_REGS(0, 0, 0, 7, 7),
> > + GPIO_REGS(1, 0, 1, 7, 8),
> > + GPIO_REGS(2, 0, 2, 7, 9),
[...]
> > +static const struct brcmstb_pin_funcs bcm2712_c0_aon_gpio_pin_funcs[] = {
> > + PIN(0, ir_in, vc_spi0, vc_uart3, vc_i2c3, te0, vc_i2c0, _, _),
> > + PIN(1, vc_pwm0, vc_spi0, vc_uart3, vc_i2c3, te1, aon_pwm, vc_i2c0, vc_pwm1),
> > + PIN(2, vc_pwm0, vc_spi0, vc_uart3, ctl_hdmi_5v, fl0, aon_pwm, ir_in, vc_pwm1),
> > + PIN(3, ir_in, vc_spi0, vc_uart3, aon_fp_4sec_resetb, fl1, sd_card_g, aon_gpclk, _),
> > + PIN(4, gpclk0, vc_spi0, vc_i2csl, aon_gpclk, pm_led_out, aon_pwm, sd_card_g, vc_pwm0),
> > + PIN(5, gpclk1, ir_in, vc_i2csl, clk_observe, aon_pwm, sd_card_g, vc_pwm0, _),
> > + PIN(6, uart1, vc_uart4, gpclk2, ctl_hdmi_5v, vc_uart0, vc_spi3, _, _),
> > + PIN(7, uart1, vc_uart4, gpclk0, aon_pwm, vc_uart0, vc_spi3, _, _),
> > + PIN(8, uart1, vc_uart4, vc_i2csl, ctl_hdmi_5v, vc_uart0, vc_spi3, _, _),
> > + PIN(9, uart1, vc_uart4, vc_i2csl, aon_pwm, vc_uart0, vc_spi3, _, _),
> > + PIN(10, tsio, ctl_hdmi_5v, sc0, spdif_out, vc_spi5, usb_pwr, aon_gpclk, sd_card_f),
> > + PIN(11, tsio, uart0, sc0, aud_fs_clk0, vc_spi5, usb_vbus, vc_uart2, sd_card_f),
> > + PIN(12, tsio, uart0, vc_uart0, tsio, vc_spi5, usb_pwr, vc_uart2, sd_card_f),
> > + PIN(13, bsc_m1, uart0, vc_uart0, uui, vc_spi5, arm_jtag, vc_uart2, vc_i2c3),
> > + PIN(14, bsc_m1, uart0, vc_uart0, uui, vc_spi5, arm_jtag, vc_uart2, vc_i2c3),
> > + PIN(15, ir_in, aon_fp_4sec_resetb, vc_uart0, pm_led_out, ctl_hdmi_5v, aon_pwm, aon_gpclk,
> > + _),
> > + PIN(16, aon_cpu_standbyb, gpclk0, pm_led_out, ctl_hdmi_5v, vc_pwm0, usb_pwr, aud_fs_clk0,
> > + _),
> I think it's okay to violate the 80 char limit in these both cases to
> improve readability.
Ack.
> > +};
> > +
> ...
> > +
> > +static int brcmstb_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
> > + unsigned long *config)
> > +{
> > + struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
> > + enum pin_config_param param = pinconf_to_config_param(*config);
> > + u32 arg;
> > +
> > + switch (param) {
> > + case PIN_CONFIG_BIAS_DISABLE:
> > + arg = (brcmstb_pull_config_get(pc, pin) == BRCMSTB_PULL_NONE);
> > + break;
> > + case PIN_CONFIG_BIAS_PULL_DOWN:
> > + arg = (brcmstb_pull_config_get(pc, pin) == BRCMSTB_PULL_DOWN);
> > + break;
> > + case PIN_CONFIG_BIAS_PULL_UP:
> > + arg = (brcmstb_pull_config_get(pc, pin) == BRCMSTB_PULL_UP);
> I'm not sure this is correct. I would expect that "arg" contains the
> resistance in Ohm for PULL_DOWN & PULL_UP.
In this case I don't have insight about the current impedance value. Since
this is easily something that changes between different implementations, I
would leave it as it is as it's more general, i.e. 0 for disabled and 1 for
pull up/down enabled (which seems to be the most common behaviour for pinconf
drivers anyway).
Once we know more details about the Ohm values or a new STB implementation
arises, we can quickly add the relevant data in the specific driver code.
Many thanks,
Andrea
>
> Best regards
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 2/3] pinctrl: bcm: Add STB family pin controller driver
2025-08-19 9:18 ` Stefan Wahren
2025-08-21 15:36 ` Andrea della Porta
@ 2025-08-27 16:31 ` Florian Fainelli
1 sibling, 0 replies; 20+ messages in thread
From: Florian Fainelli @ 2025-08-27 16:31 UTC (permalink / raw)
To: Stefan Wahren, Andrea della Porta, linus.walleij, robh, krzk+dt,
conor+dt, linux-gpio, devicetree, linux-arm-kernel,
Catalin Marinas, Will Deacon, iivanov, svarbanov, mbrugger,
Jonathan Bell, Phil Elwell
On 8/19/25 02:18, Stefan Wahren wrote:
> Hi Andrea,
>
> Am 11.08.25 um 16:46 schrieb Andrea della Porta:
>> From: "Ivan T. Ivanov" <iivanov@suse.de>
>>
>> This driver provide pin muxing and configuration functionality
>> for BCM2712 SoC used by RPi5. According to [1] this chip is an
>> instance of the one used in Broadcom STB product line.
> i'm not sure about the whole driver naming. The cover letter describe it
> as "pin control driver for BCM2712 SoC", but this patch is described as
> "STB family pin controller driver". So as a reviewer, I'm a little bit
> confused of the domain of this driver. Is it for a single SoC or really
> for a whole family of many SoCs?
The structure of the driver is applicable to the entire Broadcom STB SoC
family, of which 2712/7712 is one instance.
>
> I'm asking because all the other BCM pinctrl drivers are mostly SoC
> specific and not really general for a product line.
>
> In the former case, I would expect a driver name like pinctrl-bcm2712 to
> make it more clear.
pinctrl-brcmstb.c for the main part which is agnostic to the
chip-specific functions is adequate.
--
Florian
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 2/3] pinctrl: bcm: Add STB family pin controller driver
2025-08-21 15:36 ` Andrea della Porta
@ 2025-08-27 16:32 ` Florian Fainelli
0 siblings, 0 replies; 20+ messages in thread
From: Florian Fainelli @ 2025-08-27 16:32 UTC (permalink / raw)
To: Andrea della Porta, Stefan Wahren
Cc: linus.walleij, robh, krzk+dt, conor+dt, linux-gpio, devicetree,
linux-arm-kernel, Catalin Marinas, Will Deacon, iivanov,
svarbanov, mbrugger, Jonathan Bell, Phil Elwell
On 8/21/25 08:36, Andrea della Porta wrote:
> Hi Stefan,
>
> On 11:18 Tue 19 Aug , Stefan Wahren wrote:
>> Hi Andrea,
>>
>> Am 11.08.25 um 16:46 schrieb Andrea della Porta:
>>> From: "Ivan T. Ivanov" <iivanov@suse.de>
>>>
>>> This driver provide pin muxing and configuration functionality
>>> for BCM2712 SoC used by RPi5. According to [1] this chip is an
>>> instance of the one used in Broadcom STB product line.
>> i'm not sure about the whole driver naming. The cover letter describe it as
>> "pin control driver for BCM2712 SoC", but this patch is described as "STB
>> family pin controller driver". So as a reviewer, I'm a little bit confused
>> of the domain of this driver. Is it for a single SoC or really for a whole
>> family of many SoCs?
>
> It seems that this is indeed a whole family of which BCM2712 is the (first?)
> incarnation. I'm not really aware whether there exist other physical
> implementations but I'll amend the comment accordingly.
> Please also see:
> https://lore.kernel.org/lkml/d6ab66cf-09ac-4f53-9102-11f207d16db5@broadcom.com/
It's not the first, far from it, that pinctrl/pinmux design dates back
to the first Broadcom STB SoC (BCM7038).
--
Florian
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2025-08-27 19:15 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-11 14:46 [PATCH v3 0/3] Add pin control driver for BCM2712 SoC Andrea della Porta
2025-08-11 14:46 ` [PATCH v3 1/3] dt-bindings: pinctrl: Add support for Broadcom STB pin controller Andrea della Porta
2025-08-18 17:20 ` Rob Herring
2025-08-27 9:58 ` Andrea della Porta
2025-08-11 14:46 ` [PATCH v3 2/3] pinctrl: bcm: Add STB family pin controller driver Andrea della Porta
2025-08-19 7:40 ` Stanimir Varbanov
2025-08-19 8:14 ` Andrea della Porta
2025-08-19 8:19 ` Stanimir Varbanov
2025-08-19 8:40 ` Andrea della Porta
2025-08-19 9:18 ` Stefan Wahren
2025-08-21 15:36 ` Andrea della Porta
2025-08-27 16:32 ` Florian Fainelli
2025-08-27 16:31 ` Florian Fainelli
2025-08-19 9:37 ` Linus Walleij
2025-08-21 15:46 ` Andrea della Porta
2025-08-24 9:57 ` Stefan Wahren
2025-08-27 14:00 ` Andrea della Porta
2025-08-11 14:46 ` [PATCH v3 3/3] arm64: defconfig: Enable BCM2712 on-chip " Andrea della Porta
2025-08-19 7:25 ` Stanimir Varbanov
2025-08-21 9:35 ` Andrea della Porta
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).