Basic StarFive JH7100 RISC-V SoC support
Subsystems (16)
Emil Renner Berthing
maintainerv2 cover Basic StarFive JH7100 RISC-V SoC support
This series adds support for the StarFive JH7100 RISC-V SoC. The SoC has many devices that need non-coherent dma operations to work which isn't upstream yet[1], so this just adds basic support to boot up, get a serial console, blink an LED and reboot itself. Unlike the Allwinner D1 this chip doesn't use any extra pagetable bits, but instead the DDR RAM appears twice in the memory map, with and without the cache.
The JH7100 is a test chip for the upcoming JH7110 and about 300 BeagleV Starlight Beta boards were sent out with them as part of a now cancelled BeagleBoard.org project. However StarFive has produced more of the JH7100s and more boards will be available[2] to buy. Hopefully before the end of the year.
This series is also available at
https://github.com/esmil/linux/commits/starlight-minimal
..but a more complete kernel including drivers for non-coherent peripherals based on this series can be found at
https://github.com/starfive-tech/linux/tree/starlight
[1]: https://lore.kernel.org/linux-riscv/[email protected]/
[2]: https://www.linkedin.com/pulse/starfive-release-open-source-single-board-platform-q3-2021-starfive/
/Emil
Changes since v1:
- Let SOC_STARFIVE select RESET_CONTROLLER but drop SERIAL_8250_DW
- Add missing Signed-of-by to clock dt-binding header
- Use builtin_platform_driver macro for the clock driver, add explicit comment to the determine_rate callback and other small nits from Andy
- Use reset-controller for node names in documentation and device tree
- Use readl_poll_timeout in reset driver to avoid hanging forever if a driver leaves the associated clock gated and sort Kconfig and Makefile entries properly.
- In the pinctrl driver align register names with documentation, remove invalid __init tag from probe function, use of_property_* functions to parse device tree, hoist pinmux unpacking into helper function to better document what's going on, bail on invalid signal group in device tree and fix many other nits from Andy.
- Refactor and rebase 8250_dw quirk on tty-next
Emil Renner Berthing (12):
RISC-V: Add StarFive SoC Kconfig option
dt-bindings: timer: Add StarFive JH7100 clint
dt-bindings: interrupt-controller: Add StarFive JH7100 plic
dt-bindings: reset: Add Starfive JH7100 reset bindings
reset: starfive-jh7100: Add StarFive JH7100 reset driver
dt-bindings: pinctrl: Add StarFive pinctrl definitions
dt-bindings: pinctrl: Add StarFive JH7100 bindings
pinctrl: starfive: Add pinctrl driver for StarFive SoCs
dt-bindings: serial: snps-dw-apb-uart: Add JH7100 uarts
serial: 8250_dw: Add skip_clk_set_rate quirk
RISC-V: Add initial StarFive JH7100 device tree
RISC-V: Add BeagleV Starlight Beta device tree
Geert Uytterhoeven (4):
dt-bindings: clock: starfive: Add JH7100 clock definitions
dt-bindings: clock: starfive: Add JH7100 bindings
clk: starfive: Add JH7100 clock generator driver
dt-bindings: reset: Add StarFive JH7100 reset definitions
.../clock/starfive,jh7100-clkgen.yaml | 56 + .../sifive,plic-1.0.0.yaml | 1 + .../pinctrl/starfive,jh7100-pinctrl.yaml | 274 ++++ .../bindings/reset/starfive,jh7100-reset.yaml | 38 + .../bindings/serial/snps-dw-apb-uart.yaml | 5 + .../bindings/timer/sifive,clint.yaml | 1 + MAINTAINERS | 22 + arch/riscv/Kconfig.socs | 8 + arch/riscv/boot/dts/Makefile | 1 + arch/riscv/boot/dts/starfive/Makefile | 2 + .../dts/starfive/jh7100-beaglev-starlight.dts | 162 ++ arch/riscv/boot/dts/starfive/jh7100.dtsi | 228 +++ drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 1 + drivers/clk/starfive/Kconfig | 9 + drivers/clk/starfive/Makefile | 3 + drivers/clk/starfive/clk-starfive-jh7100.c | 776 +++++++++ drivers/pinctrl/Kconfig | 16 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-starfive.c | 1387 +++++++++++++++++ drivers/reset/Kconfig | 8 + drivers/reset/Makefile | 1 + drivers/reset/reset-starfive-jh7100.c | 165 ++ drivers/tty/serial/8250/8250_dw.c | 19 +- include/dt-bindings/clock/starfive-jh7100.h | 202 +++ .../dt-bindings/pinctrl/pinctrl-starfive.h | 274 ++++ include/dt-bindings/reset/starfive-jh7100.h | 126 ++ 27 files changed, 3784 insertions(+), 3 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7100-clkgen.yaml create mode 100644 Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml create mode 100644 Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml create mode 100644 arch/riscv/boot/dts/starfive/Makefile create mode 100644 arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts create mode 100644 arch/riscv/boot/dts/starfive/jh7100.dtsi create mode 100644 drivers/clk/starfive/Kconfig create mode 100644 drivers/clk/starfive/Makefile create mode 100644 drivers/clk/starfive/clk-starfive-jh7100.c create mode 100644 drivers/pinctrl/pinctrl-starfive.c create mode 100644 drivers/reset/reset-starfive-jh7100.c create mode 100644 include/dt-bindings/clock/starfive-jh7100.h create mode 100644 include/dt-bindings/pinctrl/pinctrl-starfive.h create mode 100644 include/dt-bindings/reset/starfive-jh7100.h
Signature · 1 line
2.33.1
Emil Renner Berthing
maintainerPATCH v2 1/16 RISC-V: Add StarFive SoC Kconfig option
Add StarFive Kconfig option to select SoC specific and common drivers required for these SoCs.
--- arch/riscv/Kconfig.socs | 8 ++++++++ 1 file changed, 8 insertions(+)
arch/riscv/Kconfig.socs +8 -0
@@ -19,6 +19,14 @@ config SOC_SIFIVE help This enables support for SiFive SoC platform hardware. +config SOC_STARFIVE + bool "StarFive SoCs" + select PINCTRL + select RESET_CONTROLLER + select SIFIVE_PLIC + help + This enables support for StarFive SoC platform hardware. + config SOC_VIRT bool "QEMU Virt Machine" select CLINT_TIMER if RISCV_M_MODE
Signature · 1 line
2.33.1
Re: [PATCH v2 01/16] RISC-V: Add StarFive SoC Kconfig option
Quoted 3 lines · Emil Renner Berthing
Add StarFive
Kconfigoption to select SoC specific and common drivers required for these SoCs.
...
arch/riscv/Kconfig.socs config SOC_SIFIVE · line 26
Quoted 6 lines
arch/riscv/Kconfig.socs +5
-0+config SOC_STARFIVE + bool "StarFive SoCs" + select PINCTRL + select RESET_CONTROLLER + select SIFIVE_PLIC
If this is well understood and platform related the above two are too generic. Why have you selected them?
arch/riscv/Kconfig.socs config SOC_SIFIVE · line 28
Quoted 2 lines
arch/riscv/Kconfig.socs +2
-0+ help + This enables support for StarFive SoC platform hardware.
Not too much to read here. What is the point of this help? I would elaborate what kind of platform it may support, what kind of drivers it selects due to necessity of the accomplishing the boot process, etc.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Emil Renner Berthing
maintainerRe: [PATCH v2 01/16] RISC-V: Add StarFive SoC Kconfig option
Quoted 12 lines · Andy Shevchenko
Quoted 3 lines · Emil Renner Berthing
Add StarFive
Kconfigoption to select SoC specific and common drivers required for these SoCs....
Quoted 4 lines
arch/riscv/Kconfig.socs +4
-0+config SOC_STARFIVE + bool "StarFive SoCs" + select PINCTRL + select RESET_CONTROLLER
Quoted 4 lines
Quoted 1 line
+ select
SIFIVE_PLICIf this is well understood and platform related the above two are too generic. Why have you selected them?
From your last comments the criterion seemed to be to only add it here if it would otherwise fail to boot. Well it does fail to boot without the reset and pinctrl drivers. The clock driver too, but RISCV already selects COMMON_CLK. Once PINCTRL and RESET_CONTROLLER is selected the specific drivers defaults to SOC_STARFIVE.
Alternatively we'd select the drivers too, but I can't promise that future StarFive chips will need the same JH7100 clock and reset drivers. Doing it this way means that selecting SOC_STARFIVE by default gives you a kernel that will boot on all StarFive SoCs, but you can still customise it further to your particular chip. It seems like SOC_SIFIVE is doing the same.
Quoted 7 lines
arch/riscv/Kconfig.socs config SOC_SIFIVE · line 28
Quoted 2 lines
arch/riscv/Kconfig.socs +2
-0+ help + This enables support for StarFive SoC platform hardware.Not too much to read here. What is the point of this help? I would elaborate what kind of platform it may support, what kind of drivers it selects due to necessity of the accomplishing the boot process, etc.
This is exactly as the other descriptions in this file. I don't know why SOC_STARFIVE should be special.
/Emil
Re: [PATCH v2 01/16] RISC-V: Add StarFive SoC Kconfig option
Quoted 2 lines · Emil Renner Berthing
Quoted 1 line · Andy Shevchenko
On Thu, Oct 21, 2021 at 8:42 PM Emil Renner Berthing <[email protected]> wrote:
...
Quoted 16 lines
Quoted 9 lines
arch/riscv/Kconfig.socs config SOC_SIFIVE · line 26
Quoted 6 lines
arch/riscv/Kconfig.socs +5
-0+config SOC_STARFIVE + bool "StarFive SoCs" + select PINCTRL + select RESET_CONTROLLER + select SIFIVE_PLICIf this is well understood and platform related the above two are too generic. Why have you selected them?
From your last comments the criterion seemed to be to only add it here if it would otherwise fail to boot. Well it does fail to boot without the reset and pinctrl drivers. The clock driver too, but RISCV already selects
COMMON_CLK. Once PINCTRL andRESET_CONTROLLERis selected the specific drivers defaults toSOC_STARFIVE.
Quoted 6 lines
Alternatively we'd select the drivers too, but I can't promise that future StarFive chips will need the same JH7100 clock and reset drivers. Doing it this way means that selecting
SOC_STARFIVEby default gives you a kernel that will boot on all StarFive SoCs, but you can still customise it further to your particular chip. It seems likeSOC_SIFIVEis doing the same.
Okay, please add this justification to the commit message in the next version.
...
Quoted 10 lines
Quoted 7 lines
arch/riscv/Kconfig.socs config SOC_SIFIVE · line 28
Quoted 2 lines
arch/riscv/Kconfig.socs +2
-0+ help + This enables support for StarFive SoC platform hardware.Not too much to read here. What is the point of this help? I would elaborate what kind of platform it may support, what kind of drivers it selects due to necessity of the accomplishing the boot process, etc.
This is exactly as the other descriptions in this file. I don't know why
SOC_STARFIVEshould be special.
OK.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Emil Renner Berthing
maintainerPATCH v2 2/16 dt-bindings: timer: Add StarFive JH7100 clint
In reply to Emil Renner BerthingAdd compatible string for the StarFive JH7100 clint.
--- Documentation/devicetree/bindings/timer/sifive,clint.yaml | 1 + 1 file changed, 1 insertion(+)
Documentation/devicetree/bindings/timer/sifive,clint.yaml +1 -0
@@ -25,6 +25,7 @@ properties: items: - enum: - sifive,fu540-c000-clint + - starfive,jh7100-clint - canaan,k210-clint - const: sifive,clint0
Signature · 1 line
2.33.1
Emil Renner Berthing
maintainerPATCH v2 3/16 dt-bindings: interrupt-controller: Add StarFive JH7100 plic
In reply to Emil Renner BerthingAdd compatible string for StarFive JH7100 plic.
--- .../bindings/interrupt-controller/sifive,plic-1.0.0.yaml | 1 + 1 file changed, 1 insertion(+)
Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml +1 -0
@@ -45,6 +45,7 @@ properties: items: - enum: - sifive,fu540-c000-plic + - starfive,jh7100-plic - canaan,k210-plic - const: sifive,plic-1.0.0
Signature · 1 line
2.33.1
Re: [PATCH v2 03/16] dt-bindings: interrupt-controller: Add StarFive JH7100 plic
Quoted 8 lines · Emil Renner Berthing
Add compatible string for StarFive JH7100 plic.
Signed-off-by Emil Renner Berthing <[email protected]>Reviewed-by Geert Uytterhoeven <[email protected]>--- .../bindings/interrupt-controller/sifive,plic-1.0.0.yaml | 1 + 1 file changed, 1 insertion(+)
Emil Renner Berthing
maintainerPATCH v2 4/16 dt-bindings: clock: starfive: Add JH7100 clock definitions
In reply to Emil Renner BerthingFrom: Geert Uytterhoeven <[email protected]>
Add all clock outputs for the StarFive JH7100 clock generator.
Based on work by Ahmad Fatoum for Barebox, with "JH7100_" prefixes added to all definitions.
--- include/dt-bindings/clock/starfive-jh7100.h | 202 ++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 include/dt-bindings/clock/starfive-jh7100.h
include/dt-bindings/clock/starfive-jh7100.h new file +202 -0
@@ -0,0 +1,202 @@ +/* SPDX-License-Identifier: GPL-2.0 OR X11 */ +/* +* Copyright (C) 2021 Ahmad Fatoum, Pengutronix +*/ + +#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7100_H__ +#define __DT_BINDINGS_CLOCK_STARFIVE_JH7100_H__ + +#define JH7100_CLK_CPUNDBUS_ROOT 0 +#define JH7100_CLK_DLA_ROOT 1 +#define JH7100_CLK_DSP_ROOT 2 +#define JH7100_CLK_GMACUSB_ROOT 3 +#define JH7100_CLK_PERH0_ROOT 4 +#define JH7100_CLK_PERH1_ROOT 5 +#define JH7100_CLK_VIN_ROOT 6 +#define JH7100_CLK_VOUT_ROOT 7 +#define JH7100_CLK_AUDIO_ROOT 8 +#define JH7100_CLK_CDECHIFI4_ROOT 9 +#define JH7100_CLK_CDEC_ROOT 10 +#define JH7100_CLK_VOUTBUS_ROOT 11 +#define JH7100_CLK_CPUNBUS_ROOT_DIV 12 +#define JH7100_CLK_DSP_ROOT_DIV 13 +#define JH7100_CLK_PERH0_SRC 14 +#define JH7100_CLK_PERH1_SRC 15 +#define JH7100_CLK_PLL0_TESTOUT 16 +#define JH7100_CLK_PLL1_TESTOUT 17 +#define JH7100_CLK_PLL2_TESTOUT 18 +#define JH7100_CLK_PLL2_REF 19 +#define JH7100_CLK_CPU_CORE 20 +#define JH7100_CLK_CPU_AXI 21 +#define JH7100_CLK_AHB_BUS 22 +#define JH7100_CLK_APB1_BUS 23 +#define JH7100_CLK_APB2_BUS 24 +#define JH7100_CLK_DOM3AHB_BUS 25 +#define JH7100_CLK_DOM7AHB_BUS 26 +#define JH7100_CLK_U74_CORE0 27 +#define JH7100_CLK_U74_CORE1 28 +#define JH7100_CLK_U74_AXI 29 +#define JH7100_CLK_U74RTC_TOGGLE 30 +#define JH7100_CLK_SGDMA2P_AXI 31 +#define JH7100_CLK_DMA2PNOC_AXI 32 +#define JH7100_CLK_SGDMA2P_AHB 33 +#define JH7100_CLK_DLA_BUS 34 +#define JH7100_CLK_DLA_AXI 35 +#define JH7100_CLK_DLANOC_AXI 36 +#define JH7100_CLK_DLA_APB 37 +#define JH7100_CLK_VP6_CORE 38 +#define JH7100_CLK_VP6BUS_SRC 39 +#define JH7100_CLK_VP6_AXI 40 +#define JH7100_CLK_VCDECBUS_SRC 41 +#define JH7100_CLK_VDEC_BUS 42 +#define JH7100_CLK_VDEC_AXI 43 +#define JH7100_CLK_VDECBRG_MAIN 44 +#define JH7100_CLK_VDEC_BCLK 45 +#define JH7100_CLK_VDEC_CCLK 46 +#define JH7100_CLK_VDEC_APB 47 +#define JH7100_CLK_JPEG_AXI 48 +#define JH7100_CLK_JPEG_CCLK 49 +#define JH7100_CLK_JPEG_APB 50 +#define JH7100_CLK_GC300_2X 51 +#define JH7100_CLK_GC300_AHB 52 +#define JH7100_CLK_JPCGC300_AXIBUS 53 +#define JH7100_CLK_GC300_AXI 54 +#define JH7100_CLK_JPCGC300_MAIN 55 +#define JH7100_CLK_VENC_BUS 56 +#define JH7100_CLK_VENC_AXI 57 +#define JH7100_CLK_VENCBRG_MAIN 58 +#define JH7100_CLK_VENC_BCLK 59 +#define JH7100_CLK_VENC_CCLK 60 +#define JH7100_CLK_VENC_APB 61 +#define JH7100_CLK_DDRPLL_DIV2 62 +#define JH7100_CLK_DDRPLL_DIV4 63 +#define JH7100_CLK_DDRPLL_DIV8 64 +#define JH7100_CLK_DDROSC_DIV2 65 +#define JH7100_CLK_DDRC0 66 +#define JH7100_CLK_DDRC1 67 +#define JH7100_CLK_DDRPHY_APB 68 +#define JH7100_CLK_NOC_ROB 69 +#define JH7100_CLK_NOC_COG 70 +#define JH7100_CLK_NNE_AHB 71 +#define JH7100_CLK_NNEBUS_SRC1 72 +#define JH7100_CLK_NNE_BUS 73 +#define JH7100_CLK_NNE_AXI 74 +#define JH7100_CLK_NNENOC_AXI 75 +#define JH7100_CLK_DLASLV_AXI 76 +#define JH7100_CLK_DSPX2C_AXI 77 +#define JH7100_CLK_HIFI4_SRC 78 +#define JH7100_CLK_HIFI4_COREFREE 79 +#define JH7100_CLK_HIFI4_CORE 80 +#define JH7100_CLK_HIFI4_BUS 81 +#define JH7100_CLK_HIFI4_AXI 82 +#define JH7100_CLK_HIFI4NOC_AXI 83 +#define JH7100_CLK_SGDMA1P_BUS 84 +#define JH7100_CLK_SGDMA1P_AXI 85 +#define JH7100_CLK_DMA1P_AXI 86 +#define JH7100_CLK_X2C_AXI 87 +#define JH7100_CLK_USB_BUS 88 +#define JH7100_CLK_USB_AXI 89 +#define JH7100_CLK_USBNOC_AXI 90 +#define JH7100_CLK_USBPHY_ROOTDIV 91 +#define JH7100_CLK_USBPHY_125M 92 +#define JH7100_CLK_USBPHY_PLLDIV25M 93 +#define JH7100_CLK_USBPHY_25M 94 +#define JH7100_CLK_AUDIO_DIV 95 +#define JH7100_CLK_AUDIO_SRC 96 +#define JH7100_CLK_AUDIO_12288 97 +#define JH7100_CLK_VIN_SRC 98 +#define JH7100_CLK_ISP0_BUS 99 +#define JH7100_CLK_ISP0_AXI 100 +#define JH7100_CLK_ISP0NOC_AXI 101 +#define JH7100_CLK_ISPSLV_AXI 102 +#define JH7100_CLK_ISP1_BUS 103 +#define JH7100_CLK_ISP1_AXI 104 +#define JH7100_CLK_ISP1NOC_AXI 105 +#define JH7100_CLK_VIN_BUS 106 +#define JH7100_CLK_VIN_AXI 107 +#define JH7100_CLK_VINNOC_AXI 108 +#define JH7100_CLK_VOUT_SRC 109 +#define JH7100_CLK_DISPBUS_SRC 110 +#define JH7100_CLK_DISP_BUS 111 +#define JH7100_CLK_DISP_AXI 112 +#define JH7100_CLK_DISPNOC_AXI 113 +#define JH7100_CLK_SDIO0_AHB 114 +#define JH7100_CLK_SDIO0_CCLKINT 115 +#define JH7100_CLK_SDIO0_CCLKINT_INV 116 +#define JH7100_CLK_SDIO1_AHB 117 +#define JH7100_CLK_SDIO1_CCLKINT 118 +#define JH7100_CLK_SDIO1_CCLKINT_INV 119 +#define JH7100_CLK_GMAC_AHB 120 +#define JH7100_CLK_GMAC_ROOT_DIV 121 +#define JH7100_CLK_GMAC_PTP_REF 122 +#define JH7100_CLK_GMAC_GTX 123 +#define JH7100_CLK_GMAC_RMII_TX 124 +#define JH7100_CLK_GMAC_RMII_RX 125 +#define JH7100_CLK_GMAC_TX 126 +#define JH7100_CLK_GMAC_TX_INV 127 +#define JH7100_CLK_GMAC_RX_PRE 128 +#define JH7100_CLK_GMAC_RX_INV 129 +#define JH7100_CLK_GMAC_RMII 130 +#define JH7100_CLK_GMAC_TOPHYREF 131 +#define JH7100_CLK_SPI2AHB_AHB 132 +#define JH7100_CLK_SPI2AHB_CORE 133 +#define JH7100_CLK_EZMASTER_AHB 134 +#define JH7100_CLK_E24_AHB 135 +#define JH7100_CLK_E24RTC_TOGGLE 136 +#define JH7100_CLK_QSPI_AHB 137 +#define JH7100_CLK_QSPI_APB 138 +#define JH7100_CLK_QSPI_REF 139 +#define JH7100_CLK_SEC_AHB 140 +#define JH7100_CLK_AES 141 +#define JH7100_CLK_SHA 142 +#define JH7100_CLK_PKA 143 +#define JH7100_CLK_TRNG_APB 144 +#define JH7100_CLK_OTP_APB 145 +#define JH7100_CLK_UART0_APB 146 +#define JH7100_CLK_UART0_CORE 147 +#define JH7100_CLK_UART1_APB 148 +#define JH7100_CLK_UART1_CORE 149 +#define JH7100_CLK_SPI0_APB 150 +#define JH7100_CLK_SPI0_CORE 151 +#define JH7100_CLK_SPI1_APB 152 +#define JH7100_CLK_SPI1_CORE 153 +#define JH7100_CLK_I2C0_APB 154 +#define JH7100_CLK_I2C0_CORE 155 +#define JH7100_CLK_I2C1_APB 156 +#define JH7100_CLK_I2C1_CORE 157 +#define JH7100_CLK_GPIO_APB 158 +#define JH7100_CLK_UART2_APB 159 +#define JH7100_CLK_UART2_CORE 160 +#define JH7100_CLK_UART3_APB 161 +#define JH7100_CLK_UART3_CORE 162 +#define JH7100_CLK_SPI2_APB 163 +#define JH7100_CLK_SPI2_CORE 164 +#define JH7100_CLK_SPI3_APB 165 +#define JH7100_CLK_SPI3_CORE 166 +#define JH7100_CLK_I2C2_APB 167 +#define JH7100_CLK_I2C2_CORE 168 +#define JH7100_CLK_I2C3_APB 169 +#define JH7100_CLK_I2C3_CORE 170 +#define JH7100_CLK_WDTIMER_APB 171 +#define JH7100_CLK_WDT_CORE 172 +#define JH7100_CLK_TIMER0_CORE 173 +#define JH7100_CLK_TIMER1_CORE 174 +#define JH7100_CLK_TIMER2_CORE 175 +#define JH7100_CLK_TIMER3_CORE 176 +#define JH7100_CLK_TIMER4_CORE 177 +#define JH7100_CLK_TIMER5_CORE 178 +#define JH7100_CLK_TIMER6_CORE 179 +#define JH7100_CLK_VP6INTC_APB 180 +#define JH7100_CLK_PWM_APB 181 +#define JH7100_CLK_MSI_APB 182 +#define JH7100_CLK_TEMP_APB 183 +#define JH7100_CLK_TEMP_SENSE 184 +#define JH7100_CLK_SYSERR_APB 185 + +#define JH7100_CLK_PLL0_OUT 186 +#define JH7100_CLK_PLL1_OUT 187 +#define JH7100_CLK_PLL2_OUT 188 + +#define JH7100_CLK_END 189 + +#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7100_H__ */
Signature · 1 line
2.33.1
Re: [PATCH v2 04/16] dt-bindings: clock: starfive: Add JH7100 clock definitions
Quoted 7 lines · Emil Renner Berthing
From: Geert Uytterhoeven <[email protected]>
Add all clock outputs for the StarFive JH7100 clock generator.
Based on work by Ahmad Fatoum for Barebox, with "
JH7100_" prefixes added to all definitions.
Quoted 7 lines
Signed-off-by Geert Uytterhoeven <[email protected]>Signed-off-by Emil Renner Berthing <[email protected]>--- include/dt-bindings/clock/starfive-jh7100.h | 202 ++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 include/dt-bindings/clock/starfive-jh7100.h
Emil Renner Berthing
maintainerPATCH v2 5/16 dt-bindings: clock: starfive: Add JH7100 bindings
In reply to Emil Renner BerthingFrom: Geert Uytterhoeven <[email protected]>
Add device tree bindings for the StarFive JH7100 clock generator.
--- .../clock/starfive,jh7100-clkgen.yaml | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7100-clkgen.yaml
Documentation/devicetree/bindings/clock/starfive,jh7100-clkgen.yaml new file +56 -0
@@ -0,0 +1,56 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/starfive,jh7100-clkgen.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: StarFive JH7100 Clock Generator + +maintainers: + - Geert Uytterhoeven <[email protected]> + - Emil Renner Berthing <[email protected]> + +properties: + compatible: + const: starfive,jh7100-clkgen + + reg: + maxItems: 1 + + clocks: + items: + - description: Main clock source (25 MHz) + - description: Application-specific clock source (12-27 MHz) + - description: RMII reference clock (50 MHz) + - description: RGMII RX clock (125 MHz) + + clock-names: + items: + - const: osc_sys + - const: osc_aud + - const: gmac_rmii_ref + - const: gmac_gr_mii_rxclk + + '#clock-cells': + const: 1 + description: + See <dt-bindings/clock/starfive-jh7100.h> for valid indices. + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + +additionalProperties: false + +examples: + - | + clkgen: clock-controller@11800000 { + compatible = "starfive,jh7100-clkgen"; + reg = <0x11800000 0x10000>; + clocks = <&osc_sys>, <&osc_aud>, <&gmac_rmii_ref>, <&gmac_gr_mii_rxclk>; + clock-names = "osc_sys", "osc_aud", "gmac_rmii_ref", "gmac_gr_mii_rxclk"; + #clock-cells = <1>; + };
Signature · 1 line
2.33.1
Re: [PATCH v2 05/16] dt-bindings: clock: starfive: Add JH7100 bindings
Quoted 11 lines · Emil Renner Berthing
From: Geert Uytterhoeven <[email protected]>
Add device tree bindings for the StarFive JH7100 clock generator.
Signed-off-by Geert Uytterhoeven <[email protected]>Signed-off-by Emil Renner Berthing <[email protected]>--- .../clock/starfive,jh7100-clkgen.yaml | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7100-clkgen.yaml
Emil Renner Berthing
maintainerRe: [PATCH v2 05/16] dt-bindings: clock: starfive: Add JH7100 bindings
Quoted 13 lines · Rob Herring
Quoted 11 lines · Emil Renner Berthing
From: Geert Uytterhoeven <[email protected]>
Add device tree bindings for the StarFive JH7100 clock generator.
Signed-off-by Geert Uytterhoeven <[email protected]>Signed-off-by Emil Renner Berthing <[email protected]>--- .../clock/starfive,jh7100-clkgen.yaml | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7100-clkgen.yaml
Quoted 1 line
Reviewed-by Rob Herring <[email protected]>
Thank you! For the reset bindings you said to remove unused labels in the example. If you don't mind I'll do that here too, but keep the tag.
/Emil
_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv
Emil Renner Berthing
maintainerPATCH v2 6/16 clk: starfive: Add JH7100 clock generator driver
In reply to Emil Renner BerthingFrom: Geert Uytterhoeven <[email protected]>
Add a driver for the StarFive JH7100 clock generator.
--- MAINTAINERS | 7 + drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 1 + drivers/clk/starfive/Kconfig | 9 + drivers/clk/starfive/Makefile | 3 + drivers/clk/starfive/clk-starfive-jh7100.c | 776 +++++++++++++++++++++ 6 files changed, 797 insertions(+) create mode 100644 drivers/clk/starfive/Kconfig create mode 100644 drivers/clk/starfive/Makefile create mode 100644 drivers/clk/starfive/clk-starfive-jh7100.c
MAINTAINERS +7 -0
@@ -17848,6 +17848,13 @@ M: Ion Badulescu <[email protected]> S: Odd Fixes F: drivers/net/ethernet/adaptec/starfire* +STARFIVE JH7100 CLOCK DRIVER +M: Emil Renner Berthing <[email protected]> +S: Maintained +F: Documentation/devicetree/bindings/clock/starfive,jh7100-clkgen.yaml +F: drivers/clk/starfive/clk-starfive-jh7100.c +F: include/dt-bindings/clock/starfive-jh7100.h + STATIC BRANCH/CALL M: Peter Zijlstra <[email protected]> M: Josh Poimboeuf <[email protected]>
drivers/clk/Kconfig +1 -0
@@ -412,6 +412,7 @@ source "drivers/clk/samsung/Kconfig" source "drivers/clk/sifive/Kconfig" source "drivers/clk/socfpga/Kconfig" source "drivers/clk/sprd/Kconfig" +source "drivers/clk/starfive/Kconfig" source "drivers/clk/sunxi/Kconfig" source "drivers/clk/sunxi-ng/Kconfig" source "drivers/clk/tegra/Kconfig"
drivers/clk/Makefile +1 -0
@@ -109,6 +109,7 @@ obj-y += socfpga/ obj-$(CONFIG_PLAT_SPEAR) += spear/ obj-y += sprd/ obj-$(CONFIG_ARCH_STI) += st/ +obj-$(CONFIG_SOC_STARFIVE) += starfive/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/ obj-$(CONFIG_SUNXI_CCU) += sunxi-ng/ obj-$(CONFIG_ARCH_TEGRA) += tegra/
drivers/clk/starfive/Kconfig new file +9 -0
@@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 + +config CLK_STARFIVE_JH7100 + bool "StarFive JH7100 clock support" + depends on SOC_STARFIVE || COMPILE_TEST + default SOC_STARFIVE + help + Say yes here to support the clock controller on the StarFive JH7100 + SoC.
drivers/clk/starfive/Makefile new file +3 -0
@@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 +# StarFive Clock +obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk-starfive-jh7100.o
drivers/clk/starfive/clk-starfive-jh7100.c new file +776 -0
776 lines not on this page · raw message
Signature · 1 line
2.33.1
Re: [PATCH v2 06/16] clk: starfive: Add JH7100 clock generator driver
On Thu, Oct 21, 2021 at 8:43 PM Emil Renner Berthing <[email protected]> wrote:
...
drivers/clk/starfive/clk-starfive-jh7100.c line 683
Quoted 8 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +8
-0+static struct clk_hw *clk_starfive_jh7100_get (struct of_phandle_args *clkspec,void *data) +{ +struct clk_starfive_jh7100_priv *priv = data; +unsigned int idx = clkspec->args[0 ]; + +if (idx >=JH7100_CLK_END ) { +dev_err (priv->dev,"invalid clock index %u\n" , idx); +return ERR_PTR (-EINVAL );
After this
https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/commit/?h=driver-core-next&id=7065f92255bb2468dbb9aa0537ff186ef64d5a02
It's okay to use
Quoted 1 line
+ }
if (idx >= JH7100_CLK_END)
return dev_err_probe(priv->dev, -EINVAL, "invalid clockindex %u\n", idx);
Ditto for other similar cases.
Quoted 5 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +5
-0+if (idx >=JH7100_CLK_PLL0_OUT ) +return priv->pll[idx -JH7100_CLK_PLL0_OUT ]; + +return &priv->reg[idx].hw; +}
...
drivers/clk/starfive/clk-starfive-jh7100.c line 755
Quoted 2 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +2
-0+while (idx) +clk_hw_unregister (&priv->reg[--idx].hw);
I still consider that usual pattern, i.e.
while (idx--)
clk_hw_unregister(&priv->reg[idx].hw);but since you are pushing hard for your variant I'll leave it to the maintainers and author.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Re: [PATCH v2 06/16] clk: starfive: Add JH7100 clock generator driver
Quoted 11 lines · Andy Shevchenko
drivers/clk/starfive/clk-starfive-jh7100.c line 755
Quoted 2 lines · Emil Renner Berthing
drivers/clk/starfive/clk-starfive-jh7100.c new file +2
-0+while (idx) +clk_hw_unregister (&priv->reg[--idx].hw);I still consider that usual pattern, i.e.
while (idx--) clk_hw_unregister(&priv->reg[idx].hw);but since you are pushing hard for your variant I'll leave it to the maintainers and author.
I agree with Andy.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
Emil Renner Berthing
maintainerRe: [PATCH v2 06/16] clk: starfive: Add JH7100 clock generator driver
In reply to Andy ShevchenkoQuoted 17 lines · Andy Shevchenko
On Thu, Oct 21, 2021 at 8:43 PM Emil Renner Berthing <[email protected]> wrote:
...
drivers/clk/starfive/clk-starfive-jh7100.c line 683
Quoted 8 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +8
-0+static struct clk_hw *clk_starfive_jh7100_get (struct of_phandle_args *clkspec,void *data) +{ +struct clk_starfive_jh7100_priv *priv = data; +unsigned int idx = clkspec->args[0 ]; + +if (idx >=JH7100_CLK_END ) { +dev_err (priv->dev,"invalid clock index %u\n" , idx); +return ERR_PTR (-EINVAL );After this
https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/commit/?h=driver-core-next&id=7065f92255bb2468dbb9aa0537ff186ef64d5a02
It's okay to use
Quoted 7 lines
Quoted 1 line
+ }
if (idx >= JH7100_CLK_END) return dev_err_probe(priv->dev, -EINVAL, "invalid clockindex %u\n", idx);
Ditto for other similar cases.
Hmm.. this function doesn't return int, but struct clk_hw *, hence the ERR_PTR. Also I don't see any other similar cases in this driver.
Quoted 22 lines
Quoted 5 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +5
-0+if (idx >=JH7100_CLK_PLL0_OUT ) +return priv->pll[idx -JH7100_CLK_PLL0_OUT ]; + +return &priv->reg[idx].hw; +}...
drivers/clk/starfive/clk-starfive-jh7100.c line 755
Quoted 2 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +2
-0+while (idx) +clk_hw_unregister (&priv->reg[--idx].hw);I still consider that usual pattern, i.e.
while (idx--) clk_hw_unregister(&priv->reg[idx].hw);but since you are pushing hard for your variant I'll leave it to the maintainers and author.
--
With Best Regards,
Andy Shevchenko
Re: [PATCH v2 06/16] clk: starfive: Add JH7100 clock generator driver
Quoted 1 line · Emil Renner Berthing
On Fri, 22 Oct 2021 at 14:34, Andy Shevchenko <[email protected]> wrote:
...
Quoted 1 line
Hmm.. this function doesn't return int, but struct
clk_hw*, hence theERR_PTR.
Ah, indeed, sorry. Got your point.
Of course one may try 'return ERR_PTR(dev_err_probe())', but this looks ugly.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Stephen Boyd
maintainerRe: [PATCH v2 06/16] clk: starfive: Add JH7100 clock generator driver
In reply to Emil Renner BerthingQuoting Emil Renner Berthing (2021-10-21 10:42:13)
Quoted 7 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +1
-0@@ -0,0 +1,776 @@ +// SPDX-License-Identifier: GPL-2.0
drivers/clk/starfive/clk-starfive-jh7100.c line 11
Quoted 10 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +10
-0+/* +* StarFive JH7100 Clock Generator Driver +* +* Copyright 2021 Ahmad Fatoum, Pengutronix +* Copyright (C) 2021 Glider bv +* Copyright (C) 2021 Emil Renner Berthing <[email protected]> +*/ + +#include <linux/bits.h> +#include <linux/clk.h>
Is this include used?
drivers/clk/starfive/clk-starfive-jh7100.c line 20
Quoted 9 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +9
-0+#include <linux/clk-provider.h> +#include <linux/debugfs.h> +#include <linux/device.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/overflow.h>
Is this include used?
Quoted 113 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +113
-0+#include <linux/platform_device.h> + +#include <dt-bindings/clock/starfive-jh7100.h> + +#define JH7100_CLK_ENABLE_SHIFT 31 +#define JH7100_CLK_INVERT_SHIFT 30 +#define JH7100_CLK_MUX_SHIFT 24 + +#define JH7100_CLK_ENABLE BIT(31) +#define JH7100_CLK_INVERT BIT(30) +#define JH7100_CLK_MUX_MASK GENMASK(27, 24) +#define JH7100_CLK_DIV_MASK GENMASK(23, 0) + +static const char *const cpundbus_root_sels[]__initconst = { + [0 ] ="osc_sys" , + [1 ] ="pll0_out" , + [2 ] ="pll1_out" , + [3 ] ="pll2_out" , +}; + +static const char *const dla_root_sels[]__initconst = { + [0 ] ="osc_sys" , + [1 ] ="pll1_out" , + [2 ] ="pll2_out" , +}; + +static const char *const dsp_root_sels[]__initconst = { + [0 ] ="osc_sys" , + [1 ] ="pll0_out" , + [2 ] ="pll1_out" , + [3 ] ="pll2_out" , +}; + +static const char *const gmacusb_root_sels[]__initconst = { + [0 ] ="osc_sys" , + [1 ] ="pll0_out" , + [2 ] ="pll2_out" , +}; + +static const char *const perh0_root_sels[]__initconst = { + [0 ] ="osc_sys" , + [1 ] ="pll0_out" , +}; + +static const char *const perh1_root_sels[]__initconst = { + [0 ] ="osc_sys" , + [1 ] ="pll2_out" , +}; + +static const char *const vin_root_sels[]__initconst = { + [0 ] ="osc_sys" , + [1 ] ="pll1_out" , + [2 ] ="pll2_out" , +}; + +static const char *const vout_root_sels[]__initconst = { + [0 ] ="osc_aud" , + [1 ] ="pll0_out" , + [2 ] ="pll2_out" , +}; + +static const char *const cdechifi4_root_sels[]__initconst = { + [0 ] ="osc_sys" , + [1 ] ="pll1_out" , + [2 ] ="pll2_out" , +}; + +static const char *const cdec_root_sels[]__initconst = { + [0 ] ="osc_sys" , + [1 ] ="pll0_out" , + [2 ] ="pll1_out" , +}; + +static const char *const voutbus_root_sels[]__initconst = { + [0 ] ="osc_aud" , + [1 ] ="pll0_out" , + [2 ] ="pll2_out" , +}; + +static const char *const pll2_refclk_sels[]__initconst = { + [0 ] ="osc_sys" , + [1 ] ="osc_aud" , +}; + +static const char *const ddrc0_sels[]__initconst = { + [0 ] ="ddrosc_div2" , + [1 ] ="ddrpll_div2" , + [2 ] ="ddrpll_div4" , + [3 ] ="ddrpll_div8" , +}; + +static const char *const ddrc1_sels[]__initconst = { + [0 ] ="ddrosc_div2" , + [1 ] ="ddrpll_div2" , + [2 ] ="ddrpll_div4" , + [3 ] ="ddrpll_div8" , +}; + +static const char *const nne_bus_sels[]__initconst = { + [0 ] ="cpu_axi" , + [1 ] ="nnebus_src1" , +}; + +static const char *const usbphy_25m_sels[]__initconst = { + [0 ] ="osc_sys" , + [1 ] ="usbphy_plldiv25m" , +}; + +static const char *const gmac_tx_sels[]__initconst = { + [0 ] ="gmac_gtxclk" , + [1 ] ="gmac_mii_txclk" , + [2 ] ="gmac_rmii_txclk" , +};
drivers/clk/starfive/clk-starfive-jh7100.c line 143
Quoted 10 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +10
-0+ +static const char *const gmac_rx_pre_sels[]__initconst = { + [0 ] ="gmac_gr_mii_rxclk" , + [1 ] ="gmac_rmii_rxclk" , +}; + +struct jh7100_clk { +struct clk_hw hw; +unsigned int idx; +u32 max;
Why u32?
drivers/clk/starfive/clk-starfive-jh7100.c line 148
Quoted 5 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +5
-0+}; + +struct clk_starfive_jh7100_priv { +/* protect registers against overlapping read-modify-write */ +spinlock_t rmw_lock;
Does overlapping mean concurrent? Do different clks share the same registers?
Quoted 55 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +55
-0+struct device *dev; +void __iomem *base; +struct clk_hw *pll[3 ]; +struct jh7100_clk reg[JH7100_CLK_PLL0_OUT ]; +}; + +static struct jh7100_clk *jh7100_clk_from (struct clk_hw *hw) +{ + return container_of(hw, struct jh7100_clk, hw); +} + +static struct clk_starfive_jh7100_priv *jh7100_priv_from (struct jh7100_clk *clk) +{ + return container_of(clk, struct clk_starfive_jh7100_priv, reg[clk->idx]); +} + +static u32 jh7100_clk_reg_get (struct jh7100_clk *clk) +{ +struct clk_starfive_jh7100_priv *priv =jh7100_priv_from (clk); +void __iomem *reg = priv->base +4 * clk->idx; + +return readl_relaxed (reg); +} + +static void jh7100_clk_reg_rmw (struct jh7100_clk *clk,u32 mask,u32 value) +{ +struct clk_starfive_jh7100_priv *priv =jh7100_priv_from (clk); +void __iomem *reg = priv->base +4 * clk->idx; +unsigned long flags; + +spin_lock_irqsave (&priv->rmw_lock, flags); + value |=readl_relaxed (reg) & ~mask; +writel_relaxed (value, reg); +spin_unlock_irqrestore (&priv->rmw_lock, flags); +} + +static int jh7100_clk_enable (struct clk_hw *hw) +{ +struct jh7100_clk *clk =jh7100_clk_from (hw); + +dev_dbg (jh7100_priv_from (clk)->dev,"enable(%s)\n" ,clk_hw_get_name (&clk->hw)); + +jh7100_clk_reg_rmw (clk,JH7100_CLK_ENABLE ,JH7100_CLK_ENABLE ); +return 0 ; +} + +static void jh7100_clk_disable (struct clk_hw *hw) +{ +struct jh7100_clk *clk =jh7100_clk_from (hw); + +dev_dbg (jh7100_priv_from (clk)->dev,"disable(%s)\n" ,clk_hw_get_name (&clk->hw)); + +jh7100_clk_reg_rmw (clk,JH7100_CLK_ENABLE ,0 ); +} +
drivers/clk/starfive/clk-starfive-jh7100.c line 213
Quoted 10 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +10
-0+static int jh7100_clk_is_enabled (struct clk_hw *hw) +{ +struct jh7100_clk *clk =jh7100_clk_from (hw); + +return !!(jh7100_clk_reg_get (clk) &JH7100_CLK_ENABLE ); +} + +static int jh7100_clk_is_parent_enabled (struct clk_hw *hw) +{ +return clk_hw_is_enabled (clk_hw_get_parent (hw));
Why do we need this function? The parent being enabled implies this clk is enabled if this clk can't gate itself but then knowing this clk is enabled is useful for what?
Quoted 86 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +86
-0+} + +static unsigned long jh7100_clk_recalc_rate (struct clk_hw *hw, +unsigned long parent_rate) +{ +struct jh7100_clk *clk =jh7100_clk_from (hw); +u32 value =jh7100_clk_reg_get (clk) &JH7100_CLK_DIV_MASK ; +unsigned long rate; + +if (value) + rate = parent_rate / value; +else + rate =0 ; + +dev_dbg (jh7100_priv_from (clk)->dev,"recalc_rate(%s, %lu) = %lu (div %u)\n" , +clk_hw_get_name (&clk->hw), parent_rate, rate, value); + +return rate; +} + +static unsigned long jh7100_clk_bestdiv (struct jh7100_clk *clk, +unsigned long rate,unsigned long parent) +{ +unsigned long max = clk->max &JH7100_CLK_DIV_MASK ; +unsigned long div =DIV_ROUND_UP (parent, rate); + +return min (div, max); +} + +static int jh7100_clk_determine_rate (struct clk_hw *hw, +struct clk_rate_request *req) +{ +struct jh7100_clk *clk =jh7100_clk_from (hw); +unsigned long parent = req->best_parent_rate; +unsigned long rate =clamp (req->rate, req->min_rate, req->max_rate); +unsigned long div =jh7100_clk_bestdiv (clk, rate, parent); +unsigned long result = parent / div; + +/* +* We want the result clamped by min_rate and max_rate if possible: +* Case 1: div hits the max divider value, which means it's less than +* parent / rate, so the result is greater than rate and min_rate in +* particular. We can't do anything about result > max_rate because the +* divider doesn't go any further. +* Case 2: div = DIV_ROUND_UP(parent, rate) which means the result is +* always lower or equal to rate and max_rate. However the result may +* turn out lower than min_rate, but then the next higher rate is fine: +* div - 1 = ceil(parent / rate) - 1 < parent / rate +* and thus +* min_rate <= rate < parent / (div - 1) +*/ +if (result < req->min_rate && div >1 ) { + div -=1 ; + result = parent / div; + } + +dev_dbg (jh7100_priv_from (clk)->dev, +"determine_rate(%s, {%lu<=%lu<=%lu from %lu}) = %lu (div %lu)\n" , +clk_hw_get_name (&clk->hw), req->min_rate, req->rate, req->max_rate, + parent, result, div); + + req->rate = result; +return 0 ; +} + +static int jh7100_clk_set_rate (struct clk_hw *hw, +unsigned long rate, +unsigned long parent_rate) +{ +struct jh7100_clk *clk =jh7100_clk_from (hw); +unsigned long div =jh7100_clk_bestdiv (clk, rate, parent_rate); + +dev_dbg (jh7100_priv_from (clk)->dev, +"set_rate(%s, %lu, %lu) = %lu (div %lu)\n" , +clk_hw_get_name (&clk->hw), rate, parent_rate, + parent_rate / div, div); + +jh7100_clk_reg_rmw (clk,JH7100_CLK_DIV_MASK , div); +return 0 ; +} + +static u8 jh7100_clk_get_parent (struct clk_hw *hw) +{ +struct jh7100_clk *clk =jh7100_clk_from (hw); +u32 value =jh7100_clk_reg_get (clk); +
drivers/clk/starfive/clk-starfive-jh7100.c line 309
Quoted 10 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +10
-0+return (value &JH7100_CLK_MUX_MASK ) >>JH7100_CLK_MUX_SHIFT ; +} + +static int jh7100_clk_set_parent (struct clk_hw *hw,u8 index) +{ +struct jh7100_clk *clk =jh7100_clk_from (hw); +u32 value = (u32 )index <<JH7100_CLK_MUX_SHIFT ; + +dev_dbg (jh7100_priv_from (clk)->dev,"set_parent(%s, %u)\n" , +clk_hw_get_name (&clk->hw), index);
Please remove these dev_dbg() messages. We have tracepoints for general clk operations and the driver shouldn't duplicate that.
Quoted 110 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +110
-0+ +jh7100_clk_reg_rmw (clk,JH7100_CLK_MUX_MASK , value); +return 0 ; +} + +static int jh7100_clk_mux_determine_rate (struct clk_hw *hw, +struct clk_rate_request *req) +{ +struct jh7100_clk *clk =jh7100_clk_from (hw); +int ret =clk_mux_determine_rate_flags (&clk->hw, req,0 ); + +dev_dbg (jh7100_priv_from (clk)->dev,"determine_rate(%s) = %d\n" , +clk_hw_get_name (&clk->hw), ret); + +return ret; +} + +static int jh7100_clk_get_phase (struct clk_hw *hw) +{ +struct jh7100_clk *clk =jh7100_clk_from (hw); +u32 value =jh7100_clk_reg_get (clk); + +return (value &JH7100_CLK_INVERT ) ?180 :0 ; +} + +static int jh7100_clk_set_phase (struct clk_hw *hw,int degrees) +{ +struct jh7100_clk *clk =jh7100_clk_from (hw); +u32 value; + +dev_dbg (jh7100_priv_from (clk)->dev,"set_phase(%s, %d)\n" , +clk_hw_get_name (&clk->hw), degrees); + +if (degrees ==0 ) + value =0 ; +else if (degrees ==180 ) + value =JH7100_CLK_INVERT ; +else +return -EINVAL ; + +jh7100_clk_reg_rmw (clk,JH7100_CLK_INVERT , value); +return 0 ; +} + +#ifdef CONFIG_DEBUG_FS +static void jh7100_clk_debug_init (struct clk_hw *hw,struct dentry *dentry) +{ +static const struct debugfs_reg32 jh7100_clk_reg = { + .name ="CTRL" , + .offset =0 , + }; +struct jh7100_clk *clk =jh7100_clk_from (hw); +struct clk_starfive_jh7100_priv *priv =jh7100_priv_from (clk); +struct debugfs_regset32 *regset; + + regset =devm_kzalloc (priv->dev,sizeof (*regset),GFP_KERNEL ); +if (!regset) +return ; + + regset->regs = &jh7100_clk_reg; + regset->nregs =1 ; + regset->base = priv->base +4 * clk->idx; + +debugfs_create_regset32 ("registers" ,0400 , dentry, regset); +} +#else +#define jh7100_clk_debug_init NULL +#endif + +static const struct clk_ops jh7100_clk_gate_ops = { + .enable = jh7100_clk_enable, + .disable = jh7100_clk_disable, + .is_enabled = jh7100_clk_is_enabled, + .debug_init = jh7100_clk_debug_init, +}; + +static const struct clk_ops jh7100_clk_div_ops = { + .is_enabled = jh7100_clk_is_parent_enabled, + .recalc_rate = jh7100_clk_recalc_rate, + .determine_rate = jh7100_clk_determine_rate, + .set_rate = jh7100_clk_set_rate, + .debug_init = jh7100_clk_debug_init, +}; + +static const struct clk_ops jh7100_clk_gdiv_ops = { + .enable = jh7100_clk_enable, + .disable = jh7100_clk_disable, + .is_enabled = jh7100_clk_is_enabled, + .recalc_rate = jh7100_clk_recalc_rate, + .determine_rate = jh7100_clk_determine_rate, + .set_rate = jh7100_clk_set_rate, + .debug_init = jh7100_clk_debug_init, +}; + +static const struct clk_ops jh7100_clk_mux_ops = { + .is_enabled = jh7100_clk_is_parent_enabled, + .get_parent = jh7100_clk_get_parent, + .set_parent = jh7100_clk_set_parent, + .determine_rate = jh7100_clk_mux_determine_rate, + .debug_init = jh7100_clk_debug_init, +}; + +static const struct clk_ops jh7100_clk_gmux_ops = { + .enable = jh7100_clk_enable, + .disable = jh7100_clk_disable, + .is_enabled = jh7100_clk_is_enabled, + .get_parent = jh7100_clk_get_parent, + .set_parent = jh7100_clk_set_parent, + .determine_rate = jh7100_clk_mux_determine_rate, + .debug_init = jh7100_clk_debug_init,
drivers/clk/starfive/clk-starfive-jh7100.c line 429
Quoted 10 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +10
-0+}; + +static const struct clk_ops jh7100_clk_inv_ops = { + .is_enabled = jh7100_clk_is_parent_enabled, + .get_phase = jh7100_clk_get_phase, + .set_phase = jh7100_clk_set_phase, + .debug_init = jh7100_clk_debug_init, +}; + +#define JH7100_GATE (_idx, _name, _parent, _flags) [_idx] = { \
Typical macro style is to tab out the \ to a single column
Quoted 116 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +116
-0+ .name = _name, \ + .ops = &jh7100_clk_gate_ops, \ + .parent = _parent, \ + .flags = CLK_SET_RATE_PARENT | (_flags), \ + .max = JH7100_CLK_ENABLE, \ +} + +#define JH7100__DIV (_idx, _name, _parent, _max) [_idx] = { \ + .name = _name, \ + .ops = &jh7100_clk_div_ops, \ + .parent = _parent, \ + .flags = 0, \ + .max = _max, \ +} + +#define JH7100_GDIV (_idx, _name, _parent, _max, _flags) [_idx] = { \ + .name = _name, \ + .ops = &jh7100_clk_gdiv_ops, \ + .parent = _parent, \ + .flags = (_flags), \ + .max = JH7100_CLK_ENABLE | (_max), \ +} + +#define JH7100__MUX (_idx, _name, _parents) [_idx] = { \ + .name = _name, \ + .ops = &jh7100_clk_mux_ops, \ + .parents = _parents, \ + .flags = 0, \ + .max = (ARRAY_SIZE(_parents) - 1) << JH7100_CLK_MUX_SHIFT, \ +} + +#define JH7100_GMUX (_idx, _name, _parents, _flags) [_idx] = { \ + .name = _name, \ + .ops = &jh7100_clk_gmux_ops, \ + .parents = _parents, \ + .flags = (_flags), \ + .max = JH7100_CLK_ENABLE | \ + ((ARRAY_SIZE(_parents) - 1) << JH7100_CLK_MUX_SHIFT), \ +} + +#define JH7100__INV (_idx, _name, _parent) [_idx] = { \ + .name = _name, \ + .ops = &jh7100_clk_inv_ops, \ + .parent = _parent, \ + .flags = CLK_SET_RATE_PARENT, \ + .max = JH7100_CLK_INVERT, \ +} + +static const struct { +const char *name; +const struct clk_ops *ops; +union { +const char *parent; +const char *const *parents; + }; +unsigned long flags; +u32 max; +} jh7100_clk_data[]__initconst = { +JH7100__MUX (JH7100_CLK_CPUNDBUS_ROOT ,"cpundbus_root" , cpundbus_root_sels), +JH7100__MUX (JH7100_CLK_DLA_ROOT ,"dla_root" , dla_root_sels), +JH7100__MUX (JH7100_CLK_DSP_ROOT ,"dsp_root" , dsp_root_sels), +JH7100__MUX (JH7100_CLK_GMACUSB_ROOT ,"gmacusb_root" , gmacusb_root_sels), +JH7100__MUX (JH7100_CLK_PERH0_ROOT ,"perh0_root" , perh0_root_sels), +JH7100__MUX (JH7100_CLK_PERH1_ROOT ,"perh1_root" , perh1_root_sels), +JH7100__MUX (JH7100_CLK_VIN_ROOT ,"vin_root" , vin_root_sels), +JH7100__MUX (JH7100_CLK_VOUT_ROOT ,"vout_root" , vout_root_sels), +JH7100_GDIV (JH7100_CLK_AUDIO_ROOT ,"audio_root" ,"pll0_out" ,8 ,0 ), +JH7100__MUX (JH7100_CLK_CDECHIFI4_ROOT ,"cdechifi4_root" , cdechifi4_root_sels), +JH7100__MUX (JH7100_CLK_CDEC_ROOT ,"cdec_root" , cdec_root_sels), +JH7100__MUX (JH7100_CLK_VOUTBUS_ROOT ,"voutbus_root" , voutbus_root_sels), +JH7100__DIV (JH7100_CLK_CPUNBUS_ROOT_DIV ,"cpunbus_root_div" ,"cpundbus_root" ,2 ), +JH7100__DIV (JH7100_CLK_DSP_ROOT_DIV ,"dsp_root_div" ,"dsp_root" ,4 ), +JH7100__DIV (JH7100_CLK_PERH0_SRC ,"perh0_src" ,"perh0_root" ,4 ), +JH7100__DIV (JH7100_CLK_PERH1_SRC ,"perh1_src" ,"perh1_root" ,4 ), +JH7100_GDIV (JH7100_CLK_PLL0_TESTOUT ,"pll0_testout" ,"perh0_src" ,31 ,0 ), +JH7100_GDIV (JH7100_CLK_PLL1_TESTOUT ,"pll1_testout" ,"dla_root" ,31 ,0 ), +JH7100_GDIV (JH7100_CLK_PLL2_TESTOUT ,"pll2_testout" ,"perh1_src" ,31 ,0 ), +JH7100__MUX (JH7100_CLK_PLL2_REF ,"pll2_refclk" , pll2_refclk_sels), +JH7100__DIV (JH7100_CLK_CPU_CORE ,"cpu_core" ,"cpunbus_root_div" ,8 ), +JH7100__DIV (JH7100_CLK_CPU_AXI ,"cpu_axi" ,"cpu_core" ,8 ), +JH7100__DIV (JH7100_CLK_AHB_BUS ,"ahb_bus" ,"cpunbus_root_div" ,8 ), +JH7100__DIV (JH7100_CLK_APB1_BUS ,"apb1_bus" ,"ahb_bus" ,8 ), +JH7100__DIV (JH7100_CLK_APB2_BUS ,"apb2_bus" ,"ahb_bus" ,8 ), +JH7100_GATE (JH7100_CLK_DOM3AHB_BUS ,"dom3ahb_bus" ,"ahb_bus" ,CLK_IGNORE_UNUSED ), +JH7100_GATE (JH7100_CLK_DOM7AHB_BUS ,"dom7ahb_bus" ,"ahb_bus" ,CLK_IGNORE_UNUSED ), +JH7100_GATE (JH7100_CLK_U74_CORE0 ,"u74_core0" ,"cpu_core" ,CLK_IGNORE_UNUSED ), +JH7100_GDIV (JH7100_CLK_U74_CORE1 ,"u74_core1" ,"cpu_core" ,8 ,CLK_IGNORE_UNUSED ), +JH7100_GATE (JH7100_CLK_U74_AXI ,"u74_axi" ,"cpu_axi" ,CLK_IGNORE_UNUSED ), +JH7100_GATE (JH7100_CLK_U74RTC_TOGGLE ,"u74rtc_toggle" ,"osc_sys" ,CLK_IGNORE_UNUSED ), +JH7100_GATE (JH7100_CLK_SGDMA2P_AXI ,"sgdma2p_axi" ,"cpu_axi" ,0 ), +JH7100_GATE (JH7100_CLK_DMA2PNOC_AXI ,"dma2pnoc_axi" ,"cpu_axi" ,0 ), +JH7100_GATE (JH7100_CLK_SGDMA2P_AHB ,"sgdma2p_ahb" ,"ahb_bus" ,0 ), +JH7100__DIV (JH7100_CLK_DLA_BUS ,"dla_bus" ,"dla_root" ,4 ), +JH7100_GATE (JH7100_CLK_DLA_AXI ,"dla_axi" ,"dla_bus" ,0 ), +JH7100_GATE (JH7100_CLK_DLANOC_AXI ,"dlanoc_axi" ,"dla_bus" ,0 ), +JH7100_GATE (JH7100_CLK_DLA_APB ,"dla_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_VP6_CORE ,"vp6_core" ,"dsp_root_div" ,4 ,0 ), +JH7100__DIV (JH7100_CLK_VP6BUS_SRC ,"vp6bus_src" ,"dsp_root" ,4 ), +JH7100_GDIV (JH7100_CLK_VP6_AXI ,"vp6_axi" ,"vp6bus_src" ,4 ,0 ), +JH7100__DIV (JH7100_CLK_VCDECBUS_SRC ,"vcdecbus_src" ,"cdechifi4_root" ,4 ), +JH7100__DIV (JH7100_CLK_VDEC_BUS ,"vdec_bus" ,"vcdecbus_src" ,8 ), +JH7100_GATE (JH7100_CLK_VDEC_AXI ,"vdec_axi" ,"vdec_bus" ,0 ), +JH7100_GATE (JH7100_CLK_VDECBRG_MAIN ,"vdecbrg_mainclk" ,"vdec_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_VDEC_BCLK ,"vdec_bclk" ,"vcdecbus_src" ,8 ,0 ), +JH7100_GDIV (JH7100_CLK_VDEC_CCLK ,"vdec_cclk" ,"cdec_root" ,8 ,0 ), +JH7100_GATE (JH7100_CLK_VDEC_APB ,"vdec_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_JPEG_AXI ,"jpeg_axi" ,"cpunbus_root_div" ,8 ,0 ), +JH7100_GDIV (JH7100_CLK_JPEG_CCLK ,"jpeg_cclk" ,"cpunbus_root_div" ,8 ,0 ), +JH7100_GATE (JH7100_CLK_JPEG_APB ,"jpeg_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_GC300_2X ,"gc300_2x" ,"cdechifi4_root" ,8 ,0 ), +JH7100_GATE (JH7100_CLK_GC300_AHB ,"gc300_ahb" ,"ahb_bus" ,0 ), +JH7100__DIV (JH7100_CLK_JPCGC300_AXIBUS ,"jpcgc300_axibus" ,"vcdecbus_src" ,8 ), +JH7100_GATE (JH7100_CLK_GC300_AXI ,"gc300_axi" ,"jpcgc300_axibus" ,0 ), +JH7100_GATE (JH7100_CLK_JPCGC300_MAIN ,"jpcgc300_mainclk" ,"jpcgc300_axibus" ,0 ), +JH7100__DIV (JH7100_CLK_VENC_BUS ,"venc_bus" ,"vcdecbus_src" ,8 ), +JH7100_GATE (JH7100_CLK_VENC_AXI ,"venc_axi" ,"venc_bus" ,0 ),
drivers/clk/starfive/clk-starfive-jh7100.c line 555
Quoted 10 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +10
-0+JH7100_GATE (JH7100_CLK_VENCBRG_MAIN ,"vencbrg_mainclk" ,"venc_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_VENC_BCLK ,"venc_bclk" ,"vcdecbus_src" ,8 ,0 ), +JH7100_GDIV (JH7100_CLK_VENC_CCLK ,"venc_cclk" ,"cdec_root" ,8 ,0 ), +JH7100_GATE (JH7100_CLK_VENC_APB ,"venc_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_DDRPLL_DIV2 ,"ddrpll_div2" ,"pll1_out" ,2 ,CLK_IGNORE_UNUSED ), +JH7100_GDIV (JH7100_CLK_DDRPLL_DIV4 ,"ddrpll_div4" ,"ddrpll_div2" ,2 ,CLK_IGNORE_UNUSED ), +JH7100_GDIV (JH7100_CLK_DDRPLL_DIV8 ,"ddrpll_div8" ,"ddrpll_div4" ,2 ,CLK_IGNORE_UNUSED ), +JH7100_GDIV (JH7100_CLK_DDROSC_DIV2 ,"ddrosc_div2" ,"osc_sys" ,2 ,CLK_IGNORE_UNUSED ), +JH7100_GMUX (JH7100_CLK_DDRC0 ,"ddrc0" , ddrc0_sels,CLK_IGNORE_UNUSED ), + JH7100_GMUX(JH7100_CLK_DDRC1, "ddrc1", ddrc1_sels, CLK_IGNORE_UNUSED),
Is it really unused? Or it is CLK_IS_CRITICAL?
Quoted 117 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +117
-0+JH7100_GATE (JH7100_CLK_DDRPHY_APB ,"ddrphy_apb" ,"apb1_bus" ,CLK_IGNORE_UNUSED ), +JH7100__DIV (JH7100_CLK_NOC_ROB ,"noc_rob" ,"cpunbus_root_div" ,8 ), +JH7100__DIV (JH7100_CLK_NOC_COG ,"noc_cog" ,"dla_root" ,8 ), +JH7100_GATE (JH7100_CLK_NNE_AHB ,"nne_ahb" ,"ahb_bus" ,0 ), +JH7100__DIV (JH7100_CLK_NNEBUS_SRC1 ,"nnebus_src1" ,"dsp_root" ,4 ), +JH7100__MUX (JH7100_CLK_NNE_BUS ,"nne_bus" , nne_bus_sels), +JH7100_GATE (JH7100_CLK_NNE_AXI ,"nne_axi" ,"nne_bus" ,0 ), +JH7100_GATE (JH7100_CLK_NNENOC_AXI ,"nnenoc_axi" ,"nne_bus" ,0 ), +JH7100_GATE (JH7100_CLK_DLASLV_AXI ,"dlaslv_axi" ,"nne_bus" ,0 ), +JH7100_GATE (JH7100_CLK_DSPX2C_AXI ,"dspx2c_axi" ,"nne_bus" ,CLK_IGNORE_UNUSED ), +JH7100__DIV (JH7100_CLK_HIFI4_SRC ,"hifi4_src" ,"cdechifi4_root" ,4 ), +JH7100__DIV (JH7100_CLK_HIFI4_COREFREE ,"hifi4_corefree" ,"hifi4_src" ,8 ), +JH7100_GATE (JH7100_CLK_HIFI4_CORE ,"hifi4_core" ,"hifi4_corefree" ,0 ), +JH7100__DIV (JH7100_CLK_HIFI4_BUS ,"hifi4_bus" ,"hifi4_corefree" ,8 ), +JH7100_GATE (JH7100_CLK_HIFI4_AXI ,"hifi4_axi" ,"hifi4_bus" ,0 ), +JH7100_GATE (JH7100_CLK_HIFI4NOC_AXI ,"hifi4noc_axi" ,"hifi4_bus" ,0 ), +JH7100__DIV (JH7100_CLK_SGDMA1P_BUS ,"sgdma1p_bus" ,"cpunbus_root_div" ,8 ), +JH7100_GATE (JH7100_CLK_SGDMA1P_AXI ,"sgdma1p_axi" ,"sgdma1p_bus" ,0 ), +JH7100_GATE (JH7100_CLK_DMA1P_AXI ,"dma1p_axi" ,"sgdma1p_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_X2C_AXI ,"x2c_axi" ,"cpunbus_root_div" ,8 ,CLK_IGNORE_UNUSED ), +JH7100__DIV (JH7100_CLK_USB_BUS ,"usb_bus" ,"cpunbus_root_div" ,8 ), +JH7100_GATE (JH7100_CLK_USB_AXI ,"usb_axi" ,"usb_bus" ,0 ), +JH7100_GATE (JH7100_CLK_USBNOC_AXI ,"usbnoc_axi" ,"usb_bus" ,0 ), +JH7100__DIV (JH7100_CLK_USBPHY_ROOTDIV ,"usbphy_rootdiv" ,"gmacusb_root" ,4 ), +JH7100_GDIV (JH7100_CLK_USBPHY_125M ,"usbphy_125m" ,"usbphy_rootdiv" ,8 ,0 ), +JH7100_GDIV (JH7100_CLK_USBPHY_PLLDIV25M ,"usbphy_plldiv25m" ,"usbphy_rootdiv" ,32 ,0 ), +JH7100__MUX (JH7100_CLK_USBPHY_25M ,"usbphy_25m" , usbphy_25m_sels), +JH7100__DIV (JH7100_CLK_AUDIO_DIV ,"audio_div" ,"audio_root" ,131072 ), +JH7100_GATE (JH7100_CLK_AUDIO_SRC ,"audio_src" ,"audio_div" ,0 ), +JH7100_GATE (JH7100_CLK_AUDIO_12288 ,"audio_12288" ,"osc_aud" ,0 ), +JH7100_GDIV (JH7100_CLK_VIN_SRC ,"vin_src" ,"vin_root" ,4 ,0 ), +JH7100__DIV (JH7100_CLK_ISP0_BUS ,"isp0_bus" ,"vin_src" ,8 ), +JH7100_GATE (JH7100_CLK_ISP0_AXI ,"isp0_axi" ,"isp0_bus" ,0 ), +JH7100_GATE (JH7100_CLK_ISP0NOC_AXI ,"isp0noc_axi" ,"isp0_bus" ,0 ), +JH7100_GATE (JH7100_CLK_ISPSLV_AXI ,"ispslv_axi" ,"isp0_bus" ,0 ), +JH7100__DIV (JH7100_CLK_ISP1_BUS ,"isp1_bus" ,"vin_src" ,8 ), +JH7100_GATE (JH7100_CLK_ISP1_AXI ,"isp1_axi" ,"isp1_bus" ,0 ), +JH7100_GATE (JH7100_CLK_ISP1NOC_AXI ,"isp1noc_axi" ,"isp1_bus" ,0 ), +JH7100__DIV (JH7100_CLK_VIN_BUS ,"vin_bus" ,"vin_src" ,8 ), +JH7100_GATE (JH7100_CLK_VIN_AXI ,"vin_axi" ,"vin_bus" ,0 ), +JH7100_GATE (JH7100_CLK_VINNOC_AXI ,"vinnoc_axi" ,"vin_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_VOUT_SRC ,"vout_src" ,"vout_root" ,4 ,0 ), +JH7100__DIV (JH7100_CLK_DISPBUS_SRC ,"dispbus_src" ,"voutbus_root" ,4 ), +JH7100__DIV (JH7100_CLK_DISP_BUS ,"disp_bus" ,"dispbus_src" ,4 ), +JH7100_GATE (JH7100_CLK_DISP_AXI ,"disp_axi" ,"disp_bus" ,0 ), +JH7100_GATE (JH7100_CLK_DISPNOC_AXI ,"dispnoc_axi" ,"disp_bus" ,0 ), +JH7100_GATE (JH7100_CLK_SDIO0_AHB ,"sdio0_ahb" ,"ahb_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_SDIO0_CCLKINT ,"sdio0_cclkint" ,"perh0_src" ,24 ,0 ), +JH7100__INV (JH7100_CLK_SDIO0_CCLKINT_INV ,"sdio0_cclkint_inv" ,"sdio0_cclkint" ), +JH7100_GATE (JH7100_CLK_SDIO1_AHB ,"sdio1_ahb" ,"ahb_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_SDIO1_CCLKINT ,"sdio1_cclkint" ,"perh1_src" ,24 ,0 ), +JH7100__INV (JH7100_CLK_SDIO1_CCLKINT_INV ,"sdio1_cclkint_inv" ,"sdio1_cclkint" ), +JH7100_GATE (JH7100_CLK_GMAC_AHB ,"gmac_ahb" ,"ahb_bus" ,0 ), +JH7100__DIV (JH7100_CLK_GMAC_ROOT_DIV ,"gmac_root_div" ,"gmacusb_root" ,8 ), +JH7100_GDIV (JH7100_CLK_GMAC_PTP_REF ,"gmac_ptp_refclk" ,"gmac_root_div" ,31 ,0 ), +JH7100_GDIV (JH7100_CLK_GMAC_GTX ,"gmac_gtxclk" ,"gmac_root_div" ,255 ,0 ), +JH7100_GDIV (JH7100_CLK_GMAC_RMII_TX ,"gmac_rmii_txclk" ,"gmac_rmii_ref" ,8 ,0 ), +JH7100_GDIV (JH7100_CLK_GMAC_RMII_RX ,"gmac_rmii_rxclk" ,"gmac_rmii_ref" ,8 ,0 ), +JH7100__MUX (JH7100_CLK_GMAC_TX ,"gmac_tx" , gmac_tx_sels), +JH7100__INV (JH7100_CLK_GMAC_TX_INV ,"gmac_tx_inv" ,"gmac_tx" ), +JH7100__MUX (JH7100_CLK_GMAC_RX_PRE ,"gmac_rx_pre" , gmac_rx_pre_sels), +JH7100__INV (JH7100_CLK_GMAC_RX_INV ,"gmac_rx_inv" ,"gmac_rx_pre" ), +JH7100_GATE (JH7100_CLK_GMAC_RMII ,"gmac_rmii" ,"gmac_rmii_ref" ,0 ), +JH7100_GDIV (JH7100_CLK_GMAC_TOPHYREF ,"gmac_tophyref" ,"gmac_root_div" ,127 ,0 ), +JH7100_GATE (JH7100_CLK_SPI2AHB_AHB ,"spi2ahb_ahb" ,"ahb_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_SPI2AHB_CORE ,"spi2ahb_core" ,"perh0_src" ,31 ,0 ), +JH7100_GATE (JH7100_CLK_EZMASTER_AHB ,"ezmaster_ahb" ,"ahb_bus" ,0 ), +JH7100_GATE (JH7100_CLK_E24_AHB ,"e24_ahb" ,"ahb_bus" ,0 ), +JH7100_GATE (JH7100_CLK_E24RTC_TOGGLE ,"e24rtc_toggle" ,"osc_sys" ,0 ), +JH7100_GATE (JH7100_CLK_QSPI_AHB ,"qspi_ahb" ,"ahb_bus" ,0 ), +JH7100_GATE (JH7100_CLK_QSPI_APB ,"qspi_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_QSPI_REF ,"qspi_refclk" ,"perh0_src" ,31 ,0 ), +JH7100_GATE (JH7100_CLK_SEC_AHB ,"sec_ahb" ,"ahb_bus" ,0 ), +JH7100_GATE (JH7100_CLK_AES ,"aes_clk" ,"sec_ahb" ,0 ), +JH7100_GATE (JH7100_CLK_SHA ,"sha_clk" ,"sec_ahb" ,0 ), +JH7100_GATE (JH7100_CLK_PKA ,"pka_clk" ,"sec_ahb" ,0 ), +JH7100_GATE (JH7100_CLK_TRNG_APB ,"trng_apb" ,"apb1_bus" ,0 ), +JH7100_GATE (JH7100_CLK_OTP_APB ,"otp_apb" ,"apb1_bus" ,0 ), +JH7100_GATE (JH7100_CLK_UART0_APB ,"uart0_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_UART0_CORE ,"uart0_core" ,"perh1_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_UART1_APB ,"uart1_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_UART1_CORE ,"uart1_core" ,"perh1_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_SPI0_APB ,"spi0_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_SPI0_CORE ,"spi0_core" ,"perh1_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_SPI1_APB ,"spi1_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_SPI1_CORE ,"spi1_core" ,"perh1_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_I2C0_APB ,"i2c0_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_I2C0_CORE ,"i2c0_core" ,"perh1_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_I2C1_APB ,"i2c1_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_I2C1_CORE ,"i2c1_core" ,"perh1_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_GPIO_APB ,"gpio_apb" ,"apb1_bus" ,0 ), +JH7100_GATE (JH7100_CLK_UART2_APB ,"uart2_apb" ,"apb2_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_UART2_CORE ,"uart2_core" ,"perh0_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_UART3_APB ,"uart3_apb" ,"apb2_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_UART3_CORE ,"uart3_core" ,"perh0_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_SPI2_APB ,"spi2_apb" ,"apb2_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_SPI2_CORE ,"spi2_core" ,"perh0_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_SPI3_APB ,"spi3_apb" ,"apb2_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_SPI3_CORE ,"spi3_core" ,"perh0_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_I2C2_APB ,"i2c2_apb" ,"apb2_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_I2C2_CORE ,"i2c2_core" ,"perh0_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_I2C3_APB ,"i2c3_apb" ,"apb2_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_I2C3_CORE ,"i2c3_core" ,"perh0_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_WDTIMER_APB ,"wdtimer_apb" ,"apb2_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_WDT_CORE ,"wdt_coreclk" ,"perh0_src" ,63 ,0 ), +JH7100_GDIV (JH7100_CLK_TIMER0_CORE ,"timer0_coreclk" ,"perh0_src" ,63 ,0 ), +JH7100_GDIV (JH7100_CLK_TIMER1_CORE ,"timer1_coreclk" ,"perh0_src" ,63 ,0 ), +JH7100_GDIV (JH7100_CLK_TIMER2_CORE ,"timer2_coreclk" ,"perh0_src" ,63 ,0 ), +JH7100_GDIV (JH7100_CLK_TIMER3_CORE ,"timer3_coreclk" ,"perh0_src" ,63 ,0 ), +JH7100_GDIV (JH7100_CLK_TIMER4_CORE ,"timer4_coreclk" ,"perh0_src" ,63 ,0 ), +JH7100_GDIV (JH7100_CLK_TIMER5_CORE ,"timer5_coreclk" ,"perh0_src" ,63 ,0 ), +JH7100_GDIV (JH7100_CLK_TIMER6_CORE ,"timer6_coreclk" ,"perh0_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_VP6INTC_APB ,"vp6intc_apb" ,"apb2_bus" ,0 ), +JH7100_GATE (JH7100_CLK_PWM_APB ,"pwm_apb" ,"apb2_bus" ,0 ), +JH7100_GATE (JH7100_CLK_MSI_APB ,"msi_apb" ,"apb2_bus" ,0 ), +JH7100_GATE (JH7100_CLK_TEMP_APB ,"temp_apb" ,"apb2_bus" ,0 ), + JH7100_GDIV(JH7100_CLK_TEMP_SENSE, "temp_sense", "osc_sys", 31, 0),
drivers/clk/starfive/clk-starfive-jh7100.c line 682
Quoted 10 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +10
-0+ JH7100_GATE(JH7100_CLK_SYSERR_APB, "syserr_apb", "apb2_bus", 0), +}; + +static struct clk_hw *clk_starfive_jh7100_get (struct of_phandle_args *clkspec,void *data) +{ +struct clk_starfive_jh7100_priv *priv = data; +unsigned int idx = clkspec->args[0 ]; + +if (idx >=JH7100_CLK_END ) { +dev_err (priv->dev,"invalid clock index %u\n" , idx);
We should pull this sort of error message up into the core instead of have it in every driver. It also doesn't look very meaningful to print the name of the device that's providing the clks vs. the name of the device that's requesting the clk that can't be found.
drivers/clk/starfive/clk-starfive-jh7100.c line 692
Quoted 10 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +10
-0+return ERR_PTR (-EINVAL ); + } + +if (idx >=JH7100_CLK_PLL0_OUT ) +return priv->pll[idx -JH7100_CLK_PLL0_OUT ]; + +return &priv->reg[idx].hw; +} + +static int __init clk_starfive_jh7100_probe (struct platform_device *pdev)
Drop __init as this can be called after kernel init is over.
Quoted 35 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +35
-0+{ +struct clk_starfive_jh7100_priv *priv; +unsigned int idx; +int ret; + + priv =devm_kzalloc (&pdev->dev,sizeof (*priv),GFP_KERNEL ); +if (!priv) +return -ENOMEM ; + +spin_lock_init (&priv->rmw_lock); + priv->dev = &pdev->dev; + priv->base =devm_platform_ioremap_resource (pdev,0 ); +if (IS_ERR (priv->base)) +return PTR_ERR (priv->base); + + priv->pll[0 ] =devm_clk_hw_register_fixed_factor (priv->dev,"pll0_out" , +"osc_sys" ,0 ,40 ,1 ); +if (IS_ERR (priv->pll[0 ])) +return PTR_ERR (priv->pll[0 ]); + + priv->pll[1 ] =devm_clk_hw_register_fixed_factor (priv->dev,"pll1_out" , +"osc_sys" ,0 ,64 ,1 ); +if (IS_ERR (priv->pll[1 ])) +return PTR_ERR (priv->pll[1 ]); + + priv->pll[2 ] =devm_clk_hw_register_fixed_factor (priv->dev,"pll2_out" , +"pll2_refclk" ,0 ,55 ,1 ); +if (IS_ERR (priv->pll[2 ])) +return PTR_ERR (priv->pll[2 ]); + +for (idx =0 ; idx <JH7100_CLK_PLL0_OUT ; idx++) { +u32 max_parent = (jh7100_clk_data[idx].max &JH7100_CLK_MUX_MASK ) >> +JH7100_CLK_MUX_SHIFT ; +struct clk_init_data init = { + .name = jh7100_clk_data[idx].name,
drivers/clk/starfive/clk-starfive-jh7100.c line 737
Quoted 10 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +10
-0+ .ops = jh7100_clk_data[idx].ops, + .num_parents = max_parent + 1, + .flags = jh7100_clk_data[idx].flags, + }; +struct jh7100_clk *clk = &priv->reg[idx]; + +if (init.num_parents >1 ) + init.parent_names = jh7100_clk_data[idx].parents; +else + init.parent_names = &jh7100_clk_data[idx].parent;
Can you use clk_parent_data instead of parent_names? To make the object size even smaller you can use the DT index instead of the .fw_name field.
drivers/clk/starfive/clk-starfive-jh7100.c line 743
Quoted 6 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +6
-0+ + clk->hw.init = &init; + clk->idx = idx; + clk->max = jh7100_clk_data[idx].max; + + ret =clk_hw_register (priv->dev, &clk->hw);
Why not use devm_clk_hw_register()?
Quoted 9 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +9
-0+if (ret) + goto err; + } + + ret =devm_of_clk_add_hw_provider (priv->dev, clk_starfive_jh7100_get, priv); +if (ret) + goto err; + +return 0 ;
drivers/clk/starfive/clk-starfive-jh7100.c line 762
Quoted 10 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +10
-0+err: +while (idx) +clk_hw_unregister (&priv->reg[--idx].hw); +return ret; +} + +static const struct of_device_id clk_starfive_jh7100_match[] = { + { .compatible ="starfive,jh7100-clkgen" }, + {/* sentinel */ } +};
Please add MODULE_DEVICE_TABLE()
Quoted 4 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +4
-0+ +static struct platform_driver clk_starfive_jh7100_driver = { + .probe = clk_starfive_jh7100_probe, + .driver = {
Emil Renner Berthing
maintainerRe: [PATCH v2 06/16] clk: starfive: Add JH7100 clock generator driver
Quoted 7 lines · Stephen Boyd
Quoting Emil Renner Berthing (2021-10-21 10:42:13)
drivers/clk/starfive/clk-starfive-jh7100.c line 143
Quoted 4 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +4
-0+struct jh7100_clk { +struct clk_hw hw; +unsigned int idx; +u32 max;Why u32?
The idea here was to mirror the configuration register when all valid fields are set to their maximum value, so that the clk_ops methods could check which features of this clock was enabled. But you're right none of the methods actually need that and only the dividers use this to know the maximum divider value, so it might as well be an unsigned int max_div.
Quoted 7 lines
drivers/clk/starfive/clk-starfive-jh7100.c line 148
Quoted 5 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +5
-0+}; + +struct clk_starfive_jh7100_priv { +/* protect registers against overlapping read-modify-write */ +spinlock_t rmw_lock;Does overlapping mean concurrent?
Yes, sorry.
Quoted 1 line
Do different clks share the same registers?
No, each clock has their own register, but they use that register both to gate the clock and other configuration. The Locking chapter of Documentation/driver-api/clk.rst talks about the prepare lock and the enable lock and then says:
"However, access to resources that are shared between operations of the two groups needs to be protected by the drivers. An example of such a resource would be a register that controls both the clock rate and the clock enable/disable state."
Quoted 12 lines
Quoted 12 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +12
-0+struct device *dev; +void __iomem *base; +struct clk_hw *pll[3 ]; +struct jh7100_clk reg[JH7100_CLK_PLL0_OUT ]; +}; + +static int jh7100_clk_is_enabled (struct clk_hw *hw) +{ +struct jh7100_clk *clk =jh7100_clk_from (hw); + +return !!(jh7100_clk_reg_get (clk) &JH7100_CLK_ENABLE ); +}
Quoted 8 lines
drivers/clk/starfive/clk-starfive-jh7100.c line 213
Quoted 4 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +4
-0+ +static int jh7100_clk_is_parent_enabled (struct clk_hw *hw) +{ +return clk_hw_is_enabled (clk_hw_get_parent (hw));Why do we need this function? The parent being enabled implies this clk is enabled if this clk can't gate itself but then knowing this clk is enabled is useful for what?
Probably only useful to me getting an overview of which clocks were actually enabled by grepping clk_summary. I'll delete it.
...
Quoted 10 lines
drivers/clk/starfive/clk-starfive-jh7100.c line 309
Quoted 7 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +7
-0+static int jh7100_clk_set_parent (struct clk_hw *hw,u8 index) +{ +struct jh7100_clk *clk =jh7100_clk_from (hw); +u32 value = (u32 )index <<JH7100_CLK_MUX_SHIFT ; + +dev_dbg (jh7100_priv_from (clk)->dev,"set_parent(%s, %u)\n" , +clk_hw_get_name (&clk->hw), index);Please remove these
dev_dbg()messages. We have tracepoints for general clk operations and the driver shouldn't duplicate that.
Gotcha.
Quoted 11 lines
drivers/clk/starfive/clk-starfive-jh7100.c line 429
Quoted 9 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +9
-0+ +static const struct clk_ops jh7100_clk_inv_ops = { + .is_enabled = jh7100_clk_is_parent_enabled, + .get_phase = jh7100_clk_get_phase, + .set_phase = jh7100_clk_set_phase, + .debug_init = jh7100_clk_debug_init, +}; + +#define JH7100_GATE (_idx, _name, _parent, _flags) [_idx] = { \Typical macro style is to tab out the \ to a single column
Ah, thanks. Will fix.
Quoted 120 lines
Quoted 120 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +120
-0+ .name = _name, \ + .ops = &jh7100_clk_gate_ops, \ + .parent = _parent, \ + .flags = CLK_SET_RATE_PARENT | (_flags), \ + .max = JH7100_CLK_ENABLE, \ +} + +#define JH7100__DIV (_idx, _name, _parent, _max) [_idx] = { \ + .name = _name, \ + .ops = &jh7100_clk_div_ops, \ + .parent = _parent, \ + .flags = 0, \ + .max = _max, \ +} + +#define JH7100_GDIV (_idx, _name, _parent, _max, _flags) [_idx] = { \ + .name = _name, \ + .ops = &jh7100_clk_gdiv_ops, \ + .parent = _parent, \ + .flags = (_flags), \ + .max = JH7100_CLK_ENABLE | (_max), \ +} + +#define JH7100__MUX (_idx, _name, _parents) [_idx] = { \ + .name = _name, \ + .ops = &jh7100_clk_mux_ops, \ + .parents = _parents, \ + .flags = 0, \ + .max = (ARRAY_SIZE(_parents) - 1) << JH7100_CLK_MUX_SHIFT, \ +} + +#define JH7100_GMUX (_idx, _name, _parents, _flags) [_idx] = { \ + .name = _name, \ + .ops = &jh7100_clk_gmux_ops, \ + .parents = _parents, \ + .flags = (_flags), \ + .max = JH7100_CLK_ENABLE | \ + ((ARRAY_SIZE(_parents) - 1) << JH7100_CLK_MUX_SHIFT), \ +} + +#define JH7100__INV (_idx, _name, _parent) [_idx] = { \ + .name = _name, \ + .ops = &jh7100_clk_inv_ops, \ + .parent = _parent, \ + .flags = CLK_SET_RATE_PARENT, \ + .max = JH7100_CLK_INVERT, \ +} + +static const struct { +const char *name; +const struct clk_ops *ops; +union { +const char *parent; +const char *const *parents; + }; +unsigned long flags; +u32 max; +} jh7100_clk_data[]__initconst = { +JH7100__MUX (JH7100_CLK_CPUNDBUS_ROOT ,"cpundbus_root" , cpundbus_root_sels), +JH7100__MUX (JH7100_CLK_DLA_ROOT ,"dla_root" , dla_root_sels), +JH7100__MUX (JH7100_CLK_DSP_ROOT ,"dsp_root" , dsp_root_sels), +JH7100__MUX (JH7100_CLK_GMACUSB_ROOT ,"gmacusb_root" , gmacusb_root_sels), +JH7100__MUX (JH7100_CLK_PERH0_ROOT ,"perh0_root" , perh0_root_sels), +JH7100__MUX (JH7100_CLK_PERH1_ROOT ,"perh1_root" , perh1_root_sels), +JH7100__MUX (JH7100_CLK_VIN_ROOT ,"vin_root" , vin_root_sels), +JH7100__MUX (JH7100_CLK_VOUT_ROOT ,"vout_root" , vout_root_sels), +JH7100_GDIV (JH7100_CLK_AUDIO_ROOT ,"audio_root" ,"pll0_out" ,8 ,0 ), +JH7100__MUX (JH7100_CLK_CDECHIFI4_ROOT ,"cdechifi4_root" , cdechifi4_root_sels), +JH7100__MUX (JH7100_CLK_CDEC_ROOT ,"cdec_root" , cdec_root_sels), +JH7100__MUX (JH7100_CLK_VOUTBUS_ROOT ,"voutbus_root" , voutbus_root_sels), +JH7100__DIV (JH7100_CLK_CPUNBUS_ROOT_DIV ,"cpunbus_root_div" ,"cpundbus_root" ,2 ), +JH7100__DIV (JH7100_CLK_DSP_ROOT_DIV ,"dsp_root_div" ,"dsp_root" ,4 ), +JH7100__DIV (JH7100_CLK_PERH0_SRC ,"perh0_src" ,"perh0_root" ,4 ), +JH7100__DIV (JH7100_CLK_PERH1_SRC ,"perh1_src" ,"perh1_root" ,4 ), +JH7100_GDIV (JH7100_CLK_PLL0_TESTOUT ,"pll0_testout" ,"perh0_src" ,31 ,0 ), +JH7100_GDIV (JH7100_CLK_PLL1_TESTOUT ,"pll1_testout" ,"dla_root" ,31 ,0 ), +JH7100_GDIV (JH7100_CLK_PLL2_TESTOUT ,"pll2_testout" ,"perh1_src" ,31 ,0 ), +JH7100__MUX (JH7100_CLK_PLL2_REF ,"pll2_refclk" , pll2_refclk_sels), +JH7100__DIV (JH7100_CLK_CPU_CORE ,"cpu_core" ,"cpunbus_root_div" ,8 ), +JH7100__DIV (JH7100_CLK_CPU_AXI ,"cpu_axi" ,"cpu_core" ,8 ), +JH7100__DIV (JH7100_CLK_AHB_BUS ,"ahb_bus" ,"cpunbus_root_div" ,8 ), +JH7100__DIV (JH7100_CLK_APB1_BUS ,"apb1_bus" ,"ahb_bus" ,8 ), +JH7100__DIV (JH7100_CLK_APB2_BUS ,"apb2_bus" ,"ahb_bus" ,8 ), +JH7100_GATE (JH7100_CLK_DOM3AHB_BUS ,"dom3ahb_bus" ,"ahb_bus" ,CLK_IGNORE_UNUSED ), +JH7100_GATE (JH7100_CLK_DOM7AHB_BUS ,"dom7ahb_bus" ,"ahb_bus" ,CLK_IGNORE_UNUSED ), +JH7100_GATE (JH7100_CLK_U74_CORE0 ,"u74_core0" ,"cpu_core" ,CLK_IGNORE_UNUSED ), +JH7100_GDIV (JH7100_CLK_U74_CORE1 ,"u74_core1" ,"cpu_core" ,8 ,CLK_IGNORE_UNUSED ), +JH7100_GATE (JH7100_CLK_U74_AXI ,"u74_axi" ,"cpu_axi" ,CLK_IGNORE_UNUSED ), +JH7100_GATE (JH7100_CLK_U74RTC_TOGGLE ,"u74rtc_toggle" ,"osc_sys" ,CLK_IGNORE_UNUSED ), +JH7100_GATE (JH7100_CLK_SGDMA2P_AXI ,"sgdma2p_axi" ,"cpu_axi" ,0 ), +JH7100_GATE (JH7100_CLK_DMA2PNOC_AXI ,"dma2pnoc_axi" ,"cpu_axi" ,0 ), +JH7100_GATE (JH7100_CLK_SGDMA2P_AHB ,"sgdma2p_ahb" ,"ahb_bus" ,0 ), +JH7100__DIV (JH7100_CLK_DLA_BUS ,"dla_bus" ,"dla_root" ,4 ), +JH7100_GATE (JH7100_CLK_DLA_AXI ,"dla_axi" ,"dla_bus" ,0 ), +JH7100_GATE (JH7100_CLK_DLANOC_AXI ,"dlanoc_axi" ,"dla_bus" ,0 ), +JH7100_GATE (JH7100_CLK_DLA_APB ,"dla_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_VP6_CORE ,"vp6_core" ,"dsp_root_div" ,4 ,0 ), +JH7100__DIV (JH7100_CLK_VP6BUS_SRC ,"vp6bus_src" ,"dsp_root" ,4 ), +JH7100_GDIV (JH7100_CLK_VP6_AXI ,"vp6_axi" ,"vp6bus_src" ,4 ,0 ), +JH7100__DIV (JH7100_CLK_VCDECBUS_SRC ,"vcdecbus_src" ,"cdechifi4_root" ,4 ), +JH7100__DIV (JH7100_CLK_VDEC_BUS ,"vdec_bus" ,"vcdecbus_src" ,8 ), +JH7100_GATE (JH7100_CLK_VDEC_AXI ,"vdec_axi" ,"vdec_bus" ,0 ), +JH7100_GATE (JH7100_CLK_VDECBRG_MAIN ,"vdecbrg_mainclk" ,"vdec_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_VDEC_BCLK ,"vdec_bclk" ,"vcdecbus_src" ,8 ,0 ), +JH7100_GDIV (JH7100_CLK_VDEC_CCLK ,"vdec_cclk" ,"cdec_root" ,8 ,0 ), +JH7100_GATE (JH7100_CLK_VDEC_APB ,"vdec_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_JPEG_AXI ,"jpeg_axi" ,"cpunbus_root_div" ,8 ,0 ), +JH7100_GDIV (JH7100_CLK_JPEG_CCLK ,"jpeg_cclk" ,"cpunbus_root_div" ,8 ,0 ), +JH7100_GATE (JH7100_CLK_JPEG_APB ,"jpeg_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_GC300_2X ,"gc300_2x" ,"cdechifi4_root" ,8 ,0 ), +JH7100_GATE (JH7100_CLK_GC300_AHB ,"gc300_ahb" ,"ahb_bus" ,0 ), +JH7100__DIV (JH7100_CLK_JPCGC300_AXIBUS ,"jpcgc300_axibus" ,"vcdecbus_src" ,8 ), +JH7100_GATE (JH7100_CLK_GC300_AXI ,"gc300_axi" ,"jpcgc300_axibus" ,0 ), +JH7100_GATE (JH7100_CLK_JPCGC300_MAIN ,"jpcgc300_mainclk" ,"jpcgc300_axibus" ,0 ), +JH7100__DIV (JH7100_CLK_VENC_BUS ,"venc_bus" ,"vcdecbus_src" ,8 ), +JH7100_GATE (JH7100_CLK_VENC_AXI ,"venc_axi" ,"venc_bus" ,0 ), +JH7100_GATE (JH7100_CLK_VENCBRG_MAIN ,"vencbrg_mainclk" ,"venc_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_VENC_BCLK ,"venc_bclk" ,"vcdecbus_src" ,8 ,0 ), +JH7100_GDIV (JH7100_CLK_VENC_CCLK ,"venc_cclk" ,"cdec_root" ,8 ,0 ), +JH7100_GATE (JH7100_CLK_VENC_APB ,"venc_apb" ,"apb1_bus" ,0 ),
Quoted 8 lines
drivers/clk/starfive/clk-starfive-jh7100.c line 555
Quoted 6 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +6
-0+JH7100_GDIV (JH7100_CLK_DDRPLL_DIV2 ,"ddrpll_div2" ,"pll1_out" ,2 ,CLK_IGNORE_UNUSED ), +JH7100_GDIV (JH7100_CLK_DDRPLL_DIV4 ,"ddrpll_div4" ,"ddrpll_div2" ,2 ,CLK_IGNORE_UNUSED ), +JH7100_GDIV (JH7100_CLK_DDRPLL_DIV8 ,"ddrpll_div8" ,"ddrpll_div4" ,2 ,CLK_IGNORE_UNUSED ), +JH7100_GDIV (JH7100_CLK_DDROSC_DIV2 ,"ddrosc_div2" ,"osc_sys" ,2 ,CLK_IGNORE_UNUSED ), +JH7100_GMUX (JH7100_CLK_DDRC0 ,"ddrc0" , ddrc0_sels,CLK_IGNORE_UNUSED ), + JH7100_GMUX(JH7100_CLK_DDRC1, "ddrc1", ddrc1_sels, CLK_IGNORE_UNUSED),Is it really unused? Or it is
CLK_IS_CRITICAL?
Ah no. CLK_IS_CRITICAL is exactly what they are, thanks.
Quoted 124 lines
Quoted 124 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +124
-0+JH7100_GATE (JH7100_CLK_DDRPHY_APB ,"ddrphy_apb" ,"apb1_bus" ,CLK_IGNORE_UNUSED ), +JH7100__DIV (JH7100_CLK_NOC_ROB ,"noc_rob" ,"cpunbus_root_div" ,8 ), +JH7100__DIV (JH7100_CLK_NOC_COG ,"noc_cog" ,"dla_root" ,8 ), +JH7100_GATE (JH7100_CLK_NNE_AHB ,"nne_ahb" ,"ahb_bus" ,0 ), +JH7100__DIV (JH7100_CLK_NNEBUS_SRC1 ,"nnebus_src1" ,"dsp_root" ,4 ), +JH7100__MUX (JH7100_CLK_NNE_BUS ,"nne_bus" , nne_bus_sels), +JH7100_GATE (JH7100_CLK_NNE_AXI ,"nne_axi" ,"nne_bus" ,0 ), +JH7100_GATE (JH7100_CLK_NNENOC_AXI ,"nnenoc_axi" ,"nne_bus" ,0 ), +JH7100_GATE (JH7100_CLK_DLASLV_AXI ,"dlaslv_axi" ,"nne_bus" ,0 ), +JH7100_GATE (JH7100_CLK_DSPX2C_AXI ,"dspx2c_axi" ,"nne_bus" ,CLK_IGNORE_UNUSED ), +JH7100__DIV (JH7100_CLK_HIFI4_SRC ,"hifi4_src" ,"cdechifi4_root" ,4 ), +JH7100__DIV (JH7100_CLK_HIFI4_COREFREE ,"hifi4_corefree" ,"hifi4_src" ,8 ), +JH7100_GATE (JH7100_CLK_HIFI4_CORE ,"hifi4_core" ,"hifi4_corefree" ,0 ), +JH7100__DIV (JH7100_CLK_HIFI4_BUS ,"hifi4_bus" ,"hifi4_corefree" ,8 ), +JH7100_GATE (JH7100_CLK_HIFI4_AXI ,"hifi4_axi" ,"hifi4_bus" ,0 ), +JH7100_GATE (JH7100_CLK_HIFI4NOC_AXI ,"hifi4noc_axi" ,"hifi4_bus" ,0 ), +JH7100__DIV (JH7100_CLK_SGDMA1P_BUS ,"sgdma1p_bus" ,"cpunbus_root_div" ,8 ), +JH7100_GATE (JH7100_CLK_SGDMA1P_AXI ,"sgdma1p_axi" ,"sgdma1p_bus" ,0 ), +JH7100_GATE (JH7100_CLK_DMA1P_AXI ,"dma1p_axi" ,"sgdma1p_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_X2C_AXI ,"x2c_axi" ,"cpunbus_root_div" ,8 ,CLK_IGNORE_UNUSED ), +JH7100__DIV (JH7100_CLK_USB_BUS ,"usb_bus" ,"cpunbus_root_div" ,8 ), +JH7100_GATE (JH7100_CLK_USB_AXI ,"usb_axi" ,"usb_bus" ,0 ), +JH7100_GATE (JH7100_CLK_USBNOC_AXI ,"usbnoc_axi" ,"usb_bus" ,0 ), +JH7100__DIV (JH7100_CLK_USBPHY_ROOTDIV ,"usbphy_rootdiv" ,"gmacusb_root" ,4 ), +JH7100_GDIV (JH7100_CLK_USBPHY_125M ,"usbphy_125m" ,"usbphy_rootdiv" ,8 ,0 ), +JH7100_GDIV (JH7100_CLK_USBPHY_PLLDIV25M ,"usbphy_plldiv25m" ,"usbphy_rootdiv" ,32 ,0 ), +JH7100__MUX (JH7100_CLK_USBPHY_25M ,"usbphy_25m" , usbphy_25m_sels), +JH7100__DIV (JH7100_CLK_AUDIO_DIV ,"audio_div" ,"audio_root" ,131072 ), +JH7100_GATE (JH7100_CLK_AUDIO_SRC ,"audio_src" ,"audio_div" ,0 ), +JH7100_GATE (JH7100_CLK_AUDIO_12288 ,"audio_12288" ,"osc_aud" ,0 ), +JH7100_GDIV (JH7100_CLK_VIN_SRC ,"vin_src" ,"vin_root" ,4 ,0 ), +JH7100__DIV (JH7100_CLK_ISP0_BUS ,"isp0_bus" ,"vin_src" ,8 ), +JH7100_GATE (JH7100_CLK_ISP0_AXI ,"isp0_axi" ,"isp0_bus" ,0 ), +JH7100_GATE (JH7100_CLK_ISP0NOC_AXI ,"isp0noc_axi" ,"isp0_bus" ,0 ), +JH7100_GATE (JH7100_CLK_ISPSLV_AXI ,"ispslv_axi" ,"isp0_bus" ,0 ), +JH7100__DIV (JH7100_CLK_ISP1_BUS ,"isp1_bus" ,"vin_src" ,8 ), +JH7100_GATE (JH7100_CLK_ISP1_AXI ,"isp1_axi" ,"isp1_bus" ,0 ), +JH7100_GATE (JH7100_CLK_ISP1NOC_AXI ,"isp1noc_axi" ,"isp1_bus" ,0 ), +JH7100__DIV (JH7100_CLK_VIN_BUS ,"vin_bus" ,"vin_src" ,8 ), +JH7100_GATE (JH7100_CLK_VIN_AXI ,"vin_axi" ,"vin_bus" ,0 ), +JH7100_GATE (JH7100_CLK_VINNOC_AXI ,"vinnoc_axi" ,"vin_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_VOUT_SRC ,"vout_src" ,"vout_root" ,4 ,0 ), +JH7100__DIV (JH7100_CLK_DISPBUS_SRC ,"dispbus_src" ,"voutbus_root" ,4 ), +JH7100__DIV (JH7100_CLK_DISP_BUS ,"disp_bus" ,"dispbus_src" ,4 ), +JH7100_GATE (JH7100_CLK_DISP_AXI ,"disp_axi" ,"disp_bus" ,0 ), +JH7100_GATE (JH7100_CLK_DISPNOC_AXI ,"dispnoc_axi" ,"disp_bus" ,0 ), +JH7100_GATE (JH7100_CLK_SDIO0_AHB ,"sdio0_ahb" ,"ahb_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_SDIO0_CCLKINT ,"sdio0_cclkint" ,"perh0_src" ,24 ,0 ), +JH7100__INV (JH7100_CLK_SDIO0_CCLKINT_INV ,"sdio0_cclkint_inv" ,"sdio0_cclkint" ), +JH7100_GATE (JH7100_CLK_SDIO1_AHB ,"sdio1_ahb" ,"ahb_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_SDIO1_CCLKINT ,"sdio1_cclkint" ,"perh1_src" ,24 ,0 ), +JH7100__INV (JH7100_CLK_SDIO1_CCLKINT_INV ,"sdio1_cclkint_inv" ,"sdio1_cclkint" ), +JH7100_GATE (JH7100_CLK_GMAC_AHB ,"gmac_ahb" ,"ahb_bus" ,0 ), +JH7100__DIV (JH7100_CLK_GMAC_ROOT_DIV ,"gmac_root_div" ,"gmacusb_root" ,8 ), +JH7100_GDIV (JH7100_CLK_GMAC_PTP_REF ,"gmac_ptp_refclk" ,"gmac_root_div" ,31 ,0 ), +JH7100_GDIV (JH7100_CLK_GMAC_GTX ,"gmac_gtxclk" ,"gmac_root_div" ,255 ,0 ), +JH7100_GDIV (JH7100_CLK_GMAC_RMII_TX ,"gmac_rmii_txclk" ,"gmac_rmii_ref" ,8 ,0 ), +JH7100_GDIV (JH7100_CLK_GMAC_RMII_RX ,"gmac_rmii_rxclk" ,"gmac_rmii_ref" ,8 ,0 ), +JH7100__MUX (JH7100_CLK_GMAC_TX ,"gmac_tx" , gmac_tx_sels), +JH7100__INV (JH7100_CLK_GMAC_TX_INV ,"gmac_tx_inv" ,"gmac_tx" ), +JH7100__MUX (JH7100_CLK_GMAC_RX_PRE ,"gmac_rx_pre" , gmac_rx_pre_sels), +JH7100__INV (JH7100_CLK_GMAC_RX_INV ,"gmac_rx_inv" ,"gmac_rx_pre" ), +JH7100_GATE (JH7100_CLK_GMAC_RMII ,"gmac_rmii" ,"gmac_rmii_ref" ,0 ), +JH7100_GDIV (JH7100_CLK_GMAC_TOPHYREF ,"gmac_tophyref" ,"gmac_root_div" ,127 ,0 ), +JH7100_GATE (JH7100_CLK_SPI2AHB_AHB ,"spi2ahb_ahb" ,"ahb_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_SPI2AHB_CORE ,"spi2ahb_core" ,"perh0_src" ,31 ,0 ), +JH7100_GATE (JH7100_CLK_EZMASTER_AHB ,"ezmaster_ahb" ,"ahb_bus" ,0 ), +JH7100_GATE (JH7100_CLK_E24_AHB ,"e24_ahb" ,"ahb_bus" ,0 ), +JH7100_GATE (JH7100_CLK_E24RTC_TOGGLE ,"e24rtc_toggle" ,"osc_sys" ,0 ), +JH7100_GATE (JH7100_CLK_QSPI_AHB ,"qspi_ahb" ,"ahb_bus" ,0 ), +JH7100_GATE (JH7100_CLK_QSPI_APB ,"qspi_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_QSPI_REF ,"qspi_refclk" ,"perh0_src" ,31 ,0 ), +JH7100_GATE (JH7100_CLK_SEC_AHB ,"sec_ahb" ,"ahb_bus" ,0 ), +JH7100_GATE (JH7100_CLK_AES ,"aes_clk" ,"sec_ahb" ,0 ), +JH7100_GATE (JH7100_CLK_SHA ,"sha_clk" ,"sec_ahb" ,0 ), +JH7100_GATE (JH7100_CLK_PKA ,"pka_clk" ,"sec_ahb" ,0 ), +JH7100_GATE (JH7100_CLK_TRNG_APB ,"trng_apb" ,"apb1_bus" ,0 ), +JH7100_GATE (JH7100_CLK_OTP_APB ,"otp_apb" ,"apb1_bus" ,0 ), +JH7100_GATE (JH7100_CLK_UART0_APB ,"uart0_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_UART0_CORE ,"uart0_core" ,"perh1_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_UART1_APB ,"uart1_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_UART1_CORE ,"uart1_core" ,"perh1_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_SPI0_APB ,"spi0_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_SPI0_CORE ,"spi0_core" ,"perh1_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_SPI1_APB ,"spi1_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_SPI1_CORE ,"spi1_core" ,"perh1_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_I2C0_APB ,"i2c0_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_I2C0_CORE ,"i2c0_core" ,"perh1_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_I2C1_APB ,"i2c1_apb" ,"apb1_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_I2C1_CORE ,"i2c1_core" ,"perh1_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_GPIO_APB ,"gpio_apb" ,"apb1_bus" ,0 ), +JH7100_GATE (JH7100_CLK_UART2_APB ,"uart2_apb" ,"apb2_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_UART2_CORE ,"uart2_core" ,"perh0_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_UART3_APB ,"uart3_apb" ,"apb2_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_UART3_CORE ,"uart3_core" ,"perh0_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_SPI2_APB ,"spi2_apb" ,"apb2_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_SPI2_CORE ,"spi2_core" ,"perh0_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_SPI3_APB ,"spi3_apb" ,"apb2_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_SPI3_CORE ,"spi3_core" ,"perh0_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_I2C2_APB ,"i2c2_apb" ,"apb2_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_I2C2_CORE ,"i2c2_core" ,"perh0_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_I2C3_APB ,"i2c3_apb" ,"apb2_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_I2C3_CORE ,"i2c3_core" ,"perh0_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_WDTIMER_APB ,"wdtimer_apb" ,"apb2_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_WDT_CORE ,"wdt_coreclk" ,"perh0_src" ,63 ,0 ), +JH7100_GDIV (JH7100_CLK_TIMER0_CORE ,"timer0_coreclk" ,"perh0_src" ,63 ,0 ), +JH7100_GDIV (JH7100_CLK_TIMER1_CORE ,"timer1_coreclk" ,"perh0_src" ,63 ,0 ), +JH7100_GDIV (JH7100_CLK_TIMER2_CORE ,"timer2_coreclk" ,"perh0_src" ,63 ,0 ), +JH7100_GDIV (JH7100_CLK_TIMER3_CORE ,"timer3_coreclk" ,"perh0_src" ,63 ,0 ), +JH7100_GDIV (JH7100_CLK_TIMER4_CORE ,"timer4_coreclk" ,"perh0_src" ,63 ,0 ), +JH7100_GDIV (JH7100_CLK_TIMER5_CORE ,"timer5_coreclk" ,"perh0_src" ,63 ,0 ), +JH7100_GDIV (JH7100_CLK_TIMER6_CORE ,"timer6_coreclk" ,"perh0_src" ,63 ,0 ), +JH7100_GATE (JH7100_CLK_VP6INTC_APB ,"vp6intc_apb" ,"apb2_bus" ,0 ), +JH7100_GATE (JH7100_CLK_PWM_APB ,"pwm_apb" ,"apb2_bus" ,0 ), +JH7100_GATE (JH7100_CLK_MSI_APB ,"msi_apb" ,"apb2_bus" ,0 ), +JH7100_GATE (JH7100_CLK_TEMP_APB ,"temp_apb" ,"apb2_bus" ,0 ), +JH7100_GDIV (JH7100_CLK_TEMP_SENSE ,"temp_sense" ,"osc_sys" ,31 ,0 ), + JH7100_GATE(JH7100_CLK_SYSERR_APB, "syserr_apb", "apb2_bus", 0), +}; + +static struct clk_hw *clk_starfive_jh7100_get (struct of_phandle_args *clkspec,void *data) +{ +struct clk_starfive_jh7100_priv *priv = data; +unsigned int idx = clkspec->args[0 ];
Quoted 8 lines
drivers/clk/starfive/clk-starfive-jh7100.c line 682
Quoted 3 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +3
-0+ +if (idx >=JH7100_CLK_END ) { +dev_err (priv->dev,"invalid clock index %u\n" , idx);We should pull this sort of error message up into the core instead of have it in every driver. It also doesn't look very meaningful to print the name of the device that's providing the clks vs. the name of the device that's requesting the clk that can't be found.
Makes sense. I'll just remove the message then.
Quoted 4 lines
Quoted 4 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +4
-0+return ERR_PTR (-EINVAL ); + } + +if (idx >=JH7100_CLK_PLL0_OUT )
Quoted 8 lines
drivers/clk/starfive/clk-starfive-jh7100.c line 692
Quoted 6 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +6
-0+return priv->pll[idx -JH7100_CLK_PLL0_OUT ]; + +return &priv->reg[idx].hw; +} + +static int __init clk_starfive_jh7100_probe (struct platform_device *pdev)Drop
__initas this can be called after kernel init is over.
Oh interesting, I'd like to know when that can happen. The comment for the builtin_platform_driver macro says it's just a wrapper for device_initcall.
Won't we then need to remove all the __initconst tags too since the probe function walks through jh7100_clk_data which eventually references all __initconst data?
Quoted 41 lines
Quoted 41 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +41
-0+{ +struct clk_starfive_jh7100_priv *priv; +unsigned int idx; +int ret; + + priv =devm_kzalloc (&pdev->dev,sizeof (*priv),GFP_KERNEL ); +if (!priv) +return -ENOMEM ; + +spin_lock_init (&priv->rmw_lock); + priv->dev = &pdev->dev; + priv->base =devm_platform_ioremap_resource (pdev,0 ); +if (IS_ERR (priv->base)) +return PTR_ERR (priv->base); + + priv->pll[0 ] =devm_clk_hw_register_fixed_factor (priv->dev,"pll0_out" , +"osc_sys" ,0 ,40 ,1 ); +if (IS_ERR (priv->pll[0 ])) +return PTR_ERR (priv->pll[0 ]); + + priv->pll[1 ] =devm_clk_hw_register_fixed_factor (priv->dev,"pll1_out" , +"osc_sys" ,0 ,64 ,1 ); +if (IS_ERR (priv->pll[1 ])) +return PTR_ERR (priv->pll[1 ]); + + priv->pll[2 ] =devm_clk_hw_register_fixed_factor (priv->dev,"pll2_out" , +"pll2_refclk" ,0 ,55 ,1 ); +if (IS_ERR (priv->pll[2 ])) +return PTR_ERR (priv->pll[2 ]); + +for (idx =0 ; idx <JH7100_CLK_PLL0_OUT ; idx++) { +u32 max_parent = (jh7100_clk_data[idx].max &JH7100_CLK_MUX_MASK ) >> +JH7100_CLK_MUX_SHIFT ; +struct clk_init_data init = { + .name = jh7100_clk_data[idx].name, + .ops = jh7100_clk_data[idx].ops, + .num_parents = max_parent +1 , + .flags = jh7100_clk_data[idx].flags, + }; +struct jh7100_clk *clk = &priv->reg[idx]; +
Quoted 8 lines
drivers/clk/starfive/clk-starfive-jh7100.c line 737
Quoted 4 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +4
-0+if (init.num_parents >1 ) + init.parent_names = jh7100_clk_data[idx].parents; +else + init.parent_names = &jh7100_clk_data[idx].parent;Can you use
clk_parent_datainstead ofparent_names? To make the object size even smaller you can use the DT index instead of the .fw_name field.
Ah cool. I'll look into that.
Quoted 8 lines
drivers/clk/starfive/clk-starfive-jh7100.c line 743
Quoted 6 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +6
-0+ + clk->hw.init = &init; + clk->idx = idx; + clk->max = jh7100_clk_data[idx].max; + + ret =clk_hw_register (priv->dev, &clk->hw);Why not use
devm_clk_hw_register()?
I probably could. Just for my understanding that's just to avoid the loop on error below, because as a builtin driver the device won't otherwise go away, right?
Quoted 13 lines
Quoted 13 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +13
-0+if (ret) + goto err; + } + + ret =devm_of_clk_add_hw_provider (priv->dev, clk_starfive_jh7100_get, priv); +if (ret) + goto err; + +return 0 ; +err: +while (idx) +clk_hw_unregister (&priv->reg[--idx].hw); +return ret;
Quoted 8 lines
drivers/clk/starfive/clk-starfive-jh7100.c line 762
Quoted 6 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +6
-0+} + +static const struct of_device_id clk_starfive_jh7100_match[] = { + { .compatible ="starfive,jh7100-clkgen" }, + {/* sentinel */ } +};Please add
MODULE_DEVICE_TABLE()
Will do!
Thank you.
/Emil
_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv
Stephen Boyd
maintainerRe: [PATCH v2 06/16] clk: starfive: Add JH7100 clock generator driver
Quoting Emil Renner Berthing (2021-10-26 15:35:36)
Quoted 14 lines · Stephen Boyd
Quoted 8 lines
Quoting Emil Renner Berthing (2021-10-21 10:42:13)
drivers/clk/starfive/clk-starfive-jh7100.c line 148
Quoted 5 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +5
-0+}; + +struct clk_starfive_jh7100_priv { +/* protect registers against overlapping read-modify-write */ +spinlock_t rmw_lock;Does overlapping mean concurrent?
Yes, sorry.
Quoted 1 line
Do different clks share the same registers?
Quoted 8 lines
No, each clock has their own register, but they use that register both to gate the clock and other configuration. The Locking chapter of
Documentation/driver-api/clk.rsttalks about the prepare lock and the enable lock and then says:
"However, access to resources that are shared between operations of the two groups needs to be protected by the drivers. An example of such a resource would be a register that controls both the clock rate and the clock enable/disable state."
Alright got it. Maybe say "protect clk enable and set rate from happening at the same time".
Quoted 14 lines
Quoted 13 lines
drivers/clk/starfive/clk-starfive-jh7100.c line 692
Quoted 11 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +10
-0+return ERR_PTR (-EINVAL ); + } + +if (idx >=JH7100_CLK_PLL0_OUT ) +return priv->pll[idx -JH7100_CLK_PLL0_OUT ]; + +return &priv->reg[idx].hw; +} + +static int __init clk_starfive_jh7100_probe (struct platform_device *pdev)Drop
__initas this can be called after kernel init is over.
Quoted 2 lines
Oh interesting, I'd like to know when that can happen. The comment for the
builtin_platform_drivermacro says it's just a wrapper for
I thought this was using module_platform_driver() macro?
Quoted 5 lines
device_initcall.Won't we then need to remove all the
__initconsttags too since the probe function walks throughjh7100_clk_datawhich eventually references all__initconstdata?
Yes. If it's builtin_platform_driver() it can't be a module/tristate Kconfig, in which case all the init markings can stay.
Quoted 10 lines
Quoted 9 lines
drivers/clk/starfive/clk-starfive-jh7100.c line 743
Quoted 7 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +6
-0+ + clk->hw.init = &init; + clk->idx = idx; + clk->max = jh7100_clk_data[idx].max; + + ret =clk_hw_register (priv->dev, &clk->hw);Why not use
devm_clk_hw_register()?
Quoted 3 lines
I probably could. Just for my understanding that's just to avoid the loop on error below, because as a builtin driver the device won't otherwise go away, right?
Yes
Quoted 23 lines
Quoted 14 lines
Quoted 14 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +13
-0+if (ret) + goto err; + } + + ret =devm_of_clk_add_hw_provider (priv->dev, clk_starfive_jh7100_get, priv); +if (ret) + goto err; + +return 0 ; +err: +while (idx) +clk_hw_unregister (&priv->reg[--idx].hw); +return ret;Quoted 8 lines
drivers/clk/starfive/clk-starfive-jh7100.c line 762
Quoted 6 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +6
-0+} + +static const struct of_device_id clk_starfive_jh7100_match[] = { + { .compatible ="starfive,jh7100-clkgen" }, + {/* sentinel */ } +};Please add
MODULE_DEVICE_TABLE()
Quoted 1 line
Will do!
If it's never going to be a module then don't add any module_* things.
Andy Shevchenko
reviewerRe: [PATCH v2 06/16] clk: starfive: Add JH7100 clock generator driver
Quoted 3 lines · Stephen Boyd
Quoting Emil Renner Berthing (2021-10-26 15:35:36)
Quoted 2 lines · Stephen Boyd
Quoted 1 line
Quoting Emil Renner Berthing (2021-10-21 10:42:13)
...
Quoted 9 lines
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
+static int
__initclk_starfive_jh7100_probe(struct platform_device *pdev)Drop
__initas this can be called after kernel init is over.Oh interesting, I'd like to know when that can happen. The comment for the
builtin_platform_drivermacro says it's just a wrapper forI thought this was using
module_platform_driver()macro?
Quoted 8 lines
Quoted 5 lines
device_initcall.Won't we then need to remove all the
__initconsttags too since the probe function walks throughjh7100_clk_datawhich eventually references all__initconstdata?Yes. If it's
builtin_platform_driver()it can't be a module/tristateKconfig, in which case all the init markings can stay.
What about bind/unbind attribute?
Signature · 2 lines
With Best Regards, Andy Shevchenko
Emil Renner Berthing
maintainerRe: [PATCH v2 06/16] clk: starfive: Add JH7100 clock generator driver
In reply to Stephen BoydQuoted 46 lines · Stephen Boyd
Quoting Emil Renner Berthing (2021-10-26 15:35:36)
Quoted 14 lines · Stephen Boyd
Quoted 8 lines
Quoting Emil Renner Berthing (2021-10-21 10:42:13)
drivers/clk/starfive/clk-starfive-jh7100.c line 148
Quoted 5 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +5
-0+}; + +struct clk_starfive_jh7100_priv { +/* protect registers against overlapping read-modify-write */ +spinlock_t rmw_lock;Does overlapping mean concurrent?
Yes, sorry.
Quoted 1 line
Do different clks share the same registers?
Quoted 8 lines
No, each clock has their own register, but they use that register both to gate the clock and other configuration. The Locking chapter of
Documentation/driver-api/clk.rsttalks about the prepare lock and the enable lock and then says:
"However, access to resources that are shared between operations of the two groups needs to be protected by the drivers. An example of such a resource would be a register that controls both the clock rate and the clock enable/disable state."Alright got it. Maybe say "protect clk enable and set rate from happening at the same time".
Quoted 14 lines
Quoted 13 lines
drivers/clk/starfive/clk-starfive-jh7100.c line 692
Quoted 11 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +10
-0+return ERR_PTR (-EINVAL ); + } + +if (idx >=JH7100_CLK_PLL0_OUT ) +return priv->pll[idx -JH7100_CLK_PLL0_OUT ]; + +return &priv->reg[idx].hw; +} + +static int __init clk_starfive_jh7100_probe (struct platform_device *pdev)Drop
__initas this can be called after kernel init is over.Quoted 2 lines
Oh interesting, I'd like to know when that can happen. The comment for the
builtin_platform_drivermacro says it's just a wrapper forI thought this was using
module_platform_driver()macro?
Quoted 8 lines
Quoted 5 lines
device_initcall.Won't we then need to remove all the
__initconsttags too since the probe function walks throughjh7100_clk_datawhich eventually references all__initconstdata?Yes. If it's
builtin_platform_driver()it can't be a module/tristateKconfig, in which case all the init markings can stay.
Yes, it's already bool in the Kconfig file. After looking into this I think it's better to do like the rockchip drivers and use builtin_platform_driver_probe to make sure the probe function only called at kernel init time:
static struct platform_driver clk_starfive_jh7100_driver = {
.driver = {
.name = "clk-starfive-jh7100",
.of_match_table = clk_starfive_jh7100_match,
.suppress_bind_attrs = true,
},
};builtin_platform_driver_probe(clk_starfive_jh7100_driver, clk_starfive_jh7100_probe);
@Andy: is the supress_bind_attrs what you were asking about?
Quoted 38 lines
Quoted 9 lines
Quoted 8 lines
drivers/clk/starfive/clk-starfive-jh7100.c line 743
Quoted 6 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +6
-0+ + clk->hw.init = &init; + clk->idx = idx; + clk->max = jh7100_clk_data[idx].max; + + ret =clk_hw_register (priv->dev, &clk->hw);Why not use
devm_clk_hw_register()?Quoted 3 lines
I probably could. Just for my understanding that's just to avoid the loop on error below, because as a builtin driver the device won't otherwise go away, right?
Yes
Quoted 23 lines
Quoted 22 lines
Quoted 10 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +9
-0+if (ret) + goto err; + } + + ret =devm_of_clk_add_hw_provider (priv->dev, clk_starfive_jh7100_get, priv); +if (ret) + goto err; + +return 0 ;drivers/clk/starfive/clk-starfive-jh7100.c line 762
Quoted 10 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +10
-0+err: +while (idx) +clk_hw_unregister (&priv->reg[--idx].hw); +return ret; +} + +static const struct of_device_id clk_starfive_jh7100_match[] = { + { .compatible ="starfive,jh7100-clkgen" }, + {/* sentinel */ } +};Please add
MODULE_DEVICE_TABLE()
Quoted 3 lines
Quoted 1 line
Will do!
If it's never going to be a module then don't add any module_* things.
So does that just mean no MODULE_DEVICE_TABLE or should I also remove MODULE_DESCRIPTION, MODULE_AUTHOR and MODULE_LICENSE? I'm just double checking because the rockchip drivers seem to have MODULE_DESCRIPTION and MODULE_LICENSE lines.
Andy Shevchenko
reviewerRe: [PATCH v2 06/16] clk: starfive: Add JH7100 clock generator driver
Quoted 4 lines · Emil Renner Berthing
Quoted 3 lines · Stephen Boyd
Quoting Emil Renner Berthing (2021-10-26 15:35:36)
Quoted 2 lines · Stephen Boyd
Quoted 1 line
Quoting Emil Renner Berthing (2021-10-21 10:42:13)
...
Quoted 30 lines
Quoted 9 lines
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
+static int
__initclk_starfive_jh7100_probe(struct platform_device *pdev)Drop
__initas this can be called after kernel init is over.Oh interesting, I'd like to know when that can happen. The comment for the
builtin_platform_drivermacro says it's just a wrapper forI thought this was using
module_platform_driver()macro?Quoted 8 lines
Quoted 5 lines
device_initcall.Won't we then need to remove all the
__initconsttags too since the probe function walks throughjh7100_clk_datawhich eventually references all__initconstdata?Yes. If it's
builtin_platform_driver()it can't be a module/tristateKconfig, in which case all the init markings can stay.Yes, it's already bool in the
Kconfigfile. After looking into this I think it's better to do like the rockchip drivers and usebuiltin_platform_driver_probeto make sure the probe function only called at kernel init time:static struct platform_driver clk_starfive_jh7100_driver = { .driver = { .name = "clk-starfive-jh7100", .of_match_table = clk_starfive_jh7100_match, .suppress_bind_attrs = true, }, };
Quoted 4 lines
builtin_platform_driver_probe(clk_starfive_jh7100_driver, clk_starfive_jh7100_probe);@Andy: is the
supress_bind_attrswhat you were asking about?
Clever chap! :-)
Yes, that's what I have in mind.
...
Quoted 6 lines
Quoted 1 line
If it's never going to be a module then don't add any module_* things.
So does that just mean no
MODULE_DEVICE_TABLEor should I also removeMODULE_DESCRIPTION,MODULE_AUTHORandMODULE_LICENSE? I'm just double checking because the rockchip drivers seem to haveMODULE_DESCRIPTIONandMODULE_LICENSElines.
You may comment them out. Convert them to comments or so. But in general yes, they are no-ops in such case.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Re: [PATCH v2 06/16] clk: starfive: Add JH7100 clock generator driver
In reply to Emil Renner BerthingAm Mittwoch, 27. Oktober 2021, 12:24:07 CEST schrieb Emil Renner Berthing:
Quoted 111 lines · Stephen Boyd
Quoted 46 lines
Quoting Emil Renner Berthing (2021-10-26 15:35:36)
Quoted 14 lines · Stephen Boyd
Quoted 8 lines
Quoting Emil Renner Berthing (2021-10-21 10:42:13)
drivers/clk/starfive/clk-starfive-jh7100.c line 148
Quoted 5 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +5
-0+}; + +struct clk_starfive_jh7100_priv { +/* protect registers against overlapping read-modify-write */ +spinlock_t rmw_lock;Does overlapping mean concurrent?
Yes, sorry.
Quoted 1 line
Do different clks share the same registers?
Quoted 8 lines
No, each clock has their own register, but they use that register both to gate the clock and other configuration. The Locking chapter of
Documentation/driver-api/clk.rsttalks about the prepare lock and the enable lock and then says:
"However, access to resources that are shared between operations of the two groups needs to be protected by the drivers. An example of such a resource would be a register that controls both the clock rate and the clock enable/disable state."Alright got it. Maybe say "protect clk enable and set rate from happening at the same time".
Quoted 14 lines
Quoted 13 lines
drivers/clk/starfive/clk-starfive-jh7100.c line 692
Quoted 11 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +10
-0+return ERR_PTR (-EINVAL ); + } + +if (idx >=JH7100_CLK_PLL0_OUT ) +return priv->pll[idx -JH7100_CLK_PLL0_OUT ]; + +return &priv->reg[idx].hw; +} + +static int __init clk_starfive_jh7100_probe (struct platform_device *pdev)Drop
__initas this can be called after kernel init is over.Quoted 2 lines
Oh interesting, I'd like to know when that can happen. The comment for the
builtin_platform_drivermacro says it's just a wrapper forI thought this was using
module_platform_driver()macro?Quoted 8 lines
Quoted 5 lines
device_initcall.Won't we then need to remove all the
__initconsttags too since the probe function walks throughjh7100_clk_datawhich eventually references all__initconstdata?Yes. If it's
builtin_platform_driver()it can't be a module/tristateKconfig, in which case all the init markings can stay.Yes, it's already bool in the
Kconfigfile. After looking into this I think it's better to do like the rockchip drivers and usebuiltin_platform_driver_probeto make sure the probe function only called at kernel init time:static struct platform_driver clk_starfive_jh7100_driver = { .driver = { .name = "clk-starfive-jh7100", .of_match_table = clk_starfive_jh7100_match, .suppress_bind_attrs = true, }, };
builtin_platform_driver_probe(clk_starfive_jh7100_driver, clk_starfive_jh7100_probe);@Andy: is the
supress_bind_attrswhat you were asking about?Quoted 38 lines
Quoted 9 lines
Quoted 8 lines
drivers/clk/starfive/clk-starfive-jh7100.c line 743
Quoted 6 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +6
-0+ + clk->hw.init = &init; + clk->idx = idx; + clk->max = jh7100_clk_data[idx].max; + + ret =clk_hw_register (priv->dev, &clk->hw);Why not use
devm_clk_hw_register()?Quoted 3 lines
I probably could. Just for my understanding that's just to avoid the loop on error below, because as a builtin driver the device won't otherwise go away, right?
Yes
Quoted 23 lines
Quoted 22 lines
Quoted 10 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +9
-0+if (ret) + goto err; + } + + ret =devm_of_clk_add_hw_provider (priv->dev, clk_starfive_jh7100_get, priv); +if (ret) + goto err; + +return 0 ;drivers/clk/starfive/clk-starfive-jh7100.c line 762
Quoted 10 lines
drivers/clk/starfive/clk-starfive-jh7100.c new file +10
-0+err: +while (idx) +clk_hw_unregister (&priv->reg[--idx].hw); +return ret; +} + +static const struct of_device_id clk_starfive_jh7100_match[] = { + { .compatible ="starfive,jh7100-clkgen" }, + {/* sentinel */ } +};Please add
MODULE_DEVICE_TABLE()
Quoted 8 lines
Quoted 3 lines
Quoted 1 line
Will do!
If it's never going to be a module then don't add any module_* things.
So does that just mean no
MODULE_DEVICE_TABLEor should I also removeMODULE_DESCRIPTION,MODULE_AUTHORandMODULE_LICENSE? I'm just double checking because the rockchip drivers seem to haveMODULE_DESCRIPTIONandMODULE_LICENSElines.
reading this I realized that the current implementation on the Rockchip side is faulty :-) .
For one, there recently was a change for 5.16 that moved this to use module_platform_driver, while keeping the initdata, which suggest that the change was actually not tested at all in that context.
And secondly the kconfig is wrong to actually use tristate and should instead use bool.
Of course this is also influenced by the recent GKI discussion [0] ;-)
I'm going to revert the one change and also adapt the kconfig to use bool again.
Heiko
[0] https://lwn.net/Articles/872209/
_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv
Emil Renner Berthing
maintainerPATCH v2 7/16 dt-bindings: reset: Add StarFive JH7100 reset definitions
In reply to Emil Renner BerthingFrom: Geert Uytterhoeven <[email protected]>
Add all resets for the StarFive JH7100 reset controller.
Based on work by Ahmad Fatoum for Barebox, with "JH7100_" prefixes added to all definitions.
--- include/dt-bindings/reset/starfive-jh7100.h | 126 ++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 include/dt-bindings/reset/starfive-jh7100.h
include/dt-bindings/reset/starfive-jh7100.h new file +126 -0
@@ -0,0 +1,126 @@ +/* SPDX-License-Identifier: GPL-2.0 OR X11 */ +/* +* Copyright (c) 2021 Ahmad Fatoum, Pengutronix +*/ + +#ifndef __DT_BINDINGS_RESET_STARFIVE_JH7100_H__ +#define __DT_BINDINGS_RESET_STARFIVE_JH7100_H__ + +#define JH7100_RSTN_DOM3AHB_BUS 0 +#define JH7100_RSTN_DOM7AHB_BUS 1 +#define JH7100_RST_U74 2 +#define JH7100_RSTN_U74_AXI 3 +#define JH7100_RSTN_SGDMA2P_AHB 4 +#define JH7100_RSTN_SGDMA2P_AXI 5 +#define JH7100_RSTN_DMA2PNOC_AXI 6 +#define JH7100_RSTN_DLA_AXI 7 +#define JH7100_RSTN_DLANOC_AXI 8 +#define JH7100_RSTN_DLA_APB 9 +#define JH7100_RST_VP6_DRESET 10 +#define JH7100_RST_VP6_BRESET 11 +#define JH7100_RSTN_VP6_AXI 12 +#define JH7100_RSTN_VDECBRG_MAIN 13 +#define JH7100_RSTN_VDEC_AXI 14 +#define JH7100_RSTN_VDEC_BCLK 15 +#define JH7100_RSTN_VDEC_CCLK 16 +#define JH7100_RSTN_VDEC_APB 17 +#define JH7100_RSTN_JPEG_AXI 18 +#define JH7100_RSTN_JPEG_CCLK 19 +#define JH7100_RSTN_JPEG_APB 20 +#define JH7100_RSTN_JPCGC300_MAIN 21 +#define JH7100_RSTN_GC300_2X 22 +#define JH7100_RSTN_GC300_AXI 23 +#define JH7100_RSTN_GC300_AHB 24 +#define JH7100_RSTN_VENC_AXI 25 +#define JH7100_RSTN_VENCBRG_MAIN 26 +#define JH7100_RSTN_VENC_BCLK 27 +#define JH7100_RSTN_VENC_CCLK 28 +#define JH7100_RSTN_VENC_APB 29 +#define JH7100_RSTN_DDRPHY_APB 30 +#define JH7100_RSTN_NOC_ROB 31 +#define JH7100_RSTN_NOC_COG 32 +#define JH7100_RSTN_HIFI4_AXI 33 +#define JH7100_RSTN_HIFI4NOC_AXI 34 +#define JH7100_RST_HIFI4_DRESET 35 +#define JH7100_RST_HIFI4_BRESET 36 +#define JH7100_RSTN_USB_AXI 37 +#define JH7100_RSTN_USBNOC_AXI 38 +#define JH7100_RSTN_SGDMA1P_AXI 39 +#define JH7100_RSTN_DMA1P_AXI 40 +#define JH7100_RSTN_X2C_AXI 41 +#define JH7100_RSTN_NNE_AHB 42 +#define JH7100_RSTN_NNE_AXI 43 +#define JH7100_RSTN_NNENOC_AXI 44 +#define JH7100_RSTN_DLASLV_AXI 45 +#define JH7100_RSTN_DSPX2C_AXI 46 +#define JH7100_RSTN_VIN_SRC 47 +#define JH7100_RSTN_ISPSLV_AXI 48 +#define JH7100_RSTN_VIN_AXI 49 +#define JH7100_RSTN_VINNOC_AXI 50 +#define JH7100_RSTN_ISP0_AXI 51 +#define JH7100_RSTN_ISP0NOC_AXI 52 +#define JH7100_RSTN_ISP1_AXI 53 +#define JH7100_RSTN_ISP1NOC_AXI 54 +#define JH7100_RSTN_VOUT_SRC 55 +#define JH7100_RSTN_DISP_AXI 56 +#define JH7100_RSTN_DISPNOC_AXI 57 +#define JH7100_RSTN_SDIO0_AHB 58 +#define JH7100_RSTN_SDIO1_AHB 59 +#define JH7100_RSTN_GMAC_AHB 60 +#define JH7100_RSTN_SPI2AHB_AHB 61 +#define JH7100_RSTN_SPI2AHB_CORE 62 +#define JH7100_RSTN_EZMASTER_AHB 63 +#define JH7100_RST_E24 64 +#define JH7100_RSTN_QSPI_AHB 65 +#define JH7100_RSTN_QSPI_CORE 66 +#define JH7100_RSTN_QSPI_APB 67 +#define JH7100_RSTN_SEC_AHB 68 +#define JH7100_RSTN_AES 69 +#define JH7100_RSTN_PKA 70 +#define JH7100_RSTN_SHA 71 +#define JH7100_RSTN_TRNG_APB 72 +#define JH7100_RSTN_OTP_APB 73 +#define JH7100_RSTN_UART0_APB 74 +#define JH7100_RSTN_UART0_CORE 75 +#define JH7100_RSTN_UART1_APB 76 +#define JH7100_RSTN_UART1_CORE 77 +#define JH7100_RSTN_SPI0_APB 78 +#define JH7100_RSTN_SPI0_CORE 79 +#define JH7100_RSTN_SPI1_APB 80 +#define JH7100_RSTN_SPI1_CORE 81 +#define JH7100_RSTN_I2C0_APB 82 +#define JH7100_RSTN_I2C0_CORE 83 +#define JH7100_RSTN_I2C1_APB 84 +#define JH7100_RSTN_I2C1_CORE 85 +#define JH7100_RSTN_GPIO_APB 86 +#define JH7100_RSTN_UART2_APB 87 +#define JH7100_RSTN_UART2_CORE 88 +#define JH7100_RSTN_UART3_APB 89 +#define JH7100_RSTN_UART3_CORE 90 +#define JH7100_RSTN_SPI2_APB 91 +#define JH7100_RSTN_SPI2_CORE 92 +#define JH7100_RSTN_SPI3_APB 93 +#define JH7100_RSTN_SPI3_CORE 94 +#define JH7100_RSTN_I2C2_APB 95 +#define JH7100_RSTN_I2C2_CORE 96 +#define JH7100_RSTN_I2C3_APB 97 +#define JH7100_RSTN_I2C3_CORE 98 +#define JH7100_RSTN_WDTIMER_APB 99 +#define JH7100_RSTN_WDT 100 +#define JH7100_RSTN_TIMER0 101 +#define JH7100_RSTN_TIMER1 102 +#define JH7100_RSTN_TIMER2 103 +#define JH7100_RSTN_TIMER3 104 +#define JH7100_RSTN_TIMER4 105 +#define JH7100_RSTN_TIMER5 106 +#define JH7100_RSTN_TIMER6 107 +#define JH7100_RSTN_VP6INTC_APB 108 +#define JH7100_RSTN_PWM_APB 109 +#define JH7100_RSTN_MSI_APB 110 +#define JH7100_RSTN_TEMP_APB 111 +#define JH7100_RSTN_TEMP_SENSE 112 +#define JH7100_RSTN_SYSERR_APB 113 + +#define JH7100_RSTN_END 114 + +#endif /* __DT_BINDINGS_RESET_STARFIVE_JH7100_H__ */
Signature · 1 line
2.33.1
Re: [PATCH v2 07/16] dt-bindings: reset: Add StarFive JH7100 reset definitions
Quoted 7 lines · Emil Renner Berthing
From: Geert Uytterhoeven <[email protected]>
Add all resets for the StarFive JH7100 reset controller.
Based on work by Ahmad Fatoum for Barebox, with "
JH7100_" prefixes added to all definitions.
Quoted 7 lines
Signed-off-by Geert Uytterhoeven <[email protected]>Signed-off-by Emil Renner Berthing <[email protected]>--- include/dt-bindings/reset/starfive-jh7100.h | 126 ++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 include/dt-bindings/reset/starfive-jh7100.h
Emil Renner Berthing
maintainerPATCH v2 8/16 dt-bindings: reset: Add Starfive JH7100 reset bindings
In reply to Emil Renner BerthingAdd device tree bindings for the StarFive JH7100 reset controller.
--- .../bindings/reset/starfive,jh7100-reset.yaml | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml
Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml new file +38 -0
@@ -0,0 +1,38 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/reset/starfive,jh7100-reset.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: StarFive JH7100 SoC Reset Controller Device Tree Bindings + +maintainers: + - Emil Renner Berthing <[email protected]> + +properties: + compatible: + enum: + - starfive,jh7100-reset + + reg: + maxItems: 1 + + "#reset-cells": + const: 1 + +required: + - compatible + - reg + - "#reset-cells" + +additionalProperties: false + +examples: + - | + rstgen: reset-controller@11840000 { + compatible = "starfive,jh7100-reset"; + reg = <0x11840000 0x10000>; + #reset-cells = <1>; + }; + +...
Signature · 1 line
2.33.1
Rob Herring
maintainerRe: [PATCH v2 08/16] dt-bindings: reset: Add Starfive JH7100 reset bindings
Quoted 14 lines · Emil Renner Berthing
Add device tree bindings for the StarFive JH7100 reset controller.
Signed-off-by Emil Renner Berthing <[email protected]>--- .../bindings/reset/starfive,jh7100-reset.yaml | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yamlDocumentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml new file +0
-0
Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml line 1
Quoted 1 line
Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml new file +1
-0@@ -0,0 +1,38 @@ +# SPDX-License-Identifier: GPL-2.0
Dual license please.
Quoted 21 lines
Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml new file +21
-0+%YAML 1.2 +--- +$id: http://devicetree.org/schemas/reset/starfive,jh7100-reset.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: StarFive JH7100 SoC Reset Controller Device Tree Bindings + +maintainers: + - Emil Renner Berthing <[email protected]> + +properties: + compatible: + enum: + - starfive,jh7100-reset + + reg: + maxItems: 1 + + "#reset-cells": + const: 1 +
Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml line 32
Quoted 10 lines
Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml new file +10
-0+required: + - compatible + - reg + - "#reset-cells" + +additionalProperties: false + +examples: + - | + rstgen: reset-controller@11840000 {
Drop unused labels.
Quoted 10 lines
Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml new file +6
-0+ compatible = "starfive,jh7100-reset"; + reg = <0x11840000 0x10000>; + #reset-cells = <1>; + }; + +...Signature · 1 line
2.33.1
Emil Renner Berthing
maintainerPATCH v2 9/16 reset: starfive-jh7100: Add StarFive JH7100 reset driver
In reply to Emil Renner BerthingAdd a driver for the StarFive JH7100 reset controller.
--- MAINTAINERS | 7 ++ drivers/reset/Kconfig | 8 ++ drivers/reset/Makefile | 1 + drivers/reset/reset-starfive-jh7100.c | 165 ++++++++++++++++++++++++++ 4 files changed, 181 insertions(+) create mode 100644 drivers/reset/reset-starfive-jh7100.c
MAINTAINERS +7 -0
@@ -17855,6 +17855,13 @@ F: Documentation/devicetree/bindings/clock/starfive,jh7100-clkgen.yaml F: drivers/clk/starfive/clk-starfive-jh7100.c F: include/dt-bindings/clock/starfive-jh7100.h +STARFIVE JH7100 RESET CONTROLLER DRIVER +M: Emil Renner Berthing <[email protected]> +S: Maintained +F: Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml +F: drivers/reset/reset-starfive-jh7100.c +F: include/dt-bindings/reset/starfive-jh7100.h + STATIC BRANCH/CALL M: Peter Zijlstra <[email protected]> M: Josh Poimboeuf <[email protected]>
drivers/reset/Kconfig +8 -0
@@ -224,6 +224,14 @@ config RESET_SOCFPGA This enables the reset driver for the SoCFPGA ARMv7 platforms. This driver gets initialized early during platform init calls. +config RESET_STARFIVE_JH7100 + bool "StarFive JH7100 Reset Driver" + depends on SOC_STARFIVE || COMPILE_TEST + depends on OF + default SOC_STARFIVE + help + This enables the reset controller driver for the StarFive JH7100 SoC. + config RESET_SUNXI bool "Allwinner SoCs Reset Driver" if COMPILE_TEST && !ARCH_SUNXI default ARCH_SUNXI
drivers/reset/Makefile +1 -0
@@ -29,6 +29,7 @@ obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o obj-$(CONFIG_RESET_SCMI) += reset-scmi.o obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o +obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o obj-$(CONFIG_RESET_TI_SYSCON) += reset-ti-syscon.o
drivers/reset/reset-starfive-jh7100.c new file +165 -0
165 lines not on this page · raw message
Signature · 1 line
2.33.1
Re: [PATCH v2 09/16] reset: starfive-jh7100: Add StarFive JH7100 reset driver
Quoted 2 lines · Emil Renner Berthing
Add a driver for the StarFive JH7100 reset controller.
...
drivers/reset/Kconfig config RESET_SOCFPGA · line 230
Quoted 5 lines
drivers/reset/Kconfig +4
-0+config RESET_STARFIVE_JH7100 + bool "StarFive JH7100 Reset Driver" + depends on SOC_STARFIVE || COMPILE_TEST + depends on OF
No evidence of this dependency. Why to limit test coverage?
Quoted 1 line
+ default
SOC_STARFIVE
...
Quoted 6 lines
+/*
+ * Reset driver for the StarFive JH7100 SoC
+ *
+ * Copyright (C) 2021 Emil Renner Berthing <[email protected]>+ *
Redundant empty line.
Quoted 1 line
+ */
...
Quoted 1 line
+#include <
linux/of_device.h>
No evidence of any usage of this header. Perhaps you meant mod_devicetable.h?
...
drivers/reset/reset-starfive-jh7100.c line 44
Quoted 5 lines
drivers/reset/reset-starfive-jh7100.c new file +4
-0+static const u32 jh7100_reset_asserted[4 ] = { +BIT (JH7100_RST_U74 %32 ) | +BIT (JH7100_RST_VP6_DRESET %32 ) | +BIT (JH7100_RST_VP6_BRESET %32 ),
It's hard to notice that this is only one entry. See also below.
drivers/reset/reset-starfive-jh7100.c line 49
Quoted 4 lines
drivers/reset/reset-starfive-jh7100.c new file +4
-0+BIT (JH7100_RST_HIFI4_DRESET %32 ) | +BIT (JH7100_RST_HIFI4_BRESET %32 ), + +BIT (JH7100_RST_E24 %32 )
+ Comma.
Quoted 1 line
+};
Why all these ugly % 32 against constants?
...
drivers/reset/reset-starfive-jh7100.c line 66
Quoted 2 lines
drivers/reset/reset-starfive-jh7100.c new file +2
-0+if (!assert) + done ^= mask;
Can you convert this to simple
if (assert)
ret = readl_...
else
ret = readl_...below?
drivers/reset/reset-starfive-jh7100.c line 78
Quoted 11 lines
drivers/reset/reset-starfive-jh7100.c new file +10
-0+spin_lock_irqsave (&data->lock, flags); + + value =readl (reg_assert); +if (assert) + value |= mask; +else + value &= ~mask; +writel (value, reg_assert); +/* if the associated clock is gated, deasserting might otherwise hang forever */ + ret =readl_poll_timeout (reg_status, value, (value & mask) == done,0 ,1000 );
You run delays under spin lock. You need to use _atomic variant.
Quoted 1 line
+
spin_unlock_irqrestore(&data->lock, flags);
...
drivers/reset/reset-starfive-jh7100.c line 121
Quoted 4 lines
drivers/reset/reset-starfive-jh7100.c new file +3
-0+u32 value = (readl (reg_status) ^ jh7100_reset_asserted[offset]) & mask; +dev_dbg (rcdev->dev,"status(%lu) = %d\n" , id, !value); +return !value;
Dup of ! operator. Can it be value = !(...); above?
Signature · 2 lines
With Best Regards, Andy Shevchenko
Emil Renner Berthing
maintainerRe: [PATCH v2 09/16] reset: starfive-jh7100: Add StarFive JH7100 reset driver
Quoted 8 lines · Andy Shevchenko
drivers/reset/reset-starfive-jh7100.c line 44
Quoted 5 lines · Emil Renner Berthing
drivers/reset/reset-starfive-jh7100.c new file +4
-0+static const u32 jh7100_reset_asserted[4 ] = { +BIT (JH7100_RST_U74 %32 ) | +BIT (JH7100_RST_VP6_DRESET %32 ) | +BIT (JH7100_RST_VP6_BRESET %32 ),It's hard to notice that this is only one entry. See also below.
Yeah, so what would be a better way to style it?
Quoted 10 lines
drivers/reset/reset-starfive-jh7100.c line 49
Quoted 4 lines
drivers/reset/reset-starfive-jh7100.c new file +4
-0+BIT (JH7100_RST_HIFI4_DRESET %32 ) | +BIT (JH7100_RST_HIFI4_BRESET %32 ), + +BIT (JH7100_RST_E24 %32 )+ Comma.
Quoted 1 line
+};
Why all these ugly % 32 against constants?
Because the JH7100_RST_ values goes higher than 31. There is a BIT_MASK macro, but that does % BITS_PER_LONG and this is a 64bit machine.
Quoted 5 lines
...
drivers/reset/reset-starfive-jh7100.c line 66
Quoted 2 lines
drivers/reset/reset-starfive-jh7100.c new file +2
-0+if (!assert) + done ^= mask;
Quoted 8 lines
Can you convert this to simple
if (assert)
ret = readl_... else ret = readl_...below?
I don't see how that would work. We're using the done value in in the readl_poll_timeout. Maybe you can be a bit more explicit.
The reason is that for most reset lines a 0 in the status register means it's asserted and a 1 means it's deasserted. For the few reset lines above this is reversed though.
/Emil
Re: [PATCH v2 09/16] reset: starfive-jh7100: Add StarFive JH7100 reset driver
Quoted 2 lines · Emil Renner Berthing
Quoted 1 line · Andy Shevchenko
On Thu, Oct 21, 2021 at 8:43 PM Emil Renner Berthing <[email protected]> wrote:
...
Quoted 5 lines
Quoted 1 line
Why all these ugly % 32 against constants?
Because the
JH7100_RST_values goes higher than 31. There is aBIT_MASKmacro, but that does %BITS_PER_LONGand this is a 64bit machine.
And? It's exactly what you have to use!
...
Quoted 11 lines
Quoted 8 lines
Can you convert this to simple
if (assert)
ret = readl_... else ret = readl_...below?
I don't see how that would work. We're using the done value in in the
readl_poll_timeout. Maybe you can be a bit more explicit.
Supply done either == mask or == ^mask. Try it.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Emil Renner Berthing
maintainerRe: [PATCH v2 09/16] reset: starfive-jh7100: Add StarFive JH7100 reset driver
Quoted 22 lines · Andy Shevchenko
Quoted 2 lines · Emil Renner Berthing
Quoted 1 line · Andy Shevchenko
On Thu, Oct 21, 2021 at 8:43 PM Emil Renner Berthing <[email protected]> wrote:
...
Quoted 5 lines
Quoted 1 line
Why all these ugly % 32 against constants?
Because the
JH7100_RST_values goes higher than 31. There is aBIT_MASKmacro, but that does %BITS_PER_LONGand this is a 64bit machine.And? It's exactly what you have to use!
Quoted 7 lines
Quoted 7 lines
Can you convert this to simple
if (assert)
ret = readl_... else ret = readl_...
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
below?
I don't see how that would work. We're using the done value in in the
readl_poll_timeout. Maybe you can be a bit more explicit.Supply done either == mask or == ^mask. Try it.
So you want this?
if (assert)
ret = readl_poll_timeout_atomic(reg_status, value, (value & mask) ==
done, 0, 1000);
else
ret = readl_poll_timeout_atomic(reg_status, value, (value & mask) ==
^done, 0, 1000);
The compiler might be clever enough, but I'd worry the long body of the readl_poll_timeout_atomic macro is inline twice. Rather than just flipping the bit in done.
Re: [PATCH v2 09/16] reset: starfive-jh7100: Add StarFive JH7100 reset driver
Quoted 4 lines · Emil Renner Berthing
Quoted 3 lines · Andy Shevchenko
Quoted 2 lines · Emil Renner Berthing
Quoted 1 line · Andy Shevchenko
On Thu, Oct 21, 2021 at 8:43 PM Emil Renner Berthing <[email protected]> wrote:
...
Quoted 22 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Can you convert this to simple
if (assert)
ret = readl_... else ret = readl_...Quoted 6 lines
Quoted 4 lines
Quoted 1 line
below?
I don't see how that would work. We're using the done value in in the
readl_poll_timeout. Maybe you can be a bit more explicit.Supply done either == mask or == ^mask. Try it.
So you want this?
if (assert)
ret = readl_poll_timeout_atomic(reg_status, value, (value & mask) ==
done, 0, 1000);
else
ret = readl_poll_timeout_atomic(reg_status, value, (value & mask) ==
^done, 0, 1000);
Quoted 3 lines
The compiler might be clever enough, but I'd worry the long body of the
readl_poll_timeout_atomicmacro is inline twice. Rather than just flipping the bit indone.
You have a point, although it would be nice to have confirmation of either.
Signature · 7 lines
With Best Regards, Andy Shevchenko _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv
Emil Renner Berthing
maintainerRe: [PATCH v2 09/16] reset: starfive-jh7100: Add StarFive JH7100 reset driver
In reply to Andy ShevchenkoQuoted 6 lines · Andy Shevchenko
Quoted 2 lines · Emil Renner Berthing
Quoted 1 line · Andy Shevchenko
On Thu, Oct 21, 2021 at 8:43 PM Emil Renner Berthing <[email protected]> wrote:
...
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
Why all these ugly % 32 against constants?
Because the
JH7100_RST_values goes higher than 31. There is aBIT_MASKmacro, but that does %BITS_PER_LONGand this is a 64bit machine.And? It's exactly what you have to use!
So you want me to use an unsigned long array or DECLARE_BITMAP and juggle two different index and bit offsets?
Also is there a macro for handling that we'd then need 4 commas on 32bit COMPILE_TEST and 2 commas on 64bit?
If you have some other way in mind you'll have to be a lot more explicit again.
The point of the jh7100_reset_asserted array is that it exactly mirrors the values of the status registers when the lines are asserted. Maybe writing it like this would be more explicit:
static const u32 jh7100_reset_asserted[4] = {
/* STATUS0 register */
BIT(JH7100_RST_U74 % 32) |
BIT(JH7100_RST_VP6_DRESET % 32) |
BIT(JH7100_RST_VP6_BRESET % 32),
/* STATUS1 register */
BIT(JH7100_RST_HIFI4_DRESET % 32) |
BIT(JH7100_RST_HIFI4_BRESET % 32),
/* STATUS2 register */
BIT(JH7100_RST_E24 % 32),
/* STATUS3 register */
0,
};Re: [PATCH v2 09/16] reset: starfive-jh7100: Add StarFive JH7100 reset driver
Quoted 4 lines · Emil Renner Berthing
Quoted 3 lines · Andy Shevchenko
Quoted 2 lines · Emil Renner Berthing
Quoted 1 line · Andy Shevchenko
On Thu, Oct 21, 2021 at 8:43 PM Emil Renner Berthing <[email protected]> wrote:
...
Quoted 10 lines
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
Why all these ugly % 32 against constants?
Because the
JH7100_RST_values goes higher than 31. There is aBIT_MASKmacro, but that does %BITS_PER_LONGand this is a 64bit machine.And? It's exactly what you have to use!
So you want me to use an unsigned long array or
DECLARE_BITMAPand juggle two different index and bit offsets?
What are the offsets of those status registers?
AFAICS they are sequential 4 32-bit registers.
So bitmap is exactly what is suitable here, you are right!
See gpio-xilinx and gpio-pca953x on how to use bitmaps in the GPIO drivers.
Quoted 8 lines
Also is there a macro for handling that we'd then need 4 commas on 32bit
COMPILE_TESTand 2 commas on 64bit?
If you have some other way in mind you'll have to be a lot more explicit again.The point of the
jh7100_reset_assertedarray is that it exactly mirrors the values of the status registers when the lines are asserted. Maybe writing it like this would be more explicit:
Quoted 13 lines
static const u32 jh7100_reset_asserted[4] = {
/* STATUS0 register */
BIT(JH7100_RST_U74 % 32) |
BIT(JH7100_RST_VP6_DRESET % 32) |
BIT(JH7100_RST_VP6_BRESET % 32),
/* STATUS1 register */
BIT(JH7100_RST_HIFI4_DRESET % 32) |
BIT(JH7100_RST_HIFI4_BRESET % 32),
/* STATUS2 register */
BIT(JH7100_RST_E24 % 32),
/* STATUS3 register */
0,
};--
With Best Regards,
Andy Shevchenko
Re: [PATCH v2 09/16] reset: starfive-jh7100: Add StarFive JH7100 reset driver
Quoted 1 line · Andy Shevchenko
On Fri, Oct 22, 2021 at 5:25 PM Emil Renner Berthing <[email protected]> wrote:
...
Quoted 1 line
See gpio-xilinx and gpio-pca953x on how to use bitmaps in the GPIO drivers.
It might be confusing, what I meant is take that as an example on how the bitmaps are used in the GPIO drivers.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Emil Renner Berthing
maintainerRe: [PATCH v2 09/16] reset: starfive-jh7100: Add StarFive JH7100 reset driver
In reply to Andy ShevchenkoQuoted 14 lines · Andy Shevchenko
Quoted 4 lines · Emil Renner Berthing
Quoted 3 lines · Andy Shevchenko
Quoted 2 lines · Emil Renner Berthing
Quoted 1 line · Andy Shevchenko
On Thu, Oct 21, 2021 at 8:43 PM Emil Renner Berthing <[email protected]> wrote:
...
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
Quoted 1 line
Why all these ugly % 32 against constants?
Because the
JH7100_RST_values goes higher than 31. There is aBIT_MASKmacro, but that does %BITS_PER_LONGand this is a 64bit machine.
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
And? It's exactly what you have to use!
So you want me to use an unsigned long array or
DECLARE_BITMAPand juggle two different index and bit offsets?What are the offsets of those status registers?
AFAICS they are sequential 4 32-bit registers.
That's right, but we're on a 64bit machine, so DECLARE_BITMAP will give us an unsigned long array that doesn't match that.
Quoted 2 lines
So bitmap is exactly what is suitable here, you are right!
See gpio-xilinx and gpio-pca953x on how to use bitmaps in the GPIO drivers.
None of them has a pre-initialized const DECLARE_BITMAP, so they don't have to deal with the 4 vs. 2 commas problem.
Quoted 25 lines
Quoted 8 lines
Also is there a macro for handling that we'd then need 4 commas on 32bit
COMPILE_TESTand 2 commas on 64bit?
If you have some other way in mind you'll have to be a lot more explicit again.The point of the
jh7100_reset_assertedarray is that it exactly mirrors the values of the status registers when the lines are asserted. Maybe writing it like this would be more explicit:Quoted 13 lines
static const u32 jh7100_reset_asserted[4] = { /* STATUS0 register */ BIT(JH7100_RST_U74 % 32) | BIT(JH7100_RST_VP6_DRESET % 32) | BIT(JH7100_RST_VP6_BRESET % 32), /* STATUS1 register */ BIT(JH7100_RST_HIFI4_DRESET % 32) | BIT(JH7100_RST_HIFI4_BRESET % 32), /* STATUS2 register */ BIT(JH7100_RST_E24 % 32), /* STATUS3 register */ 0, };--
With Best Regards,
Andy Shevchenko
Re: [PATCH v2 09/16] reset: starfive-jh7100: Add StarFive JH7100 reset driver
Quoted 6 lines · Emil Renner Berthing
Quoted 5 lines · Andy Shevchenko
Quoted 4 lines · Emil Renner Berthing
Quoted 3 lines · Andy Shevchenko
Quoted 2 lines · Emil Renner Berthing
Quoted 1 line · Andy Shevchenko
On Thu, Oct 21, 2021 at 8:43 PM Emil Renner Berthing <[email protected]> wrote:
...
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
Why all these ugly % 32 against constants?
Because the
JH7100_RST_values goes higher than 31. There is aBIT_MASKmacro, but that does %BITS_PER_LONGand this is a 64bit machine.And? It's exactly what you have to use!
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
So you want me to use an unsigned long array or
DECLARE_BITMAPand juggle two different index and bit offsets?What are the offsets of those status registers?
AFAICS they are sequential 4 32-bit registers.That's right, but we're on a 64bit machine, so
DECLARE_BITMAPwill give us an unsigned long array that doesn't match that.
I didn't get it, sorry.
You will have a bitmap array which you will split to 32-bit values. What you will probably need is to move xgpio_get_value32() and void xgpio_set_value32() to the one of bitmap related headers (look for bitmap_get_value8() and friends).
Quoted 5 lines
Quoted 2 lines
So bitmap is exactly what is suitable here, you are right!
See gpio-xilinx and gpio-pca953x on how to use bitmaps in the GPIO drivers.None of them has a pre-initialized const
DECLARE_BITMAP, so they don't have to deal with the 4 vs. 2 commas problem.
I believe it's well possible to refactor this to look much better with bitmaps (as it represents the hardware very well).
Quoted 21 lines
Quoted 21 lines
Quoted 21 lines
Also is there a macro for handling that we'd then need 4 commas on 32bit
COMPILE_TESTand 2 commas on 64bit?
If you have some other way in mind you'll have to be a lot more explicit again.The point of the
jh7100_reset_assertedarray is that it exactly mirrors the values of the status registers when the lines are asserted. Maybe writing it like this would be more explicit:static const u32 jh7100_reset_asserted[4] = { /* STATUS0 register */ BIT(JH7100_RST_U74 % 32) | BIT(JH7100_RST_VP6_DRESET % 32) | BIT(JH7100_RST_VP6_BRESET % 32), /* STATUS1 register */ BIT(JH7100_RST_HIFI4_DRESET % 32) | BIT(JH7100_RST_HIFI4_BRESET % 32), /* STATUS2 register */ BIT(JH7100_RST_E24 % 32), /* STATUS3 register */ 0, };
Signature · 2 lines
With Best Regards, Andy Shevchenko
Emil Renner Berthing
maintainerRe: [PATCH v2 09/16] reset: starfive-jh7100: Add StarFive JH7100 reset driver
Quoted 33 lines · Andy Shevchenko
Quoted 6 lines · Emil Renner Berthing
Quoted 5 lines · Andy Shevchenko
Quoted 4 lines · Emil Renner Berthing
Quoted 3 lines · Andy Shevchenko
Quoted 2 lines · Emil Renner Berthing
Quoted 1 line · Andy Shevchenko
On Thu, Oct 21, 2021 at 8:43 PM Emil Renner Berthing <[email protected]> wrote:
...
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
Why all these ugly % 32 against constants?
Because the
JH7100_RST_values goes higher than 31. There is aBIT_MASKmacro, but that does %BITS_PER_LONGand this is a 64bit machine.And? It's exactly what you have to use!
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
So you want me to use an unsigned long array or
DECLARE_BITMAPand juggle two different index and bit offsets?What are the offsets of those status registers?
AFAICS they are sequential 4 32-bit registers.That's right, but we're on a 64bit machine, so
DECLARE_BITMAPwill give us an unsigned long array that doesn't match that.I didn't get it, sorry.
You will have a bitmap array which you will split to 32-bit values. What you will probably need is to movexgpio_get_value32()and voidxgpio_set_value32()to the one of bitmap related headers (look forbitmap_get_value8()and friends).
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
So bitmap is exactly what is suitable here, you are right!
See gpio-xilinx and gpio-pca953x on how to use bitmaps in the GPIO drivers.None of them has a pre-initialized const
DECLARE_BITMAP, so they don't have to deal with the 4 vs. 2 commas problem.I believe it's well possible to refactor this to look much better with bitmaps (as it represents the hardware very well).
Right, but how exactly? This works on on 64bit, but not with 32bit COMPILE_TEST:
static const DECLARE_BITMAP(jh7100_reset_asserted, JH7100_RSTN_END) = {
/* STATUS0 register */
BIT_MASK(JH7100_RST_U74) |
BIT_MASK(JH7100_RST_VP6_DRESET) |
BIT_MASK(JH7100_RST_VP6_BRESET) |
/* STATUS1 register */
BIT_MASK(JH7100_RST_HIFI4_DRESET) |
BIT_MASK(JH7100_RST_HIFI4_BRESET),
/* STATUS2 register */
BIT_MASK(JH7100_RST_E24) |
/* STATUS3 register */
0,
};Quoted 25 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Also is there a macro for handling that we'd then need 4 commas on 32bit
COMPILE_TESTand 2 commas on 64bit?
If you have some other way in mind you'll have to be a lot more explicit again.The point of the
jh7100_reset_assertedarray is that it exactly mirrors the values of the status registers when the lines are asserted. Maybe writing it like this would be more explicit:Quoted 13 lines
Quoted 5 lines
Quoted 5 lines
static const u32 jh7100_reset_asserted[4] = { /* STATUS0 register */ BIT(JH7100_RST_U74 % 32) | BIT(JH7100_RST_VP6_DRESET % 32) | BIT(JH7100_RST_VP6_BRESET % 32),Quoted 8 lines
Quoted 8 lines
/* STATUS1 register */ BIT(JH7100_RST_HIFI4_DRESET % 32) | BIT(JH7100_RST_HIFI4_BRESET % 32), /* STATUS2 register */ BIT(JH7100_RST_E24 % 32), /* STATUS3 register */ 0, };--
With Best Regards,
Andy Shevchenko
Re: [PATCH v2 09/16] reset: starfive-jh7100: Add StarFive JH7100 reset driver
Quoted 4 lines · Emil Renner Berthing
Quoted 3 lines · Andy Shevchenko
Quoted 2 lines · Emil Renner Berthing
Quoted 1 line · Andy Shevchenko
On Fri, Oct 22, 2021 at 5:25 PM Emil Renner Berthing <[email protected]> wrote:
...
Quoted 22 lines
Quoted 11 lines
Quoted 4 lines
Quoted 1 line
AFAICS they are sequential 4 32-bit registers.
That's right, but we're on a 64bit machine, so
DECLARE_BITMAPwill give us an unsigned long array that doesn't match that.I didn't get it, sorry.
You will have a bitmap array which you will split to 32-bit values. What you will probably need is to movexgpio_get_value32()and voidxgpio_set_value32()to the one of bitmap related headers (look forbitmap_get_value8()and friends).Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
So bitmap is exactly what is suitable here, you are right!
See gpio-xilinx and gpio-pca953x on how to use bitmaps in the GPIO drivers.None of them has a pre-initialized const
DECLARE_BITMAP, so they don't have to deal with the 4 vs. 2 commas problem.I believe it's well possible to refactor this to look much better with bitmaps (as it represents the hardware very well).
Right, but how exactly? This works on on 64bit, but not with 32bit
COMPILE_TEST:
Quoted 13 lines
static const DECLARE_BITMAP(jh7100_reset_asserted, JH7100_RSTN_END) = {
/* STATUS0 register */
BIT_MASK(JH7100_RST_U74) |
BIT_MASK(JH7100_RST_VP6_DRESET) |
BIT_MASK(JH7100_RST_VP6_BRESET) |
/* STATUS1 register */
BIT_MASK(JH7100_RST_HIFI4_DRESET) |
BIT_MASK(JH7100_RST_HIFI4_BRESET),
/* STATUS2 register */
BIT_MASK(JH7100_RST_E24) |
/* STATUS3 register */
0,
};BITMAP_FROM_U64() ?
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Also is there a macro for handling that we'd then need 4 commas on 32bit
COMPILE_TESTand 2 commas on 64bit?
If you have some other way in mind you'll have to be a lot more explicit again.The point of the
jh7100_reset_assertedarray is that it exactly mirrors the values of the status registers when the lines are asserted.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Emil Renner Berthing
maintainerRe: [PATCH v2 09/16] reset: starfive-jh7100: Add StarFive JH7100 reset driver
Quoted 44 lines · Andy Shevchenko
Quoted 4 lines · Emil Renner Berthing
Quoted 3 lines · Andy Shevchenko
Quoted 2 lines · Emil Renner Berthing
Quoted 1 line · Andy Shevchenko
On Fri, Oct 22, 2021 at 5:25 PM Emil Renner Berthing <[email protected]> wrote:
...
Quoted 22 lines
Quoted 11 lines
Quoted 4 lines
Quoted 1 line
AFAICS they are sequential 4 32-bit registers.
That's right, but we're on a 64bit machine, so
DECLARE_BITMAPwill give us an unsigned long array that doesn't match that.I didn't get it, sorry.
You will have a bitmap array which you will split to 32-bit values. What you will probably need is to movexgpio_get_value32()and voidxgpio_set_value32()to the one of bitmap related headers (look forbitmap_get_value8()and friends).Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
So bitmap is exactly what is suitable here, you are right!
See gpio-xilinx and gpio-pca953x on how to use bitmaps in the GPIO drivers.None of them has a pre-initialized const
DECLARE_BITMAP, so they don't have to deal with the 4 vs. 2 commas problem.I believe it's well possible to refactor this to look much better with bitmaps (as it represents the hardware very well).
Right, but how exactly? This works on on 64bit, but not with 32bit
COMPILE_TEST:Quoted 13 lines
static const DECLARE_BITMAP(jh7100_reset_asserted, JH7100_RSTN_END) = { /* STATUS0 register */ BIT_MASK(JH7100_RST_U74) | BIT_MASK(JH7100_RST_VP6_DRESET) | BIT_MASK(JH7100_RST_VP6_BRESET) | /* STATUS1 register */ BIT_MASK(JH7100_RST_HIFI4_DRESET) | BIT_MASK(JH7100_RST_HIFI4_BRESET), /* STATUS2 register */ BIT_MASK(JH7100_RST_E24) | /* STATUS3 register */ 0, };
Quoted 1 line
BITMAP_FROM_U64()?
So you think this is better?
static const DECLARE_BITMAP(jh7100_reset_asserted, JH7100_RSTN_END) = {
BITMAP_FROM_U64(
/* STATUS0 register */
BIT_MASK(JH7100_RST_U74) |
BIT_MASK(JH7100_RST_VP6_DRESET) |
BIT_MASK(JH7100_RST_VP6_BRESET) |
/* STATUS1 register */
BIT_MASK(JH7100_RST_HIFI4_DRESET) |
BIT_MASK(JH7100_RST_HIFI4_BRESET)
),
BITMAP_FROM_U64(
/* STATUS2 register */
BIT_MASK(JH7100_RST_E24) |
/* STATUS3 register */
0
),
};Quoted 18 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Also is there a macro for handling that we'd then need 4 commas on 32bit
COMPILE_TESTand 2 commas on 64bit?
If you have some other way in mind you'll have to be a lot more explicit again.The point of the
jh7100_reset_assertedarray is that it exactly mirrors the values of the status registers when the lines are asserted.--
With Best Regards,
Andy Shevchenko_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv
Re: [PATCH v2 09/16] reset: starfive-jh7100: Add StarFive JH7100 reset driver
In reply to Emil Renner Berthingdrivers/reset/Kconfig config RESET_SOCFPGA · line 229
Quoted 3 lines · Emil Renner Berthing
drivers/reset/Kconfig +3
-0+config RESET_STARFIVE_JH7100 + bool "StarFive JH7100 Reset Driver" + depends on SOC_STARFIVE || COMPILE_TEST
Why does it need to depend on SOC_STARFIVE?
Andreas.
Signature · 3 lines
Andreas Schwab, [email protected] GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1 "And now for something completely different."
Emil Renner Berthing
maintainerRe: [PATCH v2 09/16] reset: starfive-jh7100: Add StarFive JH7100 reset driver
Quoted 7 lines · Andreas Schwab
drivers/reset/Kconfig config RESET_SOCFPGA · line 229
Quoted 3 lines · Emil Renner Berthing
drivers/reset/Kconfig +3
-0+config RESET_STARFIVE_JH7100 + bool "StarFive JH7100 Reset Driver" + depends on SOC_STARFIVE || COMPILE_TESTWhy does it need to depend on
SOC_STARFIVE?
It strictly doesn't but most other drivers in the same Kconfig file also depends on ARCH_something or SOC_something. In particular RESET_K210 depends on SOC_CANAAN. I think this is to prevent overwhelming the user with useless choices if they didn't enable the relevant SoC, and for others there are the COMPILE_TEST option.
/Emil
Emil Renner Berthing
maintainerPATCH v2 10/16 dt-bindings: pinctrl: Add StarFive pinctrl definitions
In reply to Emil Renner BerthingAdd definitons for pins and GPIO input, output and output enable signals on the StarFive JH7100 SoC.
--- .../dt-bindings/pinctrl/pinctrl-starfive.h | 274 ++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 include/dt-bindings/pinctrl/pinctrl-starfive.h
include/dt-bindings/pinctrl/pinctrl-starfive.h new file +274 -0
@@ -0,0 +1,274 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* +* Copyright (c) 2021 Emil Renner Berthing <[email protected]> +*/ +#ifndef _DT_BINDINGS_PINCTRL_STARFIVE_H +#define _DT_BINDINGS_PINCTRL_STARFIVE_H + +#define PAD_GPIO_OFFSET 0 +#define PAD_FUNC_SHARE_OFFSET 64 +#define PAD_GPIO (x) (PAD_GPIO_OFFSET + (x)) +#define PAD_FUNC_SHARE (x) (PAD_FUNC_SHARE_OFFSET + (x)) + +/* +* GPIOMUX bits: +* | 31 - 24 | 23 - 16 | 15 - 8 | 7 | 6 | 5 - 0 | +* | dout | doen | din | dout rev | doen rev | gpio nr | +* +* dout: output signal +* doen: output enable signal +* din: optional input signal, 0xff = none +* dout rev: output signal reverse bit +* doen rev: output enable signal reverse bit +* gpio nr: gpio number, 0 - 63 +*/ +#define GPIOMUX (n, dout, doen, din) ( \ + (((dout) & 0x80000000) >> (31 - 7)) | (((dout) & 0xff) << 24) | \ + (((doen) & 0x80000000) >> (31 - 6)) | (((doen) & 0xff) << 16) | \ + (((din) & 0xff) << 8) | \ + ((n) & 0x3f)) + +#define GPO_REVERSE 0x80000000 + +#define GPO_LOW 0 +#define GPO_HIGH 1 +#define GPO_ENABLE 0 +#define GPO_DISABLE 1 +#define GPO_CLK_GMAC_PAPHYREF 2 +#define GPO_JTAG_TDO 3 +#define GPO_JTAG_TDO_OEN 4 +#define GPO_DMIC_CLK_OUT 5 +#define GPO_DSP_JTDOEN_PAD 6 +#define GPO_DSP_JTDO_PAD 7 +#define GPO_I2C0_PAD_SCK_OE 8 +#define GPO_I2C0_PAD_SCK_OEN (GPO_I2C0_PAD_SCK_OE | GPO_REVERSE) +#define GPO_I2C0_PAD_SDA_OE 9 +#define GPO_I2C0_PAD_SDA_OEN (GPO_I2C0_PAD_SDA_OE | GPO_REVERSE) +#define GPO_I2C1_PAD_SCK_OE 10 +#define GPO_I2C1_PAD_SCK_OEN (GPO_I2C1_PAD_SCK_OE | GPO_REVERSE) +#define GPO_I2C1_PAD_SDA_OE 11 +#define GPO_I2C1_PAD_SDA_OEN (GPO_I2C1_PAD_SDA_OE | GPO_REVERSE) +#define GPO_I2C2_PAD_SCK_OE 12 +#define GPO_I2C2_PAD_SCK_OEN (GPO_I2C2_PAD_SCK_OE | GPO_REVERSE) +#define GPO_I2C2_PAD_SDA_OE 13 +#define GPO_I2C2_PAD_SDA_OEN (GPO_I2C2_PAD_SDA_OE | GPO_REVERSE) +#define GPO_I2C3_PAD_SCK_OE 14 +#define GPO_I2C3_PAD_SCK_OEN (GPO_I2C3_PAD_SCK_OE | GPO_REVERSE) +#define GPO_I2C3_PAD_SDA_OE 15 +#define GPO_I2C3_PAD_SDA_OEN (GPO_I2C3_PAD_SDA_OE | GPO_REVERSE) +#define GPO_I2SRX_BCLK_OUT 16 +#define GPO_I2SRX_BCLK_OUT_OEN 17 +#define GPO_I2SRX_LRCK_OUT 18 +#define GPO_I2SRX_LRCK_OUT_OEN 19 +#define GPO_I2SRX_MCLK_OUT 20 +#define GPO_I2STX_BCLK_OUT 21 +#define GPO_I2STX_BCLK_OUT_OEN 22 +#define GPO_I2STX_LRCK_OUT 23 +#define GPO_I2STX_LRCK_OUT_OEN 24 +#define GPO_I2STX_MCLK_OUT 25 +#define GPO_I2STX_SDOUT0 26 +#define GPO_I2STX_SDOUT1 27 +#define GPO_LCD_PAD_CSM_N 28 +#define GPO_PWM_PAD_OE_N_BIT0 29 +#define GPO_PWM_PAD_OE_N_BIT1 30 +#define GPO_PWM_PAD_OE_N_BIT2 31 +#define GPO_PWM_PAD_OE_N_BIT3 32 +#define GPO_PWM_PAD_OE_N_BIT4 33 +#define GPO_PWM_PAD_OE_N_BIT5 34 +#define GPO_PWM_PAD_OE_N_BIT6 35 +#define GPO_PWM_PAD_OE_N_BIT7 36 +#define GPO_PWM_PAD_OUT_BIT0 37 +#define GPO_PWM_PAD_OUT_BIT1 38 +#define GPO_PWM_PAD_OUT_BIT2 39 +#define GPO_PWM_PAD_OUT_BIT3 40 +#define GPO_PWM_PAD_OUT_BIT4 41 +#define GPO_PWM_PAD_OUT_BIT5 42 +#define GPO_PWM_PAD_OUT_BIT6 43 +#define GPO_PWM_PAD_OUT_BIT7 44 +#define GPO_PWMDAC_LEFT_OUT 45 +#define GPO_PWMDAC_RIGHT_OUT 46 +#define GPO_QSPI_CSN1_OUT 47 +#define GPO_QSPI_CSN2_OUT 48 +#define GPO_QSPI_CSN3_OUT 49 +#define GPO_REGISTER23_SCFG_CMSENSOR_RST0 50 +#define GPO_REGISTER23_SCFG_CMSENSOR_RST1 51 +#define GPO_REGISTER32_SCFG_GMAC_PHY_RSTN 52 +#define GPO_SDIO0_PAD_CARD_POWER_EN 53 +#define GPO_SDIO0_PAD_CCLK_OUT 54 +#define GPO_SDIO0_PAD_CCMD_OE 55 +#define GPO_SDIO0_PAD_CCMD_OEN (GPO_SDIO0_PAD_CCMD_OE | GPO_REVERSE) +#define GPO_SDIO0_PAD_CCMD_OUT 56 +#define GPO_SDIO0_PAD_CDATA_OE_BIT0 57 +#define GPO_SDIO0_PAD_CDATA_OEN_BIT0 (GPO_SDIO0_PAD_CDATA_OE_BIT0 | GPO_REVERSE) +#define GPO_SDIO0_PAD_CDATA_OE_BIT1 58 +#define GPO_SDIO0_PAD_CDATA_OEN_BIT1 (GPO_SDIO0_PAD_CDATA_OE_BIT1 | GPO_REVERSE) +#define GPO_SDIO0_PAD_CDATA_OE_BIT2 59 +#define GPO_SDIO0_PAD_CDATA_OEN_BIT2 (GPO_SDIO0_PAD_CDATA_OE_BIT2 | GPO_REVERSE) +#define GPO_SDIO0_PAD_CDATA_OE_BIT3 60 +#define GPO_SDIO0_PAD_CDATA_OEN_BIT3 (GPO_SDIO0_PAD_CDATA_OE_BIT3 | GPO_REVERSE) +#define GPO_SDIO0_PAD_CDATA_OE_BIT4 61 +#define GPO_SDIO0_PAD_CDATA_OEN_BIT4 (GPO_SDIO0_PAD_CDATA_OE_BIT4 | GPO_REVERSE) +#define GPO_SDIO0_PAD_CDATA_OE_BIT5 62 +#define GPO_SDIO0_PAD_CDATA_OEN_BIT5 (GPO_SDIO0_PAD_CDATA_OE_BIT5 | GPO_REVERSE) +#define GPO_SDIO0_PAD_CDATA_OE_BIT6 63 +#define GPO_SDIO0_PAD_CDATA_OEN_BIT6 (GPO_SDIO0_PAD_CDATA_OE_BIT6 | GPO_REVERSE) +#define GPO_SDIO0_PAD_CDATA_OE_BIT7 64 +#define GPO_SDIO0_PAD_CDATA_OEN_BIT7 (GPO_SDIO0_PAD_CDATA_OE_BIT7 | GPO_REVERSE) +#define GPO_SDIO0_PAD_CDATA_OUT_BIT0 65 +#define GPO_SDIO0_PAD_CDATA_OUT_BIT1 66 +#define GPO_SDIO0_PAD_CDATA_OUT_BIT2 67 +#define GPO_SDIO0_PAD_CDATA_OUT_BIT3 68 +#define GPO_SDIO0_PAD_CDATA_OUT_BIT4 69 +#define GPO_SDIO0_PAD_CDATA_OUT_BIT5 70 +#define GPO_SDIO0_PAD_CDATA_OUT_BIT6 71 +#define GPO_SDIO0_PAD_CDATA_OUT_BIT7 72 +#define GPO_SDIO0_PAD_RST_N 73 +#define GPO_SDIO1_PAD_CARD_POWER_EN 74 +#define GPO_SDIO1_PAD_CCLK_OUT 75 +#define GPO_SDIO1_PAD_CCMD_OE 76 +#define GPO_SDIO1_PAD_CCMD_OEN (GPO_SDIO1_PAD_CCMD_OE | GPO_REVERSE) +#define GPO_SDIO1_PAD_CCMD_OUT 77 +#define GPO_SDIO1_PAD_CDATA_OE_BIT0 78 +#define GPO_SDIO1_PAD_CDATA_OEN_BIT0 (GPO_SDIO1_PAD_CDATA_OE_BIT0 | GPO_REVERSE) +#define GPO_SDIO1_PAD_CDATA_OE_BIT1 79 +#define GPO_SDIO1_PAD_CDATA_OEN_BIT1 (GPO_SDIO1_PAD_CDATA_OE_BIT1 | GPO_REVERSE) +#define GPO_SDIO1_PAD_CDATA_OE_BIT2 80 +#define GPO_SDIO1_PAD_CDATA_OEN_BIT2 (GPO_SDIO1_PAD_CDATA_OE_BIT2 | GPO_REVERSE) +#define GPO_SDIO1_PAD_CDATA_OE_BIT3 81 +#define GPO_SDIO1_PAD_CDATA_OEN_BIT3 (GPO_SDIO1_PAD_CDATA_OE_BIT3 | GPO_REVERSE) +#define GPO_SDIO1_PAD_CDATA_OE_BIT4 82 +#define GPO_SDIO1_PAD_CDATA_OEN_BIT4 (GPO_SDIO1_PAD_CDATA_OE_BIT4 | GPO_REVERSE) +#define GPO_SDIO1_PAD_CDATA_OE_BIT5 83 +#define GPO_SDIO1_PAD_CDATA_OEN_BIT5 (GPO_SDIO1_PAD_CDATA_OE_BIT5 | GPO_REVERSE) +#define GPO_SDIO1_PAD_CDATA_OE_BIT6 84 +#define GPO_SDIO1_PAD_CDATA_OEN_BIT6 (GPO_SDIO1_PAD_CDATA_OE_BIT6 | GPO_REVERSE) +#define GPO_SDIO1_PAD_CDATA_OE_BIT7 85 +#define GPO_SDIO1_PAD_CDATA_OEN_BIT7 (GPO_SDIO1_PAD_CDATA_OE_BIT7 | GPO_REVERSE) +#define GPO_SDIO1_PAD_CDATA_OUT_BIT0 86 +#define GPO_SDIO1_PAD_CDATA_OUT_BIT1 87 +#define GPO_SDIO1_PAD_CDATA_OUT_BIT2 88 +#define GPO_SDIO1_PAD_CDATA_OUT_BIT3 89 +#define GPO_SDIO1_PAD_CDATA_OUT_BIT4 90 +#define GPO_SDIO1_PAD_CDATA_OUT_BIT5 91 +#define GPO_SDIO1_PAD_CDATA_OUT_BIT6 92 +#define GPO_SDIO1_PAD_CDATA_OUT_BIT7 93 +#define GPO_SDIO1_PAD_RST_N 94 +#define GPO_SPDIF_TX_SDOUT 95 +#define GPO_SPDIF_TX_SDOUT_OEN 96 +#define GPO_SPI0_PAD_OE_N 97 +#define GPO_SPI0_PAD_SCK_OUT 98 +#define GPO_SPI0_PAD_SS_0_N 99 +#define GPO_SPI0_PAD_SS_1_N 100 +#define GPO_SPI0_PAD_TXD 101 +#define GPO_SPI1_PAD_OE_N 102 +#define GPO_SPI1_PAD_SCK_OUT 103 +#define GPO_SPI1_PAD_SS_0_N 104 +#define GPO_SPI1_PAD_SS_1_N 105 +#define GPO_SPI1_PAD_TXD 106 +#define GPO_SPI2_PAD_OE_N 107 +#define GPO_SPI2_PAD_SCK_OUT 108 +#define GPO_SPI2_PAD_SS_0_N 109 +#define GPO_SPI2_PAD_SS_1_N 110 +#define GPO_SPI2_PAD_TXD 111 +#define GPO_SPI2AHB_PAD_OE_N_BIT0 112 +#define GPO_SPI2AHB_PAD_OE_N_BIT1 113 +#define GPO_SPI2AHB_PAD_OE_N_BIT2 114 +#define GPO_SPI2AHB_PAD_OE_N_BIT3 115 +#define GPO_SPI2AHB_PAD_TXD_BIT0 116 +#define GPO_SPI2AHB_PAD_TXD_BIT1 117 +#define GPO_SPI2AHB_PAD_TXD_BIT2 118 +#define GPO_SPI2AHB_PAD_TXD_BIT3 119 +#define GPO_SPI3_PAD_OE_N 120 +#define GPO_SPI3_PAD_SCK_OUT 121 +#define GPO_SPI3_PAD_SS_0_N 122 +#define GPO_SPI3_PAD_SS_1_N 123 +#define GPO_SPI3_PAD_TXD 124 +#define GPO_UART0_PAD_DTRN 125 +#define GPO_UART0_PAD_RTSN 126 +#define GPO_UART0_PAD_SOUT 127 +#define GPO_UART1_PAD_SOUT 128 +#define GPO_UART2_PAD_DTR_N 129 +#define GPO_UART2_PAD_RTS_N 130 +#define GPO_UART2_PAD_SOUT 131 +#define GPO_UART3_PAD_SOUT 132 +#define GPO_USB_DRV_BUS 133 + +#define GPI_CPU_JTAG_TCK 0 +#define GPI_CPU_JTAG_TDI 1 +#define GPI_CPU_JTAG_TMS 2 +#define GPI_CPU_JTAG_TRST 3 +#define GPI_DMIC_SDIN_BIT0 4 +#define GPI_DMIC_SDIN_BIT1 5 +#define GPI_DSP_JTCK_PAD 6 +#define GPI_DSP_JTDI_PAD 7 +#define GPI_DSP_JTMS_PAD 8 +#define GPI_DSP_TRST_PAD 9 +#define GPI_I2C0_PAD_SCK_IN 10 +#define GPI_I2C0_PAD_SDA_IN 11 +#define GPI_I2C1_PAD_SCK_IN 12 +#define GPI_I2C1_PAD_SDA_IN 13 +#define GPI_I2C2_PAD_SCK_IN 14 +#define GPI_I2C2_PAD_SDA_IN 15 +#define GPI_I2C3_PAD_SCK_IN 16 +#define GPI_I2C3_PAD_SDA_IN 17 +#define GPI_I2SRX_BCLK_IN 18 +#define GPI_I2SRX_LRCK_IN 19 +#define GPI_I2SRX_SDIN_BIT0 20 +#define GPI_I2SRX_SDIN_BIT1 21 +#define GPI_I2SRX_SDIN_BIT2 22 +#define GPI_I2STX_BCLK_IN 23 +#define GPI_I2STX_LRCK_IN 24 +#define GPI_SDIO0_PAD_CARD_DETECT_N 25 +#define GPI_SDIO0_PAD_CARD_WRITE_PRT 26 +#define GPI_SDIO0_PAD_CCMD_IN 27 +#define GPI_SDIO0_PAD_CDATA_IN_BIT0 28 +#define GPI_SDIO0_PAD_CDATA_IN_BIT1 29 +#define GPI_SDIO0_PAD_CDATA_IN_BIT2 30 +#define GPI_SDIO0_PAD_CDATA_IN_BIT3 31 +#define GPI_SDIO0_PAD_CDATA_IN_BIT4 32 +#define GPI_SDIO0_PAD_CDATA_IN_BIT5 33 +#define GPI_SDIO0_PAD_CDATA_IN_BIT6 34 +#define GPI_SDIO0_PAD_CDATA_IN_BIT7 35 +#define GPI_SDIO1_PAD_CARD_DETECT_N 36 +#define GPI_SDIO1_PAD_CARD_WRITE_PRT 37 +#define GPI_SDIO1_PAD_CCMD_IN 38 +#define GPI_SDIO1_PAD_CDATA_IN_BIT0 39 +#define GPI_SDIO1_PAD_CDATA_IN_BIT1 40 +#define GPI_SDIO1_PAD_CDATA_IN_BIT2 41 +#define GPI_SDIO1_PAD_CDATA_IN_BIT3 42 +#define GPI_SDIO1_PAD_CDATA_IN_BIT4 43 +#define GPI_SDIO1_PAD_CDATA_IN_BIT5 44 +#define GPI_SDIO1_PAD_CDATA_IN_BIT6 45 +#define GPI_SDIO1_PAD_CDATA_IN_BIT7 46 +#define GPI_SPDIF_RX_SDIN 47 +#define GPI_SPI0_PAD_RXD 48 +#define GPI_SPI0_PAD_SS_IN_N 49 +#define GPI_SPI1_PAD_RXD 50 +#define GPI_SPI1_PAD_SS_IN_N 51 +#define GPI_SPI2_PAD_RXD 52 +#define GPI_SPI2_PAD_SS_IN_N 53 +#define GPI_SPI2AHB_PAD_RXD_BIT0 54 +#define GPI_SPI2AHB_PAD_RXD_BIT1 55 +#define GPI_SPI2AHB_PAD_RXD_BIT2 56 +#define GPI_SPI2AHB_PAD_RXD_BIT3 57 +#define GPI_SPI2AHB_PAD_SS_N 58 +#define GPI_SPI2AHB_SLV_SCLKIN 59 +#define GPI_SPI3_PAD_RXD 60 +#define GPI_SPI3_PAD_SS_IN_N 61 +#define GPI_UART0_PAD_CTSN 62 +#define GPI_UART0_PAD_DCDN 63 +#define GPI_UART0_PAD_DSRN 64 +#define GPI_UART0_PAD_RIN 65 +#define GPI_UART0_PAD_SIN 66 +#define GPI_UART1_PAD_SIN 67 +#define GPI_UART2_PAD_CTS_N 68 +#define GPI_UART2_PAD_DCD_N 69 +#define GPI_UART2_PAD_DSR_N 70 +#define GPI_UART2_PAD_RI_N 71 +#define GPI_UART2_PAD_SIN 72 +#define GPI_UART3_PAD_SIN 73 +#define GPI_USB_OVER_CURRENT 74 + +#define GPI_NONE 0xff + +#endif
Signature · 1 line
2.33.1
Rob Herring
maintainerRe: [PATCH v2 10/16] dt-bindings: pinctrl: Add StarFive pinctrl definitions
Quoted 15 lines · Emil Renner Berthing
Add definitons for pins and GPIO input, output and output enable signals on the StarFive JH7100 SoC.
Signed-off-by Emil Renner Berthing <[email protected]>--- .../dt-bindings/pinctrl/pinctrl-starfive.h | 274 ++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 include/dt-bindings/pinctrl/pinctrl-starfive.hinclude/dt-bindings/pinctrl/pinctrl-starfive.h new file +0
-0
include/dt-bindings/pinctrl/pinctrl-starfive.h line 1
Quoted 1 line
include/dt-bindings/pinctrl/pinctrl-starfive.h new file +1
-0@@ -0,0 +1,274 @@ +/* SPDX-License-Identifier: GPL-2.0 */
Not consistent with other headers.
All the headers and dts files should have the same licenses.
Quoted 277 lines
include/dt-bindings/pinctrl/pinctrl-starfive.h new file +273
-0+/* +* Copyright (c) 2021 Emil Renner Berthing <[email protected]> +*/ +#ifndef _DT_BINDINGS_PINCTRL_STARFIVE_H +#define _DT_BINDINGS_PINCTRL_STARFIVE_H + +#define PAD_GPIO_OFFSET 0 +#define PAD_FUNC_SHARE_OFFSET 64 +#define PAD_GPIO (x) (PAD_GPIO_OFFSET + (x)) +#define PAD_FUNC_SHARE (x) (PAD_FUNC_SHARE_OFFSET + (x)) + +/* +* GPIOMUX bits: +* | 31 - 24 | 23 - 16 | 15 - 8 | 7 | 6 | 5 - 0 | +* | dout | doen | din | dout rev | doen rev | gpio nr | +* +* dout: output signal +* doen: output enable signal +* din: optional input signal, 0xff = none +* dout rev: output signal reverse bit +* doen rev: output enable signal reverse bit +* gpio nr: gpio number, 0 - 63 +*/ +#define GPIOMUX (n, dout, doen, din) ( \ + (((dout) & 0x80000000) >> (31 - 7)) | (((dout) & 0xff) << 24) | \ + (((doen) & 0x80000000) >> (31 - 6)) | (((doen) & 0xff) << 16) | \ + (((din) & 0xff) << 8) | \ + ((n) & 0x3f)) + +#define GPO_REVERSE 0x80000000 + +#define GPO_LOW 0 +#define GPO_HIGH 1 +#define GPO_ENABLE 0 +#define GPO_DISABLE 1 +#define GPO_CLK_GMAC_PAPHYREF 2 +#define GPO_JTAG_TDO 3 +#define GPO_JTAG_TDO_OEN 4 +#define GPO_DMIC_CLK_OUT 5 +#define GPO_DSP_JTDOEN_PAD 6 +#define GPO_DSP_JTDO_PAD 7 +#define GPO_I2C0_PAD_SCK_OE 8 +#define GPO_I2C0_PAD_SCK_OEN (GPO_I2C0_PAD_SCK_OE | GPO_REVERSE) +#define GPO_I2C0_PAD_SDA_OE 9 +#define GPO_I2C0_PAD_SDA_OEN (GPO_I2C0_PAD_SDA_OE | GPO_REVERSE) +#define GPO_I2C1_PAD_SCK_OE 10 +#define GPO_I2C1_PAD_SCK_OEN (GPO_I2C1_PAD_SCK_OE | GPO_REVERSE) +#define GPO_I2C1_PAD_SDA_OE 11 +#define GPO_I2C1_PAD_SDA_OEN (GPO_I2C1_PAD_SDA_OE | GPO_REVERSE) +#define GPO_I2C2_PAD_SCK_OE 12 +#define GPO_I2C2_PAD_SCK_OEN (GPO_I2C2_PAD_SCK_OE | GPO_REVERSE) +#define GPO_I2C2_PAD_SDA_OE 13 +#define GPO_I2C2_PAD_SDA_OEN (GPO_I2C2_PAD_SDA_OE | GPO_REVERSE) +#define GPO_I2C3_PAD_SCK_OE 14 +#define GPO_I2C3_PAD_SCK_OEN (GPO_I2C3_PAD_SCK_OE | GPO_REVERSE) +#define GPO_I2C3_PAD_SDA_OE 15 +#define GPO_I2C3_PAD_SDA_OEN (GPO_I2C3_PAD_SDA_OE | GPO_REVERSE) +#define GPO_I2SRX_BCLK_OUT 16 +#define GPO_I2SRX_BCLK_OUT_OEN 17 +#define GPO_I2SRX_LRCK_OUT 18 +#define GPO_I2SRX_LRCK_OUT_OEN 19 +#define GPO_I2SRX_MCLK_OUT 20 +#define GPO_I2STX_BCLK_OUT 21 +#define GPO_I2STX_BCLK_OUT_OEN 22 +#define GPO_I2STX_LRCK_OUT 23 +#define GPO_I2STX_LRCK_OUT_OEN 24 +#define GPO_I2STX_MCLK_OUT 25 +#define GPO_I2STX_SDOUT0 26 +#define GPO_I2STX_SDOUT1 27 +#define GPO_LCD_PAD_CSM_N 28 +#define GPO_PWM_PAD_OE_N_BIT0 29 +#define GPO_PWM_PAD_OE_N_BIT1 30 +#define GPO_PWM_PAD_OE_N_BIT2 31 +#define GPO_PWM_PAD_OE_N_BIT3 32 +#define GPO_PWM_PAD_OE_N_BIT4 33 +#define GPO_PWM_PAD_OE_N_BIT5 34 +#define GPO_PWM_PAD_OE_N_BIT6 35 +#define GPO_PWM_PAD_OE_N_BIT7 36 +#define GPO_PWM_PAD_OUT_BIT0 37 +#define GPO_PWM_PAD_OUT_BIT1 38 +#define GPO_PWM_PAD_OUT_BIT2 39 +#define GPO_PWM_PAD_OUT_BIT3 40 +#define GPO_PWM_PAD_OUT_BIT4 41 +#define GPO_PWM_PAD_OUT_BIT5 42 +#define GPO_PWM_PAD_OUT_BIT6 43 +#define GPO_PWM_PAD_OUT_BIT7 44 +#define GPO_PWMDAC_LEFT_OUT 45 +#define GPO_PWMDAC_RIGHT_OUT 46 +#define GPO_QSPI_CSN1_OUT 47 +#define GPO_QSPI_CSN2_OUT 48 +#define GPO_QSPI_CSN3_OUT 49 +#define GPO_REGISTER23_SCFG_CMSENSOR_RST0 50 +#define GPO_REGISTER23_SCFG_CMSENSOR_RST1 51 +#define GPO_REGISTER32_SCFG_GMAC_PHY_RSTN 52 +#define GPO_SDIO0_PAD_CARD_POWER_EN 53 +#define GPO_SDIO0_PAD_CCLK_OUT 54 +#define GPO_SDIO0_PAD_CCMD_OE 55 +#define GPO_SDIO0_PAD_CCMD_OEN (GPO_SDIO0_PAD_CCMD_OE | GPO_REVERSE) +#define GPO_SDIO0_PAD_CCMD_OUT 56 +#define GPO_SDIO0_PAD_CDATA_OE_BIT0 57 +#define GPO_SDIO0_PAD_CDATA_OEN_BIT0 (GPO_SDIO0_PAD_CDATA_OE_BIT0 | GPO_REVERSE) +#define GPO_SDIO0_PAD_CDATA_OE_BIT1 58 +#define GPO_SDIO0_PAD_CDATA_OEN_BIT1 (GPO_SDIO0_PAD_CDATA_OE_BIT1 | GPO_REVERSE) +#define GPO_SDIO0_PAD_CDATA_OE_BIT2 59 +#define GPO_SDIO0_PAD_CDATA_OEN_BIT2 (GPO_SDIO0_PAD_CDATA_OE_BIT2 | GPO_REVERSE) +#define GPO_SDIO0_PAD_CDATA_OE_BIT3 60 +#define GPO_SDIO0_PAD_CDATA_OEN_BIT3 (GPO_SDIO0_PAD_CDATA_OE_BIT3 | GPO_REVERSE) +#define GPO_SDIO0_PAD_CDATA_OE_BIT4 61 +#define GPO_SDIO0_PAD_CDATA_OEN_BIT4 (GPO_SDIO0_PAD_CDATA_OE_BIT4 | GPO_REVERSE) +#define GPO_SDIO0_PAD_CDATA_OE_BIT5 62 +#define GPO_SDIO0_PAD_CDATA_OEN_BIT5 (GPO_SDIO0_PAD_CDATA_OE_BIT5 | GPO_REVERSE) +#define GPO_SDIO0_PAD_CDATA_OE_BIT6 63 +#define GPO_SDIO0_PAD_CDATA_OEN_BIT6 (GPO_SDIO0_PAD_CDATA_OE_BIT6 | GPO_REVERSE) +#define GPO_SDIO0_PAD_CDATA_OE_BIT7 64 +#define GPO_SDIO0_PAD_CDATA_OEN_BIT7 (GPO_SDIO0_PAD_CDATA_OE_BIT7 | GPO_REVERSE) +#define GPO_SDIO0_PAD_CDATA_OUT_BIT0 65 +#define GPO_SDIO0_PAD_CDATA_OUT_BIT1 66 +#define GPO_SDIO0_PAD_CDATA_OUT_BIT2 67 +#define GPO_SDIO0_PAD_CDATA_OUT_BIT3 68 +#define GPO_SDIO0_PAD_CDATA_OUT_BIT4 69 +#define GPO_SDIO0_PAD_CDATA_OUT_BIT5 70 +#define GPO_SDIO0_PAD_CDATA_OUT_BIT6 71 +#define GPO_SDIO0_PAD_CDATA_OUT_BIT7 72 +#define GPO_SDIO0_PAD_RST_N 73 +#define GPO_SDIO1_PAD_CARD_POWER_EN 74 +#define GPO_SDIO1_PAD_CCLK_OUT 75 +#define GPO_SDIO1_PAD_CCMD_OE 76 +#define GPO_SDIO1_PAD_CCMD_OEN (GPO_SDIO1_PAD_CCMD_OE | GPO_REVERSE) +#define GPO_SDIO1_PAD_CCMD_OUT 77 +#define GPO_SDIO1_PAD_CDATA_OE_BIT0 78 +#define GPO_SDIO1_PAD_CDATA_OEN_BIT0 (GPO_SDIO1_PAD_CDATA_OE_BIT0 | GPO_REVERSE) +#define GPO_SDIO1_PAD_CDATA_OE_BIT1 79 +#define GPO_SDIO1_PAD_CDATA_OEN_BIT1 (GPO_SDIO1_PAD_CDATA_OE_BIT1 | GPO_REVERSE) +#define GPO_SDIO1_PAD_CDATA_OE_BIT2 80 +#define GPO_SDIO1_PAD_CDATA_OEN_BIT2 (GPO_SDIO1_PAD_CDATA_OE_BIT2 | GPO_REVERSE) +#define GPO_SDIO1_PAD_CDATA_OE_BIT3 81 +#define GPO_SDIO1_PAD_CDATA_OEN_BIT3 (GPO_SDIO1_PAD_CDATA_OE_BIT3 | GPO_REVERSE) +#define GPO_SDIO1_PAD_CDATA_OE_BIT4 82 +#define GPO_SDIO1_PAD_CDATA_OEN_BIT4 (GPO_SDIO1_PAD_CDATA_OE_BIT4 | GPO_REVERSE) +#define GPO_SDIO1_PAD_CDATA_OE_BIT5 83 +#define GPO_SDIO1_PAD_CDATA_OEN_BIT5 (GPO_SDIO1_PAD_CDATA_OE_BIT5 | GPO_REVERSE) +#define GPO_SDIO1_PAD_CDATA_OE_BIT6 84 +#define GPO_SDIO1_PAD_CDATA_OEN_BIT6 (GPO_SDIO1_PAD_CDATA_OE_BIT6 | GPO_REVERSE) +#define GPO_SDIO1_PAD_CDATA_OE_BIT7 85 +#define GPO_SDIO1_PAD_CDATA_OEN_BIT7 (GPO_SDIO1_PAD_CDATA_OE_BIT7 | GPO_REVERSE) +#define GPO_SDIO1_PAD_CDATA_OUT_BIT0 86 +#define GPO_SDIO1_PAD_CDATA_OUT_BIT1 87 +#define GPO_SDIO1_PAD_CDATA_OUT_BIT2 88 +#define GPO_SDIO1_PAD_CDATA_OUT_BIT3 89 +#define GPO_SDIO1_PAD_CDATA_OUT_BIT4 90 +#define GPO_SDIO1_PAD_CDATA_OUT_BIT5 91 +#define GPO_SDIO1_PAD_CDATA_OUT_BIT6 92 +#define GPO_SDIO1_PAD_CDATA_OUT_BIT7 93 +#define GPO_SDIO1_PAD_RST_N 94 +#define GPO_SPDIF_TX_SDOUT 95 +#define GPO_SPDIF_TX_SDOUT_OEN 96 +#define GPO_SPI0_PAD_OE_N 97 +#define GPO_SPI0_PAD_SCK_OUT 98 +#define GPO_SPI0_PAD_SS_0_N 99 +#define GPO_SPI0_PAD_SS_1_N 100 +#define GPO_SPI0_PAD_TXD 101 +#define GPO_SPI1_PAD_OE_N 102 +#define GPO_SPI1_PAD_SCK_OUT 103 +#define GPO_SPI1_PAD_SS_0_N 104 +#define GPO_SPI1_PAD_SS_1_N 105 +#define GPO_SPI1_PAD_TXD 106 +#define GPO_SPI2_PAD_OE_N 107 +#define GPO_SPI2_PAD_SCK_OUT 108 +#define GPO_SPI2_PAD_SS_0_N 109 +#define GPO_SPI2_PAD_SS_1_N 110 +#define GPO_SPI2_PAD_TXD 111 +#define GPO_SPI2AHB_PAD_OE_N_BIT0 112 +#define GPO_SPI2AHB_PAD_OE_N_BIT1 113 +#define GPO_SPI2AHB_PAD_OE_N_BIT2 114 +#define GPO_SPI2AHB_PAD_OE_N_BIT3 115 +#define GPO_SPI2AHB_PAD_TXD_BIT0 116 +#define GPO_SPI2AHB_PAD_TXD_BIT1 117 +#define GPO_SPI2AHB_PAD_TXD_BIT2 118 +#define GPO_SPI2AHB_PAD_TXD_BIT3 119 +#define GPO_SPI3_PAD_OE_N 120 +#define GPO_SPI3_PAD_SCK_OUT 121 +#define GPO_SPI3_PAD_SS_0_N 122 +#define GPO_SPI3_PAD_SS_1_N 123 +#define GPO_SPI3_PAD_TXD 124 +#define GPO_UART0_PAD_DTRN 125 +#define GPO_UART0_PAD_RTSN 126 +#define GPO_UART0_PAD_SOUT 127 +#define GPO_UART1_PAD_SOUT 128 +#define GPO_UART2_PAD_DTR_N 129 +#define GPO_UART2_PAD_RTS_N 130 +#define GPO_UART2_PAD_SOUT 131 +#define GPO_UART3_PAD_SOUT 132 +#define GPO_USB_DRV_BUS 133 + +#define GPI_CPU_JTAG_TCK 0 +#define GPI_CPU_JTAG_TDI 1 +#define GPI_CPU_JTAG_TMS 2 +#define GPI_CPU_JTAG_TRST 3 +#define GPI_DMIC_SDIN_BIT0 4 +#define GPI_DMIC_SDIN_BIT1 5 +#define GPI_DSP_JTCK_PAD 6 +#define GPI_DSP_JTDI_PAD 7 +#define GPI_DSP_JTMS_PAD 8 +#define GPI_DSP_TRST_PAD 9 +#define GPI_I2C0_PAD_SCK_IN 10 +#define GPI_I2C0_PAD_SDA_IN 11 +#define GPI_I2C1_PAD_SCK_IN 12 +#define GPI_I2C1_PAD_SDA_IN 13 +#define GPI_I2C2_PAD_SCK_IN 14 +#define GPI_I2C2_PAD_SDA_IN 15 +#define GPI_I2C3_PAD_SCK_IN 16 +#define GPI_I2C3_PAD_SDA_IN 17 +#define GPI_I2SRX_BCLK_IN 18 +#define GPI_I2SRX_LRCK_IN 19 +#define GPI_I2SRX_SDIN_BIT0 20 +#define GPI_I2SRX_SDIN_BIT1 21 +#define GPI_I2SRX_SDIN_BIT2 22 +#define GPI_I2STX_BCLK_IN 23 +#define GPI_I2STX_LRCK_IN 24 +#define GPI_SDIO0_PAD_CARD_DETECT_N 25 +#define GPI_SDIO0_PAD_CARD_WRITE_PRT 26 +#define GPI_SDIO0_PAD_CCMD_IN 27 +#define GPI_SDIO0_PAD_CDATA_IN_BIT0 28 +#define GPI_SDIO0_PAD_CDATA_IN_BIT1 29 +#define GPI_SDIO0_PAD_CDATA_IN_BIT2 30 +#define GPI_SDIO0_PAD_CDATA_IN_BIT3 31 +#define GPI_SDIO0_PAD_CDATA_IN_BIT4 32 +#define GPI_SDIO0_PAD_CDATA_IN_BIT5 33 +#define GPI_SDIO0_PAD_CDATA_IN_BIT6 34 +#define GPI_SDIO0_PAD_CDATA_IN_BIT7 35 +#define GPI_SDIO1_PAD_CARD_DETECT_N 36 +#define GPI_SDIO1_PAD_CARD_WRITE_PRT 37 +#define GPI_SDIO1_PAD_CCMD_IN 38 +#define GPI_SDIO1_PAD_CDATA_IN_BIT0 39 +#define GPI_SDIO1_PAD_CDATA_IN_BIT1 40 +#define GPI_SDIO1_PAD_CDATA_IN_BIT2 41 +#define GPI_SDIO1_PAD_CDATA_IN_BIT3 42 +#define GPI_SDIO1_PAD_CDATA_IN_BIT4 43 +#define GPI_SDIO1_PAD_CDATA_IN_BIT5 44 +#define GPI_SDIO1_PAD_CDATA_IN_BIT6 45 +#define GPI_SDIO1_PAD_CDATA_IN_BIT7 46 +#define GPI_SPDIF_RX_SDIN 47 +#define GPI_SPI0_PAD_RXD 48 +#define GPI_SPI0_PAD_SS_IN_N 49 +#define GPI_SPI1_PAD_RXD 50 +#define GPI_SPI1_PAD_SS_IN_N 51 +#define GPI_SPI2_PAD_RXD 52 +#define GPI_SPI2_PAD_SS_IN_N 53 +#define GPI_SPI2AHB_PAD_RXD_BIT0 54 +#define GPI_SPI2AHB_PAD_RXD_BIT1 55 +#define GPI_SPI2AHB_PAD_RXD_BIT2 56 +#define GPI_SPI2AHB_PAD_RXD_BIT3 57 +#define GPI_SPI2AHB_PAD_SS_N 58 +#define GPI_SPI2AHB_SLV_SCLKIN 59 +#define GPI_SPI3_PAD_RXD 60 +#define GPI_SPI3_PAD_SS_IN_N 61 +#define GPI_UART0_PAD_CTSN 62 +#define GPI_UART0_PAD_DCDN 63 +#define GPI_UART0_PAD_DSRN 64 +#define GPI_UART0_PAD_RIN 65 +#define GPI_UART0_PAD_SIN 66 +#define GPI_UART1_PAD_SIN 67 +#define GPI_UART2_PAD_CTS_N 68 +#define GPI_UART2_PAD_DCD_N 69 +#define GPI_UART2_PAD_DSR_N 70 +#define GPI_UART2_PAD_RI_N 71 +#define GPI_UART2_PAD_SIN 72 +#define GPI_UART3_PAD_SIN 73 +#define GPI_USB_OVER_CURRENT 74 + +#define GPI_NONE 0xff + +#endif Signature · 1 line
2.33.1
Emil Renner Berthing
maintainerPATCH v2 11/16 dt-bindings: pinctrl: Add StarFive JH7100 bindings
In reply to Emil Renner BerthingAdd bindings for the StarFive JH7100 GPIO/pin controller.
--- .../pinctrl/starfive,jh7100-pinctrl.yaml | 274 ++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +274 -0
@@ -0,0 +1,274 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/starfive,jh7100-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: StarFive JH7100 Pin Controller Device Tree Bindings + +maintainers: + - Emil Renner Berthing <[email protected]> + - Drew Fustini <[email protected]> + +properties: + compatible: + const: starfive,jh7100-pinctrl + + reg: + minItems: 2 + maxItems: 2 + + reg-names: + items: + - const: "gpio" + - const: "padctl" + + clocks: + maxItems: 1 + + resets: + maxItems: 1 + + gpio-controller: true + + "#gpio-cells": + const: 2 + description: | + Number of cells in GPIO specifier. Since the generic GPIO + binding is used, the amount of cells must be specified as 2. + + interrupts: + maxItems: 1 + description: The GPIO parent interrupt. + + interrupt-controller: true + + "#interrupt-cells": + const: 2 + + starfive,signal-group: + description: | + The SoC has a global setting selecting one of 7 different pinmux + configurations of the pads named GPIO[0:63] and FUNC_SHARE[0:141]. After + this global setting is chosen only the 64 "GPIO" pins can be further + muxed by configuring them to be controlled by certain peripherals rather + than software. + Note that in configuration 0 none of GPIOs are routed to pads, and only + in configuration 1 are the GPIOs routed to the pads named GPIO[0:63]. + If this property is not set it defaults to the configuration already + chosen by the earlier boot stages. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 3, 4, 5, 6] + +required: + - compatible + - reg + - reg-names + - clocks + - gpio-controller + - "#gpio-cells" + - interrupts + - interrupt-controller + - "#interrupt-cells" + +patternProperties: + '-[0-9]*$': + type: object + patternProperties: + '-pins*$': + type: object + description: | + A pinctrl node should contain at least one subnode representing the + pinctrl groups available on the machine. Each subnode will list the + pins it needs, and how they should be configured, with regard to + muxer configuration, bias, input enable/disable, input schmitt + trigger enable/disable, slew-rate and drive strength. + $ref: "/schemas/pinctrl/pincfg-node.yaml" + + properties: + pins: + description: | + The list of pin identifiers that properties in the node apply to. + This should be set using either the PAD_GPIO or PAD_FUNC_SHARE + macro. Either this or "pinmux" has to be specified. + + pinmux: + description: | + The list of GPIO identifiers and their mux settings that + properties in the node apply to. This should be set using the + GPIOMUX macro. Either this or "pins" has to be specified. + + bias-disable: true + + bias-pull-up: + type: boolean + + bias-pull-down: + type: boolean + + drive-strength: + enum: [ 14, 21, 28, 35, 42, 49, 56, 63 ] + + input-enable: true + + input-disable: true + + input-schmitt-enable: true + + input-schmitt-disable: true + + slew-rate: + maximum: 7 + + starfive,strong-pull-up: + description: enable strong pull-up. + type: boolean + + additionalProperties: false + +additionalProperties: false + +examples: + - | + #include <dt-bindings/clock/starfive-jh7100.h> + #include <dt-bindings/reset/starfive-jh7100.h> + #include <dt-bindings/pinctrl/pinctrl-starfive.h> + + soc { + #address-cells = <2>; + #size-cells = <2>; + + gpio: pinctrl@11910000 { + compatible = "starfive,jh7100-pinctrl"; + reg = <0x0 0x11910000 0x0 0x10000>, + <0x0 0x11858000 0x0 0x1000>; + reg-names = "gpio", "padctl"; + clocks = <&clkgen JH7100_CLK_GPIO_APB>; + resets = <&clkgen JH7100_RSTN_GPIO_APB>; + interrupts = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + starfive,signal-group = <6>; + + gmac_pins_default: gmac-0 { + gtxclk-pins { + pins = <PAD_FUNC_SHARE(115)>; + bias-pull-up; + drive-strength = <35>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + miitxclk-pins { + pins = <PAD_FUNC_SHARE(116)>; + bias-pull-up; + drive-strength = <14>; + input-enable; + input-schmitt-disable; + slew-rate = <0>; + }; + tx-pins { + pins = <PAD_FUNC_SHARE(117)>, + <PAD_FUNC_SHARE(119)>, + <PAD_FUNC_SHARE(120)>, + <PAD_FUNC_SHARE(121)>, + <PAD_FUNC_SHARE(122)>, + <PAD_FUNC_SHARE(123)>, + <PAD_FUNC_SHARE(124)>, + <PAD_FUNC_SHARE(125)>, + <PAD_FUNC_SHARE(126)>; + bias-disable; + drive-strength = <35>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + rxclk-pins { + pins = <PAD_FUNC_SHARE(127)>; + bias-pull-up; + drive-strength = <14>; + input-enable; + input-schmitt-disable; + slew-rate = <6>; + }; + rxer-pins { + pins = <PAD_FUNC_SHARE(129)>; + bias-pull-up; + drive-strength = <14>; + input-enable; + input-schmitt-disable; + slew-rate = <0>; + }; + rx-pins { + pins = <PAD_FUNC_SHARE(128)>, + <PAD_FUNC_SHARE(130)>, + <PAD_FUNC_SHARE(131)>, + <PAD_FUNC_SHARE(132)>, + <PAD_FUNC_SHARE(133)>, + <PAD_FUNC_SHARE(134)>, + <PAD_FUNC_SHARE(135)>, + <PAD_FUNC_SHARE(136)>, + <PAD_FUNC_SHARE(137)>, + <PAD_FUNC_SHARE(138)>, + <PAD_FUNC_SHARE(139)>, + <PAD_FUNC_SHARE(140)>, + <PAD_FUNC_SHARE(141)>; + bias-pull-up; + drive-strength = <14>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + }; + + i2c0_pins_default: i2c0-0 { + i2c-pins { + pinmux = <GPIOMUX(62, GPO_LOW, + GPO_I2C0_PAD_SCK_OEN, + GPI_I2C0_PAD_SCK_IN)>, + <GPIOMUX(61, GPO_LOW, + GPO_I2C0_PAD_SDA_OEN, + GPI_I2C0_PAD_SDA_IN)>; + bias-disable; /* external pull-up */ + input-enable; + input-schmitt-enable; + }; + }; + + uart3_pins_default: uart3-0 { + rx-pin { + pinmux = <GPIOMUX(13, GPO_LOW, GPO_DISABLE, + GPI_UART3_PAD_SIN)>; + bias-pull-up; + input-enable; + input-schmitt-enable; + }; + tx-pin { + pinmux = <GPIOMUX(14, GPO_UART3_PAD_SOUT, + GPO_ENABLE, GPI_NONE)>; + bias-disable; + input-disable; + input-schmitt-disable; + }; + }; + }; + + gmac { + pinctrl-0 = <&gmac_pins_default>; + pinctrl-names = "default"; + }; + + i2c0 { + pinctrl-0 = <&i2c0_pins_default>; + pinctrl-names = "default"; + }; + + uart3 { + pinctrl-0 = <&uart3_pins_default>; + pinctrl-names = "default"; + }; + }; + +...
Signature · 1 line
2.33.1
Re: [PATCH v2 11/16] dt-bindings: pinctrl: Add StarFive JH7100 bindings
Quoted 3 lines · Emil Renner Berthing
Add bindings for the StarFive JH7100 GPIO/pin controller.
Signed-off-by Emil Renner Berthing <[email protected]>
That is a very terse commit message for an entirely new SoC, please put a little blurb about this silicon there. Like mention that it is RISC-V at least.
Overall quite interesting!
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml line 11
Quoted 8 lines
+$id: http://devicetree.org/schemas/pinctrl/starfive,jh7100-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +6
-0+ +title: StarFive JH7100 Pin Controller Device Tree Bindings + +maintainers: + - Emil Renner Berthing <[email protected]> + - Drew Fustini <[email protected]>
Add description: talking about that this is a RISC-V SoC and other implicit things that are really good to know.
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml line 61
Quoted 13 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +13
-0+ starfive,signal-group: + description: | + The SoC has a global setting selecting one of 7 different pinmux + configurations of the pads named GPIO[0:63] and FUNC_SHARE[0:141]. After + this global setting is chosen only the 64 "GPIO" pins can be further + muxed by configuring them to be controlled by certain peripherals rather + than software. + Note that in configuration 0 none of GPIOs are routed to pads, and only + in configuration 1 are the GPIOs routed to the pads named GPIO[0:63]. + If this property is not set it defaults to the configuration already + chosen by the earlier boot stages. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 3, 4, 5, 6]
This still is hard for me to understand. Does it mean that 0..6 define how the direct-to-peripheral-pins are set up?
Then it would make sense to describe what happens for 0, 1, 2 ...6 i.e. what the different set-ups are.
Actually this is what we call group-based pin multiplexing in Linux, this property seems to avoid using that concept.
See for example:Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml line 86
Quoted 10 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +10
-0+ patternProperties: + '-pins*$': + type: object + description: | + A pinctrl node should contain at least one subnode representing the + pinctrl groups available on the machine. Each subnode will list the + pins it needs, and how they should be configured, with regard to + muxer configuration, bias, input enable/disable, input schmitt + trigger enable/disable, slew-rate and drive strength. + $ref: "/schemas/pinctrl/pincfg-node.yaml"
Nice that you use pincfg-node.yaml
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml line 99
Quoted 12 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +12
-0+ properties: + pins: + description: | + The list of pin identifiers that properties in the node apply to. + This should be set using either the PAD_GPIO or PAD_FUNC_SHARE + macro. Either this or "pinmux" has to be specified. + + pinmux: + description: | + The list of GPIO identifiers and their mux settings that + properties in the node apply to. This should be set using the + GPIOMUX macro. Either this or "pins" has to be specified.
What about referencing Documentation/devicetree/bindings/pinctrl/pinmux-node.yaml for this?
Yours,
Linus Walleij
Emil Renner Berthing
maintainerRe: [PATCH v2 11/16] dt-bindings: pinctrl: Add StarFive JH7100 bindings
Quoted 9 lines · Linus Walleij
Quoted 3 lines · Emil Renner Berthing
Add bindings for the StarFive JH7100 GPIO/pin controller.
Signed-off-by Emil Renner Berthing <[email protected]>That is a very terse commit message for an entirely new SoC, please put a little blurb about this silicon there. Like mention that it is RISC-V at least.
Will do!
Quoted 13 lines
Overall quite interesting!
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml line 11
Quoted 8 lines
+$id: http://devicetree.org/schemas/pinctrl/starfive,jh7100-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +6
-0+ +title: StarFive JH7100 Pin Controller Device Tree Bindings + +maintainers: + - Emil Renner Berthing <[email protected]> + - Drew Fustini <[email protected]>Add description: talking about that this is a RISC-V SoC and other implicit things that are really good to know.
Gotcha.
Quoted 14 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml line 61
Quoted 13 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +13
-0+ starfive,signal-group: + description: | + The SoC has a global setting selecting one of 7 different pinmux + configurations of the pads named GPIO[0:63] and FUNC_SHARE[0:141]. After + this global setting is chosen only the 64 "GPIO" pins can be further + muxed by configuring them to be controlled by certain peripherals rather + than software. + Note that in configuration 0 none of GPIOs are routed to pads, and only + in configuration 1 are the GPIOs routed to the pads named GPIO[0:63]. + If this property is not set it defaults to the configuration already + chosen by the earlier boot stages. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 3, 4, 5, 6]
Quoted 2 lines
This still is hard for me to understand. Does it mean that 0..6 define how the direct-to-peripheral-pins are set up?
Yeah, so the SoC has many pins, but only the pins named GPIO[0:63] and FUNC_SHARE[0:141] can be muxed. To do that you first select one of 7 different "signal groups". This is a global setting. There is just a single register on the whole SoC where you write either 0, 1, .., or
6. As an example signal group 6 maps LCD output to FUNC_SHARE[40:97], ethernet phy connection to FUNC_SHARE[115:141], MIPI to GPIO[0:60] and confusingly it maps "GPIO0", "GPIO1", ..., "GPIO63" to pins FUNC_SHARE[0:63]. So the pin names doesn't necessarily match the function. In fact only signal group 1 maps GPIO0-63 to pins GPIO[0:63]. See table 11-1 starting on page 62 of this PDF:
https://github.com/starfive-tech/JH7100_Docs/blob/main/JH7100%20Data%20Sheet%20V01.01.04-EN%20(4-21-2021).pdf
GPIO0-63 can of course be used as GPIOs, but they can also have their output value and output enable controlled by certain (slow) peripherals like UARTs, I2C, SPI, PWM etc. These can be chosen freely. So once you've chosen signal group 6, you can have any of GPIO0-GPIO63 (that is any of pins FUNC_SHARE[0:63]) be controlled by the UART0 TX signal fx.
So for each of GPIO0 to GPIO63 there is a register to select the output value signal and a register to select its output enable signal. You can see the list of signals to choose from in the header introduced in the previous patch.
Input from GPIO0-63 to peripherals works the other way around. Here there is a register for each input signal, where you can select which (if any) of GPIO0-63 is routed to the peripheral.
Quoted 2 lines
Then it would make sense to describe what happens for 0, 1, 2 ...6 i.e. what the different set-ups are.
Yeah, so how much of table 11-1 does it make sense to write out. Certainly I can list how GPIO0-63 are mapped to pins for each of the 7 signal groups, but should I also list LCD, ethernet, interconnect, mipi etc. for each of the 7 signal groups?
Quoted 4 lines
Actually this is what we call group-based pin multiplexing in Linux, this property seems to avoid using that concept.
See for example:Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt
I don't think this is the same, but hope you can tell me after reading the description above.
Quoted 26 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml line 86
Quoted 10 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +10
-0+ patternProperties: + '-pins*$': + type: object + description: | + A pinctrl node should contain at least one subnode representing the + pinctrl groups available on the machine. Each subnode will list the + pins it needs, and how they should be configured, with regard to + muxer configuration, bias, input enable/disable, input schmitt + trigger enable/disable, slew-rate and drive strength. + $ref: "/schemas/pinctrl/pincfg-node.yaml"Nice that you use
pincfg-node.yamlDocumentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml line 99
Quoted 12 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +12
-0+ properties: + pins: + description: | + The list of pin identifiers that properties in the node apply to. + This should be set using either the PAD_GPIO or PAD_FUNC_SHARE + macro. Either this or "pinmux" has to be specified. + + pinmux: + description: | + The list of GPIO identifiers and their mux settings that + properties in the node apply to. This should be set using the + GPIOMUX macro. Either this or "pins" has to be specified.
Quoted 3 lines
What about referencing
Documentation/devicetree/bindings/pinctrl/pinmux-node.yamlfor this?
Sure. You just mean adding $ref: like above right?
Thanks!
/Emil
Rob Herring
maintainerRe: [PATCH v2 11/16] dt-bindings: pinctrl: Add StarFive JH7100 bindings
In reply to Emil Renner BerthingQuoted 28 lines · Emil Renner Berthing
Add bindings for the StarFive JH7100 GPIO/pin controller.
Signed-off-by Emil Renner Berthing <[email protected]>--- .../pinctrl/starfive,jh7100-pinctrl.yaml | 274 ++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yamlDocumentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +14
-0@@ -0,0 +1,274 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/starfive,jh7100-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: StarFive JH7100 Pin Controller Device Tree Bindings + +maintainers: + - Emil Renner Berthing <[email protected]> + - Drew Fustini <[email protected]> + +properties: + compatible:
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml line 24
Quoted 10 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +10
-0+ const: starfive,jh7100-pinctrl + + reg: + minItems: 2 + maxItems: 2 + + reg-names: + items: + - const: "gpio" + - const: "padctl"
Don't need quotes.
Quoted 41 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +41
-0+ + clocks: + maxItems: 1 + + resets: + maxItems: 1 + + gpio-controller: true + + "#gpio-cells": + const: 2 + description: | + Number of cells in GPIO specifier. Since the generic GPIO + binding is used, the amount of cells must be specified as 2. + + interrupts: + maxItems: 1 + description: The GPIO parent interrupt. + + interrupt-controller: true + + "#interrupt-cells": + const: 2 + + starfive,signal-group: + description: | + The SoC has a global setting selecting one of 7 different pinmux + configurations of the pads named GPIO[0:63] and FUNC_SHARE[0:141]. After + this global setting is chosen only the 64 "GPIO" pins can be further + muxed by configuring them to be controlled by certain peripherals rather + than software. + Note that in configuration 0 none of GPIOs are routed to pads, and only + in configuration 1 are the GPIOs routed to the pads named GPIO[0:63]. + If this property is not set it defaults to the configuration already + chosen by the earlier boot stages. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 3, 4, 5, 6] + +required: + - compatible + - reg
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml line 75
Quoted 10 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +10
-0+ - reg-names + - clocks + - gpio-controller + - "#gpio-cells" + - interrupts + - interrupt-controller + - "#interrupt-cells" + +patternProperties: + '-[0-9]*$':
Can you make this more specific. As-is, '-' and 'foo-' are valid.
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml line 78
Quoted 3 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +3
-0+ type: object + patternProperties: + '-pins*$':
So foo-pinsssssss is okay? Drop the '*' or use ? if you intend to support 'foo-pin'.
Quoted 16 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +16
-0+ type: object + description: | + A pinctrl node should contain at least one subnode representing the + pinctrl groups available on the machine. Each subnode will list the + pins it needs, and how they should be configured, with regard to + muxer configuration, bias, input enable/disable, input schmitt + trigger enable/disable, slew-rate and drive strength. + $ref: "/schemas/pinctrl/pincfg-node.yaml" + + properties: + pins: + description: | + The list of pin identifiers that properties in the node apply to. + This should be set using either the PAD_GPIO or PAD_FUNC_SHARE + macro. Either this or "pinmux" has to be specified. +
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml line 104
Quoted 10 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +10
-0+ pinmux: + description: | + The list of GPIO identifiers and their mux settings that + properties in the node apply to. This should be set using the + GPIOMUX macro. Either this or "pins" has to be specified. + + bias-disable: true + + bias-pull-up: + type: boolean
Already has a type. Need to reference the common schema.
Quoted 174 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +170
-0+ + bias-pull-down: + type: boolean + + drive-strength: + enum: [ 14, 21, 28, 35, 42, 49, 56, 63 ] + + input-enable: true + + input-disable: true + + input-schmitt-enable: true + + input-schmitt-disable: true + + slew-rate: + maximum: 7 + + starfive,strong-pull-up: + description: enable strong pull-up. + type: boolean + + additionalProperties: false + +additionalProperties: false + +examples: + - | + #include <dt-bindings/clock/starfive-jh7100.h> + #include <dt-bindings/reset/starfive-jh7100.h> + #include <dt-bindings/pinctrl/pinctrl-starfive.h> + + soc { + #address-cells = <2>; + #size-cells = <2>; + + gpio: pinctrl@11910000 { + compatible = "starfive,jh7100-pinctrl"; + reg = <0x0 0x11910000 0x0 0x10000>, + <0x0 0x11858000 0x0 0x1000>; + reg-names = "gpio", "padctl"; + clocks = <&clkgen JH7100_CLK_GPIO_APB>; + resets = <&clkgen JH7100_RSTN_GPIO_APB>; + interrupts = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + starfive,signal-group = <6>; + + gmac_pins_default: gmac-0 { + gtxclk-pins { + pins = <PAD_FUNC_SHARE(115)>; + bias-pull-up; + drive-strength = <35>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + miitxclk-pins { + pins = <PAD_FUNC_SHARE(116)>; + bias-pull-up; + drive-strength = <14>; + input-enable; + input-schmitt-disable; + slew-rate = <0>; + }; + tx-pins { + pins = <PAD_FUNC_SHARE(117)>, + <PAD_FUNC_SHARE(119)>, + <PAD_FUNC_SHARE(120)>, + <PAD_FUNC_SHARE(121)>, + <PAD_FUNC_SHARE(122)>, + <PAD_FUNC_SHARE(123)>, + <PAD_FUNC_SHARE(124)>, + <PAD_FUNC_SHARE(125)>, + <PAD_FUNC_SHARE(126)>; + bias-disable; + drive-strength = <35>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + rxclk-pins { + pins = <PAD_FUNC_SHARE(127)>; + bias-pull-up; + drive-strength = <14>; + input-enable; + input-schmitt-disable; + slew-rate = <6>; + }; + rxer-pins { + pins = <PAD_FUNC_SHARE(129)>; + bias-pull-up; + drive-strength = <14>; + input-enable; + input-schmitt-disable; + slew-rate = <0>; + }; + rx-pins { + pins = <PAD_FUNC_SHARE(128)>, + <PAD_FUNC_SHARE(130)>, + <PAD_FUNC_SHARE(131)>, + <PAD_FUNC_SHARE(132)>, + <PAD_FUNC_SHARE(133)>, + <PAD_FUNC_SHARE(134)>, + <PAD_FUNC_SHARE(135)>, + <PAD_FUNC_SHARE(136)>, + <PAD_FUNC_SHARE(137)>, + <PAD_FUNC_SHARE(138)>, + <PAD_FUNC_SHARE(139)>, + <PAD_FUNC_SHARE(140)>, + <PAD_FUNC_SHARE(141)>; + bias-pull-up; + drive-strength = <14>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + }; + + i2c0_pins_default: i2c0-0 { + i2c-pins { + pinmux = <GPIOMUX(62, GPO_LOW, + GPO_I2C0_PAD_SCK_OEN, + GPI_I2C0_PAD_SCK_IN)>, + <GPIOMUX(61, GPO_LOW, + GPO_I2C0_PAD_SDA_OEN, + GPI_I2C0_PAD_SDA_IN)>; + bias-disable; /* external pull-up */ + input-enable; + input-schmitt-enable; + }; + }; + + uart3_pins_default: uart3-0 { + rx-pin { + pinmux = <GPIOMUX(13, GPO_LOW, GPO_DISABLE, + GPI_UART3_PAD_SIN)>; + bias-pull-up; + input-enable; + input-schmitt-enable; + }; + tx-pin { + pinmux = <GPIOMUX(14, GPO_UART3_PAD_SOUT, + GPO_ENABLE, GPI_NONE)>; + bias-disable; + input-disable; + input-schmitt-disable; + }; + }; + }; + + gmac { + pinctrl-0 = <&gmac_pins_default>; + pinctrl-names = "default"; + }; + + i2c0 { + pinctrl-0 = <&i2c0_pins_default>; + pinctrl-names = "default"; + }; + + uart3 { + pinctrl-0 = <&uart3_pins_default>; + pinctrl-names = "default"; + }; + }; + +...Signature · 1 line
2.33.1
Emil Renner Berthing
maintainerRe: [PATCH v2 11/16] dt-bindings: pinctrl: Add StarFive JH7100 bindings
Quoted 4 lines · Rob Herring
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml line 75
Quoted 2 lines · Emil Renner Berthing
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +2
-0+patternProperties: + '-[0-9]*$':
Quoted 8 lines
Can you make this more specific. As-is, '-' and 'foo-' are valid.
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml line 78
Quoted 3 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +3
-0+ type: object + patternProperties: + '-pins*$':So foo-pinsssssss is okay? Drop the '*' or use ? if you intend to support 'foo-pin'.
Ah, thanks. Both this and the pattern above was taken from pinctrl/mediatek,mt6779-pinctrl.yaml if anyone feels like fixing that too. I see now that '-[0-9]+$' and '-pins$' is more common. I'll just use that.
Quoted 20 lines
Quoted 20 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +20
-0+ type: object + description: | + A pinctrl node should contain at least one subnode representing the + pinctrl groups available on the machine. Each subnode will list the + pins it needs, and how they should be configured, with regard to + muxer configuration, bias, input enable/disable, input schmitt + trigger enable/disable, slew-rate and drive strength. + $ref: "/schemas/pinctrl/pincfg-node.yaml" + + properties: + pins: + description: | + The list of pin identifiers that properties in the node apply to. + This should be set using either the PAD_GPIO or PAD_FUNC_SHARE + macro. Either this or "pinmux" has to be specified. + + pinmux: + description: | + The list of GPIO identifiers and their mux settings that + properties in the node apply to. This should be set using the
Quoted 8 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml line 104
Quoted 6 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +6
-0+ GPIOMUX macro. Either this or "pins" has to be specified. + + bias-disable: true + + bias-pull-up: + type: booleanAlready has a type. Need to reference the common schema.
Right, but the common schema specifies one of boolean or uint32. Is there a way to reference that, but still say that this binding supports only the boolean version?
Rob Herring
maintainerRe: [PATCH v2 11/16] dt-bindings: pinctrl: Add StarFive JH7100 bindings
Quoted 49 lines · Emil Renner Berthing
Quoted 4 lines · Rob Herring
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml line 75
Quoted 2 lines · Emil Renner Berthing
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +2
-0+patternProperties: + '-[0-9]*$':Quoted 8 lines
Can you make this more specific. As-is, '-' and 'foo-' are valid.
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml line 78
Quoted 3 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +3
-0+ type: object + patternProperties: + '-pins*$':So foo-pinsssssss is okay? Drop the '*' or use ? if you intend to support 'foo-pin'.
Ah, thanks. Both this and the pattern above was taken from
pinctrl/mediatek,mt6779-pinctrl.yamlif anyone feels like fixing that too. I see now that '-[0-9]+$' and '-pins$' is more common. I'll just use that.Quoted 20 lines
Quoted 20 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +20
-0+ type: object + description: | + A pinctrl node should contain at least one subnode representing the + pinctrl groups available on the machine. Each subnode will list the + pins it needs, and how they should be configured, with regard to + muxer configuration, bias, input enable/disable, input schmitt + trigger enable/disable, slew-rate and drive strength. + $ref: "/schemas/pinctrl/pincfg-node.yaml" + + properties: + pins: + description: | + The list of pin identifiers that properties in the node apply to. + This should be set using either the PAD_GPIO or PAD_FUNC_SHARE + macro. Either this or "pinmux" has to be specified. + + pinmux: + description: | + The list of GPIO identifiers and their mux settings that + properties in the node apply to. This should be set using theQuoted 8 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml line 104
Quoted 6 lines
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml new file +6
-0+ GPIOMUX macro. Either this or "pins" has to be specified. + + bias-disable: true + + bias-pull-up: + type: booleanAlready has a type. Need to reference the common schema.
Quoted 3 lines
Right, but the common schema specifies one of boolean or uint32. Is there a way to reference that, but still say that this binding supports only the boolean version?
Okay, then keep this.
Rob
Emil Renner Berthing
maintainerPATCH v2 12/16 pinctrl: starfive: Add pinctrl driver for StarFive SoCs
In reply to Emil Renner BerthingAdd a combined pinctrl and GPIO driver for the StarFive JH7100 SoC.
For each "GPIO" there are two registers for configuring the output and output enable signals which may come from other peripherals. Among these are two special signals that are constant 0 and constant 1 respectively. Controlling the GPIOs from software is done by choosing one of these signals. In other words the same registers are used for both pinmuxing and controlling the GPIOs, which makes it easier to combine the pinctrl and GPIO driver in one.
I wrote the pinconf and pinmux parts, but the GPIO part of the code is based on the GPIO driver in the vendor tree written by Huan Feng with cleanups and fixes by Drew and me.
--- MAINTAINERS | 8 + drivers/pinctrl/Kconfig | 16 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-starfive.c | 1387 ++++++++++++++++++++++++++++ 4 files changed, 1412 insertions(+) create mode 100644 drivers/pinctrl/pinctrl-starfive.c
MAINTAINERS +8 -0
@@ -17855,6 +17855,14 @@ F: Documentation/devicetree/bindings/clock/starfive,jh7100-clkgen.yaml F: drivers/clk/starfive/clk-starfive-jh7100.c F: include/dt-bindings/clock/starfive-jh7100.h +STARFIVE JH7100 PINCTRL DRIVER +M: Emil Renner Berthing <[email protected]> +L: [email protected] +S: Maintained +F: Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml +F: drivers/pinctrl/pinctrl-starfive.c +F: include/dt-bindings/pinctrl/pinctrl-starfive.h + STARFIVE JH7100 RESET CONTROLLER DRIVER M: Emil Renner Berthing <[email protected]> S: Maintained
drivers/pinctrl/Kconfig +16 -0
@@ -265,6 +265,22 @@ config PINCTRL_ST select PINCONF select GPIOLIB_IRQCHIP +config PINCTRL_STARFIVE + tristate "Pinctrl and GPIO driver for the StarFive JH7100 SoC" + depends on SOC_STARFIVE || COMPILE_TEST + default SOC_STARFIVE + select GENERIC_PINCTRL_GROUPS + select GENERIC_PINMUX_FUNCTIONS + select GENERIC_PINCONF + select GPIOLIB + select GPIOLIB_IRQCHIP + select OF_GPIO + help + Say yes here to support pin control on the StarFive JH7100 SoC. + This also provides an interface to the GPIO pins not used by other + peripherals supporting inputs, outputs, configuring pull-up/pull-down + and interrupts on input changes. + config PINCTRL_STMFX tristate "STMicroelectronics STMFX GPIO expander pinctrl driver" depends on I2C
drivers/pinctrl/Makefile +1 -0
@@ -38,6 +38,7 @@ obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o obj-$(CONFIG_PINCTRL_LPC18XX) += pinctrl-lpc18xx.o obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o +obj-$(CONFIG_PINCTRL_STARFIVE) += pinctrl-starfive.o obj-$(CONFIG_PINCTRL_STMFX) += pinctrl-stmfx.o obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o obj-$(CONFIG_PINCTRL_ZYNQMP) += pinctrl-zynqmp.o
drivers/pinctrl/pinctrl-starfive.c new file +1387 -0
1,387 lines not on this page · raw message
Signature · 1 line
2.33.1
Re: [PATCH v2 12/16] pinctrl: starfive: Add pinctrl driver for StarFive SoCs
Quoted 157 lines · Emil Renner Berthing
Add a combined pinctrl and GPIO driver for the StarFive JH7100 SoC.
For each "GPIO" there are two registers for configuring the output and output enable signals which may come from other peripherals. Among these are two special signals that are constant 0 and constant 1 respectively. Controlling the GPIOs from software is done by choosing one of these signals. In other words the same registers are used for both pinmuxing and controlling the GPIOs, which makes it easier to combine the pinctrl and GPIO driver in one.
I wrote the pinconf and pinmux parts, but the GPIO part of the code is based on the GPIO driver in the vendor tree written by Huan Feng with cleanups and fixes by Drew and me.
Co-developed-by Huan Feng <[email protected]>Signed-off-by Huan Feng <[email protected]>Signed-off-by Emil Renner Berthing <[email protected]>Co-developed-by Drew Fustini <[email protected]>Signed-off-by Drew Fustini <[email protected]>--- MAINTAINERS | 8 + drivers/pinctrl/Kconfig | 16 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-starfive.c | 1387 ++++++++++++++++++++++++++++ 4 files changed, 1412 insertions(+) create mode 100644 drivers/pinctrl/pinctrl-starfive.cMAINTAINERS +8
-0@@ -17855,6 +17855,14 @@ F: Documentation/devicetree/bindings/clock/starfive,jh7100-clkgen.yaml F: drivers/clk/starfive/clk-starfive-jh7100.c F: include/dt-bindings/clock/starfive-jh7100.h +STARFIVE JH7100 PINCTRL DRIVER +M: Emil Renner Berthing <[email protected]> +L: [email protected] +S: Maintained +F: Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml +F: drivers/pinctrl/pinctrl-starfive.c +F: include/dt-bindings/pinctrl/pinctrl-starfive.h + STARFIVE JH7100 RESET CONTROLLER DRIVER M: Emil Renner Berthing <[email protected]> S: Maintaineddrivers/pinctrl/Kconfig +16
-0@@ -265,6 +265,22 @@ config PINCTRL_ST select PINCONF select GPIOLIB_IRQCHIP +config PINCTRL_STARFIVE + tristate "Pinctrl and GPIO driver for the StarFive JH7100 SoC" + depends on SOC_STARFIVE || COMPILE_TEST + default SOC_STARFIVE + select GENERIC_PINCTRL_GROUPS + select GENERIC_PINMUX_FUNCTIONS + select GENERIC_PINCONF + select GPIOLIB + select GPIOLIB_IRQCHIP + select OF_GPIO + help + Say yes here to support pin control on the StarFive JH7100 SoC. + This also provides an interface to the GPIO pins not used by other + peripherals supporting inputs, outputs, configuring pull-up/pull-down + and interrupts on input changes. + config PINCTRL_STMFX tristate "STMicroelectronics STMFX GPIO expander pinctrl driver" depends on I2Cdrivers/pinctrl/Makefile +1
-0@@ -38,6 +38,7 @@ obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o obj-$(CONFIG_PINCTRL_LPC18XX) += pinctrl-lpc18xx.o obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o +obj-$(CONFIG_PINCTRL_STARFIVE) += pinctrl-starfive.o obj-$(CONFIG_PINCTRL_STMFX) += pinctrl-stmfx.o obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o obj-$(CONFIG_PINCTRL_ZYNQMP) += pinctrl-zynqmp.odrivers/pinctrl/pinctrl-starfive.c new file +65
-0@@ -0,0 +1,1387 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* Pinctrl / GPIO driver for StarFive JH7100 SoC +* +* Copyright (C) 2020 Shanghai StarFive Technology Co., Ltd. +* Copyright (C) 2021 Emil Renner Berthing <[email protected]> +*/ + +#include <linux/bits.h> +#include <linux/clk.h> +#include <linux/gpio/driver.h> +#include <linux/io.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/reset.h> +#include <linux/spinlock.h> + +#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/pinmux.h> + +#include <dt-bindings/pinctrl/pinctrl-starfive.h> + +#include "core.h" +#include "pinctrl-utils.h" +#include "pinmux.h" +#include "pinconf.h" + +#define DRIVER_NAME "pinctrl-starfive" + +/* +* Refer to Section 12. GPIO Registers in the JH7100 data sheet: +* https://github.com/starfive-tech/JH7100_Docs +*/ +#define NR_GPIOS 64 + +/* +* Global enable for GPIO interrupts. If bit 0 is set to 1 the GPIO interrupts +* are enabled. If set to 0 the GPIO interrupts are disabled. +*/ +#define GPIOEN 0x000 + +/* +* The following 32-bit registers come in pairs, but only the offset of the +* first register is defined. The first controls (interrupts for) GPIO 0-31 and +* the second GPIO 32-63. +*/ + +/* +* Interrupt Type. If set to 1 the interrupt is edge-triggered. If set to 0 the +* interrupt is level-triggered. +*/ +#define GPIOIS 0x010 + +/* +* Edge-Trigger Interrupt Type. If set to 1 the interrupt gets triggered on +* both positive and negative edges. If set to 0 the interrupt is triggered by a +* single edge. +*/ +#define GPIOIBE 0x018 + +/* +* Interrupt Trigger Polarity. If set to 1 the interrupt is triggered on a +* rising edge (edge-triggered) or high level (level-triggered). If set to 0 the
drivers/pinctrl/pinctrl-starfive.c line 75
Quoted 10 lines
drivers/pinctrl/pinctrl-starfive.c new file +10
-0+* interrupt is triggered on a falling edge (edge-triggered) or low level +* (level-triggered). +*/ +#define GPIOIEV 0x020 + +/* +* Interrupt Mask. If set to 1 the interrupt is disabled (masked). If set to 0 +* the interrupt is enabled (unmasked). +*/ +#define GPIOIE 0x028
It bothered me that the datasheet used the term GPIOIE for the interrupt mask register. I had used a more verbose #define name because I worried someone reading GPIOIE in functions might mistake it for an interrupt enable register. This happened to me when I was originally working with the gpio driver.
However I suppose the best solution would have been to get the datasheet updated as I can see how it is best to have #define names in the driver match the datasheet.
Quoted 1,145 lines
drivers/pinctrl/pinctrl-starfive.c new file +1145
-0+ +/* +* Clear Edge-Triggered Interrupts. Write a 1 to clear the edge-triggered +* interrupt. +*/ +#define GPIOIC 0x030 + +/* +* Edge-Triggered Interrupt Status. A 1 means the configured edge was detected. +*/ +#define GPIORIS 0x038 + +/* +* Interrupt Status after Masking. A 1 means the configured edge or level was +* detected and not masked. +*/ +#define GPIOMIS 0x040 + +/* +* Data Value. Dynamically reflects the value of the GPIO pin. If 1 the pin is +* a digital 1 and if 0 the pin is a digital 0. +*/ +#define GPIODIN 0x048 + +/* +* From the data sheet section 12.2, there are 64 32-bit output data registers +* and 64 output enable registers. Output data and output enable registers for +* a given GPIO are contiguous. Eg. GPO0_DOUT_CFG is 0x50 and GPO0_DOEN_CFG is +* 0x54 while GPO1_DOUT_CFG is 0x58 and GPO1_DOEN_CFG is 0x5c. The stride +* between GPIO registers is effectively 8, thus: GPOn_DOUT_CFG is 0x50 + 8n +* and GPOn_DOEN_CFG is 0x54 + 8n. +*/ +#define GPON_DOUT_CFG 0x050 +#define GPON_DOEN_CFG 0x054 + +/* +* From Section 12.3, there are 75 input signal configuration registers which +* are 4 bytes wide starting with GPI_CPU_JTAG_TCK_CFG at 0x250 and ending with +* GPI_USB_OVER_CURRENT_CFG 0x378 +*/ +#define GPI_CFG_OFFSET 0x250 + +/* +* Pad Control Bits. There are 16 pad control bits for each pin located in 103 +* 32-bit registers controlling PAD_GPIO[0] to PAD_GPIO[63] followed by +* PAD_FUNC_SHARE[0] to PAD_FUNC_SHARE[141]. Odd numbered pins use the upper 16 +* bit of each register. +*/ +#define PAD_SLEW_RATE_MASK GENMASK(11, 9) +#define PAD_SLEW_RATE_POS 9 +#define PAD_BIAS_STRONG_PULL_UP BIT(8) +#define PAD_INPUT_ENABLE BIT(7) +#define PAD_INPUT_SCHMITT_ENABLE BIT(6) +#define PAD_BIAS_DISABLE BIT(5) +#define PAD_BIAS_PULL_DOWN BIT(4) +#define PAD_BIAS_MASK (PAD_BIAS_STRONG_PULL_UP | \ + PAD_BIAS_DISABLE | \ + PAD_BIAS_PULL_DOWN) +#define PAD_DRIVE_STRENGTH_MASK GENMASK(3, 0) +#define PAD_DRIVE_STRENGTH_POS 0 + +/* +* From Section 11, the IO_PADSHARE_SEL register can be programmed to select +* one of seven pre-defined multiplexed signal groups on PAD_FUNC_SHARE and +* PAD_GPIO pads. This is a global setting. +*/ +#define IO_PADSHARE_SEL 0x1a0 + +/* +* This just needs to be some number such that when +* sfp->gpio.pin_base = PAD_INVALID_GPIO then +* starfive_pin_to_gpio(sfp, validpin) is never a valid GPIO number. +* That is it should underflow and return something >= NR_GPIOS. +*/ +#define PAD_INVALID_GPIO 0x10000 + +/* +* The packed pinmux values from the device tree look like this: +* +* | 31 - 24 | 23 - 16 | 15 - 8 | 7 | 6 | 5 - 0 | +* | dout | doen | din | dout rev | doen rev | gpio nr | +* +* ..but the GPOn_DOUT_CFG and GPOn_DOEN_CFG registers look like this: +* +* | 31 | 30 - 8 | 7 - 0 | +* | dout/doen rev | unused | dout/doen | +*/ +static unsigned int starfive_pinmux_to_gpio (u32 v) +{ +return v & (NR_GPIOS -1 ); +} + +static u32 starfive_pinmux_to_dout (u32 v) +{ +return ((v &BIT (7 )) << (31 -7 )) | ((v >>24 ) &GENMASK (7 ,0 )); +} + +static u32 starfive_pinmux_to_doen (u32 v) +{ +return ((v &BIT (6 )) << (31 -6 )) | ((v >>16 ) &GENMASK (7 ,0 )); +} + +static u32 starfive_pinmux_to_din (u32 v) +{ +return (v >>8 ) &GENMASK (7 ,0 ); +} + +/* +* The maximum GPIO output current depends on the chosen drive strength: +* +* DS: 0 1 2 3 4 5 6 7 +* mA: 14.2 21.2 28.2 35.2 42.2 49.1 56.0 62.8 +* +* After rounding that is 7*DS + 14 mA +*/ +static u32 starfive_drive_strength_to_max_mA (u16 ds) +{ +return 7 * ds +14 ; +} + +static u16 starfive_drive_strength_from_max_mA (u32 i) +{ +return (clamp (i,14U ,63U ) -14 ) /7 ; +} + +struct starfive_pinctrl { +struct gpio_chip gc; +struct pinctrl_gpio_range gpios; +raw_spinlock_t lock; +void __iomem *base; +void __iomem *padctl; +struct pinctrl_dev *pctl; +}; + +static struct device *starfive_dev (const struct starfive_pinctrl *sfp) +{ +return sfp->gc.parent; +} + +static unsigned int starfive_pin_to_gpio (const struct starfive_pinctrl *sfp, +unsigned int pin) +{ +return pin - sfp->gpios.pin_base; +} + +static unsigned int starfive_gpio_to_pin (const struct starfive_pinctrl *sfp, +unsigned int gpio) +{ +return sfp->gpios.pin_base + gpio; +} + +static struct starfive_pinctrl *starfive_from_gc (struct gpio_chip *gc) +{ + return container_of(gc, struct starfive_pinctrl, gc); +} + +static struct starfive_pinctrl *starfive_from_irq_data (struct irq_data *d) +{ +return starfive_from_gc (irq_data_get_irq_chip_data (d)); +} + +static struct starfive_pinctrl *starfive_from_irq_desc (struct irq_desc *desc) +{ +return starfive_from_gc (irq_desc_get_handler_data (desc)); +} + +static const struct pinctrl_pin_desc starfive_pins[] = { +PINCTRL_PIN (PAD_GPIO (0 ),"GPIO[0]" ), +PINCTRL_PIN (PAD_GPIO (1 ),"GPIO[1]" ), +PINCTRL_PIN (PAD_GPIO (2 ),"GPIO[2]" ), +PINCTRL_PIN (PAD_GPIO (3 ),"GPIO[3]" ), +PINCTRL_PIN (PAD_GPIO (4 ),"GPIO[4]" ), +PINCTRL_PIN (PAD_GPIO (5 ),"GPIO[5]" ), +PINCTRL_PIN (PAD_GPIO (6 ),"GPIO[6]" ), +PINCTRL_PIN (PAD_GPIO (7 ),"GPIO[7]" ), +PINCTRL_PIN (PAD_GPIO (8 ),"GPIO[8]" ), +PINCTRL_PIN (PAD_GPIO (9 ),"GPIO[9]" ), +PINCTRL_PIN (PAD_GPIO (10 ),"GPIO[10]" ), +PINCTRL_PIN (PAD_GPIO (11 ),"GPIO[11]" ), +PINCTRL_PIN (PAD_GPIO (12 ),"GPIO[12]" ), +PINCTRL_PIN (PAD_GPIO (13 ),"GPIO[13]" ), +PINCTRL_PIN (PAD_GPIO (14 ),"GPIO[14]" ), +PINCTRL_PIN (PAD_GPIO (15 ),"GPIO[15]" ), +PINCTRL_PIN (PAD_GPIO (16 ),"GPIO[16]" ), +PINCTRL_PIN (PAD_GPIO (17 ),"GPIO[17]" ), +PINCTRL_PIN (PAD_GPIO (18 ),"GPIO[18]" ), +PINCTRL_PIN (PAD_GPIO (19 ),"GPIO[19]" ), +PINCTRL_PIN (PAD_GPIO (20 ),"GPIO[20]" ), +PINCTRL_PIN (PAD_GPIO (21 ),"GPIO[21]" ), +PINCTRL_PIN (PAD_GPIO (22 ),"GPIO[22]" ), +PINCTRL_PIN (PAD_GPIO (23 ),"GPIO[23]" ), +PINCTRL_PIN (PAD_GPIO (24 ),"GPIO[24]" ), +PINCTRL_PIN (PAD_GPIO (25 ),"GPIO[25]" ), +PINCTRL_PIN (PAD_GPIO (26 ),"GPIO[26]" ), +PINCTRL_PIN (PAD_GPIO (27 ),"GPIO[27]" ), +PINCTRL_PIN (PAD_GPIO (28 ),"GPIO[28]" ), +PINCTRL_PIN (PAD_GPIO (29 ),"GPIO[29]" ), +PINCTRL_PIN (PAD_GPIO (30 ),"GPIO[30]" ), +PINCTRL_PIN (PAD_GPIO (31 ),"GPIO[31]" ), +PINCTRL_PIN (PAD_GPIO (32 ),"GPIO[32]" ), +PINCTRL_PIN (PAD_GPIO (33 ),"GPIO[33]" ), +PINCTRL_PIN (PAD_GPIO (34 ),"GPIO[34]" ), +PINCTRL_PIN (PAD_GPIO (35 ),"GPIO[35]" ), +PINCTRL_PIN (PAD_GPIO (36 ),"GPIO[36]" ), +PINCTRL_PIN (PAD_GPIO (37 ),"GPIO[37]" ), +PINCTRL_PIN (PAD_GPIO (38 ),"GPIO[38]" ), +PINCTRL_PIN (PAD_GPIO (39 ),"GPIO[39]" ), +PINCTRL_PIN (PAD_GPIO (40 ),"GPIO[40]" ), +PINCTRL_PIN (PAD_GPIO (41 ),"GPIO[41]" ), +PINCTRL_PIN (PAD_GPIO (42 ),"GPIO[42]" ), +PINCTRL_PIN (PAD_GPIO (43 ),"GPIO[43]" ), +PINCTRL_PIN (PAD_GPIO (44 ),"GPIO[44]" ), +PINCTRL_PIN (PAD_GPIO (45 ),"GPIO[45]" ), +PINCTRL_PIN (PAD_GPIO (46 ),"GPIO[46]" ), +PINCTRL_PIN (PAD_GPIO (47 ),"GPIO[47]" ), +PINCTRL_PIN (PAD_GPIO (48 ),"GPIO[48]" ), +PINCTRL_PIN (PAD_GPIO (49 ),"GPIO[49]" ), +PINCTRL_PIN (PAD_GPIO (50 ),"GPIO[50]" ), +PINCTRL_PIN (PAD_GPIO (51 ),"GPIO[51]" ), +PINCTRL_PIN (PAD_GPIO (52 ),"GPIO[52]" ), +PINCTRL_PIN (PAD_GPIO (53 ),"GPIO[53]" ), +PINCTRL_PIN (PAD_GPIO (54 ),"GPIO[54]" ), +PINCTRL_PIN (PAD_GPIO (55 ),"GPIO[55]" ), +PINCTRL_PIN (PAD_GPIO (56 ),"GPIO[56]" ), +PINCTRL_PIN (PAD_GPIO (57 ),"GPIO[57]" ), +PINCTRL_PIN (PAD_GPIO (58 ),"GPIO[58]" ), +PINCTRL_PIN (PAD_GPIO (59 ),"GPIO[59]" ), +PINCTRL_PIN (PAD_GPIO (60 ),"GPIO[60]" ), +PINCTRL_PIN (PAD_GPIO (61 ),"GPIO[61]" ), +PINCTRL_PIN (PAD_GPIO (62 ),"GPIO[62]" ), +PINCTRL_PIN (PAD_GPIO (63 ),"GPIO[63]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (0 ),"FUNC_SHARE[0]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (1 ),"FUNC_SHARE[1]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (2 ),"FUNC_SHARE[2]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (3 ),"FUNC_SHARE[3]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (4 ),"FUNC_SHARE[4]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (5 ),"FUNC_SHARE[5]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (6 ),"FUNC_SHARE[6]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (7 ),"FUNC_SHARE[7]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (8 ),"FUNC_SHARE[8]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (9 ),"FUNC_SHARE[9]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (10 ),"FUNC_SHARE[10]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (11 ),"FUNC_SHARE[11]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (12 ),"FUNC_SHARE[12]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (13 ),"FUNC_SHARE[13]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (14 ),"FUNC_SHARE[14]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (15 ),"FUNC_SHARE[15]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (16 ),"FUNC_SHARE[16]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (17 ),"FUNC_SHARE[17]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (18 ),"FUNC_SHARE[18]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (19 ),"FUNC_SHARE[19]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (20 ),"FUNC_SHARE[20]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (21 ),"FUNC_SHARE[21]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (22 ),"FUNC_SHARE[22]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (23 ),"FUNC_SHARE[23]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (24 ),"FUNC_SHARE[24]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (25 ),"FUNC_SHARE[25]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (26 ),"FUNC_SHARE[26]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (27 ),"FUNC_SHARE[27]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (28 ),"FUNC_SHARE[28]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (29 ),"FUNC_SHARE[29]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (30 ),"FUNC_SHARE[30]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (31 ),"FUNC_SHARE[31]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (32 ),"FUNC_SHARE[32]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (33 ),"FUNC_SHARE[33]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (34 ),"FUNC_SHARE[34]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (35 ),"FUNC_SHARE[35]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (36 ),"FUNC_SHARE[36]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (37 ),"FUNC_SHARE[37]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (38 ),"FUNC_SHARE[38]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (39 ),"FUNC_SHARE[39]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (40 ),"FUNC_SHARE[40]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (41 ),"FUNC_SHARE[41]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (42 ),"FUNC_SHARE[42]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (43 ),"FUNC_SHARE[43]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (44 ),"FUNC_SHARE[44]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (45 ),"FUNC_SHARE[45]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (46 ),"FUNC_SHARE[46]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (47 ),"FUNC_SHARE[47]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (48 ),"FUNC_SHARE[48]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (49 ),"FUNC_SHARE[49]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (50 ),"FUNC_SHARE[50]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (51 ),"FUNC_SHARE[51]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (52 ),"FUNC_SHARE[52]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (53 ),"FUNC_SHARE[53]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (54 ),"FUNC_SHARE[54]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (55 ),"FUNC_SHARE[55]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (56 ),"FUNC_SHARE[56]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (57 ),"FUNC_SHARE[57]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (58 ),"FUNC_SHARE[58]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (59 ),"FUNC_SHARE[59]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (60 ),"FUNC_SHARE[60]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (61 ),"FUNC_SHARE[61]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (62 ),"FUNC_SHARE[62]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (63 ),"FUNC_SHARE[63]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (64 ),"FUNC_SHARE[64]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (65 ),"FUNC_SHARE[65]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (66 ),"FUNC_SHARE[66]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (67 ),"FUNC_SHARE[67]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (68 ),"FUNC_SHARE[68]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (69 ),"FUNC_SHARE[69]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (70 ),"FUNC_SHARE[70]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (71 ),"FUNC_SHARE[71]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (72 ),"FUNC_SHARE[72]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (73 ),"FUNC_SHARE[73]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (74 ),"FUNC_SHARE[74]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (75 ),"FUNC_SHARE[75]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (76 ),"FUNC_SHARE[76]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (77 ),"FUNC_SHARE[77]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (78 ),"FUNC_SHARE[78]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (79 ),"FUNC_SHARE[79]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (80 ),"FUNC_SHARE[80]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (81 ),"FUNC_SHARE[81]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (82 ),"FUNC_SHARE[82]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (83 ),"FUNC_SHARE[83]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (84 ),"FUNC_SHARE[84]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (85 ),"FUNC_SHARE[85]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (86 ),"FUNC_SHARE[86]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (87 ),"FUNC_SHARE[87]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (88 ),"FUNC_SHARE[88]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (89 ),"FUNC_SHARE[89]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (90 ),"FUNC_SHARE[90]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (91 ),"FUNC_SHARE[91]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (92 ),"FUNC_SHARE[92]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (93 ),"FUNC_SHARE[93]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (94 ),"FUNC_SHARE[94]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (95 ),"FUNC_SHARE[95]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (96 ),"FUNC_SHARE[96]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (97 ),"FUNC_SHARE[97]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (98 ),"FUNC_SHARE[98]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (99 ),"FUNC_SHARE[99]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (100 ),"FUNC_SHARE[100]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (101 ),"FUNC_SHARE[101]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (102 ),"FUNC_SHARE[102]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (103 ),"FUNC_SHARE[103]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (104 ),"FUNC_SHARE[104]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (105 ),"FUNC_SHARE[105]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (106 ),"FUNC_SHARE[106]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (107 ),"FUNC_SHARE[107]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (108 ),"FUNC_SHARE[108]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (109 ),"FUNC_SHARE[109]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (110 ),"FUNC_SHARE[110]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (111 ),"FUNC_SHARE[111]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (112 ),"FUNC_SHARE[112]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (113 ),"FUNC_SHARE[113]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (114 ),"FUNC_SHARE[114]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (115 ),"FUNC_SHARE[115]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (116 ),"FUNC_SHARE[116]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (117 ),"FUNC_SHARE[117]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (118 ),"FUNC_SHARE[118]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (119 ),"FUNC_SHARE[119]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (120 ),"FUNC_SHARE[120]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (121 ),"FUNC_SHARE[121]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (122 ),"FUNC_SHARE[122]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (123 ),"FUNC_SHARE[123]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (124 ),"FUNC_SHARE[124]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (125 ),"FUNC_SHARE[125]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (126 ),"FUNC_SHARE[126]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (127 ),"FUNC_SHARE[127]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (128 ),"FUNC_SHARE[128]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (129 ),"FUNC_SHARE[129]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (130 ),"FUNC_SHARE[130]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (131 ),"FUNC_SHARE[131]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (132 ),"FUNC_SHARE[132]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (133 ),"FUNC_SHARE[133]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (134 ),"FUNC_SHARE[134]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (135 ),"FUNC_SHARE[135]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (136 ),"FUNC_SHARE[136]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (137 ),"FUNC_SHARE[137]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (138 ),"FUNC_SHARE[138]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (139 ),"FUNC_SHARE[139]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (140 ),"FUNC_SHARE[140]" ), +PINCTRL_PIN (PAD_FUNC_SHARE (141 ),"FUNC_SHARE[141]" ), +}; + +#ifdef CONFIG_DEBUG_FS +static void starfive_pin_dbg_show (struct pinctrl_dev *pctldev, +struct seq_file *s, +unsigned int pin) +{ +struct starfive_pinctrl *sfp =pinctrl_dev_get_drvdata (pctldev); +unsigned int gpio =starfive_pin_to_gpio (sfp, pin); +void __iomem *reg; +u32 dout, doen; + +if (gpio >=NR_GPIOS ) +return ; + + reg = sfp->base +GPON_DOUT_CFG +8 * gpio; + dout =readl_relaxed (reg +0x000 ); + doen =readl_relaxed (reg +0x004 ); + +seq_printf (s,"dout=%u%s doen=%u%s" , + dout & (u32 )GENMASK (7 ,0 ), (dout &BIT (31 )) ?"r" :"" , + doen & (u32 )GENMASK (7 ,0 ), (doen &BIT (31 )) ?"r" :"" ); +} +#else +#define starfive_pin_dbg_show NULL +#endif + +static int starfive_dt_node_to_map (struct pinctrl_dev *pctldev, +struct device_node *np, +struct pinctrl_map **maps, +unsigned int *num_maps) +{ +struct starfive_pinctrl *sfp =pinctrl_dev_get_drvdata (pctldev); +struct device *dev =starfive_dev (sfp); +const char **pgnames; +struct pinctrl_map *map; +struct device_node *child; +const char *grpname; +int *pins; +u32 *pinmux; +int nmaps; +int ngroups; +int ret; + + nmaps =0 ; + ngroups =0 ; +for_each_child_of_node (np, child) { +int npinmux =of_property_count_u32_elems (child,"pinmux" ); +int npins =of_property_count_u32_elems (child,"pins" ); + +if (npinmux >0 && npins >0 ) { +dev_err (dev,"invalid pinctrl group %pOFn.%pOFn: %s\n" , + np, child,"both pinmux and pins set" ); +of_node_put (child); +return -EINVAL ; + } + +if (npinmux >0 ) { + nmaps +=2 ; + }else if (npins >0 ) { + nmaps +=1 ; + }else { +dev_err (dev,"invalid pinctrl group %pOFn.%pOFn: %s\n" , + np, child,"neither pinmux nor pins set" ); +of_node_put (child); +return -EINVAL ; + } + ngroups +=1 ; + } + + ret = -ENOMEM ; + pgnames =devm_kcalloc (dev, ngroups,sizeof (*pgnames),GFP_KERNEL ); +if (!pgnames) +return ret; + + map =kcalloc (nmaps,sizeof (*map),GFP_KERNEL ); +if (!map) + goto free_pgnames; + + nmaps =0 ; + ngroups =0 ; +for_each_child_of_node (np, child) { +int npins; +int i; + + ret = -ENOMEM ; + grpname =devm_kasprintf (dev,GFP_KERNEL ,"%s.%s" , np->name, child->name); +if (!grpname) + goto put_child; + + pgnames[ngroups++] = grpname; + +if ((npins =of_property_count_u32_elems (child,"pinmux" )) >0 ) { + pins =devm_kcalloc (dev, npins,sizeof (*pins),GFP_KERNEL ); +if (!pins) + goto free_grpname; + + pinmux =devm_kcalloc (dev, npins,sizeof (*pinmux),GFP_KERNEL ); +if (!pinmux) + goto free_pins; + +for (i =0 ; i < npins; i++) { +u32 v; + + ret =of_property_read_u32_index (child,"pinmux" , i, &v); +if (ret) + goto free_pinmux; + pins[i] =starfive_gpio_to_pin (sfp,starfive_pinmux_to_gpio (v)); + pinmux[i] = v; + } + + map[nmaps].type =PIN_MAP_TYPE_MUX_GROUP ; + map[nmaps].data.mux.function = np->name; + map[nmaps].data.mux.group = grpname; + nmaps +=1 ; + }else if ((npins =of_property_count_u32_elems (child,"pins" )) >0 ) { + pins =devm_kcalloc (dev, npins,sizeof (*pins),GFP_KERNEL ); +if (!pins) + goto free_grpname; + + pinmux =NULL ; + +for (i =0 ; i < npins; i++) { +u32 v; + + ret =of_property_read_u32_index (child,"pins" , i, &v); +if (ret) + goto free_pins; + pins[i] = v; + } + }else { + ret = -EINVAL ; + goto free_grpname; + } + + ret =pinctrl_generic_add_group (pctldev, grpname, pins, npins, pinmux); +if (ret <0 ) { +dev_err (dev,"error adding group %pOFn.%pOFn: %d\n" , + np, child, ret); + goto free_pinmux; + } + + ret =pinconf_generic_parse_dt_config (child, pctldev, + &map[nmaps].data.configs.configs, + &map[nmaps].data.configs.num_configs); +if (ret) { +dev_err (dev,"invalid pinctrl group %pOFn.%pOFn: %s\n" , + np, child,"error parsing pin config" ); + goto put_child; + } + +/* don't create a map if there are no pinconf settings */ +if (map[nmaps].data.configs.num_configs ==0 ) +continue ; + + map[nmaps].type =PIN_MAP_TYPE_CONFIGS_GROUP ; + map[nmaps].data.configs.group_or_pin = grpname; + nmaps +=1 ; + } + + ret =pinmux_generic_add_function (pctldev, np->name, pgnames, ngroups,NULL ); +if (ret <0 ) { +dev_err (dev,"error adding function %pOFn: %d\n" , np, ret); + goto free_map; + } + + *maps = map; + *num_maps = nmaps; +return 0 ; + +free_pinmux: +devm_kfree (dev, pinmux); +free_pins: +devm_kfree (dev, pins); +free_grpname: +devm_kfree (dev, grpname); +put_child: +of_node_put (child); +free_map: +pinctrl_utils_free_map (pctldev, map, nmaps); +free_pgnames: +devm_kfree (dev, pgnames); +return ret; +} + +static const struct pinctrl_ops starfive_pinctrl_ops = { + .get_groups_count = pinctrl_generic_get_group_count, + .get_group_name = pinctrl_generic_get_group_name, + .get_group_pins = pinctrl_generic_get_group_pins, + .pin_dbg_show = starfive_pin_dbg_show, + .dt_node_to_map = starfive_dt_node_to_map, + .dt_free_map = pinctrl_utils_free_map, +}; + +static int starfive_set_mux (struct pinctrl_dev *pctldev, +unsigned int fsel,unsigned int gsel) +{ +struct starfive_pinctrl *sfp =pinctrl_dev_get_drvdata (pctldev); +struct device *dev =starfive_dev (sfp); +const struct group_desc *group; +const u32 *pinmux; +unsigned int i; + + group =pinctrl_generic_get_group (pctldev, gsel); +if (!group) +return -EINVAL ; + + pinmux = group->data; +for (i =0 ; i < group->num_pins; i++) { +u32 v = pinmux[i]; +unsigned int gpio =starfive_pinmux_to_gpio (v); +u32 dout =starfive_pinmux_to_dout (v); +u32 doen =starfive_pinmux_to_doen (v); +u32 din =starfive_pinmux_to_din (v); +void __iomem *reg_dout; +void __iomem *reg_doen; +void __iomem *reg_din; +unsigned long flags; + +dev_dbg (dev,"GPIO%u: dout=0x%x doen=0x%x din=0x%x\n" , + gpio, dout, doen, din); + + reg_dout = sfp->base +GPON_DOUT_CFG +8 * gpio; + reg_doen = sfp->base +GPON_DOEN_CFG +8 * gpio; +if (din !=GPI_NONE ) + reg_din = sfp->base +GPI_CFG_OFFSET +4 * din; +else + reg_din =NULL ; + +raw_spin_lock_irqsave (&sfp->lock, flags); +writel_relaxed (dout, reg_dout); +writel_relaxed (doen, reg_doen); +if (reg_din) +writel_relaxed (gpio +2 , reg_din); +raw_spin_unlock_irqrestore (&sfp->lock, flags); + } + +return 0 ; +} + +static const struct pinmux_ops starfive_pinmux_ops = { + .get_functions_count = pinmux_generic_get_function_count, + .get_function_name = pinmux_generic_get_function_name, + .get_function_groups = pinmux_generic_get_function_groups, + .set_mux = starfive_set_mux, + .strict = true, +}; + +static u16 starfive_padctl_get (struct starfive_pinctrl *sfp, +unsigned int pin) +{ +void __iomem *reg = sfp->padctl +4 * (pin /2 ); +int shift =16 * (pin %2 ); + +return readl_relaxed (reg) >> shift; +} + +static void starfive_padctl_rmw (struct starfive_pinctrl *sfp, +unsigned int pin, +u16 _mask,u16 _value) +{ +void __iomem *reg = sfp->padctl +4 * (pin /2 ); +int shift =16 * (pin %2 ); +u32 mask = (u32 )_mask << shift; +u32 value = (u32 )_value << shift; +unsigned long flags; + +dev_dbg (starfive_dev (sfp), +"padctl_rmw(%u, 0x%03x, 0x%03x)\n" , pin, _mask, _value); + +raw_spin_lock_irqsave (&sfp->lock, flags); + value |=readl_relaxed (reg) & ~mask; +writel_relaxed (value, reg); +raw_spin_unlock_irqrestore (&sfp->lock, flags); +} + +#define PIN_CONFIG_STARFIVE_STRONG_PULL_UP (PIN_CONFIG_END + 1) + +static const struct pinconf_generic_params starfive_pinconf_custom_params[] = { + {"starfive,strong-pull-up" ,PIN_CONFIG_STARFIVE_STRONG_PULL_UP ,1 }, +}; + +#ifdef CONFIG_DEBUG_FS +static const struct pin_config_item starfive_pinconf_custom_conf_items[] = { +PCONFDUMP (PIN_CONFIG_STARFIVE_STRONG_PULL_UP ,"input bias strong pull-up" ,NULL , false), +}; + +static_assert (ARRAY_SIZE (starfive_pinconf_custom_conf_items) == +ARRAY_SIZE (starfive_pinconf_custom_params)); +#else +#define starfive_pinconf_custom_conf_items NULL +#endif + +static int starfive_pinconf_get (struct pinctrl_dev *pctldev, +unsigned int pin,unsigned long *config) +{ +struct starfive_pinctrl *sfp =pinctrl_dev_get_drvdata (pctldev); +u16 value =starfive_padctl_get (sfp, pin); +int param =pinconf_to_config_param (*config); +u32 arg; +bool enabled; + +switch (param) { +case PIN_CONFIG_BIAS_DISABLE : + enabled = value &PAD_BIAS_DISABLE ; + arg =0 ; +break ; +case PIN_CONFIG_BIAS_PULL_DOWN : + enabled = value &PAD_BIAS_PULL_DOWN ; + arg =1 ; +break ; +case PIN_CONFIG_BIAS_PULL_UP : + enabled = !(value &PAD_BIAS_MASK ); + arg =1 ; +break ; +case PIN_CONFIG_DRIVE_STRENGTH : + enabled = value &PAD_DRIVE_STRENGTH_MASK ; + arg =starfive_drive_strength_to_max_mA (value &PAD_DRIVE_STRENGTH_MASK ); +break ; +case PIN_CONFIG_INPUT_ENABLE : + enabled = value &PAD_INPUT_ENABLE ; + arg = enabled; +break ; +case PIN_CONFIG_INPUT_SCHMITT_ENABLE : + enabled = value &PAD_INPUT_SCHMITT_ENABLE ; + arg = enabled; +break ; +case PIN_CONFIG_SLEW_RATE : + enabled = value &PAD_SLEW_RATE_MASK ; + arg = (value &PAD_SLEW_RATE_MASK ) >>PAD_SLEW_RATE_POS ; +break ; +case PIN_CONFIG_STARFIVE_STRONG_PULL_UP : + enabled = value &PAD_BIAS_STRONG_PULL_UP ; + arg = enabled; +break ; +default : +return -ENOTSUPP ; + } + + *config =pinconf_to_config_packed (param, arg); +return enabled ?0 : -EINVAL ; +} + +static int starfive_pinconf_group_get (struct pinctrl_dev *pctldev, +unsigned int gsel,unsigned long *config) +{ +const struct group_desc *group; + + group =pinctrl_generic_get_group (pctldev, gsel); +if (!group) +return -EINVAL ; + +return starfive_pinconf_get (pctldev, group->pins[0 ], config); +} + +static int starfive_pinconf_group_set (struct pinctrl_dev *pctldev, +unsigned int gsel, +unsigned long *configs, +unsigned int num_configs) +{ +struct starfive_pinctrl *sfp =pinctrl_dev_get_drvdata (pctldev); +const struct group_desc *group; +u16 mask, value; +int i; + + group =pinctrl_generic_get_group (pctldev, gsel); +if (!group) +return -EINVAL ; + + mask =0 ; + value =0 ; +for (i =0 ; i < num_configs; i++) { +int param =pinconf_to_config_param (configs[i]); +u32 arg =pinconf_to_config_argument (configs[i]); + +switch (param) { +case PIN_CONFIG_BIAS_DISABLE : + mask |=PAD_BIAS_MASK ; + value = (value & ~PAD_BIAS_MASK ) |PAD_BIAS_DISABLE ; +break ; +case PIN_CONFIG_BIAS_PULL_DOWN : +if (arg ==0 ) +return -ENOTSUPP ; + mask |=PAD_BIAS_MASK ; + value = (value & ~PAD_BIAS_MASK ) |PAD_BIAS_PULL_DOWN ; +break ; +case PIN_CONFIG_BIAS_PULL_UP : +if (arg ==0 ) +return -ENOTSUPP ; + mask |=PAD_BIAS_MASK ; + value = value & ~PAD_BIAS_MASK ; +break ; +case PIN_CONFIG_DRIVE_STRENGTH : + mask |=PAD_DRIVE_STRENGTH_MASK ; + value = (value & ~PAD_DRIVE_STRENGTH_MASK ) | +starfive_drive_strength_from_max_mA (arg); +break ; +case PIN_CONFIG_INPUT_ENABLE : + mask |=PAD_INPUT_ENABLE ; +if (arg) + value |=PAD_INPUT_ENABLE ; +else + value &= ~PAD_INPUT_ENABLE ; +break ; +case PIN_CONFIG_INPUT_SCHMITT_ENABLE : + mask |=PAD_INPUT_SCHMITT_ENABLE ; +if (arg) + value |=PAD_INPUT_SCHMITT_ENABLE ; +else + value &= ~PAD_INPUT_SCHMITT_ENABLE ; +break ; +case PIN_CONFIG_SLEW_RATE : + mask |=PAD_SLEW_RATE_MASK ; + value = (value & ~PAD_SLEW_RATE_MASK ) | + ((arg <<PAD_SLEW_RATE_POS ) &PAD_SLEW_RATE_MASK ); +break ; +case PIN_CONFIG_STARFIVE_STRONG_PULL_UP : +if (arg) { + mask |=PAD_BIAS_MASK ; + value = (value & ~PAD_BIAS_MASK ) | +PAD_BIAS_STRONG_PULL_UP ; + }else { + mask |=PAD_BIAS_STRONG_PULL_UP ; + value = value & ~PAD_BIAS_STRONG_PULL_UP ; + } +break ; +default : +return -ENOTSUPP ; + } + } + +for (i =0 ; i < group->num_pins; i++) +starfive_padctl_rmw (sfp, group->pins[i], mask, value); + +return 0 ; +} + +#ifdef CONFIG_DEBUG_FS +static void starfive_pinconf_dbg_show (struct pinctrl_dev *pctldev, +struct seq_file *s,unsigned int pin) +{ +struct starfive_pinctrl *sfp =pinctrl_dev_get_drvdata (pctldev); +u16 value =starfive_padctl_get (sfp, pin); + +seq_printf (s," (0x%03x)" , value); +} +#else +#define starfive_pinconf_dbg_show NULL +#endif + +static const struct pinconf_ops starfive_pinconf_ops = { + .pin_config_get = starfive_pinconf_get, + .pin_config_group_get = starfive_pinconf_group_get, + .pin_config_group_set = starfive_pinconf_group_set, + .pin_config_dbg_show = starfive_pinconf_dbg_show, + .is_generic = true, +}; + +static struct pinctrl_desc starfive_desc = { + .name =DRIVER_NAME , + .pins = starfive_pins, + .npins =ARRAY_SIZE (starfive_pins), + .pctlops = &starfive_pinctrl_ops, + .pmxops = &starfive_pinmux_ops, + .confops = &starfive_pinconf_ops, + .owner =THIS_MODULE , + .num_custom_params =ARRAY_SIZE (starfive_pinconf_custom_params), + .custom_params = starfive_pinconf_custom_params, + .custom_conf_items = starfive_pinconf_custom_conf_items, +}; + +static int starfive_gpio_request (struct gpio_chip *gc,unsigned int gpio) +{ +return pinctrl_gpio_request (gc->base + gpio); +} + +static void starfive_gpio_free (struct gpio_chip *gc,unsigned int gpio) +{ +pinctrl_gpio_free (gc->base + gpio); +} + +static int starfive_gpio_get_direction (struct gpio_chip *gc,unsigned int gpio) +{ +struct starfive_pinctrl *sfp =starfive_from_gc (gc); + +if (gpio >=NR_GPIOS ) +return -EINVAL ; + +/* return GPIO_LINE_DIRECTION_OUT (0) only if doen == GPO_ENABLE (0) */ +return readl_relaxed (sfp->base +GPON_DOEN_CFG +8 * gpio) !=GPO_ENABLE ; +} + +static int starfive_gpio_direction_input (struct gpio_chip *gc, +unsigned int gpio) +{ +struct starfive_pinctrl *sfp =starfive_from_gc (gc); +void __iomem *doen; +unsigned long flags; + +if (gpio >=NR_GPIOS ) +return -EINVAL ; + +/* enable input and schmitt trigger */ +starfive_padctl_rmw (sfp,starfive_gpio_to_pin (sfp, gpio), +PAD_INPUT_ENABLE |PAD_INPUT_SCHMITT_ENABLE , +PAD_INPUT_ENABLE |PAD_INPUT_SCHMITT_ENABLE ); + + doen = sfp->base +GPON_DOEN_CFG +8 * gpio; +raw_spin_lock_irqsave (&sfp->lock, flags); +writel_relaxed (GPO_DISABLE , doen); +raw_spin_unlock_irqrestore (&sfp->lock, flags); +return 0 ; +} + +static int starfive_gpio_direction_output (struct gpio_chip *gc, +unsigned int gpio,int value) +{ +struct starfive_pinctrl *sfp =starfive_from_gc (gc); +void __iomem *dout; +void __iomem *doen; +unsigned long flags; + +if (gpio >=NR_GPIOS ) +return -EINVAL ; + + dout = sfp->base +GPON_DOUT_CFG +8 * gpio; + doen = sfp->base +GPON_DOEN_CFG +8 * gpio; +raw_spin_lock_irqsave (&sfp->lock, flags); +writel_relaxed (value, dout); +writel_relaxed (GPO_ENABLE , doen); +raw_spin_unlock_irqrestore (&sfp->lock, flags); + +/* disable input, schmitt trigger and bias */ +starfive_padctl_rmw (sfp,starfive_gpio_to_pin (sfp, gpio), +PAD_BIAS_MASK |PAD_INPUT_ENABLE |PAD_INPUT_SCHMITT_ENABLE , +PAD_BIAS_DISABLE ); + +return 0 ; +} + +static int starfive_gpio_get (struct gpio_chip *gc,unsigned int gpio) +{ +struct starfive_pinctrl *sfp =starfive_from_gc (gc); +void __iomem *din; + +if (gpio >=NR_GPIOS ) +return -EINVAL ; + + din = sfp->base +GPIODIN +4 * (gpio /32 ); +return !!(readl_relaxed (din) &BIT (gpio %32 )); +} + +static void starfive_gpio_set (struct gpio_chip *gc,unsigned int gpio, +int value) +{ +struct starfive_pinctrl *sfp =starfive_from_gc (gc); +void __iomem *dout; +unsigned long flags; + +if (gpio >=NR_GPIOS ) +return ; + + dout = sfp->base +GPON_DOUT_CFG +8 * gpio; +raw_spin_lock_irqsave (&sfp->lock, flags); +writel_relaxed (value, dout); +raw_spin_unlock_irqrestore (&sfp->lock, flags); +} + +static int starfive_gpio_set_config (struct gpio_chip *gc,unsigned int gpio, +unsigned long config) +{ +struct starfive_pinctrl *sfp =starfive_from_gc (gc); +u32 arg =pinconf_to_config_argument (config); +u16 mask; +u16 value; + +switch (pinconf_to_config_param (config)) { +case PIN_CONFIG_BIAS_DISABLE : + mask =PAD_BIAS_MASK ; + value =PAD_BIAS_DISABLE ; +break ; +case PIN_CONFIG_BIAS_PULL_DOWN : +if (arg ==0 ) +return -ENOTSUPP ; + mask =PAD_BIAS_MASK ; + value =PAD_BIAS_PULL_DOWN ; +break ; +case PIN_CONFIG_BIAS_PULL_UP : +if (arg ==0 ) +return -ENOTSUPP ; + mask =PAD_BIAS_MASK ; + value =0 ; +break ; +case PIN_CONFIG_DRIVE_PUSH_PULL : +return 0 ; +case PIN_CONFIG_INPUT_ENABLE : + mask =PAD_INPUT_ENABLE ; + value = arg ?PAD_INPUT_ENABLE :0 ; +break ; +case PIN_CONFIG_INPUT_SCHMITT_ENABLE : + mask =PAD_INPUT_SCHMITT_ENABLE ; + value = arg ?PAD_INPUT_SCHMITT_ENABLE :0 ; +break ; +default : +return -ENOTSUPP ; + }; + +starfive_padctl_rmw (sfp,starfive_gpio_to_pin (sfp, gpio), mask, value); +return 0 ; +} + +static int starfive_gpio_add_pin_ranges (struct gpio_chip *gc) +{ +struct starfive_pinctrl *sfp =starfive_from_gc (gc); + + sfp->gpios.name = sfp->gc.label; + sfp->gpios.base = sfp->gc.base; +/* +* sfp->gpios.pin_base depends on the chosen signal group +* and is set in starfive_probe() +*/ + sfp->gpios.npins =NR_GPIOS ; + sfp->gpios.gc = &sfp->gc; +pinctrl_add_gpio_range (sfp->pctl, &sfp->gpios); +return 0 ; +} + +static void starfive_irq_ack (struct irq_data *d) +{ +struct starfive_pinctrl *sfp =starfive_from_irq_data (d); +irq_hw_number_t gpio =irqd_to_hwirq (d); +void __iomem *ic = sfp->base +GPIOIC +4 * (gpio /32 ); +u32 mask =BIT (gpio %32 ); +unsigned long flags; + +raw_spin_lock_irqsave (&sfp->lock, flags); +writel_relaxed (mask, ic); +raw_spin_unlock_irqrestore (&sfp->lock, flags); +} + +static void starfive_irq_mask (struct irq_data *d) +{ +struct starfive_pinctrl *sfp =starfive_from_irq_data (d); +irq_hw_number_t gpio =irqd_to_hwirq (d); +void __iomem *ie = sfp->base +GPIOIE +4 * (gpio /32 ); +u32 mask =BIT (gpio %32 ); +unsigned long flags; +u32 value; + +raw_spin_lock_irqsave (&sfp->lock, flags); + value =readl_relaxed (ie) & ~mask; +writel_relaxed (value, ie); +raw_spin_unlock_irqrestore (&sfp->lock, flags); +} + +static void starfive_irq_mask_ack (struct irq_data *d) +{ +struct starfive_pinctrl *sfp =starfive_from_irq_data (d); +irq_hw_number_t gpio =irqd_to_hwirq (d); +void __iomem *ie = sfp->base +GPIOIE +4 * (gpio /32 ); +void __iomem *ic = sfp->base +GPIOIC +4 * (gpio /32 ); +u32 mask =BIT (gpio %32 ); +unsigned long flags; +u32 value; + +raw_spin_lock_irqsave (&sfp->lock, flags); + value =readl_relaxed (ie) & ~mask; +writel_relaxed (value, ie); +writel_relaxed (mask, ic); +raw_spin_unlock_irqrestore (&sfp->lock, flags); +} + +static void starfive_irq_unmask (struct irq_data *d) +{ +struct starfive_pinctrl *sfp =starfive_from_irq_data (d); +irq_hw_number_t gpio =irqd_to_hwirq (d); +void __iomem *ie = sfp->base +GPIOIE +4 * (gpio /32 ); +u32 mask =BIT (gpio %32 ); +unsigned long flags; +u32 value; + +raw_spin_lock_irqsave (&sfp->lock, flags); + value =readl_relaxed (ie) | mask; +writel_relaxed (value, ie); +raw_spin_unlock_irqrestore (&sfp->lock, flags); +} + +static int starfive_irq_set_type (struct irq_data *d,unsigned int trigger) +{ +struct starfive_pinctrl *sfp =starfive_from_irq_data (d); +irq_hw_number_t gpio =irqd_to_hwirq (d); +void __iomem *base = sfp->base +4 * (gpio /32 ); +u32 mask =BIT (gpio %32 ); +u32 irq_type, edge_both, polarity; +irq_flow_handler_t handler; +unsigned long flags; + +switch (trigger) { +case IRQ_TYPE_EDGE_RISING : + irq_type = mask;/* 1: edge triggered */ + edge_both =0 ;/* 0: single edge */ + polarity = mask;/* 1: rising edge */ + handler = handle_edge_irq; +break ; +case IRQ_TYPE_EDGE_FALLING : + irq_type = mask;/* 1: edge triggered */ + edge_both =0 ;/* 0: single edge */ + polarity =0 ;/* 0: falling edge */ + handler = handle_edge_irq; +break ; +case IRQ_TYPE_EDGE_BOTH : + irq_type = mask;/* 1: edge triggered */ + edge_both = mask;/* 1: both edges */ + polarity =0 ;/* 0: ignored */ + handler = handle_edge_irq; +break ; +case IRQ_TYPE_LEVEL_HIGH : + irq_type =0 ;/* 0: level triggered */ + edge_both =0 ;/* 0: ignored */ + polarity = mask;/* 1: high level */ + handler = handle_level_irq; +break ; +case IRQ_TYPE_LEVEL_LOW : + irq_type =0 ;/* 0: level triggered */ + edge_both =0 ;/* 0: ignored */ + polarity =0 ;/* 0: low level */ + handler = handle_level_irq; +break ; +default : +irq_set_handler_locked (d, handle_bad_irq); +return -EINVAL ; + } + +irq_set_handler_locked (d, handler); + +raw_spin_lock_irqsave (&sfp->lock, flags); + irq_type |=readl_relaxed (base +GPIOIS ) & ~mask; +writel_relaxed (irq_type, base +GPIOIS ); + edge_both |=readl_relaxed (base +GPIOIBE ) & ~mask; +writel_relaxed (edge_both, base +GPIOIBE ); + polarity |=readl_relaxed (base +GPIOIEV ) & ~mask; +writel_relaxed (polarity, base +GPIOIEV ); +raw_spin_unlock_irqrestore (&sfp->lock, flags); +return 0 ; +} + +static struct irq_chip starfive_irq_chip = { + .irq_ack = starfive_irq_ack, + .irq_mask = starfive_irq_mask, + .irq_mask_ack = starfive_irq_mask_ack, + .irq_unmask = starfive_irq_unmask, + .irq_set_type = starfive_irq_set_type, + .flags =IRQCHIP_SET_TYPE_MASKED , +}; + +static void starfive_gpio_irq_handler (struct irq_desc *desc) +{ +struct starfive_pinctrl *sfp =starfive_from_irq_desc (desc); +struct irq_chip *chip =irq_desc_get_chip (desc); +unsigned long mis; +unsigned int pin; + +chained_irq_enter (chip, desc); + + mis =readl_relaxed (sfp->base +GPIOMIS +0 ); +for_each_set_bit (pin, &mis,32 ) +generic_handle_domain_irq (sfp->gc.irq.domain, pin); + + mis =readl_relaxed (sfp->base +GPIOMIS +4 ); +for_each_set_bit (pin, &mis,32 ) +generic_handle_domain_irq (sfp->gc.irq.domain, pin +32 ); +
drivers/pinctrl/pinctrl-starfive.c line 1230
Quoted 10 lines
drivers/pinctrl/pinctrl-starfive.c new file +10
-0+chained_irq_exit (chip, desc); +} + +static int starfive_gpio_init_hw (struct gpio_chip *gc) +{ +struct starfive_pinctrl *sfp =starfive_from_gc (gc); + +/* mask all GPIO interrupts */ +writel (0 , sfp->base +GPIOIE +0 ); +writel (0 , sfp->base +GPIOIE +4 );
Woudln't 0 in GPIOIE mean mask is disabled for all interrupts?
In other words, wouldn't this enable all the interrupts?
Thanks,
Drew
Emil Renner Berthing
maintainerRe: [PATCH v2 12/16] pinctrl: starfive: Add pinctrl driver for StarFive SoCs
Quoted 72 lines · Drew Fustini
drivers/pinctrl/pinctrl-starfive.c line 75
Quoted 13 lines · Emil Renner Berthing
drivers/pinctrl/pinctrl-starfive.c new file +13
-0+/* +* Interrupt Trigger Polarity. If set to 1 the interrupt is triggered on a +* rising edge (edge-triggered) or high level (level-triggered). If set to 0 the +* interrupt is triggered on a falling edge (edge-triggered) or low level +* (level-triggered). +*/ +#define GPIOIEV 0x020 + +/* +* Interrupt Mask. If set to 1 the interrupt is disabled (masked). If set to 0 +* the interrupt is enabled (unmasked). +*/ +#define GPIOIE 0x028It bothered me that the datasheet used the term GPIOIE for the interrupt mask register. I had used a more verbose #define name because I worried someone reading GPIOIE in functions might mistake it for an interrupt enable register. This happened to me when I was originally working with the gpio driver.
However I suppose the best solution would have been to get the datasheet updated as I can see how it is best to have #define names in the driver match the datasheet.
Quoted 47 lines
drivers/pinctrl/pinctrl-starfive.c new file +47
-0+static void starfive_irq_mask (struct irq_data *d) +{ +struct starfive_pinctrl *sfp =starfive_from_irq_data (d); +irq_hw_number_t gpio =irqd_to_hwirq (d); +void __iomem *ie = sfp->base +GPIOIE +4 * (gpio /32 ); +u32 mask =BIT (gpio %32 ); +unsigned long flags; +u32 value; + +raw_spin_lock_irqsave (&sfp->lock, flags); + value =readl_relaxed (ie) & ~mask; +writel_relaxed (value, ie); +raw_spin_unlock_irqrestore (&sfp->lock, flags); +} + +static void starfive_irq_mask_ack (struct irq_data *d) +{ +struct starfive_pinctrl *sfp =starfive_from_irq_data (d); +irq_hw_number_t gpio =irqd_to_hwirq (d); +void __iomem *ie = sfp->base +GPIOIE +4 * (gpio /32 ); +void __iomem *ic = sfp->base +GPIOIC +4 * (gpio /32 ); +u32 mask =BIT (gpio %32 ); +unsigned long flags; +u32 value; + +raw_spin_lock_irqsave (&sfp->lock, flags); + value =readl_relaxed (ie) & ~mask; +writel_relaxed (value, ie); +writel_relaxed (mask, ic); +raw_spin_unlock_irqrestore (&sfp->lock, flags); +} + +static void starfive_irq_unmask (struct irq_data *d) +{ +struct starfive_pinctrl *sfp =starfive_from_irq_data (d); +irq_hw_number_t gpio =irqd_to_hwirq (d); +void __iomem *ie = sfp->base +GPIOIE +4 * (gpio /32 ); +u32 mask =BIT (gpio %32 ); +unsigned long flags; +u32 value; + +raw_spin_lock_irqsave (&sfp->lock, flags); + value =readl_relaxed (ie) | mask; +writel_relaxed (value, ie); +raw_spin_unlock_irqrestore (&sfp->lock, flags); +} +
...
Quoted 11 lines
drivers/pinctrl/pinctrl-starfive.c line 1230
Quoted 7 lines
drivers/pinctrl/pinctrl-starfive.c new file +7
-0+static int starfive_gpio_init_hw (struct gpio_chip *gc) +{ +struct starfive_pinctrl *sfp =starfive_from_gc (gc); + +/* mask all GPIO interrupts */ +writel (0 , sfp->base +GPIOIE +0 ); +writel (0 , sfp->base +GPIOIE +4 );Woudln't 0 in GPIOIE mean mask is disabled for all interrupts?
In other words, wouldn't this enable all the interrupts?
Heh, you're right. The code does the exact opposite of what the documentation says it should be doing. However I just tried and with the code as it is now GPIO interrupts work fine, but with the logic flipped the kernel fails to boot. I'm guessing because an interrupt storm. So it seems to me the documentation might be wrong and GPIOIE is actually a good name.
Michael Zhu: Can you confirm if a 1 or 0 enables the interrupt in the GPIOIE registers?
/Emil
Re: [PATCH v2 12/16] pinctrl: starfive: Add pinctrl driver for StarFive SoCs
Quoted 86 lines · Emil Renner Berthing
Quoted 72 lines · Drew Fustini
drivers/pinctrl/pinctrl-starfive.c line 75
Quoted 13 lines · Emil Renner Berthing
drivers/pinctrl/pinctrl-starfive.c new file +13
-0+/* +* Interrupt Trigger Polarity. If set to 1 the interrupt is triggered on a +* rising edge (edge-triggered) or high level (level-triggered). If set to 0 the +* interrupt is triggered on a falling edge (edge-triggered) or low level +* (level-triggered). +*/ +#define GPIOIEV 0x020 + +/* +* Interrupt Mask. If set to 1 the interrupt is disabled (masked). If set to 0 +* the interrupt is enabled (unmasked). +*/ +#define GPIOIE 0x028It bothered me that the datasheet used the term GPIOIE for the interrupt mask register. I had used a more verbose #define name because I worried someone reading GPIOIE in functions might mistake it for an interrupt enable register. This happened to me when I was originally working with the gpio driver.
However I suppose the best solution would have been to get the datasheet updated as I can see how it is best to have #define names in the driver match the datasheet.
Quoted 47 lines
drivers/pinctrl/pinctrl-starfive.c new file +47
-0+static void starfive_irq_mask (struct irq_data *d) +{ +struct starfive_pinctrl *sfp =starfive_from_irq_data (d); +irq_hw_number_t gpio =irqd_to_hwirq (d); +void __iomem *ie = sfp->base +GPIOIE +4 * (gpio /32 ); +u32 mask =BIT (gpio %32 ); +unsigned long flags; +u32 value; + +raw_spin_lock_irqsave (&sfp->lock, flags); + value =readl_relaxed (ie) & ~mask; +writel_relaxed (value, ie); +raw_spin_unlock_irqrestore (&sfp->lock, flags); +} + +static void starfive_irq_mask_ack (struct irq_data *d) +{ +struct starfive_pinctrl *sfp =starfive_from_irq_data (d); +irq_hw_number_t gpio =irqd_to_hwirq (d); +void __iomem *ie = sfp->base +GPIOIE +4 * (gpio /32 ); +void __iomem *ic = sfp->base +GPIOIC +4 * (gpio /32 ); +u32 mask =BIT (gpio %32 ); +unsigned long flags; +u32 value; + +raw_spin_lock_irqsave (&sfp->lock, flags); + value =readl_relaxed (ie) & ~mask; +writel_relaxed (value, ie); +writel_relaxed (mask, ic); +raw_spin_unlock_irqrestore (&sfp->lock, flags); +} + +static void starfive_irq_unmask (struct irq_data *d) +{ +struct starfive_pinctrl *sfp =starfive_from_irq_data (d); +irq_hw_number_t gpio =irqd_to_hwirq (d); +void __iomem *ie = sfp->base +GPIOIE +4 * (gpio /32 ); +u32 mask =BIT (gpio %32 ); +unsigned long flags; +u32 value; + +raw_spin_lock_irqsave (&sfp->lock, flags); + value =readl_relaxed (ie) | mask; +writel_relaxed (value, ie); +raw_spin_unlock_irqrestore (&sfp->lock, flags); +} +...
Quoted 10 lines
drivers/pinctrl/pinctrl-starfive.c line 1230
Quoted 7 lines
drivers/pinctrl/pinctrl-starfive.c new file +7
-0+static int starfive_gpio_init_hw (struct gpio_chip *gc) +{ +struct starfive_pinctrl *sfp =starfive_from_gc (gc); + +/* mask all GPIO interrupts */ +writel (0 , sfp->base +GPIOIE +0 ); +writel (0 , sfp->base +GPIOIE +4 );Woudln't 0 in GPIOIE mean mask is disabled for all interrupts?
Quoted 8 lines
Quoted 1 line
In other words, wouldn't this enable all the interrupts?
Heh, you're right. The code does the exact opposite of what the documentation says it should be doing. However I just tried and with the code as it is now GPIO interrupts work fine, but with the logic flipped the kernel fails to boot. I'm guessing because an interrupt storm. So it seems to me the documentation might be wrong and GPIOIE is actually a good name.
Ah, it seems I once knew this back in July [1] but never got the documentation changed:
NOTE: Table 12-9 in the JH7100 datasheet is incorrect regarding fields GPIOIE_0 and GPIOIE_1. An interrupt is enabled (unmasked) when the bit
is set to 1 and it is disabled (masked) when set to 0. The datasheet
incorrectly states the opposite. I think this is due to the datasheet author thinking of it as mask field which it is not, it is an enable field. I will raise an issue on the documentation repo.
Quoted 5 lines
Michael Zhu: Can you confirm if a 1 or 0 enables the interrupt in the GPIOIE registers?
/Emil
[1] https://github.com/esmil/linux/pull/34/commits/e247a259e40312d0202cdbdd686dbba09afc7813
Re: [PATCH v2 12/16] pinctrl: starfive: Add pinctrl driver for StarFive SoCs
In reply to Emil Renner BerthingQuoted 8 lines · Emil Renner Berthing
Add a combined pinctrl and GPIO driver for the StarFive JH7100 SoC.
For each "GPIO" there are two registers for configuring the output and output enable signals which may come from other peripherals. Among these are two special signals that are constant 0 and constant 1 respectively. Controlling the GPIOs from software is done by choosing one of these signals. In other words the same registers are used for both pinmuxing
pin muxing
Quoted 6 lines
and controlling the GPIOs, which makes it easier to combine the pinctrl and GPIO driver in one.
I wrote the pinconf and pinmux parts, but the GPIO part of the code is based on the GPIO driver in the vendor tree written by Huan Feng with cleanups and fixes by Drew and me.
...
drivers/pinctrl/pinctrl-starfive.c line 133
Quoted 3 lines
drivers/pinctrl/pinctrl-starfive.c new file +3
-0+#define PAD_BIAS_MASK (PAD_BIAS_STRONG_PULL_UP | \ + PAD_BIAS_DISABLE | \ + PAD_BIAS_PULL_DOWN)
It's slightly better looking if the value is begins on the next line
#define PAD_BIAS_MASK \
(PAD_BIAS_STRONG_PULL_UP | \
PAD_BIAS_DISABLE | \
PAD_BIAS_PULL_DOWN)...
drivers/pinctrl/pinctrl-starfive.c line 470
Quoted 3 lines
drivers/pinctrl/pinctrl-starfive.c new file +3
-0+seq_printf (s,"dout=%u%s doen=%u%s" , + dout & (u32 )GENMASK (7 ,0 ), (dout &BIT (31 )) ?"r" :"" , + doen & (u32 )GENMASK (7 ,0 ), (doen &BIT (31 )) ?"r" :"" );
Why castings?
...
drivers/pinctrl/pinctrl-starfive.c line 501
Quoted 8 lines
drivers/pinctrl/pinctrl-starfive.c new file +7
-0+for_each_child_of_node (np, child) { +int npinmux =of_property_count_u32_elems (child,"pinmux" ); +int npins =of_property_count_u32_elems (child,"pins" ); + +if (npinmux >0 && npins >0 ) { +dev_err (dev,"invalid pinctrl group %pOFn.%pOFn: %s\n" , + np, child,"both pinmux and pins set" );
Why %s for string literal?! It's quite unusual. Ditto for other similar cases.
Quoted 3 lines
drivers/pinctrl/pinctrl-starfive.c new file +3
-0+of_node_put (child); +return -EINVAL ; + }
...
drivers/pinctrl/pinctrl-starfive.c line 515
Quoted 6 lines
drivers/pinctrl/pinctrl-starfive.c new file +6
-0+ }else { +dev_err (dev,"invalid pinctrl group %pOFn.%pOFn: %s\n" , + np, child,"neither pinmux nor pins set" ); +of_node_put (child); +return -EINVAL ; + }
This can be checjed above with other sanity check(s), right?
Quoted 2 lines
(quoted diff) +2
-0+ ngroups += 1; + }
...
Quoted 1 line
+ ret =
-ENOMEM;
It should be below...
drivers/pinctrl/pinctrl-starfive.c line 522
Quoted 3 lines
drivers/pinctrl/pinctrl-starfive.c new file +3
-0+ pgnames =devm_kcalloc (dev, ngroups,sizeof (*pgnames),GFP_KERNEL ); +if (!pgnames) +return ret;
...like here, where it makes more sense.
Quoted 3 lines
drivers/pinctrl/pinctrl-starfive.c new file +3
-0+ map =kcalloc (nmaps,sizeof (*map),GFP_KERNEL ); +if (!map) + goto free_pgnames;
...
Quoted 19 lines
drivers/pinctrl/pinctrl-starfive.c new file +19
-0+for_each_child_of_node (np, child) { +int npins; +int i; + + ret = -ENOMEM ; + grpname =devm_kasprintf (dev,GFP_KERNEL ,"%s.%s" , np->name, child->name); +if (!grpname) + goto put_child; + + pgnames[ngroups++] = grpname; + +if ((npins =of_property_count_u32_elems (child,"pinmux" )) >0 ) { + pins =devm_kcalloc (dev, npins,sizeof (*pins),GFP_KERNEL ); +if (!pins) + goto free_grpname; + + pinmux =devm_kcalloc (dev, npins,sizeof (*pinmux),GFP_KERNEL ); +if (!pinmux) + goto free_pins;
drivers/pinctrl/pinctrl-starfive.c line 558
Quoted 10 lines
drivers/pinctrl/pinctrl-starfive.c new file +10
-0+ +for (i =0 ; i < npins; i++) { +u32 v; + + ret =of_property_read_u32_index (child,"pinmux" , i, &v); +if (ret) + goto free_pinmux; + pins[i] =starfive_gpio_to_pin (sfp,starfive_pinmux_to_gpio (v)); + pinmux[i] = v; + }
Why you can't use of_property_read_u32_array() APIs?
Quoted 9 lines
drivers/pinctrl/pinctrl-starfive.c new file +9
-0+ map[nmaps].type =PIN_MAP_TYPE_MUX_GROUP ; + map[nmaps].data.mux.function = np->name; + map[nmaps].data.mux.group = grpname; + nmaps +=1 ; + }else if ((npins =of_property_count_u32_elems (child,"pins" )) >0 ) { + pins =devm_kcalloc (dev, npins,sizeof (*pins),GFP_KERNEL ); +if (!pins) + goto free_grpname; +
drivers/pinctrl/pinctrl-starfive.c line 578
Quoted 10 lines
drivers/pinctrl/pinctrl-starfive.c new file +10
-0+ pinmux =NULL ; + +for (i =0 ; i < npins; i++) { +u32 v; + + ret =of_property_read_u32_index (child,"pins" , i, &v); +if (ret) + goto free_pins; + pins[i] = v; + }
NIH _array() APIs.
Quoted 29 lines
drivers/pinctrl/pinctrl-starfive.c new file +29
-0+ }else { + ret = -EINVAL ; + goto free_grpname; + } + + ret =pinctrl_generic_add_group (pctldev, grpname, pins, npins, pinmux); +if (ret <0 ) { +dev_err (dev,"error adding group %pOFn.%pOFn: %d\n" , + np, child, ret); + goto free_pinmux; + } + + ret =pinconf_generic_parse_dt_config (child, pctldev, + &map[nmaps].data.configs.configs, + &map[nmaps].data.configs.num_configs); +if (ret) { +dev_err (dev,"invalid pinctrl group %pOFn.%pOFn: %s\n" , + np, child,"error parsing pin config" ); + goto put_child; + } + +/* don't create a map if there are no pinconf settings */ +if (map[nmaps].data.configs.num_configs ==0 ) +continue ; + + map[nmaps].type =PIN_MAP_TYPE_CONFIGS_GROUP ; + map[nmaps].data.configs.group_or_pin = grpname; + nmaps +=1 ; + }
...
drivers/pinctrl/pinctrl-starfive.c line 630
Quoted 9 lines
drivers/pinctrl/pinctrl-starfive.c new file +8
-0+free_pinmux: +devm_kfree (dev, pinmux); +free_pins: +devm_kfree (dev, pins); +free_grpname: +devm_kfree (dev, grpname); +free_pgnames: +devm_kfree (dev, pgnames);
Just no, please get rid of them either way as I explained in previous reviews.
...
drivers/pinctrl/pinctrl-starfive.c line 682
Quoted 5 lines
drivers/pinctrl/pinctrl-starfive.c new file +5
-0+raw_spin_lock_irqsave (&sfp->lock, flags); +writel_relaxed (dout, reg_dout); +writel_relaxed (doen, reg_doen); +if (reg_din) +writel_relaxed (gpio +2 , reg_din);
Why 0 can't be written?
Quoted 1 line
+
raw_spin_unlock_irqrestore(&sfp->lock, flags);
...
drivers/pinctrl/pinctrl-starfive.c line 717
Quoted 2 lines
drivers/pinctrl/pinctrl-starfive.c new file +2
-0+dev_dbg (starfive_dev (sfp), +"padctl_rmw(%u, 0x%03x, 0x%03x)\n" , pin, _mask, _value);
One line?
...
drivers/pinctrl/pinctrl-starfive.c line 822
Quoted 6 lines
drivers/pinctrl/pinctrl-starfive.c new file +5
-0+ mask =0 ; + value =0 ; +for (i =0 ; i < num_configs; i++) { +int param =pinconf_to_config_param (configs[i]); +u32 arg =pinconf_to_config_argument (configs[i]);
+
drivers/pinctrl/pinctrl-starfive.c line 827
Quoted 4 lines
drivers/pinctrl/pinctrl-starfive.c new file +4
-0+switch (param) { +case PIN_CONFIG_BIAS_DISABLE : + mask |=PAD_BIAS_MASK ; + value = (value & ~PAD_BIAS_MASK ) |PAD_BIAS_DISABLE ;
Okay, I have got why you are masking on each iteration, but here is the question, shouldn't you apply the cnages belonged to each of the group of options as it's requested by the user? Here you basically ignore all previous changes to bias.
I would expect that you have something like
for () {
switch (type) {
case BIAS*:
return apply_bias();
...other types...
default:
return err; }
}
Quoted 51 lines
drivers/pinctrl/pinctrl-starfive.c new file +51
-0+break ; +case PIN_CONFIG_BIAS_PULL_DOWN : +if (arg ==0 ) +return -ENOTSUPP ; + mask |=PAD_BIAS_MASK ; + value = (value & ~PAD_BIAS_MASK ) |PAD_BIAS_PULL_DOWN ; +break ; +case PIN_CONFIG_BIAS_PULL_UP : +if (arg ==0 ) +return -ENOTSUPP ; + mask |=PAD_BIAS_MASK ; + value = value & ~PAD_BIAS_MASK ; +break ; +case PIN_CONFIG_DRIVE_STRENGTH : + mask |=PAD_DRIVE_STRENGTH_MASK ; + value = (value & ~PAD_DRIVE_STRENGTH_MASK ) | +starfive_drive_strength_from_max_mA (arg); +break ; +case PIN_CONFIG_INPUT_ENABLE : + mask |=PAD_INPUT_ENABLE ; +if (arg) + value |=PAD_INPUT_ENABLE ; +else + value &= ~PAD_INPUT_ENABLE ; +break ; +case PIN_CONFIG_INPUT_SCHMITT_ENABLE : + mask |=PAD_INPUT_SCHMITT_ENABLE ; +if (arg) + value |=PAD_INPUT_SCHMITT_ENABLE ; +else + value &= ~PAD_INPUT_SCHMITT_ENABLE ; +break ; +case PIN_CONFIG_SLEW_RATE : + mask |=PAD_SLEW_RATE_MASK ; + value = (value & ~PAD_SLEW_RATE_MASK ) | + ((arg <<PAD_SLEW_RATE_POS ) &PAD_SLEW_RATE_MASK ); +break ; +case PIN_CONFIG_STARFIVE_STRONG_PULL_UP : +if (arg) { + mask |=PAD_BIAS_MASK ; + value = (value & ~PAD_BIAS_MASK ) | +PAD_BIAS_STRONG_PULL_UP ; + }else { + mask |=PAD_BIAS_STRONG_PULL_UP ; + value = value & ~PAD_BIAS_STRONG_PULL_UP ; + } +break ; +default : +return -ENOTSUPP ; + } + }
...
drivers/pinctrl/pinctrl-starfive.c line 928
Quoted 9 lines
drivers/pinctrl/pinctrl-starfive.c new file +9
-0+static int starfive_gpio_request (struct gpio_chip *gc,unsigned int gpio) +{ +return pinctrl_gpio_request (gc->base + gpio); +} + +static void starfive_gpio_free (struct gpio_chip *gc,unsigned int gpio) +{ +pinctrl_gpio_free (gc->base + gpio); +}
Point of having these function is...?
...
Review
Quoted 2 lines
(quoted diff) +2
-0+ if (gpio >= NR_GPIOS) + return -EINVAL;
Dead code?
...
Review
Quoted 2 lines
(quoted diff) +2
-0+ if (gpio >= NR_GPIOS) + return -EINVAL;
Dead code?
...
Quoted 1 line
+ /* enable input and schmitt trigger */
Use capitalization consistently.
...
Review
Quoted 2 lines
(quoted diff) +2
-0+ if (gpio >= NR_GPIOS) + return -EINVAL;
Dead code?
...
Review
Quoted 2 lines
(quoted diff) +2
-0+ if (gpio >= NR_GPIOS) + return -EINVAL;
Dead code?
...
Review
Quoted 2 lines
(quoted diff) +2
-0+ if (gpio >= NR_GPIOS) + return;
Dead code?
...
Quoted 1 line
+ struct
starfive_pinctrl*sfp =starfive_from_gc(gc);
The starfive_from_gc() is useless. Inline it whenever you use it.
...
Quoted 7 lines
drivers/pinctrl/pinctrl-starfive.c new file +7
-0+case IRQ_TYPE_EDGE_RISING : + irq_type = mask;/* 1: edge triggered */ + edge_both =0 ;/* 0: single edge */ + polarity = mask;/* 1: rising edge */ + handler = handle_edge_irq; +break ; +case IRQ_TYPE_EDGE_FALLING :
drivers/pinctrl/pinctrl-starfive.c line 1163
Quoted 10 lines
drivers/pinctrl/pinctrl-starfive.c new file +10
-0+ irq_type = mask;/* 1: edge triggered */ + edge_both =0 ;/* 0: single edge */ + polarity =0 ;/* 0: falling edge */ + handler = handle_edge_irq + break; +case IRQ_TYPE_EDGE_BOTH : + irq_type = mask;/* 1: edge triggered */ + edge_both = mask;/* 1: both edges */ + polarity =0 ;/* 0: ignored */ + handler = handle_edge_irq;
Dup. You may do it once without any temporary variable. I haven't got why you haven't addressed this.
drivers/pinctrl/pinctrl-starfive.c line 1175
Quoted 12 lines
drivers/pinctrl/pinctrl-starfive.c new file +12
-0+break ; +case IRQ_TYPE_LEVEL_HIGH : + irq_type =0 ;/* 0: level triggered */ + edge_both =0 ;/* 0: ignored */ + polarity = mask;/* 1: high level */ + handler = handle_level_irq; +break ; +case IRQ_TYPE_LEVEL_LOW : + irq_type =0 ;/* 0: level triggered */ + edge_both =0 ;/* 0: ignored */ + polarity =0 ;/* 0: low level */ + handler = handle_level_irq;
Ditto.
Quoted 1 line
+ break;
...
drivers/pinctrl/pinctrl-starfive.c line 1267
Quoted 4 lines
drivers/pinctrl/pinctrl-starfive.c new file +3
-0+ clk =devm_clk_get (dev,NULL ); +if (IS_ERR (clk)) { + ret =PTR_ERR (clk);
Inline into below.
drivers/pinctrl/pinctrl-starfive.c line 1269
Quoted 2 lines
drivers/pinctrl/pinctrl-starfive.c new file +2
-0+return dev_err_probe (dev, ret,"could not get clock: %d\n" , ret); + }
Ditto for all other similar cases.
...
drivers/pinctrl/pinctrl-starfive.c line 1279
Quoted 3 lines
drivers/pinctrl/pinctrl-starfive.c new file +3
-0+ ret =clk_prepare_enable (clk); +if (ret) +return dev_err_probe (dev, ret,"could not enable clock: %d\n" , ret);
Double ret?!Ditto for all other similar cases.
...
Quoted 1 line
+ if (!device_property_read_u32(dev, "starfive,signal-group", &value)) {
Since you are using of_property_* elsewhere, makes sense to use same here, or otherwise, use device_*() APIs there.
...
Quoted 1 line
+done:
Perhaps you may factor out the function and get rid of this label.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Emil Renner Berthing
maintainerRe: [PATCH v2 12/16] pinctrl: starfive: Add pinctrl driver for StarFive SoCs
Quoted 24 lines · Andy Shevchenko
Quoted 23 lines · Emil Renner Berthing
drivers/pinctrl/pinctrl-starfive.c new file +23
-0+for_each_child_of_node (np, child) { +int npins; +int i; + + ret = -ENOMEM ; + grpname =devm_kasprintf (dev,GFP_KERNEL ,"%s.%s" , np->name, child->name); +if (!grpname) + goto put_child; + + pgnames[ngroups++] = grpname; + +if ((npins =of_property_count_u32_elems (child,"pinmux" )) >0 ) { + pins =devm_kcalloc (dev, npins,sizeof (*pins),GFP_KERNEL ); +if (!pins) + goto free_grpname; + + pinmux =devm_kcalloc (dev, npins,sizeof (*pinmux),GFP_KERNEL ); +if (!pinmux) + goto free_pins; + +for (i =0 ; i < npins; i++) { +u32 v; +
Quoted 8 lines
drivers/pinctrl/pinctrl-starfive.c line 558
Quoted 6 lines
drivers/pinctrl/pinctrl-starfive.c new file +6
-0+ ret =of_property_read_u32_index (child,"pinmux" , i, &v); +if (ret) + goto free_pinmux; + pins[i] =starfive_gpio_to_pin (sfp,starfive_pinmux_to_gpio (v)); + pinmux[i] = v; + }Why you can't use
of_property_read_u32_array()APIs?
I can here, but..
Quoted 13 lines
Quoted 13 lines
drivers/pinctrl/pinctrl-starfive.c new file +13
-0+ map[nmaps].type =PIN_MAP_TYPE_MUX_GROUP ; + map[nmaps].data.mux.function = np->name; + map[nmaps].data.mux.group = grpname; + nmaps +=1 ; + }else if ((npins =of_property_count_u32_elems (child,"pins" )) >0 ) { + pins =devm_kcalloc (dev, npins,sizeof (*pins),GFP_KERNEL ); +if (!pins) + goto free_grpname; + + pinmux =NULL ; + +for (i =0 ; i < npins; i++) { +u32 v;
Quoted 8 lines
drivers/pinctrl/pinctrl-starfive.c line 578
Quoted 6 lines
drivers/pinctrl/pinctrl-starfive.c new file +6
-0+ + ret =of_property_read_u32_index (child,"pins" , i, &v); +if (ret) + goto free_pins; + pins[i] = v; + }NIH
_array()APIs.
.. here the pins array is an int array and not u32 array. I can cast it and and hope Linux will never run on a machine where sizeof(int) != 4 if you think that's better?
Quoted 39 lines
Quoted 29 lines
drivers/pinctrl/pinctrl-starfive.c new file +29
-0+ }else { + ret = -EINVAL ; + goto free_grpname; + } + + ret =pinctrl_generic_add_group (pctldev, grpname, pins, npins, pinmux); +if (ret <0 ) { +dev_err (dev,"error adding group %pOFn.%pOFn: %d\n" , + np, child, ret); + goto free_pinmux; + } + + ret =pinconf_generic_parse_dt_config (child, pctldev, + &map[nmaps].data.configs.configs, + &map[nmaps].data.configs.num_configs); +if (ret) { +dev_err (dev,"invalid pinctrl group %pOFn.%pOFn: %s\n" , + np, child,"error parsing pin config" ); + goto put_child; + } + +/* don't create a map if there are no pinconf settings */ +if (map[nmaps].data.configs.num_configs ==0 ) +continue ; + + map[nmaps].type =PIN_MAP_TYPE_CONFIGS_GROUP ; + map[nmaps].data.configs.group_or_pin = grpname; + nmaps +=1 ; + }...
Quoted 6 lines
drivers/pinctrl/pinctrl-starfive.c new file +6
-0+free_pinmux: +devm_kfree (dev, pinmux); +free_pins: +devm_kfree (dev, pins); +free_grpname: +devm_kfree (dev, grpname);
Quoted 4 lines
drivers/pinctrl/pinctrl-starfive.c line 630
Quoted 2 lines
drivers/pinctrl/pinctrl-starfive.c new file +2
-0+free_pgnames: +devm_kfree (dev, pgnames);Just no, please get rid of them either way as I explained in previous reviews.
So I asked you if you thought it was better to leave these unused allocations when parsing the device tree node fails but you never answered that. I didn't want put words in your mouth so I could only assume you didn't. I'd really like a straight answer to that so I have something to refer to when people ask why this driver doesn't do the same as fx. the pinctrl-single. So just to be clear: do you think it's better to leave this unused garbage allocated if parsing the device tree node fails?
Quoted 7 lines
drivers/pinctrl/pinctrl-starfive.c line 682
Quoted 5 lines
drivers/pinctrl/pinctrl-starfive.c new file +5
-0+raw_spin_lock_irqsave (&sfp->lock, flags); +writel_relaxed (dout, reg_dout); +writel_relaxed (doen, reg_doen); +if (reg_din) +writel_relaxed (gpio +2 , reg_din);Why 0 can't be written?
Because signal 0 is a special "always 0" signal and signal 1 is a special "always 1" signal, and after that signal n is the input value of GPIO n - 2. We don't want to overwrite the PoR defaults.
Quoted 22 lines
drivers/pinctrl/pinctrl-starfive.c line 822
Quoted 6 lines
drivers/pinctrl/pinctrl-starfive.c new file +5
-0+ mask =0 ; + value =0 ; +for (i =0 ; i < num_configs; i++) { +int param =pinconf_to_config_param (configs[i]); +u32 arg =pinconf_to_config_argument (configs[i]);+
drivers/pinctrl/pinctrl-starfive.c line 827
Quoted 4 lines
drivers/pinctrl/pinctrl-starfive.c new file +4
-0+switch (param) { +case PIN_CONFIG_BIAS_DISABLE : + mask |=PAD_BIAS_MASK ; + value = (value & ~PAD_BIAS_MASK ) |PAD_BIAS_DISABLE ;Okay, I have got why you are masking on each iteration, but here is the question, shouldn't you apply the cnages belonged to each of the group of options as it's requested by the user? Here you basically ignore all previous changes to bias.
I would expect that you have something like
for () {
switch (type) {
case BIAS*:
Quoted 6 lines
return apply_bias(); ...other types... default: return err;}
}
I such cases where you get conflicting PIN_CONFIG_BIAS_* settings I don't see why it's better to do the rmw on the padctl register for the first bias setting only to then change the bits again a few microseconds later when the loop encounters the second bias setting. After the loop is done the end result would still be just the last bias setting.
Quoted 54 lines
Quoted 51 lines
drivers/pinctrl/pinctrl-starfive.c new file +51
-0+break ; +case PIN_CONFIG_BIAS_PULL_DOWN : +if (arg ==0 ) +return -ENOTSUPP ; + mask |=PAD_BIAS_MASK ; + value = (value & ~PAD_BIAS_MASK ) |PAD_BIAS_PULL_DOWN ; +break ; +case PIN_CONFIG_BIAS_PULL_UP : +if (arg ==0 ) +return -ENOTSUPP ; + mask |=PAD_BIAS_MASK ; + value = value & ~PAD_BIAS_MASK ; +break ; +case PIN_CONFIG_DRIVE_STRENGTH : + mask |=PAD_DRIVE_STRENGTH_MASK ; + value = (value & ~PAD_DRIVE_STRENGTH_MASK ) | +starfive_drive_strength_from_max_mA (arg); +break ; +case PIN_CONFIG_INPUT_ENABLE : + mask |=PAD_INPUT_ENABLE ; +if (arg) + value |=PAD_INPUT_ENABLE ; +else + value &= ~PAD_INPUT_ENABLE ; +break ; +case PIN_CONFIG_INPUT_SCHMITT_ENABLE : + mask |=PAD_INPUT_SCHMITT_ENABLE ; +if (arg) + value |=PAD_INPUT_SCHMITT_ENABLE ; +else + value &= ~PAD_INPUT_SCHMITT_ENABLE ; +break ; +case PIN_CONFIG_SLEW_RATE : + mask |=PAD_SLEW_RATE_MASK ; + value = (value & ~PAD_SLEW_RATE_MASK ) | + ((arg <<PAD_SLEW_RATE_POS ) &PAD_SLEW_RATE_MASK ); +break ; +case PIN_CONFIG_STARFIVE_STRONG_PULL_UP : +if (arg) { + mask |=PAD_BIAS_MASK ; + value = (value & ~PAD_BIAS_MASK ) | +PAD_BIAS_STRONG_PULL_UP ; + }else { + mask |=PAD_BIAS_STRONG_PULL_UP ; + value = value & ~PAD_BIAS_STRONG_PULL_UP ; + } +break ; +default : +return -ENOTSUPP ; + } + }...
Quoted 11 lines
drivers/pinctrl/pinctrl-starfive.c line 928
Quoted 9 lines
drivers/pinctrl/pinctrl-starfive.c new file +9
-0+static int starfive_gpio_request (struct gpio_chip *gc,unsigned int gpio) +{ +return pinctrl_gpio_request (gc->base + gpio); +} + +static void starfive_gpio_free (struct gpio_chip *gc,unsigned int gpio) +{ +pinctrl_gpio_free (gc->base + gpio); +}Point of having these function is...?
These calls tells the pinctrl system that a certain pin is now used for GPIO. Conversely it'll also prevent fx. userspace from doing GPIO on a pin that's already used by I2C, a UART or some other peripheral.
Quoted 3 lines
Quoted 1 line
+ /* enable input and schmitt trigger */
Use capitalization consistently.
I am?
Quoted 18 lines
Quoted 7 lines
drivers/pinctrl/pinctrl-starfive.c new file +7
-0+case IRQ_TYPE_EDGE_RISING : + irq_type = mask;/* 1: edge triggered */ + edge_both =0 ;/* 0: single edge */ + polarity = mask;/* 1: rising edge */ + handler = handle_edge_irq; +break ; +case IRQ_TYPE_EDGE_FALLING :drivers/pinctrl/pinctrl-starfive.c line 1163
Quoted 10 lines
drivers/pinctrl/pinctrl-starfive.c new file +10
-0+ irq_type = mask;/* 1: edge triggered */ + edge_both =0 ;/* 0: single edge */ + polarity =0 ;/* 0: falling edge */ + handler = handle_edge_irq + break; +case IRQ_TYPE_EDGE_BOTH : + irq_type = mask;/* 1: edge triggered */ + edge_both = mask;/* 1: both edges */ + polarity =0 ;/* 0: ignored */ + handler = handle_edge_irq;
Quoted 2 lines
Dup. You may do it once without any temporary variable. I haven't got why you haven't addressed this.
So you want two switches on the trigger variable, one for irq_type, edge_both and polarity, and one for the handler? If this is not what you have in mind please be a lot more explicit. Trying to guess what you mean gets really old.
Quoted 22 lines
drivers/pinctrl/pinctrl-starfive.c line 1175
Quoted 12 lines
drivers/pinctrl/pinctrl-starfive.c new file +12
-0+break ; +case IRQ_TYPE_LEVEL_HIGH : + irq_type =0 ;/* 0: level triggered */ + edge_both =0 ;/* 0: ignored */ + polarity = mask;/* 1: high level */ + handler = handle_level_irq; +break ; +case IRQ_TYPE_LEVEL_LOW : + irq_type =0 ;/* 0: level triggered */ + edge_both =0 ;/* 0: ignored */ + polarity =0 ;/* 0: low level */ + handler = handle_level_irq;Ditto.
Quoted 1 line
+ break;
...
Quoted 2 lines
drivers/pinctrl/pinctrl-starfive.c new file +2
-0+ clk =devm_clk_get (dev,NULL ); +if (IS_ERR (clk)) {
Quoted 8 lines
Quoted 1 line
+ ret =
PTR_ERR(clk);Inline into below.
drivers/pinctrl/pinctrl-starfive.c line 1269
Quoted 2 lines
drivers/pinctrl/pinctrl-starfive.c new file +2
-0+return dev_err_probe (dev, ret,"could not get clock: %d\n" , ret); + }Ditto for all other similar cases.
So you would rather want this?
return dev_err_probe(dev, PTR_ERR(clk), "could not get clock: %d\n",PTR_ERR(clk));
or just not tell why getting the clock failed?
Quoted 4 lines
Quoted 1 line
+ if (!device_property_read_u32(dev, "starfive,signal-group", &value)) {
Since you are using of_property_* elsewhere, makes sense to use same here, or otherwise, use device_*() APIs there.
Wait, so now you want of_property_read_u32(dev->of_node, ...) here again, is that right?
/Emil
Re: [PATCH v2 12/16] pinctrl: starfive: Add pinctrl driver for StarFive SoCs
Quoted 2 lines · Emil Renner Berthing
Quoted 1 line · Andy Shevchenko
On Thu, Oct 21, 2021 at 8:44 PM Emil Renner Berthing <[email protected]> wrote:
...
Quoted 18 lines
Quoted 9 lines
Quoted 9 lines
drivers/pinctrl/pinctrl-starfive.c new file +9
-0+ }else if ((npins =of_property_count_u32_elems (child,"pins" )) >0 ) { + pins =devm_kcalloc (dev, npins,sizeof (*pins),GFP_KERNEL ); +if (!pins) + goto free_grpname; + + pinmux =NULL ; + +for (i =0 ; i < npins; i++) { +u32 v;Quoted 8 lines
drivers/pinctrl/pinctrl-starfive.c line 578
Quoted 6 lines
drivers/pinctrl/pinctrl-starfive.c new file +6
-0+ + ret =of_property_read_u32_index (child,"pins" , i, &v); +if (ret) + goto free_pins; + pins[i] = v; + }NIH
_array()APIs.
Quoted 3 lines
.. here the pins array is an int array and not u32 array. I can cast it and and hope Linux will never run on a machine where sizeof(int) != 4 if you think that's better?
Can you make it u32?
...
Quoted 12 lines
Quoted 11 lines
drivers/pinctrl/pinctrl-starfive.c line 630
Quoted 9 lines
drivers/pinctrl/pinctrl-starfive.c new file +8
-0+free_pinmux: +devm_kfree (dev, pinmux); +free_pins: +devm_kfree (dev, pins); +free_grpname: +devm_kfree (dev, grpname); +free_pgnames: +devm_kfree (dev, pgnames);Just no, please get rid of them either way as I explained in previous reviews.
Quoted 8 lines
So I asked you if you thought it was better to leave these unused allocations when parsing the device tree node fails but you never answered that. I didn't want put words in your mouth so I could only assume you didn't. I'd really like a straight answer to that so I have something to refer to when people ask why this driver doesn't do the same as fx. the pinctrl-single. So just to be clear: do you think it's better to leave this unused garbage allocated if parsing the device tree node fails?
If it's only one time use, I don't think it's good to have it hanging around, BUT at the same time devm_*() is not suitable for such allocations.
...
Quoted 8 lines
Quoted 4 lines
drivers/pinctrl/pinctrl-starfive.c line 682
Quoted 2 lines
drivers/pinctrl/pinctrl-starfive.c new file +2
-0+if (reg_din) +writel_relaxed (gpio +2 , reg_din);Why 0 can't be written?
Because signal 0 is a special "always 0" signal and signal 1 is a special "always 1" signal, and after that signal n is the input value of GPIO n - 2. We don't want to overwrite the PoR defaults.
Okay, this, perhaps, needs a comment (if I have not missed the existing one).
And what about checking for reg_din? Do you have some blocks output-only?
...
Quoted 21 lines
Quoted 14 lines
drivers/pinctrl/pinctrl-starfive.c line 827
Quoted 3 lines
drivers/pinctrl/pinctrl-starfive.c new file +3
-0+case PIN_CONFIG_BIAS_DISABLE : + mask |=PAD_BIAS_MASK ; + value = (value & ~PAD_BIAS_MASK ) |PAD_BIAS_DISABLE ;Okay, I have got why you are masking on each iteration, but here is the question, shouldn't you apply the cnages belonged to each of the group of options as it's requested by the user? Here you basically ignore all previous changes to bias.
I would expect that you have something like
for () {
switch (type) {
case BIAS*:Quoted 6 lines
return apply_bias(); ...other types... default: return err;}
}
Quoted 6 lines
I such cases where you get conflicting PIN_CONFIG_BIAS_* settings I don't see why it's better to do the rmw on the padctl register for the first bias setting only to then change the bits again a few microseconds later when the loop encounters the second bias setting. After the loop is done the end result would still be just the last bias setting.
It could be bias X followed by something else followed by bias Y. You will write something else with bias Y. I admit I don't know this hardware and you and maintainers are supposed to decide what's better, but my guts are telling me that current algo is buggy.
Quoted 1 line
Quoted 1 line
Quoted 1 line
+ break;
...
Quoted 12 lines
Quoted 11 lines
drivers/pinctrl/pinctrl-starfive.c line 928
Quoted 9 lines
drivers/pinctrl/pinctrl-starfive.c new file +9
-0+static int starfive_gpio_request (struct gpio_chip *gc,unsigned int gpio) +{ +return pinctrl_gpio_request (gc->base + gpio); +} + +static void starfive_gpio_free (struct gpio_chip *gc,unsigned int gpio) +{ +pinctrl_gpio_free (gc->base + gpio); +}Point of having these function is...?
Quoted 3 lines
These calls tells the pinctrl system that a certain pin is now used for GPIO. Conversely it'll also prevent fx. userspace from doing GPIO on a pin that's already used by I2C, a UART or some other peripheral.
Isn't pin control doing it by default?
...
Quoted 5 lines
Quoted 3 lines
Quoted 1 line
+ /* enable input and schmitt trigger */
Use capitalization consistently.
I am?
In the comment is one style, in other comments it's another.
...
Quoted 12 lines
Quoted 12 lines
Quoted 11 lines
drivers/pinctrl/pinctrl-starfive.c new file +8
-0+case IRQ_TYPE_EDGE_RISING : + handler = handle_edge_irq; +break ; +case IRQ_TYPE_EDGE_FALLING : + handler = handle_edge_irq + break; +case IRQ_TYPE_EDGE_BOTH : + handler = handle_edge_irq;
Quoted 7 lines
Quoted 2 lines
Dup. You may do it once without any temporary variable. I haven't got why you haven't addressed this.
So you want two switches on the trigger variable, one for
irq_type,edge_bothand polarity, and one for the handler? If this is not what you have in mind please be a lot more explicit. Trying to guess what you mean gets really old.
switch (type) {
case bla bla bla:
...everything except handler...
}
if (type & EDGE)
irq_lock(edge_handler)
else if (type & LEVEL)
irq_lock(level_handler)
Quoted 13 lines
Quoted 13 lines
drivers/pinctrl/pinctrl-starfive.c line 1175
Quoted 9 lines
drivers/pinctrl/pinctrl-starfive.c new file +6
-0+break ; +case IRQ_TYPE_LEVEL_HIGH : + handler = handle_level_irq; +break ; +case IRQ_TYPE_LEVEL_LOW : + handler = handle_level_irq;Ditto.
Quoted 1 line
+ break;
...
Quoted 10 lines
Quoted 10 lines
drivers/pinctrl/pinctrl-starfive.c line 1267
Quoted 4 lines
drivers/pinctrl/pinctrl-starfive.c new file +3
-0+ clk =devm_clk_get (dev,NULL ); +if (IS_ERR (clk)) { + ret =PTR_ERR (clk);Inline into below.
Quoted 2 lines
drivers/pinctrl/pinctrl-starfive.c new file +2
-0+return dev_err_probe (dev, ret,"could not get clock: %d\n" , ret); + }
Quoted 6 lines
Quoted 1 line
Ditto for all other similar cases.
So you would rather want this?
return dev_err_probe(dev,PTR_ERR(clk), "could not get clock: %d\n",PTR_ERR(clk));
or just not tell why getting the clock failed?
Of course not, no dup of the printing error code is needed. I guess I mentioned it in another patch.
return dev_err_probe(dev, PTR_ERR($error), "$msg\n");
...
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
+ if (!device_property_read_u32(dev, "starfive,signal-group", &value)) {
Since you are using of_property_* elsewhere, makes sense to use same here, or otherwise, use device_*() APIs there.
Wait, so now you want
of_property_read_u32(dev->of_node, ...)here again, is that right?
Before I missed that there are other of_property_read*() calls, now since you used them elsewhere it makes sense to be consistent over the code.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Emil Renner Berthing
maintainerRe: [PATCH v2 12/16] pinctrl: starfive: Add pinctrl driver for StarFive SoCs
Quoted 21 lines · Andy Shevchenko
Quoted 20 lines · Emil Renner Berthing
Quoted 18 lines · Andy Shevchenko
Quoted 5 lines · Emil Renner Berthing
drivers/pinctrl/pinctrl-starfive.c new file +5
-0+ }else if ((npins =of_property_count_u32_elems (child,"pins" )) >0 ) { + pins =devm_kcalloc (dev, npins,sizeof (*pins),GFP_KERNEL ); +if (!pins) + goto free_grpname; +drivers/pinctrl/pinctrl-starfive.c line 578
Quoted 10 lines
drivers/pinctrl/pinctrl-starfive.c new file +10
-0+ pinmux =NULL ; + +for (i =0 ; i < npins; i++) { +u32 v; + + ret =of_property_read_u32_index (child,"pins" , i, &v); +if (ret) + goto free_pins; + pins[i] = v; + }NIH
_array()APIs.
Quoted 5 lines
Quoted 3 lines
.. here the pins array is an int array and not u32 array. I can cast it and and hope Linux will never run on a machine where sizeof(int) != 4 if you think that's better?
Can you make it u32?
No, the pinctrl API takes an int array.
Quoted 21 lines
Quoted 12 lines
Quoted 11 lines
drivers/pinctrl/pinctrl-starfive.c line 630
Quoted 9 lines
drivers/pinctrl/pinctrl-starfive.c new file +8
-0+free_pinmux: +devm_kfree (dev, pinmux); +free_pins: +devm_kfree (dev, pins); +free_grpname: +devm_kfree (dev, grpname); +free_pgnames: +devm_kfree (dev, pgnames);Just no, please get rid of them either way as I explained in previous reviews.
Quoted 8 lines
So I asked you if you thought it was better to leave these unused allocations when parsing the device tree node fails but you never answered that. I didn't want put words in your mouth so I could only assume you didn't. I'd really like a straight answer to that so I have something to refer to when people ask why this driver doesn't do the same as fx. the pinctrl-single. So just to be clear: do you think it's better to leave this unused garbage allocated if parsing the device tree node fails?
Quoted 3 lines
If it's only one time use, I don't think it's good to have it hanging around, BUT at the same time devm_*() is not suitable for such allocations.
So is that a yes or a no to my question? It's not clear to me.
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
drivers/pinctrl/pinctrl-starfive.c line 682
Quoted 2 lines
drivers/pinctrl/pinctrl-starfive.c new file +2
-0+if (reg_din) +writel_relaxed (gpio +2 , reg_din);Why 0 can't be written?
Quoted 7 lines
Quoted 3 lines
Because signal 0 is a special "always 0" signal and signal 1 is a special "always 1" signal, and after that signal n is the input value of GPIO n - 2. We don't want to overwrite the PoR defaults.
Okay, this, perhaps, needs a comment (if I have not missed the existing one).
And what about checking for
reg_din? Do you have some blocks output-only?
I don't know know what you mean by the first question, but yes fx. the uart tx pins would be an example of pins that have their output signal set to the uart peripheral, the output enable set to the special "always enabled" signal, and no input signal is set to any of the tx pins.
Quoted 28 lines
Quoted 21 lines
Quoted 14 lines
drivers/pinctrl/pinctrl-starfive.c line 827
Quoted 3 lines
drivers/pinctrl/pinctrl-starfive.c new file +3
-0+case PIN_CONFIG_BIAS_DISABLE : + mask |=PAD_BIAS_MASK ; + value = (value & ~PAD_BIAS_MASK ) |PAD_BIAS_DISABLE ;Okay, I have got why you are masking on each iteration, but here is the question, shouldn't you apply the cnages belonged to each of the group of options as it's requested by the user? Here you basically ignore all previous changes to bias.
I would expect that you have something like
for () {
switch (type) {
case BIAS*:Quoted 6 lines
return apply_bias(); ...other types... default: return err;}
}Quoted 6 lines
I such cases where you get conflicting PIN_CONFIG_BIAS_* settings I don't see why it's better to do the rmw on the padctl register for the first bias setting only to then change the bits again a few microseconds later when the loop encounters the second bias setting. After the loop is done the end result would still be just the last bias setting.
Quoted 4 lines
It could be bias X followed by something else followed by bias Y. You will write something else with bias Y. I admit I don't know this hardware and you and maintainers are supposed to decide what's better, but my guts are telling me that current algo is buggy.
So there is only one padctl register pr. pin. I don't see why first setting the bias bits to X, then setting some other bits, and then setting the bias bits to Y would be different from just setting all the bits in one go. Except for during that little microsecond window during the loop that I actually think it's better to avoid.
Quoted 16 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
+ break;
...
Quoted 12 lines
Quoted 11 lines
drivers/pinctrl/pinctrl-starfive.c line 928
Quoted 9 lines
drivers/pinctrl/pinctrl-starfive.c new file +9
-0+static int starfive_gpio_request (struct gpio_chip *gc,unsigned int gpio) +{ +return pinctrl_gpio_request (gc->base + gpio); +} + +static void starfive_gpio_free (struct gpio_chip *gc,unsigned int gpio) +{ +pinctrl_gpio_free (gc->base + gpio); +}Point of having these function is...?
Quoted 5 lines
Quoted 3 lines
These calls tells the pinctrl system that a certain pin is now used for GPIO. Conversely it'll also prevent fx. userspace from doing GPIO on a pin that's already used by I2C, a UART or some other peripheral.
Isn't pin control doing it by default?
I actually tested that before posting and the answer seems to be no.
Quoted 9 lines
...
Quoted 5 lines
Quoted 3 lines
Quoted 1 line
+ /* enable input and schmitt trigger */
Use capitalization consistently.
I am?
In the comment is one style, in other comments it's another.
There are documentation comments in the beginning of the file and then there are code comments in the code. I think it's a lot easier to read like that, but if you insist I can lowercase the documentation.
Quoted 25 lines
Quoted 12 lines
Quoted 12 lines
Quoted 11 lines
drivers/pinctrl/pinctrl-starfive.c new file +8
-0+case IRQ_TYPE_EDGE_RISING : + handler = handle_edge_irq; +break ; +case IRQ_TYPE_EDGE_FALLING : + handler = handle_edge_irq + break; +case IRQ_TYPE_EDGE_BOTH : + handler = handle_edge_irq;Quoted 7 lines
Quoted 2 lines
Dup. You may do it once without any temporary variable. I haven't got why you haven't addressed this.
So you want two switches on the trigger variable, one for
irq_type,edge_bothand polarity, and one for the handler? If this is not what you have in mind please be a lot more explicit. Trying to guess what you mean gets really old.switch (type) {
case bla bla bla:
...everything except handler...
}
Quoted 4 lines
if (type & EDGE)
irq_lock(edge_handler)
else if (type & LEVEL)
irq_lock(level_handler)
If you look at include/dt-bindings/interrupt-controller/irq.h I don't think such a mask exists. I guess we could do
if (trigger & IRQ_TYPE_EDGE_BOTH)
edge_handler
else if (trigger == IRQ_TYPE_LEVEL_HIGH || trigger == IRQ_TYPE_LEVEL_LOW)
level_handler
else
return -EINVAL
..but at that point I think it's probably easer to read a 2nd switch case or just leave the code as it is. What do you think?
Quoted 45 lines
Quoted 13 lines
Quoted 13 lines
drivers/pinctrl/pinctrl-starfive.c line 1175
Quoted 9 lines
drivers/pinctrl/pinctrl-starfive.c new file +6
-0+break ; +case IRQ_TYPE_LEVEL_HIGH : + handler = handle_level_irq; +break ; +case IRQ_TYPE_LEVEL_LOW : + handler = handle_level_irq;Ditto.
Quoted 1 line
+ break;
...
Quoted 10 lines
Quoted 10 lines
drivers/pinctrl/pinctrl-starfive.c line 1267
Quoted 4 lines
drivers/pinctrl/pinctrl-starfive.c new file +3
-0+ clk =devm_clk_get (dev,NULL ); +if (IS_ERR (clk)) { + ret =PTR_ERR (clk);Inline into below.
Quoted 2 lines
drivers/pinctrl/pinctrl-starfive.c new file +2
-0+return dev_err_probe (dev, ret,"could not get clock: %d\n" , ret); + }Quoted 6 lines
Quoted 1 line
Ditto for all other similar cases.
So you would rather want this?
return dev_err_probe(dev,PTR_ERR(clk), "could not get clock: %d\n",PTR_ERR(clk));
or just not tell why getting the clock failed?Of course not, no dup of the printing error code is needed. I guess I mentioned it in another patch.
return
dev_err_probe(dev, PTR_ERR($error), "$msg\n");...
Quoted 5 lines
Quoted 4 lines
Quoted 1 line
+ if (!device_property_read_u32(dev, "starfive,signal-group", &value)) {
Since you are using of_property_* elsewhere, makes sense to use same here, or otherwise, use device_*() APIs there.
Quoted 6 lines
Quoted 2 lines
Wait, so now you want
of_property_read_u32(dev->of_node, ...)here again, is that right?Before I missed that there are other of_property_read*() calls, now since you used them elsewhere it makes sense to be consistent over the code.
Gotcha.
Quoted 3 lines
--
With Best Regards,
Andy Shevchenko
Emil Renner Berthing
maintainerRe: [PATCH v2 12/16] pinctrl: starfive: Add pinctrl driver for StarFive SoCs
Quoted 13 lines · Emil Renner Berthing
Quoted 12 lines · Andy Shevchenko
Quoted 10 lines · Emil Renner Berthing
Quoted 1 line · Andy Shevchenko
On Thu, Oct 21, 2021 at 8:44 PM Emil Renner Berthing <[email protected]> wrote:
So I asked you if you thought it was better to leave these unused allocations when parsing the device tree node fails but you never answered that. I didn't want put words in your mouth so I could only assume you didn't. I'd really like a straight answer to that so I have something to refer to when people ask why this driver doesn't do the same as fx. the pinctrl-single. So just to be clear: do you think it's better to leave this unused garbage allocated if parsing the device tree node fails?
Quoted 5 lines
Quoted 3 lines
If it's only one time use, I don't think it's good to have it hanging around, BUT at the same time devm_*() is not suitable for such allocations.
So is that a yes or a no to my question? It's not clear to me.
I see now that you've probably misunderstood what the code does. It's not one time use. The function parses the device tree and dynamically registers groups and functions with the pinctrl framework. Each group needs a string name, an int array of pins and optionally the pinmux data. Once the group is registered those pieces of data needs to live with the group until the drive is unloaded. But if the device tree parsing fails before the group is registered then those allocations would never be referenced and just hang around as garbage until the driver is unloaded. In such cases fx. pinctrl-single uses devm_free to free them again.
Quoted 52 lines
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
drivers/pinctrl/pinctrl-starfive.c line 682
Quoted 2 lines
drivers/pinctrl/pinctrl-starfive.c new file +2
-0+if (reg_din) +writel_relaxed (gpio +2 , reg_din);Why 0 can't be written?
Quoted 7 lines
Quoted 3 lines
Because signal 0 is a special "always 0" signal and signal 1 is a special "always 1" signal, and after that signal n is the input value of GPIO n - 2. We don't want to overwrite the PoR defaults.
Okay, this, perhaps, needs a comment (if I have not missed the existing one).
And what about checking for
reg_din? Do you have some blocks output-only?I don't know know what you mean by the first question, but yes fx. the uart tx pins would be an example of pins that have their output signal set to the uart peripheral, the output enable set to the special "always enabled" signal, and no input signal is set to any of the tx pins.
Quoted 28 lines
Quoted 21 lines
Quoted 14 lines
drivers/pinctrl/pinctrl-starfive.c line 827
Quoted 3 lines
drivers/pinctrl/pinctrl-starfive.c new file +3
-0+case PIN_CONFIG_BIAS_DISABLE : + mask |=PAD_BIAS_MASK ; + value = (value & ~PAD_BIAS_MASK ) |PAD_BIAS_DISABLE ;Okay, I have got why you are masking on each iteration, but here is the question, shouldn't you apply the cnages belonged to each of the group of options as it's requested by the user? Here you basically ignore all previous changes to bias.
I would expect that you have something like
for () {
switch (type) {
case BIAS*:Quoted 6 lines
return apply_bias(); ...other types... default: return err;}
}Quoted 6 lines
I such cases where you get conflicting PIN_CONFIG_BIAS_* settings I don't see why it's better to do the rmw on the padctl register for the first bias setting only to then change the bits again a few microseconds later when the loop encounters the second bias setting. After the loop is done the end result would still be just the last bias setting.
Quoted 4 lines
It could be bias X followed by something else followed by bias Y. You will write something else with bias Y. I admit I don't know this hardware and you and maintainers are supposed to decide what's better, but my guts are telling me that current algo is buggy.
Quoted 5 lines
So there is only one padctl register pr. pin. I don't see why first setting the bias bits to X, then setting some other bits, and then setting the bias bits to Y would be different from just setting all the bits in one go. Except for during that little microsecond window during the loop that I actually think it's better to avoid.
Maybe an example is in order. Suppose we get strong pull-up, drive strength 3 and pull-down config flags (the strong pull-up and pull down flags conflict) and the padctl value is 0x0c0 (pull-up, input and schmitt trigger enabled). With your solution of just altering the padctl bits immediately we'd call starfive_padctl_rmw 3 times in rapid succession like this:
starfive_padctl_rmw(pin, 0x130, 0x100);starfive_padctl_rmw(pin, 0x007, 0x003);starfive_padctl_rmw(pin, 0x130, 0x010);
..and the end result would be 0x0d3, although the strong pull-up would be enabled for the microseconds between the 1st and 3nd call. As the code is now it'd just directly do
starfive_padctl_rmw(pin, 0x137, 0x013)
..which again results in 0x0d3, only without the microsecond blink of the strong pull-up.
Re: [PATCH v2 12/16] pinctrl: starfive: Add pinctrl driver for StarFive SoCs
Quoted 3 lines · Emil Renner Berthing
Quoted 2 lines · Emil Renner Berthing
Quoted 1 line · Andy Shevchenko
On Sat, Oct 23, 2021 at 9:46 PM Emil Renner Berthing <[email protected]> wrote:
...
Quoted 12 lines
Quoted 1 line
So is that a yes or a no to my question? It's not clear to me.
I see now that you've probably misunderstood what the code does. It's not one time use. The function parses the device tree and dynamically registers groups and functions with the pinctrl framework. Each group needs a string name, an int array of pins and optionally the pinmux data. Once the group is registered those pieces of data needs to live with the group until the drive is unloaded. But if the device tree parsing fails before the group is registered then those allocations would never be referenced and just hang around as garbage until the driver is unloaded. In such cases fx. pinctrl-single uses
devm_freeto free them again.
Thank you for elaboration. Please, drop devm_*(). In this case it's inappropriate to use it. pinctrl-single should be amended accordingly, but it's out of scope here.
...
Quoted 29 lines
Quoted 12 lines
Quoted 11 lines
Quoted 6 lines
I such cases where you get conflicting PIN_CONFIG_BIAS_* settings I don't see why it's better to do the rmw on the padctl register for the first bias setting only to then change the bits again a few microseconds later when the loop encounters the second bias setting. After the loop is done the end result would still be just the last bias setting.
It could be bias X followed by something else followed by bias Y. You will write something else with bias Y. I admit I don't know this hardware and you and maintainers are supposed to decide what's better, but my guts are telling me that current algo is buggy.
Quoted 5 lines
So there is only one padctl register pr. pin. I don't see why first setting the bias bits to X, then setting some other bits, and then setting the bias bits to Y would be different from just setting all the bits in one go. Except for during that little microsecond window during the loop that I actually think it's better to avoid.
Maybe an example is in order. Suppose we get strong pull-up, drive strength 3 and pull-down config flags (the strong pull-up and pull down flags conflict) and the padctl value is
0x0c0(pull-up, input and schmitt trigger enabled). With your solution of just altering the padctl bits immediately we'd callstarfive_padctl_rmw3 times in rapid succession like this:
starfive_padctl_rmw(pin, 0x130, 0x100);starfive_padctl_rmw(pin, 0x007, 0x003);starfive_padctl_rmw(pin, 0x130, 0x010);
Quoted 8 lines
..and the end result would be
0x0d3, although the strong pull-up would be enabled for the microseconds between the 1st and 3nd call. As the code is now it'd just directly do
starfive_padctl_rmw(pin, 0x137, 0x013)..which again results in
0x0d3, only without the microsecond blink of the strong pull-up.
You missed the point. Hardware on the other end may behave well differently in these two cases.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Emil Renner Berthing
maintainerRe: [PATCH v2 12/16] pinctrl: starfive: Add pinctrl driver for StarFive SoCs
Quoted 59 lines · Andy Shevchenko
Quoted 3 lines · Emil Renner Berthing
Quoted 2 lines · Emil Renner Berthing
Quoted 1 line · Andy Shevchenko
On Sat, Oct 23, 2021 at 9:46 PM Emil Renner Berthing <[email protected]> wrote:
...
Quoted 12 lines
Quoted 1 line
So is that a yes or a no to my question? It's not clear to me.
I see now that you've probably misunderstood what the code does. It's not one time use. The function parses the device tree and dynamically registers groups and functions with the pinctrl framework. Each group needs a string name, an int array of pins and optionally the pinmux data. Once the group is registered those pieces of data needs to live with the group until the drive is unloaded. But if the device tree parsing fails before the group is registered then those allocations would never be referenced and just hang around as garbage until the driver is unloaded. In such cases fx. pinctrl-single uses
devm_freeto free them again.Thank you for elaboration. Please, drop devm_*(). In this case it's inappropriate to use it. pinctrl-single should be amended accordingly, but it's out of scope here.
...
Quoted 33 lines
Quoted 12 lines
Quoted 11 lines
Quoted 6 lines
I such cases where you get conflicting PIN_CONFIG_BIAS_* settings I don't see why it's better to do the rmw on the padctl register for the first bias setting only to then change the bits again a few microseconds later when the loop encounters the second bias setting. After the loop is done the end result would still be just the last bias setting.
It could be bias X followed by something else followed by bias Y. You will write something else with bias Y. I admit I don't know this hardware and you and maintainers are supposed to decide what's better, but my guts are telling me that current algo is buggy.
Quoted 5 lines
So there is only one padctl register pr. pin. I don't see why first setting the bias bits to X, then setting some other bits, and then setting the bias bits to Y would be different from just setting all the bits in one go. Except for during that little microsecond window during the loop that I actually think it's better to avoid.
Maybe an example is in order. Suppose we get strong pull-up, drive strength 3 and pull-down config flags (the strong pull-up and pull down flags conflict) and the padctl value is
0x0c0(pull-up, input and schmitt trigger enabled). With your solution of just altering the padctl bits immediately we'd callstarfive_padctl_rmw3 times in rapid succession like this:
starfive_padctl_rmw(pin, 0x130, 0x100);starfive_padctl_rmw(pin, 0x007, 0x003);starfive_padctl_rmw(pin, 0x130, 0x010);..and the end result would be
0x0d3, although the strong pull-up would be enabled for the microseconds between the 1st and 3nd call. As the code is now it'd just directly do
Quoted 7 lines
Quoted 4 lines
starfive_padctl_rmw(pin, 0x137, 0x013)..which again results in
0x0d3, only without the microsecond blink of the strong pull-up.You missed the point. Hardware on the other end may behave well differently in these two cases.
Right, but that can never be an intended behaviour. Which of the conflicting bias settings comes first and is blipped before the 2nd remains entirely depends on how the pinctrl framework parses the devicetree. I'd much rather have it cleanly go to just one of the states, which might be the wrong one, but the conflicting bias settings are wrong to begin with.
Re: [PATCH v2 12/16] pinctrl: starfive: Add pinctrl driver for StarFive SoCs
Quoted 5 lines · Emil Renner Berthing
Quoted 4 lines · Andy Shevchenko
Quoted 3 lines · Emil Renner Berthing
Quoted 2 lines · Emil Renner Berthing
Quoted 1 line · Andy Shevchenko
On Sat, Oct 23, 2021 at 9:46 PM Emil Renner Berthing <[email protected]> wrote:
...
Quoted 41 lines
Quoted 33 lines
Quoted 33 lines
Quoted 12 lines
Quoted 11 lines
Quoted 6 lines
I such cases where you get conflicting PIN_CONFIG_BIAS_* settings I don't see why it's better to do the rmw on the padctl register for the first bias setting only to then change the bits again a few microseconds later when the loop encounters the second bias setting. After the loop is done the end result would still be just the last bias setting.
It could be bias X followed by something else followed by bias Y. You will write something else with bias Y. I admit I don't know this hardware and you and maintainers are supposed to decide what's better, but my guts are telling me that current algo is buggy.
Quoted 5 lines
So there is only one padctl register pr. pin. I don't see why first setting the bias bits to X, then setting some other bits, and then setting the bias bits to Y would be different from just setting all the bits in one go. Except for during that little microsecond window during the loop that I actually think it's better to avoid.
Maybe an example is in order. Suppose we get strong pull-up, drive strength 3 and pull-down config flags (the strong pull-up and pull down flags conflict) and the padctl value is
0x0c0(pull-up, input and schmitt trigger enabled). With your solution of just altering the padctl bits immediately we'd callstarfive_padctl_rmw3 times in rapid succession like this:
starfive_padctl_rmw(pin, 0x130, 0x100);starfive_padctl_rmw(pin, 0x007, 0x003);starfive_padctl_rmw(pin, 0x130, 0x010);..and the end result would be
0x0d3, although the strong pull-up would be enabled for the microseconds between the 1st and 3nd call. As the code is now it'd just directly doQuoted 7 lines
Quoted 4 lines
starfive_padctl_rmw(pin, 0x137, 0x013)..which again results in
0x0d3, only without the microsecond blink of the strong pull-up.You missed the point. Hardware on the other end may behave well differently in these two cases.
Quoted 6 lines
Right, but that can never be an intended behaviour. Which of the conflicting bias settings comes first and is blipped before the 2nd remains entirely depends on how the pinctrl framework parses the devicetree. I'd much rather have it cleanly go to just one of the states, which might be the wrong one, but the conflicting bias settings are wrong to begin with.
That's why I said that is up to you and maintainers and people who know hardware better than me.
Signature · 2 lines
With Best Regards, Andy Shevchenko
kernel test robot
build botRe: [PATCH v2 12/16] pinctrl: starfive: Add pinctrl driver for StarFive SoCs
In reply to Emil Renner BerthingI love your patch! Yet something to improve:
Hi Emil,
I love your patch! Yet something to improve:
[auto build test ERROR on next-20211021]
[also build test ERROR on v5.15-rc7]
[cannot apply to robh/for-next clk/clk-next pza/reset/next linus/master v5.15-rc6 v5.15-rc5 v5.15-rc4] [If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Emil-Renner-Berthing/Basic-StarFive-JH7100-RISC-V-SoC-support/20211022-014605 base: 3196a52aff93186897f15f1a6c03220ce6523d82 config: alpha-randconfig-p002-20211028 (attached as .config) compiler: alpha-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/2aa8169a8c5820ad5b70679777e7f6acd4fd4699
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Emil-Renner-Berthing/Basic-StarFive-JH7100-RISC-V-SoC-support/20211022-014605 git checkout 2aa8169a8c5820ad5b70679777e7f6acd4fd4699
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=alpha
If you fix the issue, kindly add following tag as appropriate
All errors (new ones prefixed by >>):
drivers/pinctrl/pinctrl-starfive.c: In function 'starfive_dt_node_to_map':
>> drivers/pinctrl/pinctrl-starfive.c:591:23: error: implicit declaration of function 'pinconf_generic_parse_dt_config'; did you mean 'pinconf_generic_dump_config'? [-Werror=implicit-function-declaration]
591 | ret = pinconf_generic_parse_dt_config(child, pctldev,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| pinconf_generic_dump_configcc1: some warnings being treated as errors
Kconfig warnings: (for reference only)
WARNING: unmet direct dependencies detected for OF_GPIO Depends on GPIOLIB && OF && HAS_IOMEM
Selected by
- PINCTRL_STARFIVE && PINCTRL && (SOC_STARFIVE || COMPILE_TEST
WARNING: unmet direct dependencies detected for GPIO_SYSCON Depends on GPIOLIB && HAS_IOMEM && MFD_SYSCON && OF Selected by
- GPIO_SAMA5D2_PIOBU && GPIOLIB && HAS_IOMEM && MFD_SYSCON && OF_GPIO
vim +591 drivers/pinctrl/pinctrl-starfive.c
475
476 static int starfive_dt_node_to_map(struct pinctrl_dev *pctldev,
477 struct device_node *np,
478 struct pinctrl_map **maps,
479 unsigned int *num_maps)
480 {
481 struct starfive_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
482 struct device *dev = starfive_dev(sfp);
483 const char **pgnames;
484 struct pinctrl_map *map;
485 struct device_node *child;
486 const char *grpname;
487 int *pins;
488 u32 *pinmux;
489 int nmaps;
490 int ngroups;
491 int ret;
492
493 nmaps = 0;
494 ngroups = 0;
495 for_each_child_of_node(np, child) {
496 int npinmux = of_property_count_u32_elems(child, "pinmux");
497 int npins = of_property_count_u32_elems(child, "pins");
498
499 if (npinmux > 0 && npins > 0) {
500 dev_err(dev, "invalid pinctrl group %pOFn.%pOFn: %s\n",
501 np, child, "both pinmux and pins set");
502 of_node_put(child);
503 return -EINVAL;
504 }
505
506 if (npinmux > 0) {
507 nmaps += 2;
508 } else if (npins > 0) {
509 nmaps += 1;
510 } else {
511 dev_err(dev, "invalid pinctrl group %pOFn.%pOFn: %s\n",
512 np, child, "neither pinmux nor pins set");
513 of_node_put(child);
514 return -EINVAL;
515 }
516 ngroups += 1;
517 }
518
519 ret = -ENOMEM;
520 pgnames = devm_kcalloc(dev, ngroups, sizeof(*pgnames), GFP_KERNEL);
521 if (!pgnames)
522 return ret;
523
524 map = kcalloc(nmaps, sizeof(*map), GFP_KERNEL);
525 if (!map)
526 goto free_pgnames;
527
528 nmaps = 0;
529 ngroups = 0;
530 for_each_child_of_node(np, child) {
531 int npins;
532 int i;
533
534 ret = -ENOMEM;
535 grpname = devm_kasprintf(dev, GFP_KERNEL, "%s.%s", np->name, child->name);
536 if (!grpname)
537 goto put_child;
538
539 pgnames[ngroups++] = grpname;
540
541 if ((npins = of_property_count_u32_elems(child, "pinmux")) > 0) {
542 pins = devm_kcalloc(dev, npins, sizeof(*pins), GFP_KERNEL);
543 if (!pins)
544 goto free_grpname;
545
546 pinmux = devm_kcalloc(dev, npins, sizeof(*pinmux), GFP_KERNEL);
547 if (!pinmux)
548 goto free_pins;
549
550 for (i = 0; i < npins; i++) {
551 u32 v;
552
553 ret = of_property_read_u32_index(child, "pinmux", i, &v);
554 if (ret)
555 goto free_pinmux;
556 pins[i] = starfive_gpio_to_pin(sfp, starfive_pinmux_to_gpio(v));
557 pinmux[i] = v;
558 }
559
560 map[nmaps].type = PIN_MAP_TYPE_MUX_GROUP;
561 map[nmaps].data.mux.function = np->name;
562 map[nmaps].data.mux.group = grpname;
563 nmaps += 1;
564 } else if ((npins = of_property_count_u32_elems(child, "pins")) > 0) {
565 pins = devm_kcalloc(dev, npins, sizeof(*pins), GFP_KERNEL);
566 if (!pins)
567 goto free_grpname;
568
569 pinmux = NULL;
570
571 for (i = 0; i < npins; i++) {
572 u32 v;
573
574 ret = of_property_read_u32_index(child, "pins", i, &v);
575 if (ret)
576 goto free_pins;
577 pins[i] = v;
578 }
579 } else {
580 ret = -EINVAL;
581 goto free_grpname;
582 }
583
584 ret = pinctrl_generic_add_group(pctldev, grpname, pins, npins, pinmux);
585 if (ret < 0) {
586 dev_err(dev, "error adding group %pOFn.%pOFn: %d\n",
587 np, child, ret);
588 goto free_pinmux;
589 }
590
> 591 ret = pinconf_generic_parse_dt_config(child, pctldev, 592 &map[nmaps].data.configs.configs,
593 &map[nmaps].data.configs.num_configs);
594 if (ret) {
595 dev_err(dev, "invalid pinctrl group %pOFn.%pOFn: %s\n",
596 np, child, "error parsing pin config");
597 goto put_child;
598 }
599
600 /* don't create a map if there are no pinconf settings */
601 if (map[nmaps].data.configs.num_configs == 0)
602 continue;
603
604 map[nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
605 map[nmaps].data.configs.group_or_pin = grpname;
606 nmaps += 1;
607 }
608
609 ret = pinmux_generic_add_function(pctldev, np->name, pgnames, ngroups, NULL);
610 if (ret < 0) {
611 dev_err(dev, "error adding function %pOFn: %d\n", np, ret);
612 goto free_map;
613 }
614
615 *maps = map;
616 *num_maps = nmaps;
617 return 0;
618
619 free_pinmux:
620 devm_kfree(dev, pinmux);
621 free_pins:
622 devm_kfree(dev, pins);
623 free_grpname:
624 devm_kfree(dev, grpname);
625 put_child:
626 of_node_put(child);
627 free_map:
628 pinctrl_utils_free_map(pctldev, map, nmaps);
629 free_pgnames:
630 devm_kfree(dev, pgnames);
631 return ret;
632 }
633
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]
Emil Renner Berthing
maintainerPATCH v2 13/16 dt-bindings: serial: snps-dw-apb-uart: Add JH7100 uarts
In reply to Emil Renner BerthingAdd compatibles for the StarFive JH7100 uarts.
--- .../devicetree/bindings/serial/snps-dw-apb-uart.yaml | 5 +++++ 1 file changed, 5 insertions(+)
Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml +5 -0
@@ -40,6 +40,11 @@ properties: - brcm,bcm11351-dw-apb-uart - brcm,bcm21664-dw-apb-uart - const: snps,dw-apb-uart + - items: + - enum: + - starfive,jh7100-hsuart + - starfive,jh7100-uart + - const: snps,dw-apb-uart - const: snps,dw-apb-uart reg:
Signature · 7 lines
2.33.1 _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv
Re: [PATCH v2 13/16] dt-bindings: serial: snps-dw-apb-uart: Add JH7100 uarts
Quoted 8 lines · Emil Renner Berthing
Add compatibles for the StarFive JH7100 uarts.
Signed-off-by Emil Renner Berthing <[email protected]>Reviewed-by Geert Uytterhoeven <[email protected]>--- .../devicetree/bindings/serial/snps-dw-apb-uart.yaml | 5 +++++ 1 file changed, 5 insertions(+)
Emil Renner Berthing
maintainerPATCH v2 14/16 serial: 8250_dw: Add skip_clk_set_rate quirk
In reply to Emil Renner BerthingOn the StarFive JH7100 SoC the UART core clocks can't be set to exactly 16 * 115200Hz and many other common bitrates. Trying this will only result in a higher input clock, but low enough that the UART's internal divisor can't come close enough to the baud rate target. So rather than try to set the input clock it's better to rely solely on the UART's internal divisor.
--- drivers/tty/serial/8250/8250_dw.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
drivers/tty/serial/8250/8250_dw.c +16 -3
@@ -50,6 +50,7 @@ struct dw8250_data {struct reset_control *rst; unsigned int skip_autocfg:1; + unsigned int skip_clk_set_rate:1; unsigned int uart_16550_compatible:1; };
@@ -326,14 +327,18 @@ dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old)pm_runtime_put_sync_suspend (port->dev); } -static void dw8250_set_termios (struct uart_port *p,struct ktermios *termios, -struct ktermios *old) +static void dw8250_do_clk_set_rate (struct uart_port *p,struct ktermios *termios) { -unsigned long newrate =tty_termios_baud_rate (termios) *16 ;struct dw8250_data *d =to_dw8250_data (p->private_data); +unsigned long newrate;long rate;int ret; +if (d->skip_clk_set_rate) +return ; + + newrate =tty_termios_baud_rate (termios) *16 ; +clk_disable_unprepare (d->clk); rate =clk_round_rate (d->clk, newrate);if (rate >0 ) {
@@ -349,7 +354,12 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,swap (p->uartclk, rate); }clk_prepare_enable (d->clk); +} +static void dw8250_set_termios (struct uart_port *p,struct ktermios *termios, +struct ktermios *old) +{ +dw8250_do_clk_set_rate (p, termios);dw8250_do_set_termios (p, termios, old); }
@@ -417,6 +427,8 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data)if (of_device_is_compatible (np,"marvell,armada-38x-uart" )) p->serial_out = dw8250_serial_out38x; +if (of_device_is_compatible (np,"starfive,jh7100-uart" )) + data->skip_clk_set_rate = true; }else if (acpi_dev_present ("APMC0D08" ,NULL ,-1 )) { p->iotype =UPIO_MEM32 ;
@@ -699,6 +711,7 @@ static const struct of_device_id dw8250_of_match[] = { { .compatible = "cavium,octeon-3860-uart" }, { .compatible = "marvell,armada-38x-uart" }, { .compatible = "renesas,rzn1-uart" }, + { .compatible = "starfive,jh7100-uart" }, {/* Sentinel */ } };MODULE_DEVICE_TABLE (of, dw8250_of_match);
Signature · 7 lines
2.33.1 _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv
Emil Renner Berthing
maintainerPATCH v2 15/16 RISC-V: Add initial StarFive JH7100 device tree
In reply to Emil Renner BerthingAdd initial device tree for the StarFive JH7100 SoC.
The CPU and cache data is based on the device tree in the vendor u-boot port.
--- arch/riscv/boot/dts/starfive/jh7100.dtsi | 228 +++++++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 arch/riscv/boot/dts/starfive/jh7100.dtsi
arch/riscv/boot/dts/starfive/jh7100.dtsi new file +228 -0
@@ -0,0 +1,228 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* Copyright (c) 2021 StarFive Technology Co., Ltd. */ +/* Copyright (c) 2021 Emil Renner Berthing <[email protected]> */ + +/dts-v1/; +#include <dt-bindings/clock/starfive-jh7100.h> +#include <dt-bindings/reset/starfive-jh7100.h> + +/ { + compatible = "starfive,jh7100"; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "sifive,u74-mc", "riscv"; + reg = <0>; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <32>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <64>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <32>; + mmu-type = "riscv,sv39"; + riscv,isa = "rv64imafdc"; + tlb-split; + + cpu0_intc: interrupt-controller { + compatible = "riscv,cpu-intc"; + interrupt-controller; + #interrupt-cells = <1>; + }; + }; + + cpu@1 { + compatible = "sifive,u74-mc", "riscv"; + reg = <1>; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <32>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <64>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <32>; + mmu-type = "riscv,sv39"; + riscv,isa = "rv64imafdc"; + tlb-split; + + cpu1_intc: interrupt-controller { + compatible = "riscv,cpu-intc"; + interrupt-controller; + #interrupt-cells = <1>; + }; + }; + }; + + osc_sys: osc_sys { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board */ + clock-frequency = <0>; + }; + + osc_aud: osc_aud { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board */ + clock-frequency = <0>; + }; + + gmac_rmii_ref: gmac_rmii_ref { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* Should be overridden by the board when needed */ + clock-frequency = <0>; + }; + + gmac_gr_mii_rxclk: gmac_gr_mii_rxclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* Should be overridden by the board when needed */ + clock-frequency = <0>; + }; + + soc { + compatible = "simple-bus"; + interrupt-parent = <&plic>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + clint: clint@2000000 { + compatible = "starfive,jh7100-clint", "sifive,clint0"; + reg = <0x0 0x2000000 0x0 0x10000>; + interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7 + &cpu1_intc 3 &cpu1_intc 7>; + }; + + plic: interrupt-controller@c000000 { + compatible = "starfive,jh7100-plic", "sifive,plic-1.0.0"; + reg = <0x0 0xc000000 0x0 0x4000000>; + interrupts-extended = <&cpu0_intc 11 &cpu0_intc 9 + &cpu1_intc 11 &cpu1_intc 9>; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + riscv,ndev = <127>; + }; + + clkgen: clock-controller@11800000 { + compatible = "starfive,jh7100-clkgen"; + reg = <0x0 0x11800000 0x0 0x10000>; + clocks = <&osc_sys>, <&osc_aud>, <&gmac_rmii_ref>, <&gmac_gr_mii_rxclk>; + clock-names = "osc_sys", "osc_aud", "gmac_rmii_ref", "gmac_gr_mii_rxclk"; + #clock-cells = <1>; + }; + + rstgen: reset-controller@11840000 { + compatible = "starfive,jh7100-reset"; + reg = <0x0 0x11840000 0x0 0x10000>; + #reset-cells = <1>; + }; + + i2c0: i2c@118b0000 { + compatible = "snps,designware-i2c"; + reg = <0x0 0x118b0000 0x0 0x10000>; + clocks = <&clkgen JH7100_CLK_I2C0_CORE>, + <&clkgen JH7100_CLK_I2C0_APB>; + clock-names = "ref", "pclk"; + resets = <&rstgen JH7100_RSTN_I2C0_APB>; + interrupts = <96>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c1: i2c@118c0000 { + compatible = "snps,designware-i2c"; + reg = <0x0 0x118c0000 0x0 0x10000>; + clocks = <&clkgen JH7100_CLK_I2C1_CORE>, + <&clkgen JH7100_CLK_I2C1_APB>; + clock-names = "ref", "pclk"; + resets = <&rstgen JH7100_RSTN_I2C1_APB>; + interrupts = <97>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + gpio: pinctrl@11910000 { + compatible = "starfive,jh7100-pinctrl"; + reg = <0x0 0x11910000 0x0 0x10000>, + <0x0 0x11858000 0x0 0x1000>; + reg-names = "gpio", "padctl"; + clocks = <&clkgen JH7100_CLK_GPIO_APB>; + resets = <&rstgen JH7100_RSTN_GPIO_APB>; + interrupts = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + uart2: serial@12430000 { + compatible = "starfive,jh7100-uart", "snps,dw-apb-uart"; + reg = <0x0 0x12430000 0x0 0x10000>; + clocks = <&clkgen JH7100_CLK_UART2_CORE>, + <&clkgen JH7100_CLK_UART2_APB>; + clock-names = "baudclk", "apb_pclk"; + resets = <&rstgen JH7100_RSTN_UART2_APB>; + interrupts = <72>; + reg-io-width = <4>; + reg-shift = <2>; + status = "disabled"; + }; + + uart3: serial@12440000 { + compatible = "starfive,jh7100-uart", "snps,dw-apb-uart"; + reg = <0x0 0x12440000 0x0 0x10000>; + clocks = <&clkgen JH7100_CLK_UART3_CORE>, + <&clkgen JH7100_CLK_UART3_APB>; + clock-names = "baudclk", "apb_pclk"; + resets = <&rstgen JH7100_RSTN_UART3_APB>; + interrupts = <73>; + reg-io-width = <4>; + reg-shift = <2>; + status = "disabled"; + }; + + i2c2: i2c@12450000 { + compatible = "snps,designware-i2c"; + reg = <0x0 0x12450000 0x0 0x10000>; + clocks = <&clkgen JH7100_CLK_I2C2_CORE>, + <&clkgen JH7100_CLK_I2C2_APB>; + clock-names = "ref", "pclk"; + resets = <&rstgen JH7100_RSTN_I2C2_APB>; + interrupts = <74>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c3: i2c@12460000 { + compatible = "snps,designware-i2c"; + reg = <0x0 0x12460000 0x0 0x10000>; + clocks = <&clkgen JH7100_CLK_I2C3_CORE>, + <&clkgen JH7100_CLK_I2C3_APB>; + clock-names = "ref", "pclk"; + resets = <&rstgen JH7100_RSTN_I2C3_APB>; + interrupts = <75>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; +};
Signature · 7 lines
2.33.1 _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv
Emil Renner Berthing
maintainerPATCH v2 16/16 RISC-V: Add BeagleV Starlight Beta device tree
In reply to Emil Renner BerthingAdd initial device tree for the BeagleV Starlight Beta board. About 300 of these boards were sent out as part of a now cancelled BeagleBoard.org project.
I2C timing data is based on the device tree in the vendor u-boot port. Heartbeat LED added by Geert.
--- arch/riscv/boot/dts/Makefile | 1 + arch/riscv/boot/dts/starfive/Makefile | 2 + .../dts/starfive/jh7100-beaglev-starlight.dts | 162 ++++++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 arch/riscv/boot/dts/starfive/Makefile create mode 100644 arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
arch/riscv/boot/dts/Makefile +1 -0
@@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 subdir-y += sifive +subdir-y += starfive subdir-$(CONFIG_SOC_CANAAN_K210_DTB_BUILTIN) += canaan subdir-y += microchip
arch/riscv/boot/dts/starfive/Makefile new file +2 -0
@@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +dtb-$(CONFIG_SOC_STARFIVE) += jh7100-beaglev-starlight.dtb
arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts new file +162 -0
162 lines not on this page · raw message
Signature · 7 lines
2.33.1 _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv