diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-03-14 10:22:26 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-03-14 10:22:26 -0700 |
commit | a3df5d5422b4edfcfe658d5057e7e059571e32ce (patch) | |
tree | bae26f25c2902a31d234faf2bd2459c1fc303fc0 | |
parent | 44f89c6d3c54761114b2bc0509144e3e5ced40b0 (diff) | |
parent | fa63587f94a77a49b53274dc0fd1ea41dfde5966 (diff) |
Merge tag 'pinctrl-v6.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pin control updates from Linus Walleij:
"No core changes this time around.
New drivers:
- New driver for Renesas R8A779H0 also known as R-Car V4M.
- New driver for the Awinic AW9523/B I2C GPIO expander. I found this
living out-of-tree in OpenWrt as an upstream attempt had stalled on
the finishing line, so I picked it up and finished the job.
Improvements:
- The Nomadik pin control driver was for years re-used out of tree
for the ST STA chips, and now the IP was re-used in a MIPS
automotive SoC called MobilEyeq5, so it has been split in pin
control and GPIO drivers so the latter can be reused by MobilEyeq5.
(Along with a long list of cleanups)
- A lot of overall cleanup and tidying up"
* tag 'pinctrl-v6.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (87 commits)
drivers/gpio/nomadik: move dummy nmk_gpio_dbg_show_one() to header
gpio: nomadik: remove BUG_ON() in nmk_gpio_populate_chip()
dt-bindings: pinctrl: qcom: update compatible name for match with driver
pinctrl: aw9523: Make the driver tristate
pinctrl: nomadik: fix dereference of error pointer
gpio: nomadik: Back out some managed resources
pinctrl: aw9523: Add proper terminator
pinctrl: core: comment that pinctrl_add_gpio_range() is deprecated
pinctrl: pinmux: Suppress error message for -EPROBE_DEFER
pinctrl: Add driver for Awinic AW9523/B I2C GPIO Expander
dt-bindings: pinctrl: Add bindings for Awinic AW9523/AW9523B
gpio: nomadik: Finish conversion to use firmware node APIs
gpio: nomadik: fix Kconfig dependencies inbetween pinctrl & GPIO
pinctrl: da9062: Add OF table
dt-bindings: pinctrl: at91: add sam9x7
pinctrl: ocelot: remove redundant assignment to variable ret
gpio: nomadik: grab optional reset control and deassert it at probe
gpio: nomadik: support mobileye,eyeq5-gpio
gpio: nomadik: handle variadic GPIO count
gpio: nomadik: support shared GPIO IRQs
...
55 files changed, 7496 insertions, 1046 deletions
diff --git a/Documentation/devicetree/bindings/gpio/gpio-nmk.txt b/Documentation/devicetree/bindings/gpio/gpio-nmk.txt deleted file mode 100644 index 8315ac7780ef..000000000000 --- a/Documentation/devicetree/bindings/gpio/gpio-nmk.txt +++ /dev/null @@ -1,31 +0,0 @@ -Nomadik GPIO controller - -Required properties: -- compatible : Should be "st,nomadik-gpio". -- reg : Physical base address and length of the controller's registers. -- interrupts : The interrupt outputs from the controller. -- #gpio-cells : Should be two: - The first cell is the pin number. - The second cell is used to specify optional parameters: - - bits[3:0] trigger type and level flags: - 1 = low-to-high edge triggered. - 2 = high-to-low edge triggered. - 4 = active high level-sensitive. - 8 = active low level-sensitive. -- gpio-controller : Marks the device node as a GPIO controller. -- interrupt-controller : Marks the device node as an interrupt controller. -- gpio-bank : Specifies which bank a controller owns. -- st,supports-sleepmode : Specifies whether controller can sleep or not - -Example: - - gpio1: gpio@8012e080 { - compatible = "st,nomadik-gpio"; - reg = <0x8012e080 0x80>; - interrupts = <0 120 0x4>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - st,supports-sleepmode; - gpio-bank = <1>; - }; diff --git a/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml b/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml new file mode 100644 index 000000000000..38d37d8f7201 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml @@ -0,0 +1,95 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gpio/st,nomadik-gpio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Nomadik GPIO controller + +description: + The Nomadik GPIO driver handles Nomadik SoC GPIO blocks. This block has also + been called ST STA2X11. On the Nomadik platform, this driver is intertwined + with pinctrl-nomadik. + +maintainers: + - Linus Walleij <linus.walleij@linaro.org> + +properties: + $nodename: + pattern: "^gpio@[0-9a-f]+$" + + compatible: + enum: + - st,nomadik-gpio + - mobileye,eyeq5-gpio + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + "#gpio-cells": + const: 2 + + gpio-controller: true + + interrupt-controller: true + + "#interrupt-cells": + const: 2 + + gpio-bank: + description: System-wide GPIO bank index. + $ref: /schemas/types.yaml#/definitions/uint32 + + st,supports-sleepmode: + description: Whether the controller can sleep or not. + $ref: /schemas/types.yaml#/definitions/flag + + clocks: + maxItems: 1 + + gpio-ranges: + maxItems: 1 + + ngpios: + minimum: 0 + maximum: 32 + + resets: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - "#gpio-cells" + - gpio-controller + - interrupt-controller + - gpio-bank + +unevaluatedProperties: false + +allOf: + - if: + properties: + compatible: + contains: + const: mobileye,eyeq5-gpio + then: + properties: + st,supports-sleepmode: false + +examples: + - | + gpio@8012e080 { + compatible = "st,nomadik-gpio"; + reg = <0x8012e080 0x80>; + interrupts = <0 120 0x4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + st,supports-sleepmode; + gpio-bank = <1>; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/amlogic,meson-pinctrl-a1.yaml b/Documentation/devicetree/bindings/pinctrl/amlogic,meson-pinctrl-a1.yaml index c7df4cd34197..d9e0b2c48e84 100644 --- a/Documentation/devicetree/bindings/pinctrl/amlogic,meson-pinctrl-a1.yaml +++ b/Documentation/devicetree/bindings/pinctrl/amlogic,meson-pinctrl-a1.yaml @@ -24,7 +24,7 @@ required: - compatible patternProperties: - "^bank@[0-9a-z]+$": + "^bank@[0-9a-f]+$": $ref: amlogic,meson-pinctrl-common.yaml#/$defs/meson-gpio unevaluatedProperties: false diff --git a/Documentation/devicetree/bindings/pinctrl/amlogic,meson-pinctrl-g12a-aobus.yaml b/Documentation/devicetree/bindings/pinctrl/amlogic,meson-pinctrl-g12a-aobus.yaml index 0942ea60c6cd..108719bde0d0 100644 --- a/Documentation/devicetree/bindings/pinctrl/amlogic,meson-pinctrl-g12a-aobus.yaml +++ b/Documentation/devicetree/bindings/pinctrl/amlogic,meson-pinctrl-g12a-aobus.yaml @@ -21,7 +21,7 @@ required: - compatible patternProperties: - "^bank@[0-9a-z]+$": + "^bank@[0-9a-f]+$": $ref: amlogic,meson-pinctrl-common.yaml#/$defs/meson-gpio unevaluatedProperties: false diff --git a/Documentation/devicetree/bindings/pinctrl/amlogic,meson-pinctrl-g12a-periphs.yaml b/Documentation/devicetree/bindings/pinctrl/amlogic,meson-pinctrl-g12a-periphs.yaml index e3c8bde30559..dc277f2e2edf 100644 --- a/Documentation/devicetree/bindings/pinctrl/amlogic,meson-pinctrl-g12a-periphs.yaml +++ b/Documentation/devicetree/bindings/pinctrl/amlogic,meson-pinctrl-g12a-periphs.yaml @@ -21,7 +21,7 @@ required: - compatible patternProperties: - "^bank@[0-9a-z]+$": + "^bank@[0-9a-f]+$": $ref: amlogic,meson-pinctrl-common.yaml#/$defs/meson-gpio unevaluatedProperties: false diff --git a/Documentation/devicetree/bindings/pinctrl/amlogic,meson8-pinctrl-aobus.yaml b/Documentation/devicetree/bindings/pinctrl/amlogic,meson8-pinctrl-aobus.yaml index c1b03147e8ec..add83c676327 100644 --- a/Documentation/devicetree/bindings/pinctrl/amlogic,meson8-pinctrl-aobus.yaml +++ b/Documentation/devicetree/bindings/pinctrl/amlogic,meson8-pinctrl-aobus.yaml @@ -29,7 +29,7 @@ required: - compatible patternProperties: - "^bank@[0-9a-z]+$": + "^bank@[0-9a-f]+$": $ref: amlogic,meson-pinctrl-common.yaml#/$defs/meson-gpio unevaluatedProperties: false diff --git a/Documentation/devicetree/bindings/pinctrl/amlogic,meson8-pinctrl-cbus.yaml b/Documentation/devicetree/bindings/pinctrl/amlogic,meson8-pinctrl-cbus.yaml index 4ec85b8248fa..412bbcc276f3 100644 --- a/Documentation/devicetree/bindings/pinctrl/amlogic,meson8-pinctrl-cbus.yaml +++ b/Documentation/devicetree/bindings/pinctrl/amlogic,meson8-pinctrl-cbus.yaml @@ -29,7 +29,7 @@ required: - compatible patternProperties: - "^bank@[0-9a-z]+$": + "^bank@[0-9a-f]+$": $ref: amlogic,meson-pinctrl-common.yaml#/$defs/meson-gpio unevaluatedProperties: false diff --git a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt index e8abbdad7b5d..0aa1a53012d6 100644 --- a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt @@ -20,6 +20,7 @@ such as pull-up, multi drive, etc. Required properties for iomux controller: - compatible: "atmel,at91rm9200-pinctrl" or "atmel,at91sam9x5-pinctrl" or "atmel,sama5d3-pinctrl" or "microchip,sam9x60-pinctrl" + or "microchip,sam9x7-pinctrl", "microchip,sam9x60-pinctrl" - atmel,mux-mask: array of mask (periph per bank) to describe if a pin can be configured in this periph mode. All the periph and bank need to be describe. @@ -120,6 +121,7 @@ Some requirements for using atmel,at91rm9200-pinctrl binding: For each bank the required properties are: - compatible: "atmel,at91sam9x5-gpio" or "atmel,at91rm9200-gpio" or "microchip,sam9x60-gpio" + or "microchip,sam9x7-gpio", "microchip,sam9x60-gpio", "atmel,at91rm9200-gpio" - reg: physical base address and length of the controller's registers - interrupts: interrupt outputs from the controller - interrupt-controller: marks the device node as an interrupt controller diff --git a/Documentation/devicetree/bindings/pinctrl/awinic,aw9523-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/awinic,aw9523-pinctrl.yaml new file mode 100644 index 000000000000..98c310a3c63c --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/awinic,aw9523-pinctrl.yaml @@ -0,0 +1,139 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/awinic,aw9523-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Awinic AW9523/AW9523B I2C GPIO Expander + +maintainers: + - AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org> + +description: | + The Awinic AW9523/AW9523B I2C GPIO Expander featuring 16 multi-function + I/O, 256 steps PWM mode and interrupt support. + +properties: + compatible: + const: awinic,aw9523-pinctrl + + reg: + maxItems: 1 + + '#gpio-cells': + description: | + Specifying the pin number and flags, as defined in + include/dt-bindings/gpio/gpio.h + const: 2 + + gpio-controller: true + + gpio-ranges: + maxItems: 1 + + interrupt-controller: true + + interrupts: + maxItems: 1 + description: Specifies the INTN pin IRQ. + + '#interrupt-cells': + description: + Specifies the PIN numbers and Flags, as defined in defined in + include/dt-bindings/interrupt-controller/irq.h + const: 2 + + reset-gpios: + maxItems: 1 + +# PIN CONFIGURATION NODES +patternProperties: + '-pins$': + type: object + description: + Pinctrl node's client devices use subnodes for desired pin configuration. + Client device subnodes use below standard properties. + $ref: /schemas/pinctrl/pincfg-node.yaml + + properties: + pins: + description: + List of gpio pins affected by the properties specified in + this subnode. + items: + pattern: "^gpio([0-9]|1[0-5])$" + minItems: 1 + maxItems: 16 + + function: + description: + Specify the alternative function to be configured for the + specified pins. + + enum: [ gpio, pwm ] + + bias-disable: true + bias-pull-down: true + bias-pull-up: true + drive-open-drain: true + drive-push-pull: true + input-enable: true + input-disable: true + output-high: true + output-low: true + + required: + - pins + - function + + additionalProperties: false + +required: + - compatible + - reg + - gpio-controller + - '#gpio-cells' + - gpio-ranges + +additionalProperties: false + +examples: + # Example configuration to drive pins for a keyboard matrix + - | + #include <dt-bindings/gpio/gpio.h> + #include <dt-bindings/interrupt-controller/irq.h> + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + aw9523: gpio-expander@58 { + compatible = "awinic,aw9523-pinctrl"; + reg = <0x58>; + interrupt-parent = <&tlmm>; + interrupts = <50 IRQ_TYPE_EDGE_FALLING>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&tlmm 0 0 16>; + interrupt-controller; + #interrupt-cells = <2>; + reset-gpios = <&tlmm 51 GPIO_ACTIVE_HIGH>; + + keyboard-matrix-col-pins { + pins = "gpio8", "gpio9", "gpio10", "gpio11", + "gpio12", "gpio13", "gpio14", "gpio15"; + function = "gpio"; + input-disable; + output-low; + }; + + keyboard-matrix-row-pins { + pins = "gpio0", "gpio1", "gpio2", "gpio3", + "gpio4", "gpio5", "gpio6", "gpio7"; + function = "gpio"; + bias-pull-up; + drive-open-drain; + input-enable; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/cirrus,madera.yaml b/Documentation/devicetree/bindings/pinctrl/cirrus,madera.yaml index bb61a30321a1..482acda88e73 100644 --- a/Documentation/devicetree/bindings/pinctrl/cirrus,madera.yaml +++ b/Documentation/devicetree/bindings/pinctrl/cirrus,madera.yaml @@ -93,7 +93,8 @@ properties: input-schmitt-disable: true - input-debounce: true + input-debounce: + maxItems: 1 output-low: true diff --git a/Documentation/devicetree/bindings/pinctrl/cypress,cy8c95x0.yaml b/Documentation/devicetree/bindings/pinctrl/cypress,cy8c95x0.yaml index 7f30ec2f1e54..700ac86c26b6 100644 --- a/Documentation/devicetree/bindings/pinctrl/cypress,cy8c95x0.yaml +++ b/Documentation/devicetree/bindings/pinctrl/cypress,cy8c95x0.yaml @@ -45,7 +45,8 @@ properties: maxItems: 1 gpio-reserved-ranges: - maxItems: 1 + minItems: 1 + maxItems: 60 vdd-supply: description: @@ -85,6 +86,8 @@ patternProperties: bias-disable: true + input-enable: true + output-high: true output-low: true @@ -133,6 +136,23 @@ examples: interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>; interrupt-controller; vdd-supply = <&p3v3>; - gpio-reserved-ranges = <5 1>; + gpio-reserved-ranges = <1 2>, <6 1>, <10 1>, <15 1>; + + pinctrl-0 = <&U62160_pins>, <&U62160_ipins>; + pinctrl-names = "default"; + + U62160_pins: cfg-pins { + pins = "gp03", "gp16", "gp20", "gp50", "gp51"; + function = "gpio"; + input-enable; + bias-pull-up; + }; + + U62160_ipins: icfg-pins { + pins = "gp04", "gp17", "gp21", "gp52", "gp53"; + function = "gpio"; + input-enable; + bias-pull-up; + }; }; }; diff --git a/Documentation/devicetree/bindings/pinctrl/mobileye,eyeq5-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mobileye,eyeq5-pinctrl.yaml new file mode 100644 index 000000000000..5f00604bf48c --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/mobileye,eyeq5-pinctrl.yaml @@ -0,0 +1,242 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/mobileye,eyeq5-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mobileye EyeQ5 pin controller + +description: > + The EyeQ5 pin controller handles the two pin banks of the system. It belongs + to a system-controller block called OLB. + + Pin control is about bias (pull-down, pull-up), drive strength and muxing. Pin + muxing supports two functions for each pin: first is GPIO, second is + pin-dependent. + + Pins and groups are bijective. + +maintainers: + - Grégory Clement <gregory.clement@bootlin.com> + - Théo Lebrun <theo.lebrun@bootlin.com> + - Vladimir Kondratiev <vladimir.kondratiev@mobileye.com> + +$ref: pinctrl.yaml# + +properties: + compatible: + enum: + - mobileye,eyeq5-pinctrl + + reg: + maxItems: 1 + +patternProperties: + "-pins?$": + type: object + description: Pin muxing configuration. + $ref: pinmux-node.yaml# + additionalProperties: false + properties: + pins: true + function: + enum: [gpio, + # Bank A + timer0, timer1, timer2, timer5, uart0, uart1, can0, can1, spi0, + spi1, refclk0, + # Bank B + timer3, timer4, timer6, uart2, can2, spi2, spi3, mclk0] + bias-disable: true + bias-pull-down: true + bias-pull-up: true + drive-strength: true + required: + - pins + - function + allOf: + - if: + properties: + function: + const: gpio + then: + properties: + pins: + items: # PA0 - PA28, PB0 - PB22 + pattern: '^(P(A|B)1?[0-9]|PA2[0-8]|PB2[0-2])$' + - if: + properties: + function: + const: timer0 + then: + properties: + pins: + items: + enum: [PA0, PA1] + - if: + properties: + function: + const: timer1 + then: + properties: + pins: + items: + enum: [PA2, PA3] + - if: + properties: + function: + const: timer2 + then: + properties: + pins: + items: + enum: [PA4, PA5] + - if: + properties: + function: + const: timer5 + then: + properties: + pins: + items: + enum: [PA6, PA7, PA8, PA9] + - if: + properties: + function: + const: uart0 + then: + properties: + pins: + items: + enum: [PA10, PA11] + - if: + properties: + function: + const: uart1 + then: + properties: + pins: + items: + enum: [PA12, PA13] + - if: + properties: + function: + const: can0 + then: + properties: + pins: + items: + enum: [PA14, PA15] + - if: + properties: + function: + const: can1 + then: + properties: + pins: + items: + enum: [PA16, PA17] + - if: + properties: + function: + const: spi0 + then: + properties: + pins: + items: + enum: [PA18, PA19, PA20, PA21, PA22] + - if: + properties: + function: + const: spi1 + then: + properties: + pins: + items: + enum: [PA23, PA24, PA25, PA26, PA27] + - if: + properties: + function: + const: refclk0 + then: + properties: + pins: + items: + enum: [PA28] + - if: + properties: + function: + const: timer3 + then: + properties: + pins: + items: + enum: [PB0, PB1] + - if: + properties: + function: + const: timer4 + then: + properties: + pins: + items: + enum: [PB2, PB3] + - if: + properties: + function: + const: timer6 + then: + properties: + pins: + items: + enum: [PB4, PB5, PB6, PB7] + - if: + properties: + function: + const: uart2 + then: + properties: + pins: + items: + enum: [PB8, PB9] + - if: + properties: + function: + const: can2 + then: + properties: + pins: + items: + enum: [PB10, PB11] + - if: + properties: + function: + const: spi2 + then: + properties: + pins: + items: + enum: [PB12, PB13, PB14, PB15, PB16] + - if: + properties: + function: + const: spi3 + then: + properties: + pins: + items: + enum: [PB17, PB18, PB19, PB20, PB21] + - if: + properties: + function: + const: mclk0 + then: + properties: + pins: + items: + enum: [PB22] + +required: + - compatible + - reg + +additionalProperties: false diff --git a/Documentation/devicetree/bindings/pinctrl/nuvoton,npcm845-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/nuvoton,npcm845-pinctrl.yaml index 3e8472898800..b55d9c316659 100644 --- a/Documentation/devicetree/bindings/pinctrl/nuvoton,npcm845-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/nuvoton,npcm845-pinctrl.yaml @@ -152,7 +152,6 @@ patternProperties: description: Debouncing periods in microseconds, one period per interrupt bank found in the controller - $ref: /schemas/types.yaml#/definitions/uint32-array minItems: 1 maxItems: 4 @@ -160,7 +159,6 @@ patternProperties: description: | 0: Low rate 1: High rate - $ref: /schemas/types.yaml#/definitions/uint32 enum: [0, 1] drive-strength: diff --git a/Documentation/devicetree/bindings/pinctrl/nuvoton,wpcm450-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/nuvoton,wpcm450-pinctrl.yaml index 7b7f840ffc4c..08442c880f07 100644 --- a/Documentation/devicetree/bindings/pinctrl/nuvoton,wpcm450-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/nuvoton,wpcm450-pinctrl.yaml @@ -103,7 +103,8 @@ patternProperties: items: pattern: "^gpio1?[0-9]{1,2}$" - input-debounce: true + input-debounce: + maxItems: 1 additionalProperties: false diff --git a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra234-pinmux-aon.yaml b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra234-pinmux-aon.yaml index f3deda9f7127..db8224dfba2c 100644 --- a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra234-pinmux-aon.yaml +++ b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra234-pinmux-aon.yaml @@ -10,18 +10,21 @@ maintainers: - Thierry Reding <thierry.reding@gmail.com> - Jon Hunter <jonathanh@nvidia.com> -$ref: nvidia,tegra234-pinmux-common.yaml - properties: compatible: const: nvidia,tegra234-pinmux-aon + reg: + maxItems: 1 + patternProperties: "^pinmux(-[a-z0-9-]+)?$": type: object # pin groups additionalProperties: + $ref: nvidia,tegra234-pinmux-common.yaml + properties: nvidia,pins: items: diff --git a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra234-pinmux-common.yaml b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra234-pinmux-common.yaml index 4f9de78085e5..8cf9e4c915ff 100644 --- a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra234-pinmux-common.yaml +++ b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra234-pinmux-common.yaml @@ -10,57 +10,43 @@ maintainers: - Thierry Reding <thierry.reding@gmail.com> - Jon Hunter <jonathanh@nvidia.com> -properties: - reg: - items: - - description: pinmux registers - -patternProperties: - "^pinmux(-[a-z0-9-]+)?$": - type: object - - # pin groups - additionalProperties: - $ref: nvidia,tegra-pinmux-common.yaml - # We would typically use unevaluatedProperties here but that has the - # downside that all the properties in the common bindings become valid - # for all chip generations. In this case, however, we want the per-SoC - # bindings to be able to override which of the common properties are - # allowed, since not all pinmux generations support the same sets of - # properties. This way, the common bindings define the format of the - # properties but the per-SoC bindings define which of them apply to a - # given chip. - additionalProperties: false - properties: - nvidia,function: - enum: [ gp, uartc, i2c8, spi2, i2c2, can1, can0, rsvd0, eth0, eth2, - eth1, dp, eth3, i2c4, i2c7, i2c9, eqos, pe2, pe1, pe0, pe3, - pe4, pe5, pe6, pe7, pe8, pe9, pe10, qspi0, qspi1, qpsi, - sdmmc1, sce, soc, gpio, hdmi, ufs0, spi3, spi1, uartb, uarte, - usb, extperiph2, extperiph1, i2c3, vi0, i2c5, uarta, uartd, - i2c1, i2s4, i2s6, aud, spi5, touch, uartj, rsvd1, wdt, tsc, - dmic3, led, vi0_alt, i2s5, nv, extperiph3, extperiph4, spi4, - ccla, i2s1, i2s2, i2s3, i2s8, rsvd2, dmic5, dca, displayb, - displaya, vi1, dcb, dmic1, dmic4, i2s7, dmic2, dspk0, rsvd3, - tsc_alt, istctrl, vi1_alt, dspk1, igpu ] +$ref: nvidia,tegra-pinmux-common.yaml - # out of the common properties, only these are allowed for Tegra234 - nvidia,pins: true - nvidia,pull: true - nvidia,tristate: true - nvidia,schmitt: true - nvidia,enable-input: true - nvidia,open-drain: true - nvidia,lock: true - nvidia,drive-type: true - nvidia,io-hv: true - - required: - - nvidia,pins +properties: + nvidia,function: + enum: [ gp, uartc, i2c8, spi2, i2c2, can1, can0, rsvd0, eth0, eth2, + eth1, dp, eth3, i2c4, i2c7, i2c9, eqos, pe2, pe1, pe0, pe3, + pe4, pe5, pe6, pe7, pe8, pe9, pe10, qspi0, qspi1, qpsi, + sdmmc1, sce, soc, gpio, hdmi, ufs0, spi3, spi1, uartb, uarte, + usb, extperiph2, extperiph1, i2c3, vi0, i2c5, uarta, uartd, + i2c1, i2s4, i2s6, aud, spi5, touch, uartj, rsvd1, wdt, tsc, + dmic3, led, vi0_alt, i2s5, nv, extperiph3, extperiph4, spi4, + ccla, i2s1, i2s2, i2s3, i2s8, rsvd2, dmic5, dca, displayb, + displaya, vi1, dcb, dmic1, dmic4, i2s7, dmic2, dspk0, rsvd3, + tsc_alt, istctrl, vi1_alt, dspk1, igpu ] + + # out of the common properties, only these are allowed for Tegra234 + nvidia,pins: true + nvidia,pull: true + nvidia,tristate: true + nvidia,schmitt: true + nvidia,enable-input: true + nvidia,open-drain: true + nvidia,lock: true + nvidia,drive-type: true + nvidia,io-hv: true required: - - compatible - - reg + - nvidia,pins + +# We would typically use unevaluatedProperties here but that has the +# downside that all the properties in the common bindings become valid +# for all chip generations. In this case, however, we want the per-SoC +# bindings to be able to override which of the common properties are +# allowed, since not all pinmux generations support the same sets of +# properties. This way, the common bindings define the format of the +# properties but the per-SoC bindings define which of them apply to a +# given chip. +additionalProperties: false -additionalProperties: true ... diff --git a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra234-pinmux.yaml b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra234-pinmux.yaml index 17b865ecfcda..f5a3a881dec4 100644 --- a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra234-pinmux.yaml +++ b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra234-pinmux.yaml @@ -10,18 +10,21 @@ maintainers: - Thierry Reding <thierry.reding@gmail.com> - Jon Hunter <jonathanh@nvidia.com> -$ref: nvidia,tegra234-pinmux-common.yaml - properties: compatible: const: nvidia,tegra234-pinmux + reg: + maxItems: 1 + patternProperties: "^pinmux(-[a-z0-9-]+)?$": type: object # pin groups additionalProperties: + $ref: nvidia,tegra234-pinmux-common.yaml + properties: nvidia,pins: items: diff --git a/Documentation/devicetree/bindings/pinctrl/pincfg-node.yaml b/Documentation/devicetree/bindings/pinctrl/pincfg-node.yaml index be81ed22a036..d0af21a564b4 100644 --- a/Documentation/devicetree/bindings/pinctrl/pincfg-node.yaml +++ b/Documentation/devicetree/bindings/pinctrl/pincfg-node.yaml @@ -97,7 +97,7 @@ properties: description: disable schmitt-trigger mode input-debounce: - $ref: /schemas/types.yaml#/definitions/uint32 + $ref: /schemas/types.yaml#/definitions/uint32-array description: Takes the debounce time in usec as argument or 0 to disable debouncing diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm4450-tlmm.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm4450-tlmm.yaml index bb08ca5a1509..bb675c8ec220 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm4450-tlmm.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm4450-tlmm.yaml @@ -17,7 +17,7 @@ allOf: properties: compatible: - const: qcom,sm4450-pinctrl + const: qcom,sm4450-tlmm reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml index 181cd1676c0a..5d84364d1358 100644 --- a/Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml +++ b/Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml @@ -46,6 +46,7 @@ properties: - renesas,pfc-r8a779a0 # R-Car V3U - renesas,pfc-r8a779f0 # R-Car S4-8 - renesas,pfc-r8a779g0 # R-Car V4H + - renesas,pfc-r8a779h0 # R-Car V4M - renesas,pfc-sh73a0 # SH-Mobile AG5 reg: diff --git a/Documentation/devicetree/bindings/pinctrl/xlnx,zynq-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/xlnx,pinctrl-zynq.yaml index d2676f92ef5b..de6c10ba36c4 100644 --- a/Documentation/devicetree/bindings/pinctrl/xlnx,zynq-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/xlnx,pinctrl-zynq.yaml @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause %YAML 1.2 --- -$id: http://devicetree.org/schemas/pinctrl/xlnx,zynq-pinctrl.yaml# +$id: http://devicetree.org/schemas/pinctrl/xlnx,pinctrl-zynq.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Xilinx Zynq Pinctrl @@ -28,7 +28,7 @@ description: | properties: compatible: - const: xlnx,zynq-pinctrl + const: xlnx,pinctrl-zynq reg: description: Specifies the base address and size of the SLCR space. @@ -181,7 +181,7 @@ examples: - | #include <dt-bindings/pinctrl/pinctrl-zynq.h> pinctrl0: pinctrl@700 { - compatible = "xlnx,zynq-pinctrl"; + compatible = "xlnx,pinctrl-zynq"; reg = <0x700 0x200>; syscon = <&slcr>; diff --git a/MAINTAINERS b/MAINTAINERS index c50e72258ba9..27c22f4f8daf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2471,6 +2471,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git F: Documentation/devicetree/bindings/arm/ste-* F: Documentation/devicetree/bindings/arm/ux500.yaml F: Documentation/devicetree/bindings/arm/ux500/ +F: Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml F: Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml F: arch/arm/boot/dts/st/ste-* F: arch/arm/mach-nomadik/ @@ -2479,6 +2480,7 @@ F: drivers/clk/clk-nomadik.c F: drivers/clocksource/clksrc-dbx500-prcmu.c F: drivers/dma/ste_dma40* F: drivers/pmdomain/st/ste-ux500-pm-domain.c +F: drivers/gpio/gpio-nomadik.c F: drivers/hwspinlock/u8500_hsem.c F: drivers/i2c/busses/i2c-nomadik.c F: drivers/iio/adc/ab8500-gpadc.c diff --git a/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi b/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi index a92cfcfc021b..09ef10b39f46 100644 --- a/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi +++ b/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi @@ -46,6 +46,10 @@ }; }; +&pinctrl { + gpio-ranges = <&pinctrl 0 0 232>; +}; + &soc { dma-noncoherent; interrupt-parent = <&plic>; diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 3fbb0bdb15c1..b50d0b470849 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -478,6 +478,18 @@ config GPIO_MXS select GPIO_GENERIC select GENERIC_IRQ_CHIP +config GPIO_NOMADIK + bool "Nomadik GPIO driver" + depends on ARCH_U8500 || ARCH_NOMADIK || MACH_EYEQ5 || COMPILE_TEST + select GPIOLIB_IRQCHIP + help + Say yes here to support the Nomadik SoC GPIO block. This block is also + used by the Mobileye EyeQ5 SoC. + + It handles up to 32 GPIOs per bank, that can all be interrupt sources. + It is deeply interconnected with the associated pinctrl driver as GPIO + registers handle muxing ("alternate functions") as well. + config GPIO_NPCM_SGPIO bool "Nuvoton SGPIO support" depends on ARCH_NPCM || COMPILE_TEST diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 7ae4d81de1df..fdd28c58d890 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -117,6 +117,7 @@ obj-$(CONFIG_GPIO_MT7621) += gpio-mt7621.o obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o +obj-$(CONFIG_GPIO_NOMADIK) += gpio-nomadik.o obj-$(CONFIG_GPIO_NPCM_SGPIO) += gpio-npcm-sgpio.o obj-$(CONFIG_GPIO_OCTEON) += gpio-octeon.o obj-$(CONFIG_GPIO_OMAP) += gpio-omap.o diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c new file mode 100644 index 000000000000..836f1cc760c2 --- /dev/null +++ b/drivers/gpio/gpio-nomadik.c @@ -0,0 +1,730 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * GPIO driver for the IP block found in the Nomadik SoC; it is an AMBA device, + * managing 32 pins with alternate functions. It can also handle the STA2X11 + * block from ST. + * + * The GPIO chips are shared with pinctrl-nomadik if used; it needs access for + * pinmuxing functionality and others. + * + * This driver also handles the mobileye,eyeq5-gpio compatible. It is an STA2X11 + * but with only data, direction and interrupts register active. We want to + * avoid touching SLPM, RWIMSC, FWIMSC, AFSLA and AFSLB registers; that is, + * wake and alternate function registers. It is NOT compatible with + * pinctrl-nomadik. + * + * Copyright (C) 2008,2009 STMicroelectronics + * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it> + * Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar@st.com> + * Copyright (C) 2011-2013 Linus Walleij <linus.walleij@linaro.org> + */ +#include <linux/cleanup.h> +#include <linux/clk.h> +#include <linux/gpio/driver.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/mod_devicetable.h> +#include <linux/pinctrl/pinctrl.h> +#include <linux/platform_device.h> +#include <linux/property.h> +#include <linux/reset.h> +#include <linux/seq_file.h> +#include <linux/slab.h> +#include <linux/types.h> + +#include <linux/gpio/gpio-nomadik.h> + +#ifndef CONFIG_PINCTRL_NOMADIK +static DEFINE_SPINLOCK(nmk_gpio_slpm_lock); +#endif + +void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip, unsigned int offset, + enum nmk_gpio_slpm mode) +{ + u32 slpm; + + /* We should NOT have been called. */ + if (WARN_ON(nmk_chip->is_mobileye_soc)) + return; + + slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC); + if (mode == NMK_GPIO_SLPM_NOCHANGE) + slpm |= BIT(offset); + else + slpm &= ~BIT(offset); + writel(slpm, nmk_chip->addr + NMK_GPIO_SLPC); +} + +static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip, + unsigned int offset, int val) +{ + if (val) + writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DATS); + else + writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DATC); +} + +void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip, + unsigned int offset, int val) +{ + writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRS); + __nmk_gpio_set_output(nmk_chip, offset, val); +} + +/* IRQ functions */ + +static void nmk_gpio_irq_ack(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); + + clk_enable(nmk_chip->clk); + writel(BIT(d->hwirq), nmk_chip->addr + NMK_GPIO_IC); + clk_disable(nmk_chip->clk); +} + +enum nmk_gpio_irq_type { + NORMAL, + WAKE, +}; + +static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip, + int offset, enum nmk_gpio_irq_type which, + bool enable) +{ + u32 *rimscval; + u32 *fimscval; + u32 rimscreg; + u32 fimscreg; + + if (which == NORMAL) { + rimscreg = NMK_GPIO_RIMSC; + fimscreg = NMK_GPIO_FIMSC; + rimscval = &nmk_chip->rimsc; + fimscval = &nmk_chip->fimsc; + } else { + /* We should NOT have been called. */ + if (WARN_ON(nmk_chip->is_mobileye_soc)) + return; + rimscreg = NMK_GPIO_RWIMSC; + fimscreg = NMK_GPIO_FWIMSC; + rimscval = &nmk_chip->rwimsc; + fimscval = &nmk_chip->fwimsc; + } + + /* we must individually set/clear the two edges */ + if (nmk_chip->edge_rising & BIT(offset)) { + if (enable) + *rimscval |= BIT(offset); + else + *rimscval &= ~BIT(offset); + writel(*rimscval, nmk_chip->addr + rimscreg); + } + if (nmk_chip->edge_falling & BIT(offset)) { + if (enable) + *fimscval |= BIT(offset); + else + *fimscval &= ~BIT(offset); + writel(*fimscval, nmk_chip->addr + fimscreg); + } +} + +static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip, + int offset, bool on) +{ + /* We should NOT have been called. */ + if (WARN_ON(nmk_chip->is_mobileye_soc)) + return; + + /* + * Ensure WAKEUP_ENABLE is on. No need to disable it if wakeup is + * disabled, since setting SLPM to 1 increases power consumption, and + * wakeup is anyhow controlled by the RIMSC and FIMSC registers. + */ + if (nmk_chip->sleepmode && on) { + __nmk_gpio_set_slpm(nmk_chip, offset, + NMK_GPIO_SLPM_WAKEUP_ENABLE); + } + + __nmk_gpio_irq_modify(nmk_chip, offset, WAKE, on); +} + +static void nmk_gpio_irq_maskunmask(struct nmk_gpio_chip *nmk_chip, + struct irq_data *d, bool enable) +{ + unsigned long flags; + + clk_enable(nmk_chip->clk); + spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); + spin_lock(&nmk_chip->lock); + + __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, enable); + + if (!nmk_chip->is_mobileye_soc && !(nmk_chip->real_wake & BIT(d->hwirq))) + __nmk_gpio_set_wake(nmk_chip, d->hwirq, enable); + + spin_unlock(&nmk_chip->lock); + spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); + clk_disable(nmk_chip->clk); +} + +static void nmk_gpio_irq_mask(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); + + nmk_gpio_irq_maskunmask(nmk_chip, d, false); + gpiochip_disable_irq(gc, irqd_to_hwirq(d)); +} + +static void nmk_gpio_irq_unmask(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); + + gpiochip_enable_irq(gc, irqd_to_hwirq(d)); + nmk_gpio_irq_maskunmask(nmk_chip, d, true); +} + +static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); + unsigned long flags; + + /* Handler is registered in all cases. */ + if (nmk_chip->is_mobileye_soc) + return -ENXIO; + + clk_enable(nmk_chip->clk); + spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); + spin_lock(&nmk_chip->lock); + + if (irqd_irq_disabled(d)) + __nmk_gpio_set_wake(nmk_chip, d->hwirq, on); + + if (on) + nmk_chip->real_wake |= BIT(d->hwirq); + else + nmk_chip->real_wake &= ~BIT(d->hwirq); + + spin_unlock(&nmk_chip->lock); + spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); + clk_disable(nmk_chip->clk); + + return 0; +} + +static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); + bool enabled = !irqd_irq_disabled(d); + bool wake = irqd_is_wakeup_set(d); + unsigned long flags; + + if (type & IRQ_TYPE_LEVEL_HIGH) + return -EINVAL; + if (type & IRQ_TYPE_LEVEL_LOW) + return -EINVAL; + + clk_enable(nmk_chip->clk); + spin_lock_irqsave(&nmk_chip->lock, flags); + + if (enabled) + __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, false); + + if (!nmk_chip->is_mobileye_soc && (enabled || wake)) + __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, false); + + nmk_chip->edge_rising &= ~BIT(d->hwirq); + if (type & IRQ_TYPE_EDGE_RISING) + nmk_chip->edge_rising |= BIT(d->hwirq); + + nmk_chip->edge_falling &= ~BIT(d->hwirq); + if (type & IRQ_TYPE_EDGE_FALLING) + nmk_chip->edge_falling |= BIT(d->hwirq); + + if (enabled) + __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, true); + + if (!nmk_chip->is_mobileye_soc && (enabled || wake)) + __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, true); + + spin_unlock_irqrestore(&nmk_chip->lock, flags); + clk_disable(nmk_chip->clk); + + return 0; +} + +static unsigned int nmk_gpio_irq_startup(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); + + clk_enable(nmk_chip->clk); + nmk_gpio_irq_unmask(d); + return 0; +} + +static void nmk_gpio_irq_shutdown(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); + + nmk_gpio_irq_mask(d); + clk_disable(nmk_chip->clk); +} + +static irqreturn_t nmk_gpio_irq_handler(int irq, void *dev_id) +{ + struct nmk_gpio_chip *nmk_chip = dev_id; + struct gpio_chip *chip = &nmk_chip->chip; + unsigned long mask = GENMASK(chip->ngpio - 1, 0); + unsigned long status; + int bit; + + clk_enable(nmk_chip->clk); + + status = readl(nmk_chip->addr + NMK_GPIO_IS); + + /* Ensure we cannot leave pending bits; this should never occur. */ + if (unlikely(status & ~mask)) + writel(status & ~mask, nmk_chip->addr + NMK_GPIO_IC); + + clk_disable(nmk_chip->clk); + + for_each_set_bit(bit, &status, chip->ngpio) + generic_handle_domain_irq_safe(chip->irq.domain, bit); + + return IRQ_RETVAL((status & mask) != 0); +} + +/* I/O Functions */ + +static int nmk_gpio_get_dir(struct gpio_chip *chip, unsigned int offset) +{ + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip); + int dir; + + clk_enable(nmk_chip->clk); + + dir = readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset); + + clk_disable(nmk_chip->clk); + + if (dir) + return GPIO_LINE_DIRECTION_OUT; + + return GPIO_LINE_DIRECTION_IN; +} + +static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned int offset) +{ + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip); + + clk_enable(nmk_chip->clk); + + writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRC); + + clk_disable(nmk_chip->clk); + + return 0; +} + +static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned int offset) +{ + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip); + int value; + + clk_enable(nmk_chip->clk); + + value = !!(readl(nmk_chip->addr + NMK_GPIO_DAT) & BIT(offset)); + + clk_disable(nmk_chip->clk); + + return value; +} + +static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned int offset, + int val) +{ + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip); + + clk_enable(nmk_chip->clk); + + __nmk_gpio_set_output(nmk_chip, offset, val); + + clk_disable(nmk_chip->clk); +} + +static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned int offset, + int val) +{ + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip); + + clk_enable(nmk_chip->clk); + + __nmk_gpio_make_output(nmk_chip, offset, val); + + clk_disable(nmk_chip->clk); + + return 0; +} + +#ifdef CONFIG_DEBUG_FS + +static int nmk_gpio_get_mode(struct nmk_gpio_chip *nmk_chip, int offset) +{ + u32 afunc, bfunc; + + /* We don't support modes. */ + if (nmk_chip->is_mobileye_soc) + return NMK_GPIO_ALT_GPIO; + + clk_enable(nmk_chip->clk); + + afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & BIT(offset); + bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & BIT(offset); + + clk_disable(nmk_chip->clk); + + return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0); +} + +void nmk_gpio_dbg_show_one(struct seq_file *s, struct pinctrl_dev *pctldev, + struct gpio_chip *chip, unsigned int offset, + unsigned int gpio) +{ + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip); + int mode; + bool is_out; + bool data_out; + bool pull; + static const char * const modes[] = { + [NMK_GPIO_ALT_GPIO] = "gpio", + [NMK_GPIO_ALT_A] = "altA", + [NMK_GPIO_ALT_B] = "altB", + [NMK_GPIO_ALT_C] = "altC", + [NMK_GPIO_ALT_C + 1] = "altC1", + [NMK_GPIO_ALT_C + 2] = "altC2", + [NMK_GPIO_ALT_C + 3] = "altC3", + [NMK_GPIO_ALT_C + 4] = "altC4", + }; + + char *label = gpiochip_dup_line_label(chip, offset); + if (IS_ERR(label)) + return; + + clk_enable(nmk_chip->clk); + is_out = !!(readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset)); + pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & BIT(offset)); + data_out = !!(readl(nmk_chip->addr + NMK_GPIO_DAT) & BIT(offset)); + mode = nmk_gpio_get_mode(nmk_chip, offset); +#ifdef CONFIG_PINCTRL_NOMADIK + if (mode == NMK_GPIO_ALT_C && pctldev) + mode = nmk_prcm_gpiocr_get_mode(pctldev, gpio); +#endif + + if (is_out) { + seq_printf(s, " gpio-%-3d (%-20.20s) out %s %s", + gpio, + label ?: "(none)", + data_out ? "hi" : "lo", + (mode < 0) ? "unknown" : modes[mode]); + } else { + int irq = chip->to_irq(chip, offset); + const int pullidx = pull ? 1 : 0; + int val; + static const char * const pulls[] = { + "none ", + "pull enabled", + }; + + seq_printf(s, " gpio-%-3d (%-20.20s) in %s %s", + gpio, + label ?: "(none)", + pulls[pullidx], + (mode < 0) ? "unknown" : modes[mode]); + + val = nmk_gpio_get_input(chip, offset); + seq_printf(s, " VAL %d", val); + + /* + * This races with request_irq(), set_irq_type(), + * and set_irq_wake() ... but those are "rare". + */ + if (irq > 0 && irq_has_action(irq)) { + char *trigger; + bool wake; + + if (nmk_chip->edge_rising & BIT(offset)) + trigger = "edge-rising"; + else if (nmk_chip->edge_falling & BIT(offset)) + trigger = "edge-falling"; + else + trigger = "edge-undefined"; + + wake = !!(nmk_chip->real_wake & BIT(offset)); + + seq_printf(s, " irq-%d %s%s", + irq, trigger, wake ? " wakeup" : ""); + } + } + clk_disable(nmk_chip->clk); +} + +static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) +{ + unsigned int i, gpio = chip->base; + + for (i = 0; i < chip->ngpio; i++, gpio++) { + nmk_gpio_dbg_show_one(s, NULL, chip, i, gpio); + seq_puts(s, "\n"); + } +} + +#else + +#define nmk_gpio_dbg_show NULL + +#endif + +/* + * We will allocate memory for the state container using devm* allocators + * binding to the first device reaching this point, it doesn't matter if + * it is the pin controller or GPIO driver. However we need to use the right + * platform device when looking up resources so pay attention to pdev. + */ +struct nmk_gpio_chip *nmk_gpio_populate_chip(struct fwnode_handle *fwnode, + struct platform_device *pdev) +{ + struct nmk_gpio_chip *nmk_chip; + struct platform_device *gpio_pdev; + struct device *dev = &pdev->dev; + struct reset_control *reset; + struct device *gpio_dev; + struct gpio_chip *chip; + struct resource *res; + struct clk *clk; + void __iomem *base; + u32 id, ngpio; + int ret; + + gpio_dev = bus_find_device_by_fwnode(&platform_bus_type, fwnode); + if (!gpio_dev) { + dev_err(dev, "populate \"%pfwP\": device not found\n", fwnode); + return ERR_PTR(-ENODEV); + } + gpio_pdev = to_platform_device(gpio_dev); + + if (device_property_read_u32(gpio_dev, "gpio-bank", &id)) { + dev_err(dev, "populate: gpio-bank property not found\n"); + platform_device_put(gpio_pdev); + return ERR_PTR(-EINVAL); + } + +#ifdef CONFIG_PINCTRL_NOMADIK + if (id >= ARRAY_SIZE(nmk_gpio_chips)) { + dev_err(dev, "populate: invalid id: %u\n", id); + platform_device_put(gpio_pdev); + return ERR_PTR(-EINVAL); + } + /* Already populated? */ + nmk_chip = nmk_gpio_chips[id]; + if (nmk_chip) { + platform_device_put(gpio_pdev); + return nmk_chip; + } +#endif + + nmk_chip = devm_kzalloc(dev, sizeof(*nmk_chip), GFP_KERNEL); + if (!nmk_chip) { + platform_device_put(gpio_pdev); + return ERR_PTR(-ENOMEM); + } + + if (device_property_read_u32(gpio_dev, "ngpios", &ngpio)) { + ngpio = NMK_GPIO_PER_CHIP; + dev_dbg(dev, "populate: using default ngpio (%u)\n", ngpio); + } + + nmk_chip->is_mobileye_soc = device_is_compatible(gpio_dev, + "mobileye,eyeq5-gpio"); + nmk_chip->bank = id; + chip = &nmk_chip->chip; + chip->base = -1; + chip->ngpio = ngpio; + chip->label = dev_name(gpio_dev); + chip->parent = gpio_dev; + + /* NOTE: different devices! No devm_platform_ioremap_resource() here! */ + res = platform_get_resource(gpio_pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) { + platform_device_put(gpio_pdev); + return ERR_CAST(base); + } + nmk_chip->addr = base; + + /* NOTE: do not use devm_ here! */ + clk = clk_get_optional(gpio_dev, NULL); + if (IS_ERR(clk)) { + platform_device_put(gpio_pdev); + return ERR_CAST(clk); + } + clk_prepare(clk); + nmk_chip->clk = clk; + + /* NOTE: do not use devm_ here! */ + reset = reset_control_get_optional_shared(gpio_dev, NULL); + if (IS_ERR(reset)) { + clk_unprepare(clk); + clk_put(clk); + platform_device_put(gpio_pdev); + dev_err(dev, "failed getting reset control: %pe\n", + reset); + return ERR_CAST(reset); + } + + /* + * Reset might be shared and asserts/deasserts calls are unbalanced. We + * only support sharing this reset with other gpio-nomadik devices that + * use this reset to ensure deassertion at probe. + */ + ret = reset_control_deassert(reset); + if (ret) { + reset_control_put(reset); + clk_unprepare(clk); + clk_put(clk); + platform_device_put(gpio_pdev); + dev_err(dev, "failed reset deassert: %d\n", ret); + return ERR_PTR(ret); + } + +#ifdef CONFIG_PINCTRL_NOMADIK + nmk_gpio_chips[id] = nmk_chip; +#endif + return nmk_chip; +} + +static void nmk_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); + + seq_printf(p, "nmk%u-%u-%u", nmk_chip->bank, + gc->base, gc->base + gc->ngpio - 1); +} + +static const struct irq_chip nmk_irq_chip = { + .irq_ack = nmk_gpio_irq_ack, + .irq_mask = nmk_gpio_irq_mask, + .irq_unmask = nmk_gpio_irq_unmask, + .irq_set_type = nmk_gpio_irq_set_type, + .irq_set_wake = nmk_gpio_irq_set_wake, + .irq_startup = nmk_gpio_irq_startup, + .irq_shutdown = nmk_gpio_irq_shutdown, + .irq_print_chip = nmk_gpio_irq_print_chip, + .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + +static int nmk_gpio_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct nmk_gpio_chip *nmk_chip; + struct gpio_irq_chip *girq; + bool supports_sleepmode; + struct gpio_chip *chip; + int irq; + int ret; + + nmk_chip = nmk_gpio_populate_chip(dev_fwnode(dev), pdev); + if (IS_ERR(nmk_chip)) { + dev_err(dev, "could not populate nmk chip struct\n"); + return PTR_ERR(nmk_chip); + } + + supports_sleepmode = + device_property_read_bool(dev, "st,supports-sleepmode"); + + /* Correct platform device ID */ + pdev->id = nmk_chip->bank; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + /* + * The virt address in nmk_chip->addr is in the nomadik register space, + * so we can simply convert the resource address, without remapping + */ + nmk_chip->sleepmode = supports_sleepmode; + spin_lock_init(&nmk_chip->lock); + + chip = &nmk_chip->chip; + chip->parent = dev; + chip->request = gpiochip_generic_request; + chip->free = gpiochip_generic_free; + chip->get_direction = nmk_gpio_get_dir; + chip->direction_input = nmk_gpio_make_input; + chip->get = nmk_gpio_get_input; + chip->direction_output = nmk_gpio_make_output; + chip->set = nmk_gpio_set_output; + chip->dbg_show = nmk_gpio_dbg_show; + chip->can_sleep = false; + chip->owner = THIS_MODULE; + + girq = &chip->irq; + gpio_irq_chip_set_chip(girq, &nmk_irq_chip); + girq->parent_handler = NULL; + girq->num_parents = 0; + girq->parents = NULL; + girq->default_type = IRQ_TYPE_NONE; + girq->handler = handle_edge_irq; + + ret = devm_request_irq(dev, irq, nmk_gpio_irq_handler, IRQF_SHARED, + dev_name(dev), nmk_chip); + if (ret) { + dev_err(dev, "failed requesting IRQ\n"); + return ret; + } + + if (!nmk_chip->is_mobileye_soc) { + clk_enable(nmk_chip->clk); + nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI); + clk_disable(nmk_chip->clk); + } + + ret = gpiochip_add_data(chip, nmk_chip); + if (ret) + return ret; + + platform_set_drvdata(pdev, nmk_chip); + + dev_info(dev, "chip registered\n"); + + return 0; +} + +static const struct of_device_id nmk_gpio_match[] = { + { .compatible = "st,nomadik-gpio", }, + { .compatible = "mobileye,eyeq5-gpio", }, + {} +}; + +static struct platform_driver nmk_gpio_driver = { + .driver = { + .name = "nomadik-gpio", + .of_match_table = nmk_gpio_match, + .suppress_bind_attrs = true, + }, + .probe = nmk_gpio_probe, +}; + +static int __init nmk_gpio_init(void) +{ + return platform_driver_register(&nmk_gpio_driver); +} +subsys_initcall(nmk_gpio_init); diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 8163a5983166..d45657aa986a 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -127,6 +127,24 @@ config PINCTRL_AXP209 selected. Say Y to enable pinctrl and GPIO support for the AXP209 PMIC. +config PINCTRL_AW9523 + tristate "Awinic AW9523/AW9523B I2C GPIO expander pinctrl driver" + depends on OF && I2C + select PINMUX + select PINCONF + select GENERIC_PINCONF + select GPIOLIB + select GPIOLIB_IRQCHIP + select REGMAP + select REGMAP_I2C + help + The Awinic AW9523/AW9523B is a multi-function I2C GPIO + expander with PWM functionality. This driver bundles a + pinctrl driver to select the function muxing and a GPIO + driver to handle GPIO, when the GPIO function is selected. + + Say yes to enable pinctrl and GPIO support for the AW9523(B). + config PINCTRL_BM1880 bool "Bitmain BM1880 Pinctrl driver" depends on OF && (ARCH_BITMAIN || COMPILE_TEST) diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 1071f301cc70..2152539b53d5 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_PINCTRL_ARTPEC6) += pinctrl-artpec6.o obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o +obj-$(CONFIG_PINCTRL_AW9523) += pinctrl-aw9523.o obj-$(CONFIG_PINCTRL_AXP209) += pinctrl-axp209.o obj-$(CONFIG_PINCTRL_BM1880) += pinctrl-bm1880.o obj-$(CONFIG_PINCTRL_CY8C95X0) += pinctrl-cy8c95x0.o diff --git a/drivers/pinctrl/cirrus/pinctrl-cs42l43.c b/drivers/pinctrl/cirrus/pinctrl-cs42l43.c index 012b0a3bad5a..628b60ccc2b0 100644 --- a/drivers/pinctrl/cirrus/pinctrl-cs42l43.c +++ b/drivers/pinctrl/cirrus/pinctrl-cs42l43.c @@ -5,10 +5,10 @@ // Copyright (c) 2023 Cirrus Logic, Inc. and // Cirrus Logic International Semiconductor Ltd. +#include <linux/array_size.h> #include <linux/bits.h> #include <linux/build_bug.h> #include <linux/err.h> -#include <linux/errno.h> #include <linux/gpio/driver.h> #include <linux/mfd/cs42l43.h> #include <linux/mfd/cs42l43-regs.h> @@ -17,7 +17,7 @@ #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/regmap.h> -#include <linux/string_helpers.h> +#include <linux/string_choices.h> #include <linux/pinctrl/consumer.h> #include <linux/pinctrl/pinctrl.h> @@ -276,7 +276,7 @@ static const struct pinmux_ops cs42l43_pin_mux_ops = { static const unsigned int cs42l43_pin_drv_str_ma[] = { 1, 2, 4, 8, 9, 10, 12, 16 }; -static inline int cs42l43_pin_get_drv_str(struct cs42l43_pin *priv, unsigned int pin) +static int cs42l43_pin_get_drv_str(struct cs42l43_pin *priv, unsigned int pin) { const struct cs42l43_pin_data *pdat = cs42l43_pin_pins[pin].drv_data; unsigned int val; @@ -289,8 +289,8 @@ static inline int cs42l43_pin_get_drv_str(struct cs42l43_pin *priv, unsigned int return cs42l43_pin_drv_str_ma[(val & pdat->mask) >> pdat->shift]; } -static inline int cs42l43_pin_set_drv_str(struct cs42l43_pin *priv, unsigned int pin, - unsigned int ma) +static int cs42l43_pin_set_drv_str(struct cs42l43_pin *priv, unsigned int pin, + unsigned int ma) { const struct cs42l43_pin_data *pdat = cs42l43_pin_pins[pin].drv_data; int i; @@ -314,7 +314,7 @@ err: return -EINVAL; } -static inline int cs42l43_pin_get_db(struct cs42l43_pin *priv, unsigned int pin) +static int cs42l43_pin_get_db(struct cs42l43_pin *priv, unsigned int pin) { unsigned int val; int ret; @@ -332,8 +332,8 @@ static inline int cs42l43_pin_get_db(struct cs42l43_pin *priv, unsigned int pin) return 85; // Debounce is roughly 85uS } -static inline int cs42l43_pin_set_db(struct cs42l43_pin *priv, unsigned int pin, - unsigned int us) +static int cs42l43_pin_set_db(struct cs42l43_pin *priv, unsigned int pin, + unsigned int us) { if (pin >= CS42L43_NUM_GPIOS) return -ENOTSUPP; @@ -490,7 +490,7 @@ static void cs42l43_gpio_set(struct gpio_chip *chip, unsigned int offset, int va int ret; dev_dbg(priv->dev, "Setting gpio%d to %s\n", - offset + 1, value ? "high" : "low"); + offset + 1, str_high_low(value)); ret = pm_runtime_resume_and_get(priv->dev); if (ret) { diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index bbcdece83bf4..6649357637ff 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -412,6 +412,10 @@ static int pinctrl_get_device_gpio_range(struct gpio_chip *gc, * @pctldev: pin controller device to add the range to * @range: the GPIO range to add * + * DEPRECATED: Don't use this function in new code. See section 2 of + * Documentation/devicetree/bindings/gpio/gpio.txt on how to bind pinctrl and + * gpio drivers. + * * This adds a range of GPIOs to be handled by a certain pin controller. Call * this to register handled ranges after registering your pin controller. */ diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7981.c b/drivers/pinctrl/mediatek/pinctrl-mt7981.c index 7e59a4407859..ef6123765885 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt7981.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt7981.c @@ -700,6 +700,15 @@ static int mt7981_drv_vbus_pins[] = { 14, }; static int mt7981_drv_vbus_funcs[] = { 1, }; /* EMMC */ +static int mt7981_emmc_reset_pins[] = { 15, }; +static int mt7981_emmc_reset_funcs[] = { 2, }; + +static int mt7981_emmc_4_pins[] = { 16, 17, 18, 19, 24, 25, }; +static int mt7981_emmc_4_funcs[] = { 2, 2, 2, 2, 2, 2, }; + +static int mt7981_emmc_8_pins[] = { 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, }; +static int mt7981_emmc_8_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, }; + static int mt7981_emmc_45_pins[] = { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, }; static int mt7981_emmc_45_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, }; @@ -737,6 +746,9 @@ static int mt7981_uart1_1_funcs[] = { 2, 2, 2, 2, }; static int mt7981_uart1_2_pins[] = { 9, 10, }; static int mt7981_uart1_2_funcs[] = { 2, 2, }; +static int mt7981_uart1_3_pins[] = { 26, 27, }; +static int mt7981_uart1_3_funcs[] = { 2, 2, }; + /* UART2 */ static int mt7981_uart2_1_pins[] = { 22, 23, 24, 25, }; static int mt7981_uart2_1_funcs[] = { 3, 3, 3, 3, }; @@ -851,6 +863,12 @@ static const struct group_desc mt7981_groups[] = { PINCTRL_PIN_GROUP("udi", mt7981_udi), /* @GPIO(14) DRV_VBUS(1) */ PINCTRL_PIN_GROUP("drv_vbus", mt7981_drv_vbus), + /* @GPIO(15): EMMC_RSTB(2) */ + PINCTRL_PIN_GROUP("emmc_reset", mt7981_emmc_reset), + /* @GPIO(16,17,18,19,24,25): EMMC_DATx, EMMC_CLK, EMMC_CMD */ + PINCTRL_PIN_GROUP("emmc_4", mt7981_emmc_4), + /* @GPIO(16,17,18,19,20,21,22,23,24,25): EMMC_DATx, EMMC_CLK, EMMC_CMD */ + PINCTRL_PIN_GROUP("emmc_8", mt7981_emmc_8), /* @GPIO(15,25): EMMC(2) */ PINCTRL_PIN_GROUP("emmc_45", mt7981_emmc_45), /* @GPIO(16,21): SNFI(3) */ @@ -871,6 +889,8 @@ static const struct group_desc mt7981_groups[] = { PINCTRL_PIN_GROUP("uart1_1", mt7981_uart1_1), /* @GPIO(9,10): UART1(2) */ PINCTRL_PIN_GROUP("uart1_2", mt7981_uart1_2), + /* @GPIO(26,27): UART1(2) */ + PINCTRL_PIN_GROUP("uart1_3", mt7981_uart1_3), /* @GPIO(22,25): UART1(3) */ PINCTRL_PIN_GROUP("uart2_1", mt7981_uart2_1), /* @GPIO(22,24) PTA_EXT(4) */ @@ -933,7 +953,7 @@ static const struct group_desc mt7981_groups[] = { static const char *mt7981_wa_aice_groups[] = { "wa_aice1", "wa_aice2", "wm_aice1_1", "wa_aice3", "wm_aice1_2", }; static const char *mt7981_uart_groups[] = { "net_wo0_uart_txd_0", "net_wo0_uart_txd_1", - "net_wo0_uart_txd_2", "uart0", "uart1_0", "uart1_1", "uart1_2", "uart2_0", + "net_wo0_uart_txd_2", "uart0", "uart1_0", "uart1_1", "uart1_2", "uart1_3", "uart2_0", "uart2_0_tx_rx", "uart2_1", "wm_uart_0", "wm_aurt_1", "wm_aurt_2", }; static const char *mt7981_dfd_groups[] = { "dfd", "dfd_ntrst", }; static const char *mt7981_wdt_groups[] = { "watchdog", "watchdog1", }; @@ -952,7 +972,7 @@ static const char *mt7981_i2c_groups[] = { "i2c0_0", "i2c0_1", "u2_phy_i2c", static const char *mt7981_pcm_groups[] = { "pcm", }; static const char *mt7981_udi_groups[] = { "udi", }; static const char *mt7981_usb_groups[] = { "drv_vbus", }; -static const char *mt7981_flash_groups[] = { "emmc_45", "snfi", }; +static const char *mt7981_flash_groups[] = { "emmc_reset", "emmc_4", "emmc_8", "emmc_45", "snfi", }; static const char *mt7981_ethernet_groups[] = { "smi_mdc_mdio", "gbe_ext_mdc_mdio", "wf0_mode1", "wf0_mode3", "mt7531_int", }; static const char *mt7981_ant_groups[] = { "ant_sel", }; diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7986.c b/drivers/pinctrl/mediatek/pinctrl-mt7986.c index acaac9b38aa8..39e80fa644c1 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt7986.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt7986.c @@ -16,7 +16,7 @@ PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \ _x_bits, 32, 0) -/** +/* * enum - Locking variants of the iocfg bases * * MT7986 have multiple bases to program pin configuration listed as the below: diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8186.c b/drivers/pinctrl/mediatek/pinctrl-mt8186.c index 7be591591cce..dd19e74856a9 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt8186.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt8186.c @@ -1198,7 +1198,6 @@ static const struct mtk_pin_reg_calc mt8186_reg_cals[PINCTRL_PIN_REG_MAX] = { [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt8186_pin_dir_range), [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt8186_pin_di_range), [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt8186_pin_do_range), - [PINCTRL_PIN_REG_SR] = MTK_RANGE(mt8186_pin_dir_range), [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt8186_pin_smt_range), [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt8186_pin_ies_range), [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt8186_pin_pu_range), diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8192.c b/drivers/pinctrl/mediatek/pinctrl-mt8192.c index e3a76381f7f4..3f8a9dbcb704 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt8192.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt8192.c @@ -1379,7 +1379,6 @@ static const struct mtk_pin_reg_calc mt8192_reg_cals[PINCTRL_PIN_REG_MAX] = { [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt8192_pin_dir_range), [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt8192_pin_di_range), [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt8192_pin_do_range), - [PINCTRL_PIN_REG_SR] = MTK_RANGE(mt8192_pin_dir_range), [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt8192_pin_smt_range), [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt8192_pin_ies_range), [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt8192_pin_pu_range), diff --git a/drivers/pinctrl/nomadik/Kconfig b/drivers/pinctrl/nomadik/Kconfig index 0fea167c283f..aafecf348670 100644 --- a/drivers/pinctrl/nomadik/Kconfig +++ b/drivers/pinctrl/nomadik/Kconfig @@ -18,15 +18,15 @@ config PINCTRL_AB8505 endif -if (ARCH_U8500 || ARCH_NOMADIK) +if (ARCH_U8500 || ARCH_NOMADIK || COMPILE_TEST) config PINCTRL_NOMADIK bool "Nomadik pin controller driver" - depends on OF && GPIOLIB + depends on OF select PINMUX select PINCONF - select OF_GPIO - select GPIOLIB_IRQCHIP + select GPIOLIB + select GPIO_NOMADIK config PINCTRL_STN8815 bool "STN8815 pin controller driver" diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c index 490e0959e8be..0b4a3dd9d8c7 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c @@ -3,8 +3,9 @@ #include <linux/types.h> #include <linux/pinctrl/pinctrl.h> +#include <linux/gpio/driver.h> -#include "pinctrl-nomadik.h" +#include <linux/gpio/gpio-nomadik.h> /* All the pins that can be used for GPIO and some other functions */ #define _GPIO(offset) (offset) diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c index 1552222ac68e..c5a52fcaba30 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c @@ -3,8 +3,9 @@ #include <linux/types.h> #include <linux/pinctrl/pinctrl.h> +#include <linux/gpio/driver.h> -#include "pinctrl-nomadik.h" +#include <linux/gpio/gpio-nomadik.h> /* All the pins that can be used for GPIO and some other functions */ #define _GPIO(offset) (offset) diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c index 7911353ac97d..cb0f0d5a5e45 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c @@ -1,12 +1,15 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Generic GPIO driver for logic cells found in the Nomadik SoC + * Pinmux & pinconf driver for the IP block found in the Nomadik SoC. This + * depends on gpio-nomadik and some handling is intertwined; see nmk_gpio_chips + * which is used by this driver to access the GPIO banks array. * * Copyright (C) 2008,2009 STMicroelectronics * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it> * Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar@st.com> * Copyright (C) 2011-2013 Linus Walleij <linus.walleij@linaro.org> */ + #include <linux/bitops.h> #include <linux/cleanup.h> #include <linux/clk.h> @@ -25,6 +28,7 @@ #include <linux/seq_file.h> #include <linux/slab.h> #include <linux/spinlock.h> +#include <linux/types.h> /* Since we request GPIOs from ourself */ #include <linux/pinctrl/consumer.h> @@ -36,15 +40,7 @@ #include "../core.h" #include "../pinctrl-utils.h" -#include "pinctrl-nomadik.h" - -/* - * The GPIO module in the Nomadik family of Systems-on-Chip is an - * AMBA device, managing 32 pins and alternate functions. The logic block - * is currently used in the Nomadik and ux500. - * - * Symbols in this file are called "nmk_gpio" for "nomadik gpio" - */ +#include <linux/gpio/gpio-nomadik.h> /* * pin configurations are represented by 32-bit integers: @@ -76,8 +72,6 @@ * PIN_CFG - default config with alternate function */ -typedef unsigned long pin_cfg_t; - #define PIN_NUM_MASK 0x1ff #define PIN_NUM(x) ((x) & PIN_NUM_MASK) @@ -172,7 +166,6 @@ typedef unsigned long pin_cfg_t; #define PIN_SLEEPMODE_DISABLED (0 << PIN_SLEEPMODE_SHIFT) #define PIN_SLEEPMODE_ENABLED (1 << PIN_SLEEPMODE_SHIFT) - /* Shortcuts. Use these instead of separate DIR, PULL, and VAL. */ #define PIN_INPUT_PULLDOWN (PIN_DIR_INPUT | PIN_PULL_DOWN) #define PIN_INPUT_PULLUP (PIN_DIR_INPUT | PIN_PULL_UP) @@ -200,75 +193,6 @@ typedef unsigned long pin_cfg_t; (PIN_CFG_DEFAULT |\ (PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val)) -/* - * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving - * the "gpio" namespace for generic and cross-machine functions - */ - -#define GPIO_BLOCK_SHIFT 5 -#define NMK_GPIO_PER_CHIP (1 << GPIO_BLOCK_SHIFT) -#define NMK_MAX_BANKS DIV_ROUND_UP(512, NMK_GPIO_PER_CHIP) - -/* Register in the logic block */ -#define NMK_GPIO_DAT 0x00 -#define NMK_GPIO_DATS 0x04 -#define NMK_GPIO_DATC 0x08 -#define NMK_GPIO_PDIS 0x0c -#define NMK_GPIO_DIR 0x10 -#define NMK_GPIO_DIRS 0x14 -#define NMK_GPIO_DIRC 0x18 -#define NMK_GPIO_SLPC 0x1c -#define NMK_GPIO_AFSLA 0x20 -#define NMK_GPIO_AFSLB 0x24 -#define NMK_GPIO_LOWEMI 0x28 - -#define NMK_GPIO_RIMSC 0x40 -#define NMK_GPIO_FIMSC 0x44 -#define NMK_GPIO_IS 0x48 -#define NMK_GPIO_IC 0x4c -#define NMK_GPIO_RWIMSC 0x50 -#define NMK_GPIO_FWIMSC 0x54 -#define NMK_GPIO_WKS 0x58 -/* These appear in DB8540 and later ASICs */ -#define NMK_GPIO_EDGELEVEL 0x5C -#define NMK_GPIO_LEVEL 0x60 - - -/* Pull up/down values */ -enum nmk_gpio_pull { - NMK_GPIO_PULL_NONE, - NMK_GPIO_PULL_UP, - NMK_GPIO_PULL_DOWN, -}; - -/* Sleep mode */ -enum nmk_gpio_slpm { - NMK_GPIO_SLPM_INPUT, - NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT, - NMK_GPIO_SLPM_NOCHANGE, - NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE, -}; - -struct nmk_gpio_chip { - struct gpio_chip chip; - void __iomem *addr; - struct clk *clk; - unsigned int bank; - void (*set_ioforce)(bool enable); - spinlock_t lock; - bool sleepmode; - /* Keep track of configured edges */ - u32 edge_rising; - u32 edge_falling; - u32 real_wake; - u32 rwimsc; - u32 fwimsc; - u32 rimsc; - u32 fimsc; - u32 pull_up; - u32 lowemi; -}; - /** * struct nmk_pinctrl - state container for the Nomadik pin controller * @dev: containing device pointer @@ -283,14 +207,13 @@ struct nmk_pinctrl { void __iomem *prcm_base; }; -static struct nmk_gpio_chip *nmk_gpio_chips[NMK_MAX_BANKS]; +/* See nmk_gpio_populate_chip() that fills this array. */ +struct nmk_gpio_chip *nmk_gpio_chips[NMK_MAX_BANKS]; -static DEFINE_SPINLOCK(nmk_gpio_slpm_lock); - -#define NUM_BANKS ARRAY_SIZE(nmk_gpio_chips) +DEFINE_SPINLOCK(nmk_gpio_slpm_lock); static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip, - unsigned offset, int gpio_mode) + unsigned int offset, int gpio_mode) { u32 afunc, bfunc; @@ -304,21 +227,8 @@ static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip, writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB); } -static void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip, - unsigned offset, enum nmk_gpio_slpm mode) -{ - u32 slpm; - - slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC); - if (mode == NMK_GPIO_SLPM_NOCHANGE) - slpm |= BIT(offset); - else - slpm &= ~BIT(offset); - writel(slpm, nmk_chip->addr + NMK_GPIO_SLPC); -} - static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip, - unsigned offset, enum nmk_gpio_pull pull) + unsigned int offset, enum nmk_gpio_pull pull) { u32 pdis; @@ -342,7 +252,7 @@ static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip, } static void __nmk_gpio_set_lowemi(struct nmk_gpio_chip *nmk_chip, - unsigned offset, bool lowemi) + unsigned int offset, bool lowemi) { bool enabled = nmk_chip->lowemi & BIT(offset); @@ -359,29 +269,13 @@ static void __nmk_gpio_set_lowemi(struct nmk_gpio_chip *nmk_chip, } static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip, - unsigned offset) + unsigned int offset) { writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRC); } -static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip, - unsigned offset, int val) -{ - if (val) - writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DATS); - else - writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DATC); -} - -static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip, - unsigned offset, int val) -{ - writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRS); - __nmk_gpio_set_output(nmk_chip, offset, val); -} - static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip, - unsigned offset, int gpio_mode, + unsigned int offset, int gpio_mode, bool glitch) { u32 rwimsc = nmk_chip->rwimsc; @@ -408,7 +302,7 @@ static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip, } static void -nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned offset) +nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned int offset) { u32 falling = nmk_chip->fimsc & BIT(offset); u32 rising = nmk_chip->rimsc & BIT(offset); @@ -447,7 +341,7 @@ static void nmk_write_masked(void __iomem *reg, u32 mask, u32 value) } static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, - unsigned offset, unsigned alt_num) + unsigned int offset, unsigned int alt_num) { int i; u16 reg; @@ -484,14 +378,14 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, */ if (!alt_num) { for (i = 0 ; i < PRCM_IDX_GPIOCR_ALTC_MAX ; i++) { - if (pin_desc->altcx[i].used == true) { + if (pin_desc->altcx[i].used) { reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; bit = pin_desc->altcx[i].control_bit; if (readl(npct->prcm_base + reg) & BIT(bit)) { nmk_write_masked(npct->prcm_base + reg, BIT(bit), 0); dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n", - offset, i+1); + offset, i + 1); } } } @@ -499,10 +393,10 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, } alt_index = alt_num - 1; - if (pin_desc->altcx[alt_index].used == false) { + if (!pin_desc->altcx[alt_index].used) { dev_warn(npct->dev, - "PRCM GPIOCR: pin %i: alternate-C%i does not exist\n", - offset, alt_num); + "PRCM GPIOCR: pin %i: alternate-C%i does not exist\n", + offset, alt_num); return; } @@ -513,14 +407,14 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, for (i = 0 ; i < PRCM_IDX_GPIOCR_ALTC_MAX ; i++) { if (i == alt_index) continue; - if (pin_desc->altcx[i].used == true) { + if (pin_desc->altcx[i].used) { reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; bit = pin_desc->altcx[i].control_bit; if (readl(npct->prcm_base + reg) & BIT(bit)) { nmk_write_masked(npct->prcm_base + reg, BIT(bit), 0); dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n", - offset, i+1); + offset, i + 1); } } } @@ -528,7 +422,7 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, reg = gpiocr_regs[pin_desc->altcx[alt_index].reg_index]; bit = pin_desc->altcx[alt_index].control_bit; dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been selected\n", - offset, alt_index+1); + offset, alt_index + 1); nmk_write_masked(npct->prcm_base + reg, BIT(bit), BIT(bit)); } @@ -548,7 +442,7 @@ static void nmk_gpio_glitch_slpm_init(unsigned int *slpm) { int i; - for (i = 0; i < NUM_BANKS; i++) { + for (i = 0; i < NMK_MAX_BANKS; i++) { struct nmk_gpio_chip *chip = nmk_gpio_chips[i]; unsigned int temp = slpm[i]; @@ -566,7 +460,7 @@ static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm) { int i; - for (i = 0; i < NUM_BANKS; i++) { + for (i = 0; i < NMK_MAX_BANKS; i++) { struct nmk_gpio_chip *chip = nmk_gpio_chips[i]; if (!chip) @@ -578,7 +472,8 @@ static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm) } } -static int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio) +/* Only called by gpio-nomadik but requires knowledge of struct nmk_pinctrl. */ +int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio) { int i; u16 reg; @@ -600,586 +495,16 @@ static int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, pin_desc = npct->soc->altcx_pins + i; gpiocr_regs = npct->soc->prcm_gpiocr_registers; for (i = 0; i < PRCM_IDX_GPIOCR_ALTC_MAX; i++) { - if (pin_desc->altcx[i].used == true) { + if (pin_desc->altcx[i].used) { reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; bit = pin_desc->altcx[i].control_bit; if (readl(npct->prcm_base + reg) & BIT(bit)) - return NMK_GPIO_ALT_C+i+1; + return NMK_GPIO_ALT_C + i + 1; } } return NMK_GPIO_ALT_C; } -/* IRQ functions */ - -static void nmk_gpio_irq_ack(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); - - clk_enable(nmk_chip->clk); - writel(BIT(d->hwirq), nmk_chip->addr + NMK_GPIO_IC); - clk_disable(nmk_chip->clk); -} - -enum nmk_gpio_irq_type { - NORMAL, - WAKE, -}; - -static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip, - int offset, enum nmk_gpio_irq_type which, - bool enable) -{ - u32 *rimscval; - u32 *fimscval; - u32 rimscreg; - u32 fimscreg; - - if (which == NORMAL) { - rimscreg = NMK_GPIO_RIMSC; - fimscreg = NMK_GPIO_FIMSC; - rimscval = &nmk_chip->rimsc; - fimscval = &nmk_chip->fimsc; - } else { - rimscreg = NMK_GPIO_RWIMSC; - fimscreg = NMK_GPIO_FWIMSC; - rimscval = &nmk_chip->rwimsc; - fimscval = &nmk_chip->fwimsc; - } - - /* we must individually set/clear the two edges */ - if (nmk_chip->edge_rising & BIT(offset)) { - if (enable) - *rimscval |= BIT(offset); - else - *rimscval &= ~BIT(offset); - writel(*rimscval, nmk_chip->addr + rimscreg); - } - if (nmk_chip->edge_falling & BIT(offset)) { - if (enable) - *fimscval |= BIT(offset); - else - *fimscval &= ~BIT(offset); - writel(*fimscval, nmk_chip->addr + fimscreg); - } -} - -static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip, - int offset, bool on) -{ - /* - * Ensure WAKEUP_ENABLE is on. No need to disable it if wakeup is - * disabled, since setting SLPM to 1 increases power consumption, and - * wakeup is anyhow controlled by the RIMSC and FIMSC registers. - */ - if (nmk_chip->sleepmode && on) { - __nmk_gpio_set_slpm(nmk_chip, offset, - NMK_GPIO_SLPM_WAKEUP_ENABLE); - } - - __nmk_gpio_irq_modify(nmk_chip, offset, WAKE, on); -} - -static void nmk_gpio_irq_maskunmask(struct nmk_gpio_chip *nmk_chip, - struct irq_data *d, bool enable) -{ - unsigned long flags; - - clk_enable(nmk_chip->clk); - spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); - spin_lock(&nmk_chip->lock); - - __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, enable); - - if (!(nmk_chip->real_wake & BIT(d->hwirq))) - __nmk_gpio_set_wake(nmk_chip, d->hwirq, enable); - - spin_unlock(&nmk_chip->lock); - spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); - clk_disable(nmk_chip->clk); -} - -static void nmk_gpio_irq_mask(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); - - nmk_gpio_irq_maskunmask(nmk_chip, d, false); - gpiochip_disable_irq(gc, irqd_to_hwirq(d)); -} - -static void nmk_gpio_irq_unmask(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); - - gpiochip_enable_irq(gc, irqd_to_hwirq(d)); - nmk_gpio_irq_maskunmask(nmk_chip, d, true); -} - -static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); - unsigned long flags; - - clk_enable(nmk_chip->clk); - spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); - spin_lock(&nmk_chip->lock); - - if (irqd_irq_disabled(d)) - __nmk_gpio_set_wake(nmk_chip, d->hwirq, on); - - if (on) - nmk_chip->real_wake |= BIT(d->hwirq); - else - nmk_chip->real_wake &= ~BIT(d->hwirq); - - spin_unlock(&nmk_chip->lock); - spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); - clk_disable(nmk_chip->clk); - - return 0; -} - -static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); - bool enabled = !irqd_irq_disabled(d); - bool wake = irqd_is_wakeup_set(d); - unsigned long flags; - - if (type & IRQ_TYPE_LEVEL_HIGH) - return -EINVAL; - if (type & IRQ_TYPE_LEVEL_LOW) - return -EINVAL; - - clk_enable(nmk_chip->clk); - spin_lock_irqsave(&nmk_chip->lock, flags); - - if (enabled) - __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, false); - - if (enabled || wake) - __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, false); - - nmk_chip->edge_rising &= ~BIT(d->hwirq); - if (type & IRQ_TYPE_EDGE_RISING) - nmk_chip->edge_rising |= BIT(d->hwirq); - - nmk_chip->edge_falling &= ~BIT(d->hwirq); - if (type & IRQ_TYPE_EDGE_FALLING) - nmk_chip->edge_falling |= BIT(d->hwirq); - - if (enabled) - __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, true); - - if (enabled || wake) - __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, true); - - spin_unlock_irqrestore(&nmk_chip->lock, flags); - clk_disable(nmk_chip->clk); - - return 0; -} - -static unsigned int nmk_gpio_irq_startup(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); - - clk_enable(nmk_chip->clk); - nmk_gpio_irq_unmask(d); - return 0; -} - -static void nmk_gpio_irq_shutdown(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); - - nmk_gpio_irq_mask(d); - clk_disable(nmk_chip->clk); -} - -static void nmk_gpio_irq_handler(struct irq_desc *desc) -{ - struct irq_chip *host_chip = irq_desc_get_chip(desc); - struct gpio_chip *chip = irq_desc_get_handler_data(desc); - struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip); - u32 status; - - chained_irq_enter(host_chip, desc); - - clk_enable(nmk_chip->clk); - status = readl(nmk_chip->addr + NMK_GPIO_IS); - clk_disable(nmk_chip->clk); - - while (status) { - int bit = __ffs(status); - - generic_handle_domain_irq(chip->irq.domain, bit); - status &= ~BIT(bit); - } - - chained_irq_exit(host_chip, desc); -} - -/* I/O Functions */ - -static int nmk_gpio_get_dir(struct gpio_chip *chip, unsigned offset) -{ - struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip); - int dir; - - clk_enable(nmk_chip->clk); - - dir = readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset); - - clk_disable(nmk_chip->clk); - - if (dir) - return GPIO_LINE_DIRECTION_OUT; - - return GPIO_LINE_DIRECTION_IN; -} - -static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset) -{ - struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip); - - clk_enable(nmk_chip->clk); - - writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRC); - - clk_disable(nmk_chip->clk); - - return 0; -} - -static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset) -{ - struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip); - int value; - - clk_enable(nmk_chip->clk); - - value = !!(readl(nmk_chip->addr + NMK_GPIO_DAT) & BIT(offset)); - - clk_disable(nmk_chip->clk); - - return value; -} - -static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset, - int val) -{ - struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip); - - clk_enable(nmk_chip->clk); - - __nmk_gpio_set_output(nmk_chip, offset, val); - - clk_disable(nmk_chip->clk); -} - -static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset, - int val) -{ - struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip); - - clk_enable(nmk_chip->clk); - - __nmk_gpio_make_output(nmk_chip, offset, val); - - clk_disable(nmk_chip->clk); - - return 0; -} - -#ifdef CONFIG_DEBUG_FS -static int nmk_gpio_get_mode(struct nmk_gpio_chip *nmk_chip, int offset) -{ - u32 afunc, bfunc; - - clk_enable(nmk_chip->clk); - - afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & BIT(offset); - bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & BIT(offset); - - clk_disable(nmk_chip->clk); - - return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0); -} - -static void nmk_gpio_dbg_show_one(struct seq_file *s, - struct pinctrl_dev *pctldev, struct gpio_chip *chip, - unsigned offset, unsigned gpio) -{ - struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip); - int mode; - bool is_out; - bool data_out; - bool pull; - const char *modes[] = { - [NMK_GPIO_ALT_GPIO] = "gpio", - [NMK_GPIO_ALT_A] = "altA", - [NMK_GPIO_ALT_B] = "altB", - [NMK_GPIO_ALT_C] = "altC", - [NMK_GPIO_ALT_C+1] = "altC1", - [NMK_GPIO_ALT_C+2] = "altC2", - [NMK_GPIO_ALT_C+3] = "altC3", - [NMK_GPIO_ALT_C+4] = "altC4", - }; - - char *label = gpiochip_dup_line_label(chip, offset); - if (IS_ERR(label)) - return; - - clk_enable(nmk_chip->clk); - is_out = !!(readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset)); - pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & BIT(offset)); - data_out = !!(readl(nmk_chip->addr + NMK_GPIO_DAT) & BIT(offset)); - mode = nmk_gpio_get_mode(nmk_chip, offset); - if ((mode == NMK_GPIO_ALT_C) && pctldev) - mode = nmk_prcm_gpiocr_get_mode(pctldev, gpio); - - if (is_out) { - seq_printf(s, " gpio-%-3d (%-20.20s) out %s %s", - gpio, - label ?: "(none)", - data_out ? "hi" : "lo", - (mode < 0) ? "unknown" : modes[mode]); - } else { - int irq = chip->to_irq(chip, offset); - const int pullidx = pull ? 1 : 0; - int val; - static const char * const pulls[] = { - "none ", - "pull enabled", - }; - - seq_printf(s, " gpio-%-3d (%-20.20s) in %s %s", - gpio, - label ?: "(none)", - pulls[pullidx], - (mode < 0) ? "unknown" : modes[mode]); - - val = nmk_gpio_get_input(chip, offset); - seq_printf(s, " VAL %d", val); - - /* - * This races with request_irq(), set_irq_type(), - * and set_irq_wake() ... but those are "rare". - */ - if (irq > 0 && irq_has_action(irq)) { - char *trigger; - bool wake; - - if (nmk_chip->edge_rising & BIT(offset)) - trigger = "edge-rising"; - else if (nmk_chip->edge_falling & BIT(offset)) - trigger = "edge-falling"; - else - trigger = "edge-undefined"; - - wake = !!(nmk_chip->real_wake & BIT(offset)); - - seq_printf(s, " irq-%d %s%s", - irq, trigger, wake ? " wakeup" : ""); - } - } - clk_disable(nmk_chip->clk); -} - -static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) -{ - unsigned i; - unsigned gpio = chip->base; - - for (i = 0; i < chip->ngpio; i++, gpio++) { - nmk_gpio_dbg_show_one(s, NULL, chip, i, gpio); - seq_printf(s, "\n"); - } -} - -#else -static inline void nmk_gpio_dbg_show_one(struct seq_file *s, - struct pinctrl_dev *pctldev, - struct gpio_chip *chip, - unsigned offset, unsigned gpio) -{ -} -#define nmk_gpio_dbg_show NULL -#endif - -/* - * We will allocate memory for the state container using devm* allocators - * binding to the first device reaching this point, it doesn't matter if - * it is the pin controller or GPIO driver. However we need to use the right - * platform device when looking up resources so pay attention to pdev. - */ -static struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np, - struct platform_device *pdev) -{ - struct nmk_gpio_chip *nmk_chip; - struct platform_device *gpio_pdev; - struct gpio_chip *chip; - struct resource *res; - struct clk *clk; - void __iomem *base; - u32 id; - - gpio_pdev = of_find_device_by_node(np); - if (!gpio_pdev) { - pr_err("populate \"%pOFn\": device not found\n", np); - return ERR_PTR(-ENODEV); - } - if (of_property_read_u32(np, "gpio-bank", &id)) { - dev_err(&pdev->dev, "populate: gpio-bank property not found\n"); - platform_device_put(gpio_pdev); - return ERR_PTR(-EINVAL); - } - - /* Already populated? */ - nmk_chip = nmk_gpio_chips[id]; - if (nmk_chip) { - platform_device_put(gpio_pdev); - return nmk_chip; - } - - nmk_chip = devm_kzalloc(&pdev->dev, sizeof(*nmk_chip), GFP_KERNEL); - if (!nmk_chip) { - platform_device_put(gpio_pdev); - return ERR_PTR(-ENOMEM); - } - - nmk_chip->bank = id; - chip = &nmk_chip->chip; - chip->base = id * NMK_GPIO_PER_CHIP; - chip->ngpio = NMK_GPIO_PER_CHIP; - chip->label = dev_name(&gpio_pdev->dev); - chip->parent = &gpio_pdev->dev; - - res = platform_get_resource(gpio_pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(base)) { - platform_device_put(gpio_pdev); - return ERR_CAST(base); - } - nmk_chip->addr = base; - - clk = clk_get(&gpio_pdev->dev, NULL); - if (IS_ERR(clk)) { - platform_device_put(gpio_pdev); - return (void *) clk; - } - clk_prepare(clk); - nmk_chip->clk = clk; - - BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips)); - nmk_gpio_chips[id] = nmk_chip; - return nmk_chip; -} - -static void nmk_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); - - seq_printf(p, "nmk%u-%u-%u", nmk_chip->bank, - gc->base, gc->base + gc->ngpio - 1); -} - -static const struct irq_chip nmk_irq_chip = { - .irq_ack = nmk_gpio_irq_ack, - .irq_mask = nmk_gpio_irq_mask, - .irq_unmask = nmk_gpio_irq_unmask, - .irq_set_type = nmk_gpio_irq_set_type, - .irq_set_wake = nmk_gpio_irq_set_wake, - .irq_startup = nmk_gpio_irq_startup, - .irq_shutdown = nmk_gpio_irq_shutdown, - .irq_print_chip = nmk_gpio_irq_print_chip, - .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_IMMUTABLE, - GPIOCHIP_IRQ_RESOURCE_HELPERS, -}; - -static int nmk_gpio_probe(struct platform_device *dev) -{ - struct device_node *np = dev->dev.of_node; - struct nmk_gpio_chip *nmk_chip; - struct gpio_chip *chip; - struct gpio_irq_chip *girq; - bool supports_sleepmode; - int irq; - int ret; - - nmk_chip = nmk_gpio_populate_chip(np, dev); - if (IS_ERR(nmk_chip)) { - dev_err(&dev->dev, "could not populate nmk chip struct\n"); - return PTR_ERR(nmk_chip); - } - - supports_sleepmode = - of_property_read_bool(np, "st,supports-sleepmode"); - - /* Correct platform device ID */ - dev->id = nmk_chip->bank; - - irq = platform_get_irq(dev, 0); - if (irq < 0) - return irq; - - /* - * The virt address in nmk_chip->addr is in the nomadik register space, - * so we can simply convert the resource address, without remapping - */ - nmk_chip->sleepmode = supports_sleepmode; - spin_lock_init(&nmk_chip->lock); - - chip = &nmk_chip->chip; - chip->parent = &dev->dev; - chip->request = gpiochip_generic_request; - chip->free = gpiochip_generic_free; - chip->get_direction = nmk_gpio_get_dir; - chip->direction_input = nmk_gpio_make_input; - chip->get = nmk_gpio_get_input; - chip->direction_output = nmk_gpio_make_output; - chip->set = nmk_gpio_set_output; - chip->dbg_show = nmk_gpio_dbg_show; - chip->can_sleep = false; - chip->owner = THIS_MODULE; - - girq = &chip->irq; - gpio_irq_chip_set_chip(girq, &nmk_irq_chip); - girq->parent_handler = nmk_gpio_irq_handler; - girq->num_parents = 1; - girq->parents = devm_kcalloc(&dev->dev, 1, - sizeof(*girq->parents), - GFP_KERNEL); - if (!girq->parents) - return -ENOMEM; - girq->parents[0] = irq; - girq->default_type = IRQ_TYPE_NONE; - girq->handler = handle_edge_irq; - - clk_enable(nmk_chip->clk); - nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI); - clk_disable(nmk_chip->clk); - - ret = gpiochip_add_data(chip, nmk_chip); - if (ret) - return ret; - - platform_set_drvdata(dev, nmk_chip); - - dev_info(&dev->dev, "chip registered\n"); - - return 0; -} - static int nmk_get_groups_cnt(struct pinctrl_dev *pctldev) { struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); @@ -1188,43 +513,51 @@ static int nmk_get_groups_cnt(struct pinctrl_dev *pctldev) } static const char *nmk_get_group_name(struct pinctrl_dev *pctldev, - unsigned selector) + unsigned int selector) { struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); return npct->soc->groups[selector].grp.name; } -static int nmk_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, - const unsigned **pins, - unsigned *npins) +static int nmk_get_group_pins(struct pinctrl_dev *pctldev, unsigned int selector, + const unsigned int **pins, + unsigned int *num_pins) { struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); *pins = npct->soc->groups[selector].grp.pins; - *npins = npct->soc->groups[selector].grp.npins; + *num_pins = npct->soc->groups[selector].grp.npins; return 0; } -static struct nmk_gpio_chip *find_nmk_gpio_from_pin(unsigned pin) +/* This makes the mapping from pin number to a GPIO chip. We also return the pin + * offset in the GPIO chip for convenience (and to avoid a second loop). + */ +static struct nmk_gpio_chip *find_nmk_gpio_from_pin(unsigned int pin, + unsigned int *offset) { - int i; + int i, j = 0; struct nmk_gpio_chip *nmk_gpio; - for(i = 0; i < NMK_MAX_BANKS; i++) { + /* We assume that pins are allocated in bank order. */ + for (i = 0; i < NMK_MAX_BANKS; i++) { nmk_gpio = nmk_gpio_chips[i]; if (!nmk_gpio) continue; - if (pin >= nmk_gpio->chip.base && - pin < nmk_gpio->chip.base + nmk_gpio->chip.ngpio) + if (pin >= j && pin < j + nmk_gpio->chip.ngpio) { + if (offset) + *offset = pin - j; return nmk_gpio; + } + j += nmk_gpio->chip.ngpio; } return NULL; } -static struct gpio_chip *find_gc_from_pin(unsigned pin) +static struct gpio_chip *find_gc_from_pin(unsigned int pin) { - struct nmk_gpio_chip *nmk_gpio = find_nmk_gpio_from_pin(pin); + struct nmk_gpio_chip *nmk_gpio = find_nmk_gpio_from_pin(pin, NULL); if (nmk_gpio) return &nmk_gpio->chip; @@ -1232,7 +565,7 @@ static struct gpio_chip *find_gc_from_pin(unsigned pin) } static void nmk_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, - unsigned offset) + unsigned int offset) { struct gpio_chip *chip = find_gc_from_pin(offset); @@ -1243,9 +576,9 @@ static void nmk_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, nmk_gpio_dbg_show_one(s, pctldev, chip, offset - chip->base, offset); } -static int nmk_dt_add_map_mux(struct pinctrl_map **map, unsigned *reserved_maps, - unsigned *num_maps, const char *group, - const char *function) +static int nmk_dt_add_map_mux(struct pinctrl_map **map, unsigned int *reserved_maps, + unsigned int *num_maps, const char *group, + const char *function) { if (*num_maps == *reserved_maps) return -ENOSPC; @@ -1259,9 +592,9 @@ static int nmk_dt_add_map_mux(struct pinctrl_map **map, unsigned *reserved_maps, } static int nmk_dt_add_map_configs(struct pinctrl_map **map, - unsigned *reserved_maps, - unsigned *num_maps, const char *group, - unsigned long *configs, unsigned num_configs) + unsigned int *reserved_maps, + unsigned int *num_maps, const char *group, + unsigned long *configs, unsigned int num_configs) { unsigned long *dup_configs; @@ -1352,9 +685,9 @@ static const struct nmk_cfg_param nmk_cfg_params[] = { static int nmk_dt_pin_config(int index, int val, unsigned long *config) { - if (nmk_cfg_params[index].choice == NULL) + if (!nmk_cfg_params[index].choice) { *config = nmk_cfg_params[index].config; - else { + } else { /* test if out of range */ if (val < nmk_cfg_params[index].size) { *config = nmk_cfg_params[index].config | @@ -1377,15 +710,14 @@ static const char *nmk_find_pin_name(struct pinctrl_dev *pctldev, const char *pi } static bool nmk_pinctrl_dt_get_config(struct device_node *np, - unsigned long *configs) + unsigned long *configs) { bool has_config = 0; unsigned long cfg = 0; int i, val, ret; for (i = 0; i < ARRAY_SIZE(nmk_cfg_params); i++) { - ret = of_property_read_u32(np, - nmk_cfg_params[i].property, &val); + ret = of_property_read_u32(np, nmk_cfg_params[i].property, &val); if (ret != -EINVAL) { if (nmk_dt_pin_config(i, val, &cfg) == 0) { *configs |= cfg; @@ -1398,10 +730,10 @@ static bool nmk_pinctrl_dt_get_config(struct device_node *np, } static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, - struct device_node *np, - struct pinctrl_map **map, - unsigned *reserved_maps, - unsigned *num_maps) + struct device_node *np, + struct pinctrl_map **map, + unsigned int *reserved_maps, + unsigned int *num_maps) { int ret; const char *function = NULL; @@ -1426,7 +758,7 @@ static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, of_property_for_each_string(np, "groups", prop, group) { ret = nmk_dt_add_map_mux(map, reserved_maps, num_maps, - group, function); + group, function); if (ret < 0) goto exit; } @@ -1467,10 +799,11 @@ exit: } static int nmk_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *np_config, - struct pinctrl_map **map, unsigned *num_maps) + struct device_node *np_config, + struct pinctrl_map **map, + unsigned int *num_maps) { - unsigned reserved_maps; + unsigned int reserved_maps; struct device_node *np; int ret; @@ -1480,7 +813,7 @@ static int nmk_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, for_each_child_of_node(np_config, np) { ret = nmk_pinctrl_dt_subnode_to_map(pctldev, np, map, - &reserved_maps, num_maps); + &reserved_maps, num_maps); if (ret < 0) { pinctrl_utils_free_map(pctldev, *map, *num_maps); of_node_put(np); @@ -1508,7 +841,7 @@ static int nmk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev) } static const char *nmk_pmx_get_func_name(struct pinctrl_dev *pctldev, - unsigned function) + unsigned int function) { struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); @@ -1516,7 +849,7 @@ static const char *nmk_pmx_get_func_name(struct pinctrl_dev *pctldev, } static int nmk_pmx_get_func_groups(struct pinctrl_dev *pctldev, - unsigned function, + unsigned int function, const char * const **groups, unsigned * const num_groups) { @@ -1528,12 +861,12 @@ static int nmk_pmx_get_func_groups(struct pinctrl_dev *pctldev, return 0; } -static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned function, - unsigned group) +static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function, + unsigned int group) { struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); const struct nmk_pingroup *g; - static unsigned int slpm[NUM_BANKS]; + static unsigned int slpm[NMK_MAX_BANKS]; unsigned long flags = 0; bool glitch; int ret = -EINVAL; @@ -1544,7 +877,7 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned function, if (g->altsetting < 0) return -EINVAL; - dev_dbg(npct->dev, "enable group %s, %u pins\n", g->grp.name, g->grp.npins); + dev_dbg(npct->dev, "enable group %s, %zu pins\n", g->grp.name, g->grp.npins); /* * If we're setting altfunc C by setting both AFSLA and AFSLB to 1, @@ -1579,26 +912,38 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned function, * Then mask the pins that need to be sleeping now when we're * switching to the ALT C function. */ - for (i = 0; i < g->grp.npins; i++) - slpm[g->grp.pins[i] / NMK_GPIO_PER_CHIP] &= ~BIT(g->grp.pins[i]); + for (i = 0; i < g->grp.npins; i++) { + struct nmk_gpio_chip *nmk_chip; + unsigned int bit; + + nmk_chip = find_nmk_gpio_from_pin(g->grp.pins[i], &bit); + if (!nmk_chip) { + dev_err(npct->dev, + "invalid pin offset %d in group %s at index %d\n", + g->grp.pins[i], g->grp.name, i); + goto out_pre_slpm_init; + } + + slpm[nmk_chip->bank] &= ~BIT(bit); + } nmk_gpio_glitch_slpm_init(slpm); } for (i = 0; i < g->grp.npins; i++) { struct nmk_gpio_chip *nmk_chip; - unsigned bit; + unsigned int bit; - nmk_chip = find_nmk_gpio_from_pin(g->grp.pins[i]); + nmk_chip = find_nmk_gpio_from_pin(g->grp.pins[i], &bit); if (!nmk_chip) { dev_err(npct->dev, "invalid pin offset %d in group %s at index %d\n", g->grp.pins[i], g->grp.name, i); goto out_glitch; } - dev_dbg(npct->dev, "setting pin %d to altsetting %d\n", g->grp.pins[i], g->altsetting); + dev_dbg(npct->dev, "setting pin %d to altsetting %d\n", + g->grp.pins[i], g->altsetting); clk_enable(nmk_chip->clk); - bit = g->grp.pins[i] % NMK_GPIO_PER_CHIP; /* * If the pin is switching to altfunc, and there was an * interrupt installed on it which has been lazy disabled, @@ -1609,7 +954,7 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned function, nmk_gpio_disable_lazy_irq(nmk_chip, bit); __nmk_gpio_set_mode_safe(nmk_chip, bit, - (g->altsetting & NMK_GPIO_ALT_C), glitch); + (g->altsetting & NMK_GPIO_ALT_C), glitch); clk_disable(nmk_chip->clk); /* @@ -1622,29 +967,30 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned function, */ if ((g->altsetting & NMK_GPIO_ALT_C) == NMK_GPIO_ALT_C) nmk_prcm_altcx_set_mode(npct, g->grp.pins[i], - g->altsetting >> NMK_GPIO_ALT_CX_SHIFT); + g->altsetting >> NMK_GPIO_ALT_CX_SHIFT); } /* When all pins are successfully reconfigured we get here */ ret = 0; out_glitch: - if (glitch) { + if (glitch) nmk_gpio_glitch_slpm_restore(slpm); +out_pre_slpm_init: + if (glitch) spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); - } return ret; } static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, - unsigned offset) + unsigned int pin) { struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); struct nmk_gpio_chip *nmk_chip; struct gpio_chip *chip; - unsigned bit; + unsigned int bit; if (!range) { dev_err(npct->dev, "invalid range\n"); @@ -1657,10 +1003,11 @@ static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev, chip = range->gc; nmk_chip = gpiochip_get_data(chip); - dev_dbg(npct->dev, "enable pin %u as GPIO\n", offset); + dev_dbg(npct->dev, "enable pin %u as GPIO\n", pin); + + find_nmk_gpio_from_pin(pin, &bit); clk_enable(nmk_chip->clk); - bit = offset % NMK_GPIO_PER_CHIP; /* There is no glitch when converting any pin to GPIO */ __nmk_gpio_set_mode(nmk_chip, bit, NMK_GPIO_ALT_GPIO); clk_disable(nmk_chip->clk); @@ -1670,11 +1017,11 @@ static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev, static void nmk_gpio_disable_free(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, - unsigned offset) + unsigned int pin) { struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); - dev_dbg(npct->dev, "disable pin %u as GPIO\n", offset); + dev_dbg(npct->dev, "disable pin %u as GPIO\n", pin); /* Set the pin to some default state, GPIO is usually default */ } @@ -1688,34 +1035,34 @@ static const struct pinmux_ops nmk_pinmux_ops = { .strict = true, }; -static int nmk_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, +static int nmk_pin_config_get(struct pinctrl_dev *pctldev, unsigned int pin, unsigned long *config) { /* Not implemented */ return -EINVAL; } -static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, - unsigned long *configs, unsigned num_configs) +static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *configs, unsigned int num_configs) { - static const char *pullnames[] = { + static const char * const pullnames[] = { [NMK_GPIO_PULL_NONE] = "none", [NMK_GPIO_PULL_UP] = "up", [NMK_GPIO_PULL_DOWN] = "down", [3] /* illegal */ = "??" }; - static const char *slpmnames[] = { + static const char * const slpmnames[] = { [NMK_GPIO_SLPM_INPUT] = "input/wakeup", [NMK_GPIO_SLPM_NOCHANGE] = "no-change/no-wakeup", }; struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); struct nmk_gpio_chip *nmk_chip; - unsigned bit; - pin_cfg_t cfg; + unsigned int bit; + unsigned long cfg; int pull, slpm, output, val, i; bool lowemi, gpiomode, sleep; - nmk_chip = find_nmk_gpio_from_pin(pin); + nmk_chip = find_nmk_gpio_from_pin(pin, &bit); if (!nmk_chip) { dev_err(npct->dev, "invalid pin offset %d\n", pin); @@ -1728,7 +1075,7 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, * here we just ignore that part. It's being handled by the * framework and pinmux callback respectively. */ - cfg = (pin_cfg_t) configs[i]; + cfg = configs[i]; pull = PIN_PULL(cfg); slpm = PIN_SLPM(cfg); output = PIN_DIR(cfg); @@ -1773,13 +1120,12 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, lowemi ? "on" : "off"); clk_enable(nmk_chip->clk); - bit = pin % NMK_GPIO_PER_CHIP; if (gpiomode) /* No glitch when going to GPIO mode */ __nmk_gpio_set_mode(nmk_chip, bit, NMK_GPIO_ALT_GPIO); - if (output) + if (output) { __nmk_gpio_make_output(nmk_chip, bit, val); - else { + } else { __nmk_gpio_make_input(nmk_chip, bit); __nmk_gpio_set_pull(nmk_chip, bit, pull); } @@ -1844,17 +1190,17 @@ static int nmk_pinctrl_resume(struct device *dev) static int nmk_pinctrl_probe(struct platform_device *pdev) { - struct device_node *np = pdev->dev.of_node; - struct device_node *prcm_np; + struct fwnode_handle *fwnode = dev_fwnode(&pdev->dev); + struct fwnode_handle *prcm_fwnode; struct nmk_pinctrl *npct; - unsigned int version = 0; + uintptr_t version = 0; int i; npct = devm_kzalloc(&pdev->dev, sizeof(*npct), GFP_KERNEL); if (!npct) return -ENOMEM; - version = (unsigned int)device_get_match_data(&pdev->dev); + version = (uintptr_t)device_get_match_data(&pdev->dev); /* Poke in other ASIC variants here */ if (version == PINCTRL_NMK_STN8815) @@ -1870,33 +1216,33 @@ static int nmk_pinctrl_probe(struct platform_device *pdev) * or after this point: it shouldn't matter as the APIs are orthogonal. */ for (i = 0; i < NMK_MAX_BANKS; i++) { - struct device_node *gpio_np; + struct fwnode_handle *gpio_fwnode; struct nmk_gpio_chip *nmk_chip; - gpio_np = of_parse_phandle(np, "nomadik-gpio-chips", i); - if (gpio_np) { - dev_info(&pdev->dev, - "populate NMK GPIO %d \"%pOFn\"\n", - i, gpio_np); - nmk_chip = nmk_gpio_populate_chip(gpio_np, pdev); - if (IS_ERR(nmk_chip)) - dev_err(&pdev->dev, - "could not populate nmk chip struct " - "- continue anyway\n"); - of_node_put(gpio_np); - } + gpio_fwnode = fwnode_find_reference(fwnode, "nomadik-gpio-chips", i); + if (IS_ERR(gpio_fwnode)) + continue; + + dev_info(&pdev->dev, "populate NMK GPIO %d \"%pfwP\"\n", i, gpio_fwnode); + nmk_chip = nmk_gpio_populate_chip(gpio_fwnode, pdev); + if (IS_ERR(nmk_chip)) + dev_err(&pdev->dev, + "could not populate nmk chip struct - continue anyway\n"); + else + /* We are NOT compatible with mobileye,eyeq5-gpio. */ + BUG_ON(nmk_chip->is_mobileye_soc); + fwnode_handle_put(gpio_fwnode); } - prcm_np = of_parse_phandle(np, "prcm", 0); - if (prcm_np) { - npct->prcm_base = of_iomap(prcm_np, 0); - of_node_put(prcm_np); + prcm_fwnode = fwnode_find_reference(fwnode, "prcm", 0); + if (!IS_ERR(prcm_fwnode)) { + npct->prcm_base = fwnode_iomap(prcm_fwnode, 0); + fwnode_handle_put(prcm_fwnode); } if (!npct->prcm_base) { if (version == PINCTRL_NMK_STN8815) { dev_info(&pdev->dev, - "No PRCM base, " - "assuming no ALT-Cx control is available\n"); + "No PRCM base, assuming no ALT-Cx control is available\n"); } else { dev_err(&pdev->dev, "missing PRCM base address\n"); return -EINVAL; @@ -1919,19 +1265,6 @@ static int nmk_pinctrl_probe(struct platform_device *pdev) return 0; } -static const struct of_device_id nmk_gpio_match[] = { - { .compatible = "st,nomadik-gpio", }, - {} -}; - -static struct platform_driver nmk_gpio_driver = { - .driver = { - .name = "gpio", - .of_match_table = nmk_gpio_match, - }, - .probe = nmk_gpio_probe, -}; - static SIMPLE_DEV_PM_OPS(nmk_pinctrl_pm_ops, nmk_pinctrl_suspend, nmk_pinctrl_resume); @@ -1945,12 +1278,6 @@ static struct platform_driver nmk_pinctrl_driver = { .probe = nmk_pinctrl_probe, }; -static int __init nmk_gpio_init(void) -{ - return platform_driver_register(&nmk_gpio_driver); -} -subsys_initcall(nmk_gpio_init); - static int __init nmk_pinctrl_init(void) { return platform_driver_register(&nmk_pinctrl_driver); diff --git a/drivers/pinctrl/nuvoton/pinctrl-wpcm450.c b/drivers/pinctrl/nuvoton/pinctrl-wpcm450.c index 4589900244c7..cdad4ef11a2f 100644 --- a/drivers/pinctrl/nuvoton/pinctrl-wpcm450.c +++ b/drivers/pinctrl/nuvoton/pinctrl-wpcm450.c @@ -474,7 +474,7 @@ enum { #undef WPCM450_GRP }; -static struct pingroup wpcm450_groups[] = { +static const struct pingroup wpcm450_groups[] = { #define WPCM450_GRP(x) PINCTRL_PINGROUP(#x, x ## _pins, ARRAY_SIZE(x ## _pins)) WPCM450_GRPS #undef WPCM450_GRP diff --git a/drivers/pinctrl/pinctrl-aw9523.c b/drivers/pinctrl/pinctrl-aw9523.c new file mode 100644 index 000000000000..4edd371c469f --- /dev/null +++ b/drivers/pinctrl/pinctrl-aw9523.c @@ -0,0 +1,1119 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Awinic AW9523B i2c pin controller driver + * Copyright (c) 2020, AngeloGioacchino Del Regno + * <angelogioacchino.delregno@somainline.org> + */ + +#include <linux/bitfield.h> +#include <linux/gpio/consumer.h> +#include <linux/gpio/driver.h> +#include <linux/i2c.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/mutex.h> +#include <linux/module.h> +#include <linux/pinctrl/pinconf.h> +#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/pinmux.h> +#include <linux/pinctrl/pinconf-generic.h> +#include <linux/property.h> +#include <linux/regmap.h> +#include <linux/regulator/consumer.h> +#include <linux/slab.h> + +#define AW9523_MAX_FUNCS 2 +#define AW9523_NUM_PORTS 2 +#define AW9523_PINS_PER_PORT 8 + +/* + * HW needs at least 20uS for reset and at least 1-2uS to recover from + * reset, but we have to account for eventual board quirks, if any: + * for this reason, keep reset asserted for 50uS and wait for 20uS + * to recover from the reset. + */ +#define AW9523_HW_RESET_US 50 +#define AW9523_HW_RESET_RECOVERY_US 20 + +/* Port 0: P0_0...P0_7 - Port 1: P1_0...P1_7 */ +#define AW9523_PIN_TO_PORT(pin) (pin >> 3) +#define AW9523_REG_IN_STATE(pin) (0x00 + AW9523_PIN_TO_PORT(pin)) +#define AW9523_REG_OUT_STATE(pin) (0x02 + AW9523_PIN_TO_PORT(pin)) +#define AW9523_REG_CONF_STATE(pin) (0x04 + AW9523_PIN_TO_PORT(pin)) +#define AW9523_REG_INTR_DIS(pin) (0x06 + AW9523_PIN_TO_PORT(pin)) +#define AW9523_REG_CHIPID 0x10 +#define AW9523_VAL_EXPECTED_CHIPID 0x23 + +#define AW9523_REG_GCR 0x11 +#define AW9523_GCR_ISEL_MASK GENMASK(0, 1) +#define AW9523_GCR_GPOMD_MASK BIT(4) + +#define AW9523_REG_PORT_MODE(pin) (0x12 + AW9523_PIN_TO_PORT(pin)) +#define AW9523_REG_SOFT_RESET 0x7f +#define AW9523_VAL_RESET 0x00 + +/* + * struct aw9523_irq - Interrupt controller structure + * @lock: mutex locking for the irq bus + * @irqchip: structure holding irqchip params + * @cached_gpio: stores the previous gpio status for bit comparison + */ +struct aw9523_irq { + struct mutex lock; + struct irq_chip *irqchip; + u16 cached_gpio; +}; + +/* + * struct aw9523_pinmux - Pin mux params + * @name: Name of the mux + * @grps: Groups of the mux + * @num_grps: Number of groups (sizeof array grps) + */ +struct aw9523_pinmux { + const char *name; + const char * const *grps; + const u8 num_grps; +}; + +/* + * struct aw9523 - Main driver structure + * @dev: device handle + * @regmap: regmap handle for current device + * @i2c_lock: Mutex lock for i2c operations + * @reset_gpio: Hardware reset (RSTN) signal GPIO + * @vio_vreg: VCC regulator (Optional) + * @pctl: pinctrl handle for current device + * @gpio: structure holding gpiochip params + * @irq: Interrupt controller structure + */ +struct aw9523 { + struct device *dev; + struct regmap *regmap; + struct mutex i2c_lock; + struct gpio_desc *reset_gpio; + struct regulator *vio_vreg; + struct pinctrl_dev *pctl; + struct gpio_chip gpio; + struct aw9523_irq *irq; +}; + +static const struct pinctrl_pin_desc aw9523_pins[] = { + /* Port 0 */ + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + PINCTRL_PIN(2, "gpio2"), + PINCTRL_PIN(3, "gpio3"), + PINCTRL_PIN(4, "gpio4"), + PINCTRL_PIN(5, "gpio5"), + PINCTRL_PIN(6, "gpio6"), + PINCTRL_PIN(7, "gpio7"), + + /* Port 1 */ + PINCTRL_PIN(8, "gpio8"), + PINCTRL_PIN(9, "gpio9"), + PINCTRL_PIN(10, "gpio10"), + PINCTRL_PIN(11, "gpio11"), + PINCTRL_PIN(12, "gpio12"), + PINCTRL_PIN(13, "gpio13"), + PINCTRL_PIN(14, "gpio14"), + PINCTRL_PIN(15, "gpio15"), +}; + +static int aw9523_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(aw9523_pins); +} + +static const char *aw9523_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + return aw9523_pins[selector].name; +} + +static int aw9523_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned int selector, + const unsigned int **pins, + unsigned int *num_pins) +{ + *pins = &aw9523_pins[selector].number; + *num_pins = 1; + return 0; +} + +static const struct pinctrl_ops aw9523_pinctrl_ops = { + .get_groups_count = aw9523_pinctrl_get_groups_count, + .get_group_pins = aw9523_pinctrl_get_group_pins, + .get_group_name = aw9523_pinctrl_get_group_name, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .dt_free_map = pinconf_generic_dt_free_map, +}; + +static const char * const gpio_pwm_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", + "gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11", + "gpio12", "gpio13", "gpio14", "gpio15" +}; + +/* Warning: Do NOT reorder this array */ +static const struct aw9523_pinmux aw9523_pmx[] = { + { + .name = "pwm", + .grps = gpio_pwm_groups, + .num_grps = ARRAY_SIZE(gpio_pwm_groups), + }, + { + .name = "gpio", + .grps = gpio_pwm_groups, + .num_grps = ARRAY_SIZE(gpio_pwm_groups), + }, +}; + +static int aw9523_pmx_get_funcs_count(struct pinctrl_dev *pctl) +{ + return ARRAY_SIZE(aw9523_pmx); +} + +static const char *aw9523_pmx_get_fname(struct pinctrl_dev *pctl, + unsigned int sel) +{ + return aw9523_pmx[sel].name; +} + +static int aw9523_pmx_get_groups(struct pinctrl_dev *pctl, unsigned int sel, + const char * const **groups, + unsigned int * const num_groups) +{ + *groups = aw9523_pmx[sel].grps; + *num_groups = aw9523_pmx[sel].num_grps; + return 0; +} + +static int aw9523_pmx_set_mux(struct pinctrl_dev *pctl, unsigned int fsel, + unsigned int grp) +{ + struct aw9523 *awi = pinctrl_dev_get_drvdata(pctl); + int ret, pin = aw9523_pins[grp].number % AW9523_PINS_PER_PORT; + + if (fsel >= ARRAY_SIZE(aw9523_pmx)) + return -EINVAL; + + /* + * This maps directly to the aw9523_pmx array: programming a + * high bit means "gpio" and a low bit means "pwm". + */ + mutex_lock(&awi->i2c_lock); + ret = regmap_update_bits(awi->regmap, AW9523_REG_PORT_MODE(pin), + BIT(pin), (fsel ? BIT(pin) : 0)); + mutex_unlock(&awi->i2c_lock); + return ret; +} + +static const struct pinmux_ops aw9523_pinmux_ops = { + .get_functions_count = aw9523_pmx_get_funcs_count, + .get_function_name = aw9523_pmx_get_fname, + .get_function_groups = aw9523_pmx_get_groups, + .set_mux = aw9523_pmx_set_mux, +}; + +static int aw9523_pcfg_param_to_reg(enum pin_config_param pcp, int pin, u8 *r) +{ + u8 reg; + + switch (pcp) { + case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: + case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_BIAS_PULL_UP: + reg = AW9523_REG_IN_STATE(pin); + break; + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + case PIN_CONFIG_DRIVE_PUSH_PULL: + reg = AW9523_REG_GCR; + break; + case PIN_CONFIG_INPUT_ENABLE: + case PIN_CONFIG_OUTPUT_ENABLE: + reg = AW9523_REG_CONF_STATE(pin); + break; + case PIN_CONFIG_OUTPUT: + reg = AW9523_REG_OUT_STATE(pin); + break; + default: + return -EOPNOTSUPP; + } + *r = reg; + + return 0; +} + +static int aw9523_pconf_get(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *config) +{ + struct aw9523 *awi = pinctrl_dev_get_drvdata(pctldev); + enum pin_config_param param = pinconf_to_config_param(*config); + int regbit = pin % AW9523_PINS_PER_PORT; + unsigned int val; + u8 reg; + int rc; + + rc = aw9523_pcfg_param_to_reg(param, pin, ®); + if (rc) + return rc; + + mutex_lock(&awi->i2c_lock); + rc = regmap_read(awi->regmap, reg, &val); + mutex_unlock(&awi->i2c_lock); + if (rc) + return rc; + + switch (param) { + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_INPUT_ENABLE: + case PIN_CONFIG_OUTPUT: + val &= BIT(regbit); + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_OUTPUT_ENABLE: + val &= BIT(regbit); + val = !val; + break; + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + if (pin >= AW9523_PINS_PER_PORT) + val = 0; + else + val = !FIELD_GET(AW9523_GCR_GPOMD_MASK, val); + break; + case PIN_CONFIG_DRIVE_PUSH_PULL: + if (pin >= AW9523_PINS_PER_PORT) + val = 1; + else + val = FIELD_GET(AW9523_GCR_GPOMD_MASK, val); + break; + default: + return -EOPNOTSUPP; + } + if (val < 1) + return -EINVAL; + + *config = pinconf_to_config_packed(param, !!val); + + return rc; +} + +static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *configs, unsigned int num_configs) +{ + struct aw9523 *awi = pinctrl_dev_get_drvdata(pctldev); + enum pin_config_param param; + int regbit = pin % AW9523_PINS_PER_PORT; + u32 arg; + u8 reg; + unsigned int mask, val; + int i, rc; + + mutex_lock(&awi->i2c_lock); + for (i = 0; i < num_configs; i++) { + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); + + rc = aw9523_pcfg_param_to_reg(param, pin, ®); + if (rc) + goto end; + + switch (param) { + case PIN_CONFIG_OUTPUT: + /* First, enable pin output */ + rc = regmap_update_bits(awi->regmap, + AW9523_REG_CONF_STATE(pin), + BIT(regbit), 0); + if (rc) + goto end; + + /* Then, fall through to config output level */ + fallthrough; + case PIN_CONFIG_OUTPUT_ENABLE: + arg = !arg; + fallthrough; + case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: + case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_INPUT_ENABLE: + mask = BIT(regbit); + val = arg ? BIT(regbit) : 0; + break; + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + /* Open-Drain is supported only on port 0 */ + if (pin >= AW9523_PINS_PER_PORT) { + rc = -EOPNOTSUPP; + goto end; + } + mask = AW9523_GCR_GPOMD_MASK; + val = 0; + break; + case PIN_CONFIG_DRIVE_PUSH_PULL: + /* Port 1 is always Push-Pull */ + if (pin >= AW9523_PINS_PER_PORT) { + mask = 0; + val = 0; + continue; + } + mask = AW9523_GCR_GPOMD_MASK; + val = AW9523_GCR_GPOMD_MASK; + break; + default: + rc = -EOPNOTSUPP; + goto end; + } + + rc = regmap_update_bits(awi->regmap, reg, mask, val); + if (rc) + goto end; + } +end: + mutex_unlock(&awi->i2c_lock); + return rc; +} + +static const struct pinconf_ops aw9523_pinconf_ops = { + .pin_config_get = aw9523_pconf_get, + .pin_config_set = aw9523_pconf_set, + .is_generic = true, +}; + +/* + * aw9523_get_pin_direction - Get pin direction + * @regmap: Regmap structure + * @pin: gpiolib pin number + * @n: pin index in port register + * + * Return: Pin direction for success or negative number for error + */ +static int aw9523_get_pin_direction(struct regmap *regmap, u8 pin, u8 n) +{ + int ret; + + ret = regmap_test_bits(regmap, AW9523_REG_CONF_STATE(pin), BIT(n)); + if (ret < 0) + return ret; + + return ret ? GPIO_LINE_DIRECTION_IN : GPIO_LINE_DIRECTION_OUT; +} + +/* + * aw9523_get_port_state - Get input or output state for entire port + * @regmap: Regmap structure + * @pin: gpiolib pin number + * @regbit: hw pin index, used to retrieve port number + * @state: returned port state + * + * Return: Zero for success or negative number for error + */ +static int aw9523_get_port_state(struct regmap *regmap, u8 pin, + u8 regbit, unsigned int *state) +{ + u8 reg; + int dir; + + dir = aw9523_get_pin_direction(regmap, pin, regbit); + if (dir < 0) + return dir; + + if (dir == GPIO_LINE_DIRECTION_IN) + reg = AW9523_REG_IN_STATE(pin); + else + reg = AW9523_REG_OUT_STATE(pin); + + return regmap_read(regmap, reg, state); +} + +static int aw9523_gpio_irq_type(struct irq_data *d, unsigned int type) +{ + switch (type) { + case IRQ_TYPE_NONE: + case IRQ_TYPE_EDGE_BOTH: + return 0; + default: + return -EINVAL; + }; +} + +/* + * aw9523_irq_mask - Mask interrupt + * @d: irq data + * + * Sets which interrupt to mask in the bitmap; + * The interrupt will be masked when unlocking the irq bus. + */ +static void aw9523_irq_mask(struct irq_data *d) +{ + struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d)); + unsigned int n = d->hwirq % AW9523_PINS_PER_PORT; + + regmap_update_bits(awi->regmap, + AW9523_REG_INTR_DIS(d->hwirq), + BIT(n), BIT(n)); + gpiochip_disable_irq(&awi->gpio, irqd_to_hwirq(d)); +} + +/* + * aw9523_irq_unmask - Unmask interrupt + * @d: irq data + * + * Sets which interrupt to unmask in the bitmap; + * The interrupt will be masked when unlocking the irq bus. + */ +static void aw9523_irq_unmask(struct irq_data *d) +{ + struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d)); + unsigned int n = d->hwirq % AW9523_PINS_PER_PORT; + + gpiochip_enable_irq(&awi->gpio, irqd_to_hwirq(d)); + regmap_update_bits(awi->regmap, + AW9523_REG_INTR_DIS(d->hwirq), + BIT(n), 0); +} + +static irqreturn_t aw9523_irq_thread_func(int irq, void *dev_id) +{ + struct aw9523 *awi = (struct aw9523 *)dev_id; + unsigned long n, val = 0; + unsigned long changed_gpio; + unsigned int tmp, port_pin, i, ret; + + for (i = 0; i < AW9523_NUM_PORTS; i++) { + port_pin = i * AW9523_PINS_PER_PORT; + ret = regmap_read(awi->regmap, + AW9523_REG_IN_STATE(port_pin), + &tmp); + if (ret) + return ret; + val |= (u8)tmp << (i * 8); + } + + /* Handle GPIO input release interrupt as well */ + changed_gpio = awi->irq->cached_gpio ^ val; + awi->irq->cached_gpio = val; + + /* + * To avoid up to four *slow* i2c reads from any driver hooked + * up to our interrupts, just check for the irq_find_mapping + * result: if the interrupt is not mapped, then we don't want + * to care about it. + */ + for_each_set_bit(n, &changed_gpio, awi->gpio.ngpio) { + tmp = irq_find_mapping(awi->gpio.irq.domain, n); + if (tmp <= 0) + continue; + handle_nested_irq(tmp); + } + + return IRQ_HANDLED; +} + +/* + * aw9523_irq_bus_lock - Grab lock for interrupt operation + * @d: irq data + */ +static void aw9523_irq_bus_lock(struct irq_data *d) +{ + struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d)); + + mutex_lock(&awi->irq->lock); + regcache_cache_only(awi->regmap, true); +} + +/* + * aw9523_irq_bus_sync_unlock - Synchronize state and unlock + * @d: irq data + * + * Writes the interrupt mask bits (found in the bit map) to the + * hardware, then unlocks the bus. + */ +static void aw9523_irq_bus_sync_unlock(struct irq_data *d) +{ + struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d)); + + regcache_cache_only(awi->regmap, false); + regcache_sync(awi->regmap); + mutex_unlock(&awi->irq->lock); +} + +static int aw9523_gpio_get_direction(struct gpio_chip *chip, + unsigned int offset) +{ + struct aw9523 *awi = gpiochip_get_data(chip); + u8 regbit = offset % AW9523_PINS_PER_PORT; + int ret; + + mutex_lock(&awi->i2c_lock); + ret = aw9523_get_pin_direction(awi->regmap, offset, regbit); + mutex_unlock(&awi->i2c_lock); + + return ret; +} + +static int aw9523_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + struct aw9523 *awi = gpiochip_get_data(chip); + u8 regbit = offset % AW9523_PINS_PER_PORT; + unsigned int val; + int ret; + + mutex_lock(&awi->i2c_lock); + ret = aw9523_get_port_state(awi->regmap, offset, regbit, &val); + mutex_unlock(&awi->i2c_lock); + if (ret) + return ret; + + return !!(val & BIT(regbit)); +} + +/** + * _aw9523_gpio_get_multiple - Get I/O state for an entire port + * @regmap: Regmap structure + * @pin: gpiolib pin number + * @regbit: hw pin index, used to retrieve port number + * @state: returned port I/O state + * + * Return: Zero for success or negative number for error + */ +static int _aw9523_gpio_get_multiple(struct aw9523 *awi, u8 regbit, + u8 *state, u8 mask) +{ + u32 dir_in, val; + u8 m; + int ret; + + /* Registers are 8-bits wide */ + ret = regmap_read(awi->regmap, AW9523_REG_CONF_STATE(regbit), &dir_in); + if (ret) + return ret; + *state = 0; + + m = mask & dir_in; + if (m) { + ret = regmap_read(awi->regmap, AW9523_REG_IN_STATE(regbit), + &val); + if (ret) + return ret; + *state |= (u8)val & m; + } + + m = mask & ~dir_in; + if (m) { + ret = regmap_read(awi->regmap, AW9523_REG_OUT_STATE(regbit), + &val); + if (ret) + return ret; + *state |= (u8)val & m; + } + + return 0; +} + +static int aw9523_gpio_get_multiple(struct gpio_chip *chip, + unsigned long *mask, + unsigned long *bits) +{ + struct aw9523 *awi = gpiochip_get_data(chip); + u8 m, state = 0; + int ret; + + mutex_lock(&awi->i2c_lock); + + /* Port 0 (gpio 0-7) */ + m = *mask & U8_MAX; + if (m) { + ret = _aw9523_gpio_get_multiple(awi, 0, &state, m); + if (ret) + goto out; + } + *bits = state; + + /* Port 1 (gpio 8-15) */ + m = (*mask >> 8) & U8_MAX; + if (m) { + ret = _aw9523_gpio_get_multiple(awi, AW9523_PINS_PER_PORT, + &state, m); + if (ret) + goto out; + + *bits |= (state << 8); + } +out: + mutex_unlock(&awi->i2c_lock); + return ret; +} + +static void aw9523_gpio_set_multiple(struct gpio_chip *chip, + unsigned long *mask, + unsigned long *bits) +{ + struct aw9523 *awi = gpiochip_get_data(chip); + u8 mask_lo, mask_hi, bits_lo, bits_hi; + unsigned int reg; + int ret = 0; + + mask_lo = *mask & U8_MAX; + mask_hi = (*mask >> 8) & U8_MAX; + mutex_lock(&awi->i2c_lock); + if (mask_hi) { + reg = AW9523_REG_OUT_STATE(AW9523_PINS_PER_PORT); + bits_hi = (*bits >> 8) & U8_MAX; + + ret = regmap_write_bits(awi->regmap, reg, mask_hi, bits_hi); + if (ret) { + dev_warn(awi->dev, "Cannot write port1 out level\n"); + goto out; + } + } + if (mask_lo) { + reg = AW9523_REG_OUT_STATE(0); + bits_lo = *bits & U8_MAX; + ret = regmap_write_bits(awi->regmap, reg, mask_lo, bits_lo); + if (ret) + dev_warn(awi->dev, "Cannot write port0 out level\n"); + } +out: + mutex_unlock(&awi->i2c_lock); +} + +static void aw9523_gpio_set(struct gpio_chip *chip, + unsigned int offset, int value) +{ + struct aw9523 *awi = gpiochip_get_data(chip); + u8 regbit = offset % AW9523_PINS_PER_PORT; + + mutex_lock(&awi->i2c_lock); + regmap_update_bits(awi->regmap, AW9523_REG_OUT_STATE(offset), + BIT(regbit), value ? BIT(regbit) : 0); + mutex_unlock(&awi->i2c_lock); +} + + +static int aw9523_direction_input(struct gpio_chip *chip, unsigned int offset) +{ + struct aw9523 *awi = gpiochip_get_data(chip); + u8 regbit = offset % AW9523_PINS_PER_PORT; + int ret; + + mutex_lock(&awi->i2c_lock); + ret = regmap_update_bits(awi->regmap, AW9523_REG_CONF_STATE(offset), + BIT(regbit), BIT(regbit)); + mutex_unlock(&awi->i2c_lock); + + return ret; +} + +static int aw9523_direction_output(struct gpio_chip *chip, + unsigned int offset, int value) +{ + struct aw9523 *awi = gpiochip_get_data(chip); + u8 regbit = offset % AW9523_PINS_PER_PORT; + int ret; + + mutex_lock(&awi->i2c_lock); + ret = regmap_update_bits(awi->regmap, AW9523_REG_OUT_STATE(offset), + BIT(regbit), value ? BIT(regbit) : 0); + if (ret) + goto end; + + ret = regmap_update_bits(awi->regmap, AW9523_REG_CONF_STATE(offset), + BIT(regbit), 0); +end: + mutex_unlock(&awi->i2c_lock); + return ret; +} + +static int aw9523_drive_reset_gpio(struct aw9523 *awi) +{ + unsigned int chip_id; + int ret; + + /* + * If the chip is already configured for any reason, then we + * will probably succeed in sending the soft reset signal to + * the hardware through I2C: this operation takes less time + * compared to a full HW reset and it gives the same results. + */ + ret = regmap_write(awi->regmap, AW9523_REG_SOFT_RESET, 0); + if (ret == 0) + goto done; + + dev_dbg(awi->dev, "Cannot execute soft reset: trying hard reset\n"); + ret = gpiod_direction_output(awi->reset_gpio, 0); + if (ret) + return ret; + + /* The reset pulse has to be longer than 20uS due to deglitch */ + usleep_range(AW9523_HW_RESET_US, AW9523_HW_RESET_US + 1); + + ret = gpiod_direction_output(awi->reset_gpio, 1); + if (ret) + return ret; +done: + /* The HW needs at least 1uS to reliably recover after reset */ + usleep_range(AW9523_HW_RESET_RECOVERY_US, + AW9523_HW_RESET_RECOVERY_US + 1); + + /* Check the ChipID */ + ret = regmap_read(awi->regmap, AW9523_REG_CHIPID, &chip_id); + if (ret) { + dev_err(awi->dev, "Cannot read Chip ID: %d\n", ret); + return ret; + } + if (chip_id != AW9523_VAL_EXPECTED_CHIPID) { + dev_err(awi->dev, "Bad ChipID; read 0x%x, expected 0x%x\n", + chip_id, AW9523_VAL_EXPECTED_CHIPID); + return -EINVAL; + } + + return 0; +} + +static int aw9523_hw_reset(struct aw9523 *awi) +{ + int ret, max_retries = 2; + + /* Sometimes the chip needs more than one reset cycle */ + do { + ret = aw9523_drive_reset_gpio(awi); + if (ret == 0) + break; + max_retries--; + } while (max_retries); + + return ret; +} + +static int aw9523_init_gpiochip(struct aw9523 *awi, unsigned int npins) +{ + struct device *dev = awi->dev; + struct gpio_chip *gc = &awi->gpio; + + gc->label = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL); + if (!gc->label) + return -ENOMEM; + + gc->base = -1; + gc->ngpio = npins; + gc->get_direction = aw9523_gpio_get_direction; + gc->direction_input = aw9523_direction_input; + gc->direction_output = aw9523_direction_output; + gc->get = aw9523_gpio_get; + gc->get_multiple = aw9523_gpio_get_multiple; + gc->set = aw9523_gpio_set; + gc->set_multiple = aw9523_gpio_set_multiple; + gc->set_config = gpiochip_generic_config; + gc->parent = dev; + gc->owner = THIS_MODULE; + gc->can_sleep = false; + + return 0; +} + +static const struct irq_chip aw9523_irq_chip = { + .name = "aw9523", + .irq_mask = aw9523_irq_mask, + .irq_unmask = aw9523_irq_unmask, + .irq_bus_lock = aw9523_irq_bus_lock, + .irq_bus_sync_unlock = aw9523_irq_bus_sync_unlock, + .irq_set_type = aw9523_gpio_irq_type, + .flags = IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + +static int aw9523_init_irq(struct aw9523 *awi, int irq) +{ + struct device *dev = awi->dev; + struct gpio_irq_chip *girq; + struct irq_chip *irqchip; + int ret; + + if (!device_property_read_bool(dev, "interrupt-controller")) + return 0; + + irqchip = devm_kzalloc(dev, sizeof(*irqchip), GFP_KERNEL); + if (!irqchip) + return -ENOMEM; + + awi->irq = devm_kzalloc(dev, sizeof(*awi->irq), GFP_KERNEL); + if (!awi->irq) + return -ENOMEM; + + awi->irq->irqchip = irqchip; + mutex_init(&awi->irq->lock); + + ret = devm_request_threaded_irq(dev, irq, NULL, aw9523_irq_thread_func, + IRQF_ONESHOT, dev_name(dev), awi); + if (ret) { + dev_err(dev, "Failed to request irq %d\n", irq); + return ret; + } + + girq = &awi->gpio.irq; + gpio_irq_chip_set_chip(girq, &aw9523_irq_chip); + girq->parent_handler = NULL; + girq->num_parents = 0; + girq->parents = NULL; + girq->default_type = IRQ_TYPE_EDGE_BOTH; + girq->handler = handle_simple_irq; + girq->threaded = true; + + return 0; +} + +static bool aw9523_is_reg_hole(unsigned int reg) +{ + return (reg > AW9523_REG_PORT_MODE(AW9523_PINS_PER_PORT) && + reg < AW9523_REG_SOFT_RESET) || + (reg > AW9523_REG_INTR_DIS(AW9523_PINS_PER_PORT) && + reg < AW9523_REG_CHIPID); +} + +static bool aw9523_readable_reg(struct device *dev, unsigned int reg) +{ + /* All available registers (minus holes) can be read */ + return !aw9523_is_reg_hole(reg); +} + +static bool aw9523_volatile_reg(struct device *dev, unsigned int reg) +{ + return aw9523_is_reg_hole(reg) || + reg == AW9523_REG_IN_STATE(0) || + reg == AW9523_REG_IN_STATE(AW9523_PINS_PER_PORT) || + reg == AW9523_REG_CHIPID || + reg == AW9523_REG_SOFT_RESET; +} + +static bool aw9523_writeable_reg(struct device *dev, unsigned int reg) +{ + return !aw9523_is_reg_hole(reg) && reg != AW9523_REG_CHIPID; +} + +static bool aw9523_precious_reg(struct device *dev, unsigned int reg) +{ + /* Reading AW9523_REG_IN_STATE clears interrupt status */ + return aw9523_is_reg_hole(reg) || + reg == AW9523_REG_IN_STATE(0) || + reg == AW9523_REG_IN_STATE(AW9523_PINS_PER_PORT); +} + +static const struct regmap_config aw9523_regmap = { + .reg_bits = 8, + .val_bits = 8, + .reg_stride = 1, + + .precious_reg = aw9523_precious_reg, + .readable_reg = aw9523_readable_reg, + .volatile_reg = aw9523_volatile_reg, + .writeable_reg = aw9523_writeable_reg, + + .cache_type = REGCACHE_FLAT, + .disable_locking = true, + + .num_reg_defaults_raw = AW9523_REG_SOFT_RESET, +}; + +static int aw9523_hw_init(struct aw9523 *awi) +{ + u8 p1_pin = AW9523_PINS_PER_PORT; + unsigned int val; + int ret; + + /* No register caching during initialization */ + regcache_cache_bypass(awi->regmap, true); + + /* Bring up the chip */ + ret = aw9523_hw_reset(awi); + if (ret) { + dev_err(awi->dev, "HW Reset failed: %d\n", ret); + return ret; + } + + /* + * This is the expected chip and it is running: it's time to + * set a safe default configuration in case the user doesn't + * configure (all of the available) pins in this chip. + * P.S.: The writes order doesn't matter. + */ + + /* Set all pins as GPIO */ + ret = regmap_write(awi->regmap, AW9523_REG_PORT_MODE(0), U8_MAX); + if (ret) + return ret; + ret = regmap_write(awi->regmap, AW9523_REG_PORT_MODE(p1_pin), U8_MAX); + if (ret) + return ret; + + /* Set Open-Drain mode on Port 0 (Port 1 is always P-P) */ + ret = regmap_write(awi->regmap, AW9523_REG_GCR, 0); + if (ret) + return ret; + + /* Set all pins as inputs */ + ret = regmap_write(awi->regmap, AW9523_REG_CONF_STATE(0), U8_MAX); + if (ret) + return ret; + ret = regmap_write(awi->regmap, AW9523_REG_CONF_STATE(p1_pin), U8_MAX); + if (ret) + return ret; + + /* Disable all interrupts to avoid unreasoned wakeups */ + ret = regmap_write(awi->regmap, AW9523_REG_INTR_DIS(0), U8_MAX); + if (ret) + return ret; + ret = regmap_write(awi->regmap, AW9523_REG_INTR_DIS(p1_pin), U8_MAX); + if (ret) + return ret; + + /* Clear setup-generated interrupts by performing a port state read */ + ret = aw9523_get_port_state(awi->regmap, 0, 0, &val); + if (ret) + return ret; + ret = aw9523_get_port_state(awi->regmap, p1_pin, 0, &val); + if (ret) + return ret; + + /* Everything went fine: activate and reinitialize register cache */ + regcache_cache_bypass(awi->regmap, false); + return regmap_reinit_cache(awi->regmap, &aw9523_regmap); +} + +static int aw9523_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct pinctrl_desc *pdesc; + struct aw9523 *awi; + int ret; + + awi = devm_kzalloc(dev, sizeof(*awi), GFP_KERNEL); + if (!awi) + return -ENOMEM; + + i2c_set_clientdata(client, awi); + + awi->dev = dev; + awi->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(awi->reset_gpio)) + return PTR_ERR(awi->reset_gpio); + gpiod_set_consumer_name(awi->reset_gpio, "aw9523 reset"); + + awi->regmap = devm_regmap_init_i2c(client, &aw9523_regmap); + if (IS_ERR(awi->regmap)) + return PTR_ERR(awi->regmap); + + awi->vio_vreg = devm_regulator_get_optional(dev, "vio"); + if (IS_ERR(awi->vio_vreg)) { + if (PTR_ERR(awi->vio_vreg) == -EPROBE_DEFER) + return -EPROBE_DEFER; + awi->vio_vreg = NULL; + } else { + ret = regulator_enable(awi->vio_vreg); + if (ret) + return ret; + } + + mutex_init(&awi->i2c_lock); + lockdep_set_subclass(&awi->i2c_lock, + i2c_adapter_depth(client->adapter)); + + pdesc = devm_kzalloc(dev, sizeof(*pdesc), GFP_KERNEL); + if (!pdesc) + return -ENOMEM; + + ret = aw9523_hw_init(awi); + if (ret) + goto err_disable_vregs; + + pdesc->name = dev_name(dev); + pdesc->owner = THIS_MODULE; + pdesc->pctlops = &aw9523_pinctrl_ops; + pdesc->pmxops = &aw9523_pinmux_ops; + pdesc->confops = &aw9523_pinconf_ops; + pdesc->pins = aw9523_pins; + pdesc->npins = ARRAY_SIZE(aw9523_pins); + + ret = aw9523_init_gpiochip(awi, pdesc->npins); + if (ret) + goto err_disable_vregs; + + if (client->irq) { + ret = aw9523_init_irq(awi, client->irq); + if (ret) + goto err_disable_vregs; + } + + awi->pctl = devm_pinctrl_register(dev, pdesc, awi); + if (IS_ERR(awi->pctl)) { + ret = PTR_ERR(awi->pctl); + dev_err(dev, "Cannot register pinctrl: %d", ret); + goto err_disable_vregs; + } + + ret = devm_gpiochip_add_data(dev, &awi->gpio, awi); + if (ret) + goto err_disable_vregs; + + return ret; + +err_disable_vregs: + if (awi->vio_vreg) + regulator_disable(awi->vio_vreg); + mutex_destroy(&awi->i2c_lock); + return ret; +} + +static void aw9523_remove(struct i2c_client *client) +{ + struct aw9523 *awi = i2c_get_clientdata(client); + int ret; + + if (!awi) + return; + + /* + * If the chip VIO is connected to a regulator that we can turn + * off, life is easy... otherwise, reinitialize the chip and + * set the pins to hardware defaults before removing the driver + * to leave it in a clean, safe and predictable state. + */ + if (awi->vio_vreg) { + regulator_disable(awi->vio_vreg); + } else { + mutex_lock(&awi->i2c_lock); + ret = aw9523_hw_init(awi); + mutex_unlock(&awi->i2c_lock); + if (ret) + return; + } + + mutex_destroy(&awi->i2c_lock); +} + +static const struct i2c_device_id aw9523_i2c_id_table[] = { + { "aw9523_i2c", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, aw9523_i2c_id_table); + +static const struct of_device_id of_aw9523_i2c_match[] = { + { .compatible = "awinic,aw9523-pinctrl", }, + { } +}; +MODULE_DEVICE_TABLE(of, of_aw9523_i2c_match); + +static struct i2c_driver aw9523_driver = { + .driver = { + .name = "aw9523-pinctrl", + .of_match_table = of_aw9523_i2c_match, + }, + .probe = aw9523_probe, + .remove = aw9523_remove, + .id_table = aw9523_i2c_id_table, +}; +module_i2c_driver(aw9523_driver); + +MODULE_DESCRIPTION("Awinic AW9523 I2C GPIO Expander driver"); +MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/pinctrl-da9062.c b/drivers/pinctrl/pinctrl-da9062.c index 3998b27cbe0e..22e3cd2cc963 100644 --- a/drivers/pinctrl/pinctrl-da9062.c +++ b/drivers/pinctrl/pinctrl-da9062.c @@ -281,10 +281,17 @@ static int da9062_pctl_probe(struct platform_device *pdev) return devm_gpiochip_add_data(&pdev->dev, &pctl->gc, pctl); } +static const struct of_device_id da9062_compatible_reg_id_table[] = { + { .compatible = "dlg,da9062-gpio" }, + { } +}; +MODULE_DEVICE_TABLE(of, da9062_compatible_reg_id_table); + static struct platform_driver da9062_pctl_driver = { .probe = da9062_pctl_probe, .driver = { .name = "da9062-gpio", + .of_match_table = da9062_compatible_reg_id_table, }, }; module_platform_driver(da9062_pctl_driver); diff --git a/drivers/pinctrl/pinctrl-mcp23s08.c b/drivers/pinctrl/pinctrl-mcp23s08.c index 4551575e4e7d..38c3a14c8b58 100644 --- a/drivers/pinctrl/pinctrl-mcp23s08.c +++ b/drivers/pinctrl/pinctrl-mcp23s08.c @@ -375,7 +375,8 @@ mcp23s08_direction_output(struct gpio_chip *chip, unsigned offset, int value) static irqreturn_t mcp23s08_irq(int irq, void *data) { struct mcp23s08 *mcp = data; - int intcap, intcon, intf, i, gpio, gpio_orig, intcap_mask, defval; + int intcap, intcon, intf, i, gpio, gpio_orig, intcap_mask, defval, gpinten; + unsigned long int enabled_interrupts; unsigned int child_irq; bool intf_set, intcap_changed, gpio_bit_changed, defval_changed, gpio_set; @@ -395,6 +396,9 @@ static irqreturn_t mcp23s08_irq(int irq, void *data) if (mcp_read(mcp, MCP_INTCON, &intcon)) goto unlock; + if (mcp_read(mcp, MCP_GPINTEN, &gpinten)) + goto unlock; + if (mcp_read(mcp, MCP_DEFVAL, &defval)) goto unlock; @@ -410,9 +414,12 @@ static irqreturn_t mcp23s08_irq(int irq, void *data) "intcap 0x%04X intf 0x%04X gpio_orig 0x%04X gpio 0x%04X\n", intcap, intf, gpio_orig, gpio); - for (i = 0; i < mcp->chip.ngpio; i++) { - /* We must check all of the inputs on the chip, - * otherwise we may not notice a change on >=2 pins. + enabled_interrupts = gpinten; + for_each_set_bit(i, &enabled_interrupts, mcp->chip.ngpio) { + /* + * We must check all of the inputs with enabled interrupts + * on the chip, otherwise we may not notice a change + * on more than one pin. * * On at least the mcp23s17, INTCAP is only updated * one byte at a time(INTCAPA and INTCAPB are diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c index 52aadd6d72a8..be9b8c010167 100644 --- a/drivers/pinctrl/pinctrl-ocelot.c +++ b/drivers/pinctrl/pinctrl-ocelot.c @@ -1401,7 +1401,6 @@ static int ocelot_hw_set_value(struct ocelot_pinctrl *info, if (info->pincfg) { const struct ocelot_pincfg_data *opd = info->pincfg_data; - ret = 0; switch (reg) { case PINCONF_BIAS: ret = ocelot_pincfg_clrsetbits(info, pin, diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c index 1485573b523c..5d9abd6547d0 100644 --- a/drivers/pinctrl/pinctrl-st.c +++ b/drivers/pinctrl/pinctrl-st.c @@ -723,9 +723,8 @@ static int st_gpio_direction_output(struct gpio_chip *chip, struct st_gpio_bank *bank = gpiochip_get_data(chip); __st_gpio_set(bank, offset, value); - pinctrl_gpio_direction_output(chip, offset); - return 0; + return pinctrl_gpio_direction_output(chip, offset); } static int st_gpio_get_direction(struct gpio_chip *chip, unsigned offset) diff --git a/drivers/pinctrl/pinctrl-zynqmp.c b/drivers/pinctrl/pinctrl-zynqmp.c index f2be341f73e1..5c46b7d7ebcb 100644 --- a/drivers/pinctrl/pinctrl-zynqmp.c +++ b/drivers/pinctrl/pinctrl-zynqmp.c @@ -562,7 +562,7 @@ static int zynqmp_pinctrl_prepare_func_groups(struct device *dev, u32 fid, const char **fgroups; int ret, index, i; - fgroups = devm_kzalloc(dev, sizeof(*fgroups) * func->ngroups, GFP_KERNEL); + fgroups = devm_kcalloc(dev, func->ngroups, sizeof(*fgroups), GFP_KERNEL); if (!fgroups) return -ENOMEM; @@ -754,7 +754,7 @@ static int zynqmp_pinctrl_prepare_function_info(struct device *dev, if (ret) return ret; - funcs = devm_kzalloc(dev, sizeof(*funcs) * pctrl->nfuncs, GFP_KERNEL); + funcs = devm_kcalloc(dev, pctrl->nfuncs, sizeof(*funcs), GFP_KERNEL); if (!funcs) return -ENOMEM; @@ -768,7 +768,7 @@ static int zynqmp_pinctrl_prepare_function_info(struct device *dev, pctrl->ngroups += funcs[i].ngroups; } - groups = devm_kzalloc(dev, sizeof(*groups) * pctrl->ngroups, GFP_KERNEL); + groups = devm_kcalloc(dev, pctrl->ngroups, sizeof(*groups), GFP_KERNEL); if (!groups) return -ENOMEM; @@ -830,7 +830,7 @@ static int zynqmp_pinctrl_prepare_pin_desc(struct device *dev, if (ret) return ret; - pins = devm_kzalloc(dev, sizeof(*pins) * *npins, GFP_KERNEL); + pins = devm_kcalloc(dev, *npins, sizeof(*pins), GFP_KERNEL); if (!pins) return -ENOMEM; diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index abbb044d6ace..d924207d629b 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -188,8 +188,8 @@ out_free_pin: } out: if (status) - dev_err(pctldev->dev, "pin-%d (%s) status %d\n", - pin, owner, status); + dev_err_probe(pctldev->dev, status, "pin-%d (%s)\n", + pin, owner); return status; } @@ -441,7 +441,7 @@ int pinmux_enable_setting(const struct pinctrl_setting *setting) pname = desc ? desc->name : "non-existing"; gname = pctlops->get_group_name(pctldev, setting->data.mux.group); - dev_err(pctldev->dev, + dev_err_probe(pctldev->dev, ret, "could not request pin %d (%s) from group %s " " on device %s\n", pins[i], pname, gname, diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index e0f2829c15d6..24619e80b2cc 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -125,7 +125,7 @@ config PINCTRL_SM8550_LPASS_LPI platform. config PINCTRL_SM8650_LPASS_LPI - tristate "Qualcomm Technologies Inc SM8550 LPASS LPI pin controller driver" + tristate "Qualcomm Technologies Inc SM8650 LPASS LPI pin controller driver" depends on ARM64 || COMPILE_TEST depends on PINCTRL_LPASS_LPI help diff --git a/drivers/pinctrl/renesas/Kconfig b/drivers/pinctrl/renesas/Kconfig index c8d519ca53eb..14bd55d64731 100644 --- a/drivers/pinctrl/renesas/Kconfig +++ b/drivers/pinctrl/renesas/Kconfig @@ -38,6 +38,7 @@ config PINCTRL_RENESAS select PINCTRL_PFC_R8A779A0 if ARCH_R8A779A0 select PINCTRL_PFC_R8A779F0 if ARCH_R8A779F0 select PINCTRL_PFC_R8A779G0 if ARCH_R8A779G0 + select PINCTRL_PFC_R8A779H0 if ARCH_R8A779H0 select PINCTRL_RZG2L if ARCH_RZG2L select PINCTRL_RZV2M if ARCH_R9A09G011 select PINCTRL_PFC_SH7203 if CPU_SUBTYPE_SH7203 @@ -154,6 +155,10 @@ config PINCTRL_PFC_R8A779G0 bool "pin control support for R-Car V4H" if COMPILE_TEST select PINCTRL_SH_PFC +config PINCTRL_PFC_R8A779H0 + bool "pin control support for R-Car V4M" if COMPILE_TEST + select PINCTRL_SH_PFC + config PINCTRL_PFC_R8A7740 bool "pin control support for R-Mobile A1" if COMPILE_TEST select PINCTRL_SH_PFC_GPIO @@ -187,9 +192,11 @@ config PINCTRL_RZG2L bool "pin control support for RZ/{G2L,G2UL,V2L}" if COMPILE_TEST depends on OF select GPIOLIB + select GPIOLIB_IRQCHIP select GENERIC_PINCTRL_GROUPS select GENERIC_PINMUX_FUNCTIONS select GENERIC_PINCONF + select IRQ_DOMAIN_HIERARCHY help This selects GPIO and pinctrl driver for Renesas RZ/{G2L,G2UL,V2L} platforms. diff --git a/drivers/pinctrl/renesas/Makefile b/drivers/pinctrl/renesas/Makefile index 3e776955bd4b..2ba623e04bf8 100644 --- a/drivers/pinctrl/renesas/Makefile +++ b/drivers/pinctrl/renesas/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_PINCTRL_PFC_R8A77995) += pfc-r8a77995.o obj-$(CONFIG_PINCTRL_PFC_R8A779A0) += pfc-r8a779a0.o obj-$(CONFIG_PINCTRL_PFC_R8A779F0) += pfc-r8a779f0.o obj-$(CONFIG_PINCTRL_PFC_R8A779G0) += pfc-r8a779g0.o +obj-$(CONFIG_PINCTRL_PFC_R8A779H0) += pfc-r8a779h0.o obj-$(CONFIG_PINCTRL_PFC_SH7203) += pfc-sh7203.o obj-$(CONFIG_PINCTRL_PFC_SH7264) += pfc-sh7264.o obj-$(CONFIG_PINCTRL_PFC_SH7269) += pfc-sh7269.o diff --git a/drivers/pinctrl/renesas/core.c b/drivers/pinctrl/renesas/core.c index 93e51abbf519..96d6040a8871 100644 --- a/drivers/pinctrl/renesas/core.c +++ b/drivers/pinctrl/renesas/core.c @@ -638,6 +638,12 @@ static const struct of_device_id sh_pfc_of_table[] = { .data = &r8a779g0_pinmux_info, }, #endif +#ifdef CONFIG_PINCTRL_PFC_R8A779H0 + { + .compatible = "renesas,pfc-r8a779h0", + .data = &r8a779h0_pinmux_info, + }, +#endif #ifdef CONFIG_PINCTRL_PFC_SH73A0 { .compatible = "renesas,pfc-sh73a0", @@ -731,10 +737,12 @@ static int sh_pfc_resume_noirq(struct device *dev) sh_pfc_walk_regs(pfc, sh_pfc_restore_reg); return 0; } +#define pm_psci_sleep_ptr(_ptr) pm_sleep_ptr(_ptr) #else static int sh_pfc_suspend_init(struct sh_pfc *pfc) { return 0; } static int sh_pfc_suspend_noirq(struct device *dev) { return 0; } static int sh_pfc_resume_noirq(struct device *dev) { return 0; } +#define pm_psci_sleep_ptr(_ptr) PTR_IF(false, (_ptr)) #endif /* CONFIG_ARM_PSCI_FW */ static DEFINE_NOIRQ_DEV_PM_OPS(sh_pfc_pm, sh_pfc_suspend_noirq, sh_pfc_resume_noirq); @@ -907,9 +915,11 @@ static void __init sh_pfc_check_cfg_reg(const char *drvname, sh_pfc_err("reg 0x%x: var_field_width declares %u instead of %u bits\n", cfg_reg->reg, rw, cfg_reg->reg_width); - if (n != cfg_reg->nr_enum_ids) + if (n != cfg_reg->nr_enum_ids) { sh_pfc_err("reg 0x%x: enum_ids[] has %u instead of %u values\n", cfg_reg->reg, cfg_reg->nr_enum_ids, n); + n = cfg_reg->nr_enum_ids; + } check_enum_ids: sh_pfc_check_reg_enums(drvname, cfg_reg->reg, cfg_reg->enum_ids, n); @@ -1415,7 +1425,7 @@ static struct platform_driver sh_pfc_driver = { .driver = { .name = DRV_NAME, .of_match_table = of_match_ptr(sh_pfc_of_table), - .pm = pm_sleep_ptr(&sh_pfc_pm), + .pm = pm_psci_sleep_ptr(&sh_pfc_pm), }, }; diff --git a/drivers/pinctrl/renesas/pfc-r8a779g0.c b/drivers/pinctrl/renesas/pfc-r8a779g0.c index acdea6ac1525..d2de526a3b58 100644 --- a/drivers/pinctrl/renesas/pfc-r8a779g0.c +++ b/drivers/pinctrl/renesas/pfc-r8a779g0.c @@ -2384,6 +2384,14 @@ static const unsigned int scif_clk_mux[] = { SCIF_CLK_MARK, }; +static const unsigned int scif_clk2_pins[] = { + /* SCIF_CLK2 */ + RCAR_GP_PIN(8, 11), +}; +static const unsigned int scif_clk2_mux[] = { + SCIF_CLK2_MARK, +}; + /* - SSI ------------------------------------------------- */ static const unsigned int ssi_data_pins[] = { /* SSI_SD */ @@ -2694,6 +2702,7 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(scif4_clk), SH_PFC_PIN_GROUP(scif4_ctrl), SH_PFC_PIN_GROUP(scif_clk), + SH_PFC_PIN_GROUP(scif_clk2), SH_PFC_PIN_GROUP(ssi_data), SH_PFC_PIN_GROUP(ssi_ctrl), @@ -3015,6 +3024,10 @@ static const char * const scif_clk_groups[] = { "scif_clk", }; +static const char * const scif_clk2_groups[] = { + "scif_clk2", +}; + static const char * const ssi_groups[] = { "ssi_data", "ssi_ctrl", @@ -3102,6 +3115,7 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(scif3), SH_PFC_FUNCTION(scif4), SH_PFC_FUNCTION(scif_clk), + SH_PFC_FUNCTION(scif_clk2), SH_PFC_FUNCTION(ssi), diff --git a/drivers/pinctrl/renesas/pfc-r8a779h0.c b/drivers/pinctrl/renesas/pfc-r8a779h0.c new file mode 100644 index 000000000000..afa8f06c85cf --- /dev/null +++ b/drivers/pinctrl/renesas/pfc-r8a779h0.c @@ -0,0 +1,3967 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * R8A779H0 processor support - PFC hardware block. + * + * Copyright (C) 2023 Renesas Electronics Corp. + * + * This file is based on the drivers/pinctrl/renesas/pfc-r8a779a0.c + */ + +#include <linux/errno.h> +#include <linux/io.h> +#include <linux/kernel.h> + +#include "sh_pfc.h" + +#define CFG_FLAGS (SH_PFC_PIN_CFG_DRIVE_STRENGTH | SH_PFC_PIN_CFG_PULL_UP_DOWN) + +#define CPU_ALL_GP(fn, sfx) \ + PORT_GP_CFG_19(0, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_29(1, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(1, 29, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_16(2, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(2, 17, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(2, 19, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_13(3, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(3, 13, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(3, 14, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(3, 15, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(3, 16, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(3, 17, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(3, 18, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(3, 19, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(3, 20, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(3, 21, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(3, 22, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(3, 23, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(3, 24, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(3, 25, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(3, 26, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(3, 27, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(3, 28, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(3, 29, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(3, 30, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(3, 31, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_14(4, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(4, 14, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(4, 15, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(4, 21, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(4, 23, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(4, 24, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_21(5, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_21(6, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_21(7, fn, sfx, CFG_FLAGS) + +#define CPU_ALL_NOGP(fn) \ + PIN_NOGP_CFG(VDDQ_AVB0, "VDDQ_AVB0", fn, SH_PFC_PIN_CFG_IO_VOLTAGE_18_25), \ + PIN_NOGP_CFG(VDDQ_AVB1, "VDDQ_AVB1", fn, SH_PFC_PIN_CFG_IO_VOLTAGE_18_25), \ + PIN_NOGP_CFG(VDDQ_AVB2, "VDDQ_AVB2", fn, SH_PFC_PIN_CFG_IO_VOLTAGE_18_25) + +/* + * F_() : just information + * FM() : macro for FN_xxx / xxx_MARK + */ + +/* GPSR0 */ +#define GPSR0_18 F_(MSIOF2_RXD, IP2SR0_11_8) +#define GPSR0_17 F_(MSIOF2_SCK, IP2SR0_7_4) +#define GPSR0_16 F_(MSIOF2_TXD, IP2SR0_3_0) +#define GPSR0_15 F_(MSIOF2_SYNC, IP1SR0_31_28) +#define GPSR0_14 F_(MSIOF2_SS1, IP1SR0_27_24) +#define GPSR0_13 F_(MSIOF2_SS2, IP1SR0_23_20) +#define GPSR0_12 F_(MSIOF5_RXD, IP1SR0_19_16) +#define GPSR0_11 F_(MSIOF5_SCK, IP1SR0_15_12) +#define GPSR0_10 F_(MSIOF5_TXD, IP1SR0_11_8) +#define GPSR0_9 F_(MSIOF5_SYNC, IP1SR0_7_4) +#define GPSR0_8 F_(MSIOF5_SS1, IP1SR0_3_0) +#define GPSR0_7 F_(MSIOF5_SS2, IP0SR0_31_28) +#define GPSR0_6 F_(IRQ0, IP0SR0_27_24) +#define GPSR0_5 F_(IRQ1, IP0SR0_23_20) +#define GPSR0_4 F_(IRQ2, IP0SR0_19_16) +#define GPSR0_3 F_(IRQ3, IP0SR0_15_12) +#define GPSR0_2 F_(GP0_02, IP0SR0_11_8) +#define GPSR0_1 F_(GP0_01, IP0SR0_7_4) +#define GPSR0_0 F_(GP0_00, IP0SR0_3_0) + +/* GPSR1 */ +#define GPSR1_29 F_(ERROROUTC_N_A, IP3SR1_23_20) +#define GPSR1_28 F_(HTX3, IP3SR1_19_16) +#define GPSR1_27 F_(HCTS3_N, IP3SR1_15_12) +#define GPSR1_26 F_(HRTS3_N, IP3SR1_11_8) +#define GPSR1_25 F_(HSCK3, IP3SR1_7_4) +#define GPSR1_24 F_(HRX3, IP3SR1_3_0) +#define GPSR1_23 F_(GP1_23, IP2SR1_31_28) +#define GPSR1_22 F_(AUDIO_CLKIN, IP2SR1_27_24) +#define GPSR1_21 F_(AUDIO_CLKOUT, IP2SR1_23_20) +#define GPSR1_20 F_(SSI_SD, IP2SR1_19_16) +#define GPSR1_19 F_(SSI_WS, IP2SR1_15_12) +#define GPSR1_18 F_(SSI_SCK, IP2SR1_11_8) +#define GPSR1_17 F_(SCIF_CLK, IP2SR1_7_4) +#define GPSR1_16 F_(HRX0, IP2SR1_3_0) +#define GPSR1_15 F_(HSCK0, IP1SR1_31_28) +#define GPSR1_14 F_(HRTS0_N, IP1SR1_27_24) +#define GPSR1_13 F_(HCTS0_N, IP1SR1_23_20) +#define GPSR1_12 F_(HTX0, IP1SR1_19_16) +#define GPSR1_11 F_(MSIOF0_RXD, IP1SR1_15_12) +#define GPSR1_10 F_(MSIOF0_SCK, IP1SR1_11_8) +#define GPSR1_9 F_(MSIOF0_TXD, IP1SR1_7_4) +#define GPSR1_8 F_(MSIOF0_SYNC, IP1SR1_3_0) +#define GPSR1_7 F_(MSIOF0_SS1, IP0SR1_31_28) +#define GPSR1_6 F_(MSIOF0_SS2, IP0SR1_27_24) +#define GPSR1_5 F_(MSIOF1_RXD, IP0SR1_23_20) +#define GPSR1_4 F_(MSIOF1_TXD, IP0SR1_19_16) +#define GPSR1_3 F_(MSIOF1_SCK, IP0SR1_15_12) +#define GPSR1_2 F_(MSIOF1_SYNC, IP0SR1_11_8) +#define GPSR1_1 F_(MSIOF1_SS1, IP0SR1_7_4) +#define GPSR1_0 F_(MSIOF1_SS2, IP0SR1_3_0) + +/* GPSR2 */ +#define GPSR2_19 F_(CANFD1_RX, IP2SR2_15_12) +#define GPSR2_17 F_(CANFD1_TX, IP2SR2_7_4) +#define GPSR2_15 F_(CANFD3_RX, IP1SR2_31_28) +#define GPSR2_14 F_(CANFD3_TX, IP1SR2_27_24) +#define GPSR2_13 F_(CANFD2_RX, IP1SR2_23_20) +#define GPSR2_12 F_(CANFD2_TX, IP1SR2_19_16) +#define GPSR2_11 F_(CANFD0_RX, IP1SR2_15_12) +#define GPSR2_10 F_(CANFD0_TX, IP1SR2_11_8) +#define GPSR2_9 F_(CAN_CLK, IP1SR2_7_4) +#define GPSR2_8 F_(TPU0TO0, IP1SR2_3_0) +#define GPSR2_7 F_(TPU0TO1, IP0SR2_31_28) +#define GPSR2_6 F_(FXR_TXDB, IP0SR2_27_24) +#define GPSR2_5 F_(FXR_TXENB_N_A, IP0SR2_23_20) +#define GPSR2_4 F_(RXDB_EXTFXR, IP0SR2_19_16) +#define GPSR2_3 F_(CLK_EXTFXR, IP0SR2_15_12) +#define GPSR2_2 F_(RXDA_EXTFXR, IP0SR2_11_8) +#define GPSR2_1 F_(FXR_TXENA_N_A, IP0SR2_7_4) +#define GPSR2_0 F_(FXR_TXDA, IP0SR2_3_0) + +/* GPSR3 */ +#define GPSR3_31 F_(TCLK4, IP3SR3_31_28) +#define GPSR3_30 F_(TCLK3, IP3SR3_27_24) +#define GPSR3_29 F_(RPC_INT_N, IP3SR3_23_20) +#define GPSR3_28 F_(RPC_WP_N, IP3SR3_19_16) +#define GPSR3_27 F_(RPC_RESET_N, IP3SR3_15_12) +#define GPSR3_26 F_(QSPI1_IO3, IP3SR3_11_8) +#define GPSR3_25 F_(QSPI1_SSL, IP3SR3_7_4) +#define GPSR3_24 F_(QSPI1_IO2, IP3SR3_3_0) +#define GPSR3_23 F_(QSPI1_MISO_IO1, IP2SR3_31_28) +#define GPSR3_22 F_(QSPI1_SPCLK, IP2SR3_27_24) +#define GPSR3_21 F_(QSPI1_MOSI_IO0, IP2SR3_23_20) +#define GPSR3_20 F_(QSPI0_SPCLK, IP2SR3_19_16) +#define GPSR3_19 F_(QSPI0_MOSI_IO0, IP2SR3_15_12) +#define GPSR3_18 F_(QSPI0_MISO_IO1, IP2SR3_11_8) +#define GPSR3_17 F_(QSPI0_IO2, IP2SR3_7_4) +#define GPSR3_16 F_(QSPI0_IO3, IP2SR3_3_0) +#define GPSR3_15 F_(QSPI0_SSL, IP1SR3_31_28) +#define GPSR3_14 F_(PWM2, IP1SR3_27_24) +#define GPSR3_13 F_(PWM1, IP1SR3_23_20) +#define GPSR3_12 F_(SD_WP, IP1SR3_19_16) +#define GPSR3_11 F_(SD_CD, IP1SR3_15_12) +#define GPSR3_10 F_(MMC_SD_CMD, IP1SR3_11_8) +#define GPSR3_9 F_(MMC_D6, IP1SR3_7_4) +#define GPSR3_8 F_(MMC_D7, IP1SR3_3_0) +#define GPSR3_7 F_(MMC_D4, IP0SR3_31_28) +#define GPSR3_6 F_(MMC_D5, IP0SR3_27_24) +#define GPSR3_5 F_(MMC_SD_D3, IP0SR3_23_20) +#define GPSR3_4 F_(MMC_DS, IP0SR3_19_16) +#define GPSR3_3 F_(MMC_SD_CLK, IP0SR3_15_12) +#define GPSR3_2 F_(MMC_SD_D2, IP0SR3_11_8) +#define GPSR3_1 F_(MMC_SD_D0, IP0SR3_7_4) +#define GPSR3_0 F_(MMC_SD_D1, IP0SR3_3_0) + +/* GPSR4 */ +#define GPSR4_24 F_(AVS1, IP3SR4_3_0) +#define GPSR4_23 F_(AVS0, IP2SR4_31_28) +#define GPSR4_21 F_(PCIE0_CLKREQ_N, IP2SR4_23_20) +#define GPSR4_15 F_(PWM4, IP1SR4_31_28) +#define GPSR4_14 F_(PWM3, IP1SR4_27_24) +#define GPSR4_13 F_(HSCK2, IP1SR4_23_20) +#define GPSR4_12 F_(HCTS2_N, IP1SR4_19_16) +#define GPSR4_11 F_(SCIF_CLK2, IP1SR4_15_12) +#define GPSR4_10 F_(HRTS2_N, IP1SR4_11_8) +#define GPSR4_9 F_(HTX2, IP1SR4_7_4) +#define GPSR4_8 F_(HRX2, IP1SR4_3_0) +#define GPSR4_7 F_(SDA3, IP0SR4_31_28) +#define GPSR4_6 F_(SCL3, IP0SR4_27_24) +#define GPSR4_5 F_(SDA2, IP0SR4_23_20) +#define GPSR4_4 F_(SCL2, IP0SR4_19_16) +#define GPSR4_3 F_(SDA1, IP0SR4_15_12) +#define GPSR4_2 F_(SCL1, IP0SR4_11_8) +#define GPSR4_1 F_(SDA0, IP0SR4_7_4) +#define GPSR4_0 F_(SCL0, IP0SR4_3_0) + +/* GPSR 5 */ +#define GPSR5_20 F_(AVB2_RX_CTL, IP2SR5_19_16) +#define GPSR5_19 F_(AVB2_TX_CTL, IP2SR5_15_12) +#define GPSR5_18 F_(AVB2_RXC, IP2SR5_11_8) +#define GPSR5_17 F_(AVB2_RD0, IP2SR5_7_4) +#define GPSR5_16 F_(AVB2_TXC, IP2SR5_3_0) +#define GPSR5_15 F_(AVB2_TD0, IP1SR5_31_28) +#define GPSR5_14 F_(AVB2_RD1, IP1SR5_27_24) +#define GPSR5_13 F_(AVB2_RD2, IP1SR5_23_20) +#define GPSR5_12 F_(AVB2_TD1, IP1SR5_19_16) +#define GPSR5_11 F_(AVB2_TD2, IP1SR5_15_12) +#define GPSR5_10 F_(AVB2_MDIO, IP1SR5_11_8) +#define GPSR5_9 F_(AVB2_RD3, IP1SR5_7_4) +#define GPSR5_8 F_(AVB2_TD3, IP1SR5_3_0) +#define GPSR5_7 F_(AVB2_TXCREFCLK, IP0SR5_31_28) +#define GPSR5_6 F_(AVB2_MDC, IP0SR5_27_24) +#define GPSR5_5 F_(AVB2_MAGIC, IP0SR5_23_20) +#define GPSR5_4 F_(AVB2_PHY_INT, IP0SR5_19_16) +#define GPSR5_3 F_(AVB2_LINK, IP0SR5_15_12) +#define GPSR5_2 F_(AVB2_AVTP_MATCH, IP0SR5_11_8) +#define GPSR5_1 F_(AVB2_AVTP_CAPTURE, IP0SR5_7_4) +#define GPSR5_0 F_(AVB2_AVTP_PPS, IP0SR5_3_0) + +/* GPSR 6 */ +#define GPSR6_20 F_(AVB1_TXCREFCLK, IP2SR6_19_16) +#define GPSR6_19 F_(AVB1_RD3, IP2SR6_15_12) +#define GPSR6_18 F_(AVB1_TD3, IP2SR6_11_8) +#define GPSR6_17 F_(AVB1_RD2, IP2SR6_7_4) +#define GPSR6_16 F_(AVB1_TD2, IP2SR6_3_0) +#define GPSR6_15 F_(AVB1_RD0, IP1SR6_31_28) +#define GPSR6_14 F_(AVB1_RD1, IP1SR6_27_24) +#define GPSR6_13 F_(AVB1_TD0, IP1SR6_23_20) +#define GPSR6_12 F_(AVB1_TD1, IP1SR6_19_16) +#define GPSR6_11 F_(AVB1_AVTP_CAPTURE, IP1SR6_15_12) +#define GPSR6_10 F_(AVB1_AVTP_PPS, IP1SR6_11_8) +#define GPSR6_9 F_(AVB1_RX_CTL, IP1SR6_7_4) +#define GPSR6_8 F_(AVB1_RXC, IP1SR6_3_0) +#define GPSR6_7 F_(AVB1_TX_CTL, IP0SR6_31_28) +#define GPSR6_6 F_(AVB1_TXC, IP0SR6_27_24) +#define GPSR6_5 F_(AVB1_AVTP_MATCH, IP0SR6_23_20) +#define GPSR6_4 F_(AVB1_LINK, IP0SR6_19_16) +#define GPSR6_3 F_(AVB1_PHY_INT, IP0SR6_15_12) +#define GPSR6_2 F_(AVB1_MDC, IP0SR6_11_8) +#define GPSR6_1 F_(AVB1_MAGIC, IP0SR6_7_4) +#define GPSR6_0 F_(AVB1_MDIO, IP0SR6_3_0) + +/* GPSR7 */ +#define GPSR7_20 F_(AVB0_RX_CTL, IP2SR7_19_16) +#define GPSR7_19 F_(AVB0_RXC, IP2SR7_15_12) +#define GPSR7_18 F_(AVB0_RD0, IP2SR7_11_8) +#define GPSR7_17 F_(AVB0_RD1, IP2SR7_7_4) +#define GPSR7_16 F_(AVB0_TX_CTL, IP2SR7_3_0) +#define GPSR7_15 F_(AVB0_TXC, IP1SR7_31_28) +#define GPSR7_14 F_(AVB0_MDIO, IP1SR7_27_24) +#define GPSR7_13 F_(AVB0_MDC, IP1SR7_23_20) +#define GPSR7_12 F_(AVB0_RD2, IP1SR7_19_16) +#define GPSR7_11 F_(AVB0_TD0, IP1SR7_15_12) +#define GPSR7_10 F_(AVB0_MAGIC, IP1SR7_11_8) +#define GPSR7_9 F_(AVB0_TXCREFCLK, IP1SR7_7_4) +#define GPSR7_8 F_(AVB0_RD3, IP1SR7_3_0) +#define GPSR7_7 F_(AVB0_TD1, IP0SR7_31_28) +#define GPSR7_6 F_(AVB0_TD2, IP0SR7_27_24) +#define GPSR7_5 F_(AVB0_PHY_INT, IP0SR7_23_20) +#define GPSR7_4 F_(AVB0_LINK, IP0SR7_19_16) +#define GPSR7_3 F_(AVB0_TD3, IP0SR7_15_12) +#define GPSR7_2 F_(AVB0_AVTP_MATCH, IP0SR7_11_8) +#define GPSR7_1 F_(AVB0_AVTP_CAPTURE, IP0SR7_7_4) +#define GPSR7_0 F_(AVB0_AVTP_PPS, IP0SR7_3_0) + + +/* SR0 */ +/* IP0SR0 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP0SR0_3_0 F_(0, 0) FM(ERROROUTC_N_B) FM(TCLK2_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR0_7_4 F_(0, 0) FM(MSIOF3_SS1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR0_11_8 F_(0, 0) FM(MSIOF3_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR0_15_12 FM(IRQ3) FM(MSIOF3_SCK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR0_19_16 FM(IRQ2) FM(MSIOF3_TXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR0_23_20 FM(IRQ1) FM(MSIOF3_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR0_27_24 FM(IRQ0) FM(MSIOF3_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR0_31_28 FM(MSIOF5_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* IP1SR0 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP1SR0_3_0 FM(MSIOF5_SS1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR0_7_4 FM(MSIOF5_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR0_11_8 FM(MSIOF5_TXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR0_15_12 FM(MSIOF5_SCK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR0_19_16 FM(MSIOF5_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR0_23_20 FM(MSIOF2_SS2) FM(TCLK1_A) FM(IRQ2_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR0_27_24 FM(MSIOF2_SS1) FM(HTX1_A) FM(TX1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR0_31_28 FM(MSIOF2_SYNC) FM(HRX1_A) FM(RX1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* IP2SR0 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP2SR0_3_0 FM(MSIOF2_TXD) FM(HCTS1_N_A) FM(CTS1_N_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR0_7_4 FM(MSIOF2_SCK) FM(HRTS1_N_A) FM(RTS1_N_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR0_11_8 FM(MSIOF2_RXD) FM(HSCK1_A) FM(SCK1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* SR1 */ +/* IP0SR1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP0SR1_3_0 FM(MSIOF1_SS2) FM(HTX3_B) FM(TX3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR1_7_4 FM(MSIOF1_SS1) FM(HCTS3_N_B) FM(RX3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR1_11_8 FM(MSIOF1_SYNC) FM(HRTS3_N_B) FM(RTS3_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR1_15_12 FM(MSIOF1_SCK) FM(HSCK3_B) FM(CTS3_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR1_19_16 FM(MSIOF1_TXD) FM(HRX3_B) FM(SCK3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR1_23_20 FM(MSIOF1_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR1_27_24 FM(MSIOF0_SS2) FM(HTX1_B) FM(TX1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR1_31_28 FM(MSIOF0_SS1) FM(HRX1_B) FM(RX1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* IP1SR1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP1SR1_3_0 FM(MSIOF0_SYNC) FM(HCTS1_N_B) FM(CTS1_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR1_7_4 FM(MSIOF0_TXD) FM(HRTS1_N_B) FM(RTS1_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR1_11_8 FM(MSIOF0_SCK) FM(HSCK1_B) FM(SCK1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR1_15_12 FM(MSIOF0_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR1_19_16 FM(HTX0) FM(TX0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR1_23_20 FM(HCTS0_N) FM(CTS0_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR1_27_24 FM(HRTS0_N) FM(RTS0_N) FM(PWM0_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR1_31_28 FM(HSCK0) FM(SCK0) FM(PWM0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* IP2SR1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP2SR1_3_0 FM(HRX0) FM(RX0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR1_7_4 FM(SCIF_CLK) FM(IRQ4_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR1_11_8 FM(SSI_SCK) FM(TCLK3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR1_15_12 FM(SSI_WS) FM(TCLK4_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR1_19_16 FM(SSI_SD) FM(IRQ0_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR1_23_20 FM(AUDIO_CLKOUT) FM(IRQ1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR1_27_24 FM(AUDIO_CLKIN) FM(PWM3_C) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR1_31_28 F_(0, 0) FM(TCLK2_A) FM(MSIOF4_SS1) FM(IRQ3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* IP3SR1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP3SR1_3_0 FM(HRX3_A) FM(SCK3_A) FM(MSIOF4_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP3SR1_7_4 FM(HSCK3_A) FM(CTS3_N_A) FM(MSIOF4_SCK) FM(TPU0TO0_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP3SR1_11_8 FM(HRTS3_N_A) FM(RTS3_N_A) FM(MSIOF4_TXD) FM(TPU0TO1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP3SR1_15_12 FM(HCTS3_N_A) FM(RX3_A) FM(MSIOF4_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP3SR1_19_16 FM(HTX3_A) FM(TX3_A) FM(MSIOF4_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP3SR1_23_20 FM(ERROROUTC_N_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* SR2 */ +/* IP0SR2 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP0SR2_3_0 FM(FXR_TXDA) F_(0, 0) FM(TPU0TO2_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR2_7_4 FM(FXR_TXENA_N_A) F_(0, 0) FM(TPU0TO3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR2_11_8 FM(RXDA_EXTFXR) F_(0, 0) FM(IRQ5) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR2_15_12 FM(CLK_EXTFXR) F_(0, 0) FM(IRQ4_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR2_19_16 FM(RXDB_EXTFXR) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR2_23_20 FM(FXR_TXENB_N_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR2_27_24 FM(FXR_TXDB) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR2_31_28 FM(TPU0TO1_A) F_(0, 0) F_(0, 0) FM(TCLK2_C) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* IP1SR2 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP1SR2_3_0 FM(TPU0TO0_A) F_(0, 0) F_(0, 0) FM(TCLK1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR2_7_4 FM(CAN_CLK) FM(FXR_TXENA_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR2_11_8 FM(CANFD0_TX) FM(FXR_TXENB_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR2_15_12 FM(CANFD0_RX) FM(STPWT_EXTFXR) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR2_19_16 FM(CANFD2_TX) FM(TPU0TO2_A) F_(0, 0) FM(TCLK3_C) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR2_23_20 FM(CANFD2_RX) FM(TPU0TO3_A) FM(PWM1_B) FM(TCLK4_C) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR2_27_24 FM(CANFD3_TX) F_(0, 0) FM(PWM2_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR2_31_28 FM(CANFD3_RX) F_(0, 0) FM(PWM3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* IP2SR2 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP2SR2_7_4 FM(CANFD1_TX) F_(0, 0) FM(PWM1_C) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR2_15_12 FM(CANFD1_RX) F_(0, 0) FM(PWM2_C) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* SR3 */ +/* IP0SR3 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP0SR3_3_0 FM(MMC_SD_D1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR3_7_4 FM(MMC_SD_D0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR3_11_8 FM(MMC_SD_D2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR3_15_12 FM(MMC_SD_CLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR3_19_16 FM(MMC_DS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR3_23_20 FM(MMC_SD_D3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR3_27_24 FM(MMC_D5) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR3_31_28 FM(MMC_D4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* IP1SR3 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP1SR3_3_0 FM(MMC_D7) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR3_7_4 FM(MMC_D6) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR3_11_8 FM(MMC_SD_CMD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR3_15_12 FM(SD_CD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR3_19_16 FM(SD_WP) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR3_23_20 FM(PWM1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR3_27_24 FM(PWM2_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR3_31_28 FM(QSPI0_SSL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* IP2SR3 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP2SR3_3_0 FM(QSPI0_IO3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR3_7_4 FM(QSPI0_IO2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR3_11_8 FM(QSPI0_MISO_IO1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR3_15_12 FM(QSPI0_MOSI_IO0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR3_19_16 FM(QSPI0_SPCLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR3_23_20 FM(QSPI1_MOSI_IO0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR3_27_24 FM(QSPI1_SPCLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR3_31_28 FM(QSPI1_MISO_IO1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* IP3SR3 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP3SR3_3_0 FM(QSPI1_IO2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP3SR3_7_4 FM(QSPI1_SSL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP3SR3_11_8 FM(QSPI1_IO3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP3SR3_15_12 FM(RPC_RESET_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP3SR3_19_16 FM(RPC_WP_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP3SR3_23_20 FM(RPC_INT_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP3SR3_27_24 FM(TCLK3_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP3SR3_31_28 FM(TCLK4_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* SR4 */ +/* IP0SR4 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP0SR4_3_0 FM(SCL0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR4_7_4 FM(SDA0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR4_11_8 FM(SCL1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR4_15_12 FM(SDA1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR4_19_16 FM(SCL2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR4_23_20 FM(SDA2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR4_27_24 FM(SCL3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR4_31_28 FM(SDA3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* IP1SR4 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP1SR4_3_0 FM(HRX2) FM(SCK4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR4_7_4 FM(HTX2) FM(CTS4_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR4_11_8 FM(HRTS2_N) FM(RTS4_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR4_15_12 FM(SCIF_CLK2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR4_19_16 FM(HCTS2_N) FM(TX4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR4_23_20 FM(HSCK2) FM(RX4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR4_27_24 FM(PWM3_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR4_31_28 FM(PWM4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* IP2SR4 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP2SR4_23_20 FM(PCIE0_CLKREQ_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR4_31_28 FM(AVS0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* IP3SR4 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP3SR4_3_0 FM(AVS1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* SR5 */ +/* IP0SR5 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP0SR5_3_0 FM(AVB2_AVTP_PPS) FM(Ether_GPTP_PPS0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR5_7_4 FM(AVB2_AVTP_CAPTURE) FM(Ether_GPTP_CAPTURE) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR5_11_8 FM(AVB2_AVTP_MATCH) FM(Ether_GPTP_MATCH) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR5_15_12 FM(AVB2_LINK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR5_19_16 FM(AVB2_PHY_INT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR5_23_20 FM(AVB2_MAGIC) FM(Ether_GPTP_PPS1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR5_27_24 FM(AVB2_MDC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR5_31_28 FM(AVB2_TXCREFCLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* IP1SR5 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP1SR5_3_0 FM(AVB2_TD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR5_7_4 FM(AVB2_RD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR5_11_8 FM(AVB2_MDIO) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR5_15_12 FM(AVB2_TD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR5_19_16 FM(AVB2_TD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR5_23_20 FM(AVB2_RD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR5_27_24 FM(AVB2_RD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR5_31_28 FM(AVB2_TD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* IP2SR5 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP2SR5_3_0 FM(AVB2_TXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR5_7_4 FM(AVB2_RD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR5_11_8 FM(AVB2_RXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR5_15_12 FM(AVB2_TX_CTL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR5_19_16 FM(AVB2_RX_CTL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* SR6 */ +/* IP0SR6 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP0SR6_3_0 FM(AVB1_MDIO) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR6_7_4 FM(AVB1_MAGIC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR6_11_8 FM(AVB1_MDC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR6_15_12 FM(AVB1_PHY_INT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR6_19_16 FM(AVB1_LINK) FM(AVB1_MII_TX_ER) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR6_23_20 FM(AVB1_AVTP_MATCH) FM(AVB1_MII_RX_ER) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR6_27_24 FM(AVB1_TXC) FM(AVB1_MII_TXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR6_31_28 FM(AVB1_TX_CTL) FM(AVB1_MII_TX_EN) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* IP1SR6 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP1SR6_3_0 FM(AVB1_RXC) FM(AVB1_MII_RXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR6_7_4 FM(AVB1_RX_CTL) FM(AVB1_MII_RX_DV) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR6_11_8 FM(AVB1_AVTP_PPS) FM(AVB1_MII_COL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR6_15_12 FM(AVB1_AVTP_CAPTURE) FM(AVB1_MII_CRS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR6_19_16 FM(AVB1_TD1) FM(AVB1_MII_TD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR6_23_20 FM(AVB1_TD0) FM(AVB1_MII_TD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR6_27_24 FM(AVB1_RD1) FM(AVB1_MII_RD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR6_31_28 FM(AVB1_RD0) FM(AVB1_MII_RD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* IP2SR6 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP2SR6_3_0 FM(AVB1_TD2) FM(AVB1_MII_TD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR6_7_4 FM(AVB1_RD2) FM(AVB1_MII_RD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR6_11_8 FM(AVB1_TD3) FM(AVB1_MII_TD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR6_15_12 FM(AVB1_RD3) FM(AVB1_MII_RD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR6_19_16 FM(AVB1_TXCREFCLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* SR7 */ +/* IP0SR7 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP0SR7_3_0 FM(AVB0_AVTP_PPS) FM(AVB0_MII_COL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR7_7_4 FM(AVB0_AVTP_CAPTURE) FM(AVB0_MII_CRS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR7_11_8 FM(AVB0_AVTP_MATCH) FM(AVB0_MII_RX_ER) FM(CC5_OSCOUT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR7_15_12 FM(AVB0_TD3) FM(AVB0_MII_TD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR7_19_16 FM(AVB0_LINK) FM(AVB0_MII_TX_ER) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR7_23_20 FM(AVB0_PHY_INT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR7_27_24 FM(AVB0_TD2) FM(AVB0_MII_TD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR7_31_28 FM(AVB0_TD1) FM(AVB0_MII_TD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* IP1SR7 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP1SR7_3_0 FM(AVB0_RD3) FM(AVB0_MII_RD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR7_7_4 FM(AVB0_TXCREFCLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR7_11_8 FM(AVB0_MAGIC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR7_15_12 FM(AVB0_TD0) FM(AVB0_MII_TD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR7_19_16 FM(AVB0_RD2) FM(AVB0_MII_RD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR7_23_20 FM(AVB0_MDC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR7_27_24 FM(AVB0_MDIO) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR7_31_28 FM(AVB0_TXC) FM(AVB0_MII_TXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +/* IP2SR7 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +#define IP2SR7_3_0 FM(AVB0_TX_CTL) FM(AVB0_MII_TX_EN) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR7_7_4 FM(AVB0_RD1) FM(AVB0_MII_RD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR7_11_8 FM(AVB0_RD0) FM(AVB0_MII_RD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR7_15_12 FM(AVB0_RXC) FM(AVB0_MII_RXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR7_19_16 FM(AVB0_RX_CTL) FM(AVB0_MII_RX_DV) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + +#define PINMUX_GPSR \ + GPSR3_31 \ + GPSR3_30 \ + GPSR1_29 GPSR3_29 \ + GPSR1_28 GPSR3_28 \ + GPSR1_27 GPSR3_27 \ + GPSR1_26 GPSR3_26 \ + GPSR1_25 GPSR3_25 \ + GPSR1_24 GPSR3_24 GPSR4_24 \ + GPSR1_23 GPSR3_23 GPSR4_23 \ + GPSR1_22 GPSR3_22 \ + GPSR1_21 GPSR3_21 GPSR4_21 \ + GPSR1_20 GPSR3_20 GPSR5_20 GPSR6_20 GPSR7_20 \ + GPSR1_19 GPSR2_19 GPSR3_19 GPSR5_19 GPSR6_19 GPSR7_19 \ +GPSR0_18 GPSR1_18 GPSR3_18 GPSR5_18 GPSR6_18 GPSR7_18 \ +GPSR0_17 GPSR1_17 GPSR2_17 GPSR3_17 GPSR5_17 GPSR6_17 GPSR7_17 \ +GPSR0_16 GPSR1_16 GPSR3_16 GPSR5_16 GPSR6_16 GPSR7_16 \ +GPSR0_15 GPSR1_15 GPSR2_15 GPSR3_15 GPSR4_15 GPSR5_15 GPSR6_15 GPSR7_15 \ +GPSR0_14 GPSR1_14 GPSR2_14 GPSR3_14 GPSR4_14 GPSR5_14 GPSR6_14 GPSR7_14 \ +GPSR0_13 GPSR1_13 GPSR2_13 GPSR3_13 GPSR4_13 GPSR5_13 GPSR6_13 GPSR7_13 \ +GPSR0_12 GPSR1_12 GPSR2_12 GPSR3_12 GPSR4_12 GPSR5_12 GPSR6_12 GPSR7_12 \ +GPSR0_11 GPSR1_11 GPSR2_11 GPSR3_11 GPSR4_11 GPSR5_11 GPSR6_11 GPSR7_11 \ +GPSR0_10 GPSR1_10 GPSR2_10 GPSR3_10 GPSR4_10 GPSR5_10 GPSR6_10 GPSR7_10 \ +GPSR0_9 GPSR1_9 GPSR2_9 GPSR3_9 GPSR4_9 GPSR5_9 GPSR6_9 GPSR7_9 \ +GPSR0_8 GPSR1_8 GPSR2_8 GPSR3_8 GPSR4_8 GPSR5_8 GPSR6_8 GPSR7_8 \ +GPSR0_7 GPSR1_7 GPSR2_7 GPSR3_7 GPSR4_7 GPSR5_7 GPSR6_7 GPSR7_7 \ +GPSR0_6 GPSR1_6 GPSR2_6 GPSR3_6 GPSR4_6 GPSR5_6 GPSR6_6 GPSR7_6 \ +GPSR0_5 GPSR1_5 GPSR2_5 GPSR3_5 GPSR4_5 GPSR5_5 GPSR6_5 GPSR7_5 \ +GPSR0_4 GPSR1_4 GPSR2_4 GPSR3_4 GPSR4_4 GPSR5_4 GPSR6_4 GPSR7_4 \ +GPSR0_3 GPSR1_3 GPSR2_3 GPSR3_3 GPSR4_3 GPSR5_3 GPSR6_3 GPSR7_3 \ +GPSR0_2 GPSR1_2 GPSR2_2 GPSR3_2 GPSR4_2 GPSR5_2 GPSR6_2 GPSR7_2 \ +GPSR0_1 GPSR1_1 GPSR2_1 GPSR3_1 GPSR4_1 GPSR5_1 GPSR6_1 GPSR7_1 \ +GPSR0_0 GPSR1_0 GPSR2_0 GPSR3_0 GPSR4_0 GPSR5_0 GPSR6_0 GPSR7_0 + +#define PINMUX_IPSR \ +\ +FM(IP0SR0_3_0) IP0SR0_3_0 FM(IP1SR0_3_0) IP1SR0_3_0 FM(IP2SR0_3_0) IP2SR0_3_0 \ +FM(IP0SR0_7_4) IP0SR0_7_4 FM(IP1SR0_7_4) IP1SR0_7_4 FM(IP2SR0_7_4) IP2SR0_7_4 \ +FM(IP0SR0_11_8) IP0SR0_11_8 FM(IP1SR0_11_8) IP1SR0_11_8 FM(IP2SR0_11_8) IP2SR0_11_8 \ +FM(IP0SR0_15_12) IP0SR0_15_12 FM(IP1SR0_15_12) IP1SR0_15_12 \ +FM(IP0SR0_19_16) IP0SR0_19_16 FM(IP1SR0_19_16) IP1SR0_19_16 \ +FM(IP0SR0_23_20) IP0SR0_23_20 FM(IP1SR0_23_20) IP1SR0_23_20 \ +FM(IP0SR0_27_24) IP0SR0_27_24 FM(IP1SR0_27_24) IP1SR0_27_24 \ +FM(IP0SR0_31_28) IP0SR0_31_28 FM(IP1SR0_31_28) IP1SR0_31_28 \ +\ +FM(IP0SR1_3_0) IP0SR1_3_0 FM(IP1SR1_3_0) IP1SR1_3_0 FM(IP2SR1_3_0) IP2SR1_3_0 FM(IP3SR1_3_0) IP3SR1_3_0 \ +FM(IP0SR1_7_4) IP0SR1_7_4 FM(IP1SR1_7_4) IP1SR1_7_4 FM(IP2SR1_7_4) IP2SR1_7_4 FM(IP3SR1_7_4) IP3SR1_7_4 \ +FM(IP0SR1_11_8) IP0SR1_11_8 FM(IP1SR1_11_8) IP1SR1_11_8 FM(IP2SR1_11_8) IP2SR1_11_8 FM(IP3SR1_11_8) IP3SR1_11_8 \ +FM(IP0SR1_15_12) IP0SR1_15_12 FM(IP1SR1_15_12) IP1SR1_15_12 FM(IP2SR1_15_12) IP2SR1_15_12 FM(IP3SR1_15_12) IP3SR1_15_12 \ +FM(IP0SR1_19_16) IP0SR1_19_16 FM(IP1SR1_19_16) IP1SR1_19_16 FM(IP2SR1_19_16) IP2SR1_19_16 FM(IP3SR1_19_16) IP3SR1_19_16 \ +FM(IP0SR1_23_20) IP0SR1_23_20 FM(IP1SR1_23_20) IP1SR1_23_20 FM(IP2SR1_23_20) IP2SR1_23_20 FM(IP3SR1_23_20) IP3SR1_23_20 \ +FM(IP0SR1_27_24) IP0SR1_27_24 FM(IP1SR1_27_24) IP1SR1_27_24 FM(IP2SR1_27_24) IP2SR1_27_24 \ +FM(IP0SR1_31_28) IP0SR1_31_28 FM(IP1SR1_31_28) IP1SR1_31_28 FM(IP2SR1_31_28) IP2SR1_31_28 \ +\ +FM(IP0SR2_3_0) IP0SR2_3_0 FM(IP1SR2_3_0) IP1SR2_3_0 \ +FM(IP0SR2_7_4) IP0SR2_7_4 FM(IP1SR2_7_4) IP1SR2_7_4 FM(IP2SR2_7_4) IP2SR2_7_4 \ +FM(IP0SR2_11_8) IP0SR2_11_8 FM(IP1SR2_11_8) IP1SR2_11_8 \ +FM(IP0SR2_15_12) IP0SR2_15_12 FM(IP1SR2_15_12) IP1SR2_15_12 FM(IP2SR2_15_12) IP2SR2_15_12 \ +FM(IP0SR2_19_16) IP0SR2_19_16 FM(IP1SR2_19_16) IP1SR2_19_16 \ +FM(IP0SR2_23_20) IP0SR2_23_20 FM(IP1SR2_23_20) IP1SR2_23_20 \ +FM(IP0SR2_27_24) IP0SR2_27_24 FM(IP1SR2_27_24) IP1SR2_27_24 \ +FM(IP0SR2_31_28) IP0SR2_31_28 FM(IP1SR2_31_28) IP1SR2_31_28 \ +\ +FM(IP0SR3_3_0) IP0SR3_3_0 FM(IP1SR3_3_0) IP1SR3_3_0 FM(IP2SR3_3_0) IP2SR3_3_0 FM(IP3SR3_3_0) IP3SR3_3_0 \ +FM(IP0SR3_7_4) IP0SR3_7_4 FM(IP1SR3_7_4) IP1SR3_7_4 FM(IP2SR3_7_4) IP2SR3_7_4 FM(IP3SR3_7_4) IP3SR3_7_4 \ +FM(IP0SR3_11_8) IP0SR3_11_8 FM(IP1SR3_11_8) IP1SR3_11_8 FM(IP2SR3_11_8) IP2SR3_11_8 FM(IP3SR3_11_8) IP3SR3_11_8 \ +FM(IP0SR3_15_12) IP0SR3_15_12 FM(IP1SR3_15_12) IP1SR3_15_12 FM(IP2SR3_15_12) IP2SR3_15_12 FM(IP3SR3_15_12) IP3SR3_15_12 \ +FM(IP0SR3_19_16) IP0SR3_19_16 FM(IP1SR3_19_16) IP1SR3_19_16 FM(IP2SR3_19_16) IP2SR3_19_16 FM(IP3SR3_19_16) IP3SR3_19_16 \ +FM(IP0SR3_23_20) IP0SR3_23_20 FM(IP1SR3_23_20) IP1SR3_23_20 FM(IP2SR3_23_20) IP2SR3_23_20 FM(IP3SR3_23_20) IP3SR3_23_20 \ +FM(IP0SR3_27_24) IP0SR3_27_24 FM(IP1SR3_27_24) IP1SR3_27_24 FM(IP2SR3_27_24) IP2SR3_27_24 FM(IP3SR3_27_24) IP3SR3_27_24 \ +FM(IP0SR3_31_28) IP0SR3_31_28 FM(IP1SR3_31_28) IP1SR3_31_28 FM(IP2SR3_31_28) IP2SR3_31_28 FM(IP3SR3_31_28) IP3SR3_31_28 \ +\ +FM(IP0SR4_3_0) IP0SR4_3_0 FM(IP1SR4_3_0) IP1SR4_3_0 FM(IP3SR4_3_0) IP3SR4_3_0 \ +FM(IP0SR4_7_4) IP0SR4_7_4 FM(IP1SR4_7_4) IP1SR4_7_4 \ +FM(IP0SR4_11_8) IP0SR4_11_8 FM(IP1SR4_11_8) IP1SR4_11_8 \ +FM(IP0SR4_15_12) IP0SR4_15_12 FM(IP1SR4_15_12) IP1SR4_15_12 \ +FM(IP0SR4_19_16) IP0SR4_19_16 FM(IP1SR4_19_16) IP1SR4_19_16 \ +FM(IP0SR4_23_20) IP0SR4_23_20 FM(IP1SR4_23_20) IP1SR4_23_20 FM(IP2SR4_23_20) IP2SR4_23_20 \ +FM(IP0SR4_27_24) IP0SR4_27_24 FM(IP1SR4_27_24) IP1SR4_27_24 \ +FM(IP0SR4_31_28) IP0SR4_31_28 FM(IP1SR4_31_28) IP1SR4_31_28 FM(IP2SR4_31_28) IP2SR4_31_28 \ +\ +FM(IP0SR5_3_0) IP0SR5_3_0 FM(IP1SR5_3_0) IP1SR5_3_0 FM(IP2SR5_3_0) IP2SR5_3_0 \ +FM(IP0SR5_7_4) IP0SR5_7_4 FM(IP1SR5_7_4) IP1SR5_7_4 FM(IP2SR5_7_4) IP2SR5_7_4 \ +FM(IP0SR5_11_8) IP0SR5_11_8 FM(IP1SR5_11_8) IP1SR5_11_8 FM(IP2SR5_11_8) IP2SR5_11_8 \ +FM(IP0SR5_15_12) IP0SR5_15_12 FM(IP1SR5_15_12) IP1SR5_15_12 FM(IP2SR5_15_12) IP2SR5_15_12 \ +FM(IP0SR5_19_16) IP0SR5_19_16 FM(IP1SR5_19_16) IP1SR5_19_16 FM(IP2SR5_19_16) IP2SR5_19_16 \ +FM(IP0SR5_23_20) IP0SR5_23_20 FM(IP1SR5_23_20) IP1SR5_23_20 \ +FM(IP0SR5_27_24) IP0SR5_27_24 FM(IP1SR5_27_24) IP1SR5_27_24 \ +FM(IP0SR5_31_28) IP0SR5_31_28 FM(IP1SR5_31_28) IP1SR5_31_28 \ +\ +FM(IP0SR6_3_0) IP0SR6_3_0 FM(IP1SR6_3_0) IP1SR6_3_0 FM(IP2SR6_3_0) IP2SR6_3_0 \ +FM(IP0SR6_7_4) IP0SR6_7_4 FM(IP1SR6_7_4) IP1SR6_7_4 FM(IP2SR6_7_4) IP2SR6_7_4 \ +FM(IP0SR6_11_8) IP0SR6_11_8 FM(IP1SR6_11_8) IP1SR6_11_8 FM(IP2SR6_11_8) IP2SR6_11_8 \ +FM(IP0SR6_15_12) IP0SR6_15_12 FM(IP1SR6_15_12) IP1SR6_15_12 FM(IP2SR6_15_12) IP2SR6_15_12 \ +FM(IP0SR6_19_16) IP0SR6_19_16 FM(IP1SR6_19_16) IP1SR6_19_16 FM(IP2SR6_19_16) IP2SR6_19_16 \ +FM(IP0SR6_23_20) IP0SR6_23_20 FM(IP1SR6_23_20) IP1SR6_23_20 \ +FM(IP0SR6_27_24) IP0SR6_27_24 FM(IP1SR6_27_24) IP1SR6_27_24 \ +FM(IP0SR6_31_28) IP0SR6_31_28 FM(IP1SR6_31_28) IP1SR6_31_28 \ +\ +FM(IP0SR7_3_0) IP0SR7_3_0 FM(IP1SR7_3_0) IP1SR7_3_0 FM(IP2SR7_3_0) IP2SR7_3_0 \ +FM(IP0SR7_7_4) IP0SR7_7_4 FM(IP1SR7_7_4) IP1SR7_7_4 FM(IP2SR7_7_4) IP2SR7_7_4 \ +FM(IP0SR7_11_8) IP0SR7_11_8 FM(IP1SR7_11_8) IP1SR7_11_8 FM(IP2SR7_11_8) IP2SR7_11_8 \ +FM(IP0SR7_15_12) IP0SR7_15_12 FM(IP1SR7_15_12) IP1SR7_15_12 FM(IP2SR7_15_12) IP2SR7_15_12 \ +FM(IP0SR7_19_16) IP0SR7_19_16 FM(IP1SR7_19_16) IP1SR7_19_16 FM(IP2SR7_19_16) IP2SR7_19_16 \ +FM(IP0SR7_23_20) IP0SR7_23_20 FM(IP1SR7_23_20) IP1SR7_23_20 \ +FM(IP0SR7_27_24) IP0SR7_27_24 FM(IP1SR7_27_24) IP1SR7_27_24 \ +FM(IP0SR7_31_28) IP0SR7_31_28 FM(IP1SR7_31_28) IP1SR7_31_28 \ + +/* MOD_SEL4 */ /* 0 */ /* 1 */ +#define MOD_SEL4_7 FM(SEL_SDA3_0) FM(SEL_SDA3_1) +#define MOD_SEL4_6 FM(SEL_SCL3_0) FM(SEL_SCL3_1) +#define MOD_SEL4_5 FM(SEL_SDA2_0) FM(SEL_SDA2_1) +#define MOD_SEL4_4 FM(SEL_SCL2_0) FM(SEL_SCL2_1) +#define MOD_SEL4_3 FM(SEL_SDA1_0) FM(SEL_SDA1_1) +#define MOD_SEL4_2 FM(SEL_SCL1_0) FM(SEL_SCL1_1) +#define MOD_SEL4_1 FM(SEL_SDA0_0) FM(SEL_SDA0_1) +#define MOD_SEL4_0 FM(SEL_SCL0_0) FM(SEL_SCL0_1) + +#define PINMUX_MOD_SELS \ +\ +MOD_SEL4_7 \ +MOD_SEL4_6 \ +MOD_SEL4_5 \ +MOD_SEL4_4 \ +MOD_SEL4_3 \ +MOD_SEL4_2 \ +MOD_SEL4_1 \ +MOD_SEL4_0 + +enum { + PINMUX_RESERVED = 0, + + PINMUX_DATA_BEGIN, + GP_ALL(DATA), + PINMUX_DATA_END, + +#define F_(x, y) +#define FM(x) FN_##x, + PINMUX_FUNCTION_BEGIN, + GP_ALL(FN), + PINMUX_GPSR + PINMUX_IPSR + PINMUX_MOD_SELS + PINMUX_FUNCTION_END, +#undef F_ +#undef FM + +#define F_(x, y) +#define FM(x) x##_MARK, + PINMUX_MARK_BEGIN, + PINMUX_GPSR + PINMUX_IPSR + PINMUX_MOD_SELS + PINMUX_MARK_END, +#undef F_ +#undef FM +}; + +static const u16 pinmux_data[] = { + PINMUX_DATA_GP_ALL(), + + /* IP0SR0 */ + PINMUX_IPSR_GPSR(IP0SR0_3_0, ERROROUTC_N_B), + PINMUX_IPSR_GPSR(IP0SR0_3_0, TCLK2_B), + + PINMUX_IPSR_GPSR(IP0SR0_7_4, MSIOF3_SS1), + + PINMUX_IPSR_GPSR(IP0SR0_11_8, MSIOF3_SS2), + + PINMUX_IPSR_GPSR(IP0SR0_15_12, IRQ3), + PINMUX_IPSR_GPSR(IP0SR0_15_12, MSIOF3_SCK), + + PINMUX_IPSR_GPSR(IP0SR0_19_16, IRQ2), + PINMUX_IPSR_GPSR(IP0SR0_19_16, MSIOF3_TXD), + + PINMUX_IPSR_GPSR(IP0SR0_23_20, IRQ1), + PINMUX_IPSR_GPSR(IP0SR0_23_20, MSIOF3_RXD), + + PINMUX_IPSR_GPSR(IP0SR0_27_24, IRQ0), + PINMUX_IPSR_GPSR(IP0SR0_27_24, MSIOF3_SYNC), + + PINMUX_IPSR_GPSR(IP0SR0_31_28, MSIOF5_SS2), + + /* IP1SR0 */ + PINMUX_IPSR_GPSR(IP1SR0_3_0, MSIOF5_SS1), + + PINMUX_IPSR_GPSR(IP1SR0_7_4, MSIOF5_SYNC), + + PINMUX_IPSR_GPSR(IP1SR0_11_8, MSIOF5_TXD), + + PINMUX_IPSR_GPSR(IP1SR0_15_12, MSIOF5_SCK), + + PINMUX_IPSR_GPSR(IP1SR0_19_16, MSIOF5_RXD), + + PINMUX_IPSR_GPSR(IP1SR0_23_20, MSIOF2_SS2), + PINMUX_IPSR_GPSR(IP1SR0_23_20, TCLK1_A), + PINMUX_IPSR_GPSR(IP1SR0_23_20, IRQ2_B), + + PINMUX_IPSR_GPSR(IP1SR0_27_24, MSIOF2_SS1), + PINMUX_IPSR_GPSR(IP1SR0_27_24, HTX1_A), + PINMUX_IPSR_GPSR(IP1SR0_27_24, TX1_A), + + PINMUX_IPSR_GPSR(IP1SR0_31_28, MSIOF2_SYNC), + PINMUX_IPSR_GPSR(IP1SR0_31_28, HRX1_A), + PINMUX_IPSR_GPSR(IP1SR0_31_28, RX1_A), + + /* IP2SR0 */ + PINMUX_IPSR_GPSR(IP2SR0_3_0, MSIOF2_TXD), + PINMUX_IPSR_GPSR(IP2SR0_3_0, HCTS1_N_A), + PINMUX_IPSR_GPSR(IP2SR0_3_0, CTS1_N_A), + + PINMUX_IPSR_GPSR(IP2SR0_7_4, MSIOF2_SCK), + PINMUX_IPSR_GPSR(IP2SR0_7_4, HRTS1_N_A), + PINMUX_IPSR_GPSR(IP2SR0_7_4, RTS1_N_A), + + PINMUX_IPSR_GPSR(IP2SR0_11_8, MSIOF2_RXD), + PINMUX_IPSR_GPSR(IP2SR0_11_8, HSCK1_A), + PINMUX_IPSR_GPSR(IP2SR0_11_8, SCK1_A), + + /* IP0SR1 */ + PINMUX_IPSR_GPSR(IP0SR1_3_0, MSIOF1_SS2), + PINMUX_IPSR_GPSR(IP0SR1_3_0, HTX3_B), + PINMUX_IPSR_GPSR(IP0SR1_3_0, TX3_B), + + PINMUX_IPSR_GPSR(IP0SR1_7_4, MSIOF1_SS1), + PINMUX_IPSR_GPSR(IP0SR1_7_4, HCTS3_N_B), + PINMUX_IPSR_GPSR(IP0SR1_7_4, RX3_B), + + PINMUX_IPSR_GPSR(IP0SR1_11_8, MSIOF1_SYNC), + PINMUX_IPSR_GPSR(IP0SR1_11_8, HRTS3_N_B), + PINMUX_IPSR_GPSR(IP0SR1_11_8, RTS3_N_B), + + PINMUX_IPSR_GPSR(IP0SR1_15_12, MSIOF1_SCK), + PINMUX_IPSR_GPSR(IP0SR1_15_12, HSCK3_B), + PINMUX_IPSR_GPSR(IP0SR1_15_12, CTS3_N_B), + + PINMUX_IPSR_GPSR(IP0SR1_19_16, MSIOF1_TXD), + PINMUX_IPSR_GPSR(IP0SR1_19_16, HRX3_B), + PINMUX_IPSR_GPSR(IP0SR1_19_16, SCK3_B), + + PINMUX_IPSR_GPSR(IP0SR1_23_20, MSIOF1_RXD), + + PINMUX_IPSR_GPSR(IP0SR1_27_24, MSIOF0_SS2), + PINMUX_IPSR_GPSR(IP0SR1_27_24, HTX1_B), + PINMUX_IPSR_GPSR(IP0SR1_27_24, TX1_B), + + PINMUX_IPSR_GPSR(IP0SR1_31_28, MSIOF0_SS1), + PINMUX_IPSR_GPSR(IP0SR1_31_28, HRX1_B), + PINMUX_IPSR_GPSR(IP0SR1_31_28, RX1_B), + + /* IP1SR1 */ + PINMUX_IPSR_GPSR(IP1SR1_3_0, MSIOF0_SYNC), + PINMUX_IPSR_GPSR(IP1SR1_3_0, HCTS1_N_B), + PINMUX_IPSR_GPSR(IP1SR1_3_0, CTS1_N_B), + + PINMUX_IPSR_GPSR(IP1SR1_7_4, MSIOF0_TXD), + PINMUX_IPSR_GPSR(IP1SR1_7_4, HRTS1_N_B), + PINMUX_IPSR_GPSR(IP1SR1_7_4, RTS1_N_B), + + PINMUX_IPSR_GPSR(IP1SR1_11_8, MSIOF0_SCK), + PINMUX_IPSR_GPSR(IP1SR1_11_8, HSCK1_B), + PINMUX_IPSR_GPSR(IP1SR1_11_8, SCK1_B), + + PINMUX_IPSR_GPSR(IP1SR1_15_12, MSIOF0_RXD), + + PINMUX_IPSR_GPSR(IP1SR1_19_16, HTX0), + PINMUX_IPSR_GPSR(IP1SR1_19_16, TX0), + + PINMUX_IPSR_GPSR(IP1SR1_23_20, HCTS0_N), + PINMUX_IPSR_GPSR(IP1SR1_23_20, CTS0_N), + + PINMUX_IPSR_GPSR(IP1SR1_27_24, HRTS0_N), + PINMUX_IPSR_GPSR(IP1SR1_27_24, RTS0_N), + PINMUX_IPSR_GPSR(IP1SR1_27_24, PWM0_B), + + PINMUX_IPSR_GPSR(IP1SR1_31_28, HSCK0), + PINMUX_IPSR_GPSR(IP1SR1_31_28, SCK0), + PINMUX_IPSR_GPSR(IP1SR1_31_28, PWM0_A), + + /* IP2SR1 */ + PINMUX_IPSR_GPSR(IP2SR1_3_0, HRX0), + PINMUX_IPSR_GPSR(IP2SR1_3_0, RX0), + + PINMUX_IPSR_GPSR(IP2SR1_7_4, SCIF_CLK), + PINMUX_IPSR_GPSR(IP2SR1_7_4, IRQ4_A), + + PINMUX_IPSR_GPSR(IP2SR1_11_8, SSI_SCK), + PINMUX_IPSR_GPSR(IP2SR1_11_8, TCLK3_B), + + PINMUX_IPSR_GPSR(IP2SR1_15_12, SSI_WS), + PINMUX_IPSR_GPSR(IP2SR1_15_12, TCLK4_B), + + PINMUX_IPSR_GPSR(IP2SR1_19_16, SSI_SD), + PINMUX_IPSR_GPSR(IP2SR1_19_16, IRQ0_B), + + PINMUX_IPSR_GPSR(IP2SR1_23_20, AUDIO_CLKOUT), + PINMUX_IPSR_GPSR(IP2SR1_23_20, IRQ1_B), + + PINMUX_IPSR_GPSR(IP2SR1_27_24, AUDIO_CLKIN), + PINMUX_IPSR_GPSR(IP2SR1_27_24, PWM3_C), + + PINMUX_IPSR_GPSR(IP2SR1_31_28, TCLK2_A), + PINMUX_IPSR_GPSR(IP2SR1_31_28, MSIOF4_SS1), + PINMUX_IPSR_GPSR(IP2SR1_31_28, IRQ3_B), + + /* IP3SR1 */ + PINMUX_IPSR_GPSR(IP3SR1_3_0, HRX3_A), + PINMUX_IPSR_GPSR(IP3SR1_3_0, SCK3_A), + PINMUX_IPSR_GPSR(IP3SR1_3_0, MSIOF4_SS2), + + PINMUX_IPSR_GPSR(IP3SR1_7_4, HSCK3_A), + PINMUX_IPSR_GPSR(IP3SR1_7_4, CTS3_N_A), + PINMUX_IPSR_GPSR(IP3SR1_7_4, MSIOF4_SCK), + PINMUX_IPSR_GPSR(IP3SR1_7_4, TPU0TO0_B), + + PINMUX_IPSR_GPSR(IP3SR1_11_8, HRTS3_N_A), + PINMUX_IPSR_GPSR(IP3SR1_11_8, RTS3_N_A), + PINMUX_IPSR_GPSR(IP3SR1_11_8, MSIOF4_TXD), + PINMUX_IPSR_GPSR(IP3SR1_11_8, TPU0TO1_B), + + PINMUX_IPSR_GPSR(IP3SR1_15_12, HCTS3_N_A), + PINMUX_IPSR_GPSR(IP3SR1_15_12, RX3_A), + PINMUX_IPSR_GPSR(IP3SR1_15_12, MSIOF4_RXD), + + PINMUX_IPSR_GPSR(IP3SR1_19_16, HTX3_A), + PINMUX_IPSR_GPSR(IP3SR1_19_16, TX3_A), + PINMUX_IPSR_GPSR(IP3SR1_19_16, MSIOF4_SYNC), + + PINMUX_IPSR_GPSR(IP3SR1_23_20, ERROROUTC_N_A), + + /* IP0SR2 */ + PINMUX_IPSR_GPSR(IP0SR2_3_0, FXR_TXDA), + PINMUX_IPSR_GPSR(IP0SR2_3_0, TPU0TO2_B), + + PINMUX_IPSR_GPSR(IP0SR2_7_4, FXR_TXENA_N_A), + PINMUX_IPSR_GPSR(IP0SR2_7_4, TPU0TO3_B), + + PINMUX_IPSR_GPSR(IP0SR2_11_8, RXDA_EXTFXR), + PINMUX_IPSR_GPSR(IP0SR2_11_8, IRQ5), + + PINMUX_IPSR_GPSR(IP0SR2_15_12, CLK_EXTFXR), + PINMUX_IPSR_GPSR(IP0SR2_15_12, IRQ4_B), + + PINMUX_IPSR_GPSR(IP0SR2_19_16, RXDB_EXTFXR), + + PINMUX_IPSR_GPSR(IP0SR2_23_20, FXR_TXENB_N_A), + + PINMUX_IPSR_GPSR(IP0SR2_27_24, FXR_TXDB), + + PINMUX_IPSR_GPSR(IP0SR2_31_28, TPU0TO1_A), + PINMUX_IPSR_GPSR(IP0SR2_31_28, TCLK2_C), + + /* IP1SR2 */ + PINMUX_IPSR_GPSR(IP1SR2_3_0, TPU0TO0_A), + PINMUX_IPSR_GPSR(IP1SR2_3_0, TCLK1_B), + + PINMUX_IPSR_GPSR(IP1SR2_7_4, CAN_CLK), + PINMUX_IPSR_GPSR(IP1SR2_7_4, FXR_TXENA_N_B), + + PINMUX_IPSR_GPSR(IP1SR2_11_8, CANFD0_TX), + PINMUX_IPSR_GPSR(IP1SR2_11_8, FXR_TXENB_N_B), + + PINMUX_IPSR_GPSR(IP1SR2_15_12, CANFD0_RX), + PINMUX_IPSR_GPSR(IP1SR2_15_12, STPWT_EXTFXR), + + PINMUX_IPSR_GPSR(IP1SR2_19_16, CANFD2_TX), + PINMUX_IPSR_GPSR(IP1SR2_19_16, TPU0TO2_A), + PINMUX_IPSR_GPSR(IP1SR2_19_16, TCLK3_C), + + PINMUX_IPSR_GPSR(IP1SR2_23_20, CANFD2_RX), + PINMUX_IPSR_GPSR(IP1SR2_23_20, TPU0TO3_A), + PINMUX_IPSR_GPSR(IP1SR2_23_20, PWM1_B), + PINMUX_IPSR_GPSR(IP1SR2_23_20, TCLK4_C), + + PINMUX_IPSR_GPSR(IP1SR2_27_24, CANFD3_TX), + PINMUX_IPSR_GPSR(IP1SR2_27_24, PWM2_B), + + PINMUX_IPSR_GPSR(IP1SR2_31_28, CANFD3_RX), + PINMUX_IPSR_GPSR(IP1SR2_31_28, PWM3_B), + + /* IP2SR2 */ + PINMUX_IPSR_GPSR(IP2SR2_7_4, CANFD1_TX), + PINMUX_IPSR_GPSR(IP2SR2_7_4, PWM1_C), + + PINMUX_IPSR_GPSR(IP2SR2_15_12, CANFD1_RX), + PINMUX_IPSR_GPSR(IP2SR2_15_12, PWM2_C), + + /* IP0SR3 */ + PINMUX_IPSR_GPSR(IP0SR3_3_0, MMC_SD_D1), + + PINMUX_IPSR_GPSR(IP0SR3_7_4, MMC_SD_D0), + + PINMUX_IPSR_GPSR(IP0SR3_11_8, MMC_SD_D2), + + PINMUX_IPSR_GPSR(IP0SR3_15_12, MMC_SD_CLK), + + PINMUX_IPSR_GPSR(IP0SR3_19_16, MMC_DS), + + PINMUX_IPSR_GPSR(IP0SR3_23_20, MMC_SD_D3), + + PINMUX_IPSR_GPSR(IP0SR3_27_24, MMC_D5), + + PINMUX_IPSR_GPSR(IP0SR3_31_28, MMC_D4), + + /* IP1SR3 */ + PINMUX_IPSR_GPSR(IP1SR3_3_0, MMC_D7), + + PINMUX_IPSR_GPSR(IP1SR3_7_4, MMC_D6), + + PINMUX_IPSR_GPSR(IP1SR3_11_8, MMC_SD_CMD), + + PINMUX_IPSR_GPSR(IP1SR3_15_12, SD_CD), + + PINMUX_IPSR_GPSR(IP1SR3_19_16, SD_WP), + + PINMUX_IPSR_GPSR(IP1SR3_23_20, PWM1_A), + + PINMUX_IPSR_GPSR(IP1SR3_27_24, PWM2_A), + + PINMUX_IPSR_GPSR(IP1SR3_31_28, QSPI0_SSL), + + /* IP2SR3 */ + PINMUX_IPSR_GPSR(IP2SR3_3_0, QSPI0_IO3), + + PINMUX_IPSR_GPSR(IP2SR3_7_4, QSPI0_IO2), + + PINMUX_IPSR_GPSR(IP2SR3_11_8, QSPI0_MISO_IO1), + + PINMUX_IPSR_GPSR(IP2SR3_15_12, QSPI0_MOSI_IO0), + + PINMUX_IPSR_GPSR(IP2SR3_19_16, QSPI0_SPCLK), + + PINMUX_IPSR_GPSR(IP2SR3_23_20, QSPI1_MOSI_IO0), + + PINMUX_IPSR_GPSR(IP2SR3_27_24, QSPI1_SPCLK), + + PINMUX_IPSR_GPSR(IP2SR3_31_28, QSPI1_MISO_IO1), + + /* IP3SR3 */ + PINMUX_IPSR_GPSR(IP3SR3_3_0, QSPI1_IO2), + + PINMUX_IPSR_GPSR(IP3SR3_7_4, QSPI1_SSL), + + PINMUX_IPSR_GPSR(IP3SR3_11_8, QSPI1_IO3), + + PINMUX_IPSR_GPSR(IP3SR3_15_12, RPC_RESET_N), + + PINMUX_IPSR_GPSR(IP3SR3_19_16, RPC_WP_N), + + PINMUX_IPSR_GPSR(IP3SR3_23_20, RPC_INT_N), + + PINMUX_IPSR_GPSR(IP3SR3_27_24, TCLK3_A), + + PINMUX_IPSR_GPSR(IP3SR3_31_28, TCLK4_A), + + /* IP0SR4 */ + PINMUX_IPSR_MSEL(IP0SR4_3_0, SCL0, SEL_SCL0_0), + + PINMUX_IPSR_MSEL(IP0SR4_7_4, SDA0, SEL_SDA0_0), + + PINMUX_IPSR_MSEL(IP0SR4_11_8, SCL1, SEL_SCL1_0), + + PINMUX_IPSR_MSEL(IP0SR4_15_12, SDA1, SEL_SDA1_0), + + PINMUX_IPSR_MSEL(IP0SR4_19_16, SCL2, SEL_SCL2_0), + + PINMUX_IPSR_MSEL(IP0SR4_23_20, SDA2, SEL_SDA2_0), + + PINMUX_IPSR_MSEL(IP0SR4_27_24, SCL3, SEL_SCL3_0), + + PINMUX_IPSR_MSEL(IP0SR4_31_28, SDA3, SEL_SDA3_0), + + /* IP1SR4 */ + PINMUX_IPSR_GPSR(IP1SR4_3_0, HRX2), + PINMUX_IPSR_GPSR(IP1SR4_3_0, SCK4), + + PINMUX_IPSR_GPSR(IP1SR4_7_4, HTX2), + PINMUX_IPSR_GPSR(IP1SR4_7_4, CTS4_N), + + PINMUX_IPSR_GPSR(IP1SR4_11_8, HRTS2_N), + PINMUX_IPSR_GPSR(IP1SR4_11_8, RTS4_N), + + PINMUX_IPSR_GPSR(IP1SR4_15_12, SCIF_CLK2), + + PINMUX_IPSR_GPSR(IP1SR4_19_16, HCTS2_N), + PINMUX_IPSR_GPSR(IP1SR4_19_16, TX4), + + PINMUX_IPSR_GPSR(IP1SR4_23_20, HSCK2), + PINMUX_IPSR_GPSR(IP1SR4_23_20, RX4), + + PINMUX_IPSR_GPSR(IP1SR4_27_24, PWM3_A), + + PINMUX_IPSR_GPSR(IP1SR4_31_28, PWM4), + + /* IP2SR4 */ + PINMUX_IPSR_GPSR(IP2SR4_23_20, PCIE0_CLKREQ_N), + + PINMUX_IPSR_GPSR(IP2SR4_31_28, AVS0), + + /* IP3SR4 */ + PINMUX_IPSR_GPSR(IP3SR4_3_0, AVS1), + + /* IP0SR5 */ + PINMUX_IPSR_GPSR(IP0SR5_3_0, AVB2_AVTP_PPS), + PINMUX_IPSR_GPSR(IP0SR5_3_0, Ether_GPTP_PPS0), + + PINMUX_IPSR_GPSR(IP0SR5_7_4, AVB2_AVTP_CAPTURE), + PINMUX_IPSR_GPSR(IP0SR5_7_4, Ether_GPTP_CAPTURE), + + PINMUX_IPSR_GPSR(IP0SR5_11_8, AVB2_AVTP_MATCH), + PINMUX_IPSR_GPSR(IP0SR5_11_8, Ether_GPTP_MATCH), + + PINMUX_IPSR_GPSR(IP0SR5_15_12, AVB2_LINK), + + PINMUX_IPSR_GPSR(IP0SR5_19_16, AVB2_PHY_INT), + + PINMUX_IPSR_GPSR(IP0SR5_23_20, AVB2_MAGIC), + PINMUX_IPSR_GPSR(IP0SR5_23_20, Ether_GPTP_PPS1), + + PINMUX_IPSR_GPSR(IP0SR5_27_24, AVB2_MDC), + + PINMUX_IPSR_GPSR(IP0SR5_31_28, AVB2_TXCREFCLK), + + /* IP1SR5 */ + PINMUX_IPSR_GPSR(IP1SR5_3_0, AVB2_TD3), + + PINMUX_IPSR_GPSR(IP1SR5_7_4, AVB2_RD3), + + PINMUX_IPSR_GPSR(IP1SR5_11_8, AVB2_MDIO), + + PINMUX_IPSR_GPSR(IP1SR5_15_12, AVB2_TD2), + + PINMUX_IPSR_GPSR(IP1SR5_19_16, AVB2_TD1), + + PINMUX_IPSR_GPSR(IP1SR5_23_20, AVB2_RD2), + + PINMUX_IPSR_GPSR(IP1SR5_27_24, AVB2_RD1), + + PINMUX_IPSR_GPSR(IP1SR5_31_28, AVB2_TD0), + + /* IP2SR5 */ + PINMUX_IPSR_GPSR(IP2SR5_3_0, AVB2_TXC), + + PINMUX_IPSR_GPSR(IP2SR5_7_4, AVB2_RD0), + + PINMUX_IPSR_GPSR(IP2SR5_11_8, AVB2_RXC), + + PINMUX_IPSR_GPSR(IP2SR5_15_12, AVB2_TX_CTL), + + PINMUX_IPSR_GPSR(IP2SR5_19_16, AVB2_RX_CTL), + + /* IP0SR6 */ + PINMUX_IPSR_GPSR(IP0SR6_3_0, AVB1_MDIO), + + PINMUX_IPSR_GPSR(IP0SR6_7_4, AVB1_MAGIC), + + PINMUX_IPSR_GPSR(IP0SR6_11_8, AVB1_MDC), + + PINMUX_IPSR_GPSR(IP0SR6_15_12, AVB1_PHY_INT), + + PINMUX_IPSR_GPSR(IP0SR6_19_16, AVB1_LINK), + PINMUX_IPSR_GPSR(IP0SR6_19_16, AVB1_MII_TX_ER), + + PINMUX_IPSR_GPSR(IP0SR6_23_20, AVB1_AVTP_MATCH), + PINMUX_IPSR_GPSR(IP0SR6_23_20, AVB1_MII_RX_ER), + + PINMUX_IPSR_GPSR(IP0SR6_27_24, AVB1_TXC), + PINMUX_IPSR_GPSR(IP0SR6_27_24, AVB1_MII_TXC), + + PINMUX_IPSR_GPSR(IP0SR6_31_28, AVB1_TX_CTL), + PINMUX_IPSR_GPSR(IP0SR6_31_28, AVB1_MII_TX_EN), + + /* IP1SR6 */ + PINMUX_IPSR_GPSR(IP1SR6_3_0, AVB1_RXC), + PINMUX_IPSR_GPSR(IP1SR6_3_0, AVB1_MII_RXC), + + PINMUX_IPSR_GPSR(IP1SR6_7_4, AVB1_RX_CTL), + PINMUX_IPSR_GPSR(IP1SR6_7_4, AVB1_MII_RX_DV), + + PINMUX_IPSR_GPSR(IP1SR6_11_8, AVB1_AVTP_PPS), + PINMUX_IPSR_GPSR(IP1SR6_11_8, AVB1_MII_COL), + + PINMUX_IPSR_GPSR(IP1SR6_15_12, AVB1_AVTP_CAPTURE), + PINMUX_IPSR_GPSR(IP1SR6_15_12, AVB1_MII_CRS), + + PINMUX_IPSR_GPSR(IP1SR6_19_16, AVB1_TD1), + PINMUX_IPSR_GPSR(IP1SR6_19_16, AVB1_MII_TD1), + + PINMUX_IPSR_GPSR(IP1SR6_23_20, AVB1_TD0), + PINMUX_IPSR_GPSR(IP1SR6_23_20, AVB1_MII_TD0), + + PINMUX_IPSR_GPSR(IP1SR6_27_24, AVB1_RD1), + PINMUX_IPSR_GPSR(IP1SR6_27_24, AVB1_MII_RD1), + + PINMUX_IPSR_GPSR(IP1SR6_31_28, AVB1_RD0), + PINMUX_IPSR_GPSR(IP1SR6_31_28, AVB1_MII_RD0), + + /* IP2SR6 */ + PINMUX_IPSR_GPSR(IP2SR6_3_0, AVB1_TD2), + PINMUX_IPSR_GPSR(IP2SR6_3_0, AVB1_MII_TD2), + + PINMUX_IPSR_GPSR(IP2SR6_7_4, AVB1_RD2), + PINMUX_IPSR_GPSR(IP2SR6_7_4, AVB1_MII_RD2), + + PINMUX_IPSR_GPSR(IP2SR6_11_8, AVB1_TD3), + PINMUX_IPSR_GPSR(IP2SR6_11_8, AVB1_MII_TD3), + + PINMUX_IPSR_GPSR(IP2SR6_15_12, AVB1_RD3), + PINMUX_IPSR_GPSR(IP2SR6_15_12, AVB1_MII_RD3), + + PINMUX_IPSR_GPSR(IP2SR6_19_16, AVB1_TXCREFCLK), + + /* IP0SR7 */ + PINMUX_IPSR_GPSR(IP0SR7_3_0, AVB0_AVTP_PPS), + PINMUX_IPSR_GPSR(IP0SR7_3_0, AVB0_MII_COL), + + PINMUX_IPSR_GPSR(IP0SR7_7_4, AVB0_AVTP_CAPTURE), + PINMUX_IPSR_GPSR(IP0SR7_7_4, AVB0_MII_CRS), + + PINMUX_IPSR_GPSR(IP0SR7_11_8, AVB0_AVTP_MATCH), + PINMUX_IPSR_GPSR(IP0SR7_11_8, AVB0_MII_RX_ER), + PINMUX_IPSR_GPSR(IP0SR7_11_8, CC5_OSCOUT), + + PINMUX_IPSR_GPSR(IP0SR7_15_12, AVB0_TD3), + PINMUX_IPSR_GPSR(IP0SR7_15_12, AVB0_MII_TD3), + + PINMUX_IPSR_GPSR(IP0SR7_19_16, AVB0_LINK), + PINMUX_IPSR_GPSR(IP0SR7_19_16, AVB0_MII_TX_ER), + + PINMUX_IPSR_GPSR(IP0SR7_23_20, AVB0_PHY_INT), + + PINMUX_IPSR_GPSR(IP0SR7_27_24, AVB0_TD2), + PINMUX_IPSR_GPSR(IP0SR7_27_24, AVB0_MII_TD2), + + PINMUX_IPSR_GPSR(IP0SR7_31_28, AVB0_TD1), + PINMUX_IPSR_GPSR(IP0SR7_31_28, AVB0_MII_TD1), + + /* IP1SR7 */ + PINMUX_IPSR_GPSR(IP1SR7_3_0, AVB0_RD3), + PINMUX_IPSR_GPSR(IP1SR7_3_0, AVB0_MII_RD3), + + PINMUX_IPSR_GPSR(IP1SR7_7_4, AVB0_TXCREFCLK), + + PINMUX_IPSR_GPSR(IP1SR7_11_8, AVB0_MAGIC), + + PINMUX_IPSR_GPSR(IP1SR7_15_12, AVB0_TD0), + PINMUX_IPSR_GPSR(IP1SR7_15_12, AVB0_MII_TD0), + + PINMUX_IPSR_GPSR(IP1SR7_19_16, AVB0_RD2), + PINMUX_IPSR_GPSR(IP1SR7_19_16, AVB0_MII_RD2), + + PINMUX_IPSR_GPSR(IP1SR7_23_20, AVB0_MDC), + + PINMUX_IPSR_GPSR(IP1SR7_27_24, AVB0_MDIO), + + PINMUX_IPSR_GPSR(IP1SR7_31_28, AVB0_TXC), + PINMUX_IPSR_GPSR(IP1SR7_31_28, AVB0_MII_TXC), + + /* IP2SR7 */ + PINMUX_IPSR_GPSR(IP2SR7_3_0, AVB0_TX_CTL), + PINMUX_IPSR_GPSR(IP2SR7_3_0, AVB0_MII_TX_EN), + + PINMUX_IPSR_GPSR(IP2SR7_7_4, AVB0_RD1), + PINMUX_IPSR_GPSR(IP2SR7_7_4, AVB0_MII_RD1), + + PINMUX_IPSR_GPSR(IP2SR7_11_8, AVB0_RD0), + PINMUX_IPSR_GPSR(IP2SR7_11_8, AVB0_MII_RD0), + + PINMUX_IPSR_GPSR(IP2SR7_15_12, AVB0_RXC), + PINMUX_IPSR_GPSR(IP2SR7_15_12, AVB0_MII_RXC), + + PINMUX_IPSR_GPSR(IP2SR7_19_16, AVB0_RX_CTL), + PINMUX_IPSR_GPSR(IP2SR7_19_16, AVB0_MII_RX_DV), +}; + +/* + * Pins not associated with a GPIO port. + */ +enum { + GP_ASSIGN_LAST(), + NOGP_ALL(), +}; + +static const struct sh_pfc_pin pinmux_pins[] = { + PINMUX_GPIO_GP_ALL(), + PINMUX_NOGP_ALL(), +}; + +/* - AUDIO CLOCK ----------------------------------------- */ +static const unsigned int audio_clkin_pins[] = { + /* CLK IN */ + RCAR_GP_PIN(1, 22), +}; +static const unsigned int audio_clkin_mux[] = { + AUDIO_CLKIN_MARK, +}; +static const unsigned int audio_clkout_pins[] = { + /* CLK OUT */ + RCAR_GP_PIN(1, 21), +}; +static const unsigned int audio_clkout_mux[] = { + AUDIO_CLKOUT_MARK, +}; + +/* - AVB0 ------------------------------------------------ */ +static const unsigned int avb0_link_pins[] = { + /* AVB0_LINK */ + RCAR_GP_PIN(7, 4), +}; +static const unsigned int avb0_link_mux[] = { + AVB0_LINK_MARK, +}; +static const unsigned int avb0_magic_pins[] = { + /* AVB0_MAGIC */ + RCAR_GP_PIN(7, 10), +}; +static const unsigned int avb0_magic_mux[] = { + AVB0_MAGIC_MARK, +}; +static const unsigned int avb0_phy_int_pins[] = { + /* AVB0_PHY_INT */ + RCAR_GP_PIN(7, 5), +}; +static const unsigned int avb0_phy_int_mux[] = { + AVB0_PHY_INT_MARK, +}; +static const unsigned int avb0_mdio_pins[] = { + /* AVB0_MDC, AVB0_MDIO */ + RCAR_GP_PIN(7, 13), RCAR_GP_PIN(7, 14), +}; +static const unsigned int avb0_mdio_mux[] = { + AVB0_MDC_MARK, AVB0_MDIO_MARK, +}; +static const unsigned int avb0_rgmii_pins[] = { + /* + * AVB0_TX_CTL, AVB0_TXC, AVB0_TD0, AVB0_TD1, AVB0_TD2, AVB0_TD3, + * AVB0_RX_CTL, AVB0_RXC, AVB0_RD0, AVB0_RD1, AVB0_RD2, AVB0_RD3, + */ + RCAR_GP_PIN(7, 16), RCAR_GP_PIN(7, 15), + RCAR_GP_PIN(7, 11), RCAR_GP_PIN(7, 7), + RCAR_GP_PIN(7, 6), RCAR_GP_PIN(7, 3), + RCAR_GP_PIN(7, 20), RCAR_GP_PIN(7, 19), + RCAR_GP_PIN(7, 18), RCAR_GP_PIN(7, 17), + RCAR_GP_PIN(7, 12), RCAR_GP_PIN(7, 8), +}; +static const unsigned int avb0_rgmii_mux[] = { + AVB0_TX_CTL_MARK, AVB0_TXC_MARK, + AVB0_TD0_MARK, AVB0_TD1_MARK, + AVB0_TD2_MARK, AVB0_TD3_MARK, + AVB0_RX_CTL_MARK, AVB0_RXC_MARK, + AVB0_RD0_MARK, AVB0_RD1_MARK, + AVB0_RD2_MARK, AVB0_RD3_MARK, +}; +static const unsigned int avb0_txcrefclk_pins[] = { + /* AVB0_TXCREFCLK */ + RCAR_GP_PIN(7, 9), +}; +static const unsigned int avb0_txcrefclk_mux[] = { + AVB0_TXCREFCLK_MARK, +}; +static const unsigned int avb0_avtp_pps_pins[] = { + /* AVB0_AVTP_PPS */ + RCAR_GP_PIN(7, 0), +}; +static const unsigned int avb0_avtp_pps_mux[] = { + AVB0_AVTP_PPS_MARK, +}; +static const unsigned int avb0_avtp_capture_pins[] = { + /* AVB0_AVTP_CAPTURE */ + RCAR_GP_PIN(7, 1), +}; +static const unsigned int avb0_avtp_capture_mux[] = { + AVB0_AVTP_CAPTURE_MARK, +}; +static const unsigned int avb0_avtp_match_pins[] = { + /* AVB0_AVTP_MATCH */ + RCAR_GP_PIN(7, 2), +}; +static const unsigned int avb0_avtp_match_mux[] = { + AVB0_AVTP_MATCH_MARK, +}; + +/* - AVB1 ------------------------------------------------ */ +static const unsigned int avb1_link_pins[] = { + /* AVB1_LINK */ + RCAR_GP_PIN(6, 4), +}; +static const unsigned int avb1_link_mux[] = { + AVB1_LINK_MARK, +}; +static const unsigned int avb1_magic_pins[] = { + /* AVB1_MAGIC */ + RCAR_GP_PIN(6, 1), +}; +static const unsigned int avb1_magic_mux[] = { + AVB1_MAGIC_MARK, +}; +static const unsigned int avb1_phy_int_pins[] = { + /* AVB1_PHY_INT */ + RCAR_GP_PIN(6, 3), +}; +static const unsigned int avb1_phy_int_mux[] = { + AVB1_PHY_INT_MARK, +}; +static const unsigned int avb1_mdio_pins[] = { + /* AVB1_MDC, AVB1_MDIO */ + RCAR_GP_PIN(6, 2), RCAR_GP_PIN(6, 0), +}; +static const unsigned int avb1_mdio_mux[] = { + AVB1_MDC_MARK, AVB1_MDIO_MARK, +}; +static const unsigned int avb1_rgmii_pins[] = { + /* + * AVB1_TX_CTL, AVB1_TXC, AVB1_TD0, AVB1_TD1, AVB1_TD2, AVB1_TD3, + * AVB1_RX_CTL, AVB1_RXC, AVB1_RD0, AVB1_RD1, AVB1_RD2, AVB1_RD3, + */ + RCAR_GP_PIN(6, 7), RCAR_GP_PIN(6, 6), + RCAR_GP_PIN(6, 13), RCAR_GP_PIN(6, 12), + RCAR_GP_PIN(6, 16), RCAR_GP_PIN(6, 18), + RCAR_GP_PIN(6, 9), RCAR_GP_PIN(6, 8), + RCAR_GP_PIN(6, 15), RCAR_GP_PIN(6, 14), + RCAR_GP_PIN(6, 17), RCAR_GP_PIN(6, 19), +}; +static const unsigned int avb1_rgmii_mux[] = { + AVB1_TX_CTL_MARK, AVB1_TXC_MARK, + AVB1_TD0_MARK, AVB1_TD1_MARK, + AVB1_TD2_MARK, AVB1_TD3_MARK, + AVB1_RX_CTL_MARK, AVB1_RXC_MARK, + AVB1_RD0_MARK, AVB1_RD1_MARK, + AVB1_RD2_MARK, AVB1_RD3_MARK, +}; +static const unsigned int avb1_txcrefclk_pins[] = { + /* AVB1_TXCREFCLK */ + RCAR_GP_PIN(6, 20), +}; +static const unsigned int avb1_txcrefclk_mux[] = { + AVB1_TXCREFCLK_MARK, +}; +static const unsigned int avb1_avtp_pps_pins[] = { + /* AVB1_AVTP_PPS */ + RCAR_GP_PIN(6, 10), +}; +static const unsigned int avb1_avtp_pps_mux[] = { + AVB1_AVTP_PPS_MARK, +}; +static const unsigned int avb1_avtp_capture_pins[] = { + /* AVB1_AVTP_CAPTURE */ + RCAR_GP_PIN(6, 11), +}; +static const unsigned int avb1_avtp_capture_mux[] = { + AVB1_AVTP_CAPTURE_MARK, +}; +static const unsigned int avb1_avtp_match_pins[] = { + /* AVB1_AVTP_MATCH */ + RCAR_GP_PIN(6, 5), +}; +static const unsigned int avb1_avtp_match_mux[] = { + AVB1_AVTP_MATCH_MARK, +}; + +/* - AVB2 ------------------------------------------------ */ +static const unsigned int avb2_link_pins[] = { + /* AVB2_LINK */ + RCAR_GP_PIN(5, 3), +}; +static const unsigned int avb2_link_mux[] = { + AVB2_LINK_MARK, +}; +static const unsigned int avb2_magic_pins[] = { + /* AVB2_MAGIC */ + RCAR_GP_PIN(5, 5), +}; +static const unsigned int avb2_magic_mux[] = { + AVB2_MAGIC_MARK, +}; +static const unsigned int avb2_phy_int_pins[] = { + /* AVB2_PHY_INT */ + RCAR_GP_PIN(5, 4), +}; +static const unsigned int avb2_phy_int_mux[] = { + AVB2_PHY_INT_MARK, +}; +static const unsigned int avb2_mdio_pins[] = { + /* AVB2_MDC, AVB2_MDIO */ + RCAR_GP_PIN(5, 6), RCAR_GP_PIN(5, 10), +}; +static const unsigned int avb2_mdio_mux[] = { + AVB2_MDC_MARK, AVB2_MDIO_MARK, +}; +static const unsigned int avb2_rgmii_pins[] = { + /* + * AVB2_TX_CTL, AVB2_TXC, AVB2_TD0, AVB2_TD1, AVB2_TD2, AVB2_TD3, + * AVB2_RX_CTL, AVB2_RXC, AVB2_RD0, AVB2_RD1, AVB2_RD2, AVB2_RD3, + */ + RCAR_GP_PIN(5, 19), RCAR_GP_PIN(5, 16), + RCAR_GP_PIN(5, 15), RCAR_GP_PIN(5, 12), + RCAR_GP_PIN(5, 11), RCAR_GP_PIN(5, 8), + RCAR_GP_PIN(5, 20), RCAR_GP_PIN(5, 18), + RCAR_GP_PIN(5, 17), RCAR_GP_PIN(5, 14), + RCAR_GP_PIN(5, 13), RCAR_GP_PIN(5, 9), +}; +static const unsigned int avb2_rgmii_mux[] = { + AVB2_TX_CTL_MARK, AVB2_TXC_MARK, + AVB2_TD0_MARK, AVB2_TD1_MARK, + AVB2_TD2_MARK, AVB2_TD3_MARK, + AVB2_RX_CTL_MARK, AVB2_RXC_MARK, + AVB2_RD0_MARK, AVB2_RD1_MARK, + AVB2_RD2_MARK, AVB2_RD3_MARK, +}; +static const unsigned int avb2_txcrefclk_pins[] = { + /* AVB2_TXCREFCLK */ + RCAR_GP_PIN(5, 7), +}; +static const unsigned int avb2_txcrefclk_mux[] = { + AVB2_TXCREFCLK_MARK, +}; +static const unsigned int avb2_avtp_pps_pins[] = { + /* AVB2_AVTP_PPS */ + RCAR_GP_PIN(5, 0), +}; +static const unsigned int avb2_avtp_pps_mux[] = { + AVB2_AVTP_PPS_MARK, +}; +static const unsigned int avb2_avtp_capture_pins[] = { + /* AVB2_AVTP_CAPTURE */ + RCAR_GP_PIN(5, 1), +}; +static const unsigned int avb2_avtp_capture_mux[] = { + AVB2_AVTP_CAPTURE_MARK, +}; +static const unsigned int avb2_avtp_match_pins[] = { + /* AVB2_AVTP_MATCH */ + RCAR_GP_PIN(5, 2), +}; +static const unsigned int avb2_avtp_match_mux[] = { + AVB2_AVTP_MATCH_MARK, +}; + +/* - CANFD0 ----------------------------------------------------------------- */ +static const unsigned int canfd0_data_pins[] = { + /* CANFD0_TX, CANFD0_RX */ + RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11), +}; +static const unsigned int canfd0_data_mux[] = { + CANFD0_TX_MARK, CANFD0_RX_MARK, +}; + +/* - CANFD1 ----------------------------------------------------------------- */ +static const unsigned int canfd1_data_pins[] = { + /* CANFD1_TX, CANFD1_RX */ + RCAR_GP_PIN(2, 17), RCAR_GP_PIN(2, 19), +}; +static const unsigned int canfd1_data_mux[] = { + CANFD1_TX_MARK, CANFD1_RX_MARK, +}; + +/* - CANFD2 ----------------------------------------------------------------- */ +static const unsigned int canfd2_data_pins[] = { + /* CANFD2_TX, CANFD2_RX */ + RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13), +}; +static const unsigned int canfd2_data_mux[] = { + CANFD2_TX_MARK, CANFD2_RX_MARK, +}; + +/* - CANFD3 ----------------------------------------------------------------- */ +static const unsigned int canfd3_data_pins[] = { + /* CANFD3_TX, CANFD3_RX */ + RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 15), +}; +static const unsigned int canfd3_data_mux[] = { + CANFD3_TX_MARK, CANFD3_RX_MARK, +}; + +/* - CANFD Clock ------------------------------------------------------------ */ +static const unsigned int can_clk_pins[] = { + /* CAN_CLK */ + RCAR_GP_PIN(2, 9), +}; +static const unsigned int can_clk_mux[] = { + CAN_CLK_MARK, +}; + +/* - HSCIF0 ----------------------------------------------------------------- */ +static const unsigned int hscif0_data_pins[] = { + /* HRX0, HTX0 */ + RCAR_GP_PIN(1, 16), RCAR_GP_PIN(1, 12), +}; +static const unsigned int hscif0_data_mux[] = { + HRX0_MARK, HTX0_MARK, +}; +static const unsigned int hscif0_clk_pins[] = { + /* HSCK0 */ + RCAR_GP_PIN(1, 15), +}; +static const unsigned int hscif0_clk_mux[] = { + HSCK0_MARK, +}; +static const unsigned int hscif0_ctrl_pins[] = { + /* HRTS0_N, HCTS0_N */ + RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 13), +}; +static const unsigned int hscif0_ctrl_mux[] = { + HRTS0_N_MARK, HCTS0_N_MARK, +}; + +/* - HSCIF1_A ----------------------------------------------------------------- */ +static const unsigned int hscif1_data_a_pins[] = { + /* HRX1_A, HTX1_A */ + RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 14), +}; +static const unsigned int hscif1_data_a_mux[] = { + HRX1_A_MARK, HTX1_A_MARK, +}; +static const unsigned int hscif1_clk_a_pins[] = { + /* HSCK1_A */ + RCAR_GP_PIN(0, 18), +}; +static const unsigned int hscif1_clk_a_mux[] = { + HSCK1_A_MARK, +}; +static const unsigned int hscif1_ctrl_a_pins[] = { + /* HRTS1_N_A, HCTS1_N_A */ + RCAR_GP_PIN(0, 17), RCAR_GP_PIN(0, 16), +}; +static const unsigned int hscif1_ctrl_a_mux[] = { + HRTS1_N_A_MARK, HCTS1_N_A_MARK, +}; + +/* - HSCIF1_B ---------------------------------------------------------------- */ +static const unsigned int hscif1_data_b_pins[] = { + /* HRX1_B, HTX1_B */ + RCAR_GP_PIN(1, 7), RCAR_GP_PIN(1, 6), +}; +static const unsigned int hscif1_data_b_mux[] = { + HRX1_B_MARK, HTX1_B_MARK, +}; +static const unsigned int hscif1_clk_b_pins[] = { + /* HSCK1_B */ + RCAR_GP_PIN(1, 10), +}; +static const unsigned int hscif1_clk_b_mux[] = { + HSCK1_B_MARK, +}; +static const unsigned int hscif1_ctrl_b_pins[] = { + /* HRTS1_N_B, HCTS1_N_B */ + RCAR_GP_PIN(1, 9), RCAR_GP_PIN(1, 8), +}; +static const unsigned int hscif1_ctrl_b_mux[] = { + HRTS1_N_B_MARK, HCTS1_N_B_MARK, +}; + +/* - HSCIF2 ----------------------------------------------------------------- */ +static const unsigned int hscif2_data_pins[] = { + /* HRX2, HTX2 */ + RCAR_GP_PIN(4, 8), RCAR_GP_PIN(4, 9), +}; +static const unsigned int hscif2_data_mux[] = { + HRX2_MARK, HTX2_MARK, +}; +static const unsigned int hscif2_clk_pins[] = { + /* HSCK2 */ + RCAR_GP_PIN(4, 13), +}; +static const unsigned int hscif2_clk_mux[] = { + HSCK2_MARK, +}; +static const unsigned int hscif2_ctrl_pins[] = { + /* HRTS2_N, HCTS2_N */ + RCAR_GP_PIN(4, 10), RCAR_GP_PIN(4, 12), +}; +static const unsigned int hscif2_ctrl_mux[] = { + HRTS2_N_MARK, HCTS2_N_MARK, +}; + +/* - HSCIF3_A ----------------------------------------------------------------- */ +static const unsigned int hscif3_data_a_pins[] = { + /* HRX3_A, HTX3_A */ + RCAR_GP_PIN(1, 24), RCAR_GP_PIN(1, 28), +}; +static const unsigned int hscif3_data_a_mux[] = { + HRX3_A_MARK, HTX3_A_MARK, +}; +static const unsigned int hscif3_clk_a_pins[] = { + /* HSCK3_A */ + RCAR_GP_PIN(1, 25), +}; +static const unsigned int hscif3_clk_a_mux[] = { + HSCK3_A_MARK, +}; +static const unsigned int hscif3_ctrl_a_pins[] = { + /* HRTS3_N_A, HCTS3_N_A */ + RCAR_GP_PIN(1, 26), RCAR_GP_PIN(1, 27), +}; +static const unsigned int hscif3_ctrl_a_mux[] = { + HRTS3_N_A_MARK, HCTS3_N_A_MARK, +}; + +/* - HSCIF3_B ----------------------------------------------------------------- */ +static const unsigned int hscif3_data_b_pins[] = { + /* HRX3_B, HTX3_B */ + RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 0), +}; +static const unsigned int hscif3_data_b_mux[] = { + HRX3_B_MARK, HTX3_B_MARK, +}; +static const unsigned int hscif3_clk_b_pins[] = { + /* HSCK3_B */ + RCAR_GP_PIN(1, 3), +}; +static const unsigned int hscif3_clk_b_mux[] = { + HSCK3_B_MARK, +}; +static const unsigned int hscif3_ctrl_b_pins[] = { + /* HRTS3_N_B, HCTS3_N_B */ + RCAR_GP_PIN(1, 2), RCAR_GP_PIN(1, 1), +}; +static const unsigned int hscif3_ctrl_b_mux[] = { + HRTS3_N_B_MARK, HCTS3_N_B_MARK, +}; + +/* - I2C0 ------------------------------------------------------------------- */ +static const unsigned int i2c0_pins[] = { + /* SDA0, SCL0 */ + RCAR_GP_PIN(4, 1), RCAR_GP_PIN(4, 0), +}; +static const unsigned int i2c0_mux[] = { + SDA0_MARK, SCL0_MARK, +}; + +/* - I2C1 ------------------------------------------------------------------- */ +static const unsigned int i2c1_pins[] = { + /* SDA1, SCL1 */ + RCAR_GP_PIN(4, 3), RCAR_GP_PIN(4, 2), +}; +static const unsigned int i2c1_mux[] = { + SDA1_MARK, SCL1_MARK, +}; + +/* - I2C2 ------------------------------------------------------------------- */ +static const unsigned int i2c2_pins[] = { + /* SDA2, SCL2 */ + RCAR_GP_PIN(4, 5), RCAR_GP_PIN(4, 4), +}; +static const unsigned int i2c2_mux[] = { + SDA2_MARK, SCL2_MARK, +}; + +/* - I2C3 ------------------------------------------------------------------- */ +static const unsigned int i2c3_pins[] = { + /* SDA3, SCL3 */ + RCAR_GP_PIN(4, 7), RCAR_GP_PIN(4, 6), +}; +static const unsigned int i2c3_mux[] = { + SDA3_MARK, SCL3_MARK, +}; + +/* - MMC -------------------------------------------------------------------- */ +static const unsigned int mmc_data_pins[] = { + /* MMC_SD_D[0:3], MMC_D[4:7] */ + RCAR_GP_PIN(3, 1), RCAR_GP_PIN(3, 0), + RCAR_GP_PIN(3, 2), RCAR_GP_PIN(3, 5), + RCAR_GP_PIN(3, 7), RCAR_GP_PIN(3, 6), + RCAR_GP_PIN(3, 9), RCAR_GP_PIN(3, 8), +}; +static const unsigned int mmc_data_mux[] = { + MMC_SD_D0_MARK, MMC_SD_D1_MARK, + MMC_SD_D2_MARK, MMC_SD_D3_MARK, + MMC_D4_MARK, MMC_D5_MARK, + MMC_D6_MARK, MMC_D7_MARK, +}; +static const unsigned int mmc_ctrl_pins[] = { + /* MMC_SD_CLK, MMC_SD_CMD */ + RCAR_GP_PIN(3, 3), RCAR_GP_PIN(3, 10), +}; +static const unsigned int mmc_ctrl_mux[] = { + MMC_SD_CLK_MARK, MMC_SD_CMD_MARK, +}; +static const unsigned int mmc_cd_pins[] = { + /* SD_CD */ + RCAR_GP_PIN(3, 11), +}; +static const unsigned int mmc_cd_mux[] = { + SD_CD_MARK, +}; +static const unsigned int mmc_wp_pins[] = { + /* SD_WP */ + RCAR_GP_PIN(3, 12), +}; +static const unsigned int mmc_wp_mux[] = { + SD_WP_MARK, +}; +static const unsigned int mmc_ds_pins[] = { + /* MMC_DS */ + RCAR_GP_PIN(3, 4), +}; +static const unsigned int mmc_ds_mux[] = { + MMC_DS_MARK, +}; + +/* - MSIOF0 ----------------------------------------------------------------- */ +static const unsigned int msiof0_clk_pins[] = { + /* MSIOF0_SCK */ + RCAR_GP_PIN(1, 10), +}; +static const unsigned int msiof0_clk_mux[] = { + MSIOF0_SCK_MARK, +}; +static const unsigned int msiof0_sync_pins[] = { + /* MSIOF0_SYNC */ + RCAR_GP_PIN(1, 8), +}; +static const unsigned int msiof0_sync_mux[] = { + MSIOF0_SYNC_MARK, +}; +static const unsigned int msiof0_ss1_pins[] = { + /* MSIOF0_SS1 */ + RCAR_GP_PIN(1, 7), +}; +static const unsigned int msiof0_ss1_mux[] = { + MSIOF0_SS1_MARK, +}; +static const unsigned int msiof0_ss2_pins[] = { + /* MSIOF0_SS2 */ + RCAR_GP_PIN(1, 6), +}; +static const unsigned int msiof0_ss2_mux[] = { + MSIOF0_SS2_MARK, +}; +static const unsigned int msiof0_txd_pins[] = { + /* MSIOF0_TXD */ + RCAR_GP_PIN(1, 9), +}; +static const unsigned int msiof0_txd_mux[] = { + MSIOF0_TXD_MARK, +}; +static const unsigned int msiof0_rxd_pins[] = { + /* MSIOF0_RXD */ + RCAR_GP_PIN(1, 11), +}; +static const unsigned int msiof0_rxd_mux[] = { + MSIOF0_RXD_MARK, +}; + +/* - MSIOF1 ----------------------------------------------------------------- */ +static const unsigned int msiof1_clk_pins[] = { + /* MSIOF1_SCK */ + RCAR_GP_PIN(1, 3), +}; +static const unsigned int msiof1_clk_mux[] = { + MSIOF1_SCK_MARK, +}; +static const unsigned int msiof1_sync_pins[] = { + /* MSIOF1_SYNC */ + RCAR_GP_PIN(1, 2), +}; +static const unsigned int msiof1_sync_mux[] = { + MSIOF1_SYNC_MARK, +}; +static const unsigned int msiof1_ss1_pins[] = { + /* MSIOF1_SS1 */ + RCAR_GP_PIN(1, 1), +}; +static const unsigned int msiof1_ss1_mux[] = { + MSIOF1_SS1_MARK, +}; +static const unsigned int msiof1_ss2_pins[] = { + /* MSIOF1_SS2 */ + RCAR_GP_PIN(1, 0), +}; +static const unsigned int msiof1_ss2_mux[] = { + MSIOF1_SS2_MARK, +}; +static const unsigned int msiof1_txd_pins[] = { + /* MSIOF1_TXD */ + RCAR_GP_PIN(1, 4), +}; +static const unsigned int msiof1_txd_mux[] = { + MSIOF1_TXD_MARK, +}; +static const unsigned int msiof1_rxd_pins[] = { + /* MSIOF1_RXD */ + RCAR_GP_PIN(1, 5), +}; +static const unsigned int msiof1_rxd_mux[] = { + MSIOF1_RXD_MARK, +}; + +/* - MSIOF2 ----------------------------------------------------------------- */ +static const unsigned int msiof2_clk_pins[] = { + /* MSIOF2_SCK */ + RCAR_GP_PIN(0, 17), +}; +static const unsigned int msiof2_clk_mux[] = { + MSIOF2_SCK_MARK, +}; +static const unsigned int msiof2_sync_pins[] = { + /* MSIOF2_SYNC */ + RCAR_GP_PIN(0, 15), +}; +static const unsigned int msiof2_sync_mux[] = { + MSIOF2_SYNC_MARK, +}; +static const unsigned int msiof2_ss1_pins[] = { + /* MSIOF2_SS1 */ + RCAR_GP_PIN(0, 14), +}; +static const unsigned int msiof2_ss1_mux[] = { + MSIOF2_SS1_MARK, +}; +static const unsigned int msiof2_ss2_pins[] = { + /* MSIOF2_SS2 */ + RCAR_GP_PIN(0, 13), +}; +static const unsigned int msiof2_ss2_mux[] = { + MSIOF2_SS2_MARK, +}; +static const unsigned int msiof2_txd_pins[] = { + /* MSIOF2_TXD */ + RCAR_GP_PIN(0, 16), +}; +static const unsigned int msiof2_txd_mux[] = { + MSIOF2_TXD_MARK, +}; +static const unsigned int msiof2_rxd_pins[] = { + /* MSIOF2_RXD */ + RCAR_GP_PIN(0, 18), +}; +static const unsigned int msiof2_rxd_mux[] = { + MSIOF2_RXD_MARK, +}; + +/* - MSIOF3 ----------------------------------------------------------------- */ +static const unsigned int msiof3_clk_pins[] = { + /* MSIOF3_SCK */ + RCAR_GP_PIN(0, 3), +}; +static const unsigned int msiof3_clk_mux[] = { + MSIOF3_SCK_MARK, +}; +static const unsigned int msiof3_sync_pins[] = { + /* MSIOF3_SYNC */ + RCAR_GP_PIN(0, 6), +}; +static const unsigned int msiof3_sync_mux[] = { + MSIOF3_SYNC_MARK, +}; +static const unsigned int msiof3_ss1_pins[] = { + /* MSIOF3_SS1 */ + RCAR_GP_PIN(0, 1), +}; +static const unsigned int msiof3_ss1_mux[] = { + MSIOF3_SS1_MARK, +}; +static const unsigned int msiof3_ss2_pins[] = { + /* MSIOF3_SS2 */ + RCAR_GP_PIN(0, 2), +}; +static const unsigned int msiof3_ss2_mux[] = { + MSIOF3_SS2_MARK, +}; +static const unsigned int msiof3_txd_pins[] = { + /* MSIOF3_TXD */ + RCAR_GP_PIN(0, 4), +}; +static const unsigned int msiof3_txd_mux[] = { + MSIOF3_TXD_MARK, +}; +static const unsigned int msiof3_rxd_pins[] = { + /* MSIOF3_RXD */ + RCAR_GP_PIN(0, 5), +}; +static const unsigned int msiof3_rxd_mux[] = { + MSIOF3_RXD_MARK, +}; + +/* - MSIOF4 ----------------------------------------------------------------- */ +static const unsigned int msiof4_clk_pins[] = { + /* MSIOF4_SCK */ + RCAR_GP_PIN(1, 25), +}; +static const unsigned int msiof4_clk_mux[] = { + MSIOF4_SCK_MARK, +}; +static const unsigned int msiof4_sync_pins[] = { + /* MSIOF4_SYNC */ + RCAR_GP_PIN(1, 28), +}; +static const unsigned int msiof4_sync_mux[] = { + MSIOF4_SYNC_MARK, +}; +static const unsigned int msiof4_ss1_pins[] = { + /* MSIOF4_SS1 */ + RCAR_GP_PIN(1, 23), +}; +static const unsigned int msiof4_ss1_mux[] = { + MSIOF4_SS1_MARK, +}; +static const unsigned int msiof4_ss2_pins[] = { + /* MSIOF4_SS2 */ + RCAR_GP_PIN(1, 24), +}; +static const unsigned int msiof4_ss2_mux[] = { + MSIOF4_SS2_MARK, +}; +static const unsigned int msiof4_txd_pins[] = { + /* MSIOF4_TXD */ + RCAR_GP_PIN(1, 26), +}; +static const unsigned int msiof4_txd_mux[] = { + MSIOF4_TXD_MARK, +}; +static const unsigned int msiof4_rxd_pins[] = { + /* MSIOF4_RXD */ + RCAR_GP_PIN(1, 27), +}; +static const unsigned int msiof4_rxd_mux[] = { + MSIOF4_RXD_MARK, +}; + +/* - MSIOF5 ----------------------------------------------------------------- */ +static const unsigned int msiof5_clk_pins[] = { + /* MSIOF5_SCK */ + RCAR_GP_PIN(0, 11), +}; +static const unsigned int msiof5_clk_mux[] = { + MSIOF5_SCK_MARK, +}; +static const unsigned int msiof5_sync_pins[] = { + /* MSIOF5_SYNC */ + RCAR_GP_PIN(0, 9), +}; +static const unsigned int msiof5_sync_mux[] = { + MSIOF5_SYNC_MARK, +}; +static const unsigned int msiof5_ss1_pins[] = { + /* MSIOF5_SS1 */ + RCAR_GP_PIN(0, 8), +}; +static const unsigned int msiof5_ss1_mux[] = { + MSIOF5_SS1_MARK, +}; +static const unsigned int msiof5_ss2_pins[] = { + /* MSIOF5_SS2 */ + RCAR_GP_PIN(0, 7), +}; +static const unsigned int msiof5_ss2_mux[] = { + MSIOF5_SS2_MARK, +}; +static const unsigned int msiof5_txd_pins[] = { + /* MSIOF5_TXD */ + RCAR_GP_PIN(0, 10), +}; +static const unsigned int msiof5_txd_mux[] = { + MSIOF5_TXD_MARK, +}; +static const unsigned int msiof5_rxd_pins[] = { + /* MSIOF5_RXD */ + RCAR_GP_PIN(0, 12), +}; +static const unsigned int msiof5_rxd_mux[] = { + MSIOF5_RXD_MARK, +}; + +/* - PCIE ------------------------------------------------------------------- */ +static const unsigned int pcie0_clkreq_n_pins[] = { + /* PCIE0_CLKREQ_N */ + RCAR_GP_PIN(4, 21), +}; + +static const unsigned int pcie0_clkreq_n_mux[] = { + PCIE0_CLKREQ_N_MARK, +}; + +/* - PWM0_A ------------------------------------------------------------------- */ +static const unsigned int pwm0_a_pins[] = { + /* PWM0_A */ + RCAR_GP_PIN(1, 15), +}; +static const unsigned int pwm0_a_mux[] = { + PWM0_A_MARK, +}; + +/* - PWM0_B ------------------------------------------------------------------- */ +static const unsigned int pwm0_b_pins[] = { + /* PWM0_B */ + RCAR_GP_PIN(1, 14), +}; +static const unsigned int pwm0_b_mux[] = { + PWM0_B_MARK, +}; + +/* - PWM1_A ------------------------------------------------------------------- */ +static const unsigned int pwm1_a_pins[] = { + /* PWM1_A */ + RCAR_GP_PIN(3, 13), +}; +static const unsigned int pwm1_a_mux[] = { + PWM1_A_MARK, +}; + +/* - PWM1_B ------------------------------------------------------------------- */ +static const unsigned int pwm1_b_pins[] = { + /* PWM1_B */ + RCAR_GP_PIN(2, 13), +}; +static const unsigned int pwm1_b_mux[] = { + PWM1_B_MARK, +}; + +/* - PWM1_C ------------------------------------------------------------------- */ +static const unsigned int pwm1_c_pins[] = { + /* PWM1_C */ + RCAR_GP_PIN(2, 17), +}; +static const unsigned int pwm1_c_mux[] = { + PWM1_C_MARK, +}; + +/* - PWM2_A ------------------------------------------------------------------- */ +static const unsigned int pwm2_a_pins[] = { + /* PWM2_A */ + RCAR_GP_PIN(3, 14), +}; +static const unsigned int pwm2_a_mux[] = { + PWM2_A_MARK, +}; + +/* - PWM2_B ------------------------------------------------------------------- */ +static const unsigned int pwm2_b_pins[] = { + /* PWM2_B */ + RCAR_GP_PIN(2, 14), +}; +static const unsigned int pwm2_b_mux[] = { + PWM2_B_MARK, +}; + +/* - PWM2_C ------------------------------------------------------------------- */ +static const unsigned int pwm2_c_pins[] = { + /* PWM2_C */ + RCAR_GP_PIN(2, 19), +}; +static const unsigned int pwm2_c_mux[] = { + PWM2_C_MARK, +}; + +/* - PWM3_A ------------------------------------------------------------------- */ +static const unsigned int pwm3_a_pins[] = { + /* PWM3_A */ + RCAR_GP_PIN(4, 14), +}; +static const unsigned int pwm3_a_mux[] = { + PWM3_A_MARK, +}; + +/* - PWM3_B ------------------------------------------------------------------- */ +static const unsigned int pwm3_b_pins[] = { + /* PWM3_B */ + RCAR_GP_PIN(2, 15), +}; +static const unsigned int pwm3_b_mux[] = { + PWM3_B_MARK, +}; + +/* - PWM3_C ------------------------------------------------------------------- */ +static const unsigned int pwm3_c_pins[] = { + /* PWM3_C */ + RCAR_GP_PIN(1, 22), +}; +static const unsigned int pwm3_c_mux[] = { + PWM3_C_MARK, +}; + +/* - PWM4 ------------------------------------------------------------------- */ +static const unsigned int pwm4_pins[] = { + /* PWM4 */ + RCAR_GP_PIN(4, 15), +}; +static const unsigned int pwm4_mux[] = { + PWM4_MARK, +}; + +/* - QSPI0 ------------------------------------------------------------------ */ +static const unsigned int qspi0_ctrl_pins[] = { + /* SPCLK, SSL */ + RCAR_GP_PIN(3, 20), RCAR_GP_PIN(3, 15), +}; +static const unsigned int qspi0_ctrl_mux[] = { + QSPI0_SPCLK_MARK, QSPI0_SSL_MARK, +}; +static const unsigned int qspi0_data_pins[] = { + /* MOSI_IO0, MISO_IO1, IO2, IO3 */ + RCAR_GP_PIN(3, 19), RCAR_GP_PIN(3, 18), + RCAR_GP_PIN(3, 17), RCAR_GP_PIN(3, 16), +}; +static const unsigned int qspi0_data_mux[] = { + QSPI0_MOSI_IO0_MARK, QSPI0_MISO_IO1_MARK, + QSPI0_IO2_MARK, QSPI0_IO3_MARK +}; + +/* - QSPI1 ------------------------------------------------------------------ */ +static const unsigned int qspi1_ctrl_pins[] = { + /* SPCLK, SSL */ + RCAR_GP_PIN(3, 22), RCAR_GP_PIN(3, 25), +}; +static const unsigned int qspi1_ctrl_mux[] = { + QSPI1_SPCLK_MARK, QSPI1_SSL_MARK, +}; +static const unsigned int qspi1_data_pins[] = { + /* MOSI_IO0, MISO_IO1, IO2, IO3 */ + RCAR_GP_PIN(3, 21), RCAR_GP_PIN(3, 23), + RCAR_GP_PIN(3, 24), RCAR_GP_PIN(3, 26), +}; +static const unsigned int qspi1_data_mux[] = { + QSPI1_MOSI_IO0_MARK, QSPI1_MISO_IO1_MARK, + QSPI1_IO2_MARK, QSPI1_IO3_MARK +}; + +/* - SCIF0 ------------------------------------------------------------------ */ +static const unsigned int scif0_data_pins[] = { + /* RX0, TX0 */ + RCAR_GP_PIN(1, 16), RCAR_GP_PIN(1, 12), +}; +static const unsigned int scif0_data_mux[] = { + RX0_MARK, TX0_MARK, +}; +static const unsigned int scif0_clk_pins[] = { + /* SCK0 */ + RCAR_GP_PIN(1, 15), +}; +static const unsigned int scif0_clk_mux[] = { + SCK0_MARK, +}; +static const unsigned int scif0_ctrl_pins[] = { + /* RTS0_N, CTS0_N */ + RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 13), +}; +static const unsigned int scif0_ctrl_mux[] = { + RTS0_N_MARK, CTS0_N_MARK, +}; + +/* - SCIF1_A ------------------------------------------------------------------ */ +static const unsigned int scif1_data_a_pins[] = { + /* RX1_A, TX1_A */ + RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 14), +}; +static const unsigned int scif1_data_a_mux[] = { + RX1_A_MARK, TX1_A_MARK, +}; +static const unsigned int scif1_clk_a_pins[] = { + /* SCK1_A */ + RCAR_GP_PIN(0, 18), +}; +static const unsigned int scif1_clk_a_mux[] = { + SCK1_A_MARK, +}; +static const unsigned int scif1_ctrl_a_pins[] = { + /* RTS1_N_A, CTS1_N_A */ + RCAR_GP_PIN(0, 17), RCAR_GP_PIN(0, 16), +}; +static const unsigned int scif1_ctrl_a_mux[] = { + RTS1_N_A_MARK, CTS1_N_A_MARK, +}; + +/* - SCIF1_B ------------------------------------------------------------------ */ +static const unsigned int scif1_data_b_pins[] = { + /* RX1_B, TX1_B */ + RCAR_GP_PIN(1, 7), RCAR_GP_PIN(1, 6), +}; +static const unsigned int scif1_data_b_mux[] = { + RX1_B_MARK, TX1_B_MARK, +}; +static const unsigned int scif1_clk_b_pins[] = { + /* SCK1_B */ + RCAR_GP_PIN(1, 10), +}; +static const unsigned int scif1_clk_b_mux[] = { + SCK1_B_MARK, +}; +static const unsigned int scif1_ctrl_b_pins[] = { + /* RTS1_N_B, CTS1_N_B */ + RCAR_GP_PIN(1, 9), RCAR_GP_PIN(1, 8), +}; +static const unsigned int scif1_ctrl_b_mux[] = { + RTS1_N_B_MARK, CTS1_N_B_MARK, +}; + +/* - SCIF3_A ------------------------------------------------------------------ */ +static const unsigned int scif3_data_a_pins[] = { + /* RX3_A, TX3_A */ + RCAR_GP_PIN(1, 27), RCAR_GP_PIN(1, 28), +}; +static const unsigned int scif3_data_a_mux[] = { + RX3_A_MARK, TX3_A_MARK, +}; +static const unsigned int scif3_clk_a_pins[] = { + /* SCK3_A */ + RCAR_GP_PIN(1, 24), +}; +static const unsigned int scif3_clk_a_mux[] = { + SCK3_A_MARK, +}; +static const unsigned int scif3_ctrl_a_pins[] = { + /* RTS3_N_A, CTS3_N_A */ + RCAR_GP_PIN(1, 26), RCAR_GP_PIN(1, 25), +}; +static const unsigned int scif3_ctrl_a_mux[] = { + RTS3_N_A_MARK, CTS3_N_A_MARK, +}; + +/* - SCIF3_B ------------------------------------------------------------------ */ +static const unsigned int scif3_data_b_pins[] = { + /* RX3_B, TX3_B */ + RCAR_GP_PIN(1, 1), RCAR_GP_PIN(1, 0), +}; +static const unsigned int scif3_data_b_mux[] = { + RX3_B_MARK, TX3_B_MARK, +}; +static const unsigned int scif3_clk_b_pins[] = { + /* SCK3_B */ + RCAR_GP_PIN(1, 4), +}; +static const unsigned int scif3_clk_b_mux[] = { + SCK3_B_MARK, +}; +static const unsigned int scif3_ctrl_b_pins[] = { + /* RTS3_N_B, CTS3_N_B */ + RCAR_GP_PIN(1, 2), RCAR_GP_PIN(1, 3), +}; +static const unsigned int scif3_ctrl_b_mux[] = { + RTS3_N_B_MARK, CTS3_N_B_MARK, +}; + +/* - SCIF4 ------------------------------------------------------------------ */ +static const unsigned int scif4_data_pins[] = { + /* RX4, TX4 */ + RCAR_GP_PIN(4, 13), RCAR_GP_PIN(4, 12), +}; +static const unsigned int scif4_data_mux[] = { + RX4_MARK, TX4_MARK, +}; +static const unsigned int scif4_clk_pins[] = { + /* SCK4 */ + RCAR_GP_PIN(4, 8), +}; +static const unsigned int scif4_clk_mux[] = { + SCK4_MARK, +}; +static const unsigned int scif4_ctrl_pins[] = { + /* RTS4_N, CTS4_N */ + RCAR_GP_PIN(4, 10), RCAR_GP_PIN(4, 9), +}; +static const unsigned int scif4_ctrl_mux[] = { + RTS4_N_MARK, CTS4_N_MARK, +}; + +/* - SCIF Clock ------------------------------------------------------------- */ +static const unsigned int scif_clk_pins[] = { + /* SCIF_CLK */ + RCAR_GP_PIN(1, 17), +}; +static const unsigned int scif_clk_mux[] = { + SCIF_CLK_MARK, +}; + +static const unsigned int scif_clk2_pins[] = { + /* SCIF_CLK2 */ + RCAR_GP_PIN(4, 11), +}; +static const unsigned int scif_clk2_mux[] = { + SCIF_CLK2_MARK, +}; + +/* - SSI ------------------------------------------------- */ +static const unsigned int ssi_data_pins[] = { + /* SSI_SD */ + RCAR_GP_PIN(1, 20), +}; +static const unsigned int ssi_data_mux[] = { + SSI_SD_MARK, +}; +static const unsigned int ssi_ctrl_pins[] = { + /* SSI_SCK, SSI_WS */ + RCAR_GP_PIN(1, 18), RCAR_GP_PIN(1, 19), +}; +static const unsigned int ssi_ctrl_mux[] = { + SSI_SCK_MARK, SSI_WS_MARK, +}; + +/* - TPU_A ------------------------------------------------------------------- */ +static const unsigned int tpu_to0_a_pins[] = { + /* TPU0TO0_A */ + RCAR_GP_PIN(2, 8), +}; +static const unsigned int tpu_to0_a_mux[] = { + TPU0TO0_A_MARK, +}; +static const unsigned int tpu_to1_a_pins[] = { + /* TPU0TO1_A */ + RCAR_GP_PIN(2, 7), +}; +static const unsigned int tpu_to1_a_mux[] = { + TPU0TO1_A_MARK, +}; +static const unsigned int tpu_to2_a_pins[] = { + /* TPU0TO2_A */ + RCAR_GP_PIN(2, 12), +}; +static const unsigned int tpu_to2_a_mux[] = { + TPU0TO2_A_MARK, +}; +static const unsigned int tpu_to3_a_pins[] = { + /* TPU0TO3_A */ + RCAR_GP_PIN(2, 13), +}; +static const unsigned int tpu_to3_a_mux[] = { + TPU0TO3_A_MARK, +}; + +/* - TPU_B ------------------------------------------------------------------- */ +static const unsigned int tpu_to0_b_pins[] = { + /* TPU0TO0_B */ + RCAR_GP_PIN(1, 25), +}; +static const unsigned int tpu_to0_b_mux[] = { + TPU0TO0_B_MARK, +}; +static const unsigned int tpu_to1_b_pins[] = { + /* TPU0TO1_B */ + RCAR_GP_PIN(1, 26), +}; +static const unsigned int tpu_to1_b_mux[] = { + TPU0TO1_B_MARK, +}; +static const unsigned int tpu_to2_b_pins[] = { + /* TPU0TO2_B */ + RCAR_GP_PIN(2, 0), +}; +static const unsigned int tpu_to2_b_mux[] = { + TPU0TO2_B_MARK, +}; +static const unsigned int tpu_to3_b_pins[] = { + /* TPU0TO3_B */ + RCAR_GP_PIN(2, 1), +}; +static const unsigned int tpu_to3_b_mux[] = { + TPU0TO3_B_MARK, +}; + +static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(audio_clkin), + SH_PFC_PIN_GROUP(audio_clkout), + + SH_PFC_PIN_GROUP(avb0_link), + SH_PFC_PIN_GROUP(avb0_magic), + SH_PFC_PIN_GROUP(avb0_phy_int), + SH_PFC_PIN_GROUP(avb0_mdio), + SH_PFC_PIN_GROUP(avb0_rgmii), + SH_PFC_PIN_GROUP(avb0_txcrefclk), + SH_PFC_PIN_GROUP(avb0_avtp_pps), + SH_PFC_PIN_GROUP(avb0_avtp_capture), + SH_PFC_PIN_GROUP(avb0_avtp_match), + + SH_PFC_PIN_GROUP(avb1_link), + SH_PFC_PIN_GROUP(avb1_magic), + SH_PFC_PIN_GROUP(avb1_phy_int), + SH_PFC_PIN_GROUP(avb1_mdio), + SH_PFC_PIN_GROUP(avb1_rgmii), + SH_PFC_PIN_GROUP(avb1_txcrefclk), + SH_PFC_PIN_GROUP(avb1_avtp_pps), + SH_PFC_PIN_GROUP(avb1_avtp_capture), + SH_PFC_PIN_GROUP(avb1_avtp_match), + + SH_PFC_PIN_GROUP(avb2_link), + SH_PFC_PIN_GROUP(avb2_magic), + SH_PFC_PIN_GROUP(avb2_phy_int), + SH_PFC_PIN_GROUP(avb2_mdio), + SH_PFC_PIN_GROUP(avb2_rgmii), + SH_PFC_PIN_GROUP(avb2_txcrefclk), + SH_PFC_PIN_GROUP(avb2_avtp_pps), + SH_PFC_PIN_GROUP(avb2_avtp_capture), + SH_PFC_PIN_GROUP(avb2_avtp_match), + + SH_PFC_PIN_GROUP(canfd0_data), + SH_PFC_PIN_GROUP(canfd1_data), + SH_PFC_PIN_GROUP(canfd2_data), + SH_PFC_PIN_GROUP(canfd3_data), + SH_PFC_PIN_GROUP(can_clk), + + SH_PFC_PIN_GROUP(hscif0_data), + SH_PFC_PIN_GROUP(hscif0_clk), + SH_PFC_PIN_GROUP(hscif0_ctrl), + SH_PFC_PIN_GROUP(hscif1_data_a), + SH_PFC_PIN_GROUP(hscif1_clk_a), + SH_PFC_PIN_GROUP(hscif1_ctrl_a), + SH_PFC_PIN_GROUP(hscif1_data_b), + SH_PFC_PIN_GROUP(hscif1_clk_b), + SH_PFC_PIN_GROUP(hscif1_ctrl_b), + SH_PFC_PIN_GROUP(hscif2_data), + SH_PFC_PIN_GROUP(hscif2_clk), + SH_PFC_PIN_GROUP(hscif2_ctrl), + SH_PFC_PIN_GROUP(hscif3_data_a), + SH_PFC_PIN_GROUP(hscif3_clk_a), + SH_PFC_PIN_GROUP(hscif3_ctrl_a), + SH_PFC_PIN_GROUP(hscif3_data_b), + SH_PFC_PIN_GROUP(hscif3_clk_b), + SH_PFC_PIN_GROUP(hscif3_ctrl_b), + + SH_PFC_PIN_GROUP(i2c0), + SH_PFC_PIN_GROUP(i2c1), + SH_PFC_PIN_GROUP(i2c2), + SH_PFC_PIN_GROUP(i2c3), + + BUS_DATA_PIN_GROUP(mmc_data, 1), + BUS_DATA_PIN_GROUP(mmc_data, 4), + BUS_DATA_PIN_GROUP(mmc_data, 8), + SH_PFC_PIN_GROUP(mmc_ctrl), + SH_PFC_PIN_GROUP(mmc_cd), + SH_PFC_PIN_GROUP(mmc_wp), + SH_PFC_PIN_GROUP(mmc_ds), + + SH_PFC_PIN_GROUP(msiof0_clk), + SH_PFC_PIN_GROUP(msiof0_sync), + SH_PFC_PIN_GROUP(msiof0_ss1), + SH_PFC_PIN_GROUP(msiof0_ss2), + SH_PFC_PIN_GROUP(msiof0_txd), + SH_PFC_PIN_GROUP(msiof0_rxd), + + SH_PFC_PIN_GROUP(msiof1_clk), + SH_PFC_PIN_GROUP(msiof1_sync), + SH_PFC_PIN_GROUP(msiof1_ss1), + SH_PFC_PIN_GROUP(msiof1_ss2), + SH_PFC_PIN_GROUP(msiof1_txd), + SH_PFC_PIN_GROUP(msiof1_rxd), + + SH_PFC_PIN_GROUP(msiof2_clk), + SH_PFC_PIN_GROUP(msiof2_sync), + SH_PFC_PIN_GROUP(msiof2_ss1), + SH_PFC_PIN_GROUP(msiof2_ss2), + SH_PFC_PIN_GROUP(msiof2_txd), + SH_PFC_PIN_GROUP(msiof2_rxd), + + SH_PFC_PIN_GROUP(msiof3_clk), + SH_PFC_PIN_GROUP(msiof3_sync), + SH_PFC_PIN_GROUP(msiof3_ss1), + SH_PFC_PIN_GROUP(msiof3_ss2), + SH_PFC_PIN_GROUP(msiof3_txd), + SH_PFC_PIN_GROUP(msiof3_rxd), + + SH_PFC_PIN_GROUP(msiof4_clk), + SH_PFC_PIN_GROUP(msiof4_sync), + SH_PFC_PIN_GROUP(msiof4_ss1), + SH_PFC_PIN_GROUP(msiof4_ss2), + SH_PFC_PIN_GROUP(msiof4_txd), + SH_PFC_PIN_GROUP(msiof4_rxd), + + SH_PFC_PIN_GROUP(msiof5_clk), + SH_PFC_PIN_GROUP(msiof5_sync), + SH_PFC_PIN_GROUP(msiof5_ss1), + SH_PFC_PIN_GROUP(msiof5_ss2), + SH_PFC_PIN_GROUP(msiof5_txd), + SH_PFC_PIN_GROUP(msiof5_rxd), + + SH_PFC_PIN_GROUP(pcie0_clkreq_n), + + SH_PFC_PIN_GROUP(pwm0_a), + SH_PFC_PIN_GROUP(pwm0_b), + SH_PFC_PIN_GROUP(pwm1_a), + SH_PFC_PIN_GROUP(pwm1_b), + SH_PFC_PIN_GROUP(pwm1_c), + SH_PFC_PIN_GROUP(pwm2_a), + SH_PFC_PIN_GROUP(pwm2_b), + SH_PFC_PIN_GROUP(pwm2_c), + SH_PFC_PIN_GROUP(pwm3_a), + SH_PFC_PIN_GROUP(pwm3_b), + SH_PFC_PIN_GROUP(pwm3_c), + SH_PFC_PIN_GROUP(pwm4), + + SH_PFC_PIN_GROUP(qspi0_ctrl), + BUS_DATA_PIN_GROUP(qspi0_data, 2), + BUS_DATA_PIN_GROUP(qspi0_data, 4), + SH_PFC_PIN_GROUP(qspi1_ctrl), + BUS_DATA_PIN_GROUP(qspi1_data, 2), + BUS_DATA_PIN_GROUP(qspi1_data, 4), + + SH_PFC_PIN_GROUP(scif0_data), + SH_PFC_PIN_GROUP(scif0_clk), + SH_PFC_PIN_GROUP(scif0_ctrl), + SH_PFC_PIN_GROUP(scif1_data_a), + SH_PFC_PIN_GROUP(scif1_clk_a), + SH_PFC_PIN_GROUP(scif1_ctrl_a), + SH_PFC_PIN_GROUP(scif1_data_b), + SH_PFC_PIN_GROUP(scif1_clk_b), + SH_PFC_PIN_GROUP(scif1_ctrl_b), + SH_PFC_PIN_GROUP(scif3_data_a), + SH_PFC_PIN_GROUP(scif3_clk_a), + SH_PFC_PIN_GROUP(scif3_ctrl_a), + SH_PFC_PIN_GROUP(scif3_data_b), + SH_PFC_PIN_GROUP(scif3_clk_b), + SH_PFC_PIN_GROUP(scif3_ctrl_b), + SH_PFC_PIN_GROUP(scif4_data), + SH_PFC_PIN_GROUP(scif4_clk), + SH_PFC_PIN_GROUP(scif4_ctrl), + SH_PFC_PIN_GROUP(scif_clk), + SH_PFC_PIN_GROUP(scif_clk2), + + SH_PFC_PIN_GROUP(ssi_data), + SH_PFC_PIN_GROUP(ssi_ctrl), + + SH_PFC_PIN_GROUP(tpu_to0_a), + SH_PFC_PIN_GROUP(tpu_to0_b), + SH_PFC_PIN_GROUP(tpu_to1_a), + SH_PFC_PIN_GROUP(tpu_to1_b), + SH_PFC_PIN_GROUP(tpu_to2_a), + SH_PFC_PIN_GROUP(tpu_to2_b), + SH_PFC_PIN_GROUP(tpu_to3_a), + SH_PFC_PIN_GROUP(tpu_to3_b), +}; + +static const char * const audio_clk_groups[] = { + "audio_clkin", + "audio_clkout", +}; + +static const char * const avb0_groups[] = { + "avb0_link", + "avb0_magic", + "avb0_phy_int", + "avb0_mdio", + "avb0_rgmii", + "avb0_txcrefclk", + "avb0_avtp_pps", + "avb0_avtp_capture", + "avb0_avtp_match", +}; + +static const char * const avb1_groups[] = { + "avb1_link", + "avb1_magic", + "avb1_phy_int", + "avb1_mdio", + "avb1_rgmii", + "avb1_txcrefclk", + "avb1_avtp_pps", + "avb1_avtp_capture", + "avb1_avtp_match", +}; + +static const char * const avb2_groups[] = { + "avb2_link", + "avb2_magic", + "avb2_phy_int", + "avb2_mdio", + "avb2_rgmii", + "avb2_txcrefclk", + "avb2_avtp_pps", + "avb2_avtp_capture", + "avb2_avtp_match", +}; + +static const char * const canfd0_groups[] = { + "canfd0_data", +}; + +static const char * const canfd1_groups[] = { + "canfd1_data", +}; + +static const char * const canfd2_groups[] = { + "canfd2_data", +}; + +static const char * const canfd3_groups[] = { + "canfd3_data", +}; + +static const char * const can_clk_groups[] = { + "can_clk", +}; + +static const char * const hscif0_groups[] = { + "hscif0_data", + "hscif0_clk", + "hscif0_ctrl", +}; + +static const char * const hscif1_groups[] = { + "hscif1_data_a", + "hscif1_clk_a", + "hscif1_ctrl_a", + "hscif1_data_b", + "hscif1_clk_b", + "hscif1_ctrl_b", +}; + +static const char * const hscif2_groups[] = { + "hscif2_data", + "hscif2_clk", + "hscif2_ctrl", +}; + +static const char * const hscif3_groups[] = { + "hscif3_data_a", + "hscif3_clk_a", + "hscif3_ctrl_a", + "hscif3_data_b", + "hscif3_clk_b", + "hscif3_ctrl_b", +}; + +static const char * const i2c0_groups[] = { + "i2c0", +}; + +static const char * const i2c1_groups[] = { + "i2c1", +}; + +static const char * const i2c2_groups[] = { + "i2c2", +}; + +static const char * const i2c3_groups[] = { + "i2c3", +}; + +static const char * const mmc_groups[] = { + "mmc_data1", + "mmc_data4", + "mmc_data8", + "mmc_ctrl", + "mmc_cd", + "mmc_wp", + "mmc_ds", +}; + +static const char * const msiof0_groups[] = { + "msiof0_clk", + "msiof0_sync", + "msiof0_ss1", + "msiof0_ss2", + "msiof0_txd", + "msiof0_rxd", +}; + +static const char * const msiof1_groups[] = { + "msiof1_clk", + "msiof1_sync", + "msiof1_ss1", + "msiof1_ss2", + "msiof1_txd", + "msiof1_rxd", +}; + +static const char * const msiof2_groups[] = { + "msiof2_clk", + "msiof2_sync", + "msiof2_ss1", + "msiof2_ss2", + "msiof2_txd", + "msiof2_rxd", +}; + +static const char * const msiof3_groups[] = { + "msiof3_clk", + "msiof3_sync", + "msiof3_ss1", + "msiof3_ss2", + "msiof3_txd", + "msiof3_rxd", +}; + +static const char * const msiof4_groups[] = { + "msiof4_clk", + "msiof4_sync", + "msiof4_ss1", + "msiof4_ss2", + "msiof4_txd", + "msiof4_rxd", +}; + +static const char * const msiof5_groups[] = { + "msiof5_clk", + "msiof5_sync", + "msiof5_ss1", + "msiof5_ss2", + "msiof5_txd", + "msiof5_rxd", +}; + +static const char * const pcie_groups[] = { + "pcie0_clkreq_n", +}; + +static const char * const pwm0_groups[] = { + "pwm0_a", + "pwm0_b", +}; + +static const char * const pwm1_groups[] = { + "pwm1_a", + "pwm1_b", + "pwm1_c", +}; + +static const char * const pwm2_groups[] = { + "pwm2_a", + "pwm2_b", + "pwm2_c", +}; + +static const char * const pwm3_groups[] = { + "pwm3_a", + "pwm3_b", + "pwm3_c", +}; + +static const char * const pwm4_groups[] = { + "pwm4", +}; + +static const char * const qspi0_groups[] = { + "qspi0_ctrl", + "qspi0_data2", + "qspi0_data4", +}; + +static const char * const qspi1_groups[] = { + "qspi1_ctrl", + "qspi1_data2", + "qspi1_data4", +}; + +static const char * const scif0_groups[] = { + "scif0_data", + "scif0_clk", + "scif0_ctrl", +}; + +static const char * const scif1_groups[] = { + "scif1_data_a", + "scif1_clk_a", + "scif1_ctrl_a", + "scif1_data_b", + "scif1_clk_b", + "scif1_ctrl_b", +}; + +static const char * const scif3_groups[] = { + "scif3_data_a", + "scif3_clk_a", + "scif3_ctrl_a", + "scif3_data_b", + "scif3_clk_b", + "scif3_ctrl_b", +}; + +static const char * const scif4_groups[] = { + "scif4_data", + "scif4_clk", + "scif4_ctrl", +}; + +static const char * const scif_clk_groups[] = { + "scif_clk", +}; + +static const char * const scif_clk2_groups[] = { + "scif_clk2", +}; + +static const char * const ssi_groups[] = { + "ssi_data", + "ssi_ctrl", +}; + +static const char * const tpu_groups[] = { + "tpu_to0_a", + "tpu_to0_b", + "tpu_to1_a", + "tpu_to1_b", + "tpu_to2_a", + "tpu_to2_b", + "tpu_to3_a", + "tpu_to3_b", +}; + +static const struct sh_pfc_function pinmux_functions[] = { + SH_PFC_FUNCTION(audio_clk), + + SH_PFC_FUNCTION(avb0), + SH_PFC_FUNCTION(avb1), + SH_PFC_FUNCTION(avb2), + + SH_PFC_FUNCTION(canfd0), + SH_PFC_FUNCTION(canfd1), + SH_PFC_FUNCTION(canfd2), + SH_PFC_FUNCTION(canfd3), + SH_PFC_FUNCTION(can_clk), + + SH_PFC_FUNCTION(hscif0), + SH_PFC_FUNCTION(hscif1), + SH_PFC_FUNCTION(hscif2), + SH_PFC_FUNCTION(hscif3), + + SH_PFC_FUNCTION(i2c0), + SH_PFC_FUNCTION(i2c1), + SH_PFC_FUNCTION(i2c2), + SH_PFC_FUNCTION(i2c3), + + SH_PFC_FUNCTION(mmc), + + SH_PFC_FUNCTION(msiof0), + SH_PFC_FUNCTION(msiof1), + SH_PFC_FUNCTION(msiof2), + SH_PFC_FUNCTION(msiof3), + SH_PFC_FUNCTION(msiof4), + SH_PFC_FUNCTION(msiof5), + + SH_PFC_FUNCTION(pcie), + + SH_PFC_FUNCTION(pwm0), + SH_PFC_FUNCTION(pwm1), + SH_PFC_FUNCTION(pwm2), + SH_PFC_FUNCTION(pwm3), + SH_PFC_FUNCTION(pwm4), + + SH_PFC_FUNCTION(qspi0), + SH_PFC_FUNCTION(qspi1), + + SH_PFC_FUNCTION(scif0), + SH_PFC_FUNCTION(scif1), + SH_PFC_FUNCTION(scif3), + SH_PFC_FUNCTION(scif4), + SH_PFC_FUNCTION(scif_clk), + SH_PFC_FUNCTION(scif_clk2), + + SH_PFC_FUNCTION(ssi), + + SH_PFC_FUNCTION(tpu), +}; + +static const struct pinmux_cfg_reg pinmux_config_regs[] = { +#define F_(x, y) FN_##y +#define FM(x) FN_##x + { PINMUX_CFG_REG_VAR("GPSR0", 0xE6050040, 32, + GROUP(-13, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), + GROUP( + /* GP0_31_19 RESERVED */ + GP_0_18_FN, GPSR0_18, + GP_0_17_FN, GPSR0_17, + GP_0_16_FN, GPSR0_16, + GP_0_15_FN, GPSR0_15, + GP_0_14_FN, GPSR0_14, + GP_0_13_FN, GPSR0_13, + GP_0_12_FN, GPSR0_12, + GP_0_11_FN, GPSR0_11, + GP_0_10_FN, GPSR0_10, + GP_0_9_FN, GPSR0_9, + GP_0_8_FN, GPSR0_8, + GP_0_7_FN, GPSR0_7, + GP_0_6_FN, GPSR0_6, + GP_0_5_FN, GPSR0_5, + GP_0_4_FN, GPSR0_4, + GP_0_3_FN, GPSR0_3, + GP_0_2_FN, GPSR0_2, + GP_0_1_FN, GPSR0_1, + GP_0_0_FN, GPSR0_0, )) + }, + { PINMUX_CFG_REG("GPSR1", 0xE6050840, 32, 1, GROUP( + 0, 0, + 0, 0, + GP_1_29_FN, GPSR1_29, + GP_1_28_FN, GPSR1_28, + GP_1_27_FN, GPSR1_27, + GP_1_26_FN, GPSR1_26, + GP_1_25_FN, GPSR1_25, + GP_1_24_FN, GPSR1_24, + GP_1_23_FN, GPSR1_23, + GP_1_22_FN, GPSR1_22, + GP_1_21_FN, GPSR1_21, + GP_1_20_FN, GPSR1_20, + GP_1_19_FN, GPSR1_19, + GP_1_18_FN, GPSR1_18, + GP_1_17_FN, GPSR1_17, + GP_1_16_FN, GPSR1_16, + GP_1_15_FN, GPSR1_15, + GP_1_14_FN, GPSR1_14, + GP_1_13_FN, GPSR1_13, + GP_1_12_FN, GPSR1_12, + GP_1_11_FN, GPSR1_11, + GP_1_10_FN, GPSR1_10, + GP_1_9_FN, GPSR1_9, + GP_1_8_FN, GPSR1_8, + GP_1_7_FN, GPSR1_7, + GP_1_6_FN, GPSR1_6, + GP_1_5_FN, GPSR1_5, + GP_1_4_FN, GPSR1_4, + GP_1_3_FN, GPSR1_3, + GP_1_2_FN, GPSR1_2, + GP_1_1_FN, GPSR1_1, + GP_1_0_FN, GPSR1_0, )) + }, + { PINMUX_CFG_REG_VAR("GPSR2", 0xE6058040, 32, + GROUP(-12, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), + GROUP( + /* GP2_31_20 RESERVED */ + GP_2_19_FN, GPSR2_19, + /* GP2_18 RESERVED */ + GP_2_17_FN, GPSR2_17, + /* GP2_16 RESERVED */ + GP_2_15_FN, GPSR2_15, + GP_2_14_FN, GPSR2_14, + GP_2_13_FN, GPSR2_13, + GP_2_12_FN, GPSR2_12, + GP_2_11_FN, GPSR2_11, + GP_2_10_FN, GPSR2_10, + GP_2_9_FN, GPSR2_9, + GP_2_8_FN, GPSR2_8, + GP_2_7_FN, GPSR2_7, + GP_2_6_FN, GPSR2_6, + GP_2_5_FN, GPSR2_5, + GP_2_4_FN, GPSR2_4, + GP_2_3_FN, GPSR2_3, + GP_2_2_FN, GPSR2_2, + GP_2_1_FN, GPSR2_1, + GP_2_0_FN, GPSR2_0, )) + }, + { PINMUX_CFG_REG("GPSR3", 0xE6058840, 32, 1, GROUP( + GP_3_31_FN, GPSR3_31, + GP_3_30_FN, GPSR3_30, + GP_3_29_FN, GPSR3_29, + GP_3_28_FN, GPSR3_28, + GP_3_27_FN, GPSR3_27, + GP_3_26_FN, GPSR3_26, + GP_3_25_FN, GPSR3_25, + GP_3_24_FN, GPSR3_24, + GP_3_23_FN, GPSR3_23, + GP_3_22_FN, GPSR3_22, + GP_3_21_FN, GPSR3_21, + GP_3_20_FN, GPSR3_20, + GP_3_19_FN, GPSR3_19, + GP_3_18_FN, GPSR3_18, + GP_3_17_FN, GPSR3_17, + GP_3_16_FN, GPSR3_16, + GP_3_15_FN, GPSR3_15, + GP_3_14_FN, GPSR3_14, + GP_3_13_FN, GPSR3_13, + GP_3_12_FN, GPSR3_12, + GP_3_11_FN, GPSR3_11, + GP_3_10_FN, GPSR3_10, + GP_3_9_FN, GPSR3_9, + GP_3_8_FN, GPSR3_8, + GP_3_7_FN, GPSR3_7, + GP_3_6_FN, GPSR3_6, + GP_3_5_FN, GPSR3_5, + GP_3_4_FN, GPSR3_4, + GP_3_3_FN, GPSR3_3, + GP_3_2_FN, GPSR3_2, + GP_3_1_FN, GPSR3_1, + GP_3_0_FN, GPSR3_0, )) + }, + { PINMUX_CFG_REG_VAR("GPSR4", 0xE6060040, 32, + GROUP(-7, 1, 1, -1, 1, -5, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), + GROUP( + /* GP4_31_25 RESERVED */ + GP_4_24_FN, GPSR4_24, + GP_4_23_FN, GPSR4_23, + /* GP4_22 RESERVED */ + GP_4_21_FN, GPSR4_21, + /* GP4_20_16 RESERVED */ + GP_4_15_FN, GPSR4_15, + GP_4_14_FN, GPSR4_14, + GP_4_13_FN, GPSR4_13, + GP_4_12_FN, GPSR4_12, + GP_4_11_FN, GPSR4_11, + GP_4_10_FN, GPSR4_10, + GP_4_9_FN, GPSR4_9, + GP_4_8_FN, GPSR4_8, + GP_4_7_FN, GPSR4_7, + GP_4_6_FN, GPSR4_6, + GP_4_5_FN, GPSR4_5, + GP_4_4_FN, GPSR4_4, + GP_4_3_FN, GPSR4_3, + GP_4_2_FN, GPSR4_2, + GP_4_1_FN, GPSR4_1, + GP_4_0_FN, GPSR4_0, )) + }, + { PINMUX_CFG_REG_VAR("GPSR5", 0xE6060840, 32, + GROUP(-11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), + GROUP( + /* GP5_31_21 RESERVED */ + GP_5_20_FN, GPSR5_20, + GP_5_19_FN, GPSR5_19, + GP_5_18_FN, GPSR5_18, + GP_5_17_FN, GPSR5_17, + GP_5_16_FN, GPSR5_16, + GP_5_15_FN, GPSR5_15, + GP_5_14_FN, GPSR5_14, + GP_5_13_FN, GPSR5_13, + GP_5_12_FN, GPSR5_12, + GP_5_11_FN, GPSR5_11, + GP_5_10_FN, GPSR5_10, + GP_5_9_FN, GPSR5_9, + GP_5_8_FN, GPSR5_8, + GP_5_7_FN, GPSR5_7, + GP_5_6_FN, GPSR5_6, + GP_5_5_FN, GPSR5_5, + GP_5_4_FN, GPSR5_4, + GP_5_3_FN, GPSR5_3, + GP_5_2_FN, GPSR5_2, + GP_5_1_FN, GPSR5_1, + GP_5_0_FN, GPSR5_0, )) + }, + { PINMUX_CFG_REG_VAR("GPSR6", 0xE6061040, 32, + GROUP(-11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), + GROUP( + /* GP6_31_21 RESERVED */ + GP_6_20_FN, GPSR6_20, + GP_6_19_FN, GPSR6_19, + GP_6_18_FN, GPSR6_18, + GP_6_17_FN, GPSR6_17, + GP_6_16_FN, GPSR6_16, + GP_6_15_FN, GPSR6_15, + GP_6_14_FN, GPSR6_14, + GP_6_13_FN, GPSR6_13, + GP_6_12_FN, GPSR6_12, + GP_6_11_FN, GPSR6_11, + GP_6_10_FN, GPSR6_10, + GP_6_9_FN, GPSR6_9, + GP_6_8_FN, GPSR6_8, + GP_6_7_FN, GPSR6_7, + GP_6_6_FN, GPSR6_6, + GP_6_5_FN, GPSR6_5, + GP_6_4_FN, GPSR6_4, + GP_6_3_FN, GPSR6_3, + GP_6_2_FN, GPSR6_2, + GP_6_1_FN, GPSR6_1, + GP_6_0_FN, GPSR6_0, )) + }, + { PINMUX_CFG_REG_VAR("GPSR7", 0xE6061840, 32, + GROUP(-11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), + GROUP( + /* GP7_31_21 RESERVED */ + GP_7_20_FN, GPSR7_20, + GP_7_19_FN, GPSR7_19, + GP_7_18_FN, GPSR7_18, + GP_7_17_FN, GPSR7_17, + GP_7_16_FN, GPSR7_16, + GP_7_15_FN, GPSR7_15, + GP_7_14_FN, GPSR7_14, + GP_7_13_FN, GPSR7_13, + GP_7_12_FN, GPSR7_12, + GP_7_11_FN, GPSR7_11, + GP_7_10_FN, GPSR7_10, + GP_7_9_FN, GPSR7_9, + GP_7_8_FN, GPSR7_8, + GP_7_7_FN, GPSR7_7, + GP_7_6_FN, GPSR7_6, + GP_7_5_FN, GPSR7_5, + GP_7_4_FN, GPSR7_4, + GP_7_3_FN, GPSR7_3, + GP_7_2_FN, GPSR7_2, + GP_7_1_FN, GPSR7_1, + GP_7_0_FN, GPSR7_0, )) + }, +#undef F_ +#undef FM + +#define F_(x, y) x, +#define FM(x) FN_##x, + { PINMUX_CFG_REG("IP0SR0", 0xE6050060, 32, 4, GROUP( + IP0SR0_31_28 + IP0SR0_27_24 + IP0SR0_23_20 + IP0SR0_19_16 + IP0SR0_15_12 + IP0SR0_11_8 + IP0SR0_7_4 + IP0SR0_3_0)) + }, + { PINMUX_CFG_REG("IP1SR0", 0xE6050064, 32, 4, GROUP( + IP1SR0_31_28 + IP1SR0_27_24 + IP1SR0_23_20 + IP1SR0_19_16 + IP1SR0_15_12 + IP1SR0_11_8 + IP1SR0_7_4 + IP1SR0_3_0)) + }, + { PINMUX_CFG_REG_VAR("IP2SR0", 0xE6050068, 32, + GROUP(-20, 4, 4, 4), + GROUP( + /* IP2SR0_31_12 RESERVED */ + IP2SR0_11_8 + IP2SR0_7_4 + IP2SR0_3_0)) + }, + { PINMUX_CFG_REG("IP0SR1", 0xE6050860, 32, 4, GROUP( + IP0SR1_31_28 + IP0SR1_27_24 + IP0SR1_23_20 + IP0SR1_19_16 + IP0SR1_15_12 + IP0SR1_11_8 + IP0SR1_7_4 + IP0SR1_3_0)) + }, + { PINMUX_CFG_REG("IP1SR1", 0xE6050864, 32, 4, GROUP( + IP1SR1_31_28 + IP1SR1_27_24 + IP1SR1_23_20 + IP1SR1_19_16 + IP1SR1_15_12 + IP1SR1_11_8 + IP1SR1_7_4 + IP1SR1_3_0)) + }, + { PINMUX_CFG_REG("IP2SR1", 0xE6050868, 32, 4, GROUP( + IP2SR1_31_28 + IP2SR1_27_24 + IP2SR1_23_20 + IP2SR1_19_16 + IP2SR1_15_12 + IP2SR1_11_8 + IP2SR1_7_4 + IP2SR1_3_0)) + }, + { PINMUX_CFG_REG_VAR("IP3SR1", 0xE605086C, 32, + GROUP(-8, 4, 4, 4, 4, 4, 4), + GROUP( + /* IP3SR1_31_24 RESERVED */ + IP3SR1_23_20 + IP3SR1_19_16 + IP3SR1_15_12 + IP3SR1_11_8 + IP3SR1_7_4 + IP3SR1_3_0)) + }, + { PINMUX_CFG_REG("IP0SR2", 0xE6058060, 32, 4, GROUP( + IP0SR2_31_28 + IP0SR2_27_24 + IP0SR2_23_20 + IP0SR2_19_16 + IP0SR2_15_12 + IP0SR2_11_8 + IP0SR2_7_4 + IP0SR2_3_0)) + }, + { PINMUX_CFG_REG("IP1SR2", 0xE6058064, 32, 4, GROUP( + IP1SR2_31_28 + IP1SR2_27_24 + IP1SR2_23_20 + IP1SR2_19_16 + IP1SR2_15_12 + IP1SR2_11_8 + IP1SR2_7_4 + IP1SR2_3_0)) + }, + { PINMUX_CFG_REG_VAR("IP2SR2", 0xE6058068, 32, + GROUP(-16, 4, -4, 4, -4), + GROUP( + /* IP2SR2_31_16 RESERVED */ + IP2SR2_15_12 + /* IP2SR2_11_8 RESERVED */ + IP2SR2_7_4 + /* IP2SR2_3_0 RESERVED */)) + }, + { PINMUX_CFG_REG("IP0SR3", 0xE6058860, 32, 4, GROUP( + IP0SR3_31_28 + IP0SR3_27_24 + IP0SR3_23_20 + IP0SR3_19_16 + IP0SR3_15_12 + IP0SR3_11_8 + IP0SR3_7_4 + IP0SR3_3_0)) + }, + { PINMUX_CFG_REG("IP1SR3", 0xE6058864, 32, 4, GROUP( + IP1SR3_31_28 + IP1SR3_27_24 + IP1SR3_23_20 + IP1SR3_19_16 + IP1SR3_15_12 + IP1SR3_11_8 + IP1SR3_7_4 + IP1SR3_3_0)) + }, + { PINMUX_CFG_REG("IP2SR3", 0xE6058868, 32, 4, GROUP( + IP2SR3_31_28 + IP2SR3_27_24 + IP2SR3_23_20 + IP2SR3_19_16 + IP2SR3_15_12 + IP2SR3_11_8 + IP2SR3_7_4 + IP2SR3_3_0)) + }, + { PINMUX_CFG_REG("IP3SR3", 0xE605886C, 32, 4, GROUP( + IP3SR3_31_28 + IP3SR3_27_24 + IP3SR3_23_20 + IP3SR3_19_16 + IP3SR3_15_12 + IP3SR3_11_8 + IP3SR3_7_4 + IP3SR3_3_0)) + }, + { PINMUX_CFG_REG("IP0SR4", 0xE6060060, 32, 4, GROUP( + IP0SR4_31_28 + IP0SR4_27_24 + IP0SR4_23_20 + IP0SR4_19_16 + IP0SR4_15_12 + IP0SR4_11_8 + IP0SR4_7_4 + IP0SR4_3_0)) + }, + { PINMUX_CFG_REG("IP1SR4", 0xE6060064, 32, 4, GROUP( + IP1SR4_31_28 + IP1SR4_27_24 + IP1SR4_23_20 + IP1SR4_19_16 + IP1SR4_15_12 + IP1SR4_11_8 + IP1SR4_7_4 + IP1SR4_3_0)) + }, + { PINMUX_CFG_REG_VAR("IP2SR4", 0xE6060068, 32, + GROUP(4, -4, 4, -20), + GROUP( + IP2SR4_31_28 + /* IP2SR4_27_24 RESERVED */ + IP2SR4_23_20 + /* IP2SR4_19_0 RESERVED */)) + }, + { PINMUX_CFG_REG_VAR("IP3SR4", 0xE606006C, 32, + GROUP(-28, 4), + GROUP( + /* IP3SR4_31_4 RESERVED */ + IP3SR4_3_0)) + }, + { PINMUX_CFG_REG("IP0SR5", 0xE6060860, 32, 4, GROUP( + IP0SR5_31_28 + IP0SR5_27_24 + IP0SR5_23_20 + IP0SR5_19_16 + IP0SR5_15_12 + IP0SR5_11_8 + IP0SR5_7_4 + IP0SR5_3_0)) + }, + { PINMUX_CFG_REG("IP1SR5", 0xE6060864, 32, 4, GROUP( + IP1SR5_31_28 + IP1SR5_27_24 + IP1SR5_23_20 + IP1SR5_19_16 + IP1SR5_15_12 + IP1SR5_11_8 + IP1SR5_7_4 + IP1SR5_3_0)) + }, + { PINMUX_CFG_REG_VAR("IP2SR5", 0xE6060868, 32, + GROUP(-12, 4, 4, 4, 4, 4), + GROUP( + /* IP2SR5_31_20 RESERVED */ + IP2SR5_19_16 + IP2SR5_15_12 + IP2SR5_11_8 + IP2SR5_7_4 + IP2SR5_3_0)) + }, + { PINMUX_CFG_REG("IP0SR6", 0xE6061060, 32, 4, GROUP( + IP0SR6_31_28 + IP0SR6_27_24 + IP0SR6_23_20 + IP0SR6_19_16 + IP0SR6_15_12 + IP0SR6_11_8 + IP0SR6_7_4 + IP0SR6_3_0)) + }, + { PINMUX_CFG_REG("IP1SR6", 0xE6061064, 32, 4, GROUP( + IP1SR6_31_28 + IP1SR6_27_24 + IP1SR6_23_20 + IP1SR6_19_16 + IP1SR6_15_12 + IP1SR6_11_8 + IP1SR6_7_4 + IP1SR6_3_0)) + }, + { PINMUX_CFG_REG_VAR("IP2SR6", 0xE6061068, 32, + GROUP(-12, 4, 4, 4, 4, 4), + GROUP( + /* IP2SR6_31_20 RESERVED */ + IP2SR6_19_16 + IP2SR6_15_12 + IP2SR6_11_8 + IP2SR6_7_4 + IP2SR6_3_0)) + }, + { PINMUX_CFG_REG("IP0SR7", 0xE6061860, 32, 4, GROUP( + IP0SR7_31_28 + IP0SR7_27_24 + IP0SR7_23_20 + IP0SR7_19_16 + IP0SR7_15_12 + IP0SR7_11_8 + IP0SR7_7_4 + IP0SR7_3_0)) + }, + { PINMUX_CFG_REG("IP1SR7", 0xE6061864, 32, 4, GROUP( + IP1SR7_31_28 + IP1SR7_27_24 + IP1SR7_23_20 + IP1SR7_19_16 + IP1SR7_15_12 + IP1SR7_11_8 + IP1SR7_7_4 + IP1SR7_3_0)) + }, + { PINMUX_CFG_REG_VAR("IP2SR7", 0xE6061868, 32, + GROUP(-12, 4, 4, 4, 4, 4), + GROUP( + /* IP2SR7_31_20 RESERVED */ + IP2SR7_19_16 + IP2SR7_15_12 + IP2SR7_11_8 + IP2SR7_7_4 + IP2SR7_3_0)) + }, +#undef F_ +#undef FM + +#define F_(x, y) x, +#define FM(x) FN_##x, + { PINMUX_CFG_REG_VAR("MOD_SEL4", 0xE6060100, 32, + GROUP(-24, 1, 1, 1, 1, 1, 1, 1, 1), + GROUP( + /* RESERVED 31-8 */ + MOD_SEL4_7 + MOD_SEL4_6 + MOD_SEL4_5 + MOD_SEL4_4 + MOD_SEL4_3 + MOD_SEL4_2 + MOD_SEL4_1 + MOD_SEL4_0)) + }, + { }, +}; + +static const struct pinmux_drive_reg pinmux_drive_regs[] = { + { PINMUX_DRIVE_REG("DRV0CTRL0", 0xE6050080) { + { RCAR_GP_PIN(0, 7), 28, 3 }, /* MSIOF5_SS2 */ + { RCAR_GP_PIN(0, 6), 24, 3 }, /* IRQ0 */ + { RCAR_GP_PIN(0, 5), 20, 3 }, /* IRQ1 */ + { RCAR_GP_PIN(0, 4), 16, 3 }, /* IRQ2 */ + { RCAR_GP_PIN(0, 3), 12, 3 }, /* IRQ3 */ + { RCAR_GP_PIN(0, 2), 8, 3 }, /* GP0_02 */ + { RCAR_GP_PIN(0, 1), 4, 3 }, /* GP0_01 */ + { RCAR_GP_PIN(0, 0), 0, 3 }, /* GP0_00 */ + } }, + { PINMUX_DRIVE_REG("DRV1CTRL0", 0xE6050084) { + { RCAR_GP_PIN(0, 15), 28, 3 }, /* MSIOF2_SYNC */ + { RCAR_GP_PIN(0, 14), 24, 3 }, /* MSIOF2_SS1 */ + { RCAR_GP_PIN(0, 13), 20, 3 }, /* MSIOF2_SS2 */ + { RCAR_GP_PIN(0, 12), 16, 3 }, /* MSIOF5_RXD */ + { RCAR_GP_PIN(0, 11), 12, 3 }, /* MSIOF5_SCK */ + { RCAR_GP_PIN(0, 10), 8, 3 }, /* MSIOF5_TXD */ + { RCAR_GP_PIN(0, 9), 4, 3 }, /* MSIOF5_SYNC */ + { RCAR_GP_PIN(0, 8), 0, 3 }, /* MSIOF5_SS1 */ + } }, + { PINMUX_DRIVE_REG("DRV2CTRL0", 0xE6050088) { + { RCAR_GP_PIN(0, 18), 8, 3 }, /* MSIOF2_RXD */ + { RCAR_GP_PIN(0, 17), 4, 3 }, /* MSIOF2_SCK */ + { RCAR_GP_PIN(0, 16), 0, 3 }, /* MSIOF2_TXD */ + } }, + { PINMUX_DRIVE_REG("DRV0CTRL1", 0xE6050880) { + { RCAR_GP_PIN(1, 7), 28, 3 }, /* MSIOF0_SS1 */ + { RCAR_GP_PIN(1, 6), 24, 3 }, /* MSIOF0_SS2 */ + { RCAR_GP_PIN(1, 5), 20, 3 }, /* MSIOF1_RXD */ + { RCAR_GP_PIN(1, 4), 16, 3 }, /* MSIOF1_TXD */ + { RCAR_GP_PIN(1, 3), 12, 3 }, /* MSIOF1_SCK */ + { RCAR_GP_PIN(1, 2), 8, 3 }, /* MSIOF1_SYNC */ + { RCAR_GP_PIN(1, 1), 4, 3 }, /* MSIOF1_SS1 */ + { RCAR_GP_PIN(1, 0), 0, 3 }, /* MSIOF1_SS2 */ + } }, + { PINMUX_DRIVE_REG("DRV1CTRL1", 0xE6050884) { + { RCAR_GP_PIN(1, 15), 28, 3 }, /* HSCK0 */ + { RCAR_GP_PIN(1, 14), 24, 3 }, /* HRTS0_N */ + { RCAR_GP_PIN(1, 13), 20, 3 }, /* HCTS0_N */ + { RCAR_GP_PIN(1, 12), 16, 3 }, /* HTX0 */ + { RCAR_GP_PIN(1, 11), 12, 3 }, /* MSIOF0_RXD */ + { RCAR_GP_PIN(1, 10), 8, 3 }, /* MSIOF0_SCK */ + { RCAR_GP_PIN(1, 9), 4, 3 }, /* MSIOF0_TXD */ + { RCAR_GP_PIN(1, 8), 0, 3 }, /* MSIOF0_SYNC */ + } }, + { PINMUX_DRIVE_REG("DRV2CTRL1", 0xE6050888) { + { RCAR_GP_PIN(1, 23), 28, 3 }, /* GP1_23 */ + { RCAR_GP_PIN(1, 22), 24, 3 }, /* AUDIO_CLKIN */ + { RCAR_GP_PIN(1, 21), 20, 3 }, /* AUDIO_CLKOUT */ + { RCAR_GP_PIN(1, 20), 16, 3 }, /* SSI_SD */ + { RCAR_GP_PIN(1, 19), 12, 3 }, /* SSI_WS */ + { RCAR_GP_PIN(1, 18), 8, 3 }, /* SSI_SCK */ + { RCAR_GP_PIN(1, 17), 4, 3 }, /* SCIF_CLK */ + { RCAR_GP_PIN(1, 16), 0, 3 }, /* HRX0 */ + } }, + { PINMUX_DRIVE_REG("DRV3CTRL1", 0xE605088C) { + { RCAR_GP_PIN(1, 29), 20, 2 }, /* ERROROUTC_N */ + { RCAR_GP_PIN(1, 28), 16, 3 }, /* HTX3 */ + { RCAR_GP_PIN(1, 27), 12, 3 }, /* HCTS3_N */ + { RCAR_GP_PIN(1, 26), 8, 3 }, /* HRTS3_N */ + { RCAR_GP_PIN(1, 25), 4, 3 }, /* HSCK3 */ + { RCAR_GP_PIN(1, 24), 0, 3 }, /* HRX3 */ + } }, + { PINMUX_DRIVE_REG("DRV0CTRL2", 0xE6058080) { + { RCAR_GP_PIN(2, 7), 28, 3 }, /* TPU0TO1 */ + { RCAR_GP_PIN(2, 6), 24, 3 }, /* FXR_TXDB */ + { RCAR_GP_PIN(2, 5), 20, 3 }, /* FXR_TXENB_N */ + { RCAR_GP_PIN(2, 4), 16, 3 }, /* RXDB_EXTFXR */ + { RCAR_GP_PIN(2, 3), 12, 3 }, /* CLK_EXTFXR */ + { RCAR_GP_PIN(2, 2), 8, 3 }, /* RXDA_EXTFXR */ + { RCAR_GP_PIN(2, 1), 4, 3 }, /* FXR_TXENA_N */ + { RCAR_GP_PIN(2, 0), 0, 3 }, /* FXR_TXDA */ + } }, + { PINMUX_DRIVE_REG("DRV1CTRL2", 0xE6058084) { + { RCAR_GP_PIN(2, 15), 28, 3 }, /* CANFD3_RX */ + { RCAR_GP_PIN(2, 14), 24, 3 }, /* CANFD3_TX */ + { RCAR_GP_PIN(2, 13), 20, 3 }, /* CANFD2_RX */ + { RCAR_GP_PIN(2, 12), 16, 3 }, /* CANFD2_TX */ + { RCAR_GP_PIN(2, 11), 12, 3 }, /* CANFD0_RX */ + { RCAR_GP_PIN(2, 10), 8, 3 }, /* CANFD0_TX */ + { RCAR_GP_PIN(2, 9), 4, 3 }, /* CAN_CLK */ + { RCAR_GP_PIN(2, 8), 0, 3 }, /* TPU0TO0 */ + } }, + { PINMUX_DRIVE_REG("DRV2CTRL2", 0xE6058088) { + { RCAR_GP_PIN(2, 19), 12, 3 }, /* CANFD1_RX */ + { RCAR_GP_PIN(2, 17), 4, 3 }, /* CANFD1_TX */ + } }, + { PINMUX_DRIVE_REG("DRV0CTRL3", 0xE6058880) { + { RCAR_GP_PIN(3, 7), 28, 3 }, /* MMC_D4 */ + { RCAR_GP_PIN(3, 6), 24, 3 }, /* MMC_D5 */ + { RCAR_GP_PIN(3, 5), 20, 3 }, /* MMC_SD_D3 */ + { RCAR_GP_PIN(3, 4), 16, 3 }, /* MMC_DS */ + { RCAR_GP_PIN(3, 3), 12, 3 }, /* MMC_SD_CLK */ + { RCAR_GP_PIN(3, 2), 8, 3 }, /* MMC_SD_D2 */ + { RCAR_GP_PIN(3, 1), 4, 3 }, /* MMC_SD_D0 */ + { RCAR_GP_PIN(3, 0), 0, 3 }, /* MMC_SD_D1 */ + } }, + { PINMUX_DRIVE_REG("DRV1CTRL3", 0xE6058884) { + { RCAR_GP_PIN(3, 15), 28, 2 }, /* QSPI0_SSL */ + { RCAR_GP_PIN(3, 14), 24, 2 }, /* PWM2 */ + { RCAR_GP_PIN(3, 13), 20, 2 }, /* PWM1 */ + { RCAR_GP_PIN(3, 12), 16, 3 }, /* SD_WP */ + { RCAR_GP_PIN(3, 11), 12, 3 }, /* SD_CD */ + { RCAR_GP_PIN(3, 10), 8, 3 }, /* MMC_SD_CMD */ + { RCAR_GP_PIN(3, 9), 4, 3 }, /* MMC_D6*/ + { RCAR_GP_PIN(3, 8), 0, 3 }, /* MMC_D7 */ + } }, + { PINMUX_DRIVE_REG("DRV2CTRL3", 0xE6058888) { + { RCAR_GP_PIN(3, 23), 28, 2 }, /* QSPI1_MISO_IO1 */ + { RCAR_GP_PIN(3, 22), 24, 2 }, /* QSPI1_SPCLK */ + { RCAR_GP_PIN(3, 21), 20, 2 }, /* QSPI1_MOSI_IO0 */ + { RCAR_GP_PIN(3, 20), 16, 2 }, /* QSPI0_SPCLK */ + { RCAR_GP_PIN(3, 19), 12, 2 }, /* QSPI0_MOSI_IO0 */ + { RCAR_GP_PIN(3, 18), 8, 2 }, /* QSPI0_MISO_IO1 */ + { RCAR_GP_PIN(3, 17), 4, 2 }, /* QSPI0_IO2 */ + { RCAR_GP_PIN(3, 16), 0, 2 }, /* QSPI0_IO3 */ + } }, + { PINMUX_DRIVE_REG("DRV3CTRL3", 0xE605888C) { + { RCAR_GP_PIN(3, 31), 28, 2 }, /* TCLK4 */ + { RCAR_GP_PIN(3, 30), 24, 2 }, /* TCLK3 */ + { RCAR_GP_PIN(3, 29), 20, 2 }, /* RPC_INT_N */ + { RCAR_GP_PIN(3, 28), 16, 2 }, /* RPC_WP_N */ + { RCAR_GP_PIN(3, 27), 12, 2 }, /* RPC_RESET_N */ + { RCAR_GP_PIN(3, 26), 8, 2 }, /* QSPI1_IO3 */ + { RCAR_GP_PIN(3, 25), 4, 2 }, /* QSPI1_SSL */ + { RCAR_GP_PIN(3, 24), 0, 2 }, /* QSPI1_IO2 */ + } }, + { PINMUX_DRIVE_REG("DRV0CTRL4", 0xE6060080) { + { RCAR_GP_PIN(4, 7), 28, 3 }, /* SDA3 */ + { RCAR_GP_PIN(4, 6), 24, 3 }, /* SCL3 */ + { RCAR_GP_PIN(4, 5), 20, 3 }, /* SDA2 */ + { RCAR_GP_PIN(4, 4), 16, 3 }, /* SCL2 */ + { RCAR_GP_PIN(4, 3), 12, 3 }, /* SDA1 */ + { RCAR_GP_PIN(4, 2), 8, 3 }, /* SCL1 */ + { RCAR_GP_PIN(4, 1), 4, 3 }, /* SDA0 */ + { RCAR_GP_PIN(4, 0), 0, 3 }, /* SCL0 */ + } }, + { PINMUX_DRIVE_REG("DRV1CTRL4", 0xE6060084) { + { RCAR_GP_PIN(4, 15), 28, 3 }, /* PWM4 */ + { RCAR_GP_PIN(4, 14), 24, 3 }, /* PWM3 */ + { RCAR_GP_PIN(4, 13), 20, 3 }, /* HSCK2 */ + { RCAR_GP_PIN(4, 12), 16, 3 }, /* HCTS2_N */ + { RCAR_GP_PIN(4, 11), 12, 3 }, /* SCIF_CLK2 */ + { RCAR_GP_PIN(4, 10), 8, 3 }, /* HRTS2_N */ + { RCAR_GP_PIN(4, 9), 4, 3 }, /* HTX2 */ + { RCAR_GP_PIN(4, 8), 0, 3 }, /* HRX2 */ + } }, + { PINMUX_DRIVE_REG("DRV2CTRL4", 0xE6060088) { + { RCAR_GP_PIN(4, 23), 28, 3 }, /* AVS0 */ + { RCAR_GP_PIN(4, 21), 20, 3 }, /* PCIE0_CLKREQ_N */ + } }, + { PINMUX_DRIVE_REG("DRV3CTRL4", 0xE606008C) { + { RCAR_GP_PIN(4, 24), 0, 3 }, /* AVS1 */ + } }, + { PINMUX_DRIVE_REG("DRV0CTRL5", 0xE6060880) { + { RCAR_GP_PIN(5, 7), 28, 3 }, /* AVB2_TXCREFCLK */ + { RCAR_GP_PIN(5, 6), 24, 3 }, /* AVB2_MDC */ + { RCAR_GP_PIN(5, 5), 20, 3 }, /* AVB2_MAGIC */ + { RCAR_GP_PIN(5, 4), 16, 3 }, /* AVB2_PHY_INT */ + { RCAR_GP_PIN(5, 3), 12, 3 }, /* AVB2_LINK */ + { RCAR_GP_PIN(5, 2), 8, 3 }, /* AVB2_AVTP_MATCH */ + { RCAR_GP_PIN(5, 1), 4, 3 }, /* AVB2_AVTP_CAPTURE */ + { RCAR_GP_PIN(5, 0), 0, 3 }, /* AVB2_AVTP_PPS */ + } }, + { PINMUX_DRIVE_REG("DRV1CTRL5", 0xE6060884) { + { RCAR_GP_PIN(5, 15), 28, 3 }, /* AVB2_TD0 */ + { RCAR_GP_PIN(5, 14), 24, 3 }, /* AVB2_RD1 */ + { RCAR_GP_PIN(5, 13), 20, 3 }, /* AVB2_RD2 */ + { RCAR_GP_PIN(5, 12), 16, 3 }, /* AVB2_TD1 */ + { RCAR_GP_PIN(5, 11), 12, 3 }, /* AVB2_TD2 */ + { RCAR_GP_PIN(5, 10), 8, 3 }, /* AVB2_MDIO */ + { RCAR_GP_PIN(5, 9), 4, 3 }, /* AVB2_RD3 */ + { RCAR_GP_PIN(5, 8), 0, 3 }, /* AVB2_TD3 */ + } }, + { PINMUX_DRIVE_REG("DRV2CTRL5", 0xE6060888) { + { RCAR_GP_PIN(5, 20), 16, 3 }, /* AVB2_RX_CTL */ + { RCAR_GP_PIN(5, 19), 12, 3 }, /* AVB2_TX_CTL */ + { RCAR_GP_PIN(5, 18), 8, 3 }, /* AVB2_RXC */ + { RCAR_GP_PIN(5, 17), 4, 3 }, /* AVB2_RD0 */ + { RCAR_GP_PIN(5, 16), 0, 3 }, /* AVB2_TXC */ + } }, + { PINMUX_DRIVE_REG("DRV0CTRL6", 0xE6061080) { + { RCAR_GP_PIN(6, 7), 28, 3 }, /* AVB1_TX_CTL */ + { RCAR_GP_PIN(6, 6), 24, 3 }, /* AVB1_TXC */ + { RCAR_GP_PIN(6, 5), 20, 3 }, /* AVB1_AVTP_MATCH */ + { RCAR_GP_PIN(6, 4), 16, 3 }, /* AVB1_LINK */ + { RCAR_GP_PIN(6, 3), 12, 3 }, /* AVB1_PHY_INT */ + { RCAR_GP_PIN(6, 2), 8, 3 }, /* AVB1_MDC */ + { RCAR_GP_PIN(6, 1), 4, 3 }, /* AVB1_MAGIC */ + { RCAR_GP_PIN(6, 0), 0, 3 }, /* AVB1_MDIO */ + } }, + { PINMUX_DRIVE_REG("DRV1CTRL6", 0xE6061084) { + { RCAR_GP_PIN(6, 15), 28, 3 }, /* AVB1_RD0 */ + { RCAR_GP_PIN(6, 14), 24, 3 }, /* AVB1_RD1 */ + { RCAR_GP_PIN(6, 13), 20, 3 }, /* AVB1_TD0 */ + { RCAR_GP_PIN(6, 12), 16, 3 }, /* AVB1_TD1 */ + { RCAR_GP_PIN(6, 11), 12, 3 }, /* AVB1_AVTP_CAPTURE */ + { RCAR_GP_PIN(6, 10), 8, 3 }, /* AVB1_AVTP_PPS */ + { RCAR_GP_PIN(6, 9), 4, 3 }, /* AVB1_RX_CTL */ + { RCAR_GP_PIN(6, 8), 0, 3 }, /* AVB1_RXC */ + } }, + { PINMUX_DRIVE_REG("DRV2CTRL6", 0xE6061088) { + { RCAR_GP_PIN(6, 20), 16, 3 }, /* AVB1_TXCREFCLK */ + { RCAR_GP_PIN(6, 19), 12, 3 }, /* AVB1_RD3 */ + { RCAR_GP_PIN(6, 18), 8, 3 }, /* AVB1_TD3 */ + { RCAR_GP_PIN(6, 17), 4, 3 }, /* AVB1_RD2 */ + { RCAR_GP_PIN(6, 16), 0, 3 }, /* AVB1_TD2 */ + } }, + { PINMUX_DRIVE_REG("DRV0CTRL7", 0xE6061880) { + { RCAR_GP_PIN(7, 7), 28, 3 }, /* AVB0_TD1 */ + { RCAR_GP_PIN(7, 6), 24, 3 }, /* AVB0_TD2 */ + { RCAR_GP_PIN(7, 5), 20, 3 }, /* AVB0_PHY_INT */ + { RCAR_GP_PIN(7, 4), 16, 3 }, /* AVB0_LINK */ + { RCAR_GP_PIN(7, 3), 12, 3 }, /* AVB0_TD3 */ + { RCAR_GP_PIN(7, 2), 8, 3 }, /* AVB0_AVTP_MATCH */ + { RCAR_GP_PIN(7, 1), 4, 3 }, /* AVB0_AVTP_CAPTURE */ + { RCAR_GP_PIN(7, 0), 0, 3 }, /* AVB0_AVTP_PPS */ + } }, + { PINMUX_DRIVE_REG("DRV1CTRL7", 0xE6061884) { + { RCAR_GP_PIN(7, 15), 28, 3 }, /* AVB0_TXC */ + { RCAR_GP_PIN(7, 14), 24, 3 }, /* AVB0_MDIO */ + { RCAR_GP_PIN(7, 13), 20, 3 }, /* AVB0_MDC */ + { RCAR_GP_PIN(7, 12), 16, 3 }, /* AVB0_RD2 */ + { RCAR_GP_PIN(7, 11), 12, 3 }, /* AVB0_TD0 */ + { RCAR_GP_PIN(7, 10), 8, 3 }, /* AVB0_MAGIC */ + { RCAR_GP_PIN(7, 9), 4, 3 }, /* AVB0_TXCREFCLK */ + { RCAR_GP_PIN(7, 8), 0, 3 }, /* AVB0_RD3 */ + } }, + { PINMUX_DRIVE_REG("DRV2CTRL7", 0xE6061888) { + { RCAR_GP_PIN(7, 20), 16, 3 }, /* AVB0_RX_CTL */ + { RCAR_GP_PIN(7, 19), 12, 3 }, /* AVB0_RXC */ + { RCAR_GP_PIN(7, 18), 8, 3 }, /* AVB0_RD0 */ + { RCAR_GP_PIN(7, 17), 4, 3 }, /* AVB0_RD1 */ + { RCAR_GP_PIN(7, 16), 0, 3 }, /* AVB0_TX_CTL */ + } }, + { }, +}; + +enum ioctrl_regs { + POC0, + POC1, + POC3, + POC4, + POC5, + POC6, + POC7, +}; + +static const struct pinmux_ioctrl_reg pinmux_ioctrl_regs[] = { + [POC0] = { 0xE60500A0, }, + [POC1] = { 0xE60508A0, }, + [POC3] = { 0xE60588A0, }, + [POC4] = { 0xE60600A0, }, + [POC5] = { 0xE60608A0, }, + [POC6] = { 0xE60610A0, }, + [POC7] = { 0xE60618A0, }, + { /* sentinel */ }, +}; + +static int r8a779h0_pin_to_pocctrl(unsigned int pin, u32 *pocctrl) +{ + int bit = pin & 0x1f; + + switch (pin) { + case RCAR_GP_PIN(0, 0) ... RCAR_GP_PIN(0, 18): + *pocctrl = pinmux_ioctrl_regs[POC0].reg; + return bit; + + case RCAR_GP_PIN(1, 0) ... RCAR_GP_PIN(1, 28): + *pocctrl = pinmux_ioctrl_regs[POC1].reg; + return bit; + + case RCAR_GP_PIN(3, 0) ... RCAR_GP_PIN(3, 12): + *pocctrl = pinmux_ioctrl_regs[POC3].reg; + return bit; + + case RCAR_GP_PIN(4, 0) ... RCAR_GP_PIN(4, 13): + *pocctrl = pinmux_ioctrl_regs[POC4].reg; + return bit; + + case PIN_VDDQ_AVB2: + *pocctrl = pinmux_ioctrl_regs[POC5].reg; + return 0; + + case PIN_VDDQ_AVB1: + *pocctrl = pinmux_ioctrl_regs[POC6].reg; + return 0; + + case PIN_VDDQ_AVB0: + *pocctrl = pinmux_ioctrl_regs[POC7].reg; + return 0; + + default: + return -EINVAL; + } +} + +static const struct pinmux_bias_reg pinmux_bias_regs[] = { + { PINMUX_BIAS_REG("PUEN0", 0xE60500C0, "PUD0", 0xE60500E0) { + [ 0] = RCAR_GP_PIN(0, 0), /* GP0_00 */ + [ 1] = RCAR_GP_PIN(0, 1), /* GP0_01 */ + [ 2] = RCAR_GP_PIN(0, 2), /* GP0_02 */ + [ 3] = RCAR_GP_PIN(0, 3), /* IRQ3 */ + [ 4] = RCAR_GP_PIN(0, 4), /* IRQ2 */ + [ 5] = RCAR_GP_PIN(0, 5), /* IRQ1 */ + [ 6] = RCAR_GP_PIN(0, 6), /* IRQ0 */ + [ 7] = RCAR_GP_PIN(0, 7), /* MSIOF5_SS2 */ + [ 8] = RCAR_GP_PIN(0, 8), /* MSIOF5_SS1 */ + [ 9] = RCAR_GP_PIN(0, 9), /* MSIOF5_SYNC */ + [10] = RCAR_GP_PIN(0, 10), /* MSIOF5_TXD */ + [11] = RCAR_GP_PIN(0, 11), /* MSIOF5_SCK */ + [12] = RCAR_GP_PIN(0, 12), /* MSIOF5_RXD */ + [13] = RCAR_GP_PIN(0, 13), /* MSIOF2_SS2 */ + [14] = RCAR_GP_PIN(0, 14), /* MSIOF2_SS1 */ + [15] = RCAR_GP_PIN(0, 15), /* MSIOF2_SYNC */ + [16] = RCAR_GP_PIN(0, 16), /* MSIOF2_TXD */ + [17] = RCAR_GP_PIN(0, 17), /* MSIOF2_SCK */ + [18] = RCAR_GP_PIN(0, 18), /* MSIOF2_RXD */ + [19] = SH_PFC_PIN_NONE, + [20] = SH_PFC_PIN_NONE, + [21] = SH_PFC_PIN_NONE, + [22] = SH_PFC_PIN_NONE, + [23] = SH_PFC_PIN_NONE, + [24] = SH_PFC_PIN_NONE, + [25] = SH_PFC_PIN_NONE, + [26] = SH_PFC_PIN_NONE, + [27] = SH_PFC_PIN_NONE, + [28] = SH_PFC_PIN_NONE, + [29] = SH_PFC_PIN_NONE, + [30] = SH_PFC_PIN_NONE, + [31] = SH_PFC_PIN_NONE, + } }, + { PINMUX_BIAS_REG("PUEN1", 0xE60508C0, "PUD1", 0xE60508E0) { + [ 0] = RCAR_GP_PIN(1, 0), /* MSIOF1_SS2 */ + [ 1] = RCAR_GP_PIN(1, 1), /* MSIOF1_SS1 */ + [ 2] = RCAR_GP_PIN(1, 2), /* MSIOF1_SYNC */ + [ 3] = RCAR_GP_PIN(1, 3), /* MSIOF1_SCK */ + [ 4] = RCAR_GP_PIN(1, 4), /* MSIOF1_TXD */ + [ 5] = RCAR_GP_PIN(1, 5), /* MSIOF1_RXD */ + [ 6] = RCAR_GP_PIN(1, 6), /* MSIOF0_SS2 */ + [ 7] = RCAR_GP_PIN(1, 7), /* MSIOF0_SS1 */ + [ 8] = RCAR_GP_PIN(1, 8), /* MSIOF0_SYNC */ + [ 9] = RCAR_GP_PIN(1, 9), /* MSIOF0_TXD */ + [10] = RCAR_GP_PIN(1, 10), /* MSIOF0_SCK */ + [11] = RCAR_GP_PIN(1, 11), /* MSIOF0_RXD */ + [12] = RCAR_GP_PIN(1, 12), /* HTX0 */ + [13] = RCAR_GP_PIN(1, 13), /* HCTS0_N */ + [14] = RCAR_GP_PIN(1, 14), /* HRTS0_N */ + [15] = RCAR_GP_PIN(1, 15), /* HSCK0 */ + [16] = RCAR_GP_PIN(1, 16), /* HRX0 */ + [17] = RCAR_GP_PIN(1, 17), /* SCIF_CLK */ + [18] = RCAR_GP_PIN(1, 18), /* SSI_SCK */ + [19] = RCAR_GP_PIN(1, 19), /* SSI_WS */ + [20] = RCAR_GP_PIN(1, 20), /* SSI_SD */ + [21] = RCAR_GP_PIN(1, 21), /* AUDIO_CLKOUT */ + [22] = RCAR_GP_PIN(1, 22), /* AUDIO_CLKIN */ + [23] = RCAR_GP_PIN(1, 23), /* GP1_23 */ + [24] = RCAR_GP_PIN(1, 24), /* HRX3 */ + [25] = RCAR_GP_PIN(1, 25), /* HSCK3 */ + [26] = RCAR_GP_PIN(1, 26), /* HRTS3_N */ + [27] = RCAR_GP_PIN(1, 27), /* HCTS3_N */ + [28] = RCAR_GP_PIN(1, 28), /* HTX3 */ + [29] = RCAR_GP_PIN(1, 29), /* ERROROUTC_N */ + [30] = SH_PFC_PIN_NONE, + [31] = SH_PFC_PIN_NONE, + } }, + { PINMUX_BIAS_REG("PUEN2", 0xE60580C0, "PUD2", 0xE60580E0) { + [ 0] = RCAR_GP_PIN(2, 0), /* FXR_TXDA */ + [ 1] = RCAR_GP_PIN(2, 1), /* FXR_TXENA_N */ + [ 2] = RCAR_GP_PIN(2, 2), /* RXDA_EXTFXR */ + [ 3] = RCAR_GP_PIN(2, 3), /* CLK_EXTFXR */ + [ 4] = RCAR_GP_PIN(2, 4), /* RXDB_EXTFXR */ + [ 5] = RCAR_GP_PIN(2, 5), /* FXR_TXENB_N */ + [ 6] = RCAR_GP_PIN(2, 6), /* FXR_TXDB */ + [ 7] = RCAR_GP_PIN(2, 7), /* TPU0TO1 */ + [ 8] = RCAR_GP_PIN(2, 8), /* TPU0TO0 */ + [ 9] = RCAR_GP_PIN(2, 9), /* CAN_CLK */ + [10] = RCAR_GP_PIN(2, 10), /* CANFD0_TX */ + [11] = RCAR_GP_PIN(2, 11), /* CANFD0_RX */ + [12] = RCAR_GP_PIN(2, 12), /* CANFD2_TX */ + [13] = RCAR_GP_PIN(2, 13), /* CANFD2_RX */ + [14] = RCAR_GP_PIN(2, 14), /* CANFD3_TX */ + [15] = RCAR_GP_PIN(2, 15), /* CANFD3_RX */ + [16] = SH_PFC_PIN_NONE, + [17] = RCAR_GP_PIN(2, 17), /* CANFD1_TX */ + [18] = SH_PFC_PIN_NONE, + [19] = RCAR_GP_PIN(2, 19), /* CANFD1_RX */ + [20] = SH_PFC_PIN_NONE, + [21] = SH_PFC_PIN_NONE, + [22] = SH_PFC_PIN_NONE, + [23] = SH_PFC_PIN_NONE, + [24] = SH_PFC_PIN_NONE, + [25] = SH_PFC_PIN_NONE, + [26] = SH_PFC_PIN_NONE, + [27] = SH_PFC_PIN_NONE, + [28] = SH_PFC_PIN_NONE, + [29] = SH_PFC_PIN_NONE, + [30] = SH_PFC_PIN_NONE, + [31] = SH_PFC_PIN_NONE, + } }, + { PINMUX_BIAS_REG("PUEN3", 0xE60588C0, "PUD3", 0xE60588E0) { + [ 0] = RCAR_GP_PIN(3, 0), /* MMC_SD_D1 */ + [ 1] = RCAR_GP_PIN(3, 1), /* MMC_SD_D0 */ + [ 2] = RCAR_GP_PIN(3, 2), /* MMC_SD_D2 */ + [ 3] = RCAR_GP_PIN(3, 3), /* MMC_SD_CLK */ + [ 4] = RCAR_GP_PIN(3, 4), /* MMC_DS */ + [ 5] = RCAR_GP_PIN(3, 5), /* MMC_SD_D3 */ + [ 6] = RCAR_GP_PIN(3, 6), /* MMC_D5 */ + [ 7] = RCAR_GP_PIN(3, 7), /* MMC_D4 */ + [ 8] = RCAR_GP_PIN(3, 8), /* MMC_D7 */ + [ 9] = RCAR_GP_PIN(3, 9), /* MMC_D6 */ + [10] = RCAR_GP_PIN(3, 10), /* MMC_SD_CMD */ + [11] = RCAR_GP_PIN(3, 11), /* SD_CD */ + [12] = RCAR_GP_PIN(3, 12), /* SD_WP */ + [13] = RCAR_GP_PIN(3, 13), /* PWM1 */ + [14] = RCAR_GP_PIN(3, 14), /* PWM2 */ + [15] = RCAR_GP_PIN(3, 15), /* QSPI0_SSL */ + [16] = RCAR_GP_PIN(3, 16), /* QSPI0_IO3 */ + [17] = RCAR_GP_PIN(3, 17), /* QSPI0_IO2 */ + [18] = RCAR_GP_PIN(3, 18), /* QSPI0_MISO_IO1 */ + [19] = RCAR_GP_PIN(3, 19), /* QSPI0_MOSI_IO0 */ + [20] = RCAR_GP_PIN(3, 20), /* QSPI0_SPCLK */ + [21] = RCAR_GP_PIN(3, 21), /* QSPI1_MOSI_IO0 */ + [22] = RCAR_GP_PIN(3, 22), /* QSPI1_SPCLK */ + [23] = RCAR_GP_PIN(3, 23), /* QSPI1_MISO_IO1 */ + [24] = RCAR_GP_PIN(3, 24), /* QSPI1_IO2 */ + [25] = RCAR_GP_PIN(3, 25), /* QSPI1_SSL */ + [26] = RCAR_GP_PIN(3, 26), /* QSPI1_IO3 */ + [27] = RCAR_GP_PIN(3, 27), /* RPC_RESET_N */ + [28] = RCAR_GP_PIN(3, 28), /* RPC_WP_N */ + [29] = RCAR_GP_PIN(3, 29), /* RPC_INT_N */ + [30] = RCAR_GP_PIN(3, 30), /* TCLK3 */ + [31] = RCAR_GP_PIN(3, 31), /* TCLK4 */ + } }, + { PINMUX_BIAS_REG("PUEN4", 0xE60600C0, "PUD4", 0xE60600E0) { + [ 0] = RCAR_GP_PIN(4, 0), /* SCL0 */ + [ 1] = RCAR_GP_PIN(4, 1), /* SDA0 */ + [ 2] = RCAR_GP_PIN(4, 2), /* SCL1 */ + [ 3] = RCAR_GP_PIN(4, 3), /* SDA1 */ + [ 4] = RCAR_GP_PIN(4, 4), /* SCL2 */ + [ 5] = RCAR_GP_PIN(4, 5), /* SDA2 */ + [ 6] = RCAR_GP_PIN(4, 6), /* SCL3 */ + [ 7] = RCAR_GP_PIN(4, 7), /* SDA3 */ + [ 8] = RCAR_GP_PIN(4, 8), /* HRX2 */ + [ 9] = RCAR_GP_PIN(4, 9), /* HTX2 */ + [10] = RCAR_GP_PIN(4, 10), /* HRTS2_N */ + [11] = RCAR_GP_PIN(4, 11), /* SCIF_CLK2 */ + [12] = RCAR_GP_PIN(4, 12), /* HCTS2_N */ + [13] = RCAR_GP_PIN(4, 13), /* HSCK2 */ + [14] = RCAR_GP_PIN(4, 14), /* PWM3 */ + [15] = RCAR_GP_PIN(4, 15), /* PWM4 */ + [16] = SH_PFC_PIN_NONE, + [17] = SH_PFC_PIN_NONE, + [18] = SH_PFC_PIN_NONE, + [19] = SH_PFC_PIN_NONE, + [20] = SH_PFC_PIN_NONE, + [21] = RCAR_GP_PIN(4, 21), /* PCIE0_CLKREQ_N */ + [22] = SH_PFC_PIN_NONE, + [23] = RCAR_GP_PIN(4, 23), /* AVS0 */ + [24] = RCAR_GP_PIN(4, 24), /* AVS1 */ + [25] = SH_PFC_PIN_NONE, + [26] = SH_PFC_PIN_NONE, + [27] = SH_PFC_PIN_NONE, + [28] = SH_PFC_PIN_NONE, + [29] = SH_PFC_PIN_NONE, + [30] = SH_PFC_PIN_NONE, + [31] = SH_PFC_PIN_NONE, + } }, + { PINMUX_BIAS_REG("PUEN5", 0xE60608C0, "PUD5", 0xE60608E0) { + [ 0] = RCAR_GP_PIN(5, 0), /* AVB2_AVTP_PPS */ + [ 1] = RCAR_GP_PIN(5, 1), /* AVB0_AVTP_CAPTURE */ + [ 2] = RCAR_GP_PIN(5, 2), /* AVB2_AVTP_MATCH */ + [ 3] = RCAR_GP_PIN(5, 3), /* AVB2_LINK */ + [ 4] = RCAR_GP_PIN(5, 4), /* AVB2_PHY_INT */ + [ 5] = RCAR_GP_PIN(5, 5), /* AVB2_MAGIC */ + [ 6] = RCAR_GP_PIN(5, 6), /* AVB2_MDC */ + [ 7] = RCAR_GP_PIN(5, 7), /* AVB2_TXCREFCLK */ + [ 8] = RCAR_GP_PIN(5, 8), /* AVB2_TD3 */ + [ 9] = RCAR_GP_PIN(5, 9), /* AVB2_RD3 */ + [10] = RCAR_GP_PIN(5, 10), /* AVB2_MDIO */ + [11] = RCAR_GP_PIN(5, 11), /* AVB2_TD2 */ + [12] = RCAR_GP_PIN(5, 12), /* AVB2_TD1 */ + [13] = RCAR_GP_PIN(5, 13), /* AVB2_RD2 */ + [14] = RCAR_GP_PIN(5, 14), /* AVB2_RD1 */ + [15] = RCAR_GP_PIN(5, 15), /* AVB2_TD0 */ + [16] = RCAR_GP_PIN(5, 16), /* AVB2_TXC */ + [17] = RCAR_GP_PIN(5, 17), /* AVB2_RD0 */ + [18] = RCAR_GP_PIN(5, 18), /* AVB2_RXC */ + [19] = RCAR_GP_PIN(5, 19), /* AVB2_TX_CTL */ + [20] = RCAR_GP_PIN(5, 20), /* AVB2_RX_CTL */ + [21] = SH_PFC_PIN_NONE, + [22] = SH_PFC_PIN_NONE, + [23] = SH_PFC_PIN_NONE, + [24] = SH_PFC_PIN_NONE, + [25] = SH_PFC_PIN_NONE, + [26] = SH_PFC_PIN_NONE, + [27] = SH_PFC_PIN_NONE, + [28] = SH_PFC_PIN_NONE, + [29] = SH_PFC_PIN_NONE, + [30] = SH_PFC_PIN_NONE, + [31] = SH_PFC_PIN_NONE, + } }, + { PINMUX_BIAS_REG("PUEN6", 0xE60610C0, "PUD6", 0xE60610E0) { + [ 0] = RCAR_GP_PIN(6, 0), /* AVB1_MDIO */ + [ 1] = RCAR_GP_PIN(6, 1), /* AVB1_MAGIC */ + [ 2] = RCAR_GP_PIN(6, 2), /* AVB1_MDC */ + [ 3] = RCAR_GP_PIN(6, 3), /* AVB1_PHY_INT */ + [ 4] = RCAR_GP_PIN(6, 4), /* AVB1_LINK */ + [ 5] = RCAR_GP_PIN(6, 5), /* AVB1_AVTP_MATCH */ + [ 6] = RCAR_GP_PIN(6, 6), /* AVB1_TXC */ + [ 7] = RCAR_GP_PIN(6, 7), /* AVB1_TX_CTL */ + [ 8] = RCAR_GP_PIN(6, 8), /* AVB1_RXC */ + [ 9] = RCAR_GP_PIN(6, 9), /* AVB1_RX_CTL */ + [10] = RCAR_GP_PIN(6, 10), /* AVB1_AVTP_PPS */ + [11] = RCAR_GP_PIN(6, 11), /* AVB1_AVTP_CAPTURE */ + [12] = RCAR_GP_PIN(6, 12), /* AVB1_TD1 */ + [13] = RCAR_GP_PIN(6, 13), /* AVB1_TD0 */ + [14] = RCAR_GP_PIN(6, 14), /* AVB1_RD1*/ + [15] = RCAR_GP_PIN(6, 15), /* AVB1_RD0 */ + [16] = RCAR_GP_PIN(6, 16), /* AVB1_TD2 */ + [17] = RCAR_GP_PIN(6, 17), /* AVB1_RD2 */ + [18] = RCAR_GP_PIN(6, 18), /* AVB1_TD3 */ + [19] = RCAR_GP_PIN(6, 19), /* AVB1_RD3 */ + [20] = RCAR_GP_PIN(6, 20), /* AVB1_TXCREFCLK */ + [21] = SH_PFC_PIN_NONE, + [22] = SH_PFC_PIN_NONE, + [23] = SH_PFC_PIN_NONE, + [24] = SH_PFC_PIN_NONE, + [25] = SH_PFC_PIN_NONE, + [26] = SH_PFC_PIN_NONE, + [27] = SH_PFC_PIN_NONE, + [28] = SH_PFC_PIN_NONE, + [29] = SH_PFC_PIN_NONE, + [30] = SH_PFC_PIN_NONE, + [31] = SH_PFC_PIN_NONE, + } }, + { PINMUX_BIAS_REG("PUEN7", 0xE60618C0, "PUD7", 0xE60618E0) { + [ 0] = RCAR_GP_PIN(7, 0), /* AVB0_AVTP_PPS */ + [ 1] = RCAR_GP_PIN(7, 1), /* AVB0_AVTP_CAPTURE */ + [ 2] = RCAR_GP_PIN(7, 2), /* AVB0_AVTP_MATCH */ + [ 3] = RCAR_GP_PIN(7, 3), /* AVB0_TD3 */ + [ 4] = RCAR_GP_PIN(7, 4), /* AVB0_LINK */ + [ 5] = RCAR_GP_PIN(7, 5), /* AVB0_PHY_INT */ + [ 6] = RCAR_GP_PIN(7, 6), /* AVB0_TD2 */ + [ 7] = RCAR_GP_PIN(7, 7), /* AVB0_TD1 */ + [ 8] = RCAR_GP_PIN(7, 8), /* AVB0_RD3 */ + [ 9] = RCAR_GP_PIN(7, 9), /* AVB0_TXCREFCLK */ + [10] = RCAR_GP_PIN(7, 10), /* AVB0_MAGIC */ + [11] = RCAR_GP_PIN(7, 11), /* AVB0_TD0 */ + [12] = RCAR_GP_PIN(7, 12), /* AVB0_RD2 */ + [13] = RCAR_GP_PIN(7, 13), /* AVB0_MDC */ + [14] = RCAR_GP_PIN(7, 14), /* AVB0_MDIO */ + [15] = RCAR_GP_PIN(7, 15), /* AVB0_TXC */ + [16] = RCAR_GP_PIN(7, 16), /* AVB0_TX_CTL */ + [17] = RCAR_GP_PIN(7, 17), /* AVB0_RD1 */ + [18] = RCAR_GP_PIN(7, 18), /* AVB0_RD0 */ + [19] = RCAR_GP_PIN(7, 19), /* AVB0_RXC */ + [20] = RCAR_GP_PIN(7, 20), /* AVB0_RX_CTL */ + [21] = SH_PFC_PIN_NONE, + [22] = SH_PFC_PIN_NONE, + [23] = SH_PFC_PIN_NONE, + [24] = SH_PFC_PIN_NONE, + [25] = SH_PFC_PIN_NONE, + [26] = SH_PFC_PIN_NONE, + [27] = SH_PFC_PIN_NONE, + [28] = SH_PFC_PIN_NONE, + [29] = SH_PFC_PIN_NONE, + [30] = SH_PFC_PIN_NONE, + [31] = SH_PFC_PIN_NONE, + } }, + { /* sentinel */ }, +}; + +static const struct sh_pfc_soc_operations r8a779h0_pin_ops = { + .pin_to_pocctrl = r8a779h0_pin_to_pocctrl, + .get_bias = rcar_pinmux_get_bias, + .set_bias = rcar_pinmux_set_bias, +}; + +const struct sh_pfc_soc_info r8a779h0_pinmux_info = { + .name = "r8a779h0_pfc", + .ops = &r8a779h0_pin_ops, + .unlock_reg = 0x1ff, /* PMMRn mask */ + + .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, + + .pins = pinmux_pins, + .nr_pins = ARRAY_SIZE(pinmux_pins), + .groups = pinmux_groups, + .nr_groups = ARRAY_SIZE(pinmux_groups), + .functions = pinmux_functions, + .nr_functions = ARRAY_SIZE(pinmux_functions), + + .cfg_regs = pinmux_config_regs, + .drive_regs = pinmux_drive_regs, + .bias_regs = pinmux_bias_regs, + .ioctrl_regs = pinmux_ioctrl_regs, + + .pinmux_data = pinmux_data, + .pinmux_data_size = ARRAY_SIZE(pinmux_data), +}; diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c index 80fb5011c7bb..eb5a8c654260 100644 --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c @@ -5,6 +5,7 @@ * Copyright (C) 2021 Renesas Electronics Corporation. */ +#include <linux/bitfield.h> #include <linux/bitops.h> #include <linux/clk.h> #include <linux/gpio/driver.h> @@ -38,8 +39,6 @@ */ #define MUX_PIN_ID_MASK GENMASK(15, 0) #define MUX_FUNC_MASK GENMASK(31, 16) -#define MUX_FUNC_OFFS 16 -#define MUX_FUNC(pinconf) (((pinconf) & MUX_FUNC_MASK) >> MUX_FUNC_OFFS) /* PIN capabilities */ #define PIN_CFG_IOLH_A BIT(0) @@ -58,6 +57,8 @@ #define PIN_CFG_IOLH_C BIT(13) #define PIN_CFG_SOFT_PS BIT(14) #define PIN_CFG_OEN BIT(15) +#define PIN_CFG_VARIABLE BIT(16) +#define PIN_CFG_NOGPIO_INT BIT(17) #define RZG2L_MPXED_COMMON_PIN_FUNCS(group) \ (PIN_CFG_IOLH_##group | \ @@ -77,27 +78,41 @@ PIN_CFG_FILNUM | \ PIN_CFG_FILCLKSEL) +#define PIN_CFG_PIN_MAP_MASK GENMASK_ULL(35, 28) +#define PIN_CFG_PIN_REG_MASK GENMASK(27, 20) +#define PIN_CFG_MASK GENMASK(19, 0) + +/* + * m indicates the bitmap of supported pins, a is the register index + * and f is pin configuration capabilities supported. + */ +#define RZG2L_GPIO_PORT_SPARSE_PACK(m, a, f) (FIELD_PREP_CONST(PIN_CFG_PIN_MAP_MASK, (m)) | \ + FIELD_PREP_CONST(PIN_CFG_PIN_REG_MASK, (a)) | \ + FIELD_PREP_CONST(PIN_CFG_MASK, (f))) + /* * n indicates number of pins in the port, a is the register index * and f is pin configuration capabilities supported. */ -#define RZG2L_GPIO_PORT_PACK(n, a, f) (((n) << 28) | ((a) << 20) | (f)) -#define RZG2L_GPIO_PORT_GET_PINCNT(x) (((x) & GENMASK(30, 28)) >> 28) +#define RZG2L_GPIO_PORT_PACK(n, a, f) RZG2L_GPIO_PORT_SPARSE_PACK((1ULL << (n)) - 1, (a), (f)) /* - * BIT(31) indicates dedicated pin, p is the register index while + * BIT(63) indicates dedicated pin, p is the register index while * referencing to SR/IEN/IOLH/FILxx registers, b is the register bits * (b * 8) and f is the pin configuration capabilities supported. */ -#define RZG2L_SINGLE_PIN BIT(31) +#define RZG2L_SINGLE_PIN BIT_ULL(63) +#define RZG2L_SINGLE_PIN_INDEX_MASK GENMASK(30, 24) +#define RZG2L_SINGLE_PIN_BITS_MASK GENMASK(22, 20) + #define RZG2L_SINGLE_PIN_PACK(p, b, f) (RZG2L_SINGLE_PIN | \ - ((p) << 24) | ((b) << 20) | (f)) -#define RZG2L_SINGLE_PIN_GET_BIT(x) (((x) & GENMASK(22, 20)) >> 20) + FIELD_PREP_CONST(RZG2L_SINGLE_PIN_INDEX_MASK, (p)) | \ + FIELD_PREP_CONST(RZG2L_SINGLE_PIN_BITS_MASK, (b)) | \ + FIELD_PREP_CONST(PIN_CFG_MASK, (f))) -#define RZG2L_PIN_CFG_TO_CAPS(cfg) ((cfg) & GENMASK(19, 0)) #define RZG2L_PIN_CFG_TO_PORT_OFFSET(cfg) ((cfg) & RZG2L_SINGLE_PIN ? \ - (((cfg) & GENMASK(30, 24)) >> 24) : \ - (((cfg) & GENMASK(26, 20)) >> 20)) + FIELD_GET(RZG2L_SINGLE_PIN_INDEX_MASK, (cfg)) : \ + FIELD_GET(PIN_CFG_PIN_REG_MASK, (cfg))) #define P(off) (0x0000 + (off)) #define PM(off) (0x0100 + (off) * 2) @@ -134,6 +149,33 @@ #define RZG2L_TINT_IRQ_START_INDEX 9 #define RZG2L_PACK_HWIRQ(t, i) (((t) << 16) | (i)) +/* Read/write 8 bits register */ +#define RZG2L_PCTRL_REG_ACCESS8(_read, _addr, _val) \ + do { \ + if (_read) \ + _val = readb(_addr); \ + else \ + writeb(_val, _addr); \ + } while (0) + +/* Read/write 16 bits register */ +#define RZG2L_PCTRL_REG_ACCESS16(_read, _addr, _val) \ + do { \ + if (_read) \ + _val = readw(_addr); \ + else \ + writew(_val, _addr); \ + } while (0) + +/* Read/write 32 bits register */ +#define RZG2L_PCTRL_REG_ACCESS32(_read, _addr, _val) \ + do { \ + if (_read) \ + _val = readl(_addr); \ + else \ + writel(_val, _addr); \ + } while (0) + /** * struct rzg2l_register_offsets - specific register offsets * @pwpr: PWPR register offset @@ -189,17 +231,31 @@ struct rzg2l_hwcfg { struct rzg2l_dedicated_configs { const char *name; - u32 config; + u64 config; +}; + +/** + * struct rzg2l_variable_pin_cfg - pin data cfg + * @cfg: port pin configuration + * @port: port number + * @pin: port pin + */ +struct rzg2l_variable_pin_cfg { + u32 cfg:20; + u32 port:5; + u32 pin:3; }; struct rzg2l_pinctrl_data { const char * const *port_pins; - const u32 *port_pin_configs; + const u64 *port_pin_configs; unsigned int n_ports; const struct rzg2l_dedicated_configs *dedicated_pins; unsigned int n_port_pins; unsigned int n_dedicated_pins; const struct rzg2l_hwcfg *hwcfg; + const struct rzg2l_variable_pin_cfg *variable_pin_cfg; + unsigned int n_variable_pin_cfg; }; /** @@ -212,6 +268,32 @@ struct rzg2l_pinctrl_pin_settings { u16 drive_strength_ua; }; +/** + * struct rzg2l_pinctrl_reg_cache - register cache structure (to be used in suspend/resume) + * @p: P registers cache + * @pm: PM registers cache + * @pmc: PMC registers cache + * @pfc: PFC registers cache + * @iolh: IOLH registers cache + * @ien: IEN registers cache + * @sd_ch: SD_CH registers cache + * @eth_poc: ET_POC registers cache + * @eth_mode: ETH_MODE register cache + * @qspi: QSPI registers cache + */ +struct rzg2l_pinctrl_reg_cache { + u8 *p; + u16 *pm; + u8 *pmc; + u32 *pfc; + u32 *iolh[2]; + u32 *ien[2]; + u8 sd_ch[2]; + u8 eth_poc[2]; + u8 eth_mode; + u8 qspi; +}; + struct rzg2l_pinctrl { struct pinctrl_dev *pctl; struct pinctrl_desc desc; @@ -221,6 +303,8 @@ struct rzg2l_pinctrl { void __iomem *base; struct device *dev; + struct clk *clk; + struct gpio_chip gpio_chip; struct pinctrl_gpio_range gpio_range; DECLARE_BITMAP(tint_slot, RZG2L_TINT_MAX_INTERRUPT); @@ -231,10 +315,150 @@ struct rzg2l_pinctrl { struct mutex mutex; /* serialize adding groups and functions */ struct rzg2l_pinctrl_pin_settings *settings; + struct rzg2l_pinctrl_reg_cache *cache; + struct rzg2l_pinctrl_reg_cache *dedicated_cache; + atomic_t wakeup_path; }; static const u16 available_ps[] = { 1800, 2500, 3300 }; +#ifdef CONFIG_RISCV +static u64 rzg2l_pinctrl_get_variable_pin_cfg(struct rzg2l_pinctrl *pctrl, + u64 pincfg, + unsigned int port, + u8 pin) +{ + unsigned int i; + + for (i = 0; i < pctrl->data->n_variable_pin_cfg; i++) { + if (pctrl->data->variable_pin_cfg[i].port == port && + pctrl->data->variable_pin_cfg[i].pin == pin) + return (pincfg & ~PIN_CFG_VARIABLE) | pctrl->data->variable_pin_cfg[i].cfg; + } + + return 0; +} + +static const struct rzg2l_variable_pin_cfg r9a07g043f_variable_pin_cfg[] = { + { + .port = 20, + .pin = 0, + .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD | + PIN_CFG_FILONOFF | PIN_CFG_FILNUM | PIN_CFG_FILCLKSEL | + PIN_CFG_IEN | PIN_CFG_NOGPIO_INT, + }, + { + .port = 20, + .pin = 1, + .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD | + PIN_CFG_FILONOFF | PIN_CFG_FILNUM | PIN_CFG_FILCLKSEL | + PIN_CFG_IEN | PIN_CFG_NOGPIO_INT, + }, + { + .port = 20, + .pin = 2, + .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD | + PIN_CFG_FILONOFF | PIN_CFG_FILNUM | PIN_CFG_FILCLKSEL | + PIN_CFG_IEN | PIN_CFG_NOGPIO_INT, + }, + { + .port = 20, + .pin = 3, + .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD | + PIN_CFG_IEN | PIN_CFG_NOGPIO_INT, + }, + { + .port = 20, + .pin = 4, + .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD | + PIN_CFG_IEN | PIN_CFG_NOGPIO_INT, + }, + { + .port = 20, + .pin = 5, + .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD | + PIN_CFG_IEN | PIN_CFG_NOGPIO_INT, + }, + { + .port = 20, + .pin = 6, + .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD | + PIN_CFG_IEN | PIN_CFG_NOGPIO_INT, + }, + { + .port = 20, + .pin = 7, + .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD | + PIN_CFG_IEN | PIN_CFG_NOGPIO_INT, + }, + { + .port = 23, + .pin = 1, + .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD | + PIN_CFG_NOGPIO_INT + }, + { + .port = 23, + .pin = 2, + .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD | + PIN_CFG_NOGPIO_INT, + }, + { + .port = 23, + .pin = 3, + .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD | + PIN_CFG_NOGPIO_INT, + }, + { + .port = 23, + .pin = 4, + .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD | + PIN_CFG_NOGPIO_INT, + }, + { + .port = 23, + .pin = 5, + .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_NOGPIO_INT, + }, + { + .port = 24, + .pin = 0, + .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_NOGPIO_INT, + }, + { + .port = 24, + .pin = 1, + .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD | + PIN_CFG_NOGPIO_INT, + }, + { + .port = 24, + .pin = 2, + .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD | + PIN_CFG_NOGPIO_INT, + }, + { + .port = 24, + .pin = 3, + .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD | + PIN_CFG_NOGPIO_INT, + }, + { + .port = 24, + .pin = 4, + .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD | + PIN_CFG_NOGPIO_INT, + }, + { + .port = 24, + .pin = 5, + .cfg = PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD | + PIN_CFG_FILONOFF | PIN_CFG_FILNUM | PIN_CFG_FILCLKSEL | + PIN_CFG_NOGPIO_INT, + }, +}; +#endif + static void rzg2l_pinctrl_set_pfc_mode(struct rzg2l_pinctrl *pctrl, u8 pin, u8 off, u8 func) { @@ -295,7 +519,7 @@ static int rzg2l_pinctrl_set_mux(struct pinctrl_dev *pctldev, pins = group->grp.pins; for (i = 0; i < group->grp.npins; i++) { - unsigned int *pin_data = pctrl->desc.pins[pins[i]].drv_data; + u64 *pin_data = pctrl->desc.pins[pins[i]].drv_data; u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data); u32 pin = RZG2L_PIN_ID_TO_PIN(pins[i]); @@ -432,8 +656,8 @@ static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev, ret = of_property_read_u32_index(np, "pinmux", i, &value); if (ret) goto done; - pins[i] = value & MUX_PIN_ID_MASK; - psel_val[i] = MUX_FUNC(value); + pins[i] = FIELD_GET(MUX_PIN_ID_MASK, value); + psel_val[i] = FIELD_GET(MUX_FUNC_MASK, value); } if (parent) { @@ -447,6 +671,16 @@ static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev, name = np->name; } + if (num_configs) { + ret = rzg2l_map_add_config(&maps[idx], name, + PIN_MAP_TYPE_CONFIGS_GROUP, + configs, num_configs); + if (ret < 0) + goto done; + + idx++; + } + mutex_lock(&pctrl->mutex); /* Register a single pin group listing all the pins we read from DT */ @@ -474,16 +708,6 @@ static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev, maps[idx].data.mux.function = name; idx++; - if (num_configs) { - ret = rzg2l_map_add_config(&maps[idx], name, - PIN_MAP_TYPE_CONFIGS_GROUP, - configs, num_configs); - if (ret < 0) - goto remove_group; - - idx++; - } - dev_dbg(pctrl->dev, "Parsed %pOF with %d pins\n", np, num_pinmux); ret = 0; goto done; @@ -558,13 +782,13 @@ done: } static int rzg2l_validate_gpio_pin(struct rzg2l_pinctrl *pctrl, - u32 cfg, u32 port, u8 bit) + u64 cfg, u32 port, u8 bit) { - u8 pincount = RZG2L_GPIO_PORT_GET_PINCNT(cfg); + u8 pinmap = FIELD_GET(PIN_CFG_PIN_MAP_MASK, cfg); u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(cfg); - u32 data; + u64 data; - if (bit >= pincount || port >= pctrl->data->n_port_pins) + if (!(pinmap & BIT(bit)) || port >= pctrl->data->n_port_pins) return -EINVAL; data = pctrl->data->port_pin_configs[port]; @@ -856,7 +1080,7 @@ static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *pctldev, enum pin_config_param param = pinconf_to_config_param(*config); const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg; const struct pinctrl_pin_desc *pin = &pctrl->desc.pins[_pin]; - unsigned int *pin_data = pin->drv_data; + u64 *pin_data = pin->drv_data; unsigned int arg = 0; u32 off, cfg; int ret; @@ -866,9 +1090,9 @@ static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *pctldev, return -EINVAL; off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data); - cfg = RZG2L_PIN_CFG_TO_CAPS(*pin_data); + cfg = FIELD_GET(PIN_CFG_MASK, *pin_data); if (*pin_data & RZG2L_SINGLE_PIN) { - bit = RZG2L_SINGLE_PIN_GET_BIT(*pin_data); + bit = FIELD_GET(RZG2L_SINGLE_PIN_BITS_MASK, *pin_data); } else { bit = RZG2L_PIN_ID_TO_PIN(_pin); @@ -959,7 +1183,7 @@ static int rzg2l_pinctrl_pinconf_set(struct pinctrl_dev *pctldev, const struct pinctrl_pin_desc *pin = &pctrl->desc.pins[_pin]; const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg; struct rzg2l_pinctrl_pin_settings settings = pctrl->settings[_pin]; - unsigned int *pin_data = pin->drv_data; + u64 *pin_data = pin->drv_data; enum pin_config_param param; unsigned int i, arg, index; u32 cfg, off; @@ -970,9 +1194,9 @@ static int rzg2l_pinctrl_pinconf_set(struct pinctrl_dev *pctldev, return -EINVAL; off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data); - cfg = RZG2L_PIN_CFG_TO_CAPS(*pin_data); + cfg = FIELD_GET(PIN_CFG_MASK, *pin_data); if (*pin_data & RZG2L_SINGLE_PIN) { - bit = RZG2L_SINGLE_PIN_GET_BIT(*pin_data); + bit = FIELD_GET(RZG2L_SINGLE_PIN_BITS_MASK, *pin_data); } else { bit = RZG2L_PIN_ID_TO_PIN(_pin); @@ -1164,7 +1388,7 @@ static int rzg2l_gpio_request(struct gpio_chip *chip, unsigned int offset) { struct rzg2l_pinctrl *pctrl = gpiochip_get_data(chip); const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[offset]; - u32 *pin_data = pin_desc->drv_data; + u64 *pin_data = pin_desc->drv_data; u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data); u32 port = RZG2L_PIN_ID_TO_PORT(offset); u8 bit = RZG2L_PIN_ID_TO_PIN(offset); @@ -1196,7 +1420,7 @@ static void rzg2l_gpio_set_direction(struct rzg2l_pinctrl *pctrl, u32 offset, bool output) { const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[offset]; - unsigned int *pin_data = pin_desc->drv_data; + u64 *pin_data = pin_desc->drv_data; u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data); u8 bit = RZG2L_PIN_ID_TO_PIN(offset); unsigned long flags; @@ -1217,7 +1441,7 @@ static int rzg2l_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) { struct rzg2l_pinctrl *pctrl = gpiochip_get_data(chip); const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[offset]; - unsigned int *pin_data = pin_desc->drv_data; + u64 *pin_data = pin_desc->drv_data; u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data); u8 bit = RZG2L_PIN_ID_TO_PIN(offset); @@ -1248,7 +1472,7 @@ static void rzg2l_gpio_set(struct gpio_chip *chip, unsigned int offset, { struct rzg2l_pinctrl *pctrl = gpiochip_get_data(chip); const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[offset]; - unsigned int *pin_data = pin_desc->drv_data; + u64 *pin_data = pin_desc->drv_data; u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data); u8 bit = RZG2L_PIN_ID_TO_PIN(offset); unsigned long flags; @@ -1281,7 +1505,7 @@ static int rzg2l_gpio_get(struct gpio_chip *chip, unsigned int offset) { struct rzg2l_pinctrl *pctrl = gpiochip_get_data(chip); const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[offset]; - unsigned int *pin_data = pin_desc->drv_data; + u64 *pin_data = pin_desc->drv_data; u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data); u8 bit = RZG2L_PIN_ID_TO_PIN(offset); u16 reg16; @@ -1366,7 +1590,7 @@ static const char * const rzg2l_gpio_names[] = { "P48_0", "P48_1", "P48_2", "P48_3", "P48_4", "P48_5", "P48_6", "P48_7", }; -static const u32 r9a07g044_gpio_configs[] = { +static const u64 r9a07g044_gpio_configs[] = { RZG2L_GPIO_PORT_PACK(2, 0x10, RZG2L_MPXED_PIN_FUNCS), RZG2L_GPIO_PORT_PACK(2, 0x11, RZG2L_MPXED_PIN_FUNCS), RZG2L_GPIO_PORT_PACK(2, 0x12, RZG2L_MPXED_PIN_FUNCS), @@ -1418,7 +1642,7 @@ static const u32 r9a07g044_gpio_configs[] = { RZG2L_GPIO_PORT_PACK(5, 0x40, RZG2L_MPXED_PIN_FUNCS), }; -static const u32 r9a07g043_gpio_configs[] = { +static const u64 r9a07g043_gpio_configs[] = { RZG2L_GPIO_PORT_PACK(4, 0x10, RZG2L_MPXED_PIN_FUNCS), RZG2L_GPIO_PORT_PACK(5, 0x11, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH0)), RZG2L_GPIO_PORT_PACK(4, 0x12, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH0)), @@ -1438,9 +1662,28 @@ static const u32 r9a07g043_gpio_configs[] = { RZG2L_GPIO_PORT_PACK(2, 0x20, RZG2L_MPXED_PIN_FUNCS), RZG2L_GPIO_PORT_PACK(4, 0x21, RZG2L_MPXED_PIN_FUNCS), RZG2L_GPIO_PORT_PACK(6, 0x22, RZG2L_MPXED_PIN_FUNCS), +#ifdef CONFIG_RISCV + /* Below additional port pins (P19 - P28) are exclusively available on RZ/Five SoC only */ + RZG2L_GPIO_PORT_SPARSE_PACK(0x2, 0x06, PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD | + PIN_CFG_FILONOFF | PIN_CFG_FILNUM | PIN_CFG_FILCLKSEL | + PIN_CFG_IEN | PIN_CFG_NOGPIO_INT), /* P19 */ + RZG2L_GPIO_PORT_PACK(8, 0x07, PIN_CFG_VARIABLE), /* P20 */ + RZG2L_GPIO_PORT_SPARSE_PACK(0x2, 0x08, PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD | + PIN_CFG_IEN | PIN_CFG_NOGPIO_INT), /* P21 */ + RZG2L_GPIO_PORT_PACK(4, 0x09, PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_PUPD | + PIN_CFG_IEN | PIN_CFG_NOGPIO_INT), /* P22 */ + RZG2L_GPIO_PORT_SPARSE_PACK(0x3e, 0x0a, PIN_CFG_VARIABLE), /* P23 */ + RZG2L_GPIO_PORT_PACK(6, 0x0b, PIN_CFG_VARIABLE), /* P24 */ + RZG2L_GPIO_PORT_SPARSE_PACK(0x2, 0x0c, PIN_CFG_IOLH_B | PIN_CFG_SR | PIN_CFG_FILONOFF | + PIN_CFG_FILNUM | PIN_CFG_FILCLKSEL | + PIN_CFG_NOGPIO_INT), /* P25 */ + 0x0, /* P26 */ + 0x0, /* P27 */ + RZG2L_GPIO_PORT_PACK(6, 0x0f, RZG2L_MPXED_PIN_FUNCS | PIN_CFG_NOGPIO_INT), /* P28 */ +#endif }; -static const u32 r9a08g045_gpio_configs[] = { +static const u64 r9a08g045_gpio_configs[] = { RZG2L_GPIO_PORT_PACK(4, 0x20, RZG3S_MPXED_PIN_FUNCS(A)), /* P0 */ RZG2L_GPIO_PORT_PACK(5, 0x30, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IOLH_C | PIN_CFG_IO_VMC_ETH0)) | @@ -1598,40 +1841,42 @@ static const struct rzg2l_dedicated_configs rzg3s_dedicated_pins[] = { PIN_CFG_IO_VMC_SD1)) }, }; -static int rzg2l_gpio_get_gpioint(unsigned int virq, const struct rzg2l_pinctrl_data *data) +static int rzg2l_gpio_get_gpioint(unsigned int virq, struct rzg2l_pinctrl *pctrl) { + const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[virq]; + const struct rzg2l_pinctrl_data *data = pctrl->data; + u64 *pin_data = pin_desc->drv_data; unsigned int gpioint; unsigned int i; u32 port, bit; + if (*pin_data & PIN_CFG_NOGPIO_INT) + return -EINVAL; + port = virq / 8; bit = virq % 8; if (port >= data->n_ports || - bit >= RZG2L_GPIO_PORT_GET_PINCNT(data->port_pin_configs[port])) + bit >= hweight8(FIELD_GET(PIN_CFG_PIN_MAP_MASK, data->port_pin_configs[port]))) return -EINVAL; gpioint = bit; for (i = 0; i < port; i++) - gpioint += RZG2L_GPIO_PORT_GET_PINCNT(data->port_pin_configs[i]); + gpioint += hweight8(FIELD_GET(PIN_CFG_PIN_MAP_MASK, data->port_pin_configs[i])); return gpioint; } -static void rzg2l_gpio_irq_disable(struct irq_data *d) +static void rzg2l_gpio_irq_endisable(struct rzg2l_pinctrl *pctrl, + unsigned int hwirq, bool enable) { - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct rzg2l_pinctrl *pctrl = container_of(gc, struct rzg2l_pinctrl, gpio_chip); - unsigned int hwirq = irqd_to_hwirq(d); const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[hwirq]; - unsigned int *pin_data = pin_desc->drv_data; + u64 *pin_data = pin_desc->drv_data; u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data); u8 bit = RZG2L_PIN_ID_TO_PIN(hwirq); unsigned long flags; void __iomem *addr; - irq_chip_disable_parent(d); - addr = pctrl->base + ISEL(off); if (bit >= 4) { bit -= 4; @@ -1639,36 +1884,28 @@ static void rzg2l_gpio_irq_disable(struct irq_data *d) } spin_lock_irqsave(&pctrl->lock, flags); - writel(readl(addr) & ~BIT(bit * 8), addr); + if (enable) + writel(readl(addr) | BIT(bit * 8), addr); + else + writel(readl(addr) & ~BIT(bit * 8), addr); spin_unlock_irqrestore(&pctrl->lock, flags); +} +static void rzg2l_gpio_irq_disable(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + unsigned int hwirq = irqd_to_hwirq(d); + + irq_chip_disable_parent(d); gpiochip_disable_irq(gc, hwirq); } static void rzg2l_gpio_irq_enable(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct rzg2l_pinctrl *pctrl = container_of(gc, struct rzg2l_pinctrl, gpio_chip); unsigned int hwirq = irqd_to_hwirq(d); - const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[hwirq]; - unsigned int *pin_data = pin_desc->drv_data; - u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data); - u8 bit = RZG2L_PIN_ID_TO_PIN(hwirq); - unsigned long flags; - void __iomem *addr; gpiochip_enable_irq(gc, hwirq); - - addr = pctrl->base + ISEL(off); - if (bit >= 4) { - bit -= 4; - addr += 4; - } - - spin_lock_irqsave(&pctrl->lock, flags); - writel(readl(addr) | BIT(bit * 8), addr); - spin_unlock_irqrestore(&pctrl->lock, flags); - irq_chip_enable_parent(d); } @@ -1689,6 +1926,28 @@ static void rzg2l_gpio_irq_print_chip(struct irq_data *data, struct seq_file *p) seq_printf(p, dev_name(gc->parent)); } +static int rzg2l_gpio_irq_set_wake(struct irq_data *data, unsigned int on) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + struct rzg2l_pinctrl *pctrl = container_of(gc, struct rzg2l_pinctrl, gpio_chip); + int ret; + + /* It should not happen. */ + if (!data->parent_data) + return -EOPNOTSUPP; + + ret = irq_chip_set_wake_parent(data, on); + if (ret) + return ret; + + if (on) + atomic_inc(&pctrl->wakeup_path); + else + atomic_dec(&pctrl->wakeup_path); + + return 0; +} + static const struct irq_chip rzg2l_gpio_irqchip = { .name = "rzg2l-gpio", .irq_disable = rzg2l_gpio_irq_disable, @@ -1699,10 +1958,31 @@ static const struct irq_chip rzg2l_gpio_irqchip = { .irq_eoi = rzg2l_gpio_irqc_eoi, .irq_print_chip = rzg2l_gpio_irq_print_chip, .irq_set_affinity = irq_chip_set_affinity_parent, + .irq_set_wake = rzg2l_gpio_irq_set_wake, .flags = IRQCHIP_IMMUTABLE, GPIOCHIP_IRQ_RESOURCE_HELPERS, }; +static int rzg2l_gpio_interrupt_input_mode(struct gpio_chip *chip, unsigned int offset) +{ + struct rzg2l_pinctrl *pctrl = gpiochip_get_data(chip); + const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[offset]; + u64 *pin_data = pin_desc->drv_data; + u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data); + u8 bit = RZG2L_PIN_ID_TO_PIN(offset); + u8 reg8; + int ret; + + reg8 = readb(pctrl->base + PMC(off)); + if (reg8 & BIT(bit)) { + ret = rzg2l_gpio_request(chip, offset); + if (ret) + return ret; + } + + return rzg2l_gpio_direction_input(chip, offset); +} + static int rzg2l_gpio_child_to_parent_hwirq(struct gpio_chip *gc, unsigned int child, unsigned int child_type, @@ -1712,16 +1992,25 @@ static int rzg2l_gpio_child_to_parent_hwirq(struct gpio_chip *gc, struct rzg2l_pinctrl *pctrl = gpiochip_get_data(gc); unsigned long flags; int gpioint, irq; + int ret; - gpioint = rzg2l_gpio_get_gpioint(child, pctrl->data); + gpioint = rzg2l_gpio_get_gpioint(child, pctrl); if (gpioint < 0) return gpioint; + ret = rzg2l_gpio_interrupt_input_mode(gc, child); + if (ret) + return ret; + spin_lock_irqsave(&pctrl->bitmap_lock, flags); irq = bitmap_find_free_region(pctrl->tint_slot, RZG2L_TINT_MAX_INTERRUPT, get_order(1)); spin_unlock_irqrestore(&pctrl->bitmap_lock, flags); - if (irq < 0) - return -ENOSPC; + if (irq < 0) { + ret = -ENOSPC; + goto err; + } + + rzg2l_gpio_irq_endisable(pctrl, child, true); pctrl->hwirq[irq] = child; irq += RZG2L_TINT_IRQ_START_INDEX; @@ -1729,6 +2018,10 @@ static int rzg2l_gpio_child_to_parent_hwirq(struct gpio_chip *gc, *parent_type = IRQ_TYPE_LEVEL_HIGH; *parent = RZG2L_PACK_HWIRQ(gpioint, irq); return 0; + +err: + rzg2l_gpio_free(gc, child); + return ret; } static int rzg2l_gpio_populate_parent_fwspec(struct gpio_chip *chip, @@ -1746,6 +2039,35 @@ static int rzg2l_gpio_populate_parent_fwspec(struct gpio_chip *chip, return 0; } +static void rzg2l_gpio_irq_restore(struct rzg2l_pinctrl *pctrl) +{ + struct irq_domain *domain = pctrl->gpio_chip.irq.domain; + + for (unsigned int i = 0; i < RZG2L_TINT_MAX_INTERRUPT; i++) { + struct irq_data *data; + unsigned int virq; + + if (!pctrl->hwirq[i]) + continue; + + virq = irq_find_mapping(domain, pctrl->hwirq[i]); + if (!virq) { + dev_crit(pctrl->dev, "Failed to find IRQ mapping for hwirq %u\n", + pctrl->hwirq[i]); + continue; + } + + data = irq_domain_get_irq_data(domain, virq); + if (!data) { + dev_crit(pctrl->dev, "Failed to get IRQ data for virq=%u\n", virq); + continue; + } + + if (!irqd_irq_disabled(data)) + rzg2l_gpio_irq_enable(data); + } +} + static void rzg2l_gpio_irq_domain_free(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs) { @@ -1761,6 +2083,8 @@ static void rzg2l_gpio_irq_domain_free(struct irq_domain *domain, unsigned int v for (i = 0; i < RZG2L_TINT_MAX_INTERRUPT; i++) { if (pctrl->hwirq[i] == hwirq) { + rzg2l_gpio_irq_endisable(pctrl, hwirq, false); + rzg2l_gpio_free(gc, hwirq); spin_lock_irqsave(&pctrl->bitmap_lock, flags); bitmap_release_region(pctrl->tint_slot, i, get_order(1)); spin_unlock_irqrestore(&pctrl->bitmap_lock, flags); @@ -1788,11 +2112,74 @@ static void rzg2l_init_irq_valid_mask(struct gpio_chip *gc, bit = offset % 8; if (port >= pctrl->data->n_ports || - bit >= RZG2L_GPIO_PORT_GET_PINCNT(pctrl->data->port_pin_configs[port])) + bit >= hweight8(FIELD_GET(PIN_CFG_PIN_MAP_MASK, + pctrl->data->port_pin_configs[port]))) clear_bit(offset, valid_mask); } } +static int rzg2l_pinctrl_reg_cache_alloc(struct rzg2l_pinctrl *pctrl) +{ + u32 nports = pctrl->data->n_port_pins / RZG2L_PINS_PER_PORT; + struct rzg2l_pinctrl_reg_cache *cache, *dedicated_cache; + + cache = devm_kzalloc(pctrl->dev, sizeof(*cache), GFP_KERNEL); + if (!cache) + return -ENOMEM; + + dedicated_cache = devm_kzalloc(pctrl->dev, sizeof(*dedicated_cache), GFP_KERNEL); + if (!dedicated_cache) + return -ENOMEM; + + cache->p = devm_kcalloc(pctrl->dev, nports, sizeof(*cache->p), GFP_KERNEL); + if (!cache->p) + return -ENOMEM; + + cache->pm = devm_kcalloc(pctrl->dev, nports, sizeof(*cache->pm), GFP_KERNEL); + if (!cache->pm) + return -ENOMEM; + + cache->pmc = devm_kcalloc(pctrl->dev, nports, sizeof(*cache->pmc), GFP_KERNEL); + if (!cache->pmc) + return -ENOMEM; + + cache->pfc = devm_kcalloc(pctrl->dev, nports, sizeof(*cache->pfc), GFP_KERNEL); + if (!cache->pfc) + return -ENOMEM; + + for (u8 i = 0; i < 2; i++) { + u32 n_dedicated_pins = pctrl->data->n_dedicated_pins; + + cache->iolh[i] = devm_kcalloc(pctrl->dev, nports, sizeof(*cache->iolh[i]), + GFP_KERNEL); + if (!cache->iolh[i]) + return -ENOMEM; + + cache->ien[i] = devm_kcalloc(pctrl->dev, nports, sizeof(*cache->ien[i]), + GFP_KERNEL); + if (!cache->ien[i]) + return -ENOMEM; + + /* Allocate dedicated cache. */ + dedicated_cache->iolh[i] = devm_kcalloc(pctrl->dev, n_dedicated_pins, + sizeof(*dedicated_cache->iolh[i]), + GFP_KERNEL); + if (!dedicated_cache->iolh[i]) + return -ENOMEM; + + dedicated_cache->ien[i] = devm_kcalloc(pctrl->dev, n_dedicated_pins, + sizeof(*dedicated_cache->ien[i]), + GFP_KERNEL); + if (!dedicated_cache->ien[i]) + return -ENOMEM; + } + + pctrl->cache = cache; + pctrl->dedicated_cache = dedicated_cache; + + return 0; +} + static int rzg2l_gpio_register(struct rzg2l_pinctrl *pctrl) { struct device_node *np = pctrl->dev->of_node; @@ -1870,7 +2257,7 @@ static int rzg2l_pinctrl_register(struct rzg2l_pinctrl *pctrl) const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg; struct pinctrl_pin_desc *pins; unsigned int i, j; - u32 *pin_data; + u64 *pin_data; int ret; pctrl->desc.name = DRV_NAME; @@ -1898,6 +2285,13 @@ static int rzg2l_pinctrl_register(struct rzg2l_pinctrl *pctrl) if (i && !(i % RZG2L_PINS_PER_PORT)) j++; pin_data[i] = pctrl->data->port_pin_configs[j]; +#ifdef CONFIG_RISCV + if (pin_data[i] & PIN_CFG_VARIABLE) + pin_data[i] = rzg2l_pinctrl_get_variable_pin_cfg(pctrl, + pin_data[i], + j, + i % RZG2L_PINS_PER_PORT); +#endif pins[i].drv_data = &pin_data[i]; } @@ -1926,6 +2320,10 @@ static int rzg2l_pinctrl_register(struct rzg2l_pinctrl *pctrl) } } + ret = rzg2l_pinctrl_reg_cache_alloc(pctrl); + if (ret) + return ret; + ret = devm_pinctrl_register_and_init(pctrl->dev, &pctrl->desc, pctrl, &pctrl->pctl); if (ret) { @@ -1951,7 +2349,6 @@ static int rzg2l_pinctrl_register(struct rzg2l_pinctrl *pctrl) static int rzg2l_pinctrl_probe(struct platform_device *pdev) { struct rzg2l_pinctrl *pctrl; - struct clk *clk; int ret; BUILD_BUG_ON(ARRAY_SIZE(r9a07g044_gpio_configs) * RZG2L_PINS_PER_PORT > @@ -1977,14 +2374,16 @@ static int rzg2l_pinctrl_probe(struct platform_device *pdev) if (IS_ERR(pctrl->base)) return PTR_ERR(pctrl->base); - clk = devm_clk_get_enabled(pctrl->dev, NULL); - if (IS_ERR(clk)) - return dev_err_probe(pctrl->dev, PTR_ERR(clk), + pctrl->clk = devm_clk_get_enabled(pctrl->dev, NULL); + if (IS_ERR(pctrl->clk)) { + return dev_err_probe(pctrl->dev, PTR_ERR(pctrl->clk), "failed to enable GPIO clk\n"); + } spin_lock_init(&pctrl->lock); spin_lock_init(&pctrl->bitmap_lock); mutex_init(&pctrl->mutex); + atomic_set(&pctrl->wakeup_path, 0); platform_set_drvdata(pdev, pctrl); @@ -1996,6 +2395,224 @@ static int rzg2l_pinctrl_probe(struct platform_device *pdev) return 0; } +static void rzg2l_pinctrl_pm_setup_regs(struct rzg2l_pinctrl *pctrl, bool suspend) +{ + u32 nports = pctrl->data->n_port_pins / RZG2L_PINS_PER_PORT; + struct rzg2l_pinctrl_reg_cache *cache = pctrl->cache; + + for (u32 port = 0; port < nports; port++) { + bool has_iolh, has_ien; + u32 off, caps; + u8 pincnt; + u64 cfg; + + cfg = pctrl->data->port_pin_configs[port]; + off = RZG2L_PIN_CFG_TO_PORT_OFFSET(cfg); + pincnt = hweight8(FIELD_GET(PIN_CFG_PIN_MAP_MASK, cfg)); + + caps = FIELD_GET(PIN_CFG_MASK, cfg); + has_iolh = !!(caps & (PIN_CFG_IOLH_A | PIN_CFG_IOLH_B | PIN_CFG_IOLH_C)); + has_ien = !!(caps & PIN_CFG_IEN); + + if (suspend) + RZG2L_PCTRL_REG_ACCESS32(suspend, pctrl->base + PFC(off), cache->pfc[port]); + + /* + * Now cache the registers or set them in the order suggested by + * HW manual (section "Operation for GPIO Function"). + */ + RZG2L_PCTRL_REG_ACCESS8(suspend, pctrl->base + PMC(off), cache->pmc[port]); + if (has_iolh) { + RZG2L_PCTRL_REG_ACCESS32(suspend, pctrl->base + IOLH(off), + cache->iolh[0][port]); + if (pincnt >= 4) { + RZG2L_PCTRL_REG_ACCESS32(suspend, pctrl->base + IOLH(off) + 4, + cache->iolh[1][port]); + } + } + + RZG2L_PCTRL_REG_ACCESS16(suspend, pctrl->base + PM(off), cache->pm[port]); + RZG2L_PCTRL_REG_ACCESS8(suspend, pctrl->base + P(off), cache->p[port]); + + if (has_ien) { + RZG2L_PCTRL_REG_ACCESS32(suspend, pctrl->base + IEN(off), + cache->ien[0][port]); + if (pincnt >= 4) { + RZG2L_PCTRL_REG_ACCESS32(suspend, pctrl->base + IEN(off) + 4, + cache->ien[1][port]); + } + } + } +} + +static void rzg2l_pinctrl_pm_setup_dedicated_regs(struct rzg2l_pinctrl *pctrl, bool suspend) +{ + struct rzg2l_pinctrl_reg_cache *cache = pctrl->dedicated_cache; + + /* + * Make sure entries in pctrl->data->n_dedicated_pins[] having the same + * port offset are close together. + */ + for (u32 i = 0, caps = 0; i < pctrl->data->n_dedicated_pins; i++) { + bool has_iolh, has_ien; + u32 off, next_off = 0; + u64 cfg, next_cfg; + u8 pincnt; + + cfg = pctrl->data->dedicated_pins[i].config; + off = RZG2L_PIN_CFG_TO_PORT_OFFSET(cfg); + if (i + 1 < pctrl->data->n_dedicated_pins) { + next_cfg = pctrl->data->dedicated_pins[i + 1].config; + next_off = RZG2L_PIN_CFG_TO_PORT_OFFSET(next_cfg); + } + + if (off == next_off) { + /* Gather caps of all port pins. */ + caps |= FIELD_GET(PIN_CFG_MASK, cfg); + continue; + } + + /* And apply them in a single shot. */ + has_iolh = !!(caps & (PIN_CFG_IOLH_A | PIN_CFG_IOLH_B | PIN_CFG_IOLH_C)); + has_ien = !!(caps & PIN_CFG_IEN); + pincnt = hweight8(FIELD_GET(RZG2L_SINGLE_PIN_BITS_MASK, cfg)); + + if (has_iolh) { + RZG2L_PCTRL_REG_ACCESS32(suspend, pctrl->base + IOLH(off), + cache->iolh[0][i]); + } + if (has_ien) { + RZG2L_PCTRL_REG_ACCESS32(suspend, pctrl->base + IEN(off), + cache->ien[0][i]); + } + + if (pincnt >= 4) { + if (has_iolh) { + RZG2L_PCTRL_REG_ACCESS32(suspend, + pctrl->base + IOLH(off) + 4, + cache->iolh[1][i]); + } + if (has_ien) { + RZG2L_PCTRL_REG_ACCESS32(suspend, + pctrl->base + IEN(off) + 4, + cache->ien[1][i]); + } + } + caps = 0; + } +} + +static void rzg2l_pinctrl_pm_setup_pfc(struct rzg2l_pinctrl *pctrl) +{ + u32 nports = pctrl->data->n_port_pins / RZG2L_PINS_PER_PORT; + const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg; + const struct rzg2l_register_offsets *regs = &hwcfg->regs; + + /* Set the PWPR register to allow PFC register to write. */ + writel(0x0, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=0 */ + writel(PWPR_PFCWE, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=1 */ + + /* Restore port registers. */ + for (u32 port = 0; port < nports; port++) { + unsigned long pinmap; + u8 pmc = 0, max_pin; + u32 off, pfc = 0; + u64 cfg; + u16 pm; + u8 pin; + + cfg = pctrl->data->port_pin_configs[port]; + off = RZG2L_PIN_CFG_TO_PORT_OFFSET(cfg); + pinmap = FIELD_GET(PIN_CFG_PIN_MAP_MASK, cfg); + max_pin = fls(pinmap); + + pm = readw(pctrl->base + PM(off)); + for_each_set_bit(pin, &pinmap, max_pin) { + struct rzg2l_pinctrl_reg_cache *cache = pctrl->cache; + + /* Nothing to do if PFC was not configured before. */ + if (!(cache->pmc[port] & BIT(pin))) + continue; + + /* Set pin to 'Non-use (Hi-Z input protection)' */ + pm &= ~(PM_MASK << (pin * 2)); + writew(pm, pctrl->base + PM(off)); + + /* Temporarily switch to GPIO mode with PMC register */ + pmc &= ~BIT(pin); + writeb(pmc, pctrl->base + PMC(off)); + + /* Select Pin function mode. */ + pfc &= ~(PFC_MASK << (pin * 4)); + pfc |= (cache->pfc[port] & (PFC_MASK << (pin * 4))); + writel(pfc, pctrl->base + PFC(off)); + + /* Switch to Peripheral pin function. */ + pmc |= BIT(pin); + writeb(pmc, pctrl->base + PMC(off)); + } + } + + /* Set the PWPR register to be write-protected. */ + writel(0x0, pctrl->base + regs->pwpr); /* B0WI=0, PFCWE=0 */ + writel(PWPR_B0WI, pctrl->base + regs->pwpr); /* B0WI=1, PFCWE=0 */ +} + +static int rzg2l_pinctrl_suspend_noirq(struct device *dev) +{ + struct rzg2l_pinctrl *pctrl = dev_get_drvdata(dev); + const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg; + const struct rzg2l_register_offsets *regs = &hwcfg->regs; + struct rzg2l_pinctrl_reg_cache *cache = pctrl->cache; + + rzg2l_pinctrl_pm_setup_regs(pctrl, true); + rzg2l_pinctrl_pm_setup_dedicated_regs(pctrl, true); + + for (u8 i = 0; i < 2; i++) { + cache->sd_ch[i] = readb(pctrl->base + SD_CH(regs->sd_ch, i)); + cache->eth_poc[i] = readb(pctrl->base + ETH_POC(regs->eth_poc, i)); + } + + cache->qspi = readb(pctrl->base + QSPI); + cache->eth_mode = readb(pctrl->base + ETH_MODE); + + if (!atomic_read(&pctrl->wakeup_path)) + clk_disable_unprepare(pctrl->clk); + else + device_set_wakeup_path(dev); + + return 0; +} + +static int rzg2l_pinctrl_resume_noirq(struct device *dev) +{ + struct rzg2l_pinctrl *pctrl = dev_get_drvdata(dev); + const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg; + const struct rzg2l_register_offsets *regs = &hwcfg->regs; + struct rzg2l_pinctrl_reg_cache *cache = pctrl->cache; + int ret; + + if (!atomic_read(&pctrl->wakeup_path)) { + ret = clk_prepare_enable(pctrl->clk); + if (ret) + return ret; + } + + writeb(cache->qspi, pctrl->base + QSPI); + writeb(cache->eth_mode, pctrl->base + ETH_MODE); + for (u8 i = 0; i < 2; i++) { + writeb(cache->sd_ch[i], pctrl->base + SD_CH(regs->sd_ch, i)); + writeb(cache->eth_poc[i], pctrl->base + ETH_POC(regs->eth_poc, i)); + } + + rzg2l_pinctrl_pm_setup_pfc(pctrl); + rzg2l_pinctrl_pm_setup_regs(pctrl, false); + rzg2l_pinctrl_pm_setup_dedicated_regs(pctrl, false); + rzg2l_gpio_irq_restore(pctrl); + + return 0; +} + static const struct rzg2l_hwcfg rzg2l_hwcfg = { .regs = { .pwpr = 0x3014, @@ -2049,6 +2666,10 @@ static struct rzg2l_pinctrl_data r9a07g043_data = { .n_port_pins = ARRAY_SIZE(r9a07g043_gpio_configs) * RZG2L_PINS_PER_PORT, .n_dedicated_pins = ARRAY_SIZE(rzg2l_dedicated_pins.common), .hwcfg = &rzg2l_hwcfg, +#ifdef CONFIG_RISCV + .variable_pin_cfg = r9a07g043f_variable_pin_cfg, + .n_variable_pin_cfg = ARRAY_SIZE(r9a07g043f_variable_pin_cfg), +#endif }; static struct rzg2l_pinctrl_data r9a07g044_data = { @@ -2088,10 +2709,15 @@ static const struct of_device_id rzg2l_pinctrl_of_table[] = { { /* sentinel */ } }; +static const struct dev_pm_ops rzg2l_pinctrl_pm_ops = { + NOIRQ_SYSTEM_SLEEP_PM_OPS(rzg2l_pinctrl_suspend_noirq, rzg2l_pinctrl_resume_noirq) +}; + static struct platform_driver rzg2l_pinctrl_driver = { .driver = { .name = DRV_NAME, .of_match_table = of_match_ptr(rzg2l_pinctrl_of_table), + .pm = pm_sleep_ptr(&rzg2l_pinctrl_pm_ops), }, .probe = rzg2l_pinctrl_probe, }; diff --git a/drivers/pinctrl/renesas/sh_pfc.h b/drivers/pinctrl/renesas/sh_pfc.h index 8dc7a66009ad..0061e9640059 100644 --- a/drivers/pinctrl/renesas/sh_pfc.h +++ b/drivers/pinctrl/renesas/sh_pfc.h @@ -322,6 +322,7 @@ extern const struct sh_pfc_soc_info r8a77995_pinmux_info; extern const struct sh_pfc_soc_info r8a779a0_pinmux_info; extern const struct sh_pfc_soc_info r8a779f0_pinmux_info; extern const struct sh_pfc_soc_info r8a779g0_pinmux_info; +extern const struct sh_pfc_soc_info r8a779h0_pinmux_info; extern const struct sh_pfc_soc_info sh7203_pinmux_info; extern const struct sh_pfc_soc_info sh7264_pinmux_info; extern const struct sh_pfc_soc_info sh7269_pinmux_info; diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.h b/include/linux/gpio/gpio-nomadik.h index 1ef2559bc571..b5a84864650d 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.h +++ b/include/linux/gpio/gpio-nomadik.h @@ -1,16 +1,77 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#ifndef PINCTRL_PINCTRL_NOMADIK_H -#define PINCTRL_PINCTRL_NOMADIK_H +#ifndef __LINUX_GPIO_NOMADIK_H +#define __LINUX_GPIO_NOMADIK_H -#include <linux/kernel.h> -#include <linux/types.h> - -#include <linux/pinctrl/pinctrl.h> +struct fwnode_handle; /* Package definitions */ #define PINCTRL_NMK_STN8815 0 #define PINCTRL_NMK_DB8500 1 +#define GPIO_BLOCK_SHIFT 5 +#define NMK_GPIO_PER_CHIP BIT(GPIO_BLOCK_SHIFT) +#define NMK_MAX_BANKS DIV_ROUND_UP(512, NMK_GPIO_PER_CHIP) + +/* Register in the logic block */ +#define NMK_GPIO_DAT 0x00 +#define NMK_GPIO_DATS 0x04 +#define NMK_GPIO_DATC 0x08 +#define NMK_GPIO_PDIS 0x0c +#define NMK_GPIO_DIR 0x10 +#define NMK_GPIO_DIRS 0x14 +#define NMK_GPIO_DIRC 0x18 +#define NMK_GPIO_SLPC 0x1c +#define NMK_GPIO_AFSLA 0x20 +#define NMK_GPIO_AFSLB 0x24 +#define NMK_GPIO_LOWEMI 0x28 + +#define NMK_GPIO_RIMSC 0x40 +#define NMK_GPIO_FIMSC 0x44 +#define NMK_GPIO_IS 0x48 +#define NMK_GPIO_IC 0x4c +#define NMK_GPIO_RWIMSC 0x50 +#define NMK_GPIO_FWIMSC 0x54 +#define NMK_GPIO_WKS 0x58 +/* These appear in DB8540 and later ASICs */ +#define NMK_GPIO_EDGELEVEL 0x5C +#define NMK_GPIO_LEVEL 0x60 + +/* Pull up/down values */ +enum nmk_gpio_pull { + NMK_GPIO_PULL_NONE, + NMK_GPIO_PULL_UP, + NMK_GPIO_PULL_DOWN, +}; + +/* Sleep mode */ +enum nmk_gpio_slpm { + NMK_GPIO_SLPM_INPUT, + NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT, + NMK_GPIO_SLPM_NOCHANGE, + NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE, +}; + +struct nmk_gpio_chip { + struct gpio_chip chip; + void __iomem *addr; + struct clk *clk; + unsigned int bank; + void (*set_ioforce)(bool enable); + spinlock_t lock; + bool sleepmode; + bool is_mobileye_soc; + /* Keep track of configured edges */ + u32 edge_rising; + u32 edge_falling; + u32 real_wake; + u32 rwimsc; + u32 fwimsc; + u32 rimsc; + u32 fimsc; + u32 pull_up; + u32 lowemi; +}; + /* Alternate functions: function C is set in hw by setting both A and B */ #define NMK_GPIO_ALT_GPIO 0 #define NMK_GPIO_ALT_A 1 @@ -104,7 +165,7 @@ struct prcm_gpiocr_altcx_pin_desc { struct nmk_function { const char *name; const char * const *groups; - unsigned ngroups; + unsigned int ngroups; }; /** @@ -141,13 +202,13 @@ struct nmk_pingroup { */ struct nmk_pinctrl_soc_data { const struct pinctrl_pin_desc *pins; - unsigned npins; + unsigned int npins; const struct nmk_function *functions; - unsigned nfunctions; + unsigned int nfunctions; const struct nmk_pingroup *groups; - unsigned ngroups; + unsigned int ngroups; const struct prcm_gpiocr_altcx_pin_desc *altcx_pins; - unsigned npins_altcx; + unsigned int npins_altcx; const u16 *prcm_gpiocr_registers; }; @@ -177,4 +238,57 @@ nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc) #endif -#endif /* PINCTRL_PINCTRL_NOMADIK_H */ +#ifdef CONFIG_PINCTRL_DB8540 + +void nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc); + +#else + +static inline void +nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc) +{ +} + +#endif + +struct platform_device; + +#ifdef CONFIG_DEBUG_FS + +/* + * Symbols declared in gpio-nomadik used by pinctrl-nomadik. If pinctrl-nomadik + * is enabled, then gpio-nomadik is enabled as well; the reverse if not always + * true. + */ +void nmk_gpio_dbg_show_one(struct seq_file *s, struct pinctrl_dev *pctldev, + struct gpio_chip *chip, unsigned int offset, + unsigned int gpio); + +#else + +static inline void nmk_gpio_dbg_show_one(struct seq_file *s, + struct pinctrl_dev *pctldev, + struct gpio_chip *chip, + unsigned int offset, + unsigned int gpio) +{ +} + +#endif + +void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip, + unsigned int offset, int val); +void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip, unsigned int offset, + enum nmk_gpio_slpm mode); +struct nmk_gpio_chip *nmk_gpio_populate_chip(struct fwnode_handle *fwnode, + struct platform_device *pdev); + +/* Symbols declared in pinctrl-nomadik used by gpio-nomadik. */ +#ifdef CONFIG_PINCTRL_NOMADIK +extern struct nmk_gpio_chip *nmk_gpio_chips[NMK_MAX_BANKS]; +extern spinlock_t nmk_gpio_slpm_lock; +int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, + int gpio); +#endif + +#endif /* __LINUX_GPIO_NOMADIK_H */ |