* [RFC PATCH v3 1/7] dt-bindings: pinctrl: starfive: Add JH8100 pinctrl
2024-05-03 11:14 [RFC PATCH v3 0/7] Add Pinctrl driver for Starfive JH8100 SoC Alex Soo
@ 2024-05-03 11:14 ` Alex Soo
2024-05-03 13:34 ` Rob Herring (Arm)
2024-05-03 16:07 ` Conor Dooley
2024-05-03 11:14 ` [RFC PATCH v3 2/7] pinctrl: starfive: jh8100: add main driver and sys_east domain sub-driver Alex Soo
` (7 subsequent siblings)
8 siblings, 2 replies; 18+ messages in thread
From: Alex Soo @ 2024-05-03 11:14 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Hal Feng, Ley Foon Tan,
Jianlong Huang, Emil Renner Berthing, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Drew Fustini
Cc: linux-gpio, linux-kernel, devicetree, linux-riscv, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alex Soo
Add documentation and header file for JH8100 pinctrl driver.
Signed-off-by: Alex Soo <yuklin.soo@starfivetech.com>
---
.../pinctrl/starfive,jh8100-aon-pinctrl.yaml | 260 ++++++++++++++++++
.../starfive,jh8100-sys-east-pinctrl.yaml | 222 +++++++++++++++
.../starfive,jh8100-sys-gmac-pinctrl.yaml | 162 +++++++++++
.../starfive,jh8100-sys-west-pinctrl.yaml | 219 +++++++++++++++
.../pinctrl/starfive,jh8100-pinctrl.h | 13 +
5 files changed, 876 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/starfive,jh8100-aon-pinctrl.yaml
create mode 100644 Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-east-pinctrl.yaml
create mode 100644 Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-gmac-pinctrl.yaml
create mode 100644 Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-west-pinctrl.yaml
create mode 100644 include/dt-bindings/pinctrl/starfive,jh8100-pinctrl.h
diff --git a/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-aon-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-aon-pinctrl.yaml
new file mode 100644
index 000000000000..abd2a7570a54
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-aon-pinctrl.yaml
@@ -0,0 +1,260 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/starfive,jh8100-aon-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JH8100 AON (always-on) Pin Controller
+
+description: |
+ Pinctrl bindings for JH8100 RISC-V SoC from StarFive Technology Ltd.
+
+ The JH8100 SoC has 4 pinctrl domains - sys_east, sys_west, sys_gmac, and aon.
+ This document provides an overview of the "aon" pinctrl domain.
+
+ The "aon" domain has a pin controller which provides
+ - I/O multiplexing for peripheral signals specific to this domain.
+ - GPIO pins which support external GPIO interrupts or external wake-up.
+ - syscon registers to configure device I/O reference voltage.
+
+ In the AON Pin Controller, the pins named PAD_RGPIO0 to PAD_GPIO15 can be
+ multiplexed and have configurable bias, drive strength, schmitt trigger etc.
+ Only peripherals in the AON domain can have their I/O go through the 16
+ "PAD_RGPIOs". This includes I2C, UART, watchdog, eMMC, SDIO0, XSPI etc.
+
+ All these peripherals can be connected to any of the 16 PAD_RGPIOs in such a way
+ that any iopad can be set up to be controlled by any of the peripherals.
+
+ The pin muxing is illustrated by the diagram below.
+ _____________
+ | |
+ RGPIO0 --------------| |--- PAD_RGPIO0
+ RGPIO1 --------------| AON I/O MUX |--- PAD_RGPIO1
+ ... | | ...
+ I2C8 SDA interface --| |--- PAD_RGPIO15
+ | |
+ -------------
+
+ The AON Pin Controller provides syscon registers to configure
+
+ 1. reference voltage of
+ - eMMC I/O interface
+ supported voltage - 1.8V
+ - SDIO0 I/O interface
+ supported voltage - 3.3V, 1.8V
+ - PAD_RGPIO bank
+ - 16 PAD_RGPIOs (PAD_RGPIO0 to PAD_GPIO15)
+ - all devices attached to PAD_RGPIOs must use I/O voltage 3.3V.
+ - XSPI I/O interface
+ supported voltage level - 3.3V
+
+ Regulator supplies the device voltage, and each device has a corresponding syscon
+ register bit [1:0] that must be configured to indicate the device voltage level.
+
+ +--------+--------+-------------------+
+ | Bit[1] | Bit[0] | Reference Voltage |
+ +--------+--------+-------------------+
+ | 0 | 0 | 3.3 V |
+ +--------+--------+-------------------+
+ | 0 | 1 | 2.5 V |
+ +--------+--------+-------------------+
+ | 1 | x | 1.8 V |
+ +--------+--------+-------------------+
+
+ 2. reference voltage and slew rate of GMAC0
+
+ Voltage level on GMAC0 interface is dependent on the PHY that it is pairing with. The
+ supported voltage levels are 3.3V, 2.5V, and 1.8V.
+
+ GMAC0 has 2 set of syscon registers -
+
+ 2.1 PAD_VREF_GMAC0_syscon - bit [1:0] must be configured to indicate the voltage level on
+ GMAC0 interface. The default setting is 3.3V.
+
+ +--------+--------+-----------------------------------+
+ | Bit[1] | Bit[0] | GMAC0 Interface Reference Voltage |
+ +--------+--------+-----------------------------------+
+ | 0 | 0 | 3.3V |
+ +--------+--------+-----------------------------------+
+ | 0 | 1 | 2.5V |
+ +--------+--------+-----------------------------------+
+ | 1 | x | 1.8V |
+ +--------+--------+-----------------------------------+
+
+ 2.2 PAD_GMAC0_<SIGNAL_NAME>_syscon - each GMAC0 pad has a corresponding syscon bit [0] set
+ to 0 by default. When GMAC0 mode is RGMII and voltage level is 2.5V, the bit [0] must be
+ set to 1.
+
+ +-------------+-----------------------+---------+
+ | GMAC0 Mode | GMAC0 Voltage Level | Bit[0] |
+ +-------------+-----------------------+---------+
+ | | 3.3V | 0 |
+ | |-----------------------+---------+
+ | RGMII | 2.5V | 1 |
+ | |-----------------------+---------+
+ | | 1.8V | 0 |
+ +-------------+-----------------------+---------+
+ | | 3.3V | 0 |
+ | |-----------------------+---------+
+ | RMII | 2.5V | 0 |
+ | |-----------------------+---------+
+ | | 1.8V | 0 |
+ +-------------+-----------------------+---------+
+
+ the bit [2] can be used to configure GMAC0 signal slew rate,
+
+ +--------+-----------+
+ | Bit[2] | Slew Rate |
+ +--------+-----------+
+ | 0 | Fast |
+ +--------+-----------+
+ | 1 | Slow |
+ +--------+-----------+
+
+ Under any circumstances, the syscon register's reference voltage setting must not be
+ lower than the actual device voltage, otherwise, the device I/O pads will get damaged.
+
+ Follow the guidelines below when configure reference voltage -
+
+ To increase the device voltage, set bit [1:0] to the new operating state first before
+ raising the actual voltage to the higher operating point.
+
+ To decrease the device voltage, hold bit [1:0] to the current operating state until
+ the actual voltage has stabilized at the lower operating point before changing the
+ setting.
+
+ Alternatively, a device voltage change can always be initiated by first setting syscon
+ register bit [1:0] = 0, the safe 3.3V startup condition, before changing the device
+ voltage. Then once the actual voltage is changed and has stabilized at the new operating
+ point, bit [1:0] can be reset as appropriate.
+
+maintainers:
+ - Alex Soo <yuklin.soo@starfivetech.com>
+
+properties:
+ compatible:
+ - items:
+ - const: starfive,jh8100-aon-pinctrl
+ - const: syscon
+ - const: simple-mfd
+
+ reg:
+ maxItems: 1
+
+ resets:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ interrupt-controller: true
+
+ gpio-controller: true
+
+ '#gpio-cells':
+ const: 2
+
+ gpio-ranges:
+ maxItems: 1
+
+ wakeup-gpios:
+ maxItems: 1
+ description: GPIO pin to be used for waking up the system from sleep mode.
+
+ wakeup-source:
+ maxItems: 1
+ description: to indicate pinctrl has wakeup capability.
+
+patternProperties:
+ '-grp$':
+ type: object
+ additionalProperties: false
+ patternProperties:
+ '-pins$':
+ type: object
+ description: |
+ A pinctrl node should contain at least one subnode representing the
+ pinctrl groups available in the domain. Each subnode will list the
+ pins it needs, and how they should be configured, with regard to
+ muxer configuration, bias, input enable/disable, input schmitt
+ trigger enable/disable, slew-rate and drive strength.
+ allOf:
+ - $ref: /schemas/pinctrl/pincfg-node.yaml
+ - $ref: /schemas/pinctrl/pinmux-node.yaml
+ unevaluatedProperties: false
+
+ properties:
+ pinmux:
+ description: |
+ The list of GPIOs and their mux settings or function select.
+ The GPIOMUX and PINMUX macros are used to configure the
+ I/O multiplexing and function selection respectively.
+
+ bias-disable: true
+
+ bias-pull-up:
+ type: boolean
+
+ bias-pull-down:
+ type: boolean
+
+ drive-strength-microamp:
+ enum: [ 2000, 4000, 8000, 12000 ]
+
+ input-enable: true
+
+ input-disable: true
+
+ input-schmitt-enable: true
+
+ input-schmitt-disable: true
+
+ slew-rate:
+ enum: [ 0, 1 ]
+ default: 0
+ description: |
+ 0: slow (half frequency)
+ 1: fast
+
+required:
+ - compatible
+ - reg
+ - resets
+ - interrupts
+ - interrupt-controller
+ - gpio-controller
+ - '#gpio-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ pinctrl_aon: pinctrl@1f300000 {
+ compatible = "starfive,jh8100-aon-pinctrl", "syscon", "simple-mfd";
+ reg = <0x0 0x1f300000 0x0 0x10000>;
+ resets = <&aoncrg 0>;
+ interrupts = <160>;
+ interrupt-controller;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl_aon 0 0 16>;
+
+ i2c7_pins: i2c7-grp {
+ i2c7-scl-pins {
+ pinmux = <0x23265409>;
+ bias-pull-up;
+ input-enable;
+ };
+
+ i2c7-sda-pins {
+ pinmux = <0x2427580a>;
+ bias-pull-up;
+ input-enable;
+ };
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-east-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-east-pinctrl.yaml
new file mode 100644
index 000000000000..6ad518e9bee2
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-east-pinctrl.yaml
@@ -0,0 +1,222 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/starfive,jh8100-sys-east-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JH8100 SYS_EAST Pin Controller
+
+description: |
+ Pinctrl bindings for JH8100 RISC-V SoC from StarFive Technology Ltd.
+
+ The JH8100 SoC has 4 pinctrl domains - sys_east, sys_west, sys_gmac, and aon.
+ This document provides an overview of the "sys_east" pinctrl domain.
+
+ The "sys_east" domain has a pin controller which provides
+ - I/O multiplexing for peripheral signals specific to this domain.
+ - function selection for GPIO pads.
+ - GPIO interrupt handling.
+ - syscon for device voltage reference.
+
+ In the SYS_EAST Pin Controller, the pins named PAD_GPIO0_E to PAD_GPIO47_E can
+ be multiplexed and have configurable bias, drive strength, schmitt trigger etc.
+ Only peripherals in the SYS_EAST domain can have their I/O go through the 48
+ "PAD_GPIOs". This includes CANs, I2Cs, I2Ss, SPIs, UARTs, PWMs, SMBUS0, SDIO1 etc.
+
+ All these peripherals can be connected to any of the 48 PAD_GPIOs in such a way
+ that any iopad can be set up to be controlled by any of the peripherals.
+
+ The pin muxing is illustrated by the diagram below.
+ __________________
+ | |
+ GPIO0 ----------------------| |--- PAD_GPIO0_E
+ GPIO1 ----------------------| SYS_EAST I/O MUX |--- PAD_GPIO1_E
+ GPIO2 ----------------------| |--- PAD_GPIO2_E
+ ... | | ...
+ I2C0 Clock interface -------| |--- PAD_GPIO9_E
+ I2C0 Data interface -------| |--- PAD_GPIO10_E
+ ... | | ...
+ UART0 transmit interface ---| |--- PAD_GPIO20_E
+ UART0 receive interface ----| |--- PAD_GPIO21_E
+ ... | | ...
+ GPIO47 ---------------------| |--- PAD_GPIO47_E
+ | |
+ ------------------
+
+ Alternatively, the "PAD_GPIOs" can be multiplexed to other peripherals through
+ function selection. Each iopad has a maximum of up to 3 functions - 0, 1, and 2.
+ Function 0 is the default function or peripheral signal of an iopad.
+ The function 1 and function 2 are other optional functions or peripheral signals
+ available to an iopad. The function selection can be carried out by writing the
+ function number to the iopad function select register.
+
+ The "sys_east" domain has 4 PAD_GPIO banks -
+ E0 - 16 PAD_GPIOs (PAD_GPIO0_E to PAD_GPIO15_E)
+ E1 - 16 PAD_GPIOs (PAD_GPIO16_E to PAD_GPIO31_E)
+ E2 - 8 PAD_GPIOs (PAD_GPIO32_E to PAD_GPIO39_E)
+ E3 - 8 PAD_GPIOs (PAD_GPIO40_E to PAD_GPIO47_E)
+
+ Each PAD_GPIO bank can be set to a voltage level 3.3V or 1.8V. All devices attached
+ to the PAD_GPIOs must use the same I/O voltage level as the bank voltage setting.
+ This allows user to select different I/O voltages for their devices. For instance,
+ the UART have 3.3V/1.8V requirement, the UART devices that use 1.8V are attached
+ to a PAD_GPIO bank which is configured to 1.8V.
+
+ Regulators supply voltages to the PAD_GPIO banks, and each PAD_GPIO bank has a corresponding
+ syscon bit [1:0] that must be configured to indicate its voltage level. The default setting
+ is 3.3V.
+
+ +--------+--------+-------------------+
+ | Bit[1] | Bit[0] | Reference Voltage |
+ +--------+--------+-------------------+
+ | 0 | 0 | 3.3 V |
+ +--------+--------+-------------------+
+ | 1 | x | 1.8 V |
+ +--------+--------+-------------------+
+
+ Under any circumstances, the syscon register's reference voltage setting must not be
+ lower than the actual device voltage, otherwise, the device I/O pads will get damaged.
+
+ Follow the guidelines below when configure reference voltage -
+
+ To increase the device voltage, set bit [1:0] to the new operating state first before
+ raising the actual voltage to the higher operating point.
+
+ To decrease the device voltage, hold bit [1:0] to the current operating state until
+ the actual voltage has stabilized at the lower operating point before changing the
+ setting.
+
+ Alternatively, a device voltage change can always be initiated by first setting syscon
+ register bit [1:0] = 0, the safe 3.3V startup condition, before changing the device
+ voltage. Then once the actual voltage is changed and has stabilized at the new operating
+ point, bit [1:0] can be reset as appropriate.
+
+maintainers:
+ - Alex Soo <yuklin.soo@starfivetech.com>
+
+properties:
+ compatible:
+ - items:
+ - const: starfive,jh8100-sys-pinctrl-east
+ - const: syscon
+ - const: simple-mfd
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ resets:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ interrupt-controller: true
+
+ gpio-controller: true
+
+ '#gpio-cells':
+ const: 2
+
+ gpio-ranges:
+ maxItems: 1
+
+ gpio-line-names: true
+
+patternProperties:
+ '-grp$':
+ type: object
+ additionalProperties: false
+ patternProperties:
+ '-pins$':
+ type: object
+ description: |
+ A pinctrl node should contain at least one subnode representing the
+ pinctrl groups available in the domain. Each subnode will list the
+ pins it needs, and how they should be configured, with regard to
+ muxer configuration, bias, input enable/disable, input schmitt
+ trigger enable/disable, slew-rate and drive strength.
+ allOf:
+ - $ref: /schemas/pinctrl/pincfg-node.yaml
+ - $ref: /schemas/pinctrl/pinmux-node.yaml
+ unevaluatedProperties: false
+
+ properties:
+ pinmux:
+ description: |
+ The list of GPIOs and their mux settings or function select.
+ The GPIOMUX and PINMUX macros are used to configure the
+ I/O multiplexing and function selection respectively.
+
+ bias-disable: true
+
+ bias-pull-up:
+ type: boolean
+
+ bias-pull-down:
+ type: boolean
+
+ drive-strength-microamp:
+ enum: [ 2000, 4000, 8000, 12000 ]
+
+ input-enable: true
+
+ input-disable: true
+
+ input-schmitt-enable: true
+
+ input-schmitt-disable: true
+
+ slew-rate:
+ enum: [ 0, 1 ]
+ default: 0
+ description: |
+ 0: slow (half frequency)
+ 1: fast
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - resets
+ - interrupts
+ - interrupt-controller
+ - gpio-controller
+ - '#gpio-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ pinctrl_east: pinctrl@122d0000 {
+ compatible = "starfive,jh8100-sys-pinctrl-east", "syscon", "simple-mfd";
+ reg = <0x0 0x122d0000 0x0 0x10000>;
+ clocks = <&syscrg_ne 153>;
+ resets = <&syscrg_ne 48>;
+ interrupts = <182>;
+ interrupt-controller;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl_east 0 0 48>;
+
+ smbus0_pins: smbus0-grp {
+ smbus0-scl-pins {
+ pinmux = <0x1122480b>;
+ bias-pull-up;
+ input-enable;
+ };
+
+ smbus0-sda-pins {
+ pinmux = <0x12234c0c>;
+ bias-pull-up;
+ input-enable;
+ };
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-gmac-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-gmac-pinctrl.yaml
new file mode 100644
index 000000000000..567ff0d9fd6c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-gmac-pinctrl.yaml
@@ -0,0 +1,162 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/starfive,jh8100-sys-gmac-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JH8100 SYS_GMAC Pin Controller
+
+description: |
+ Pinctrl bindings for JH8100 RISC-V SoC from StarFive Technology Ltd.
+
+ The JH8100 SoC has 4 pinctrl domains - sys_east, sys_west, sys_gmac, and aon.
+ This document provides an overview of the "sys_gmac" pinctrl domain.
+
+ The "sys_gmac" domain has a pin-controller which provides syscon registers to
+ configure device reference voltage and slew rate.
+
+ The SYS_GMAC Pin Controller does not have any PAD_GPIOs, therefore, it does not
+ support the GPIO pad I/O Multiplexing and interrupt handling.
+
+ The SYS_GMAC Pin Controller provides syscon registers to configure
+
+ 1. reference voltage of SDIO1
+
+ The supported voltage levels are 3.3V and 1.8V
+
+ The bit [1:0] must be configured to indicate the SDIO1 voltage level.
+
+ +--------+--------+--------------------------+
+ | Bit[1] | Bit[0] | SDIO1 Reference Voltage |
+ +--------+--------+--------------------------+
+ | 0 | 0 | 3.3 V |
+ +--------+--------+--------------------------+
+ | 1 | 0 | 1.8 V |
+ +--------+--------+--------------------------+
+
+ 2. reference voltage and slew rate of GMAC1
+
+ Voltage level on GMAC1 interface is dependent on the PHY that it is pairing with. The
+ supported voltage levels are 3.3V, 2.5V, and 1.8V.
+
+ GMAC1 has 2 set of syscon registers -
+
+ 2.1 PAD_VREF_GMAC1_syscon - bit [1:0] must be configured to indicate the voltage level on
+ GMAC1 interface. The default setting is 3.3V.
+
+ +--------+--------+-----------------------------------+
+ | Bit[1] | Bit[0] | GMAC1 Interface Reference Voltage |
+ +--------+--------+-----------------------------------+
+ | 0 | 0 | 3.3V |
+ +--------+--------+-----------------------------------+
+ | 0 | 1 | 2.5V |
+ +--------+--------+-----------------------------------+
+ | 1 | x | 1.8V |
+ +--------+--------+-----------------------------------+
+
+ 2.2 PAD_GMAC1_<SIGNAL_NAME>_syscon - each GMAC1 pad has a corresponding syscon bit [0] set
+ to 0 by default. When GMAC1 mode is RGMII and voltage level is 2.5V, the bit [0] must be
+ set to 1.
+
+ +-------------+-----------------------+---------+
+ | GMAC1 Mode | GMAC1 Voltage Level | Bit[0] |
+ +-------------+-----------------------+---------+
+ | | 3.3V | 0 |
+ | |-----------------------+---------+
+ | RGMII | 2.5V | 1 |
+ | |-----------------------+---------+
+ | | 1.8V | 0 |
+ +-------------+-----------------------+---------+
+ | | 3.3V | 0 |
+ | |-----------------------+---------+
+ | RMII | 2.5V | 0 |
+ | |-----------------------+---------+
+ | | 1.8V | 0 |
+ +-------------+-----------------------+---------+
+
+ the bit [2] can be used to configure the GMAC1 signal slew rate,
+
+ +--------+-----------+
+ | Bit[2] | Slew Rate |
+ +--------+-----------+
+ | 0 | Fast |
+ +--------+-----------+
+ | 1 | Slow |
+ +--------+-----------+
+
+ Under any circumstances, the syscon register's reference voltage setting must not be
+ lower than the actual voltage, otherwise, the device I/O pads will get damaged.
+
+ Follow the guidelines below when configure reference voltage -
+
+ To increase the device voltage, set bit [1:0] to the new operating state first before
+ raising the actual voltage to the higher operating point.
+
+ To decrease the device voltage, hold bit [1:0] to the current operating state until
+ the actual voltage has stabilized at the lower operating point before changing the
+ setting.
+
+ Alternatively, a device voltage change can always be initiated by first setting syscon
+ register bit [1:0] = 0, the safe 3.3V startup condition, before changing the device
+ voltage. Then once the actual voltage is changed and has stabilized at the new operating
+ point, bit [1:0] can be reset as appropriate.
+
+maintainers:
+ - Alex Soo <yuklin.soo@starfivetech.com>
+
+properties:
+ compatible:
+ - items:
+ - const: starfive,jh8100-sys-pinctrl-gmac
+ - const: syscon
+ - const: simple-mfd
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ resets:
+ maxItems: 1
+
+patternProperties:
+ '-grp$':
+ type: object
+ additionalProperties: false
+ patternProperties:
+ '-pins$':
+ type: object
+ description: |
+ A pinctrl node should contain at least one subnode representing the
+ pinctrl groups available in the domain. Each subnode will list the
+ pins it needs, and how they should be configured, with regard to
+ muxer configuration, bias, input enable/disable, input schmitt
+ trigger enable/disable, slew-rate and drive strength.
+ allOf:
+ - $ref: /schemas/pinctrl/pincfg-node.yaml
+ - $ref: /schemas/pinctrl/pinmux-node.yaml
+ unevaluatedProperties: false
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - resets
+
+additionalProperties: false
+
+examples:
+ - |
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ pinctrl_gmac: pinctrl@12770000 {
+ compatible = "starfive,jh8100-sys-pinctrl-gmac", "syscon", "simple-mfd";
+ reg = <0x0 0x12770000 0x0 0x10000>;
+ clocks = <&gmac_sdio_crg 16>;
+ resets = <&gmac_sdio_crg 3>;
+ };
+
+ };
diff --git a/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-west-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-west-pinctrl.yaml
new file mode 100644
index 000000000000..ecff5656ecc3
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-west-pinctrl.yaml
@@ -0,0 +1,219 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/starfive,jh8100-sys-west-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JH8100 SYS_WEST Pin Controller
+
+description: |
+ Pinctrl bindings for JH8100 RISC-V SoC from StarFive Technology Ltd.
+
+ The JH8100 SoC has 4 pinctrl domains - sys_east, sys_west, sys_gmac, and aon.
+ This document provides an overview of the "sys_west" pinctrl domain.
+
+ The "sys_west" domain has a pin-controller which provides
+ - I/O multiplexing for peripheral signals specific to this domain.
+ - function selection for GPIO pads.
+ - GPIO interrupt handling.
+ - syscon for device voltage reference.
+
+ In the SYS_WEST Pin Controller, the pins named PAD_GPIO0_W to PAD_GPIO15_W can
+ be multiplexed and have configurable bias, drive strength, schmitt trigger etc.
+ Only peripherals in the SYS_WEST domain can have their I/O go through the 16
+ "PAD_GPIOs". This includes I2Cs, HD_AUDIO, HIFI4, SPIs, UARTs, SMBUS1 etc.
+
+ All these peripherals can be connected to any of the 16 PAD_GPIOs in such a way
+ that any iopad can be set up to be controlled by any of the peripherals.
+
+ The pin muxing is illustrated by the diagram below.
+ __________________
+ | |
+ GPIO0 ----------------------| |--- PAD_GPIO0_W
+ GPIO1 ----------------------| SYS_WEST I/O MUX |--- PAD_GPIO1_W
+ GPIO2 ----------------------| |--- PAD_GPIO2_W
+ ... | | ...
+ HIFI4 JTAG TDO interface ---| |--- PAD_GPIO10_W
+ HIFI4 JTAG TDI interface ---| |--- PAD_GPIO11_W
+ SMBUS1 Data interface -----| |--- PAD_GPIO12_W
+ SMBUS1 Clock interface -----| |--- PAD_GPIO13_W
+ ... | | ...
+ GPIO14 ---------------------| |--- PAD_GPIO14_W
+ GPIO15 ---------------------| |--- PAD_GPIO15_W
+ | |
+ ------------------
+
+ Alternatively, the "PAD_GPIOs" can be multiplexed to other peripherals through
+ function selection. Each iopad has a maximum of up to 3 functions - 0, 1, and 2.
+ Function 0 is the default function or peripheral signal of an iopad.
+ The function 1 and function 2 are other optional functions or peripheral signals
+ available to an iopad. The function selection can be carried out by writing the
+ function number to the iopad function select register.
+
+ The "sys_west" domain has one PAD_GPIO bank -
+ W0 - 16 PAD_GPIOs (PAD_GPIO0_W to PAD_GPIO15_W)
+
+ The PAD_GPIO bank can be set to voltage level 3.3V or 1.8V. All devices attached
+ to the PAD_GPIOs must use the same I/O voltage level as the bank voltage setting.
+ This allows user to select different I/O voltages for their devices. For instance,
+ the UART have 3.3V/1.8V requirement, the UART devices that use 1.8V are attached
+ to a PAD_GPIO bank which is configured to 1.8V.
+
+ Regulator supplies voltage to the PAD_GPIO bank, and the PAD_GPIO bank has a
+ corresponding syscon bit [1:0] that must be configured to indicate its voltage
+ level. The default voltage setting of each PAD_GPIO bank is 3.3V.
+
+ +--------+--------+-------------------+
+ | Bit[1] | Bit[0] | Reference Voltage |
+ +--------+--------+-------------------+
+ | 0 | 0 | 3.3 V |
+ +--------+--------+-------------------+
+ | 1 | x | 1.8 V |
+ +--------+--------+-------------------+
+
+ Under any circumstances, the syscon register's reference voltage setting must not be
+ lower than the actual device voltage, otherwise, the device I/O pads will get damaged.
+
+ Follow the guidelines below when configure reference voltage -
+
+ To increase the device voltage, set bit [1:0] to the new operating state first before
+ raising the actual voltage to the higher operating point.
+
+ To decrease the device voltage, hold bit [1:0] to the current operating state until
+ the actual voltage has stabilized at the lower operating point before changing the
+ setting.
+
+ Alternatively, a device voltage change can always be initiated by first setting syscon
+ register bit [1:0] = 0, the safe 3.3V startup condition, before changing the device
+ voltage. Then once the actual voltage is changed and has stabilized at the new operating
+ point, bit [1:0] can be reset as appropriate.
+
+maintainers:
+ - Alex Soo <yuklin.soo@starfivetech.com>
+
+properties:
+ compatible:
+ - items:
+ - const: starfive,jh8100-sys-pinctrl-west
+ - const: syscon
+ - const: simple-mfd
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ resets:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ interrupt-controller: true
+
+ gpio-controller: true
+
+ '#gpio-cells':
+ const: 2
+
+ gpio-ranges:
+ maxItems: 1
+
+ gpio-line-names: true
+
+patternProperties:
+ '-grp$':
+ type: object
+ additionalProperties: false
+ patternProperties:
+ '-pins$':
+ type: object
+ description: |
+ A pinctrl node should contain at least one subnode representing the
+ pinctrl groups available in the domain. Each subnode will list the
+ pins it needs, and how they should be configured, with regard to
+ muxer configuration, bias, input enable/disable, input schmitt
+ trigger enable/disable, slew-rate and drive strength.
+ allOf:
+ - $ref: /schemas/pinctrl/pincfg-node.yaml
+ - $ref: /schemas/pinctrl/pinmux-node.yaml
+ unevaluatedProperties: false
+
+ properties:
+ pinmux:
+ description: |
+ The list of GPIOs and their mux settings or function select.
+ The GPIOMUX and PINMUX macros are used to configure the
+ I/O multiplexing and function selection respectively.
+
+ bias-disable: true
+
+ bias-pull-up:
+ type: boolean
+
+ bias-pull-down:
+ type: boolean
+
+ drive-strength-microamp:
+ enum: [ 2000, 4000, 8000, 12000 ]
+
+ input-enable: true
+
+ input-disable: true
+
+ input-schmitt-enable: true
+
+ input-schmitt-disable: true
+
+ slew-rate:
+ enum: [ 0, 1 ]
+ default: 0
+ description: |
+ 0: slow (half frequency)
+ 1: fast
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - resets
+ - interrupts
+ - interrupt-controller
+ - gpio-controller
+ - '#gpio-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ pinctrl_west: pinctrl@123e0000 {
+ compatible = "starfive,jh8100-sys-pinctrl-west", "syscon", "simple-mfd";
+ reg = <0x0 0x123e0000 0x0 0x10000>;
+ clocks = <&syscrg_nw 6>;
+ resets = <&syscrg_nw 1>;
+ interrupts = <183>;
+ interrupt-controller;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl_west 0 0 16>;
+
+ smbus1_pins: smbus1-grp {
+ smbus1-scl-pins {
+ pinmux = <0x1014300d>;
+ bias-pull-up;
+ input-enable;
+ };
+
+ smbus1-sda-pins {
+ pinmux = <0x1115340c>;
+ bias-pull-up;
+ input-enable;
+ };
+ };
+ };
+ };
diff --git a/include/dt-bindings/pinctrl/starfive,jh8100-pinctrl.h b/include/dt-bindings/pinctrl/starfive,jh8100-pinctrl.h
new file mode 100644
index 000000000000..153ba950c062
--- /dev/null
+++ b/include/dt-bindings/pinctrl/starfive,jh8100-pinctrl.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright (C) 2023-2024 StarFive Technology Co., Ltd.
+ */
+
+#ifndef __DT_BINDINGS_PINCTRL_STARFIVE_JH8100_H__
+#define __DT_BINDINGS_PINCTRL_STARFIVE_JH8100_H__
+
+/* Pad Slew Rates */
+#define PAD_SLEW_RATE_FAST 1
+#define PAD_SLEW_RATE_SLOW 0
+
+#endif
--
2.25.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [RFC PATCH v3 1/7] dt-bindings: pinctrl: starfive: Add JH8100 pinctrl
2024-05-03 11:14 ` [RFC PATCH v3 1/7] dt-bindings: pinctrl: starfive: Add JH8100 pinctrl Alex Soo
@ 2024-05-03 13:34 ` Rob Herring (Arm)
2024-05-03 16:07 ` Conor Dooley
1 sibling, 0 replies; 18+ messages in thread
From: Rob Herring (Arm) @ 2024-05-03 13:34 UTC (permalink / raw)
To: Alex Soo
Cc: Linus Walleij, Palmer Dabbelt, linux-gpio, linux-kernel,
Drew Fustini, linux-riscv, devicetree, Bartosz Golaszewski,
Ley Foon Tan, Jianlong Huang, Conor Dooley, Paul Walmsley,
Albert Ou, Krzysztof Kozlowski, Hal Feng, Emil Renner Berthing
On Fri, 03 May 2024 19:14:30 +0800, Alex Soo wrote:
> Add documentation and header file for JH8100 pinctrl driver.
>
> Signed-off-by: Alex Soo <yuklin.soo@starfivetech.com>
> ---
> .../pinctrl/starfive,jh8100-aon-pinctrl.yaml | 260 ++++++++++++++++++
> .../starfive,jh8100-sys-east-pinctrl.yaml | 222 +++++++++++++++
> .../starfive,jh8100-sys-gmac-pinctrl.yaml | 162 +++++++++++
> .../starfive,jh8100-sys-west-pinctrl.yaml | 219 +++++++++++++++
> .../pinctrl/starfive,jh8100-pinctrl.h | 13 +
> 5 files changed, 876 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/pinctrl/starfive,jh8100-aon-pinctrl.yaml
> create mode 100644 Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-east-pinctrl.yaml
> create mode 100644 Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-gmac-pinctrl.yaml
> create mode 100644 Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-west-pinctrl.yaml
> create mode 100644 include/dt-bindings/pinctrl/starfive,jh8100-pinctrl.h
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
./Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-gmac-pinctrl.yaml:109:7: [warning] wrong indentation: expected 4 but found 6 (indentation)
./Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-west-pinctrl.yaml:96:7: [warning] wrong indentation: expected 4 but found 6 (indentation)
./Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-east-pinctrl.yaml:99:7: [warning] wrong indentation: expected 4 but found 6 (indentation)
./Documentation/devicetree/bindings/pinctrl/starfive,jh8100-aon-pinctrl.yaml:136:7: [warning] wrong indentation: expected 4 but found 6 (indentation)
dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-gmac-pinctrl.yaml: properties:compatible: [{'items': [{'const': 'starfive,jh8100-sys-pinctrl-gmac'}, {'const': 'syscon'}, {'const': 'simple-mfd'}]}] is not of type 'object', 'boolean'
from schema $id: http://json-schema.org/draft-07/schema#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-gmac-pinctrl.yaml: properties:compatible: [{'items': [{'const': 'starfive,jh8100-sys-pinctrl-gmac'}, {'const': 'syscon'}, {'const': 'simple-mfd'}]}] is not of type 'object', 'boolean'
from schema $id: http://devicetree.org/meta-schemas/keywords.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-west-pinctrl.yaml: properties:compatible: [{'items': [{'const': 'starfive,jh8100-sys-pinctrl-west'}, {'const': 'syscon'}, {'const': 'simple-mfd'}]}] is not of type 'object', 'boolean'
from schema $id: http://json-schema.org/draft-07/schema#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-west-pinctrl.yaml: properties:compatible: [{'items': [{'const': 'starfive,jh8100-sys-pinctrl-west'}, {'const': 'syscon'}, {'const': 'simple-mfd'}]}] is not of type 'object', 'boolean'
from schema $id: http://devicetree.org/meta-schemas/keywords.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-east-pinctrl.yaml: properties:compatible: [{'items': [{'const': 'starfive,jh8100-sys-pinctrl-east'}, {'const': 'syscon'}, {'const': 'simple-mfd'}]}] is not of type 'object', 'boolean'
from schema $id: http://json-schema.org/draft-07/schema#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-east-pinctrl.yaml: properties:compatible: [{'items': [{'const': 'starfive,jh8100-sys-pinctrl-east'}, {'const': 'syscon'}, {'const': 'simple-mfd'}]}] is not of type 'object', 'boolean'
from schema $id: http://devicetree.org/meta-schemas/keywords.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-aon-pinctrl.yaml: properties:compatible: [{'items': [{'const': 'starfive,jh8100-aon-pinctrl'}, {'const': 'syscon'}, {'const': 'simple-mfd'}]}] is not of type 'object', 'boolean'
from schema $id: http://json-schema.org/draft-07/schema#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-aon-pinctrl.yaml: properties:compatible: [{'items': [{'const': 'starfive,jh8100-aon-pinctrl'}, {'const': 'syscon'}, {'const': 'simple-mfd'}]}] is not of type 'object', 'boolean'
from schema $id: http://devicetree.org/meta-schemas/keywords.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-gmac-pinctrl.yaml: ignoring, error in schema: properties: compatible
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-west-pinctrl.yaml: ignoring, error in schema: properties: compatible
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-east-pinctrl.yaml: ignoring, error in schema: properties: compatible
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/pinctrl/starfive,jh8100-aon-pinctrl.yaml: ignoring, error in schema: properties: compatible
Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-west-pinctrl.example.dtb: /example-0/soc/pinctrl@123e0000: failed to match any schema with compatible: ['starfive,jh8100-sys-pinctrl-west', 'syscon', 'simple-mfd']
Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-gmac-pinctrl.example.dtb: /example-0/soc/pinctrl@12770000: failed to match any schema with compatible: ['starfive,jh8100-sys-pinctrl-gmac', 'syscon', 'simple-mfd']
Documentation/devicetree/bindings/pinctrl/starfive,jh8100-sys-east-pinctrl.example.dtb: /example-0/soc/pinctrl@122d0000: failed to match any schema with compatible: ['starfive,jh8100-sys-pinctrl-east', 'syscon', 'simple-mfd']
Documentation/devicetree/bindings/pinctrl/starfive,jh8100-aon-pinctrl.example.dtb: /example-0/soc/pinctrl@1f300000: failed to match any schema with compatible: ['starfive,jh8100-aon-pinctrl', 'syscon', 'simple-mfd']
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240503111436.113089-2-yuklin.soo@starfivetech.com
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [RFC PATCH v3 1/7] dt-bindings: pinctrl: starfive: Add JH8100 pinctrl
2024-05-03 11:14 ` [RFC PATCH v3 1/7] dt-bindings: pinctrl: starfive: Add JH8100 pinctrl Alex Soo
2024-05-03 13:34 ` Rob Herring (Arm)
@ 2024-05-03 16:07 ` Conor Dooley
2024-05-09 2:24 ` Yuklin Soo
1 sibling, 1 reply; 18+ messages in thread
From: Conor Dooley @ 2024-05-03 16:07 UTC (permalink / raw)
To: Alex Soo
Cc: Linus Walleij, Bartosz Golaszewski, Hal Feng, Ley Foon Tan,
Jianlong Huang, Emil Renner Berthing, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Drew Fustini, linux-gpio,
linux-kernel, devicetree, linux-riscv, Paul Walmsley,
Palmer Dabbelt, Albert Ou
[-- Attachment #1: Type: text/plain, Size: 1164 bytes --]
On Fri, May 03, 2024 at 07:14:30PM +0800, Alex Soo wrote:
> Add documentation and header file for JH8100 pinctrl driver.
>
> Signed-off-by: Alex Soo <yuklin.soo@starfivetech.com>
> diff --git a/include/dt-bindings/pinctrl/starfive,jh8100-pinctrl.h b/include/dt-bindings/pinctrl/starfive,jh8100-pinctrl.h
> new file mode 100644
> index 000000000000..153ba950c062
> --- /dev/null
> +++ b/include/dt-bindings/pinctrl/starfive,jh8100-pinctrl.h
> @@ -0,0 +1,13 @@
> +/* SPDX-License-Identifier: GPL-2.0 OR MIT */
> +/*
> + * Copyright (C) 2023-2024 StarFive Technology Co., Ltd.
> + */
> +
> +#ifndef __DT_BINDINGS_PINCTRL_STARFIVE_JH8100_H__
> +#define __DT_BINDINGS_PINCTRL_STARFIVE_JH8100_H__
> +
> +/* Pad Slew Rates */
> +#define PAD_SLEW_RATE_FAST 1
> +#define PAD_SLEW_RATE_SLOW 0
Should this really be in the bindings? I don't see it having a direct
user in the driver.
Also, if this is the only header you have, I think the RFC tag could be
dropped, since there'll not be a header we need to worry about getting
into U-Boot etc with values that may change when the SoC moves from an
FPGA etc to tape out.
Cheers,
Conor.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* RE: [RFC PATCH v3 1/7] dt-bindings: pinctrl: starfive: Add JH8100 pinctrl
2024-05-03 16:07 ` Conor Dooley
@ 2024-05-09 2:24 ` Yuklin Soo
0 siblings, 0 replies; 18+ messages in thread
From: Yuklin Soo @ 2024-05-09 2:24 UTC (permalink / raw)
To: Conor Dooley
Cc: Linus Walleij, Bartosz Golaszewski, Hal Feng, Leyfoon Tan,
Jianlong Huang, Emil Renner Berthing, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Drew Fustini,
linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org, linux-riscv@lists.infradead.org,
Paul Walmsley, Palmer Dabbelt, Albert Ou
> -----Original Message-----
> From: Conor Dooley <conor@kernel.org>
> Sent: Saturday, May 4, 2024 12:07 AM
> To: Yuklin Soo <yuklin.soo@starfivetech.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>; Bartosz Golaszewski
> <bartosz.golaszewski@linaro.org>; Hal Feng <hal.feng@starfivetech.com>;
> Leyfoon Tan <leyfoon.tan@starfivetech.com>; Jianlong Huang
> <jianlong.huang@starfivetech.com>; Emil Renner Berthing <kernel@esmil.dk>;
> Rob Herring <robh@kernel.org>; Krzysztof Kozlowski
> <krzysztof.kozlowski+dt@linaro.org>; Conor Dooley <conor+dt@kernel.org>;
> Drew Fustini <drew@beagleboard.org>; linux-gpio@vger.kernel.org; linux-
> kernel@vger.kernel.org; devicetree@vger.kernel.org; linux-
> riscv@lists.infradead.org; Paul Walmsley <paul.walmsley@sifive.com>; Palmer
> Dabbelt <palmer@dabbelt.com>; Albert Ou <aou@eecs.berkeley.edu>
> Subject: Re: [RFC PATCH v3 1/7] dt-bindings: pinctrl: starfive: Add JH8100 pinctrl
>
> On Fri, May 03, 2024 at 07:14:30PM +0800, Alex Soo wrote:
> > Add documentation and header file for JH8100 pinctrl driver.
> >
> > Signed-off-by: Alex Soo <yuklin.soo@starfivetech.com>
>
> > diff --git a/include/dt-bindings/pinctrl/starfive,jh8100-pinctrl.h
> > b/include/dt-bindings/pinctrl/starfive,jh8100-pinctrl.h
> > new file mode 100644
> > index 000000000000..153ba950c062
> > --- /dev/null
> > +++ b/include/dt-bindings/pinctrl/starfive,jh8100-pinctrl.h
> > @@ -0,0 +1,13 @@
> > +/* SPDX-License-Identifier: GPL-2.0 OR MIT */
> > +/*
> > + * Copyright (C) 2023-2024 StarFive Technology Co., Ltd.
> > + */
> > +
> > +#ifndef __DT_BINDINGS_PINCTRL_STARFIVE_JH8100_H__
> > +#define __DT_BINDINGS_PINCTRL_STARFIVE_JH8100_H__
> > +
> > +/* Pad Slew Rates */
> > +#define PAD_SLEW_RATE_FAST 1
> > +#define PAD_SLEW_RATE_SLOW 0
>
> Should this really be in the bindings? I don't see it having a direct user in the
> driver.
>
> Also, if this is the only header you have, I think the RFC tag could be dropped,
> since there'll not be a header we need to worry about getting into U-Boot etc
> with values that may change when the SoC moves from an FPGA etc to tape out.
I will drop the PAD_SLEW_RATE_* macros from dt-bindings header and move them
to the DTS header file. Will submit the next version (V4) without the "RFC PATCH"
subject prefix.
>
> Cheers,
> Conor.
^ permalink raw reply [flat|nested] 18+ messages in thread
* [RFC PATCH v3 2/7] pinctrl: starfive: jh8100: add main driver and sys_east domain sub-driver
2024-05-03 11:14 [RFC PATCH v3 0/7] Add Pinctrl driver for Starfive JH8100 SoC Alex Soo
2024-05-03 11:14 ` [RFC PATCH v3 1/7] dt-bindings: pinctrl: starfive: Add JH8100 pinctrl Alex Soo
@ 2024-05-03 11:14 ` Alex Soo
2024-05-06 20:15 ` Andy Shevchenko
2024-05-03 11:14 ` [RFC PATCH v3 3/7] pinctrl: starfive: jh8100: add sys_west " Alex Soo
` (6 subsequent siblings)
8 siblings, 1 reply; 18+ messages in thread
From: Alex Soo @ 2024-05-03 11:14 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Hal Feng, Ley Foon Tan,
Jianlong Huang, Emil Renner Berthing, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Drew Fustini
Cc: linux-gpio, linux-kernel, devicetree, linux-riscv, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alex Soo
Add Starfive JH8100 SoC pinctrl main driver to provide the
common APIs that are used by the sub-drivers of pinctrl
domains:
- sys_east,
- sys_west,
- sys_gmac,
- aon (always-on)
to implement the following tasks:
- applies pin multiplexing, function selection, and pin
configuration for devices during system initialization
or change of pinctrl state due to power management.
- read or set pin configuration from user space.
Also, add the sys_east domain sub-driver since it requires
at least one domain sub-driver to run the probe function in
the main driver to enable the basic pinctrl functionalities
on the system.
Signed-off-by: Alex Soo <yuklin.soo@starfivetech.com>
---
drivers/pinctrl/starfive/Kconfig | 21 +
drivers/pinctrl/starfive/Makefile | 3 +
.../pinctrl-starfive-jh8100-sys-east.c | 220 ++++
.../starfive/pinctrl-starfive-jh8100.c | 1094 +++++++++++++++++
.../starfive/pinctrl-starfive-jh8100.h | 111 ++
5 files changed, 1449 insertions(+)
create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh8100-sys-east.c
create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh8100.c
create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh8100.h
diff --git a/drivers/pinctrl/starfive/Kconfig b/drivers/pinctrl/starfive/Kconfig
index 8192ac2087fc..afcbf9d4dc8d 100644
--- a/drivers/pinctrl/starfive/Kconfig
+++ b/drivers/pinctrl/starfive/Kconfig
@@ -49,3 +49,24 @@ config PINCTRL_STARFIVE_JH7110_AON
This also provides an interface to the GPIO pins not used by other
peripherals supporting inputs, outputs, configuring pull-up/pull-down
and interrupts on input changes.
+
+config PINCTRL_STARFIVE_JH8100
+ bool
+ select GENERIC_PINCONF
+ select GENERIC_PINCTRL_GROUPS
+ select GENERIC_PINMUX_FUNCTIONS
+ select GPIOLIB
+ select GPIOLIB_IRQCHIP
+ select OF_GPIO
+
+config PINCTRL_STARFIVE_JH8100_SYS_EAST
+ tristate "StarFive JH8100 SoC System IOMUX-East pinctrl and GPIO driver"
+ depends on ARCH_STARFIVE || COMPILE_TEST
+ depends on OF
+ select PINCTRL_STARFIVE_JH8100
+ default ARCH_STARFIVE
+ help
+ Say yes here to support system iomux-east pin control on the StarFive JH8100 SoC.
+ This also provides an interface to the GPIO pins not used by other
+ peripherals supporting inputs, outputs, configuring pull-up/pull-down
+ and interrupts on input changes.
diff --git a/drivers/pinctrl/starfive/Makefile b/drivers/pinctrl/starfive/Makefile
index ee0d32d085cb..45698c502b48 100644
--- a/drivers/pinctrl/starfive/Makefile
+++ b/drivers/pinctrl/starfive/Makefile
@@ -5,3 +5,6 @@ obj-$(CONFIG_PINCTRL_STARFIVE_JH7100) += pinctrl-starfive-jh7100.o
obj-$(CONFIG_PINCTRL_STARFIVE_JH7110) += pinctrl-starfive-jh7110.o
obj-$(CONFIG_PINCTRL_STARFIVE_JH7110_SYS) += pinctrl-starfive-jh7110-sys.o
obj-$(CONFIG_PINCTRL_STARFIVE_JH7110_AON) += pinctrl-starfive-jh7110-aon.o
+
+obj-$(CONFIG_PINCTRL_STARFIVE_JH8100) += pinctrl-starfive-jh8100.o
+obj-$(CONFIG_PINCTRL_STARFIVE_JH8100_SYS_EAST) += pinctrl-starfive-jh8100-sys-east.o
diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh8100-sys-east.c b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100-sys-east.c
new file mode 100644
index 000000000000..45ade4d68d66
--- /dev/null
+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100-sys-east.c
@@ -0,0 +1,220 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Pinctrl / GPIO driver for StarFive JH8100 SoC sys east controller
+ *
+ * Copyright (C) 2023-2024 StarFive Technology Co., Ltd.
+ * Author: Alex Soo <yuklin.soo@starfivetech.com>
+ *
+ */
+
+#include <linux/gpio/driver.h>
+#include <linux/module.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include <dt-bindings/pinctrl/starfive,jh8100-pinctrl.h>
+
+#include "pinctrl-starfive-jh8100.h"
+
+#define JH8100_SYS_E_GC_BASE 16
+
+/* registers */
+#define JH8100_SYS_E_DOEN 0x000
+#define JH8100_SYS_E_DOUT 0x030
+#define JH8100_SYS_E_GPI 0x060
+#define JH8100_SYS_E_GPIOIN 0x0f4
+
+#define JH8100_SYS_E_GPIOEN 0x0b8
+#define JH8100_SYS_E_GPIOIS0 0x0bc
+#define JH8100_SYS_E_GPIOIS1 0x0c0
+#define JH8100_SYS_E_GPIOIC0 0x0c4
+#define JH8100_SYS_E_GPIOIC1 0x0c8
+#define JH8100_SYS_E_GPIOIBE0 0x0cc
+#define JH8100_SYS_E_GPIOIBE1 0x0d0
+#define JH8100_SYS_E_GPIOIEV0 0x0d4
+#define JH8100_SYS_E_GPIOIEV1 0x0d8
+#define JH8100_SYS_E_GPIOIE0 0x0dc
+#define JH8100_SYS_E_GPIOIE1 0x0e0
+#define JH8100_SYS_E_GPIORIS0 0x0e4
+#define JH8100_SYS_E_GPIORIS1 0x0e8
+#define JH8100_SYS_E_GPIOMIS0 0x0ec
+#define JH8100_SYS_E_GPIOMIS1 0x0f0
+
+static const struct pinctrl_pin_desc jh8100_sys_e_pins[] = {
+ PINCTRL_PIN(0, "SYS_E_GPIO0"),
+ PINCTRL_PIN(1, "SYS_E_GPIO1"),
+ PINCTRL_PIN(2, "SYS_E_GPIO2"),
+ PINCTRL_PIN(3, "SYS_E_GPIO3"),
+ PINCTRL_PIN(4, "SYS_E_GPIO4"),
+ PINCTRL_PIN(5, "SYS_E_GPIO5"),
+ PINCTRL_PIN(6, "SYS_E_GPIO6"),
+ PINCTRL_PIN(7, "SYS_E_GPIO7"),
+ PINCTRL_PIN(8, "SYS_E_GPIO8"),
+ PINCTRL_PIN(9, "SYS_E_GPIO9"),
+ PINCTRL_PIN(10, "SYS_E_GPIO10"),
+ PINCTRL_PIN(11, "SYS_E_GPIO11"),
+ PINCTRL_PIN(12, "SYS_E_GPIO12"),
+ PINCTRL_PIN(13, "SYS_E_GPIO13"),
+ PINCTRL_PIN(14, "SYS_E_GPIO14"),
+ PINCTRL_PIN(15, "SYS_E_GPIO15"),
+ PINCTRL_PIN(16, "SYS_E_GPIO16"),
+ PINCTRL_PIN(17, "SYS_E_GPIO17"),
+ PINCTRL_PIN(18, "SYS_E_GPIO18"),
+ PINCTRL_PIN(19, "SYS_E_GPIO19"),
+ PINCTRL_PIN(20, "SYS_E_GPIO20"),
+ PINCTRL_PIN(21, "SYS_E_GPIO21"),
+ PINCTRL_PIN(22, "SYS_E_GPIO22"),
+ PINCTRL_PIN(23, "SYS_E_GPIO23"),
+ PINCTRL_PIN(24, "SYS_E_GPIO24"),
+ PINCTRL_PIN(25, "SYS_E_GPIO25"),
+ PINCTRL_PIN(26, "SYS_E_GPIO26"),
+ PINCTRL_PIN(27, "SYS_E_GPIO27"),
+ PINCTRL_PIN(28, "SYS_E_GPIO28"),
+ PINCTRL_PIN(29, "SYS_E_GPIO29"),
+ PINCTRL_PIN(30, "SYS_E_GPIO30"),
+ PINCTRL_PIN(31, "SYS_E_GPIO31"),
+ PINCTRL_PIN(32, "SYS_E_GPIO32"),
+ PINCTRL_PIN(33, "SYS_E_GPIO33"),
+ PINCTRL_PIN(34, "SYS_E_GPIO34"),
+ PINCTRL_PIN(35, "SYS_E_GPIO35"),
+ PINCTRL_PIN(36, "SYS_E_GPIO36"),
+ PINCTRL_PIN(37, "SYS_E_GPIO37"),
+ PINCTRL_PIN(38, "SYS_E_GPIO38"),
+ PINCTRL_PIN(39, "SYS_E_GPIO39"),
+ PINCTRL_PIN(40, "SYS_E_GPIO40"),
+ PINCTRL_PIN(41, "SYS_E_GPIO41"),
+ PINCTRL_PIN(42, "SYS_E_GPIO42"),
+ PINCTRL_PIN(43, "SYS_E_GPIO43"),
+ PINCTRL_PIN(44, "SYS_E_GPIO44"),
+ PINCTRL_PIN(45, "SYS_E_GPIO45"),
+ PINCTRL_PIN(46, "SYS_E_GPIO46"),
+ PINCTRL_PIN(47, "SYS_E_GPIO47"),
+};
+
+static const struct jh8100_gpio_func_sel
+ jh8100_sys_e_func_sel[ARRAY_SIZE(jh8100_sys_e_pins)] = {
+ [20] = { 0x1d4, 0, 2 },
+ [21] = { 0x1d4, 2, 2 },
+ [22] = { 0x1d4, 4, 2 },
+ [23] = { 0x1d4, 6, 2 },
+ [24] = { 0x1d4, 8, 2 },
+ [25] = { 0x1d4, 10, 2 },
+ [26] = { 0x1d4, 12, 2 },
+ [27] = { 0x1d4, 14, 2 },
+ [28] = { 0x1d4, 16, 2 },
+ [29] = { 0x1d4, 18, 2 },
+ [30] = { 0x1d4, 20, 2 },
+ [31] = { 0x1d4, 22, 2 },
+ [32] = { 0x1d4, 24, 2 },
+ [33] = { 0x1d4, 26, 2 },
+ [34] = { 0x1d4, 28, 2 },
+ [35] = { 0x1d4, 30, 2 },
+
+ [36] = { 0x1d8, 0, 2 },
+ [37] = { 0x1d8, 2, 2 },
+ [38] = { 0x1d8, 4, 2 },
+ [39] = { 0x1d8, 6, 2 },
+ [40] = { 0x1d8, 8, 2 },
+ [41] = { 0x1d8, 10, 2 },
+ [42] = { 0x1d8, 12, 2 },
+ [43] = { 0x1d8, 14, 2 },
+ [44] = { 0x1d8, 16, 2 },
+ [45] = { 0x1d8, 18, 2 },
+ [46] = { 0x1d8, 20, 2 },
+ [47] = { 0x1d8, 22, 2 },
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int jh8100_sys_e_pinctrl_suspend(struct device *dev)
+{
+ struct jh8100_pinctrl *sfp;
+ int i;
+
+ sfp = dev_get_drvdata(dev);
+ if (!sfp)
+ return -EINVAL;
+
+ for (i = 0; i < sfp->info->nregs; i++)
+ sfp->jh8100_sys_east_regs[i] = readl_relaxed(sfp->base + (i * 4));
+
+ return pinctrl_force_sleep(sfp->pctl);
+}
+
+static int jh8100_sys_e_pinctrl_resume(struct device *dev)
+{
+ struct jh8100_pinctrl *sfp;
+ int i;
+
+ sfp = dev_get_drvdata(dev);
+ if (!sfp)
+ return -EINVAL;
+
+ for (i = 0; i < sfp->info->nregs; i++)
+ writel_relaxed(sfp->jh8100_sys_east_regs[i], sfp->base + (i * 4));
+
+ return pinctrl_force_default(sfp->pctl);
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(jh8100_sys_e_pinctrl_dev_pm_ops,
+ jh8100_sys_e_pinctrl_suspend,
+ jh8100_sys_e_pinctrl_resume);
+
+static const struct jh8100_gpio_irq_reg jh8100_sys_e_irq_reg = {
+ .is_reg_base = JH8100_SYS_E_GPIOIS0,
+ .ic_reg_base = JH8100_SYS_E_GPIOIC0,
+ .ic1_reg_base = JH8100_SYS_E_GPIOIC1,
+ .ibe_reg_base = JH8100_SYS_E_GPIOIBE0,
+ .iev_reg_base = JH8100_SYS_E_GPIOIEV0,
+ .ie_reg_base = JH8100_SYS_E_GPIOIE0,
+ .ris_reg_base = JH8100_SYS_E_GPIORIS0,
+ .mis_reg_base = JH8100_SYS_E_GPIOMIS0,
+ .mis1_reg_base = JH8100_SYS_E_GPIOMIS1,
+ .ien_reg_base = JH8100_SYS_E_GPIOEN,
+};
+
+static const struct jh8100_pinctrl_domain_info jh8100_sys_e_pinctrl_info = {
+ .pins = jh8100_sys_e_pins,
+ .npins = ARRAY_SIZE(jh8100_sys_e_pins),
+ .ngpios = JH8100_SYS_E_NGPIO,
+ .gc_base = JH8100_SYS_E_GC_BASE,
+ .name = JH8100_SYS_E_DOMAIN_NAME,
+ .nregs = JH8100_SYS_E_REG_NUM,
+ .dout_reg_base = JH8100_SYS_E_DOUT,
+ .dout_mask = GENMASK(6, 0),
+ .doen_reg_base = JH8100_SYS_E_DOEN,
+ .doen_mask = GENMASK(5, 0),
+ .gpi_reg_base = JH8100_SYS_E_GPI,
+ .gpi_mask = GENMASK(5, 0),
+ .gpioin_reg_base = JH8100_SYS_E_GPIOIN,
+ .func_sel = jh8100_sys_e_func_sel,
+ .irq_reg = &jh8100_sys_e_irq_reg,
+ .mis_pin_num = 32,
+ .mis1_pin_num = 16,
+};
+
+static const struct of_device_id jh8100_sys_e_pinctrl_of_match[] = {
+ {
+ .compatible = "starfive,jh8100-sys-pinctrl-east",
+ .data = &jh8100_sys_e_pinctrl_info,
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, jh8100_sys_e_pinctrl_of_match);
+
+static struct platform_driver jh8100_sys_e_pinctrl_driver = {
+ .probe = jh8100_pinctrl_probe,
+ .driver = {
+ .name = "starfive-jh8100-sys-pinctrl-east",
+#ifdef CONFIG_PM_SLEEP
+ .pm = &jh8100_sys_e_pinctrl_dev_pm_ops,
+#endif
+ .of_match_table = jh8100_sys_e_pinctrl_of_match,
+ },
+};
+module_platform_driver(jh8100_sys_e_pinctrl_driver);
+
+MODULE_DESCRIPTION("Pinctrl driver for StarFive JH8100 SoC sys east controller");
+MODULE_AUTHOR("Alex Soo <yuklin.soo@starfivetech.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.c b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.c
new file mode 100644
index 000000000000..4b68463ff5a5
--- /dev/null
+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.c
@@ -0,0 +1,1094 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Pinctrl / GPIO driver for StarFive JH8100 SoC
+ *
+ * Copyright (C) 2023-2024 StarFive Technology Co., Ltd.
+ * Author: Alex Soo <yuklin.soo@starfivetech.com>
+ *
+ */
+
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/pm_wakeirq.h>
+#include <linux/reset.h>
+#include <linux/seq_file.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+
+#include <dt-bindings/pinctrl/starfive,jh8100-pinctrl.h>
+
+#include "pinctrl-starfive-jh8100.h"
+
+/* pad control bits */
+#define JH8100_PADCFG_POS BIT(7)
+#define JH8100_PADCFG_SMT BIT(6)
+#define JH8100_PADCFG_SLEW BIT(5)
+#define JH8100_PADCFG_PD BIT(4)
+#define JH8100_PADCFG_PU BIT(3)
+#define JH8100_PADCFG_BIAS_MASK (JH8100_PADCFG_PD | JH8100_PADCFG_PU)
+#define JH8100_PADCFG_DS_MASK GENMASK(2, 1)
+#define JH8100_PADCFG_DS_2MA (0U << 1)
+#define JH8100_PADCFG_DS_4MA (1U << 1)
+#define JH8100_PADCFG_DS_8MA (2U << 1)
+#define JH8100_PADCFG_DS_12MA (3U << 1)
+#define JH8100_PADCFG_IE BIT(0)
+
+/*
+ * The packed pinmux values from the device tree look like this:
+ *
+ * | 31 - 24 | 23 - 16 | 15 - 10 | 9 - 8 | 7 - 0 |
+ * | din | dout | doen | function | pin |
+ */
+static unsigned int jh8100_pinmux_din(u32 v)
+{
+ return (v & GENMASK(31, 24)) >> 24;
+}
+
+static u32 jh8100_pinmux_dout(u32 v)
+{
+ return (v & GENMASK(23, 16)) >> 16;
+}
+
+static u32 jh8100_pinmux_doen(u32 v)
+{
+ return (v & GENMASK(15, 10)) >> 10;
+}
+
+static u32 jh8100_pinmux_function(u32 v)
+{
+ return (v & GENMASK(9, 8)) >> 8;
+}
+
+static unsigned int jh8100_pinmux_pin(u32 v)
+{
+ return v & GENMASK(7, 0);
+}
+
+static struct jh8100_pinctrl *jh8100_from_irq_data(struct irq_data *d)
+{
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+
+ return container_of(gc, struct jh8100_pinctrl, gc);
+}
+
+struct jh8100_pinctrl *jh8100_from_irq_desc(struct irq_desc *desc)
+{
+ struct gpio_chip *gc = irq_desc_get_handler_data(desc);
+
+ return container_of(gc, struct jh8100_pinctrl, gc);
+}
+EXPORT_SYMBOL_GPL(jh8100_from_irq_desc);
+
+#ifdef CONFIG_DEBUG_FS
+static void jh8100_pin_dbg_show(struct pinctrl_dev *pctldev,
+ struct seq_file *s, unsigned int pin)
+{
+ struct jh8100_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
+ const struct jh8100_pinctrl_domain_info *info = sfp->info;
+
+ seq_printf(s, "%s", dev_name(pctldev->dev));
+
+ if (pin < sfp->gc.ngpio) {
+ unsigned int offset = 4 * (pin / 4);
+ unsigned int shift = 8 * (pin % 4);
+ u32 dout = readl_relaxed(sfp->base + info->dout_reg_base + offset);
+ u32 doen = readl_relaxed(sfp->base + info->doen_reg_base + offset);
+ u32 gpi = readl_relaxed(sfp->base + info->gpi_reg_base + offset);
+
+ dout = (dout >> shift) & info->dout_mask;
+ doen = (doen >> shift) & info->doen_mask;
+ gpi = ((gpi >> shift) - 2) & info->gpi_mask;
+
+ seq_printf(s, " dout=%u doen=%u din=%u", dout, doen, gpi);
+ }
+}
+#else
+#define jh8100_pin_dbg_show NULL
+#endif
+
+static int jh8100_dt_node_to_map(struct pinctrl_dev *pctldev,
+ struct device_node *np,
+ struct pinctrl_map **maps,
+ unsigned int *num_maps)
+{
+ struct jh8100_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
+ struct device *dev = sfp->gc.parent;
+ struct device_node *child;
+ struct pinctrl_map *map;
+ const char **pgnames;
+ const char *grpname;
+ int ngroups;
+ int nmaps;
+ int ret;
+
+ ngroups = 0;
+ for_each_child_of_node(np, child)
+ ngroups += 1;
+ nmaps = 2 * ngroups;
+
+ pgnames = devm_kcalloc(dev, ngroups, sizeof(*pgnames), GFP_KERNEL);
+ if (!pgnames)
+ return -ENOMEM;
+
+ map = kcalloc(nmaps, sizeof(*map), GFP_KERNEL);
+ if (!map)
+ return -ENOMEM;
+
+ nmaps = 0;
+ ngroups = 0;
+ mutex_lock(&sfp->mutex);
+ for_each_child_of_node(np, child) {
+ int npins = of_property_count_u32_elems(child, "pinmux");
+ int *pins;
+ u32 *pinmux;
+ int i;
+
+ if (npins < 1) {
+ dev_err(dev,
+ "invalid pinctrl group %pOFn.%pOFn: pinmux not set\n",
+ np, child);
+ ret = -EINVAL;
+ goto put_child;
+ }
+
+ grpname = devm_kasprintf(dev, GFP_KERNEL, "%pOFn.%pOFn", np, child);
+ if (!grpname) {
+ ret = -ENOMEM;
+ goto put_child;
+ }
+
+ pgnames[ngroups++] = grpname;
+
+ pins = devm_kcalloc(dev, npins, sizeof(*pins), GFP_KERNEL);
+ if (!pins) {
+ ret = -ENOMEM;
+ goto put_child;
+ }
+
+ pinmux = devm_kcalloc(dev, npins, sizeof(*pinmux), GFP_KERNEL);
+ if (!pinmux) {
+ ret = -ENOMEM;
+ goto put_child;
+ }
+
+ ret = of_property_read_u32_array(child, "pinmux", pinmux, npins);
+ if (ret)
+ goto put_child;
+
+ for (i = 0; i < npins; i++)
+ pins[i] = jh8100_pinmux_pin(pinmux[i]);
+
+ map[nmaps].type = PIN_MAP_TYPE_MUX_GROUP;
+ map[nmaps].data.mux.function = np->name;
+ map[nmaps].data.mux.group = grpname;
+ nmaps += 1;
+
+ ret = pinctrl_generic_add_group(pctldev, grpname,
+ pins, npins, pinmux);
+ if (ret < 0) {
+ dev_err(dev, "error adding group %s: %d\n", grpname, ret);
+ goto put_child;
+ }
+
+ ret = pinconf_generic_parse_dt_config(child, pctldev,
+ &map[nmaps].data.configs.configs,
+ &map[nmaps].data.configs.num_configs);
+ if (ret) {
+ dev_err(dev, "error parsing pin config of group %s: %d\n",
+ grpname, ret);
+ goto put_child;
+ }
+
+ /* don't create a map if there are no pinconf settings */
+ if (map[nmaps].data.configs.num_configs == 0)
+ continue;
+
+ map[nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
+ map[nmaps].data.configs.group_or_pin = grpname;
+ nmaps += 1;
+ }
+
+ ret = pinmux_generic_add_function(pctldev, np->name,
+ pgnames, ngroups, NULL);
+ if (ret < 0) {
+ dev_err(dev, "error adding function %s: %d\n", np->name, ret);
+ goto free_map;
+ }
+ mutex_unlock(&sfp->mutex);
+
+ *maps = map;
+ *num_maps = nmaps;
+ return 0;
+
+put_child:
+ of_node_put(child);
+free_map:
+ pinctrl_utils_free_map(pctldev, map, nmaps);
+ mutex_unlock(&sfp->mutex);
+ return ret;
+}
+
+static const struct pinctrl_ops jh8100_pinctrl_ops = {
+ .get_groups_count = pinctrl_generic_get_group_count,
+ .get_group_name = pinctrl_generic_get_group_name,
+ .get_group_pins = pinctrl_generic_get_group_pins,
+ .pin_dbg_show = jh8100_pin_dbg_show,
+ .dt_node_to_map = jh8100_dt_node_to_map,
+ .dt_free_map = pinctrl_utils_free_map,
+};
+
+void jh8100_set_gpiomux(struct jh8100_pinctrl *sfp, unsigned int pin,
+ unsigned int din, u32 dout, u32 doen)
+{
+ const struct jh8100_pinctrl_domain_info *info = sfp->info;
+
+ unsigned int offset = 4 * (pin / 4);
+ unsigned int shift = 8 * (pin % 4);
+ u32 dout_mask = info->dout_mask << shift;
+ u32 done_mask = info->doen_mask << shift;
+ u32 ival, imask;
+ u32 tmp;
+ void __iomem *reg_dout;
+ void __iomem *reg_doen;
+ void __iomem *reg_din;
+ unsigned long flags;
+
+ reg_dout = sfp->base + info->dout_reg_base + offset;
+ reg_doen = sfp->base + info->doen_reg_base + offset;
+ dout <<= shift;
+ doen <<= shift;
+ if (din != 255) {
+ unsigned int ioffset = 4 * (din / 4);
+ unsigned int ishift = 8 * (din % 4);
+
+ reg_din = sfp->base + info->gpi_reg_base + ioffset;
+ ival = (pin + 2) << ishift;
+ imask = info->gpi_mask << ishift;
+ } else {
+ reg_din = NULL;
+ }
+
+ raw_spin_lock_irqsave(&sfp->lock, flags);
+ dout |= readl_relaxed(reg_dout) & ~dout_mask;
+ writel_relaxed(dout, reg_dout);
+ doen |= readl_relaxed(reg_doen) & ~done_mask;
+ writel_relaxed(doen, reg_doen);
+ if (reg_din) {
+ tmp = readl_relaxed(reg_din) & ~imask;
+ writel_relaxed(tmp, reg_din);
+ ival |= readl_relaxed(reg_din) & ~imask;
+ writel_relaxed(ival, reg_din);
+ }
+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
+}
+
+static void jh8100_set_function(struct jh8100_pinctrl *sfp,
+ unsigned int pin, u32 func)
+{
+ const struct jh8100_gpio_func_sel *fs = &sfp->info->func_sel[pin];
+ unsigned long flags;
+ void __iomem *reg;
+ u32 mask;
+
+ if (!fs->offset)
+ return;
+
+ if (func > fs->max)
+ return;
+
+ reg = sfp->base + fs->offset;
+ func = func << fs->shift;
+ mask = 0x3U << fs->shift;
+
+ raw_spin_lock_irqsave(&sfp->lock, flags);
+ func |= readl_relaxed(reg) & ~mask;
+ writel_relaxed(func, reg);
+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
+}
+
+static int jh8100_set_one_pin_mux(struct jh8100_pinctrl *sfp,
+ unsigned int pin,
+ unsigned int din, u32 dout,
+ u32 doen, u32 func)
+{
+ if (pin < sfp->gc.ngpio && func == 0)
+ jh8100_set_gpiomux(sfp, pin, din, dout, doen);
+
+ if (!strcmp(sfp->info->name, JH8100_SYS_E_DOMAIN_NAME) &&
+ pin < sfp->gc.ngpio && func == 1)
+ jh8100_set_function(sfp, pin, func);
+
+ return 0;
+}
+
+static int jh8100_set_mux(struct pinctrl_dev *pctldev,
+ unsigned int fsel, unsigned int gsel)
+{
+ struct jh8100_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
+ const struct group_desc *group;
+ const u32 *pinmux;
+ unsigned int i;
+
+ group = pinctrl_generic_get_group(pctldev, gsel);
+ if (!group)
+ return -EINVAL;
+
+ pinmux = group->data;
+
+ for (i = 0; i < group->grp.npins; i++) {
+ u32 v = pinmux[i];
+
+ jh8100_set_one_pin_mux(sfp,
+ jh8100_pinmux_pin(v),
+ jh8100_pinmux_din(v),
+ jh8100_pinmux_dout(v),
+ jh8100_pinmux_doen(v),
+ jh8100_pinmux_function(v));
+ }
+
+ return 0;
+}
+
+static const struct pinmux_ops jh8100_pinmux_ops = {
+ .get_functions_count = pinmux_generic_get_function_count,
+ .get_function_name = pinmux_generic_get_function_name,
+ .get_function_groups = pinmux_generic_get_function_groups,
+ .set_mux = jh8100_set_mux,
+ .strict = true,
+};
+
+static const u8 jh8100_drive_strength_mA[4] = { 2, 4, 8, 12 };
+
+static u32 jh8100_padcfg_ds_to_mA(u32 padcfg)
+{
+ return jh8100_drive_strength_mA[(padcfg >> 1) & 3U];
+}
+
+static u32 jh8100_padcfg_ds_to_uA(u32 padcfg)
+{
+ return jh8100_drive_strength_mA[(padcfg >> 1) & 3U] * 1000;
+}
+
+static u32 jh8100_padcfg_ds_from_mA(u32 v)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(jh8100_drive_strength_mA); i++) {
+ if (v <= jh8100_drive_strength_mA[i])
+ break;
+ }
+ return i << 1;
+}
+
+static u32 jh8100_padcfg_ds_from_uA(u32 v)
+{
+ /* Convert from uA to mA */
+ v /= 1000;
+
+ return jh8100_padcfg_ds_from_mA(v);
+}
+
+static int jh8100_get_padcfg_base(struct jh8100_pinctrl *sfp,
+ unsigned int pin)
+{
+ if (!strcmp(sfp->info->name, JH8100_SYS_E_DOMAIN_NAME)) {
+ if (pin < JH8100_SYS_E_NGPIO)
+ return JH8100_SYS_E_GPO_PDA_00_47_CFG;
+ }
+
+ return -ENXIO;
+}
+
+static void jh8100_padcfg_rmw(struct jh8100_pinctrl *sfp,
+ unsigned int pin, u32 mask, u32 value)
+{
+ void __iomem *reg;
+ unsigned long flags;
+ int padcfg_base;
+
+ padcfg_base = jh8100_get_padcfg_base(sfp, pin);
+ if (padcfg_base < 0)
+ return;
+
+ reg = sfp->base + padcfg_base + 4 * pin;
+ value &= mask;
+
+ raw_spin_lock_irqsave(&sfp->lock, flags);
+ value |= readl_relaxed(reg) & ~mask;
+ writel_relaxed(value, reg);
+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
+}
+
+static int jh8100_pinconf_get(struct pinctrl_dev *pctldev,
+ unsigned int pin, unsigned long *config)
+{
+ struct jh8100_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
+ int param = pinconf_to_config_param(*config);
+ u32 padcfg, arg;
+ bool enabled;
+ int padcfg_base;
+
+ padcfg_base = jh8100_get_padcfg_base(sfp, pin);
+ if (padcfg_base < 0)
+ return 0;
+
+ padcfg = readl_relaxed(sfp->base + padcfg_base + 4 * pin);
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ enabled = !(padcfg & JH8100_PADCFG_BIAS_MASK);
+ arg = 0;
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ enabled = padcfg & JH8100_PADCFG_PD;
+ arg = 1;
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ enabled = padcfg & JH8100_PADCFG_PU;
+ arg = 1;
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ enabled = true;
+ arg = jh8100_padcfg_ds_to_mA(padcfg);
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH_UA:
+ enabled = true;
+ arg = jh8100_padcfg_ds_to_uA(padcfg);
+ break;
+ case PIN_CONFIG_INPUT_ENABLE:
+ enabled = padcfg & JH8100_PADCFG_IE;
+ arg = enabled;
+ break;
+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+ enabled = padcfg & JH8100_PADCFG_SMT;
+ arg = enabled;
+ break;
+ case PIN_CONFIG_SLEW_RATE:
+ enabled = true;
+ arg = !!(padcfg & JH8100_PADCFG_SLEW);
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ *config = pinconf_to_config_packed(param, arg);
+ return enabled ? 0 : -EINVAL;
+}
+
+static int jh8100_pinconf_set(struct pinctrl_dev *pctldev,
+ unsigned int gpio, unsigned long *config,
+ unsigned int num_configs)
+{
+ struct jh8100_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
+ u32 param;
+ u32 arg;
+ u32 value;
+ u32 mask;
+ int i;
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(config[i]);
+ arg = pinconf_to_config_argument(config[i]);
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ mask = JH8100_PADCFG_BIAS_MASK;
+ value = 0;
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ if (arg == 0)
+ return -ENOTSUPP;
+ mask = JH8100_PADCFG_BIAS_MASK;
+ value = JH8100_PADCFG_PD;
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ if (arg == 0)
+ return -ENOTSUPP;
+ mask = JH8100_PADCFG_BIAS_MASK;
+ value = JH8100_PADCFG_PU;
+ break;
+ case PIN_CONFIG_DRIVE_PUSH_PULL:
+ return 0;
+ case PIN_CONFIG_INPUT_ENABLE:
+ mask = JH8100_PADCFG_IE;
+ value = arg ? JH8100_PADCFG_IE : 0;
+ break;
+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+ mask = JH8100_PADCFG_SMT;
+ value = arg ? JH8100_PADCFG_SMT : 0;
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ jh8100_padcfg_rmw(sfp, gpio, mask, value);
+ }
+
+ return 0;
+}
+
+static int jh8100_pinconf_group_get(struct pinctrl_dev *pctldev,
+ unsigned int gsel,
+ unsigned long *config)
+{
+ const struct group_desc *group;
+
+ group = pinctrl_generic_get_group(pctldev, gsel);
+ if (!group)
+ return -EINVAL;
+
+ return jh8100_pinconf_get(pctldev, group->grp.pins[0], config);
+}
+
+static int jh8100_pinconf_group_set(struct pinctrl_dev *pctldev,
+ unsigned int gsel,
+ unsigned long *configs,
+ unsigned int num_configs)
+{
+ struct jh8100_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
+ const struct group_desc *group;
+ u16 mask, value;
+ int i;
+
+ group = pinctrl_generic_get_group(pctldev, gsel);
+ if (!group)
+ return -EINVAL;
+
+ mask = 0;
+ value = 0;
+ for (i = 0; i < num_configs; i++) {
+ int param = pinconf_to_config_param(configs[i]);
+ u32 arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ mask |= JH8100_PADCFG_BIAS_MASK;
+ value &= ~JH8100_PADCFG_BIAS_MASK;
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ if (arg == 0)
+ return -ENOTSUPP;
+ mask |= JH8100_PADCFG_BIAS_MASK;
+ value = (value & ~JH8100_PADCFG_BIAS_MASK) | JH8100_PADCFG_PD;
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ if (arg == 0)
+ return -ENOTSUPP;
+ mask |= JH8100_PADCFG_BIAS_MASK;
+ value = (value & ~JH8100_PADCFG_BIAS_MASK) | JH8100_PADCFG_PU;
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ mask |= JH8100_PADCFG_DS_MASK;
+ value = (value & ~JH8100_PADCFG_DS_MASK) |
+ jh8100_padcfg_ds_from_mA(arg);
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH_UA:
+ mask |= JH8100_PADCFG_DS_MASK;
+ value = (value & ~JH8100_PADCFG_DS_MASK) |
+ jh8100_padcfg_ds_from_uA(arg);
+ break;
+ case PIN_CONFIG_INPUT_ENABLE:
+ mask |= JH8100_PADCFG_IE;
+ if (arg)
+ value |= JH8100_PADCFG_IE;
+ else
+ value &= ~JH8100_PADCFG_IE;
+ break;
+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+ mask |= JH8100_PADCFG_SMT;
+ if (arg)
+ value |= JH8100_PADCFG_SMT;
+ else
+ value &= ~JH8100_PADCFG_SMT;
+ break;
+ case PIN_CONFIG_SLEW_RATE:
+ mask |= JH8100_PADCFG_SLEW;
+ if (arg)
+ value |= JH8100_PADCFG_SLEW;
+ else
+ value &= ~JH8100_PADCFG_SLEW;
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+ }
+
+ for (i = 0; i < group->grp.npins; i++)
+ jh8100_padcfg_rmw(sfp, group->grp.pins[i], mask, value);
+
+ return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static void jh8100_pinconf_dbg_show(struct pinctrl_dev *pctldev,
+ struct seq_file *s, unsigned int pin)
+{
+ struct jh8100_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
+ u32 value;
+ int padcfg_base;
+
+ padcfg_base = jh8100_get_padcfg_base(sfp, pin);
+ if (padcfg_base < 0)
+ return;
+
+ value = readl_relaxed(sfp->base + padcfg_base + 4 * pin);
+ seq_printf(s, " (0x%02x)", value);
+}
+#else
+#define jh8100_pinconf_dbg_show NULL
+#endif
+
+static const struct pinconf_ops jh8100_pinconf_ops = {
+ .pin_config_get = jh8100_pinconf_get,
+ .pin_config_set = jh8100_pinconf_set,
+ .pin_config_group_get = jh8100_pinconf_group_get,
+ .pin_config_group_set = jh8100_pinconf_group_set,
+ .pin_config_dbg_show = jh8100_pinconf_dbg_show,
+ .is_generic = true,
+};
+
+static int jh8100_gpio_get_direction(struct gpio_chip *gc,
+ unsigned int gpio)
+{
+ struct jh8100_pinctrl *sfp = container_of(gc,
+ struct jh8100_pinctrl, gc);
+ const struct jh8100_pinctrl_domain_info *info = sfp->info;
+ unsigned int offset = 4 * (gpio / 4);
+ unsigned int shift = 8 * (gpio % 4);
+ u32 doen = readl_relaxed(sfp->base + info->doen_reg_base + offset);
+
+ doen = (doen >> shift) & info->doen_mask;
+
+ return doen == 0 ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
+}
+
+static int jh8100_gpio_direction_input(struct gpio_chip *gc,
+ unsigned int gpio)
+{
+ struct jh8100_pinctrl *sfp = container_of(gc,
+ struct jh8100_pinctrl, gc);
+
+ /* enable input and schmitt trigger */
+ jh8100_padcfg_rmw(sfp, gpio,
+ JH8100_PADCFG_IE | JH8100_PADCFG_SMT,
+ JH8100_PADCFG_IE | JH8100_PADCFG_SMT);
+
+ jh8100_set_one_pin_mux(sfp, gpio, 255, 0, 1, 0);
+
+ return 0;
+}
+
+static int jh8100_gpio_direction_output(struct gpio_chip *gc,
+ unsigned int gpio, int value)
+{
+ struct jh8100_pinctrl *sfp = container_of(gc,
+ struct jh8100_pinctrl, gc);
+
+ jh8100_set_one_pin_mux(sfp, gpio,
+ 255, value ? 1 : 0,
+ 0, 0);
+
+ /* disable input, schmitt trigger and bias */
+ jh8100_padcfg_rmw(sfp, gpio,
+ JH8100_PADCFG_IE | JH8100_PADCFG_SMT,
+ 0);
+ return 0;
+}
+
+static int jh8100_gpio_get(struct gpio_chip *gc, unsigned int gpio)
+{
+ struct jh8100_pinctrl *sfp = container_of(gc,
+ struct jh8100_pinctrl, gc);
+ const struct jh8100_pinctrl_domain_info *info = sfp->info;
+ void __iomem *reg = sfp->base + info->gpioin_reg_base
+ + 4 * (gpio / 32);
+
+ return !!(readl_relaxed(reg) & BIT(gpio % 32));
+}
+
+static void jh8100_gpio_set(struct gpio_chip *gc,
+ unsigned int gpio, int value)
+{
+ struct jh8100_pinctrl *sfp = container_of(gc,
+ struct jh8100_pinctrl, gc);
+ const struct jh8100_pinctrl_domain_info *info = sfp->info;
+ unsigned int offset = 4 * (gpio / 4);
+ unsigned int shift = 8 * (gpio % 4);
+ void __iomem *reg_dout = sfp->base + info->dout_reg_base + offset;
+ u32 dout = (value ? 1 : 0) << shift;
+ u32 mask = info->dout_mask << shift;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&sfp->lock, flags);
+ dout |= readl_relaxed(reg_dout) & ~mask;
+ writel_relaxed(dout, reg_dout);
+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
+}
+
+static void jh8100_irq_ack(struct irq_data *d)
+{
+ struct jh8100_pinctrl *sfp = jh8100_from_irq_data(d);
+ const struct jh8100_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
+ irq_hw_number_t gpio = irqd_to_hwirq(d);
+ void __iomem *ic = sfp->base + irq_reg->ic_reg_base
+ + 4 * (gpio / 32);
+ u32 mask = BIT(gpio % 32);
+ unsigned long flags;
+ u32 value;
+
+ raw_spin_lock_irqsave(&sfp->lock, flags);
+ value = readl_relaxed(ic) & ~mask;
+ writel_relaxed(value, ic);
+ writel_relaxed(value | mask, ic);
+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
+}
+
+static void jh8100_irq_mask(struct irq_data *d)
+{
+ struct jh8100_pinctrl *sfp = jh8100_from_irq_data(d);
+ const struct jh8100_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
+ irq_hw_number_t gpio = irqd_to_hwirq(d);
+ void __iomem *ie = sfp->base + irq_reg->ie_reg_base
+ + 4 * (gpio / 32);
+ u32 mask = BIT(gpio % 32);
+ unsigned long flags;
+ u32 value;
+
+ raw_spin_lock_irqsave(&sfp->lock, flags);
+ value = readl_relaxed(ie) & ~mask;
+ writel_relaxed(value, ie);
+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
+
+ gpiochip_disable_irq(&sfp->gc, d->hwirq);
+}
+
+static void jh8100_irq_mask_ack(struct irq_data *d)
+{
+ struct jh8100_pinctrl *sfp = jh8100_from_irq_data(d);
+ const struct jh8100_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
+ irq_hw_number_t gpio = irqd_to_hwirq(d);
+ void __iomem *ie = sfp->base + irq_reg->ie_reg_base
+ + 4 * (gpio / 32);
+ void __iomem *ic = sfp->base + irq_reg->ic_reg_base
+ + 4 * (gpio / 32);
+ u32 mask = BIT(gpio % 32);
+ unsigned long flags;
+ u32 value;
+
+ raw_spin_lock_irqsave(&sfp->lock, flags);
+ value = readl_relaxed(ie) & ~mask;
+ writel_relaxed(value, ie);
+
+ value = readl_relaxed(ic) & ~mask;
+ writel_relaxed(value, ic);
+ writel_relaxed(value | mask, ic);
+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
+}
+
+static void jh8100_irq_unmask(struct irq_data *d)
+{
+ struct jh8100_pinctrl *sfp = jh8100_from_irq_data(d);
+ const struct jh8100_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
+ irq_hw_number_t gpio = irqd_to_hwirq(d);
+ void __iomem *ie = sfp->base + irq_reg->ie_reg_base
+ + 4 * (gpio / 32);
+ u32 mask = BIT(gpio % 32);
+ unsigned long flags;
+ u32 value;
+
+ gpiochip_enable_irq(&sfp->gc, d->hwirq);
+
+ raw_spin_lock_irqsave(&sfp->lock, flags);
+ value = readl_relaxed(ie) | mask;
+ writel_relaxed(value, ie);
+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
+}
+
+static int jh8100_irq_set_type(struct irq_data *d, unsigned int trigger)
+{
+ struct jh8100_pinctrl *sfp = jh8100_from_irq_data(d);
+ const struct jh8100_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
+ irq_hw_number_t gpio = irqd_to_hwirq(d);
+ void __iomem *base = sfp->base + 4 * (gpio / 32);
+ u32 mask = BIT(gpio % 32);
+ u32 irq_type, edge_both, polarity;
+ unsigned long flags;
+
+ switch (trigger) {
+ case IRQ_TYPE_EDGE_RISING:
+ irq_type = mask; /* 1: edge triggered */
+ edge_both = 0; /* 0: single edge */
+ polarity = mask; /* 1: rising edge */
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ irq_type = mask; /* 1: edge triggered */
+ edge_both = 0; /* 0: single edge */
+ polarity = 0; /* 0: falling edge */
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ irq_type = mask; /* 1: edge triggered */
+ edge_both = mask; /* 1: both edges */
+ polarity = 0; /* 0: ignored */
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ irq_type = 0; /* 0: level triggered */
+ edge_both = 0; /* 0: ignored */
+ polarity = mask; /* 1: high level */
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ irq_type = 0; /* 0: level triggered */
+ edge_both = 0; /* 0: ignored */
+ polarity = 0; /* 0: low level */
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (trigger & IRQ_TYPE_EDGE_BOTH)
+ irq_set_handler_locked(d, handle_edge_irq);
+ else
+ irq_set_handler_locked(d, handle_level_irq);
+
+ raw_spin_lock_irqsave(&sfp->lock, flags);
+ irq_type |= readl_relaxed(base + irq_reg->is_reg_base) & ~mask;
+ writel_relaxed(irq_type, base + irq_reg->is_reg_base);
+
+ edge_both |= readl_relaxed(base + irq_reg->ibe_reg_base) & ~mask;
+ writel_relaxed(edge_both, base + irq_reg->ibe_reg_base);
+
+ polarity |= readl_relaxed(base + irq_reg->iev_reg_base) & ~mask;
+ writel_relaxed(polarity, base + irq_reg->iev_reg_base);
+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
+ return 0;
+}
+
+static int jh8100_irq_set_wake(struct irq_data *d, unsigned int enable)
+{
+ struct jh8100_pinctrl *sfp = jh8100_from_irq_data(d);
+ int ret = 0;
+
+ if (enable)
+ ret = enable_irq_wake(sfp->wakeup_irq);
+ else
+ ret = disable_irq_wake(sfp->wakeup_irq);
+ if (ret)
+ dev_err(sfp->dev, "failed to %s wake-up interrupt\n",
+ enable ? "enable" : "disable");
+
+ return ret;
+}
+
+static void jh8100_irq_print_chip(struct irq_data *d, struct seq_file *p)
+{
+ struct jh8100_pinctrl *sfp = jh8100_from_irq_data(d);
+
+ seq_printf(p, sfp->gc.label);
+}
+
+static const struct irq_chip jh8100_irq_chip = {
+ .irq_ack = jh8100_irq_ack,
+ .irq_mask = jh8100_irq_mask,
+ .irq_mask_ack = jh8100_irq_mask_ack,
+ .irq_unmask = jh8100_irq_unmask,
+ .irq_set_type = jh8100_irq_set_type,
+ .irq_set_wake = jh8100_irq_set_wake,
+ .irq_print_chip = jh8100_irq_print_chip,
+ .flags = IRQCHIP_SET_TYPE_MASKED |
+ IRQCHIP_IMMUTABLE |
+ IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND |
+ IRQCHIP_MASK_ON_SUSPEND |
+ IRQCHIP_SKIP_SET_WAKE,
+ GPIOCHIP_IRQ_RESOURCE_HELPERS,
+};
+
+static void jh8100_gpio_irq_handler(struct irq_desc *desc)
+{
+ struct jh8100_pinctrl *sfp = jh8100_from_irq_desc(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct gpio_irq_chip *girq = &sfp->gc.irq;
+ unsigned long mis;
+ unsigned int pin;
+
+ chained_irq_enter(chip, desc);
+
+ mis = readl_relaxed(sfp->base + sfp->info->irq_reg->mis_reg_base);
+ for_each_set_bit(pin, &mis, sfp->info->mis_pin_num)
+ generic_handle_domain_irq(girq->domain, pin);
+
+ if (sfp->info->irq_reg->mis1_reg_base) {
+ mis = readl_relaxed(sfp->base + sfp->info->irq_reg->mis1_reg_base);
+ for_each_set_bit(pin, &mis, sfp->info->mis1_pin_num)
+ generic_handle_domain_irq(girq->domain, pin + 32);
+ }
+
+ chained_irq_exit(chip, desc);
+}
+
+static int jh8100_gpio_init_hw(struct gpio_chip *gc)
+{
+ struct jh8100_pinctrl *sfp = container_of(gc,
+ struct jh8100_pinctrl, gc);
+
+ /* mask all GPIO interrupts */
+ writel_relaxed(0U, sfp->base + sfp->info->irq_reg->ie_reg_base);
+ /* clear edge interrupt flags */
+ writel_relaxed(0U, sfp->base + sfp->info->irq_reg->ic_reg_base);
+ writel_relaxed(~0U, sfp->base + sfp->info->irq_reg->ic_reg_base);
+ if (sfp->info->irq_reg->ic1_reg_base) {
+ writel_relaxed(0U, sfp->base + sfp->info->irq_reg->ic1_reg_base);
+ writel_relaxed(~0U, sfp->base + sfp->info->irq_reg->ic1_reg_base);
+ }
+ /* enable GPIO interrupts */
+ writel_relaxed(1, sfp->base + sfp->info->irq_reg->ien_reg_base);
+
+ return 0;
+}
+
+static void jh8100_disable_clock(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
+int jh8100_pinctrl_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct gpio_irq_chip *girq;
+ const struct jh8100_pinctrl_domain_info *info;
+ struct jh8100_pinctrl *sfp;
+ struct pinctrl_desc *jh8100_pinctrl_desc;
+ struct reset_control *rst;
+ struct clk *clk;
+ int ret;
+
+ info = of_device_get_match_data(&pdev->dev);
+ if (!info)
+ return -ENODEV;
+
+ sfp = devm_kzalloc(dev, sizeof(*sfp), GFP_KERNEL);
+ if (!sfp)
+ return -ENOMEM;
+
+ sfp->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(sfp->base))
+ return PTR_ERR(sfp->base);
+
+ clk = devm_clk_get_optional(dev, NULL);
+ if (IS_ERR(clk))
+ return dev_err_probe(dev, PTR_ERR(clk), "could not get clock\n");
+
+ rst = devm_reset_control_get_exclusive(dev, NULL);
+ if (IS_ERR(rst))
+ return dev_err_probe(dev, PTR_ERR(rst), "could not get reset control\n");
+
+ ret = clk_prepare_enable(clk);
+ if (ret)
+ return dev_err_probe(dev, ret, "could not enable clock\n");
+
+ ret = devm_add_action_or_reset(dev, jh8100_disable_clock, clk);
+ if (ret)
+ return ret;
+
+ /*
+ * we don't want to assert reset and risk undoing pin muxing for the
+ * early boot serial console, but let's make sure the reset line is
+ * deasserted in case someone runs a really minimal bootloader.
+ */
+ ret = reset_control_deassert(rst);
+ if (ret)
+ return dev_err_probe(dev, ret, "could not deassert reset\n");
+
+ jh8100_pinctrl_desc = devm_kzalloc(&pdev->dev,
+ sizeof(*jh8100_pinctrl_desc),
+ GFP_KERNEL);
+ if (!jh8100_pinctrl_desc)
+ return -ENOMEM;
+
+ jh8100_pinctrl_desc->name = dev_name(dev);
+ jh8100_pinctrl_desc->pins = info->pins;
+ jh8100_pinctrl_desc->npins = info->npins;
+ jh8100_pinctrl_desc->pctlops = &jh8100_pinctrl_ops;
+ jh8100_pinctrl_desc->pmxops = &jh8100_pinmux_ops;
+ jh8100_pinctrl_desc->confops = &jh8100_pinconf_ops;
+ jh8100_pinctrl_desc->owner = THIS_MODULE;
+
+ sfp->info = info;
+ sfp->dev = dev;
+ platform_set_drvdata(pdev, sfp);
+ sfp->gc.parent = dev;
+ raw_spin_lock_init(&sfp->lock);
+ mutex_init(&sfp->mutex);
+
+ ret = devm_pinctrl_register_and_init(dev,
+ jh8100_pinctrl_desc,
+ sfp, &sfp->pctl);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "could not register pinctrl driver\n");
+
+ sfp->gc.label = dev_name(dev);
+ sfp->gc.owner = THIS_MODULE;
+ sfp->gc.request = pinctrl_gpio_request;
+ sfp->gc.free = pinctrl_gpio_free;
+ sfp->gc.get_direction = jh8100_gpio_get_direction;
+ sfp->gc.direction_input = jh8100_gpio_direction_input;
+ sfp->gc.direction_output = jh8100_gpio_direction_output;
+ sfp->gc.get = jh8100_gpio_get;
+ sfp->gc.set = jh8100_gpio_set;
+ sfp->gc.set_config = gpiochip_generic_config;
+ sfp->gc.base = info->gc_base;
+ sfp->gc.ngpio = info->ngpios;
+
+ girq = &sfp->gc.irq;
+
+ if (info->irq_reg) {
+ gpio_irq_chip_set_chip(girq, &jh8100_irq_chip);
+ girq->parent_handler = jh8100_gpio_irq_handler;
+ girq->num_parents = 1;
+ girq->parents = devm_kcalloc(dev, girq->num_parents,
+ sizeof(*girq->parents),
+ GFP_KERNEL);
+ if (!girq->parents)
+ return -ENOMEM;
+ girq->default_type = IRQ_TYPE_NONE;
+ girq->handler = handle_bad_irq;
+ girq->init_hw = jh8100_gpio_init_hw;
+
+ ret = platform_get_irq(pdev, 0);
+ if (ret < 0)
+ return ret;
+ girq->parents[0] = ret;
+ }
+
+ ret = pinctrl_enable(sfp->pctl);
+ if (ret)
+ return ret;
+
+ if (sfp->gc.ngpio > 0) {
+ ret = devm_gpiochip_add_data(dev, &sfp->gc, sfp);
+ if (ret)
+ return dev_err_probe(dev, ret, "could not register gpiochip\n");
+
+ dev_info(dev, "StarFive JH8100 GPIO chip registered %d GPIOs\n", sfp->gc.ngpio);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(jh8100_pinctrl_probe);
+
+MODULE_DESCRIPTION("Pinctrl driver for the StarFive JH8100 SoC");
+MODULE_AUTHOR("Alex Soo <yuklin.soo@starfivetech.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.h b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.h
new file mode 100644
index 000000000000..6eb4f1896a90
--- /dev/null
+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.h
@@ -0,0 +1,111 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Pinctrl / GPIO driver for StarFive JH8100 SoC
+ *
+ * Copyright (C) 2023-2024 StarFive Technology Co., Ltd.
+ * Author: Alex Soo <yuklin.soo@starfivetech.com>
+ *
+ */
+
+#ifndef __PINCTRL_STARFIVE_JH8100_H__
+#define __PINCTRL_STARFIVE_JH8100_H__
+
+#include "../core.h"
+
+#define JH8100_SYS_E_DOMAIN_NAME "jh8100-sys-east"
+
+#define JH8100_SYS_E_NGPIO 48
+
+#define JH8100_SYS_E_REG_NUM 116
+
+#define JH8100_SYS_E_GPO_PDA_00_47_CFG 0x114
+
+struct jh8100_pinctrl {
+ struct device *dev;
+ struct gpio_chip gc;
+ struct pinctrl_gpio_range gpios;
+ raw_spinlock_t lock;
+ void __iomem *base;
+ struct pinctrl_dev *pctl;
+ /* register read/write mutex */
+ struct mutex mutex;
+ const struct jh8100_pinctrl_domain_info *info;
+ unsigned int jh8100_sys_east_regs[JH8100_SYS_E_REG_NUM];
+ /* wakeup */
+ struct irq_domain *irq_domain;
+ struct gpio_desc *wakeup_gpio;
+ int wakeup_irq;
+};
+
+struct jh8100_gpio_func_sel {
+ unsigned short offset;
+ unsigned char shift;
+ unsigned char max;
+};
+
+struct jh8100_gpio_irq_reg {
+ unsigned int is_reg_base;
+ unsigned int ic_reg_base;
+ unsigned int ic1_reg_base;
+ unsigned int ibe_reg_base;
+ unsigned int iev_reg_base;
+ unsigned int ie_reg_base;
+ unsigned int ris_reg_base;
+ unsigned int mis_reg_base;
+ unsigned int mis1_reg_base;
+ unsigned int ien_reg_base;
+};
+
+struct jh8100_pinctrl_domain_info {
+ const struct pinctrl_pin_desc *pins;
+ unsigned int npins;
+ unsigned int ngpios;
+ unsigned int gc_base;
+
+ const char *name;
+ unsigned int nregs;
+
+ /* gpio dout/doen/din/gpioinput register */
+ unsigned int dout_reg_base;
+ unsigned int dout_mask;
+ unsigned int doen_reg_base;
+ unsigned int doen_mask;
+ unsigned int gpi_reg_base;
+ unsigned int gpi_mask;
+ unsigned int gpioin_reg_base;
+
+ const struct jh8100_gpio_func_sel *func_sel;
+ const struct jh8100_gpio_irq_reg *irq_reg;
+
+ /* gpio chip */
+ unsigned int mis_pin_num;
+ unsigned int mis1_pin_num;
+};
+
+int jh8100_pinctrl_probe(struct platform_device *pdev);
+void jh8100_set_gpiomux(struct jh8100_pinctrl *sfp, unsigned int pin,
+ unsigned int din, u32 dout, u32 doen);
+struct jh8100_pinctrl *jh8100_from_irq_desc(struct irq_desc *desc);
+void pinctrl_utils_free_map(struct pinctrl_dev *pctldev,
+ struct pinctrl_map *map, unsigned int num_maps);
+int pinmux_generic_get_function_count(struct pinctrl_dev *pctldev);
+const char *pinmux_generic_get_function_name(struct pinctrl_dev *pctldev,
+ unsigned int selector);
+int pinmux_generic_get_function_groups(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ const char * const **groups,
+ unsigned int * const num_groups);
+int pinmux_generic_add_function(struct pinctrl_dev *pctldev,
+ const char *name,
+ const char * const *groups,
+ unsigned int const num_groups,
+ void *data);
+
+#if defined(CONFIG_GENERIC_PINCONF) && defined(CONFIG_OF)
+int pinconf_generic_parse_dt_config(struct device_node *np,
+ struct pinctrl_dev *pctldev,
+ unsigned long **configs,
+ unsigned int *nconfigs);
+#endif
+
+#endif /* __PINCTRL_STARFIVE_JH8100_H__ */
--
2.25.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [RFC PATCH v3 2/7] pinctrl: starfive: jh8100: add main driver and sys_east domain sub-driver
2024-05-03 11:14 ` [RFC PATCH v3 2/7] pinctrl: starfive: jh8100: add main driver and sys_east domain sub-driver Alex Soo
@ 2024-05-06 20:15 ` Andy Shevchenko
0 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2024-05-06 20:15 UTC (permalink / raw)
To: Alex Soo
Cc: Linus Walleij, Bartosz Golaszewski, Hal Feng, Ley Foon Tan,
Jianlong Huang, Emil Renner Berthing, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Drew Fustini, linux-gpio,
linux-kernel, devicetree, linux-riscv, Paul Walmsley,
Palmer Dabbelt, Albert Ou
Fri, May 03, 2024 at 07:14:31PM +0800, Alex Soo kirjoitti:
> Add Starfive JH8100 SoC pinctrl main driver to provide the
> common APIs that are used by the sub-drivers of pinctrl
> domains:
> - sys_east,
> - sys_west,
> - sys_gmac,
> - aon (always-on)
>
> to implement the following tasks:
>
> - applies pin multiplexing, function selection, and pin
> configuration for devices during system initialization
> or change of pinctrl state due to power management.
> - read or set pin configuration from user space.
>
> Also, add the sys_east domain sub-driver since it requires
> at least one domain sub-driver to run the probe function in
> the main driver to enable the basic pinctrl functionalities
> on the system.
...
> +config PINCTRL_STARFIVE_JH8100
> + bool
> + select GENERIC_PINCONF
> + select GENERIC_PINCTRL_GROUPS
> + select GENERIC_PINMUX_FUNCTIONS
> + select GPIOLIB
> + select GPIOLIB_IRQCHIP
> + select OF_GPIO
Why?
...
> +/*
> + * Pinctrl / GPIO driver for StarFive JH8100 SoC sys east controller
> + *
> + * Copyright (C) 2023-2024 StarFive Technology Co., Ltd.
> + * Author: Alex Soo <yuklin.soo@starfivetech.com>
> + *
Unneeded blank line.
> + */
...
> +#include <linux/gpio/driver.h>
> +#include <linux/module.h>
> +#include <linux/pinctrl/pinctrl.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
This lacks some of inclusions.
E.g., array_size.h, mod_devicetable.h, io.h.
...
> +#ifdef CONFIG_PM_SLEEP
SHouldn't be in a new code. Use proper PM macros.
> +static int jh8100_sys_e_pinctrl_suspend(struct device *dev)
> +{
> + struct jh8100_pinctrl *sfp;
> + int i;
> +
> + sfp = dev_get_drvdata(dev);
> + if (!sfp)
> + return -EINVAL;
When this check can be true?
> + for (i = 0; i < sfp->info->nregs; i++)
> + sfp->jh8100_sys_east_regs[i] = readl_relaxed(sfp->base + (i * 4));
> +
> + return pinctrl_force_sleep(sfp->pctl);
> +}
> +
> +static int jh8100_sys_e_pinctrl_resume(struct device *dev)
> +{
> + struct jh8100_pinctrl *sfp;
> + int i;
> + sfp = dev_get_drvdata(dev);
> + if (!sfp)
> + return -EINVAL;
Ditto.
> + for (i = 0; i < sfp->info->nregs; i++)
> + writel_relaxed(sfp->jh8100_sys_east_regs[i], sfp->base + (i * 4));
Too many parentheses.
> + return pinctrl_force_default(sfp->pctl);
> +}
> +#endif
...
> +static SIMPLE_DEV_PM_OPS(jh8100_sys_e_pinctrl_dev_pm_ops,
> + jh8100_sys_e_pinctrl_suspend,
> + jh8100_sys_e_pinctrl_resume);
Don't use obsoleted macros, use new ones.
...
> +#ifdef CONFIG_PM_SLEEP
> + .pm = &jh8100_sys_e_pinctrl_dev_pm_ops,
> +#endif
Ditto, no ugly ifdeffery.
> + .of_match_table = jh8100_sys_e_pinctrl_of_match,
> + },
> +};
...
> +/*
> + * Pinctrl / GPIO driver for StarFive JH8100 SoC
> + *
> + * Copyright (C) 2023-2024 StarFive Technology Co., Ltd.
> + * Author: Alex Soo <yuklin.soo@starfivetech.com>
> + *
Unneeded blank line.
> + */
...
+ array_size.h
> +#include <linux/bits.h>
> +#include <linux/clk.h>
+ container_of.h
> +#include <linux/gpio/consumer.h>
> +#include <linux/gpio/driver.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_wakeirq.h>
> +#include <linux/reset.h>
> +#include <linux/seq_file.h>
> +#include <linux/spinlock.h>
> +#include <linux/string.h>
+ types.h
...
> +static unsigned int jh8100_pinmux_din(u32 v)
> +{
> + return (v & GENMASK(31, 24)) >> 24;
> +}
> +
> +static u32 jh8100_pinmux_dout(u32 v)
> +{
> + return (v & GENMASK(23, 16)) >> 16;
> +}
> +
> +static u32 jh8100_pinmux_doen(u32 v)
> +{
> + return (v & GENMASK(15, 10)) >> 10;
> +}
> +
> +static u32 jh8100_pinmux_function(u32 v)
> +{
> + return (v & GENMASK(9, 8)) >> 8;
> +}
> +
> +static unsigned int jh8100_pinmux_pin(u32 v)
> +{
> + return v & GENMASK(7, 0);
> +}
These all are reinventions of bitfield.h.
...
> +static void jh8100_pin_dbg_show(struct pinctrl_dev *pctldev,
> + struct seq_file *s, unsigned int pin)
> +{
> + struct jh8100_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
> + const struct jh8100_pinctrl_domain_info *info = sfp->info;
> +
> + seq_printf(s, "%s", dev_name(pctldev->dev));
> + if (pin < sfp->gc.ngpio) {
When this is not true?
If that case even possible, invert the conditional to reduce the indentation
level.
> + unsigned int offset = 4 * (pin / 4);
> + unsigned int shift = 8 * (pin % 4);
> + u32 dout = readl_relaxed(sfp->base + info->dout_reg_base + offset);
> + u32 doen = readl_relaxed(sfp->base + info->doen_reg_base + offset);
> + u32 gpi = readl_relaxed(sfp->base + info->gpi_reg_base + offset);
> +
> + dout = (dout >> shift) & info->dout_mask;
> + doen = (doen >> shift) & info->doen_mask;
> + gpi = ((gpi >> shift) - 2) & info->gpi_mask;
> +
> + seq_printf(s, " dout=%u doen=%u din=%u", dout, doen, gpi);
> + }
> +}
...
> + pgnames = devm_kcalloc(dev, ngroups, sizeof(*pgnames), GFP_KERNEL);
> + if (!pgnames)
> + return -ENOMEM;
> +
> + map = kcalloc(nmaps, sizeof(*map), GFP_KERNEL);
> + if (!map)
> + return -ENOMEM;
Why one is managed and another is not? Shouldn't be both either managed or not?
...
> + mutex_lock(&sfp->mutex);
Don't you want to use cleanup.h from day 1?
...
> + for_each_child_of_node(np, child) {
Why not using _scoped() variant?
...
> + int npins = of_property_count_u32_elems(child, "pinmux");
Why signed?
Please, decouple definition and assignment.
> + int *pins;
> + u32 *pinmux;
> + int i;
> +
> + if (npins < 1) {
> + dev_err(dev,
> + "invalid pinctrl group %pOFn.%pOFn: pinmux not set\n",
> + np, child);
> + ret = -EINVAL;
Can npins be negative? In such case why shadowing an error code?
> + goto put_child;
> + }
...
> + ret = pinctrl_generic_add_group(pctldev, grpname,
> + pins, npins, pinmux);
One line?
...
> + for (i = 0; i < group->grp.npins; i++) {
> + u32 v = pinmux[i];
> +
> + jh8100_set_one_pin_mux(sfp,
> + jh8100_pinmux_pin(v),
> + jh8100_pinmux_din(v),
> + jh8100_pinmux_dout(v),
> + jh8100_pinmux_doen(v),
> + jh8100_pinmux_function(v));
> + }
Indentation?
...
> +static u32 jh8100_padcfg_ds_to_mA(u32 padcfg)
> +{
> + return jh8100_drive_strength_mA[(padcfg >> 1) & 3U];
GENMASK() ?
> +}
> +
> +static u32 jh8100_padcfg_ds_to_uA(u32 padcfg)
> +{
> + return jh8100_drive_strength_mA[(padcfg >> 1) & 3U] * 1000;
Ditto.
> +}
...
> +static u32 jh8100_padcfg_ds_from_mA(u32 v)
> +{
> + int i;
Why signed?
> + for (i = 0; i < ARRAY_SIZE(jh8100_drive_strength_mA); i++) {
> + if (v <= jh8100_drive_strength_mA[i])
> + break;
> + }
> + return i << 1;
> +}
...
> +static int jh8100_gpio_get_direction(struct gpio_chip *gc,
> + unsigned int gpio)
One line?
> +{
> + struct jh8100_pinctrl *sfp = container_of(gc,
> + struct jh8100_pinctrl, gc);
> + const struct jh8100_pinctrl_domain_info *info = sfp->info;
> + unsigned int offset = 4 * (gpio / 4);
> + unsigned int shift = 8 * (gpio % 4);
> + u32 doen = readl_relaxed(sfp->base + info->doen_reg_base + offset);
> + doen = (doen >> shift) & info->doen_mask;
> +
> + return doen == 0 ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
if ((doen >> shift) & info->doen_mask)
return GPIO_LINE_DIRECTION_IN;
return GPIO_LINE_DIRECTION_OUT;
> +}
...
> +static int jh8100_gpio_direction_input(struct gpio_chip *gc,
> + unsigned int gpio)
> +{
> + struct jh8100_pinctrl *sfp = container_of(gc,
> + struct jh8100_pinctrl, gc);
Broken indentation, just put on one line.
> + /* enable input and schmitt trigger */
> + jh8100_padcfg_rmw(sfp, gpio,
> + JH8100_PADCFG_IE | JH8100_PADCFG_SMT,
> + JH8100_PADCFG_IE | JH8100_PADCFG_SMT);
> +
> + jh8100_set_one_pin_mux(sfp, gpio, 255, 0, 1, 0);
> +
> + return 0;
> +}
...
> +static int jh8100_gpio_direction_output(struct gpio_chip *gc,
> + unsigned int gpio, int value)
> +{
> + struct jh8100_pinctrl *sfp = container_of(gc,
> + struct jh8100_pinctrl, gc);
> + jh8100_set_one_pin_mux(sfp, gpio,
> + 255, value ? 1 : 0,
> + 0, 0);
Use room on the previous lines.
> + /* disable input, schmitt trigger and bias */
> + jh8100_padcfg_rmw(sfp, gpio,
> + JH8100_PADCFG_IE | JH8100_PADCFG_SMT,
> + 0);
> + return 0;
> +}
...
> +{
> + struct jh8100_pinctrl *sfp = container_of(gc,
> + struct jh8100_pinctrl, gc);
One line. You may create a helper to_jh8100_pinctrl() and use everywhere,
> + const struct jh8100_pinctrl_domain_info *info = sfp->info;
> + void __iomem *reg = sfp->base + info->gpioin_reg_base
> + + 4 * (gpio / 32);
Split definition and assignment. It will increase readability.
> + return !!(readl_relaxed(reg) & BIT(gpio % 32));
> +}
...
> +static void jh8100_gpio_set(struct gpio_chip *gc,
> + unsigned int gpio, int value)
> +{
> + struct jh8100_pinctrl *sfp = container_of(gc,
> + struct jh8100_pinctrl, gc);
> + const struct jh8100_pinctrl_domain_info *info = sfp->info;
> + unsigned int offset = 4 * (gpio / 4);
> + unsigned int shift = 8 * (gpio % 4);
> + void __iomem *reg_dout = sfp->base + info->dout_reg_base + offset;
> + u32 dout = (value ? 1 : 0) << shift;
u32 dout = value ? BIT(shift) : 0;
> + u32 mask = info->dout_mask << shift;
> + unsigned long flags;
> +
> + raw_spin_lock_irqsave(&sfp->lock, flags);
> + dout |= readl_relaxed(reg_dout) & ~mask;
> + writel_relaxed(dout, reg_dout);
> + raw_spin_unlock_irqrestore(&sfp->lock, flags);
> +}
...
> +static void jh8100_irq_mask(struct irq_data *d)
> +{
> + struct jh8100_pinctrl *sfp = jh8100_from_irq_data(d);
> + const struct jh8100_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
> + irq_hw_number_t gpio = irqd_to_hwirq(d);
> + void __iomem *ie = sfp->base + irq_reg->ie_reg_base
> + + 4 * (gpio / 32);
> + u32 mask = BIT(gpio % 32);
> + unsigned long flags;
> + u32 value;
> +
> + raw_spin_lock_irqsave(&sfp->lock, flags);
> + value = readl_relaxed(ie) & ~mask;
> + writel_relaxed(value, ie);
> + raw_spin_unlock_irqrestore(&sfp->lock, flags);
> +
> + gpiochip_disable_irq(&sfp->gc, d->hwirq);
You have gpio, why not use it here?
> +}
...
> +static void jh8100_irq_unmask(struct irq_data *d)
> +{
> + struct jh8100_pinctrl *sfp = jh8100_from_irq_data(d);
> + const struct jh8100_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
> + irq_hw_number_t gpio = irqd_to_hwirq(d);
> + void __iomem *ie = sfp->base + irq_reg->ie_reg_base
> + + 4 * (gpio / 32);
> + u32 mask = BIT(gpio % 32);
> + unsigned long flags;
> + u32 value;
> +
> + gpiochip_enable_irq(&sfp->gc, d->hwirq);
Ditto.
> + raw_spin_lock_irqsave(&sfp->lock, flags);
> + value = readl_relaxed(ie) | mask;
> + writel_relaxed(value, ie);
> + raw_spin_unlock_irqrestore(&sfp->lock, flags);
> +}
...
> +static int jh8100_irq_set_wake(struct irq_data *d, unsigned int enable)
> +{
> + struct jh8100_pinctrl *sfp = jh8100_from_irq_data(d);
> + int ret = 0;
> +
> + if (enable)
> + ret = enable_irq_wake(sfp->wakeup_irq);
> + else
> + ret = disable_irq_wake(sfp->wakeup_irq);
> + if (ret)
> + dev_err(sfp->dev, "failed to %s wake-up interrupt\n",
> + enable ? "enable" : "disable");
str_enable_disable() (will require string_choices.h).
> + return ret;
> +}
...
> +static void jh8100_irq_print_chip(struct irq_data *d, struct seq_file *p)
> +{
> + struct jh8100_pinctrl *sfp = jh8100_from_irq_data(d);
> +
> + seq_printf(p, sfp->gc.label);
This is bad. Use seq_puts() or proper formatting string.
> +}
...
> + writel_relaxed(~0U, sfp->base + sfp->info->irq_reg->ic_reg_base);
GENMASK() ?
...
> + writel_relaxed(~0U, sfp->base + sfp->info->irq_reg->ic1_reg_base);
Ditto.
...
> + info = of_device_get_match_data(&pdev->dev);
> + if (!info)
> + return -ENODEV;
Use device_get_match_data() from property.h.
...
> + clk = devm_clk_get_optional(dev, NULL);
> + if (IS_ERR(clk))
> + return dev_err_probe(dev, PTR_ERR(clk), "could not get clock\n");
Why not _enabled() variant?
...
> + /*
> + * we don't want to assert reset and risk undoing pin muxing for the
We
> + * early boot serial console, but let's make sure the reset line is
> + * deasserted in case someone runs a really minimal bootloader.
> + */
...
> + ret = devm_pinctrl_register_and_init(dev,
> + jh8100_pinctrl_desc,
> + sfp, &sfp->pctl);
Can occupy less lines.
> + if (ret)
> + return dev_err_probe(dev, ret,
> + "could not register pinctrl driver\n");
...
> + if (sfp->gc.ngpio > 0) {
Is it really can be not true?
> + ret = devm_gpiochip_add_data(dev, &sfp->gc, sfp);
> + if (ret)
> + return dev_err_probe(dev, ret, "could not register gpiochip\n");
> +
> + dev_info(dev, "StarFive JH8100 GPIO chip registered %d GPIOs\n", sfp->gc.ngpio);
> + }
...
> +/*
> + * Pinctrl / GPIO driver for StarFive JH8100 SoC
> + *
> + * Copyright (C) 2023-2024 StarFive Technology Co., Ltd.
> + * Author: Alex Soo <yuklin.soo@starfivetech.com>
> + *
Unneeded blank line.
> + */
> +
> +#ifndef __PINCTRL_STARFIVE_JH8100_H__
> +#define __PINCTRL_STARFIVE_JH8100_H__
A lot of inclusions are missed, like
types.h
> +#include "../core.h"
Some of the forward declarations are missed, like
struct device;
> +#endif /* __PINCTRL_STARFIVE_JH8100_H__ */
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 18+ messages in thread
* [RFC PATCH v3 3/7] pinctrl: starfive: jh8100: add sys_west domain sub-driver
2024-05-03 11:14 [RFC PATCH v3 0/7] Add Pinctrl driver for Starfive JH8100 SoC Alex Soo
2024-05-03 11:14 ` [RFC PATCH v3 1/7] dt-bindings: pinctrl: starfive: Add JH8100 pinctrl Alex Soo
2024-05-03 11:14 ` [RFC PATCH v3 2/7] pinctrl: starfive: jh8100: add main driver and sys_east domain sub-driver Alex Soo
@ 2024-05-03 11:14 ` Alex Soo
2024-05-03 11:14 ` [RFC PATCH v3 4/7] pinctrl: starfive: jh8100: add sys_gmac " Alex Soo
` (5 subsequent siblings)
8 siblings, 0 replies; 18+ messages in thread
From: Alex Soo @ 2024-05-03 11:14 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Hal Feng, Ley Foon Tan,
Jianlong Huang, Emil Renner Berthing, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Drew Fustini
Cc: linux-gpio, linux-kernel, devicetree, linux-riscv, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alex Soo
Add sys_west domain sub-driver.
Signed-off-by: Alex Soo <yuklin.soo@starfivetech.com>
---
drivers/pinctrl/starfive/Kconfig | 12 ++
drivers/pinctrl/starfive/Makefile | 1 +
.../pinctrl-starfive-jh8100-sys-west.c | 164 ++++++++++++++++++
.../starfive/pinctrl-starfive-jh8100.c | 6 +
.../starfive/pinctrl-starfive-jh8100.h | 5 +
5 files changed, 188 insertions(+)
create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh8100-sys-west.c
diff --git a/drivers/pinctrl/starfive/Kconfig b/drivers/pinctrl/starfive/Kconfig
index afcbf9d4dc8d..d78f161a636c 100644
--- a/drivers/pinctrl/starfive/Kconfig
+++ b/drivers/pinctrl/starfive/Kconfig
@@ -70,3 +70,15 @@ config PINCTRL_STARFIVE_JH8100_SYS_EAST
This also provides an interface to the GPIO pins not used by other
peripherals supporting inputs, outputs, configuring pull-up/pull-down
and interrupts on input changes.
+
+config PINCTRL_STARFIVE_JH8100_SYS_WEST
+ tristate "StarFive JH8100 SoC System IOMUX-West pinctrl and GPIO driver"
+ depends on ARCH_STARFIVE || COMPILE_TEST
+ depends on OF
+ select PINCTRL_STARFIVE_JH8100
+ default ARCH_STARFIVE
+ help
+ Say yes here to support system iomux-west pin control on the StarFive JH8100 SoC.
+ This also provides an interface to the GPIO pins not used by other
+ peripherals supporting inputs, outputs, configuring pull-up/pull-down
+ and interrupts on input changes.
diff --git a/drivers/pinctrl/starfive/Makefile b/drivers/pinctrl/starfive/Makefile
index 45698c502b48..784465157ae2 100644
--- a/drivers/pinctrl/starfive/Makefile
+++ b/drivers/pinctrl/starfive/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_PINCTRL_STARFIVE_JH7110_AON) += pinctrl-starfive-jh7110-aon.o
obj-$(CONFIG_PINCTRL_STARFIVE_JH8100) += pinctrl-starfive-jh8100.o
obj-$(CONFIG_PINCTRL_STARFIVE_JH8100_SYS_EAST) += pinctrl-starfive-jh8100-sys-east.o
+obj-$(CONFIG_PINCTRL_STARFIVE_JH8100_SYS_WEST) += pinctrl-starfive-jh8100-sys-west.o
diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh8100-sys-west.c b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100-sys-west.c
new file mode 100644
index 000000000000..b97d89777aa3
--- /dev/null
+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100-sys-west.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Pinctrl / GPIO driver for StarFive JH8100 SoC sys west controller
+ *
+ * Copyright (C) 2023-2024 StarFive Technology Co., Ltd.
+ * Author: Alex Soo <yuklin.soo@starfivetech.com>
+ *
+ */
+
+#include <linux/gpio/driver.h>
+#include <linux/module.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include <dt-bindings/pinctrl/starfive,jh8100-pinctrl.h>
+
+#include "pinctrl-starfive-jh8100.h"
+
+#define JH8100_SYS_W_GC_BASE 0
+
+/* registers */
+#define JH8100_SYS_W_DOEN 0x000
+#define JH8100_SYS_W_DOUT 0x010
+#define JH8100_SYS_W_GPI 0x020
+#define JH8100_SYS_W_GPIOIN 0x068
+
+#define JH8100_SYS_W_GPIOEN 0x048
+#define JH8100_SYS_W_GPIOIS0 0x04c
+#define JH8100_SYS_W_GPIOIC0 0x050
+#define JH8100_SYS_W_GPIOIBE0 0x054
+#define JH8100_SYS_W_GPIOIEV0 0x058
+#define JH8100_SYS_W_GPIOIE0 0x05c
+#define JH8100_SYS_W_GPIORIS0 0x060
+#define JH8100_SYS_W_GPIOMIS0 0x064
+
+static const struct pinctrl_pin_desc jh8100_sys_w_pins[] = {
+ PINCTRL_PIN(0, "SYS_W_GPIO0"),
+ PINCTRL_PIN(1, "SYS_W_GPIO1"),
+ PINCTRL_PIN(2, "SYS_W_GPIO2"),
+ PINCTRL_PIN(3, "SYS_W_GPIO3"),
+ PINCTRL_PIN(4, "SYS_W_GPIO4"),
+ PINCTRL_PIN(5, "SYS_W_GPIO5"),
+ PINCTRL_PIN(6, "SYS_W_GPIO6"),
+ PINCTRL_PIN(7, "SYS_W_GPIO7"),
+ PINCTRL_PIN(8, "SYS_W_GPIO8"),
+ PINCTRL_PIN(9, "SYS_W_GPIO9"),
+ PINCTRL_PIN(10, "SYS_W_GPIO10"),
+ PINCTRL_PIN(11, "SYS_W_GPIO11"),
+ PINCTRL_PIN(12, "SYS_W_GPIO12"),
+ PINCTRL_PIN(13, "SYS_W_GPIO13"),
+ PINCTRL_PIN(14, "SYS_W_GPIO14"),
+ PINCTRL_PIN(15, "SYS_W_GPIO15"),
+};
+
+static const struct jh8100_gpio_func_sel
+ jh8100_sys_w_func_sel[ARRAY_SIZE(jh8100_sys_w_pins)] = {
+ [0] = { 0xb4, 0, 2 },
+ [1] = { 0xb4, 12, 2 },
+ [2] = { 0xb4, 14, 2 },
+ [3] = { 0xb4, 16, 2 },
+ [4] = { 0xb4, 18, 2 },
+ [5] = { 0xb4, 20, 2 },
+ [6] = { 0xb4, 22, 2 },
+ [7] = { 0xb4, 24, 2 },
+ [8] = { 0xb4, 26, 2 },
+ [9] = { 0xb4, 28, 2 },
+ [10] = { 0xb4, 2, 2 },
+ [11] = { 0xb4, 4, 2 },
+ [12] = { 0xb4, 6, 2 },
+ [13] = { 0xb4, 8, 2 },
+ [14] = { 0xb4, 10, 2 },
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int jh8100_sys_w_pinctrl_suspend(struct device *dev)
+{
+ struct jh8100_pinctrl *sfp;
+ int i;
+
+ sfp = dev_get_drvdata(dev);
+ if (!sfp)
+ return -EINVAL;
+
+ for (i = 0; i < sfp->info->nregs; i++)
+ sfp->jh8100_sys_west_regs[i] = readl_relaxed(sfp->base + (i * 4));
+
+ return pinctrl_force_sleep(sfp->pctl);
+}
+
+static int jh8100_sys_w_pinctrl_resume(struct device *dev)
+{
+ struct jh8100_pinctrl *sfp;
+ int i;
+
+ sfp = dev_get_drvdata(dev);
+ if (!sfp)
+ return -EINVAL;
+
+ for (i = 0; i < sfp->info->nregs; i++)
+ writel_relaxed(sfp->jh8100_sys_west_regs[i], sfp->base + (i * 4));
+
+ return pinctrl_force_default(sfp->pctl);
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(jh8100_sys_w_pinctrl_dev_pm_ops,
+ jh8100_sys_w_pinctrl_suspend,
+ jh8100_sys_w_pinctrl_resume);
+
+static const struct jh8100_gpio_irq_reg jh8100_sys_w_irq_reg = {
+ .is_reg_base = JH8100_SYS_W_GPIOIS0,
+ .ic_reg_base = JH8100_SYS_W_GPIOIC0,
+ .ibe_reg_base = JH8100_SYS_W_GPIOIBE0,
+ .iev_reg_base = JH8100_SYS_W_GPIOIEV0,
+ .ie_reg_base = JH8100_SYS_W_GPIOIE0,
+ .ris_reg_base = JH8100_SYS_W_GPIORIS0,
+ .mis_reg_base = JH8100_SYS_W_GPIOMIS0,
+ .ien_reg_base = JH8100_SYS_W_GPIOEN,
+};
+
+static const struct jh8100_pinctrl_domain_info jh8100_sys_w_pinctrl_info = {
+ .pins = jh8100_sys_w_pins,
+ .npins = ARRAY_SIZE(jh8100_sys_w_pins),
+ .ngpios = JH8100_SYS_W_NGPIO,
+ .gc_base = JH8100_SYS_W_GC_BASE,
+ .name = JH8100_SYS_W_DOMAIN_NAME,
+ .nregs = JH8100_SYS_W_REG_NUM,
+ .dout_reg_base = JH8100_SYS_W_DOUT,
+ .dout_mask = GENMASK(5, 0),
+ .doen_reg_base = JH8100_SYS_W_DOEN,
+ .doen_mask = GENMASK(4, 0),
+ .gpi_reg_base = JH8100_SYS_W_GPI,
+ .gpi_mask = GENMASK(4, 0),
+ .gpioin_reg_base = JH8100_SYS_W_GPIOIN,
+ .func_sel = jh8100_sys_w_func_sel,
+ .irq_reg = &jh8100_sys_w_irq_reg,
+ .mis_pin_num = JH8100_SYS_W_NGPIO,
+};
+
+static const struct of_device_id jh8100_sys_w_pinctrl_of_match[] = {
+ {
+ .compatible = "starfive,jh8100-sys-pinctrl-west",
+ .data = &jh8100_sys_w_pinctrl_info,
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, jh8100_sys_w_pinctrl_of_match);
+
+static struct platform_driver jh8100_sys_w_pinctrl_driver = {
+ .probe = jh8100_pinctrl_probe,
+ .driver = {
+ .name = "starfive-jh8100-sys-pinctrl-west",
+#ifdef CONFIG_PM_SLEEP
+ .pm = &jh8100_sys_w_pinctrl_dev_pm_ops,
+#endif
+ .of_match_table = jh8100_sys_w_pinctrl_of_match,
+ },
+};
+module_platform_driver(jh8100_sys_w_pinctrl_driver);
+
+MODULE_DESCRIPTION("Pinctrl driver for StarFive JH8100 SoC sys west controller");
+MODULE_AUTHOR("Alex Soo <yuklin.soo@starfivetech.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.c b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.c
index 4b68463ff5a5..8c3e4a90d68d 100644
--- a/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.c
+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.c
@@ -333,6 +333,9 @@ static int jh8100_set_one_pin_mux(struct jh8100_pinctrl *sfp,
if (!strcmp(sfp->info->name, JH8100_SYS_E_DOMAIN_NAME) &&
pin < sfp->gc.ngpio && func == 1)
jh8100_set_function(sfp, pin, func);
+ else if (!strcmp(sfp->info->name, JH8100_SYS_W_DOMAIN_NAME) &&
+ pin < sfp->gc.ngpio - 1 && func == 2)
+ jh8100_set_function(sfp, pin, func);
return 0;
}
@@ -410,6 +413,9 @@ static int jh8100_get_padcfg_base(struct jh8100_pinctrl *sfp,
if (!strcmp(sfp->info->name, JH8100_SYS_E_DOMAIN_NAME)) {
if (pin < JH8100_SYS_E_NGPIO)
return JH8100_SYS_E_GPO_PDA_00_47_CFG;
+ } else if (!strcmp(sfp->info->name, JH8100_SYS_W_DOMAIN_NAME)) {
+ if (pin < JH8100_SYS_W_NGPIO)
+ return JH8100_SYS_W_GPO_PDA_00_15_CFG;
}
return -ENXIO;
diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.h b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.h
index 6eb4f1896a90..7c7a05c1c828 100644
--- a/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.h
+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.h
@@ -12,12 +12,16 @@
#include "../core.h"
+#define JH8100_SYS_W_DOMAIN_NAME "jh8100-sys-west"
#define JH8100_SYS_E_DOMAIN_NAME "jh8100-sys-east"
+#define JH8100_SYS_W_NGPIO 16
#define JH8100_SYS_E_NGPIO 48
+#define JH8100_SYS_W_REG_NUM 44
#define JH8100_SYS_E_REG_NUM 116
+#define JH8100_SYS_W_GPO_PDA_00_15_CFG 0x074
#define JH8100_SYS_E_GPO_PDA_00_47_CFG 0x114
struct jh8100_pinctrl {
@@ -30,6 +34,7 @@ struct jh8100_pinctrl {
/* register read/write mutex */
struct mutex mutex;
const struct jh8100_pinctrl_domain_info *info;
+ unsigned int jh8100_sys_west_regs[JH8100_SYS_W_REG_NUM];
unsigned int jh8100_sys_east_regs[JH8100_SYS_E_REG_NUM];
/* wakeup */
struct irq_domain *irq_domain;
--
2.25.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* [RFC PATCH v3 4/7] pinctrl: starfive: jh8100: add sys_gmac domain sub-driver
2024-05-03 11:14 [RFC PATCH v3 0/7] Add Pinctrl driver for Starfive JH8100 SoC Alex Soo
` (2 preceding siblings ...)
2024-05-03 11:14 ` [RFC PATCH v3 3/7] pinctrl: starfive: jh8100: add sys_west " Alex Soo
@ 2024-05-03 11:14 ` Alex Soo
2024-05-03 11:14 ` [RFC PATCH v3 5/7] pinctrl: starfive: jh8100: add AON " Alex Soo
` (4 subsequent siblings)
8 siblings, 0 replies; 18+ messages in thread
From: Alex Soo @ 2024-05-03 11:14 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Hal Feng, Ley Foon Tan,
Jianlong Huang, Emil Renner Berthing, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Drew Fustini
Cc: linux-gpio, linux-kernel, devicetree, linux-riscv, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alex Soo
Add sys_gmac domain sub-driver.
Signed-off-by: Alex Soo <yuklin.soo@starfivetech.com>
---
drivers/pinctrl/starfive/Kconfig | 12 +++
drivers/pinctrl/starfive/Makefile | 1 +
.../pinctrl-starfive-jh8100-sys-gmac.c | 89 +++++++++++++++++++
.../starfive/pinctrl-starfive-jh8100.h | 4 +
4 files changed, 106 insertions(+)
create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh8100-sys-gmac.c
diff --git a/drivers/pinctrl/starfive/Kconfig b/drivers/pinctrl/starfive/Kconfig
index d78f161a636c..bc123c0bf35e 100644
--- a/drivers/pinctrl/starfive/Kconfig
+++ b/drivers/pinctrl/starfive/Kconfig
@@ -82,3 +82,15 @@ config PINCTRL_STARFIVE_JH8100_SYS_WEST
This also provides an interface to the GPIO pins not used by other
peripherals supporting inputs, outputs, configuring pull-up/pull-down
and interrupts on input changes.
+
+config PINCTRL_STARFIVE_JH8100_SYS_GMAC
+ tristate "StarFive JH8100 SoC System IOMUX-GMAC pinctrl and GPIO driver"
+ depends on ARCH_STARFIVE || COMPILE_TEST
+ depends on OF
+ select PINCTRL_STARFIVE_JH8100
+ default ARCH_STARFIVE
+ help
+ Say yes here to support system iomux-gmac pin control on the StarFive JH8100 SoC.
+ This provides syscon registers to indicate voltage level on SDIO1/GMAC1, to indicate
+ GMAC1 pads voltage level under different GMAC interface modes, and to configure
+ GMAC1 interface slew rate.
diff --git a/drivers/pinctrl/starfive/Makefile b/drivers/pinctrl/starfive/Makefile
index 784465157ae2..236a693a8aef 100644
--- a/drivers/pinctrl/starfive/Makefile
+++ b/drivers/pinctrl/starfive/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_PINCTRL_STARFIVE_JH7110_AON) += pinctrl-starfive-jh7110-aon.o
obj-$(CONFIG_PINCTRL_STARFIVE_JH8100) += pinctrl-starfive-jh8100.o
obj-$(CONFIG_PINCTRL_STARFIVE_JH8100_SYS_EAST) += pinctrl-starfive-jh8100-sys-east.o
obj-$(CONFIG_PINCTRL_STARFIVE_JH8100_SYS_WEST) += pinctrl-starfive-jh8100-sys-west.o
+obj-$(CONFIG_PINCTRL_STARFIVE_JH8100_SYS_GMAC) += pinctrl-starfive-jh8100-sys-gmac.o
diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh8100-sys-gmac.c b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100-sys-gmac.c
new file mode 100644
index 000000000000..3758280e3660
--- /dev/null
+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100-sys-gmac.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Pinctrl / GPIO driver for StarFive JH8100 SoC sys gmac controller
+ *
+ * Copyright (C) 2023-2024 StarFive Technology Co., Ltd.
+ * Author: Alex Soo <yuklin.soo@starfivetech.com>
+ *
+ */
+
+#include <linux/gpio/driver.h>
+#include <linux/module.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include <dt-bindings/pinctrl/starfive,jh8100-pinctrl.h>
+
+#include "pinctrl-starfive-jh8100.h"
+
+#define JH8100_SYS_G_GC_BASE -1
+#define JH8100_SYS_G_DOMAIN_NAME "jh8100-sys-gmac"
+
+#ifdef CONFIG_PM_SLEEP
+static int jh8100_sys_gmac_pinctrl_suspend(struct device *dev)
+{
+ struct jh8100_pinctrl *sfp;
+ int i;
+
+ sfp = dev_get_drvdata(dev);
+ if (!sfp)
+ return -EINVAL;
+
+ for (i = 0; i < sfp->info->nregs; i++)
+ sfp->jh8100_sys_gmac_regs[i] = readl_relaxed(sfp->base + (i * 4));
+
+ return pinctrl_force_sleep(sfp->pctl);
+}
+
+static int jh8100_sys_gmac_pinctrl_resume(struct device *dev)
+{
+ struct jh8100_pinctrl *sfp;
+ int i;
+
+ sfp = dev_get_drvdata(dev);
+ if (!sfp)
+ return -EINVAL;
+
+ for (i = 0; i < sfp->info->nregs; i++)
+ writel_relaxed(sfp->jh8100_sys_gmac_regs[i], sfp->base + (i * 4));
+
+ return pinctrl_force_default(sfp->pctl);
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(jh8100_sys_gmac_pinctrl_dev_pm_ops,
+ jh8100_sys_gmac_pinctrl_suspend,
+ jh8100_sys_gmac_pinctrl_resume);
+
+static const struct jh8100_pinctrl_domain_info jh8100_sys_gmac_pinctrl_info = {
+ .ngpios = JH8100_SYS_G_NGPIO,
+ .gc_base = JH8100_SYS_G_GC_BASE,
+ .name = JH8100_SYS_G_DOMAIN_NAME,
+ .nregs = JH8100_SYS_G_REG_NUM,
+};
+
+static const struct of_device_id jh8100_sys_gmac_pinctrl_of_match[] = {
+ {
+ .compatible = "starfive,jh8100-sys-pinctrl-gmac",
+ .data = &jh8100_sys_gmac_pinctrl_info,
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, jh8100_sys_gmac_pinctrl_of_match);
+
+static struct platform_driver jh8100_sys_gmac_pinctrl_driver = {
+ .probe = jh8100_pinctrl_probe,
+ .driver = {
+ .name = "starfive-jh8100-sys-pinctrl-gmac",
+#ifdef CONFIG_PM_SLEEP
+ .pm = &jh8100_sys_gmac_pinctrl_dev_pm_ops,
+#endif
+ .of_match_table = jh8100_sys_gmac_pinctrl_of_match,
+ },
+};
+module_platform_driver(jh8100_sys_gmac_pinctrl_driver);
+
+MODULE_DESCRIPTION("Pinctrl driver for StarFive JH8100 SoC sys gmac controller");
+MODULE_AUTHOR("Alex Soo <yuklin.soo@starfivetech.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.h b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.h
index 7c7a05c1c828..90eef6417dd7 100644
--- a/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.h
+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.h
@@ -14,12 +14,15 @@
#define JH8100_SYS_W_DOMAIN_NAME "jh8100-sys-west"
#define JH8100_SYS_E_DOMAIN_NAME "jh8100-sys-east"
+#define JH8100_SYS_G_DOMAIN_NAME "jh8100-sys-gmac"
#define JH8100_SYS_W_NGPIO 16
#define JH8100_SYS_E_NGPIO 48
+#define JH8100_SYS_G_NGPIO 0
#define JH8100_SYS_W_REG_NUM 44
#define JH8100_SYS_E_REG_NUM 116
+#define JH8100_SYS_G_REG_NUM 19
#define JH8100_SYS_W_GPO_PDA_00_15_CFG 0x074
#define JH8100_SYS_E_GPO_PDA_00_47_CFG 0x114
@@ -36,6 +39,7 @@ struct jh8100_pinctrl {
const struct jh8100_pinctrl_domain_info *info;
unsigned int jh8100_sys_west_regs[JH8100_SYS_W_REG_NUM];
unsigned int jh8100_sys_east_regs[JH8100_SYS_E_REG_NUM];
+ unsigned int jh8100_sys_gmac_regs[JH8100_SYS_G_REG_NUM];
/* wakeup */
struct irq_domain *irq_domain;
struct gpio_desc *wakeup_gpio;
--
2.25.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* [RFC PATCH v3 5/7] pinctrl: starfive: jh8100: add AON domain sub-driver
2024-05-03 11:14 [RFC PATCH v3 0/7] Add Pinctrl driver for Starfive JH8100 SoC Alex Soo
` (3 preceding siblings ...)
2024-05-03 11:14 ` [RFC PATCH v3 4/7] pinctrl: starfive: jh8100: add sys_gmac " Alex Soo
@ 2024-05-03 11:14 ` Alex Soo
2024-05-03 11:14 ` [RFC PATCH v3 6/7] gpiolib: enable GPIO interrupt to wake up a system from sleep Alex Soo
` (3 subsequent siblings)
8 siblings, 0 replies; 18+ messages in thread
From: Alex Soo @ 2024-05-03 11:14 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Hal Feng, Ley Foon Tan,
Jianlong Huang, Emil Renner Berthing, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Drew Fustini
Cc: linux-gpio, linux-kernel, devicetree, linux-riscv, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alex Soo
Add AON domain sub-driver.
Signed-off-by: Alex Soo <yuklin.soo@starfivetech.com>
---
MAINTAINERS | 7 +
drivers/pinctrl/starfive/Kconfig | 14 ++
drivers/pinctrl/starfive/Makefile | 1 +
.../starfive/pinctrl-starfive-jh8100-aon.c | 150 ++++++++++++++++++
.../starfive/pinctrl-starfive-jh8100.c | 3 +
.../starfive/pinctrl-starfive-jh8100.h | 5 +
6 files changed, 180 insertions(+)
create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh8100-aon.c
diff --git a/MAINTAINERS b/MAINTAINERS
index dbd104f1f267..3f6b17688ac8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21125,6 +21125,13 @@ S: Maintained
F: drivers/reset/starfive/reset-starfive-jh81*
F: include/dt-bindings/reset/starfive?jh81*.h
+STARFIVE JH8100 PINCTRL DRIVERS
+M: Alex Soo <yuklin.soo@starfivetech.com>
+S: Supported
+F: Documentation/devicetree/bindings/pinctrl/starfive,jh81*.yaml
+F: drivers/pinctrl/starfive/pinctrl-starfive-jh81*
+F: include/dt-bindings/pinctrl/starfive,jh8100-pinctrl.h
+
STATIC BRANCH/CALL
M: Peter Zijlstra <peterz@infradead.org>
M: Josh Poimboeuf <jpoimboe@kernel.org>
diff --git a/drivers/pinctrl/starfive/Kconfig b/drivers/pinctrl/starfive/Kconfig
index bc123c0bf35e..6c448837f5f6 100644
--- a/drivers/pinctrl/starfive/Kconfig
+++ b/drivers/pinctrl/starfive/Kconfig
@@ -94,3 +94,17 @@ config PINCTRL_STARFIVE_JH8100_SYS_GMAC
This provides syscon registers to indicate voltage level on SDIO1/GMAC1, to indicate
GMAC1 pads voltage level under different GMAC interface modes, and to configure
GMAC1 interface slew rate.
+
+config PINCTRL_STARFIVE_JH8100_AON
+ tristate "Always-on pinctrl and GPIO driver for the StarFive JH8100 SoC"
+ depends on ARCH_STARFIVE || COMPILE_TEST
+ depends on OF
+ select PINCTRL_STARFIVE_JH8100
+ default ARCH_STARFIVE
+ help
+ Say yes here to support always-on pin control on the StarFive JH8100 SoC.
+ This provides an interface to the RGPIO pins not used by other peripherals
+ supporting inputs, outputs, configuring pull-up/pull-down and interrupts
+ on input changes. And also, the syscon registers to indicate voltage level
+ on eMMC/SDIO0/XSPI/RGPIOs/GMAC0, to indicate GMAC0 pads voltage level under
+ different GMAC interface modes, and to configure GMAC0 interface slew rate.
diff --git a/drivers/pinctrl/starfive/Makefile b/drivers/pinctrl/starfive/Makefile
index 236a693a8aef..46b1ab97779b 100644
--- a/drivers/pinctrl/starfive/Makefile
+++ b/drivers/pinctrl/starfive/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_PINCTRL_STARFIVE_JH8100) += pinctrl-starfive-jh8100.o
obj-$(CONFIG_PINCTRL_STARFIVE_JH8100_SYS_EAST) += pinctrl-starfive-jh8100-sys-east.o
obj-$(CONFIG_PINCTRL_STARFIVE_JH8100_SYS_WEST) += pinctrl-starfive-jh8100-sys-west.o
obj-$(CONFIG_PINCTRL_STARFIVE_JH8100_SYS_GMAC) += pinctrl-starfive-jh8100-sys-gmac.o
+obj-$(CONFIG_PINCTRL_STARFIVE_JH8100_AON) += pinctrl-starfive-jh8100-aon.o
diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh8100-aon.c b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100-aon.c
new file mode 100644
index 000000000000..3ced9f94f47a
--- /dev/null
+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100-aon.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Pinctrl / GPIO driver for StarFive JH8100 SoC aon controller
+ *
+ * Copyright (C) 2023-2024 StarFive Technology Co., Ltd.
+ * Author: Alex Soo <yuklin.soo@starfivetech.com>
+ *
+ */
+
+#include <linux/gpio/driver.h>
+#include <linux/module.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include <dt-bindings/pinctrl/starfive,jh8100-pinctrl.h>
+
+#include "pinctrl-starfive-jh8100.h"
+
+#define JH8100_AON_GC_BASE 64
+
+/* registers */
+#define JH8100_AON_DOEN 0x00
+#define JH8100_AON_DOUT 0x10
+#define JH8100_AON_GPI 0x20
+#define JH8100_AON_GPIOIN 0x54
+
+#define JH8100_AON_GPIOEN 0x34
+#define JH8100_AON_GPIOIS 0x38
+#define JH8100_AON_GPIOIC 0x3c
+#define JH8100_AON_GPIOIBE 0x40
+#define JH8100_AON_GPIOIEV 0x44
+#define JH8100_AON_GPIOIE 0x48
+#define JH8100_AON_GPIORIS 0x4c
+#define JH8100_AON_GPIOMIS 0x50
+
+static const struct pinctrl_pin_desc jh8100_aon_pins[] = {
+ PINCTRL_PIN(0, "AON_RGPIO0"),
+ PINCTRL_PIN(1, "AON_RGPIO1"),
+ PINCTRL_PIN(2, "AON_RGPIO2"),
+ PINCTRL_PIN(3, "AON_RGPIO3"),
+ PINCTRL_PIN(4, "AON_RGPIO4"),
+ PINCTRL_PIN(5, "AON_RGPIO5"),
+ PINCTRL_PIN(6, "AON_RGPIO6"),
+ PINCTRL_PIN(7, "AON_RGPIO7"),
+ PINCTRL_PIN(8, "AON_RGPIO8"),
+ PINCTRL_PIN(9, "AON_RGPIO9"),
+ PINCTRL_PIN(10, "AON_RGPIO10"),
+ PINCTRL_PIN(11, "AON_RGPIO11"),
+ PINCTRL_PIN(12, "AON_RGPIO12"),
+ PINCTRL_PIN(13, "AON_RGPIO13"),
+ PINCTRL_PIN(14, "AON_RGPIO14"),
+ PINCTRL_PIN(15, "AON_RGPIO15"),
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int jh8100_aon_pinctrl_suspend(struct device *dev)
+{
+ struct jh8100_pinctrl *sfp;
+ int i;
+
+ sfp = dev_get_drvdata(dev);
+ if (!sfp)
+ return -EINVAL;
+
+ if (device_may_wakeup(dev))
+ enable_irq_wake(sfp->wakeup_irq);
+
+ for (i = 0; i < sfp->info->nregs; i++)
+ sfp->jh8100_aon_regs[i] = readl_relaxed(sfp->base + (i * 4));
+
+ return pinctrl_force_sleep(sfp->pctl);
+}
+
+static int jh8100_aon_pinctrl_resume(struct device *dev)
+{
+ struct jh8100_pinctrl *sfp;
+ int i;
+
+ sfp = dev_get_drvdata(dev);
+ if (!sfp)
+ return -EINVAL;
+
+ if (device_may_wakeup(dev))
+ disable_irq_wake(sfp->wakeup_irq);
+
+ for (i = 0; i < sfp->info->nregs; i++)
+ writel_relaxed(sfp->jh8100_aon_regs[i], sfp->base + (i * 4));
+
+ return pinctrl_force_default(sfp->pctl);
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(jh8100_aon_pinctrl_dev_pm_ops,
+ jh8100_aon_pinctrl_suspend,
+ jh8100_aon_pinctrl_resume);
+
+static const struct jh8100_gpio_irq_reg jh8100_aon_irq_reg = {
+ .is_reg_base = JH8100_AON_GPIOIS,
+ .ic_reg_base = JH8100_AON_GPIOIC,
+ .ibe_reg_base = JH8100_AON_GPIOIBE,
+ .iev_reg_base = JH8100_AON_GPIOIEV,
+ .ie_reg_base = JH8100_AON_GPIOIE,
+ .ris_reg_base = JH8100_AON_GPIORIS,
+ .mis_reg_base = JH8100_AON_GPIOMIS,
+ .ien_reg_base = JH8100_AON_GPIOEN,
+};
+
+static const struct jh8100_pinctrl_domain_info jh8100_aon_pinctrl_info = {
+ .pins = jh8100_aon_pins,
+ .npins = ARRAY_SIZE(jh8100_aon_pins),
+ .ngpios = JH8100_AON_NGPIO,
+ .gc_base = JH8100_AON_GC_BASE,
+ .name = JH8100_AON_DOMAIN_NAME,
+ .nregs = JH8100_AON_REG_NUM,
+ .dout_reg_base = JH8100_AON_DOUT,
+ .dout_mask = GENMASK(4, 0),
+ .doen_reg_base = JH8100_AON_DOEN,
+ .doen_mask = GENMASK(2, 0),
+ .gpi_reg_base = JH8100_AON_GPI,
+ .gpi_mask = GENMASK(4, 0),
+ .gpioin_reg_base = JH8100_AON_GPIOIN,
+ .irq_reg = &jh8100_aon_irq_reg,
+ .mis_pin_num = JH8100_AON_NGPIO
+};
+
+static const struct of_device_id jh8100_aon_pinctrl_of_match[] = {
+ {
+ .compatible = "starfive,jh8100-aon-pinctrl",
+ .data = &jh8100_aon_pinctrl_info,
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, jh8100_aon_pinctrl_of_match);
+
+static struct platform_driver jh8100_aon_pinctrl_driver = {
+ .probe = jh8100_pinctrl_probe,
+ .driver = {
+ .name = "starfive-jh8100-aon-pinctrl",
+#ifdef CONFIG_PM_SLEEP
+ .pm = &jh8100_aon_pinctrl_dev_pm_ops,
+#endif
+ .of_match_table = jh8100_aon_pinctrl_of_match,
+ },
+};
+module_platform_driver(jh8100_aon_pinctrl_driver);
+
+MODULE_DESCRIPTION("Pinctrl driver for StarFive JH8100 SoC aon controller");
+MODULE_AUTHOR("Alex Soo <yuklin.soo@starfivetech.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.c b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.c
index 8c3e4a90d68d..edf2a6fb6da2 100644
--- a/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.c
+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.c
@@ -416,6 +416,9 @@ static int jh8100_get_padcfg_base(struct jh8100_pinctrl *sfp,
} else if (!strcmp(sfp->info->name, JH8100_SYS_W_DOMAIN_NAME)) {
if (pin < JH8100_SYS_W_NGPIO)
return JH8100_SYS_W_GPO_PDA_00_15_CFG;
+ } else if (!strcmp(sfp->info->name, JH8100_AON_DOMAIN_NAME)) {
+ if (pin < JH8100_AON_NGPIO)
+ return JH8100_AON_GPO_PDA_00_15_CFG;
}
return -ENXIO;
diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.h b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.h
index 90eef6417dd7..ba44a7dd96e1 100644
--- a/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.h
+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh8100.h
@@ -15,17 +15,21 @@
#define JH8100_SYS_W_DOMAIN_NAME "jh8100-sys-west"
#define JH8100_SYS_E_DOMAIN_NAME "jh8100-sys-east"
#define JH8100_SYS_G_DOMAIN_NAME "jh8100-sys-gmac"
+#define JH8100_AON_DOMAIN_NAME "jh8100-aon"
#define JH8100_SYS_W_NGPIO 16
#define JH8100_SYS_E_NGPIO 48
#define JH8100_SYS_G_NGPIO 0
+#define JH8100_AON_NGPIO 16
#define JH8100_SYS_W_REG_NUM 44
#define JH8100_SYS_E_REG_NUM 116
#define JH8100_SYS_G_REG_NUM 19
+#define JH8100_AON_REG_NUM 65
#define JH8100_SYS_W_GPO_PDA_00_15_CFG 0x074
#define JH8100_SYS_E_GPO_PDA_00_47_CFG 0x114
+#define JH8100_AON_GPO_PDA_00_15_CFG 0x90
struct jh8100_pinctrl {
struct device *dev;
@@ -40,6 +44,7 @@ struct jh8100_pinctrl {
unsigned int jh8100_sys_west_regs[JH8100_SYS_W_REG_NUM];
unsigned int jh8100_sys_east_regs[JH8100_SYS_E_REG_NUM];
unsigned int jh8100_sys_gmac_regs[JH8100_SYS_G_REG_NUM];
+ unsigned int jh8100_aon_regs[JH8100_AON_REG_NUM];
/* wakeup */
struct irq_domain *irq_domain;
struct gpio_desc *wakeup_gpio;
--
2.25.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* [RFC PATCH v3 6/7] gpiolib: enable GPIO interrupt to wake up a system from sleep
2024-05-03 11:14 [RFC PATCH v3 0/7] Add Pinctrl driver for Starfive JH8100 SoC Alex Soo
` (4 preceding siblings ...)
2024-05-03 11:14 ` [RFC PATCH v3 5/7] pinctrl: starfive: jh8100: add AON " Alex Soo
@ 2024-05-03 11:14 ` Alex Soo
2024-05-06 20:25 ` Andy Shevchenko
2024-05-27 12:31 ` Linus Walleij
2024-05-03 11:14 ` [RFC PATCH v3 7/7] riscv: dts: starfive: jh8100: add pinctrl device tree nodes Alex Soo
` (2 subsequent siblings)
8 siblings, 2 replies; 18+ messages in thread
From: Alex Soo @ 2024-05-03 11:14 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Hal Feng, Ley Foon Tan,
Jianlong Huang, Emil Renner Berthing, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Drew Fustini
Cc: linux-gpio, linux-kernel, devicetree, linux-riscv, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alex Soo
Add function gpiochip_wakeup_irq_setup() to configure and enable a
GPIO pin with interrupt wakeup capability according to user-defined
wakeup-gpios property in the device tree. Interrupt generated by
toggling the logic level (rising/falling edge) on the specified
GPIO pin can wake up a system from sleep mode.
Signed-off-by: Alex Soo <yuklin.soo@starfivetech.com>
---
drivers/gpio/gpiolib.c | 87 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 87 insertions(+)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 94903fc1c145..92cfbc34abb0 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pinctrl/consumer.h>
+#include <linux/pm_wakeirq.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
@@ -96,6 +97,7 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gc);
static int gpiochip_irqchip_init_hw(struct gpio_chip *gc);
static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gc);
static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gc);
+static int gpiochip_wakeup_irq_setup(struct gpio_chip *gc);
static bool gpiolib_initialized;
@@ -1045,8 +1047,15 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
if (ret)
goto err_remove_irqchip;
}
+
+ ret = gpiochip_wakeup_irq_setup(gc);
+ if (ret)
+ goto err_remove_device;
+
return 0;
+err_remove_device:
+ gcdev_unregister(gdev);
err_remove_irqchip:
gpiochip_irqchip_remove(gc);
err_remove_irqchip_mask:
@@ -1874,6 +1883,84 @@ static int gpiochip_irqchip_add_allocated_domain(struct gpio_chip *gc,
return 0;
}
+static irqreturn_t gpio_wake_irq_handler(int irq, void *data)
+{
+ struct irq_data *irq_data = data;
+
+ if (!irq_data || irq != irq_data->irq)
+ return IRQ_NONE;
+
+ return IRQ_HANDLED;
+}
+
+static int gpiochip_wakeup_irq_setup(struct gpio_chip *gc)
+{
+ struct device *dev = gc->parent;
+ struct gpio_irq_chip *girq = &gc->irq;
+ struct gpio_desc *wakeup_gpiod;
+ struct irq_desc *wakeup_irqd;
+ struct irq_domain *irq_domain;
+ struct irq_data *irq_data;
+ unsigned int offset;
+ int wakeup_irq;
+ int ret;
+
+ if (!(device_property_read_bool(dev, "wakeup-source")))
+ return 0;
+
+ irq_domain = girq->domain;
+
+ if (!irq_domain) {
+ dev_err(dev, "Couldn't allocate IRQ domain\n");
+ return -ENXIO;
+ }
+
+ wakeup_gpiod = devm_gpiod_get_optional(dev, "wakeup", GPIOD_IN);
+
+ if (IS_ERR(wakeup_gpiod)) {
+ dev_err(dev, "invalid wakeup gpio: %lu\n", PTR_ERR(wakeup_gpiod));
+ return PTR_ERR(wakeup_gpiod);
+ }
+ if (!wakeup_gpiod) {
+ dev_dbg(dev, "property wakeup-gpios is not defined\n");
+ return 0;
+ }
+
+ offset = gpio_chip_hwgpio(wakeup_gpiod);
+ wakeup_irq = gpiod_to_irq(wakeup_gpiod);
+ if (wakeup_irq < 0) {
+ dev_err(dev, "failed to convert wakeup GPIO to IRQ\n");
+ return wakeup_irq;
+ }
+ irq_domain->ops->map(irq_domain, wakeup_irq, offset);
+ wakeup_irqd = irq_to_desc(wakeup_irq);
+ irq_data = irq_get_irq_data(wakeup_irq);
+ girq->handler = handle_edge_irq;
+
+ if (!(wakeup_irqd->status_use_accessors & IRQ_NOREQUEST)) {
+ device_init_wakeup(dev, 1);
+ ret = devm_request_threaded_irq(dev, wakeup_irq, NULL,
+ gpio_wake_irq_handler,
+ IRQF_TRIGGER_FALLING |
+ IRQF_TRIGGER_RISING |
+ IRQF_ONESHOT |
+ IRQF_SHARED,
+ "pm-wakeup-gpio", irq_data);
+ if (ret) {
+ dev_err(dev, "unable to request wakeup IRQ: %d\n", ret);
+ return ret;
+ }
+ }
+
+ ret = dev_pm_set_wake_irq(dev, wakeup_irq);
+ if (ret) {
+ dev_err(dev, "failed to enable gpio irq wake\n");
+ return ret;
+ }
+
+ return 0;
+}
+
/**
* gpiochip_add_irqchip() - adds an IRQ chip to a GPIO chip
* @gc: the GPIO chip to add the IRQ chip to
--
2.25.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [RFC PATCH v3 6/7] gpiolib: enable GPIO interrupt to wake up a system from sleep
2024-05-03 11:14 ` [RFC PATCH v3 6/7] gpiolib: enable GPIO interrupt to wake up a system from sleep Alex Soo
@ 2024-05-06 20:25 ` Andy Shevchenko
2024-05-27 12:31 ` Linus Walleij
1 sibling, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2024-05-06 20:25 UTC (permalink / raw)
To: Alex Soo
Cc: Linus Walleij, Bartosz Golaszewski, Hal Feng, Ley Foon Tan,
Jianlong Huang, Emil Renner Berthing, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Drew Fustini, linux-gpio,
linux-kernel, devicetree, linux-riscv, Paul Walmsley,
Palmer Dabbelt, Albert Ou
Fri, May 03, 2024 at 07:14:35PM +0800, Alex Soo kirjoitti:
> Add function gpiochip_wakeup_irq_setup() to configure and enable a
> GPIO pin with interrupt wakeup capability according to user-defined
> wakeup-gpios property in the device tree. Interrupt generated by
> toggling the logic level (rising/falling edge) on the specified
> GPIO pin can wake up a system from sleep mode.
...
> +static irqreturn_t gpio_wake_irq_handler(int irq, void *data)
> +{
> + struct irq_data *irq_data = data;
> +
> + if (!irq_data || irq != irq_data->irq)
Hmm... When irq_data can be NULL?
> + return IRQ_NONE;
> +
> + return IRQ_HANDLED;
> +}
...
> +static int gpiochip_wakeup_irq_setup(struct gpio_chip *gc)
> +{
> + struct device *dev = gc->parent;
> + struct gpio_irq_chip *girq = &gc->irq;
> + struct gpio_desc *wakeup_gpiod;
> + struct irq_desc *wakeup_irqd;
> + struct irq_domain *irq_domain;
> + struct irq_data *irq_data;
> + unsigned int offset;
> + int wakeup_irq;
> + int ret;
> +
> + if (!(device_property_read_bool(dev, "wakeup-source")))
Too many parentheses.
> + return 0;
> +
> + irq_domain = girq->domain;
> +
Unneeded blank line. Ditto for all similar cases.
> + if (!irq_domain) {
> + dev_err(dev, "Couldn't allocate IRQ domain\n");
> + return -ENXIO;
return dev_err_probe(...);
Ditto for all similar cases.
> + }
...
> + wakeup_gpiod = devm_gpiod_get_optional(dev, "wakeup", GPIOD_IN);
> +
> + if (IS_ERR(wakeup_gpiod)) {
> + dev_err(dev, "invalid wakeup gpio: %lu\n", PTR_ERR(wakeup_gpiod));
> + return PTR_ERR(wakeup_gpiod);
> + }
> + if (!wakeup_gpiod) {
> + dev_dbg(dev, "property wakeup-gpios is not defined\n");
> + return 0;
> + }
> +
> + offset = gpio_chip_hwgpio(wakeup_gpiod);
> + wakeup_irq = gpiod_to_irq(wakeup_gpiod);
> + if (wakeup_irq < 0) {
> + dev_err(dev, "failed to convert wakeup GPIO to IRQ\n");
> + return wakeup_irq;
> + }
> + irq_domain->ops->map(irq_domain, wakeup_irq, offset);
> + wakeup_irqd = irq_to_desc(wakeup_irq);
> + irq_data = irq_get_irq_data(wakeup_irq);
What these lines are for?
> + girq->handler = handle_edge_irq;
> +
> + if (!(wakeup_irqd->status_use_accessors & IRQ_NOREQUEST)) {
> + device_init_wakeup(dev, 1);
> + ret = devm_request_threaded_irq(dev, wakeup_irq, NULL,
> + gpio_wake_irq_handler,
> + IRQF_TRIGGER_FALLING |
> + IRQF_TRIGGER_RISING |
What's wrong with the flags from DT?
> + IRQF_ONESHOT |
> + IRQF_SHARED,
> + "pm-wakeup-gpio", irq_data);
> + if (ret) {
> + dev_err(dev, "unable to request wakeup IRQ: %d\n", ret);
> + return ret;
> + }
> + }
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [RFC PATCH v3 6/7] gpiolib: enable GPIO interrupt to wake up a system from sleep
2024-05-03 11:14 ` [RFC PATCH v3 6/7] gpiolib: enable GPIO interrupt to wake up a system from sleep Alex Soo
2024-05-06 20:25 ` Andy Shevchenko
@ 2024-05-27 12:31 ` Linus Walleij
1 sibling, 0 replies; 18+ messages in thread
From: Linus Walleij @ 2024-05-27 12:31 UTC (permalink / raw)
To: Alex Soo
Cc: Bartosz Golaszewski, Hal Feng, Ley Foon Tan, Jianlong Huang,
Emil Renner Berthing, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Drew Fustini, linux-gpio, linux-kernel, devicetree,
linux-riscv, Paul Walmsley, Palmer Dabbelt, Albert Ou
On Fri, May 3, 2024 at 1:15 PM Alex Soo <yuklin.soo@starfivetech.com> wrote:
> Add function gpiochip_wakeup_irq_setup() to configure and enable a
> GPIO pin with interrupt wakeup capability according to user-defined
> wakeup-gpios property in the device tree. Interrupt generated by
> toggling the logic level (rising/falling edge) on the specified
> GPIO pin can wake up a system from sleep mode.
>
> Signed-off-by: Alex Soo <yuklin.soo@starfivetech.com>
This is a very helpful patch I think.
I'm looking forward to the next iteration.
> @@ -1045,8 +1047,15 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
> if (ret)
> goto err_remove_irqchip;
> }
> +
> + ret = gpiochip_wakeup_irq_setup(gc);
> + if (ret)
> + goto err_remove_device;
Do we have any in-tree drivers that do this by themselves already?
In that case we should convert them to use this function in the same
patch to avoid regressions.
> +static irqreturn_t gpio_wake_irq_handler(int irq, void *data)
> +{
> + struct irq_data *irq_data = data;
I'm minimalist so I usually just call the parameter "d" instead of "data"
and irq_data I would call *id but it's your pick.
> +
> + if (!irq_data || irq != irq_data->irq)
> + return IRQ_NONE;
> +
> + return IRQ_HANDLED;
Please add some debug print:
struct gpio_chip *gc = irq_data->chip_data;
chip_dbg(gc, "GPIO wakeup on IRQ %d\n", irq);
The rest looks good to me (after fixing Andy's comments!)
I would perhaps put some
debug print that "GPIO wakeup enabled at offset %d" in the
end as well, so people can easily follow this in the debug prints.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 18+ messages in thread
* [RFC PATCH v3 7/7] riscv: dts: starfive: jh8100: add pinctrl device tree nodes
2024-05-03 11:14 [RFC PATCH v3 0/7] Add Pinctrl driver for Starfive JH8100 SoC Alex Soo
` (5 preceding siblings ...)
2024-05-03 11:14 ` [RFC PATCH v3 6/7] gpiolib: enable GPIO interrupt to wake up a system from sleep Alex Soo
@ 2024-05-03 11:14 ` Alex Soo
2024-05-06 6:35 ` [RFC PATCH v3 0/7] Add Pinctrl driver for Starfive JH8100 SoC Linus Walleij
2024-05-06 20:25 ` Andy Shevchenko
8 siblings, 0 replies; 18+ messages in thread
From: Alex Soo @ 2024-05-03 11:14 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Hal Feng, Ley Foon Tan,
Jianlong Huang, Emil Renner Berthing, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Drew Fustini
Cc: linux-gpio, linux-kernel, devicetree, linux-riscv, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alex Soo
Add pinctrl_east/pinctrl_west/pinctrl_gmac/pinctrl_aon device
tree nodes for JH8100 SoC.
Signed-off-by: Alex Soo <yuklin.soo@starfivetech.com>
---
arch/riscv/boot/dts/starfive/jh8100-evb.dts | 7 +
arch/riscv/boot/dts/starfive/jh8100-pinfunc.h | 504 ++++++++++++++++++
arch/riscv/boot/dts/starfive/jh8100.dtsi | 46 ++
3 files changed, 557 insertions(+)
create mode 100644 arch/riscv/boot/dts/starfive/jh8100-pinfunc.h
diff --git a/arch/riscv/boot/dts/starfive/jh8100-evb.dts b/arch/riscv/boot/dts/starfive/jh8100-evb.dts
index c16bc25d8988..dde01ed35e3e 100644
--- a/arch/riscv/boot/dts/starfive/jh8100-evb.dts
+++ b/arch/riscv/boot/dts/starfive/jh8100-evb.dts
@@ -4,6 +4,8 @@
*/
#include "jh8100.dtsi"
+#include "jh8100-pinfunc.h"
+#include <dt-bindings/pinctrl/starfive,jh8100-pinctrl.h>
/ {
model = "StarFive JH8100 EVB";
@@ -26,3 +28,8 @@ memory@40000000 {
&uart0 {
status = "okay";
};
+
+&pinctrl_aon {
+ wakeup-gpios = <&pinctrl_aon PAD_RGPIO1 GPIO_ACTIVE_HIGH>;
+ wakeup-source;
+};
diff --git a/arch/riscv/boot/dts/starfive/jh8100-pinfunc.h b/arch/riscv/boot/dts/starfive/jh8100-pinfunc.h
new file mode 100644
index 000000000000..0325338dee08
--- /dev/null
+++ b/arch/riscv/boot/dts/starfive/jh8100-pinfunc.h
@@ -0,0 +1,504 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
+ * Author: Alex Soo <yuklin.soo@starfivetech.com>
+ *
+ */
+
+#ifndef __JH8100_PINFUNC_H__
+#define __JH8100_PINFUNC_H__
+
+/*
+ * mux bits:
+ * | 31 - 24 | 23 - 16 | 15 - 10 | 9 - 8 | 7 - 0 |
+ * | din | dout | doen | function | gpio nr |
+ *
+ * dout: output signal
+ * doen: output enable signal
+ * din: optional input signal, 0xff = none
+ * function:
+ * gpio nr: gpio number, 0 - 63
+ */
+#define GPIOMUX(n, dout, doen, din) ( \
+ (((din) & 0xff) << 24) | \
+ (((dout) & 0xff) << 16) | \
+ (((doen) & 0x3f) << 10) | \
+ ((n) & 0x3f))
+
+#define PINMUX(n, func) ((1 << 10) | (((func) & 0x3) << 8) | ((n) & 0xff))
+
+/* sys_iomux_east pins */
+#define PAD_GPIO0_E 0
+#define PAD_GPIO1_E 1
+#define PAD_GPIO2_E 2
+#define PAD_GPIO3_E 3
+#define PAD_GPIO4_E 4
+#define PAD_GPIO5_E 5
+#define PAD_GPIO6_E 6
+#define PAD_GPIO7_E 7
+#define PAD_GPIO8_E 8
+#define PAD_GPIO9_E 9
+#define PAD_GPIO10_E 10
+#define PAD_GPIO11_E 11
+#define PAD_GPIO12_E 12
+#define PAD_GPIO13_E 13
+#define PAD_GPIO14_E 14
+#define PAD_GPIO15_E 15
+#define PAD_GPIO16_E 16
+#define PAD_GPIO17_E 17
+#define PAD_GPIO18_E 18
+#define PAD_GPIO19_E 19
+#define PAD_GPIO20_E 20
+#define PAD_GPIO21_E 21
+#define PAD_GPIO22_E 22
+#define PAD_GPIO23_E 23
+#define PAD_GPIO24_E 24
+#define PAD_GPIO25_E 25
+#define PAD_GPIO26_E 26
+#define PAD_GPIO27_E 27
+#define PAD_GPIO28_E 28
+#define PAD_GPIO29_E 29
+#define PAD_GPIO30_E 30
+#define PAD_GPIO31_E 31
+#define PAD_GPIO32_E 32
+#define PAD_GPIO33_E 33
+#define PAD_GPIO34_E 34
+#define PAD_GPIO35_E 35
+#define PAD_GPIO36_E 36
+#define PAD_GPIO37_E 37
+#define PAD_GPIO38_E 38
+#define PAD_GPIO39_E 39
+#define PAD_GPIO40_E 40
+#define PAD_GPIO41_E 41
+#define PAD_GPIO42_E 42
+#define PAD_GPIO43_E 43
+#define PAD_GPIO44_E 44
+#define PAD_GPIO45_E 45
+#define PAD_GPIO46_E 46
+#define PAD_GPIO47_E 47
+
+/* sys_iomux_west pins */
+#define PAD_GPIO0_W 0
+#define PAD_GPIO1_W 1
+#define PAD_GPIO2_W 2
+#define PAD_GPIO3_W 3
+#define PAD_GPIO4_W 4
+#define PAD_GPIO5_W 5
+#define PAD_GPIO6_W 6
+#define PAD_GPIO7_W 7
+#define PAD_GPIO8_W 8
+#define PAD_GPIO9_W 9
+#define PAD_GPIO10_W 10
+#define PAD_GPIO11_W 11
+#define PAD_GPIO12_W 12
+#define PAD_GPIO13_W 13
+#define PAD_GPIO14_W 14
+#define PAD_GPIO15_W 15
+
+/* aon_iomux pins */
+#define PAD_RGPIO0 0
+#define PAD_RGPIO1 1
+#define PAD_RGPIO2 2
+#define PAD_RGPIO3 3
+#define PAD_RGPIO4 4
+#define PAD_RGPIO5 5
+#define PAD_RGPIO6 6
+#define PAD_RGPIO7 7
+#define PAD_RGPIO8 8
+#define PAD_RGPIO9 9
+#define PAD_RGPIO10 10
+#define PAD_RGPIO11 11
+#define PAD_RGPIO12 12
+#define PAD_RGPIO13 13
+#define PAD_RGPIO14 14
+#define PAD_RGPIO15 15
+
+/* sys_iomux_east dout */
+#define GPOUT_LOW 0
+#define GPOUT_HIGH 1
+#define GPOUT_SYS_CAN0_STBY 2
+#define GPOUT_SYS_CAN0_TST_NEXT_BIT 3
+#define GPOUT_SYS_CAN0_TST_SAMPLE_POINT 4
+#define GPOUT_SYS_CAN0_TXD 5
+#define GPOUT_SYS_I2C0_CLK 6
+#define GPOUT_SYS_I2C0_DATA 7
+#define GPOUT_SYS_I2S0_STEREO_RSCKO 8
+#define GPOUT_SYS_I2S0_STEREO_RWSO 9
+#define GPOUT_SYS_I2S0_STEREO_SDO_0 10
+#define GPOUT_SYS_I2S0_STEREO_SDO_1 11
+#define GPOUT_SYS_I2S0_STEREO_TSCKO 12
+#define GPOUT_SYS_I2S0_STEREO_TWSO 13
+#define GPOUT_SYS_SPI0_MO 14
+#define GPOUT_SYS_SPI0_SS0 15
+#define GPOUT_SYS_SPI0_SS1 16
+#define GPOUT_SYS_SPI0_SS2 17
+#define GPOUT_SYS_SPI0_SS3 18
+#define GPOUT_SYS_SPI0_SCLK 19
+#define GPOUT_SYS_SPI0_SO 20
+#define GPOUT_SYS_UART0_DTR 21
+#define GPOUT_SYS_UART0_RTS 22
+#define GPOUT_SYS_UART0_TX 23
+#define GPOUT_SYS_USB0_DBG_DRIVE_VBUS 24
+#define GPOUT_SYS_PDM_MCLK 25
+#define GPOUT_SYS_PWM_CHANNEL0 26
+#define GPOUT_SYS_PWM_CHANNEL1 27
+#define GPOUT_SYS_PWM_CHANNEL2 28
+#define GPOUT_SYS_PWM_CHANNEL3 29
+#define GPOUT_SYS_PWM_CHANNEL4 30
+#define GPOUT_SYS_PWM_CHANNEL5 31
+#define GPOUT_SYS_PWM_CHANNEL6 32
+#define GPOUT_SYS_PWM_CHANNEL7 33
+#define GPOUT_SYS_SMBUS0_CLK 34
+#define GPOUT_SYS_SMBUS0_DATA 35
+#define GPOUT_SYS_SMBUS0_SUSPEND 36
+#define GPOUT_SYS_CLK_GCLK1 37
+#define GPOUT_SYS_CLK_GCLK2 38
+#define GPOUT_SYS_CLK_GCLK3 39
+#define GPOUT_SYS_CLK_GCLK4 40
+#define GPOUT_SYS_CLK_GCLK6 41
+#define GPOUT_SYS_CLK_GCLK7 42
+#define GPOUT_SYS_MCLK 43
+#define GPOUT_SYS_USB0_TYPEC_DRIVE_VBUS 44
+#define GPOUT_SYS_WATCHDOG0_RESET 45
+#define GPOUT_SYS_CAN1_STBY 46
+#define GPOUT_SYS_CAN1_TST_NEXT_BIT 47
+#define GPOUT_SYS_CAN1_TST_SAMPLE_POINT 48
+#define GPOUT_SYS_CAN1_TXD 49
+#define GPOUT_SYS_I2C1_CLK 50
+#define GPOUT_SYS_I2C1_DATA 51
+#define GPOUT_SYS_I2S1_RSCKO 52
+#define GPOUT_SYS_I2S1_RWSO 53
+#define GPOUT_SYS_I2S1_SDO0 54
+#define GPOUT_SYS_I2S1_SDO1 55
+#define GPOUT_SYS_I2S1_SDO2 56
+#define GPOUT_SYS_I2S1_SDO3 57
+#define GPOUT_SYS_I2S1_SDO4 58
+#define GPOUT_SYS_I2S1_SDO5 59
+#define GPOUT_SYS_I2S1_SDO6 60
+#define GPOUT_SYS_I2S1_SDO7 61
+#define GPOUT_SYS_I2S1_TSCKO 62
+#define GPOUT_SYS_I2S1_TWSO 63
+#define GPOUT_SYS_SDIO1_PU_PD_DATA2 64
+#define GPOUT_SYS_SDIO1_BUS_POWER 65
+#define GPOUT_SYS_SDIO1_RESET 66
+#define GPOUT_SYS_SDIO1_BUS_VOLTAGE_0 67
+#define GPOUT_SYS_SDIO1_BUS_VOLTAGE_1 68
+#define GPOUT_SYS_SDIO1_BUS_VOLTAGE_2 69
+#define GPOUT_SYS_SDIO1_LED 70
+#define GPOUT_SYS_SPI1_MO 71
+#define GPOUT_SYS_SPI1_SS0 72
+#define GPOUT_SYS_SPI1_SS1 73
+#define GPOUT_SYS_SPI1_SS2 74
+#define GPOUT_SYS_SPI1_SS3 75
+#define GPOUT_SYS_SPI1_SCLK 76
+#define GPOUT_SYS_SPI1_SO 77
+#define GPOUT_SYS_UART1_DTR 78
+#define GPOUT_SYS_UART1_RTS 79
+#define GPOUT_SYS_UART1_TX 80
+#define GPOUT_SYS_USB1_DBG_DRIVE_VBUS 81
+#define GPOUT_SYS_I2C2_CLK 82
+#define GPOUT_SYS_I2C2_DATA 83
+#define GPOUT_SYS_UART2_DTR 84
+#define GPOUT_SYS_UART2_RTS 85
+#define GPOUT_SYS_UART2_TX 86
+#define GPOUT_SYS_USB2_DBG_DRIVE_VBUS 87
+#define GPOUT_SYS_I2C3_CLK 88
+#define GPOUT_SYS_I2C3_DATA 89
+#define GPOUT_SYS_UART3_DTR 90
+#define GPOUT_SYS_UART3_RTS 91
+#define GPOUT_SYS_UART3_TX 92
+#define GPOUT_SYS_USB3_DBG_DRIVE_VBUS 93
+#define GPOUT_SYS_I2C4_CLK 94
+#define GPOUT_SYS_I2C4_DATA 95
+#define GPOUT_SYS_UART4_DTR 96
+#define GPOUT_SYS_UART4_RTS 97
+#define GPOUT_SYS_UART4_TX 98
+#define GPOUT_SYS_I2C5_CLK 99
+#define GPOUT_SYS_I2C5_DATA 100
+
+/* sys_iomux_west dout */
+#define GPOUT_SYS_RSVD0 2
+#define GPOUT_SYS_RSVD1 3
+#define GPOUT_SYS_RSVD2 4
+#define GPOUT_SYS_RSVD3 5
+#define GPOUT_SYS_RSVD4 6
+#define GPOUT_SYS_RSVD5 7
+#define GPOUT_SYS_RSVD6 8
+#define GPOUT_SYS_RSVD7 9
+#define GPOUT_SYS_RSVD8 10
+#define GPOUT_SYS_HD_AUDIO0_BCLK 11
+#define GPOUT_SYS_HD_AUDIO0_RST 12
+#define GPOUT_SYS_HD_AUDIO0_SDI0_O 13
+#define GPOUT_SYS_HD_AUDIO0_SDI1_O 14
+#define GPOUT_SYS_HD_AUDIO0_SDO0 15
+#define GPOUT_SYS_HD_AUDIO0_SDO1 16
+#define GPOUT_SYS_HD_AUDIO0_SYNC 17
+#define GPOUT_SYS_HIFI4_JTAG_TDO 18
+#define GPOUT_SYS_CLK_GCLK5 19
+#define GPOUT_SYS_SMBUS1_CLK 20
+#define GPOUT_SYS_SMBUS1_DATA 21
+#define GPOUT_SYS_SMBUS1_SUSPEND 22
+#define GPOUT_SYS_SPI2_MO 23
+#define GPOUT_SYS_SPI2_SS0 24
+#define GPOUT_SYS_SPI2_SS1 25
+#define GPOUT_SYS_SPI2_SS2 26
+#define GPOUT_SYS_SPI2_SS3 27
+#define GPOUT_SYS_SPI2_SCLK 28
+#define GPOUT_SYS_SPI2_SO 29
+#define GPOUT_SYS_UART5_DTR 30
+#define GPOUT_SYS_UART5_RTS 31
+#define GPOUT_SYS_UART5_TX 32
+#define GPOUT_SYS_I2C6_CLK 33
+#define GPOUT_SYS_I2C6_DATA 34
+#define GPOUT_SYS_UART6_DTR 35
+#define GPOUT_SYS_UART6_RTS 36
+#define GPOUT_SYS_UART6_TX 37
+#define GPOUT_SYS_I2C7_CLK 38
+#define GPOUT_SYS_I2C7_DATA 39
+
+/* aon_iomux dout */
+#define GPOUT_AON_CLK_32K 2
+#define GPOUT_AON_CLK_GCLK0 3
+#define GPOUT_AON_CLK_GCLK_OSC 4
+#define GPOUT_AON_SIG_STUB_POWER_EN_O 5
+#define GPOUT_AON_EMMC_PU_PD_DATA2 6
+#define GPOUT_AON_EMMC_BUS_POWER 7
+#define GPOUT_AON_EMMC_BUS_VOLTAGE_0 8
+#define GPOUT_AON_EMMC_BUS_VOLTAGE_1 9
+#define GPOUT_AON_EMMC_BUS_VOLTAGE_2 10
+#define GPOUT_AON_EMMC_LED 11
+#define GPOUT_AON_SDIO0_PU_PD_DATA2 12
+#define GPOUT_AON_SDIO0_BUS_POWER 13
+#define GPOUT_AON_SDIO0_RESET 14
+#define GPOUT_AON_SDIO0_BUS_VOLTAGE_0 15
+#define GPOUT_AON_SDIO0_BUS_VOLTAGE_1 16
+#define GPOUT_AON_SDIO0_BUS_VOLTAGE_2 17
+#define GPOUT_AON_SDIO0_LED 18
+#define GPOUT_AON_JTAG_TDO 19
+#define GPOUT_AON_SCP_POWER_EN 20
+#define GPOUT_AON_WATCHDOG1_RESET 21
+#define GPOUT_AON_UART7_TX 22
+#define GPOUT_AON_I2C8_CLK 23
+#define GPOUT_AON_I2C8_DATA 24
+
+/* sys_iomux_east doen */
+#define GPOEN_SYS_ENABLE 0
+#define GPOEN_SYS_DISABLE 1
+#define GPOEN_SYS_I2C0_CLK 2
+#define GPOEN_SYS_I2C0_DATA 3
+#define GPOEN_SYS_I2S0_STEREO_SDOE_0 4
+#define GPOEN_SYS_I2S0_STEREO_SDOE_1 5
+#define GPOEN_SYS_SPI0_N_MO_EN 6
+#define GPOEN_SYS_SPI0_N_SCLK_EN 7
+#define GPOEN_SYS_SPI0_N_SO_EN 8
+#define GPOEN_SYS_SPI0_N_SS_EN 9
+#define GPOEN_SYS_PWM_CHANNEL0 10
+#define GPOEN_SYS_PWM_CHANNEL1 11
+#define GPOEN_SYS_PWM_CHANNEL2 12
+#define GPOEN_SYS_PWM_CHANNEL3 13
+#define GPOEN_SYS_PWM_CHANNEL4 14
+#define GPOEN_SYS_PWM_CHANNEL5 15
+#define GPOEN_SYS_PWM_CHANNEL6 16
+#define GPOEN_SYS_PWM_CHANNEL7 17
+#define GPOEN_SYS_SMBUS0_CLK 18
+#define GPOEN_SYS_SMBUS0_DATA 19
+#define GPOEN_SYS_SMBUS0_ALERT 20
+#define GPOEN_SYS_I2C1_CLK 21
+#define GPOEN_SYS_I2C1_DATA 22
+#define GPOEN_SYS_I2S1_SDO0 23
+#define GPOEN_SYS_I2S1_SDO1 24
+#define GPOEN_SYS_I2S1_SDO2 25
+#define GPOEN_SYS_I2S1_SDO3 26
+#define GPOEN_SYS_I2S1_SDO4 27
+#define GPOEN_SYS_I2S1_SDO5 28
+#define GPOEN_SYS_I2S1_SDO6 29
+#define GPOEN_SYS_I2S1_SDO7 30
+#define GPOEN_SYS_SPI1_N_MO_EN 31
+#define GPOEN_SYS_SPI1_N_SCLK_EN 32
+#define GPOEN_SYS_SPI1_N_SO_EN 33
+#define GPOEN_SYS_SPI1_N_SS_EN 34
+#define GPOEN_SYS_I2C2_CLK 35
+#define GPOEN_SYS_I2C2_DATA 36
+#define GPOEN_SYS_I2C3_CLK 37
+#define GPOEN_SYS_I2C3_DATA 38
+#define GPOEN_SYS_I2C4_CLK 39
+#define GPOEN_SYS_I2C4_DATA 40
+#define GPOEN_SYS_I2C5_CLK 41
+#define GPOEN_SYS_I2C5_DATA 42
+
+/* sys_iomux_west doen */
+#define GPOEN_SYS_RSVD0 2
+#define GPOEN_SYS_RSVD1 3
+#define GPOEN_SYS_RSVD2 4
+#define GPOEN_SYS_RSVD3 5
+#define GPOEN_SYS_RSVD4 6
+#define GPOEN_SYS_RSVD5 7
+#define GPOEN_SYS_RSVD6 8
+#define GPOEN_SYS_HD_AUDIO0_SDI0 9
+#define GPOEN_SYS_HD_AUDIO0_SDI1 10
+#define GPOEN_SYS_HIFI4_JTAG_TDO 11
+#define GPOEN_SYS_SMBUS1_CLK 12
+#define GPOEN_SYS_SMBUS1_DATA 13
+#define GPOEN_SYS_SMBUS1_ALERT 14
+#define GPOEN_SYS_SPI2_MO 15
+#define GPOEN_SYS_SPI2_SCLK 16
+#define GPOEN_SYS_SPI2_SO 17
+#define GPOEN_SYS_SPI2_SS 18
+#define GPOEN_SYS_I2C6_CLK 19
+#define GPOEN_SYS_I2C6_DATA 20
+#define GPOEN_SYS_I2C7_CLK 21
+#define GPOEN_SYS_I2C7_DATA 22
+
+/* aon_iomux doen */
+#define GPOEN_AON_JTAG_TDO 2
+#define GPOEN_AON_I2C8_CLK 3
+#define GPOEN_AON_I2C8_DATA 4
+
+/* sys_iomux din */
+#define GPI_NONE 255
+
+/* sys_iomux_east din */
+#define GPI_SYS_CAN0_RXD 0
+#define GPI_SYS_I2C0_CLK 1
+#define GPI_SYS_I2C0_DATA 2
+#define GPI_SYS_SPI0_SCLK 3
+#define GPI_SYS_SPI0_MI 4
+#define GPI_SYS_SPI0_SS_N 5
+#define GPI_SYS_SPI0_SI 6
+#define GPI_SYS_UART0_CTS 7
+#define GPI_SYS_UART0_DCD 8
+#define GPI_SYS_UART0_DSR 9
+#define GPI_SYS_UART0_RI 10
+#define GPI_SYS_UART0_RX 11
+#define GPI_SYS_USB0_DBG_OVERCURRENT 12
+#define GPI_SYS_PDM_DMIC0 13
+#define GPI_SYS_PDM_DMIC1 14
+#define GPI_SYS_I2SRX0_SDIN0 15
+#define GPI_SYS_I2SRX0_SDIN1 16
+#define GPI_SYS_SMBUS0_CLK 17
+#define GPI_SYS_SMBUS0_DATA 18
+#define GPI_SYS_SMBUS0_ALERT 19
+#define GPI_SYS_JTAG_TCK 20
+#define GPI_SYS_MCLK_EXT 21
+#define GPI_SYS_I2SRX0_BCLK 22
+#define GPI_SYS_I2SRX0_LRCK 23
+#define GPI_SYS_I2STX0_BCLK 24
+#define GPI_SYS_I2STX0_LRCK 25
+#define GPI_SYS_SPI0_SCLK_IN0 26
+#define GPI_SYS_SPI0_SCLK_IN1 27
+#define GPI_SYS_I2S0_STEREO_RX_BCLK 28
+#define GPI_SYS_I2S0_STEREO_RX_LRCK 29
+#define GPI_SYS_I2S0_STEREO_TX_BCLK 30
+#define GPI_SYS_I2S0_STEREO_TX_LRCK 31
+#define GPI_SYS_I2S1_RX_BCLK 32
+#define GPI_SYS_I2S1_RX_LRCK 33
+#define GPI_SYS_I2S1_TX_BCLK 34
+#define GPI_SYS_I2S1_TX_LRCK 35
+#define GPI_SYS_USB0_TYPEC_OVERCURRENT 36
+#define GPI_SYS_CAN1_RXD 37
+#define GPI_SYS_I2C1_CLK 38
+#define GPI_SYS_I2C1_DATA 39
+#define GPI_SYS_I2S1_SDI_0 40
+#define GPI_SYS_I2S1_SDI_1 41
+#define GPI_SYS_I2S1_SDI_2 42
+#define GPI_SYS_I2S1_SDI_3 43
+#define GPI_SYS_I2S1_SDI_4 44
+#define GPI_SYS_I2S1_SDI_5 45
+#define GPI_SYS_I2S1_SDI_6 46
+#define GPI_SYS_I2S1_SDI_7 47
+#define GPI_SYS_SDIO1_CARD_DETECT 48
+#define GPI_SYS_SDIO1_WRITE_PROTECT 49
+#define GPI_SYS_SPI1_EXT_CLK 50
+#define GPI_SYS_SPI1_MI 51
+#define GPI_SYS_SPI1_SS_IN 52
+#define GPI_SYS_SPI1_SI 53
+#define GPI_SYS_UART1_CTS 54
+#define GPI_SYS_UART1_DCD 55
+#define GPI_SYS_UART1_DSR 56
+#define GPI_SYS_UART1_RI 57
+#define GPI_SYS_UART1_RX 58
+#define GPI_SYS_USB1_DBG_OVERCURRENT 59
+#define GPI_SYS_I2C2_CLK 60
+#define GPI_SYS_I2C2_DATA 61
+#define GPI_SYS_UART2_CTS 62
+#define GPI_SYS_UART2_DCD 63
+#define GPI_SYS_UART2_DSR 64
+#define GPI_SYS_UART2_RI 65
+#define GPI_SYS_UART2_RX 66
+#define GPI_SYS_USB2_DBG_OVERCURRENT 67
+#define GPI_SYS_I2C3_CLK 68
+#define GPI_SYS_I2C3_DATA 69
+#define GPI_SYS_UART3_CTS 70
+#define GPI_SYS_UART3_DCD 71
+#define GPI_SYS_UART3_DSR 72
+#define GPI_SYS_UART3_RI 73
+#define GPI_SYS_UART3_RX 74
+#define GPI_SYS_USB3_DBG_OVERCURRENT 75
+#define GPI_SYS_I2C4_CLK 76
+#define GPI_SYS_I2C4_DATA 77
+#define GPI_SYS_UART4_CTS 78
+#define GPI_SYS_UART4_DCD 79
+#define GPI_SYS_UART4_DSR 80
+#define GPI_SYS_UART4_RI 81
+#define GPI_SYS_UART4_RX 82
+#define GPI_SYS_I2C5_CLK 83
+#define GPI_SYS_I2C5_DATA 84
+
+/* sys_iomux_west din */
+#define GPI_SYS_RSVD0 0
+#define GPI_SYS_RSVD1 1
+#define GPI_SYS_RSVD2 2
+#define GPI_SYS_RSVD3 3
+#define GPI_SYS_RSVD4 4
+#define GPI_SYS_RSVD5 5
+#define GPI_SYS_RSVD6 6
+#define GPI_SYS_HD_AUDIO0_SDI0_I 7
+#define GPI_SYS_HD_AUDIO0_SDI1_I 8
+#define GPI_SYS_HIFI4_JTAG_TDI 9
+#define GPI_SYS_HIFI4_JTAG_TMS 10
+#define GPI_SYS_HIFI4_JTAG_RST 11
+#define GPI_SYS_RSVD7 12
+#define GPI_SYS_HIFI4_JTAG_TCK 13
+#define GPI_SYS_RSVD8 14
+#define GPI_SYS_SPI0_SCLK_IN2 15
+#define GPI_SYS_SMBUS1_CLK 16
+#define GPI_SYS_SMBUS1_DATA 17
+#define GPI_SYS_SMBUS1_ALERT 18
+#define GPI_SYS_SPI2_EXT_CLK 19
+#define GPI_SYS_SPI2_MI 20
+#define GPI_SYS_SPI2_SS_IN 21
+#define GPI_SYS_SPI2_SI 22
+#define GPI_SYS_UART5_CTS 23
+#define GPI_SYS_UART5_DCD 24
+#define GPI_SYS_UART5_DSR 25
+#define GPI_SYS_UART5_RI 26
+#define GPI_SYS_UART5_RX 27
+#define GPI_SYS_I2C6_CLK 28
+#define GPI_SYS_I2C6_DATA 29
+#define GPI_SYS_UART6_CTS 30
+#define GPI_SYS_UART6_DCD 31
+#define GPI_SYS_UART6_DSR 32
+#define GPI_SYS_UART6_RI 33
+#define GPI_SYS_UART6_RX 34
+#define GPI_SYS_I2C7_CLK 35
+#define GPI_SYS_I2C7_DATA 36
+
+/* aon_iomux din */
+#define GPI_AON_JTAG_TCK 0
+#define GPI_AON_SIG_STUB_RESERVED_0 1
+#define GPI_AON_SIG_STUB_RESERVED_1 2
+#define GPI_AON_SIG_STUB_RESERVED_2 3
+#define GPI_AON_XSPI0_GP_OPEN_DRAIN_0 4
+#define GPI_AON_XSPI0_GP_OPEN_DRAIN_1 5
+#define GPI_AON_XSPI0_GP_OPEN_DRAIN_2 6
+#define GPI_AON_XSPI0_GP_OPEN_DRAIN_3 7
+#define GPI_AON_SDIO0_CARD_DETECTION 8
+#define GPI_AON_SDIO0_WRITE_PROTECTION 9
+#define GPI_AON_SRC_BUF_JTAG_RST 10
+#define GPI_AON_JTAG_TDI 11
+#define GPI_AON_JTAG_TMS 12
+#define GPI_AON_UART7_RX 13
+#define GPI_AON_I2C8_CLK 14
+#define GPI_AON_I2C8_DATA 15
+
+#endif
diff --git a/arch/riscv/boot/dts/starfive/jh8100.dtsi b/arch/riscv/boot/dts/starfive/jh8100.dtsi
index 5ba826e38ead..37251010d96f 100644
--- a/arch/riscv/boot/dts/starfive/jh8100.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh8100.dtsi
@@ -5,6 +5,7 @@
/dts-v1/;
#include <dt-bindings/clock/starfive,jh8100-crg.h>
+#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/reset/starfive,jh8100-crg.h>
/ {
@@ -563,6 +564,19 @@ uart4: serial@121a0000 {
status = "disabled";
};
+ pinctrl_east: pinctrl@122d0000 {
+ compatible = "starfive,jh8100-sys-pinctrl-east",
+ "syscon", "simple-mfd";
+ reg = <0x0 0x122d0000 0x0 0x10000>;
+ clocks = <&necrg JH8100_NECLK_IOMUX_EAST_PCLK>;
+ resets = <&necrg JH8100_NERST_SYS_IOMUX_E>;
+ interrupts = <182>;
+ interrupt-controller;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl_east 0 0 48>;
+ };
+
necrg: clock-controller@12320000 {
compatible = "starfive,jh8100-necrg";
reg = <0x0 0x12320000 0x0 0x10000>;
@@ -634,6 +648,19 @@ nwcrg: clock-controller@123c0000 {
#reset-cells = <1>;
};
+ pinctrl_west: pinctrl@123e0000 {
+ compatible = "starfive,jh8100-sys-pinctrl-west",
+ "syscon", "simple-mfd";
+ reg = <0x0 0x123e0000 0x0 0x10000>;
+ clocks = <&nwcrg JH8100_NWCLK_IOMUX_WEST_PCLK>;
+ resets = <&nwcrg JH8100_NWRST_SYS_IOMUX_W>;
+ interrupts = <183>;
+ interrupt-controller;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl_west 0 0 16>;
+ };
+
syscrg: clock-controller@126d0000 {
compatible = "starfive,jh8100-syscrg";
reg = <0x0 0x126d0000 0x0 0x10000>;
@@ -656,6 +683,13 @@ swcrg: clock-controller@12720000 {
#reset-cells = <1>;
};
+ pinctrl_gmac: pinctrl@12770000 {
+ compatible = "starfive,jh8100-sys-pinctrl-gmac",
+ "syscon", "simple-mfd";
+ status = "disabled";
+ reg = <0x0 0x12770000 0x0 0x10000>;
+ };
+
uart5: serial@127d0000 {
compatible = "starfive,jh8100-uart", "cdns,uart-r1p8";
reg = <0x0 0x127d0000 0x0 0x10000>;
@@ -674,6 +708,18 @@ uart6: serial@127e0000 {
status = "disabled";
};
+ pinctrl_aon: pinctrl@1f300000 {
+ compatible = "starfive,jh8100-aon-pinctrl",
+ "syscon", "simple-mfd";
+ reg = <0x0 0x1f300000 0x0 0x10000>;
+ resets = <&aoncrg JH8100_AONRST_AON_IOMUX_PRESETN>;
+ interrupts = <160>;
+ interrupt-controller;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl_aon 0 0 16>;
+ };
+
aoncrg: clock-controller@1f310000 {
compatible = "starfive,jh8100-aoncrg";
reg = <0x0 0x1f310000 0x0 0x10000>;
--
2.25.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [RFC PATCH v3 0/7] Add Pinctrl driver for Starfive JH8100 SoC
2024-05-03 11:14 [RFC PATCH v3 0/7] Add Pinctrl driver for Starfive JH8100 SoC Alex Soo
` (6 preceding siblings ...)
2024-05-03 11:14 ` [RFC PATCH v3 7/7] riscv: dts: starfive: jh8100: add pinctrl device tree nodes Alex Soo
@ 2024-05-06 6:35 ` Linus Walleij
2024-05-06 7:31 ` Leyfoon Tan
2024-05-06 20:25 ` Andy Shevchenko
8 siblings, 1 reply; 18+ messages in thread
From: Linus Walleij @ 2024-05-06 6:35 UTC (permalink / raw)
To: Alex Soo
Cc: Bartosz Golaszewski, Hal Feng, Ley Foon Tan, Jianlong Huang,
Emil Renner Berthing, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Drew Fustini, linux-gpio, linux-kernel, devicetree,
linux-riscv, Paul Walmsley, Palmer Dabbelt, Albert Ou
On Fri, May 3, 2024 at 1:14 PM Alex Soo <yuklin.soo@starfivetech.com> wrote:
> Starfive JH8100 SoC consists of 4 pinctrl domains - sys_east,
> sys_west, sys_gmac, and aon. This patch series adds pinctrl
> drivers for these 4 pinctrl domains and this patch series is
> depending on the JH8100 base patch series in [1] and [2].
> The relevant dt-binding documentation for each pinctrl domain has
> been updated accordingly.
>
> [1] https://lore.kernel.org/lkml/20231201121410.95298-1-jeeheng.sia@starfivetech.com/
> [2] https://lore.kernel.org/lkml/20231206115000.295825-1-jeeheng.sia@starfivetech.com/
v3 is starting to look very nice, why is this patch set still in "RFC"?
I would like some proper review from the StarFive maintainers
at this point so we can get it finished.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 18+ messages in thread* RE: [RFC PATCH v3 0/7] Add Pinctrl driver for Starfive JH8100 SoC
2024-05-06 6:35 ` [RFC PATCH v3 0/7] Add Pinctrl driver for Starfive JH8100 SoC Linus Walleij
@ 2024-05-06 7:31 ` Leyfoon Tan
2024-05-06 12:09 ` Conor Dooley
0 siblings, 1 reply; 18+ messages in thread
From: Leyfoon Tan @ 2024-05-06 7:31 UTC (permalink / raw)
To: Linus Walleij, Yuklin Soo
Cc: Bartosz Golaszewski, Hal Feng, Emil Renner Berthing, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Drew Fustini,
linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org, linux-riscv@lists.infradead.org,
Paul Walmsley, Palmer Dabbelt, Albert Ou
> -----Original Message-----
> From: Linus Walleij <linus.walleij@linaro.org>
> Sent: Monday, May 6, 2024 2:35 PM
> To: Yuklin Soo <yuklin.soo@starfivetech.com>
> Cc: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>; Hal Feng
> <hal.feng@starfivetech.com>; Leyfoon Tan <leyfoon.tan@starfivetech.com>;
> Jianlong Huang <jianlong.huang@starfivetech.com>; Emil Renner Berthing
> <kernel@esmil.dk>; Rob Herring <robh@kernel.org>; Krzysztof Kozlowski
> <krzysztof.kozlowski+dt@linaro.org>; Conor Dooley <conor+dt@kernel.org>;
> Drew Fustini <drew@beagleboard.org>; linux-gpio@vger.kernel.org; linux-
> kernel@vger.kernel.org; devicetree@vger.kernel.org; linux-
> riscv@lists.infradead.org; Paul Walmsley <paul.walmsley@sifive.com>; Palmer
> Dabbelt <palmer@dabbelt.com>; Albert Ou <aou@eecs.berkeley.edu>
> Subject: Re: [RFC PATCH v3 0/7] Add Pinctrl driver for Starfive JH8100 SoC
>
> On Fri, May 3, 2024 at 1:14 PM Alex Soo <yuklin.soo@starfivetech.com>
> wrote:
>
> > Starfive JH8100 SoC consists of 4 pinctrl domains - sys_east,
> > sys_west, sys_gmac, and aon. This patch series adds pinctrl drivers
> > for these 4 pinctrl domains and this patch series is depending on the
> > JH8100 base patch series in [1] and [2].
> > The relevant dt-binding documentation for each pinctrl domain has been
> > updated accordingly.
> >
> > [1]
> > https://lore.kernel.org/lkml/20231201121410.95298-1-jeeheng.sia@starfi
> > vetech.com/ [2]
> > https://lore.kernel.org/lkml/20231206115000.295825-1-
> jeeheng.sia@starf
> > ivetech.com/
>
> v3 is starting to look very nice, why is this patch set still in "RFC"?
>
> I would like some proper review from the StarFive maintainers at this point so
> we can get it finished.
>
> Yours,
> Linus Walleij
Hi Linus
Thanks for reviewing the patches.
There is a discussion in another thread about the JH8100 SoC being validated on FPGA/Emulation only now. The suggestion is to send the patches as "RFC" before the real silicon availability.
https://patchew.org/linux/20231201121410.95298-1-jeeheng.sia@starfivetech.com/20231201121410.95298-3-jeeheng.sia@starfivetech.com/
Regards
Ley Foon
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC PATCH v3 0/7] Add Pinctrl driver for Starfive JH8100 SoC
2024-05-06 7:31 ` Leyfoon Tan
@ 2024-05-06 12:09 ` Conor Dooley
0 siblings, 0 replies; 18+ messages in thread
From: Conor Dooley @ 2024-05-06 12:09 UTC (permalink / raw)
To: Leyfoon Tan
Cc: Linus Walleij, Yuklin Soo, Bartosz Golaszewski, Hal Feng,
Emil Renner Berthing, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Drew Fustini, linux-gpio@vger.kernel.org,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
linux-riscv@lists.infradead.org, Paul Walmsley, Palmer Dabbelt,
Albert Ou
[-- Attachment #1: Type: text/plain, Size: 2599 bytes --]
On Mon, May 06, 2024 at 07:31:19AM +0000, Leyfoon Tan wrote:
>
>
> > -----Original Message-----
> > From: Linus Walleij <linus.walleij@linaro.org>
> > Sent: Monday, May 6, 2024 2:35 PM
> > To: Yuklin Soo <yuklin.soo@starfivetech.com>
> > Cc: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>; Hal Feng
> > <hal.feng@starfivetech.com>; Leyfoon Tan <leyfoon.tan@starfivetech.com>;
> > Jianlong Huang <jianlong.huang@starfivetech.com>; Emil Renner Berthing
> > <kernel@esmil.dk>; Rob Herring <robh@kernel.org>; Krzysztof Kozlowski
> > <krzysztof.kozlowski+dt@linaro.org>; Conor Dooley <conor+dt@kernel.org>;
> > Drew Fustini <drew@beagleboard.org>; linux-gpio@vger.kernel.org; linux-
> > kernel@vger.kernel.org; devicetree@vger.kernel.org; linux-
> > riscv@lists.infradead.org; Paul Walmsley <paul.walmsley@sifive.com>; Palmer
> > Dabbelt <palmer@dabbelt.com>; Albert Ou <aou@eecs.berkeley.edu>
> > Subject: Re: [RFC PATCH v3 0/7] Add Pinctrl driver for Starfive JH8100 SoC
> >
> > On Fri, May 3, 2024 at 1:14 PM Alex Soo <yuklin.soo@starfivetech.com>
> > wrote:
> >
> > > Starfive JH8100 SoC consists of 4 pinctrl domains - sys_east,
> > > sys_west, sys_gmac, and aon. This patch series adds pinctrl drivers
> > > for these 4 pinctrl domains and this patch series is depending on the
> > > JH8100 base patch series in [1] and [2].
> > > The relevant dt-binding documentation for each pinctrl domain has been
> > > updated accordingly.
> > >
> > > [1]
> > > https://lore.kernel.org/lkml/20231201121410.95298-1-jeeheng.sia@starfi
> > > vetech.com/ [2]
> > > https://lore.kernel.org/lkml/20231206115000.295825-1-
> > jeeheng.sia@starf
> > > ivetech.com/
> >
> > v3 is starting to look very nice, why is this patch set still in "RFC"?
> >
> > I would like some proper review from the StarFive maintainers at this point so
> > we can get it finished.
> >
> > Yours,
> > Linus Walleij
>
> Hi Linus
>
> Thanks for reviewing the patches.
>
> There is a discussion in another thread about the JH8100 SoC being validated on FPGA/Emulation only now. The suggestion is to send the patches as "RFC" before the real silicon availability.
>
> https://patchew.org/linux/20231201121410.95298-1-jeeheng.sia@starfivetech.com/20231201121410.95298-3-jeeheng.sia@starfivetech.com/
I know I said "drivers" in that mail you link to, but I was mostly
concerned about binding headers etc, of which I think there are actually
none here, so see my reply to this thread a few days ago:
https://lore.kernel.org/all/20240503-undress-mantra-e5e46b2f6360@spud/
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC PATCH v3 0/7] Add Pinctrl driver for Starfive JH8100 SoC
2024-05-03 11:14 [RFC PATCH v3 0/7] Add Pinctrl driver for Starfive JH8100 SoC Alex Soo
` (7 preceding siblings ...)
2024-05-06 6:35 ` [RFC PATCH v3 0/7] Add Pinctrl driver for Starfive JH8100 SoC Linus Walleij
@ 2024-05-06 20:25 ` Andy Shevchenko
8 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2024-05-06 20:25 UTC (permalink / raw)
To: Alex Soo
Cc: Linus Walleij, Bartosz Golaszewski, Hal Feng, Ley Foon Tan,
Jianlong Huang, Emil Renner Berthing, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Drew Fustini, linux-gpio,
linux-kernel, devicetree, linux-riscv, Paul Walmsley,
Palmer Dabbelt, Albert Ou
Fri, May 03, 2024 at 07:14:29PM +0800, Alex Soo kirjoitti:
> Starfive JH8100 SoC consists of 4 pinctrl domains - sys_east,
> sys_west, sys_gmac, and aon. This patch series adds pinctrl
> drivers for these 4 pinctrl domains and this patch series is
> depending on the JH8100 base patch series in [1] and [2].
> The relevant dt-binding documentation for each pinctrl domain has
> been updated accordingly.
I commented one of pinctrl: prefixed patch, but it looks like the same comments
are applicable to all of them.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 18+ messages in thread