* [PATCH v20 00/11] Add Sunplus SP7021 SoC Support
@ 2022-06-28 6:26 ` Qin Jian
0 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian
This patch series add Sunplus SP7021 SoC support.
Sunplus SP7021 is an ARM Cortex A7 (4 cores) based SoC. It integrates many
peripherals (ex: UART, I2C, SPI, SDIO, eMMC, USB, SD card and etc.) into a
single chip. It is designed for industrial control.
SP7021 consists of two chips (dies) in a package. One is called C-chip
(computing chip). It is a 4-core ARM Cortex A7 CPU. It adopts high-level
process (22 nm) for high performance computing. The other is called P-
chip (peripheral chip). It has many peripherals and an ARM A926 added
especially for real-time control. P-chip is made for customers. It adopts
low-level process (ex: 0.11 um) to reduce cost.
Refer to (for documentations):
https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
Refer to (applications):
https://tibbo.com/store/plus1.html
Refer to (applications):
http://www.sinovoip.com.cn/ecp_view.asp?id=586
Changes in v20:
- Based on 5.19-rc4 & resend
Changes in v19:
- clk-provider.h: Add devm_clk_hw_register_gate_parent_data()
- clk-sp7021.c: Addressed Stephen's comments
- board dts: Addressed Arnd's comments
Changes in v18:
- Fixed the tags
- board dts: Fix the comments from Krzysztof
Changes in v17:
- Based on 5.18.1 & resend
Changes in v16:
- clk-sp7021.c: Fix the comments from Stephen Boyd
- board dts: Fix the comments from Krzysztof
Changes in v15:
- Add Sunplus SP7021-demo-v3 board dts
- Refine yaml title
- Rename dt-binding header filename to match compatible string
Changes in v14:
- clock/sp-sp7021.h: Fix the comments from Krzysztof
- sunplus,sp7021-clkc.yaml: Fix the comments from Rob
Changes in v13:
- reset/sp-sp7021.h: Move HW mapping from dt-binding header to driver
- reset-sunplus.c: Move HW mapping from dt-binding header to driver
- clock/sp-sp7021.h: Move HW mapping from dt-binding header to driver
- clk-sp7021.c: Fix the comments from Arnd
- irq-sp7021-intc.c: Remove empty set_affinity callback function
- sp7021_defconfig: Fix the comments from Arnd
Changes in v12:
- sunplus,sp7021-clkc.yaml: Move 'reg' after 'compatible'
- sunplus,sp7021-intc.yaml: Move 'reg' after 'compatible'
- sunplus,reset.yaml: Move 'reg' after 'compatible'
- Remove wrong reviewed-tags
Changes in v11:
- clk-sp7021.c: Remove the dead code
Changes in v10:
- arm/sunplus,sp7021.yaml: Add SoC compatible: "sunplus,sp7021"
- clock/sunplus,sp7021-clkc.yaml: Remove the internal clock parent from DTS
- clk-sp7021.c: Refine the macro DBG_CLK
- clk-sp7021.c: Refine the clock_parent_data
Changes in v9:
- clk/Kconfig: fix the comments form Stephen Boyd
- clk-sp7021.c: fix the comments form Stephen Boyd
Changes in v8:
- clk-sp7021.c: fix the comments form Stephen Boyd
Changes in v7:
- sunplus,sp7021-clkc.yaml: Add clocks & clock-names
- clk-sp7021.c: fix the comments form Stephen Boyd
- irq-sp7021-intc.c: fix the comments from Marc
Changes in v6:
- reset-sunplus.c: fix the comments from Philipp
- irq-sp7021-intc.c: fix the comments from Marc
- mach-sunplus: fix the comments from Arnd
Changes in v5:
- reset-sunplus.c: fix strict checks
- clk/Kconfig: fix spell
- clk-sp7021.c: using bitfield ops, fix strict checks
- irqchip/Kconfig: fix spell
- irq-sp7021-intc.c: cleanup error path in probe, fix strict checks
- arm/Kconfig: fix spell & typo, remove CONFIG_SERIAL_SUNPLUS
- mach-sunplus/Kconfig: fix typo
- sp7021_defconfig: add CONFIG_SERIAL_SUNPLUS
Changes in v4:
- mach-sunplus: add initial support for SP7021
- sp7021_defconfig: add generic SP7021 defconfig
- reset-sunplus: remove Q645 support
- reset-sunplus.c: refine code based on Philipp's review
- clk-sp7021: clock defines add prefix, more clean up
Changes in v3:
- sp7021-intc: remove primary controller mode due to P-chip running Linux
not supported any more.
- sp7021-intc.h: removed, not set ext through the DT but sp_intc_set_ext()
- sunplus,sp7021-intc.yaml: update descriptions for above changes
- irq-sp7021-intc.c: more cleanup based on Marc's review
- all driver's Kconfig removed default, it's selected by platform config
Changes in v2:
- sunplus,sp7021-intc.yaml: add descrption for "#interrupt-cells", interrupts
- sunplus,sp7021-intc.yaml: drop "ext0-mask"/"ext1-mask" from DT
- sunplus,sp7021-intc.yaml: fix example.dt too long error
- irq-sp7021-intc.c: major rewrite
- all files with dual license
Qin Jian (11):
dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards
dt-bindings: reset: Add bindings for SP7021 reset driver
reset: Add Sunplus SP7021 reset driver
dt-bindings: clock: Add bindings for SP7021 clock driver
clk: gate: Add devm_clk_hw_register_gate_parent_data()
clk: Add Sunplus SP7021 clock driver
dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt
controller
irqchip: Add Sunplus SP7021 interrupt controller driver
ARM: sunplus: Add initial support for Sunplus SP7021 SoC
ARM: sp7021_defconfig: Add Sunplus SP7021 defconfig
ARM: dts: Add Sunplus SP7021-Demo-V3 board device tree
.../bindings/arm/sunplus,sp7021.yaml | 29 +
.../bindings/clock/sunplus,sp7021-clkc.yaml | 52 ++
.../sunplus,sp7021-intc.yaml | 62 ++
.../bindings/reset/sunplus,reset.yaml | 38 +
MAINTAINERS | 18 +
arch/arm/Kconfig | 2 +
arch/arm/Makefile | 1 +
arch/arm/boot/dts/Makefile | 2 +
arch/arm/boot/dts/sunplus-sp7021-achip.dtsi | 84 +++
arch/arm/boot/dts/sunplus-sp7021-demo-v3.dts | 30 +
arch/arm/boot/dts/sunplus-sp7021.dtsi | 310 ++++++++
arch/arm/configs/multi_v7_defconfig | 1 +
arch/arm/configs/sp7021_defconfig | 59 ++
arch/arm/mach-sunplus/Kconfig | 27 +
arch/arm/mach-sunplus/Makefile | 8 +
arch/arm/mach-sunplus/sp7021.c | 16 +
drivers/clk/Kconfig | 10 +
drivers/clk/Makefile | 1 +
drivers/clk/clk-sp7021.c | 713 ++++++++++++++++++
drivers/irqchip/Kconfig | 9 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-sp7021-intc.c | 278 +++++++
drivers/reset/Kconfig | 9 +
drivers/reset/Makefile | 1 +
drivers/reset/reset-sunplus.c | 212 ++++++
.../dt-bindings/clock/sunplus,sp7021-clkc.h | 88 +++
.../dt-bindings/reset/sunplus,sp7021-reset.h | 87 +++
include/linux/clk-provider.h | 17 +
28 files changed, 2165 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
create mode 100644 Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
create mode 100644 Documentation/devicetree/bindings/reset/sunplus,reset.yaml
create mode 100644 arch/arm/boot/dts/sunplus-sp7021-achip.dtsi
create mode 100644 arch/arm/boot/dts/sunplus-sp7021-demo-v3.dts
create mode 100644 arch/arm/boot/dts/sunplus-sp7021.dtsi
create mode 100644 arch/arm/configs/sp7021_defconfig
create mode 100644 arch/arm/mach-sunplus/Kconfig
create mode 100644 arch/arm/mach-sunplus/Makefile
create mode 100644 arch/arm/mach-sunplus/sp7021.c
create mode 100644 drivers/clk/clk-sp7021.c
create mode 100644 drivers/irqchip/irq-sp7021-intc.c
create mode 100644 drivers/reset/reset-sunplus.c
create mode 100644 include/dt-bindings/clock/sunplus,sp7021-clkc.h
create mode 100644 include/dt-bindings/reset/sunplus,sp7021-reset.h
--
2.33.1
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v20 00/11] Add Sunplus SP7021 SoC Support
@ 2022-06-28 6:26 ` Qin Jian
0 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian
This patch series add Sunplus SP7021 SoC support.
Sunplus SP7021 is an ARM Cortex A7 (4 cores) based SoC. It integrates many
peripherals (ex: UART, I2C, SPI, SDIO, eMMC, USB, SD card and etc.) into a
single chip. It is designed for industrial control.
SP7021 consists of two chips (dies) in a package. One is called C-chip
(computing chip). It is a 4-core ARM Cortex A7 CPU. It adopts high-level
process (22 nm) for high performance computing. The other is called P-
chip (peripheral chip). It has many peripherals and an ARM A926 added
especially for real-time control. P-chip is made for customers. It adopts
low-level process (ex: 0.11 um) to reduce cost.
Refer to (for documentations):
https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
Refer to (applications):
https://tibbo.com/store/plus1.html
Refer to (applications):
http://www.sinovoip.com.cn/ecp_view.asp?id=586
Changes in v20:
- Based on 5.19-rc4 & resend
Changes in v19:
- clk-provider.h: Add devm_clk_hw_register_gate_parent_data()
- clk-sp7021.c: Addressed Stephen's comments
- board dts: Addressed Arnd's comments
Changes in v18:
- Fixed the tags
- board dts: Fix the comments from Krzysztof
Changes in v17:
- Based on 5.18.1 & resend
Changes in v16:
- clk-sp7021.c: Fix the comments from Stephen Boyd
- board dts: Fix the comments from Krzysztof
Changes in v15:
- Add Sunplus SP7021-demo-v3 board dts
- Refine yaml title
- Rename dt-binding header filename to match compatible string
Changes in v14:
- clock/sp-sp7021.h: Fix the comments from Krzysztof
- sunplus,sp7021-clkc.yaml: Fix the comments from Rob
Changes in v13:
- reset/sp-sp7021.h: Move HW mapping from dt-binding header to driver
- reset-sunplus.c: Move HW mapping from dt-binding header to driver
- clock/sp-sp7021.h: Move HW mapping from dt-binding header to driver
- clk-sp7021.c: Fix the comments from Arnd
- irq-sp7021-intc.c: Remove empty set_affinity callback function
- sp7021_defconfig: Fix the comments from Arnd
Changes in v12:
- sunplus,sp7021-clkc.yaml: Move 'reg' after 'compatible'
- sunplus,sp7021-intc.yaml: Move 'reg' after 'compatible'
- sunplus,reset.yaml: Move 'reg' after 'compatible'
- Remove wrong reviewed-tags
Changes in v11:
- clk-sp7021.c: Remove the dead code
Changes in v10:
- arm/sunplus,sp7021.yaml: Add SoC compatible: "sunplus,sp7021"
- clock/sunplus,sp7021-clkc.yaml: Remove the internal clock parent from DTS
- clk-sp7021.c: Refine the macro DBG_CLK
- clk-sp7021.c: Refine the clock_parent_data
Changes in v9:
- clk/Kconfig: fix the comments form Stephen Boyd
- clk-sp7021.c: fix the comments form Stephen Boyd
Changes in v8:
- clk-sp7021.c: fix the comments form Stephen Boyd
Changes in v7:
- sunplus,sp7021-clkc.yaml: Add clocks & clock-names
- clk-sp7021.c: fix the comments form Stephen Boyd
- irq-sp7021-intc.c: fix the comments from Marc
Changes in v6:
- reset-sunplus.c: fix the comments from Philipp
- irq-sp7021-intc.c: fix the comments from Marc
- mach-sunplus: fix the comments from Arnd
Changes in v5:
- reset-sunplus.c: fix strict checks
- clk/Kconfig: fix spell
- clk-sp7021.c: using bitfield ops, fix strict checks
- irqchip/Kconfig: fix spell
- irq-sp7021-intc.c: cleanup error path in probe, fix strict checks
- arm/Kconfig: fix spell & typo, remove CONFIG_SERIAL_SUNPLUS
- mach-sunplus/Kconfig: fix typo
- sp7021_defconfig: add CONFIG_SERIAL_SUNPLUS
Changes in v4:
- mach-sunplus: add initial support for SP7021
- sp7021_defconfig: add generic SP7021 defconfig
- reset-sunplus: remove Q645 support
- reset-sunplus.c: refine code based on Philipp's review
- clk-sp7021: clock defines add prefix, more clean up
Changes in v3:
- sp7021-intc: remove primary controller mode due to P-chip running Linux
not supported any more.
- sp7021-intc.h: removed, not set ext through the DT but sp_intc_set_ext()
- sunplus,sp7021-intc.yaml: update descriptions for above changes
- irq-sp7021-intc.c: more cleanup based on Marc's review
- all driver's Kconfig removed default, it's selected by platform config
Changes in v2:
- sunplus,sp7021-intc.yaml: add descrption for "#interrupt-cells", interrupts
- sunplus,sp7021-intc.yaml: drop "ext0-mask"/"ext1-mask" from DT
- sunplus,sp7021-intc.yaml: fix example.dt too long error
- irq-sp7021-intc.c: major rewrite
- all files with dual license
Qin Jian (11):
dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards
dt-bindings: reset: Add bindings for SP7021 reset driver
reset: Add Sunplus SP7021 reset driver
dt-bindings: clock: Add bindings for SP7021 clock driver
clk: gate: Add devm_clk_hw_register_gate_parent_data()
clk: Add Sunplus SP7021 clock driver
dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt
controller
irqchip: Add Sunplus SP7021 interrupt controller driver
ARM: sunplus: Add initial support for Sunplus SP7021 SoC
ARM: sp7021_defconfig: Add Sunplus SP7021 defconfig
ARM: dts: Add Sunplus SP7021-Demo-V3 board device tree
.../bindings/arm/sunplus,sp7021.yaml | 29 +
.../bindings/clock/sunplus,sp7021-clkc.yaml | 52 ++
.../sunplus,sp7021-intc.yaml | 62 ++
.../bindings/reset/sunplus,reset.yaml | 38 +
MAINTAINERS | 18 +
arch/arm/Kconfig | 2 +
arch/arm/Makefile | 1 +
arch/arm/boot/dts/Makefile | 2 +
arch/arm/boot/dts/sunplus-sp7021-achip.dtsi | 84 +++
arch/arm/boot/dts/sunplus-sp7021-demo-v3.dts | 30 +
arch/arm/boot/dts/sunplus-sp7021.dtsi | 310 ++++++++
arch/arm/configs/multi_v7_defconfig | 1 +
arch/arm/configs/sp7021_defconfig | 59 ++
arch/arm/mach-sunplus/Kconfig | 27 +
arch/arm/mach-sunplus/Makefile | 8 +
arch/arm/mach-sunplus/sp7021.c | 16 +
drivers/clk/Kconfig | 10 +
drivers/clk/Makefile | 1 +
drivers/clk/clk-sp7021.c | 713 ++++++++++++++++++
drivers/irqchip/Kconfig | 9 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-sp7021-intc.c | 278 +++++++
drivers/reset/Kconfig | 9 +
drivers/reset/Makefile | 1 +
drivers/reset/reset-sunplus.c | 212 ++++++
.../dt-bindings/clock/sunplus,sp7021-clkc.h | 88 +++
.../dt-bindings/reset/sunplus,sp7021-reset.h | 87 +++
include/linux/clk-provider.h | 17 +
28 files changed, 2165 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
create mode 100644 Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
create mode 100644 Documentation/devicetree/bindings/reset/sunplus,reset.yaml
create mode 100644 arch/arm/boot/dts/sunplus-sp7021-achip.dtsi
create mode 100644 arch/arm/boot/dts/sunplus-sp7021-demo-v3.dts
create mode 100644 arch/arm/boot/dts/sunplus-sp7021.dtsi
create mode 100644 arch/arm/configs/sp7021_defconfig
create mode 100644 arch/arm/mach-sunplus/Kconfig
create mode 100644 arch/arm/mach-sunplus/Makefile
create mode 100644 arch/arm/mach-sunplus/sp7021.c
create mode 100644 drivers/clk/clk-sp7021.c
create mode 100644 drivers/irqchip/irq-sp7021-intc.c
create mode 100644 drivers/reset/reset-sunplus.c
create mode 100644 include/dt-bindings/clock/sunplus,sp7021-clkc.h
create mode 100644 include/dt-bindings/reset/sunplus,sp7021-reset.h
--
2.33.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v20 01/11] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards
2022-06-28 6:26 ` Qin Jian
@ 2022-06-28 6:26 ` Qin Jian
-1 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian, Rob Herring, Krzysztof Kozlowski
This introduces bindings for boards based Sunplus SP7021 SoC.
Acked-by: Rob Herring <robh@kernel.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
.../bindings/arm/sunplus,sp7021.yaml | 29 +++++++++++++++++++
MAINTAINERS | 7 +++++
2 files changed, 36 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
diff --git a/Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml b/Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
new file mode 100644
index 000000000..def7d0cfe
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) Sunplus Co., Ltd. 2021
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/sunplus,sp7021.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sunplus SP7021 Boards
+
+maintainers:
+ - qinjian <qinjian@cqplus1.com>
+
+description: |
+ ARM platforms using Sunplus SP7021, an ARM Cortex A7 (4-cores) based SoC.
+ Wiki: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
+
+properties:
+ $nodename:
+ const: '/'
+ compatible:
+ items:
+ - enum:
+ - sunplus,sp7021-achip
+ - sunplus,sp7021-demo-v3
+ - const: sunplus,sp7021
+
+additionalProperties: true
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index fe5daf141..3258a4d1a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2825,6 +2825,13 @@ F: drivers/clocksource/armv7m_systick.c
N: stm32
N: stm
+ARM/SUNPLUS SP7021 SOC SUPPORT
+M: Qin Jian <qinjian@cqplus1.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for mon-subscribers)
+S: Maintained
+W: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
+F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
+
ARM/Synaptics SoC support
M: Jisheng Zhang <jszhang@kernel.org>
M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
--
2.33.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 01/11] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards
@ 2022-06-28 6:26 ` Qin Jian
0 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian, Rob Herring, Krzysztof Kozlowski
This introduces bindings for boards based Sunplus SP7021 SoC.
Acked-by: Rob Herring <robh@kernel.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
.../bindings/arm/sunplus,sp7021.yaml | 29 +++++++++++++++++++
MAINTAINERS | 7 +++++
2 files changed, 36 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
diff --git a/Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml b/Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
new file mode 100644
index 000000000..def7d0cfe
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) Sunplus Co., Ltd. 2021
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/sunplus,sp7021.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sunplus SP7021 Boards
+
+maintainers:
+ - qinjian <qinjian@cqplus1.com>
+
+description: |
+ ARM platforms using Sunplus SP7021, an ARM Cortex A7 (4-cores) based SoC.
+ Wiki: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
+
+properties:
+ $nodename:
+ const: '/'
+ compatible:
+ items:
+ - enum:
+ - sunplus,sp7021-achip
+ - sunplus,sp7021-demo-v3
+ - const: sunplus,sp7021
+
+additionalProperties: true
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index fe5daf141..3258a4d1a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2825,6 +2825,13 @@ F: drivers/clocksource/armv7m_systick.c
N: stm32
N: stm
+ARM/SUNPLUS SP7021 SOC SUPPORT
+M: Qin Jian <qinjian@cqplus1.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for mon-subscribers)
+S: Maintained
+W: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
+F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
+
ARM/Synaptics SoC support
M: Jisheng Zhang <jszhang@kernel.org>
M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
--
2.33.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 02/11] dt-bindings: reset: Add bindings for SP7021 reset driver
2022-06-28 6:26 ` Qin Jian
@ 2022-06-28 6:26 ` Qin Jian
-1 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian, Rob Herring, Krzysztof Kozlowski
Add documentation to describe Sunplus SP7021 reset driver bindings.
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
.../bindings/reset/sunplus,reset.yaml | 38 ++++++++
MAINTAINERS | 2 +
.../dt-bindings/reset/sunplus,sp7021-reset.h | 87 +++++++++++++++++++
3 files changed, 127 insertions(+)
create mode 100644 Documentation/devicetree/bindings/reset/sunplus,reset.yaml
create mode 100644 include/dt-bindings/reset/sunplus,sp7021-reset.h
diff --git a/Documentation/devicetree/bindings/reset/sunplus,reset.yaml b/Documentation/devicetree/bindings/reset/sunplus,reset.yaml
new file mode 100644
index 000000000..f24646ba9
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/sunplus,reset.yaml
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) Sunplus Co., Ltd. 2021
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/reset/sunplus,reset.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Sunplus SoC Reset Controller
+
+maintainers:
+ - Qin Jian <qinjian@cqplus1.com>
+
+properties:
+ compatible:
+ const: sunplus,sp7021-reset
+
+ reg:
+ maxItems: 1
+
+ "#reset-cells":
+ const: 1
+
+required:
+ - compatible
+ - reg
+ - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ rstc: reset@9c000054 {
+ compatible = "sunplus,sp7021-reset";
+ reg = <0x9c000054 0x28>;
+ #reset-cells = <1>;
+ };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 3258a4d1a..d24ef0b09 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2831,6 +2831,8 @@ L: linux-arm-kernel@lists.infradead.org (moderated for mon-subscribers)
S: Maintained
W: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
+F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml
+F: include/dt-bindings/reset/sunplus,sp7021-reset.h
ARM/Synaptics SoC support
M: Jisheng Zhang <jszhang@kernel.org>
diff --git a/include/dt-bindings/reset/sunplus,sp7021-reset.h b/include/dt-bindings/reset/sunplus,sp7021-reset.h
new file mode 100644
index 000000000..ab4867073
--- /dev/null
+++ b/include/dt-bindings/reset/sunplus,sp7021-reset.h
@@ -0,0 +1,87 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ * All rights reserved.
+ */
+#ifndef _DT_BINDINGS_RST_SUNPLUS_SP7021_H
+#define _DT_BINDINGS_RST_SUNPLUS_SP7021_H
+
+#define RST_SYSTEM 0
+#define RST_RTC 1
+#define RST_IOCTL 2
+#define RST_IOP 3
+#define RST_OTPRX 4
+#define RST_NOC 5
+#define RST_BR 6
+#define RST_RBUS_L00 7
+#define RST_SPIFL 8
+#define RST_SDCTRL0 9
+#define RST_PERI0 10
+#define RST_A926 11
+#define RST_UMCTL2 12
+#define RST_PERI1 13
+#define RST_DDR_PHY0 14
+#define RST_ACHIP 15
+#define RST_STC0 16
+#define RST_STC_AV0 17
+#define RST_STC_AV1 18
+#define RST_STC_AV2 19
+#define RST_UA0 20
+#define RST_UA1 21
+#define RST_UA2 22
+#define RST_UA3 23
+#define RST_UA4 24
+#define RST_HWUA 25
+#define RST_DDC0 26
+#define RST_UADMA 27
+#define RST_CBDMA0 28
+#define RST_CBDMA1 29
+#define RST_SPI_COMBO_0 30
+#define RST_SPI_COMBO_1 31
+#define RST_SPI_COMBO_2 32
+#define RST_SPI_COMBO_3 33
+#define RST_AUD 34
+#define RST_USBC0 35
+#define RST_USBC1 36
+#define RST_UPHY0 37
+#define RST_UPHY1 38
+#define RST_I2CM0 39
+#define RST_I2CM1 40
+#define RST_I2CM2 41
+#define RST_I2CM3 42
+#define RST_PMC 43
+#define RST_CARD_CTL0 44
+#define RST_CARD_CTL1 45
+#define RST_CARD_CTL4 46
+#define RST_BCH 47
+#define RST_DDFCH 48
+#define RST_CSIIW0 49
+#define RST_CSIIW1 50
+#define RST_MIPICSI0 51
+#define RST_MIPICSI1 52
+#define RST_HDMI_TX 53
+#define RST_VPOST 54
+#define RST_TGEN 55
+#define RST_DMIX 56
+#define RST_TCON 57
+#define RST_INTERRUPT 58
+#define RST_RGST 59
+#define RST_GPIO 60
+#define RST_RBUS_TOP 61
+#define RST_MAILBOX 62
+#define RST_SPIND 63
+#define RST_I2C2CBUS 64
+#define RST_SEC 65
+#define RST_DVE 66
+#define RST_GPOST0 67
+#define RST_OSD0 68
+#define RST_DISP_PWM 69
+#define RST_UADBG 70
+#define RST_DUMMY_MASTER 71
+#define RST_FIO_CTL 72
+#define RST_FPGA 73
+#define RST_L2SW 74
+#define RST_ICM 75
+#define RST_AXI_GLOBAL 76
+
+#endif
--
2.33.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 02/11] dt-bindings: reset: Add bindings for SP7021 reset driver
@ 2022-06-28 6:26 ` Qin Jian
0 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian, Rob Herring, Krzysztof Kozlowski
Add documentation to describe Sunplus SP7021 reset driver bindings.
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
.../bindings/reset/sunplus,reset.yaml | 38 ++++++++
MAINTAINERS | 2 +
.../dt-bindings/reset/sunplus,sp7021-reset.h | 87 +++++++++++++++++++
3 files changed, 127 insertions(+)
create mode 100644 Documentation/devicetree/bindings/reset/sunplus,reset.yaml
create mode 100644 include/dt-bindings/reset/sunplus,sp7021-reset.h
diff --git a/Documentation/devicetree/bindings/reset/sunplus,reset.yaml b/Documentation/devicetree/bindings/reset/sunplus,reset.yaml
new file mode 100644
index 000000000..f24646ba9
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/sunplus,reset.yaml
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) Sunplus Co., Ltd. 2021
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/reset/sunplus,reset.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Sunplus SoC Reset Controller
+
+maintainers:
+ - Qin Jian <qinjian@cqplus1.com>
+
+properties:
+ compatible:
+ const: sunplus,sp7021-reset
+
+ reg:
+ maxItems: 1
+
+ "#reset-cells":
+ const: 1
+
+required:
+ - compatible
+ - reg
+ - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ rstc: reset@9c000054 {
+ compatible = "sunplus,sp7021-reset";
+ reg = <0x9c000054 0x28>;
+ #reset-cells = <1>;
+ };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 3258a4d1a..d24ef0b09 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2831,6 +2831,8 @@ L: linux-arm-kernel@lists.infradead.org (moderated for mon-subscribers)
S: Maintained
W: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
+F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml
+F: include/dt-bindings/reset/sunplus,sp7021-reset.h
ARM/Synaptics SoC support
M: Jisheng Zhang <jszhang@kernel.org>
diff --git a/include/dt-bindings/reset/sunplus,sp7021-reset.h b/include/dt-bindings/reset/sunplus,sp7021-reset.h
new file mode 100644
index 000000000..ab4867073
--- /dev/null
+++ b/include/dt-bindings/reset/sunplus,sp7021-reset.h
@@ -0,0 +1,87 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ * All rights reserved.
+ */
+#ifndef _DT_BINDINGS_RST_SUNPLUS_SP7021_H
+#define _DT_BINDINGS_RST_SUNPLUS_SP7021_H
+
+#define RST_SYSTEM 0
+#define RST_RTC 1
+#define RST_IOCTL 2
+#define RST_IOP 3
+#define RST_OTPRX 4
+#define RST_NOC 5
+#define RST_BR 6
+#define RST_RBUS_L00 7
+#define RST_SPIFL 8
+#define RST_SDCTRL0 9
+#define RST_PERI0 10
+#define RST_A926 11
+#define RST_UMCTL2 12
+#define RST_PERI1 13
+#define RST_DDR_PHY0 14
+#define RST_ACHIP 15
+#define RST_STC0 16
+#define RST_STC_AV0 17
+#define RST_STC_AV1 18
+#define RST_STC_AV2 19
+#define RST_UA0 20
+#define RST_UA1 21
+#define RST_UA2 22
+#define RST_UA3 23
+#define RST_UA4 24
+#define RST_HWUA 25
+#define RST_DDC0 26
+#define RST_UADMA 27
+#define RST_CBDMA0 28
+#define RST_CBDMA1 29
+#define RST_SPI_COMBO_0 30
+#define RST_SPI_COMBO_1 31
+#define RST_SPI_COMBO_2 32
+#define RST_SPI_COMBO_3 33
+#define RST_AUD 34
+#define RST_USBC0 35
+#define RST_USBC1 36
+#define RST_UPHY0 37
+#define RST_UPHY1 38
+#define RST_I2CM0 39
+#define RST_I2CM1 40
+#define RST_I2CM2 41
+#define RST_I2CM3 42
+#define RST_PMC 43
+#define RST_CARD_CTL0 44
+#define RST_CARD_CTL1 45
+#define RST_CARD_CTL4 46
+#define RST_BCH 47
+#define RST_DDFCH 48
+#define RST_CSIIW0 49
+#define RST_CSIIW1 50
+#define RST_MIPICSI0 51
+#define RST_MIPICSI1 52
+#define RST_HDMI_TX 53
+#define RST_VPOST 54
+#define RST_TGEN 55
+#define RST_DMIX 56
+#define RST_TCON 57
+#define RST_INTERRUPT 58
+#define RST_RGST 59
+#define RST_GPIO 60
+#define RST_RBUS_TOP 61
+#define RST_MAILBOX 62
+#define RST_SPIND 63
+#define RST_I2C2CBUS 64
+#define RST_SEC 65
+#define RST_DVE 66
+#define RST_GPOST0 67
+#define RST_OSD0 68
+#define RST_DISP_PWM 69
+#define RST_UADBG 70
+#define RST_DUMMY_MASTER 71
+#define RST_FIO_CTL 72
+#define RST_FPGA 73
+#define RST_L2SW 74
+#define RST_ICM 75
+#define RST_AXI_GLOBAL 76
+
+#endif
--
2.33.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 03/11] reset: Add Sunplus SP7021 reset driver
2022-06-28 6:26 ` Qin Jian
@ 2022-06-28 6:26 ` Qin Jian
-1 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian, Philipp Zabel
Add reset driver for Sunplus SP7021 SoC.
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
MAINTAINERS | 1 +
drivers/reset/Kconfig | 9 ++
drivers/reset/Makefile | 1 +
drivers/reset/reset-sunplus.c | 212 ++++++++++++++++++++++++++++++++++
4 files changed, 223 insertions(+)
create mode 100644 drivers/reset/reset-sunplus.c
diff --git a/MAINTAINERS b/MAINTAINERS
index d24ef0b09..db00f5e50 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2832,6 +2832,7 @@ S: Maintained
W: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml
+F: drivers/reset/reset-sunplus.c
F: include/dt-bindings/reset/sunplus,sp7021-reset.h
ARM/Synaptics SoC support
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 93c8d07ee..48d94649e 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -231,6 +231,15 @@ config RESET_STARFIVE_JH7100
help
This enables the reset controller driver for the StarFive JH7100 SoC.
+config RESET_SUNPLUS
+ bool "Sunplus SoCs Reset Driver" if COMPILE_TEST
+ default ARCH_SUNPLUS
+ help
+ This enables the reset driver support for Sunplus SoCs.
+ The reset lines that can be asserted and deasserted by toggling bits
+ in a contiguous, exclusive register space. The register is HIWORD_MASKED,
+ which means each register holds 16 reset lines.
+
config RESET_SUNXI
bool "Allwinner SoCs Reset Driver" if COMPILE_TEST && !ARCH_SUNXI
default ARCH_SUNXI
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index a80a9c400..3ff378f43 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -30,6 +30,7 @@ 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_SUNPLUS) += reset-sunplus.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
diff --git a/drivers/reset/reset-sunplus.c b/drivers/reset/reset-sunplus.c
new file mode 100644
index 000000000..2f23ecaa7
--- /dev/null
+++ b/drivers/reset/reset-sunplus.c
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * SP7021 reset driver
+ *
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ * All rights reserved.
+ */
+
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/reboot.h>
+
+/* HIWORD_MASK_REG BITS */
+#define BITS_PER_HWM_REG 16
+
+/* resets HW info: reg_index_shift */
+static const u32 sp_resets[] = {
+/* SP7021: mo_reset0 ~ mo_reset9 */
+ 0x00,
+ 0x02,
+ 0x03,
+ 0x04,
+ 0x05,
+ 0x06,
+ 0x07,
+ 0x08,
+ 0x09,
+ 0x0a,
+ 0x0b,
+ 0x0d,
+ 0x0e,
+ 0x0f,
+ 0x10,
+ 0x12,
+ 0x14,
+ 0x15,
+ 0x16,
+ 0x17,
+ 0x18,
+ 0x19,
+ 0x1a,
+ 0x1b,
+ 0x1c,
+ 0x1d,
+ 0x1e,
+ 0x1f,
+ 0x20,
+ 0x21,
+ 0x22,
+ 0x23,
+ 0x24,
+ 0x25,
+ 0x26,
+ 0x2a,
+ 0x2b,
+ 0x2d,
+ 0x2e,
+ 0x30,
+ 0x31,
+ 0x32,
+ 0x33,
+ 0x3d,
+ 0x3e,
+ 0x3f,
+ 0x42,
+ 0x44,
+ 0x4b,
+ 0x4c,
+ 0x4d,
+ 0x4e,
+ 0x4f,
+ 0x50,
+ 0x55,
+ 0x60,
+ 0x61,
+ 0x6a,
+ 0x6f,
+ 0x70,
+ 0x73,
+ 0x74,
+ 0x86,
+ 0x8a,
+ 0x8b,
+ 0x8d,
+ 0x8e,
+ 0x8f,
+ 0x90,
+ 0x92,
+ 0x93,
+ 0x94,
+ 0x95,
+ 0x96,
+ 0x97,
+ 0x98,
+ 0x99,
+};
+
+struct sp_reset {
+ struct reset_controller_dev rcdev;
+ struct notifier_block notifier;
+ void __iomem *base;
+};
+
+static inline struct sp_reset *to_sp_reset(struct reset_controller_dev *rcdev)
+{
+ return container_of(rcdev, struct sp_reset, rcdev);
+}
+
+static int sp_reset_update(struct reset_controller_dev *rcdev,
+ unsigned long id, bool assert)
+{
+ struct sp_reset *reset = to_sp_reset(rcdev);
+ int index = sp_resets[id] / BITS_PER_HWM_REG;
+ int shift = sp_resets[id] % BITS_PER_HWM_REG;
+ u32 val;
+
+ val = (1 << (16 + shift)) | (assert << shift);
+ writel(val, reset->base + (index * 4));
+
+ return 0;
+}
+
+static int sp_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ return sp_reset_update(rcdev, id, true);
+}
+
+static int sp_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ return sp_reset_update(rcdev, id, false);
+}
+
+static int sp_reset_status(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct sp_reset *reset = to_sp_reset(rcdev);
+ int index = sp_resets[id] / BITS_PER_HWM_REG;
+ int shift = sp_resets[id] % BITS_PER_HWM_REG;
+ u32 reg;
+
+ reg = readl(reset->base + (index * 4));
+
+ return !!(reg & BIT(shift));
+}
+
+static const struct reset_control_ops sp_reset_ops = {
+ .assert = sp_reset_assert,
+ .deassert = sp_reset_deassert,
+ .status = sp_reset_status,
+};
+
+static int sp_restart(struct notifier_block *nb, unsigned long mode,
+ void *cmd)
+{
+ struct sp_reset *reset = container_of(nb, struct sp_reset, notifier);
+
+ sp_reset_assert(&reset->rcdev, 0);
+ sp_reset_deassert(&reset->rcdev, 0);
+
+ return NOTIFY_DONE;
+}
+
+static int sp_reset_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct sp_reset *reset;
+ struct resource *res;
+ int ret;
+
+ reset = devm_kzalloc(dev, sizeof(*reset), GFP_KERNEL);
+ if (!reset)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ reset->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(reset->base))
+ return PTR_ERR(reset->base);
+
+ reset->rcdev.ops = &sp_reset_ops;
+ reset->rcdev.owner = THIS_MODULE;
+ reset->rcdev.of_node = dev->of_node;
+ reset->rcdev.nr_resets = resource_size(res) / 4 * BITS_PER_HWM_REG;
+
+ ret = devm_reset_controller_register(dev, &reset->rcdev);
+ if (ret)
+ return ret;
+
+ reset->notifier.notifier_call = sp_restart;
+ reset->notifier.priority = 192;
+
+ return register_restart_handler(&reset->notifier);
+}
+
+static const struct of_device_id sp_reset_dt_ids[] = {
+ {.compatible = "sunplus,sp7021-reset",},
+ { /* sentinel */ },
+};
+
+static struct platform_driver sp_reset_driver = {
+ .probe = sp_reset_probe,
+ .driver = {
+ .name = "sunplus-reset",
+ .of_match_table = sp_reset_dt_ids,
+ .suppress_bind_attrs = true,
+ },
+};
+builtin_platform_driver(sp_reset_driver);
--
2.33.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 03/11] reset: Add Sunplus SP7021 reset driver
@ 2022-06-28 6:26 ` Qin Jian
0 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian, Philipp Zabel
Add reset driver for Sunplus SP7021 SoC.
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
MAINTAINERS | 1 +
drivers/reset/Kconfig | 9 ++
drivers/reset/Makefile | 1 +
drivers/reset/reset-sunplus.c | 212 ++++++++++++++++++++++++++++++++++
4 files changed, 223 insertions(+)
create mode 100644 drivers/reset/reset-sunplus.c
diff --git a/MAINTAINERS b/MAINTAINERS
index d24ef0b09..db00f5e50 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2832,6 +2832,7 @@ S: Maintained
W: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml
+F: drivers/reset/reset-sunplus.c
F: include/dt-bindings/reset/sunplus,sp7021-reset.h
ARM/Synaptics SoC support
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 93c8d07ee..48d94649e 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -231,6 +231,15 @@ config RESET_STARFIVE_JH7100
help
This enables the reset controller driver for the StarFive JH7100 SoC.
+config RESET_SUNPLUS
+ bool "Sunplus SoCs Reset Driver" if COMPILE_TEST
+ default ARCH_SUNPLUS
+ help
+ This enables the reset driver support for Sunplus SoCs.
+ The reset lines that can be asserted and deasserted by toggling bits
+ in a contiguous, exclusive register space. The register is HIWORD_MASKED,
+ which means each register holds 16 reset lines.
+
config RESET_SUNXI
bool "Allwinner SoCs Reset Driver" if COMPILE_TEST && !ARCH_SUNXI
default ARCH_SUNXI
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index a80a9c400..3ff378f43 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -30,6 +30,7 @@ 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_SUNPLUS) += reset-sunplus.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
diff --git a/drivers/reset/reset-sunplus.c b/drivers/reset/reset-sunplus.c
new file mode 100644
index 000000000..2f23ecaa7
--- /dev/null
+++ b/drivers/reset/reset-sunplus.c
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * SP7021 reset driver
+ *
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ * All rights reserved.
+ */
+
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/reboot.h>
+
+/* HIWORD_MASK_REG BITS */
+#define BITS_PER_HWM_REG 16
+
+/* resets HW info: reg_index_shift */
+static const u32 sp_resets[] = {
+/* SP7021: mo_reset0 ~ mo_reset9 */
+ 0x00,
+ 0x02,
+ 0x03,
+ 0x04,
+ 0x05,
+ 0x06,
+ 0x07,
+ 0x08,
+ 0x09,
+ 0x0a,
+ 0x0b,
+ 0x0d,
+ 0x0e,
+ 0x0f,
+ 0x10,
+ 0x12,
+ 0x14,
+ 0x15,
+ 0x16,
+ 0x17,
+ 0x18,
+ 0x19,
+ 0x1a,
+ 0x1b,
+ 0x1c,
+ 0x1d,
+ 0x1e,
+ 0x1f,
+ 0x20,
+ 0x21,
+ 0x22,
+ 0x23,
+ 0x24,
+ 0x25,
+ 0x26,
+ 0x2a,
+ 0x2b,
+ 0x2d,
+ 0x2e,
+ 0x30,
+ 0x31,
+ 0x32,
+ 0x33,
+ 0x3d,
+ 0x3e,
+ 0x3f,
+ 0x42,
+ 0x44,
+ 0x4b,
+ 0x4c,
+ 0x4d,
+ 0x4e,
+ 0x4f,
+ 0x50,
+ 0x55,
+ 0x60,
+ 0x61,
+ 0x6a,
+ 0x6f,
+ 0x70,
+ 0x73,
+ 0x74,
+ 0x86,
+ 0x8a,
+ 0x8b,
+ 0x8d,
+ 0x8e,
+ 0x8f,
+ 0x90,
+ 0x92,
+ 0x93,
+ 0x94,
+ 0x95,
+ 0x96,
+ 0x97,
+ 0x98,
+ 0x99,
+};
+
+struct sp_reset {
+ struct reset_controller_dev rcdev;
+ struct notifier_block notifier;
+ void __iomem *base;
+};
+
+static inline struct sp_reset *to_sp_reset(struct reset_controller_dev *rcdev)
+{
+ return container_of(rcdev, struct sp_reset, rcdev);
+}
+
+static int sp_reset_update(struct reset_controller_dev *rcdev,
+ unsigned long id, bool assert)
+{
+ struct sp_reset *reset = to_sp_reset(rcdev);
+ int index = sp_resets[id] / BITS_PER_HWM_REG;
+ int shift = sp_resets[id] % BITS_PER_HWM_REG;
+ u32 val;
+
+ val = (1 << (16 + shift)) | (assert << shift);
+ writel(val, reset->base + (index * 4));
+
+ return 0;
+}
+
+static int sp_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ return sp_reset_update(rcdev, id, true);
+}
+
+static int sp_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ return sp_reset_update(rcdev, id, false);
+}
+
+static int sp_reset_status(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct sp_reset *reset = to_sp_reset(rcdev);
+ int index = sp_resets[id] / BITS_PER_HWM_REG;
+ int shift = sp_resets[id] % BITS_PER_HWM_REG;
+ u32 reg;
+
+ reg = readl(reset->base + (index * 4));
+
+ return !!(reg & BIT(shift));
+}
+
+static const struct reset_control_ops sp_reset_ops = {
+ .assert = sp_reset_assert,
+ .deassert = sp_reset_deassert,
+ .status = sp_reset_status,
+};
+
+static int sp_restart(struct notifier_block *nb, unsigned long mode,
+ void *cmd)
+{
+ struct sp_reset *reset = container_of(nb, struct sp_reset, notifier);
+
+ sp_reset_assert(&reset->rcdev, 0);
+ sp_reset_deassert(&reset->rcdev, 0);
+
+ return NOTIFY_DONE;
+}
+
+static int sp_reset_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct sp_reset *reset;
+ struct resource *res;
+ int ret;
+
+ reset = devm_kzalloc(dev, sizeof(*reset), GFP_KERNEL);
+ if (!reset)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ reset->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(reset->base))
+ return PTR_ERR(reset->base);
+
+ reset->rcdev.ops = &sp_reset_ops;
+ reset->rcdev.owner = THIS_MODULE;
+ reset->rcdev.of_node = dev->of_node;
+ reset->rcdev.nr_resets = resource_size(res) / 4 * BITS_PER_HWM_REG;
+
+ ret = devm_reset_controller_register(dev, &reset->rcdev);
+ if (ret)
+ return ret;
+
+ reset->notifier.notifier_call = sp_restart;
+ reset->notifier.priority = 192;
+
+ return register_restart_handler(&reset->notifier);
+}
+
+static const struct of_device_id sp_reset_dt_ids[] = {
+ {.compatible = "sunplus,sp7021-reset",},
+ { /* sentinel */ },
+};
+
+static struct platform_driver sp_reset_driver = {
+ .probe = sp_reset_probe,
+ .driver = {
+ .name = "sunplus-reset",
+ .of_match_table = sp_reset_dt_ids,
+ .suppress_bind_attrs = true,
+ },
+};
+builtin_platform_driver(sp_reset_driver);
--
2.33.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 04/11] dt-bindings: clock: Add bindings for SP7021 clock driver
2022-06-28 6:26 ` Qin Jian
@ 2022-06-28 6:26 ` Qin Jian
-1 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian, Krzysztof Kozlowski
Add documentation to describe Sunplus SP7021 clock driver bindings.
Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
.../bindings/clock/sunplus,sp7021-clkc.yaml | 52 +++++++++++
MAINTAINERS | 2 +
.../dt-bindings/clock/sunplus,sp7021-clkc.h | 88 +++++++++++++++++++
3 files changed, 142 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
create mode 100644 include/dt-bindings/clock/sunplus,sp7021-clkc.h
diff --git a/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml b/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
new file mode 100644
index 000000000..bcc140882
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) Sunplus Co., Ltd. 2021
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/sunplus,sp7021-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sunplus SP7021 SoC Clock Controller
+
+maintainers:
+ - Qin Jian <qinjian@cqplus1.com>
+
+properties:
+ compatible:
+ const: sunplus,sp7021-clkc
+
+ reg:
+ maxItems: 3
+
+ clocks:
+ maxItems: 1
+
+ "#clock-cells":
+ const: 1
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ extclk: osc0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <27000000>;
+ clock-output-names = "extclk";
+ };
+
+ clkc: clock-controller@9c000004 {
+ compatible = "sunplus,sp7021-clkc";
+ reg = <0x9c000004 0x28>,
+ <0x9c000200 0x44>,
+ <0x9c000268 0x08>;
+ clocks = <&extclk>;
+ #clock-cells = <1>;
+ };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index db00f5e50..28948357e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2831,8 +2831,10 @@ L: linux-arm-kernel@lists.infradead.org (moderated for mon-subscribers)
S: Maintained
W: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
+F: Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml
F: drivers/reset/reset-sunplus.c
+F: include/dt-bindings/clock/sunplus,sp7021-clkc.h
F: include/dt-bindings/reset/sunplus,sp7021-reset.h
ARM/Synaptics SoC support
diff --git a/include/dt-bindings/clock/sunplus,sp7021-clkc.h b/include/dt-bindings/clock/sunplus,sp7021-clkc.h
new file mode 100644
index 000000000..cd84321eb
--- /dev/null
+++ b/include/dt-bindings/clock/sunplus,sp7021-clkc.h
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ * All rights reserved.
+ */
+#ifndef _DT_BINDINGS_CLOCK_SUNPLUS_SP7021_H
+#define _DT_BINDINGS_CLOCK_SUNPLUS_SP7021_H
+
+/* gates */
+#define CLK_RTC 0
+#define CLK_OTPRX 1
+#define CLK_NOC 2
+#define CLK_BR 3
+#define CLK_SPIFL 4
+#define CLK_PERI0 5
+#define CLK_PERI1 6
+#define CLK_STC0 7
+#define CLK_STC_AV0 8
+#define CLK_STC_AV1 9
+#define CLK_STC_AV2 10
+#define CLK_UA0 11
+#define CLK_UA1 12
+#define CLK_UA2 13
+#define CLK_UA3 14
+#define CLK_UA4 15
+#define CLK_HWUA 16
+#define CLK_DDC0 17
+#define CLK_UADMA 18
+#define CLK_CBDMA0 19
+#define CLK_CBDMA1 20
+#define CLK_SPI_COMBO_0 21
+#define CLK_SPI_COMBO_1 22
+#define CLK_SPI_COMBO_2 23
+#define CLK_SPI_COMBO_3 24
+#define CLK_AUD 25
+#define CLK_USBC0 26
+#define CLK_USBC1 27
+#define CLK_UPHY0 28
+#define CLK_UPHY1 29
+#define CLK_I2CM0 30
+#define CLK_I2CM1 31
+#define CLK_I2CM2 32
+#define CLK_I2CM3 33
+#define CLK_PMC 34
+#define CLK_CARD_CTL0 35
+#define CLK_CARD_CTL1 36
+#define CLK_CARD_CTL4 37
+#define CLK_BCH 38
+#define CLK_DDFCH 39
+#define CLK_CSIIW0 40
+#define CLK_CSIIW1 41
+#define CLK_MIPICSI0 42
+#define CLK_MIPICSI1 43
+#define CLK_HDMI_TX 44
+#define CLK_VPOST 45
+#define CLK_TGEN 46
+#define CLK_DMIX 47
+#define CLK_TCON 48
+#define CLK_GPIO 49
+#define CLK_MAILBOX 50
+#define CLK_SPIND 51
+#define CLK_I2C2CBUS 52
+#define CLK_SEC 53
+#define CLK_DVE 54
+#define CLK_GPOST0 55
+#define CLK_OSD0 56
+#define CLK_DISP_PWM 57
+#define CLK_UADBG 58
+#define CLK_FIO_CTL 59
+#define CLK_FPGA 60
+#define CLK_L2SW 61
+#define CLK_ICM 62
+#define CLK_AXI_GLOBAL 63
+
+/* plls */
+#define PLL_A 64
+#define PLL_E 65
+#define PLL_E_2P5 66
+#define PLL_E_25 67
+#define PLL_E_112P5 68
+#define PLL_F 69
+#define PLL_TV 70
+#define PLL_TV_A 71
+#define PLL_SYS 72
+
+#define CLK_MAX 73
+
+#endif
--
2.33.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 04/11] dt-bindings: clock: Add bindings for SP7021 clock driver
@ 2022-06-28 6:26 ` Qin Jian
0 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian, Krzysztof Kozlowski
Add documentation to describe Sunplus SP7021 clock driver bindings.
Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
.../bindings/clock/sunplus,sp7021-clkc.yaml | 52 +++++++++++
MAINTAINERS | 2 +
.../dt-bindings/clock/sunplus,sp7021-clkc.h | 88 +++++++++++++++++++
3 files changed, 142 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
create mode 100644 include/dt-bindings/clock/sunplus,sp7021-clkc.h
diff --git a/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml b/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
new file mode 100644
index 000000000..bcc140882
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) Sunplus Co., Ltd. 2021
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/sunplus,sp7021-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sunplus SP7021 SoC Clock Controller
+
+maintainers:
+ - Qin Jian <qinjian@cqplus1.com>
+
+properties:
+ compatible:
+ const: sunplus,sp7021-clkc
+
+ reg:
+ maxItems: 3
+
+ clocks:
+ maxItems: 1
+
+ "#clock-cells":
+ const: 1
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ extclk: osc0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <27000000>;
+ clock-output-names = "extclk";
+ };
+
+ clkc: clock-controller@9c000004 {
+ compatible = "sunplus,sp7021-clkc";
+ reg = <0x9c000004 0x28>,
+ <0x9c000200 0x44>,
+ <0x9c000268 0x08>;
+ clocks = <&extclk>;
+ #clock-cells = <1>;
+ };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index db00f5e50..28948357e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2831,8 +2831,10 @@ L: linux-arm-kernel@lists.infradead.org (moderated for mon-subscribers)
S: Maintained
W: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
+F: Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml
F: drivers/reset/reset-sunplus.c
+F: include/dt-bindings/clock/sunplus,sp7021-clkc.h
F: include/dt-bindings/reset/sunplus,sp7021-reset.h
ARM/Synaptics SoC support
diff --git a/include/dt-bindings/clock/sunplus,sp7021-clkc.h b/include/dt-bindings/clock/sunplus,sp7021-clkc.h
new file mode 100644
index 000000000..cd84321eb
--- /dev/null
+++ b/include/dt-bindings/clock/sunplus,sp7021-clkc.h
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ * All rights reserved.
+ */
+#ifndef _DT_BINDINGS_CLOCK_SUNPLUS_SP7021_H
+#define _DT_BINDINGS_CLOCK_SUNPLUS_SP7021_H
+
+/* gates */
+#define CLK_RTC 0
+#define CLK_OTPRX 1
+#define CLK_NOC 2
+#define CLK_BR 3
+#define CLK_SPIFL 4
+#define CLK_PERI0 5
+#define CLK_PERI1 6
+#define CLK_STC0 7
+#define CLK_STC_AV0 8
+#define CLK_STC_AV1 9
+#define CLK_STC_AV2 10
+#define CLK_UA0 11
+#define CLK_UA1 12
+#define CLK_UA2 13
+#define CLK_UA3 14
+#define CLK_UA4 15
+#define CLK_HWUA 16
+#define CLK_DDC0 17
+#define CLK_UADMA 18
+#define CLK_CBDMA0 19
+#define CLK_CBDMA1 20
+#define CLK_SPI_COMBO_0 21
+#define CLK_SPI_COMBO_1 22
+#define CLK_SPI_COMBO_2 23
+#define CLK_SPI_COMBO_3 24
+#define CLK_AUD 25
+#define CLK_USBC0 26
+#define CLK_USBC1 27
+#define CLK_UPHY0 28
+#define CLK_UPHY1 29
+#define CLK_I2CM0 30
+#define CLK_I2CM1 31
+#define CLK_I2CM2 32
+#define CLK_I2CM3 33
+#define CLK_PMC 34
+#define CLK_CARD_CTL0 35
+#define CLK_CARD_CTL1 36
+#define CLK_CARD_CTL4 37
+#define CLK_BCH 38
+#define CLK_DDFCH 39
+#define CLK_CSIIW0 40
+#define CLK_CSIIW1 41
+#define CLK_MIPICSI0 42
+#define CLK_MIPICSI1 43
+#define CLK_HDMI_TX 44
+#define CLK_VPOST 45
+#define CLK_TGEN 46
+#define CLK_DMIX 47
+#define CLK_TCON 48
+#define CLK_GPIO 49
+#define CLK_MAILBOX 50
+#define CLK_SPIND 51
+#define CLK_I2C2CBUS 52
+#define CLK_SEC 53
+#define CLK_DVE 54
+#define CLK_GPOST0 55
+#define CLK_OSD0 56
+#define CLK_DISP_PWM 57
+#define CLK_UADBG 58
+#define CLK_FIO_CTL 59
+#define CLK_FPGA 60
+#define CLK_L2SW 61
+#define CLK_ICM 62
+#define CLK_AXI_GLOBAL 63
+
+/* plls */
+#define PLL_A 64
+#define PLL_E 65
+#define PLL_E_2P5 66
+#define PLL_E_25 67
+#define PLL_E_112P5 68
+#define PLL_F 69
+#define PLL_TV 70
+#define PLL_TV_A 71
+#define PLL_SYS 72
+
+#define CLK_MAX 73
+
+#endif
--
2.33.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 05/11] clk: gate: Add devm_clk_hw_register_gate_parent_data()
2022-06-28 6:26 ` Qin Jian
@ 2022-06-28 6:26 ` Qin Jian
-1 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian
Add devm_clk_hw_register_gate_parent_data() - devres-managed version
of clk_hw_register_gate_parent_data()
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
include/linux/clk-provider.h | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index c10dc4c65..179346c5c 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -567,6 +567,23 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
__devm_clk_hw_register_gate((dev), NULL, (name), (parent_name), NULL, \
NULL, (flags), (reg), (bit_idx), \
(clk_gate_flags), (lock))
+/**
+ * devm_clk_hw_register_gate_parent_data - register a gate clock with the
+ * clock framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_data: parent clk data
+ * @flags: framework-specific flags for this clock
+ * @reg: register address to control gating of this clock
+ * @bit_idx: which bit in the register controls gating of this clock
+ * @clk_gate_flags: gate-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
+#define devm_clk_hw_register_gate_parent_data(dev, name, parent_data, flags, \
+ reg, bit_idx, clk_gate_flags, lock) \
+ __devm_clk_hw_register_gate((dev), NULL, (name), NULL, NULL, \
+ (parent_data), (flags), (reg), (bit_idx), \
+ (clk_gate_flags), (lock))
void clk_unregister_gate(struct clk *clk);
void clk_hw_unregister_gate(struct clk_hw *hw);
int clk_gate_is_enabled(struct clk_hw *hw);
--
2.33.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 05/11] clk: gate: Add devm_clk_hw_register_gate_parent_data()
@ 2022-06-28 6:26 ` Qin Jian
0 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian
Add devm_clk_hw_register_gate_parent_data() - devres-managed version
of clk_hw_register_gate_parent_data()
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
include/linux/clk-provider.h | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index c10dc4c65..179346c5c 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -567,6 +567,23 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
__devm_clk_hw_register_gate((dev), NULL, (name), (parent_name), NULL, \
NULL, (flags), (reg), (bit_idx), \
(clk_gate_flags), (lock))
+/**
+ * devm_clk_hw_register_gate_parent_data - register a gate clock with the
+ * clock framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_data: parent clk data
+ * @flags: framework-specific flags for this clock
+ * @reg: register address to control gating of this clock
+ * @bit_idx: which bit in the register controls gating of this clock
+ * @clk_gate_flags: gate-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
+#define devm_clk_hw_register_gate_parent_data(dev, name, parent_data, flags, \
+ reg, bit_idx, clk_gate_flags, lock) \
+ __devm_clk_hw_register_gate((dev), NULL, (name), NULL, NULL, \
+ (parent_data), (flags), (reg), (bit_idx), \
+ (clk_gate_flags), (lock))
void clk_unregister_gate(struct clk *clk);
void clk_hw_unregister_gate(struct clk_hw *hw);
int clk_gate_is_enabled(struct clk_hw *hw);
--
2.33.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 06/11] clk: Add Sunplus SP7021 clock driver
2022-06-28 6:26 ` Qin Jian
@ 2022-06-28 6:26 ` Qin Jian
-1 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian
Add clock driver for Sunplus SP7021 SoC.
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
Addressed Stephen's comments
---
MAINTAINERS | 1 +
drivers/clk/Kconfig | 10 +
drivers/clk/Makefile | 1 +
drivers/clk/clk-sp7021.c | 713 +++++++++++++++++++++++++++++++++++++++
4 files changed, 725 insertions(+)
create mode 100644 drivers/clk/clk-sp7021.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 28948357e..63aa492a4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2833,6 +2833,7 @@ W: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
F: Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml
+F: drivers/clk/clk-sp7021.c
F: drivers/reset/reset-sunplus.c
F: include/dt-bindings/clock/sunplus,sp7021-clkc.h
F: include/dt-bindings/reset/sunplus,sp7021-reset.h
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 48f8f4221..134919446 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -428,6 +428,16 @@ config COMMON_CLK_K210
help
Support for the Canaan Kendryte K210 RISC-V SoC clocks.
+config COMMON_CLK_SP7021
+ tristate "Clock driver for Sunplus SP7021 SoC"
+ depends on SOC_SP7021 || COMPILE_TEST
+ default SOC_SP7021
+ help
+ This driver supports the Sunplus SP7021 SoC clocks.
+ It implements SP7021 PLLs/gate.
+ Not all features of the PLL are currently supported
+ by the driver.
+
source "drivers/clk/actions/Kconfig"
source "drivers/clk/analogbits/Kconfig"
source "drivers/clk/baikal-t1/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index d5db170d3..2979675a5 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o
obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o
obj-$(CONFIG_COMMON_CLK_SI544) += clk-si544.o
obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
+obj-$(CONFIG_COMMON_CLK_SP7021) += clk-sp7021.o
obj-$(CONFIG_COMMON_CLK_STM32F) += clk-stm32f4.o
obj-$(CONFIG_COMMON_CLK_STM32H7) += clk-stm32h7.o
obj-$(CONFIG_COMMON_CLK_STM32MP157) += clk-stm32mp1.o
diff --git a/drivers/clk/clk-sp7021.c b/drivers/clk/clk-sp7021.c
new file mode 100644
index 000000000..c11f32a97
--- /dev/null
+++ b/drivers/clk/clk-sp7021.c
@@ -0,0 +1,713 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ * All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/bitfield.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/sunplus,sp7021-clkc.h>
+
+/* speical div_width values for PLLTV/PLLA */
+#define DIV_TV 33
+#define DIV_A 34
+
+/* PLLTV parameters */
+enum {
+ SEL_FRA,
+ SDM_MOD,
+ PH_SEL,
+ NFRA,
+ DIVR,
+ DIVN,
+ DIVM,
+ P_MAX
+};
+
+#define MASK_SEL_FRA GENMASK(1, 1)
+#define MASK_SDM_MOD GENMASK(2, 2)
+#define MASK_PH_SEL GENMASK(4, 4)
+#define MASK_NFRA GENMASK(12, 6)
+#define MASK_DIVR GENMASK(8, 7)
+#define MASK_DIVN GENMASK(7, 0)
+#define MASK_DIVM GENMASK(14, 8)
+
+/* HIWORD_MASK FIELD_PREP */
+#define HWM_FIELD_PREP(mask, value) \
+({ \
+ u32 _m = mask; \
+ (_m << 16) | FIELD_PREP(_m, value); \
+})
+
+struct sp_pll {
+ struct clk_hw hw;
+ void __iomem *reg;
+ spinlock_t lock; /* lock for reg */
+ int div_shift;
+ int div_width;
+ int pd_bit; /* power down bit idx */
+ int bp_bit; /* bypass bit idx */
+ unsigned long brate; /* base rate, TODO: replace brate with muldiv */
+ u32 p[P_MAX]; /* for hold PLLTV/PLLA parameters */
+};
+
+#define to_sp_pll(_hw) container_of(_hw, struct sp_pll, hw)
+
+struct sp_clk_gate_info {
+ u16 reg; /* reg_index_shift */
+ u16 ext_parent; /* parent is extclk */
+};
+
+static const struct sp_clk_gate_info sp_clk_gates[] = {
+ { 0x02 },
+ { 0x05 },
+ { 0x06 },
+ { 0x07 },
+ { 0x09 },
+ { 0x0b, 1 },
+ { 0x0f, 1 },
+ { 0x14 },
+ { 0x15 },
+ { 0x16 },
+ { 0x17 },
+ { 0x18, 1 },
+ { 0x19, 1 },
+ { 0x1a, 1 },
+ { 0x1b, 1 },
+ { 0x1c, 1 },
+ { 0x1d, 1 },
+ { 0x1e },
+ { 0x1f, 1 },
+ { 0x20 },
+ { 0x21 },
+ { 0x22 },
+ { 0x23 },
+ { 0x24 },
+ { 0x25 },
+ { 0x26 },
+ { 0x2a },
+ { 0x2b },
+ { 0x2d },
+ { 0x2e },
+ { 0x30 },
+ { 0x31 },
+ { 0x32 },
+ { 0x33 },
+ { 0x3d },
+ { 0x3e },
+ { 0x3f },
+ { 0x42 },
+ { 0x44 },
+ { 0x4b },
+ { 0x4c },
+ { 0x4d },
+ { 0x4e },
+ { 0x4f },
+ { 0x50 },
+ { 0x55 },
+ { 0x60 },
+ { 0x61 },
+ { 0x6a },
+ { 0x73 },
+ { 0x86 },
+ { 0x8a },
+ { 0x8b },
+ { 0x8d },
+ { 0x8e },
+ { 0x8f },
+ { 0x90 },
+ { 0x92 },
+ { 0x93 },
+ { 0x95 },
+ { 0x96 },
+ { 0x97 },
+ { 0x98 },
+ { 0x99 },
+};
+
+#define _M 1000000UL
+#define F_27M (27 * _M)
+
+/*********************************** PLL_TV **********************************/
+
+/* TODO: set proper FVCO range */
+#define FVCO_MIN (100 * _M)
+#define FVCO_MAX (200 * _M)
+
+#define F_MIN (FVCO_MIN / 8)
+#define F_MAX (FVCO_MAX)
+
+static long plltv_integer_div(struct sp_pll *clk, unsigned long freq)
+{
+ /* valid m values: 27M must be divisible by m */
+ static const u32 m_table[] = {
+ 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32
+ };
+ u32 m, n, r;
+ unsigned long fvco, nf;
+ long ret;
+
+ freq = clamp(freq, F_MIN, F_MAX);
+
+ /* DIVR 0~3 */
+ for (r = 0; r <= 3; r++) {
+ fvco = freq << r;
+ if (fvco <= FVCO_MAX)
+ break;
+ }
+
+ /* DIVM */
+ for (m = 0; m < ARRAY_SIZE(m_table); m++) {
+ nf = fvco * m_table[m];
+ n = nf / F_27M;
+ if ((n * F_27M) == nf)
+ break;
+ }
+ m = m_table[m];
+
+ if (!m) {
+ ret = -EINVAL;
+ goto err_not_found;
+ }
+
+ /* save parameters */
+ clk->p[SEL_FRA] = 0;
+ clk->p[DIVR] = r;
+ clk->p[DIVN] = n;
+ clk->p[DIVM] = m;
+
+ return freq;
+
+err_not_found:
+ pr_err("%s: %s freq:%lu not found a valid setting\n",
+ __func__, clk_hw_get_name(&clk->hw), freq);
+
+ return ret;
+}
+
+/* parameters for PLLTV fractional divider */
+static const u32 pt[][5] = {
+ /* conventional fractional */
+ {
+ 1, /* factor */
+ 5, /* 5 * p0 (nint) */
+ 1, /* 1 * p0 */
+ F_27M, /* F_27M / p0 */
+ 1, /* p0 / p2 */
+ },
+ /* phase rotation */
+ {
+ 10, /* factor */
+ 54, /* 5.4 * p0 (nint) */
+ 2, /* 0.2 * p0 */
+ F_27M / 10, /* F_27M / p0 */
+ 5, /* p0 / p2 */
+ },
+};
+
+static const u32 sdm_mod_vals[] = { 91, 55 };
+
+static long plltv_fractional_div(struct sp_pll *clk, unsigned long freq)
+{
+ u32 m, r;
+ u32 nint, nfra;
+ u32 df_quotient_min = 210000000;
+ u32 df_remainder_min = 0;
+ unsigned long fvco, nf, f, fout = 0;
+ int sdm, ph;
+
+ freq = clamp(freq, F_MIN, F_MAX);
+
+ /* DIVR 0~3 */
+ for (r = 0; r <= 3; r++) {
+ fvco = freq << r;
+ if (fvco <= FVCO_MAX)
+ break;
+ }
+ f = F_27M >> r;
+
+ /* PH_SEL */
+ for (ph = ARRAY_SIZE(pt) - 1; ph >= 0; ph--) {
+ const u32 *pp = pt[ph];
+
+ /* SDM_MOD */
+ for (sdm = 0; sdm < ARRAY_SIZE(sdm_mod_vals); sdm++) {
+ u32 mod = sdm_mod_vals[sdm];
+
+ /* DIVM 1~32 */
+ for (m = 1; m <= 32; m++) {
+ u32 df; /* diff freq */
+ u32 df_quotient, df_remainder;
+
+ nf = fvco * m;
+ nint = nf / pp[3];
+
+ if (nint < pp[1])
+ continue;
+ if (nint > pp[1])
+ break;
+
+ nfra = (((nf % pp[3]) * mod * pp[4]) + (F_27M / 2)) / F_27M;
+ if (nfra) {
+ u32 df0 = f * (nint + pp[2]) / pp[0];
+ u32 df1 = f * (mod - nfra) / mod / pp[4];
+
+ df = df0 - df1;
+ } else {
+ df = f * (nint) / pp[0];
+ }
+
+ df_quotient = df / m;
+ df_remainder = ((df % m) * 1000) / m;
+
+ if (freq > df_quotient) {
+ df_quotient = freq - df_quotient - 1;
+ df_remainder = 1000 - df_remainder;
+ } else {
+ df_quotient = df_quotient - freq;
+ }
+
+ if (df_quotient_min > df_quotient ||
+ (df_quotient_min == df_quotient &&
+ df_remainder_min > df_remainder)) {
+ /* found a closer freq, save parameters */
+ clk->p[SEL_FRA] = 1;
+ clk->p[SDM_MOD] = sdm;
+ clk->p[PH_SEL] = ph;
+ clk->p[NFRA] = nfra;
+ clk->p[DIVR] = r;
+ clk->p[DIVM] = m;
+
+ fout = df / m;
+ df_quotient_min = df_quotient;
+ df_remainder_min = df_remainder;
+ }
+ }
+ }
+ }
+
+ if (!fout) {
+ pr_err("%s: %s freq:%lu not found a valid setting\n",
+ __func__, clk_hw_get_name(&clk->hw), freq);
+ return -EINVAL;
+ }
+
+ return fout;
+}
+
+static long plltv_div(struct sp_pll *clk, unsigned long freq)
+{
+ if (freq % 100)
+ return plltv_fractional_div(clk, freq);
+
+ return plltv_integer_div(clk, freq);
+}
+
+static int plltv_set_rate(struct sp_pll *clk)
+{
+ unsigned long flags;
+ u32 r0, r1, r2;
+
+ r0 = BIT(clk->bp_bit + 16);
+ r0 |= HWM_FIELD_PREP(MASK_SEL_FRA, clk->p[SEL_FRA]);
+ r0 |= HWM_FIELD_PREP(MASK_SDM_MOD, clk->p[SDM_MOD]);
+ r0 |= HWM_FIELD_PREP(MASK_PH_SEL, clk->p[PH_SEL]);
+ r0 |= HWM_FIELD_PREP(MASK_NFRA, clk->p[NFRA]);
+
+ r1 = HWM_FIELD_PREP(MASK_DIVR, clk->p[DIVR]);
+
+ r2 = HWM_FIELD_PREP(MASK_DIVN, clk->p[DIVN] - 1);
+ r2 |= HWM_FIELD_PREP(MASK_DIVM, clk->p[DIVM] - 1);
+
+ spin_lock_irqsave(&clk->lock, flags);
+ writel(r0, clk->reg);
+ writel(r1, clk->reg + 4);
+ writel(r2, clk->reg + 8);
+ spin_unlock_irqrestore(&clk->lock, flags);
+
+ return 0;
+}
+
+/*********************************** PLL_A ***********************************/
+
+/* from Q628_PLLs_REG_setting.xlsx */
+static const struct {
+ u32 rate;
+ u32 regs[5];
+} pa[] = {
+ {
+ .rate = 135475200,
+ .regs = {
+ 0x4801,
+ 0x02df,
+ 0x248f,
+ 0x0211,
+ 0x33e9
+ }
+ },
+ {
+ .rate = 147456000,
+ .regs = {
+ 0x4801,
+ 0x1adf,
+ 0x2490,
+ 0x0349,
+ 0x33e9
+ }
+ },
+ {
+ .rate = 196608000,
+ .regs = {
+ 0x4801,
+ 0x42ef,
+ 0x2495,
+ 0x01c6,
+ 0x33e9
+ }
+ },
+};
+
+static int plla_set_rate(struct sp_pll *clk)
+{
+ const u32 *pp = pa[clk->p[0]].regs;
+ unsigned long flags;
+ int i;
+
+ spin_lock_irqsave(&clk->lock, flags);
+ for (i = 0; i < ARRAY_SIZE(pa->regs); i++)
+ writel(0xffff0000 | pp[i], clk->reg + (i * 4));
+ spin_unlock_irqrestore(&clk->lock, flags);
+
+ return 0;
+}
+
+static long plla_round_rate(struct sp_pll *clk, unsigned long rate)
+{
+ int i = ARRAY_SIZE(pa);
+
+ while (--i) {
+ if (rate >= pa[i].rate)
+ break;
+ }
+ clk->p[0] = i;
+
+ return pa[i].rate;
+}
+
+/********************************** SP_PLL ***********************************/
+
+static long sp_pll_calc_div(struct sp_pll *clk, unsigned long rate)
+{
+ u32 fbdiv;
+ u32 max = 1 << clk->div_width;
+
+ fbdiv = DIV_ROUND_CLOSEST(rate, clk->brate);
+ if (fbdiv > max)
+ fbdiv = max;
+
+ return fbdiv;
+}
+
+static long sp_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct sp_pll *clk = to_sp_pll(hw);
+ long ret;
+
+ if (rate == *prate) {
+ ret = *prate; /* bypass */
+ } else if (clk->div_width == DIV_A) {
+ ret = plla_round_rate(clk, rate);
+ } else if (clk->div_width == DIV_TV) {
+ ret = plltv_div(clk, rate);
+ if (ret < 0)
+ ret = *prate;
+ } else {
+ ret = sp_pll_calc_div(clk, rate) * clk->brate;
+ }
+
+ return ret;
+}
+
+static unsigned long sp_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long prate)
+{
+ struct sp_pll *clk = to_sp_pll(hw);
+ u32 reg = readl(clk->reg);
+ unsigned long ret;
+
+ if (reg & BIT(clk->bp_bit)) {
+ ret = prate; /* bypass */
+ } else if (clk->div_width == DIV_A) {
+ ret = pa[clk->p[0]].rate;
+ } else if (clk->div_width == DIV_TV) {
+ u32 m, r, reg2;
+
+ r = FIELD_GET(MASK_DIVR, readl(clk->reg + 4));
+ reg2 = readl(clk->reg + 8);
+ m = FIELD_GET(MASK_DIVM, reg2) + 1;
+
+ if (reg & MASK_SEL_FRA) {
+ /* fractional divider */
+ u32 sdm = FIELD_GET(MASK_SDM_MOD, reg);
+ u32 ph = FIELD_GET(MASK_PH_SEL, reg);
+ u32 nfra = FIELD_GET(MASK_NFRA, reg);
+ const u32 *pp = pt[ph];
+ unsigned long r0, r1;
+
+ ret = prate >> r;
+ r0 = ret * (pp[1] + pp[2]) / pp[0];
+ r1 = ret * (sdm_mod_vals[sdm] - nfra) / sdm_mod_vals[sdm] / pp[4];
+ ret = (r0 - r1) / m;
+ } else {
+ /* integer divider */
+ u32 n = FIELD_GET(MASK_DIVN, reg2) + 1;
+
+ ret = (prate / m * n) >> r;
+ }
+ } else {
+ u32 fbdiv = ((reg >> clk->div_shift) & ((1 << clk->div_width) - 1)) + 1;
+
+ ret = clk->brate * fbdiv;
+ }
+
+ return ret;
+}
+
+static int sp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long prate)
+{
+ struct sp_pll *clk = to_sp_pll(hw);
+ unsigned long flags;
+ u32 reg;
+
+ reg = BIT(clk->bp_bit + 16); /* HIWORD_MASK */
+
+ if (rate == prate) {
+ reg |= BIT(clk->bp_bit); /* bypass */
+ } else if (clk->div_width == DIV_A) {
+ return plla_set_rate(clk);
+ } else if (clk->div_width == DIV_TV) {
+ return plltv_set_rate(clk);
+ } else if (clk->div_width) {
+ u32 fbdiv = sp_pll_calc_div(clk, rate);
+ u32 mask = GENMASK(clk->div_shift + clk->div_width - 1, clk->div_shift);
+
+ reg |= mask << 16;
+ reg |= ((fbdiv - 1) << clk->div_shift) & mask;
+ }
+
+ spin_lock_irqsave(&clk->lock, flags);
+ writel(reg, clk->reg);
+ spin_unlock_irqrestore(&clk->lock, flags);
+
+ return 0;
+}
+
+static int sp_pll_enable(struct clk_hw *hw)
+{
+ struct sp_pll *clk = to_sp_pll(hw);
+
+ writel(BIT(clk->pd_bit + 16) | BIT(clk->pd_bit), clk->reg);
+
+ return 0;
+}
+
+static void sp_pll_disable(struct clk_hw *hw)
+{
+ struct sp_pll *clk = to_sp_pll(hw);
+
+ writel(BIT(clk->pd_bit + 16), clk->reg);
+}
+
+static int sp_pll_is_enabled(struct clk_hw *hw)
+{
+ struct sp_pll *clk = to_sp_pll(hw);
+
+ return readl(clk->reg) & BIT(clk->pd_bit);
+}
+
+static const struct clk_ops sp_pll_ops = {
+ .enable = sp_pll_enable,
+ .disable = sp_pll_disable,
+ .is_enabled = sp_pll_is_enabled,
+ .round_rate = sp_pll_round_rate,
+ .recalc_rate = sp_pll_recalc_rate,
+ .set_rate = sp_pll_set_rate
+};
+
+static const struct clk_ops sp_pll_sub_ops = {
+ .enable = sp_pll_enable,
+ .disable = sp_pll_disable,
+ .is_enabled = sp_pll_is_enabled,
+ .recalc_rate = sp_pll_recalc_rate,
+};
+
+static struct clk_hw *sp_pll_register(struct device *dev, const char *name,
+ const struct clk_parent_data *parent_data,
+ void __iomem *reg, int pd_bit, int bp_bit,
+ unsigned long brate, int shift, int width,
+ unsigned long flags)
+{
+ struct sp_pll *pll;
+ struct clk_hw *hw;
+ struct clk_init_data initd = {
+ .name = name,
+ .parent_data = parent_data,
+ .ops = (bp_bit >= 0) ? &sp_pll_ops : &sp_pll_sub_ops,
+ .num_parents = 1,
+ .flags = flags,
+ };
+ int ret;
+
+ pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ pll->hw.init = &initd;
+ pll->reg = reg;
+ pll->pd_bit = pd_bit;
+ pll->bp_bit = bp_bit;
+ pll->brate = brate;
+ pll->div_shift = shift;
+ pll->div_width = width;
+ spin_lock_init(&pll->lock);
+
+ hw = &pll->hw;
+ ret = devm_clk_hw_register(dev, hw);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return hw;
+}
+
+#define PLLA_CTL (pll_base + 0x1c)
+#define PLLE_CTL (pll_base + 0x30)
+#define PLLF_CTL (pll_base + 0x34)
+#define PLLTV_CTL (pll_base + 0x38)
+
+static int sp7021_clk_probe(struct platform_device *pdev)
+{
+ static const u32 sp_clken[] = {
+ 0x67ef, 0x03ff, 0xff03, 0xfff0, 0x0004, /* G0.1~5 */
+ 0x0000, 0x8000, 0xffff, 0x0040, 0x0000, /* G0.6~10 */
+ };
+ static struct clk_parent_data pd_ext, pd_sys, pd_e;
+ struct device *dev = &pdev->dev;
+ void __iomem *clk_base, *pll_base, *sys_base;
+ struct clk_hw_onecell_data *clk_data;
+ struct clk_hw **hws;
+ int i;
+
+ clk_base = devm_platform_ioremap_resource(pdev, 0);
+ if (!clk_base)
+ return -ENXIO;
+ pll_base = devm_platform_ioremap_resource(pdev, 1);
+ if (!pll_base)
+ return -ENXIO;
+ sys_base = devm_platform_ioremap_resource(pdev, 2);
+ if (!sys_base)
+ return -ENXIO;
+
+ /* enable default clks */
+ for (i = 0; i < ARRAY_SIZE(sp_clken); i++)
+ writel((sp_clken[i] << 16) | sp_clken[i], clk_base + i * 4);
+
+ clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, CLK_MAX),
+ GFP_KERNEL);
+ if (!clk_data)
+ return -ENOMEM;
+
+ hws = clk_data->hws;
+ pd_ext.index = 0;
+
+ /* PLLs */
+ hws[PLL_A] = sp_pll_register(dev, "plla", &pd_ext, PLLA_CTL,
+ 11, 12, 27000000, 0, DIV_A, 0);
+ if (IS_ERR(hws[PLL_A]))
+ return PTR_ERR(hws[PLL_A]);
+
+ hws[PLL_E] = sp_pll_register(dev, "plle", &pd_ext, PLLE_CTL,
+ 6, 2, 50000000, 0, 0, 0);
+ if (IS_ERR(hws[PLL_E]))
+ return PTR_ERR(hws[PLL_E]);
+ pd_e.hw = hws[PLL_E];
+ hws[PLL_E_2P5] = sp_pll_register(dev, "plle_2p5", &pd_e, PLLE_CTL,
+ 13, -1, 2500000, 0, 0, 0);
+ if (IS_ERR(hws[PLL_E_2P5]))
+ return PTR_ERR(hws[PLL_E_2P5]);
+ hws[PLL_E_25] = sp_pll_register(dev, "plle_25", &pd_e, PLLE_CTL,
+ 12, -1, 25000000, 0, 0, 0);
+ if (IS_ERR(hws[PLL_E_25]))
+ return PTR_ERR(hws[PLL_E_25]);
+ hws[PLL_E_112P5] = sp_pll_register(dev, "plle_112p5", &pd_e, PLLE_CTL,
+ 11, -1, 112500000, 0, 0, 0);
+ if (IS_ERR(hws[PLL_E_112P5]))
+ return PTR_ERR(hws[PLL_E_112P5]);
+
+ hws[PLL_F] = sp_pll_register(dev, "pllf", &pd_ext, PLLF_CTL,
+ 0, 10, 13500000, 1, 4, 0);
+ if (IS_ERR(hws[PLL_F]))
+ return PTR_ERR(hws[PLL_F]);
+
+ hws[PLL_TV] = sp_pll_register(dev, "plltv", &pd_ext, PLLTV_CTL,
+ 0, 15, 27000000, 0, DIV_TV, 0);
+ if (IS_ERR(hws[PLL_TV]))
+ return PTR_ERR(hws[PLL_TV]);
+ hws[PLL_TV_A] = devm_clk_hw_register_divider(dev, "plltv_a", "plltv", 0,
+ PLLTV_CTL + 4, 5, 1,
+ CLK_DIVIDER_POWER_OF_TWO,
+ &to_sp_pll(hws[PLL_TV])->lock);
+ if (IS_ERR(hws[PLL_TV_A]))
+ return PTR_ERR(hws[PLL_TV_A]);
+
+ /* system clock, should not be disabled */
+ hws[PLL_SYS] = sp_pll_register(dev, "pllsys", &pd_ext, sys_base,
+ 10, 9, 13500000, 0, 4, CLK_IS_CRITICAL);
+ if (IS_ERR(hws[PLL_SYS]))
+ return PTR_ERR(hws[PLL_SYS]);
+ pd_sys.hw = hws[PLL_SYS];
+
+ /* gates */
+ for (i = 0; i < ARRAY_SIZE(sp_clk_gates); i++) {
+ char name[10];
+ u32 j = sp_clk_gates[i].reg;
+ struct clk_parent_data *pd = sp_clk_gates[i].ext_parent ? &pd_ext : &pd_sys;
+
+ sprintf(name, "%02d_0x%02x", i, j);
+ hws[i] = devm_clk_hw_register_gate_parent_data(dev, name, pd, 0,
+ clk_base + (j >> 4) * 4,
+ j & 0x0f,
+ CLK_GATE_HIWORD_MASK,
+ NULL);
+ if (IS_ERR(hws[i]))
+ return PTR_ERR(hws[i]);
+ }
+
+ clk_data->num = CLK_MAX;
+ return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
+}
+
+static const struct of_device_id sp7021_clk_dt_ids[] = {
+ { .compatible = "sunplus,sp7021-clkc" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, sp7021_clk_dt_ids);
+
+static struct platform_driver sp7021_clk_driver = {
+ .probe = sp7021_clk_probe,
+ .driver = {
+ .name = "sp7021-clk",
+ .of_match_table = sp7021_clk_dt_ids,
+ },
+};
+module_platform_driver(sp7021_clk_driver);
+
+MODULE_AUTHOR("Sunplus Technology");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Clock driver for Sunplus SP7021 SoC");
--
2.33.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 06/11] clk: Add Sunplus SP7021 clock driver
@ 2022-06-28 6:26 ` Qin Jian
0 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian
Add clock driver for Sunplus SP7021 SoC.
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
Addressed Stephen's comments
---
MAINTAINERS | 1 +
drivers/clk/Kconfig | 10 +
drivers/clk/Makefile | 1 +
drivers/clk/clk-sp7021.c | 713 +++++++++++++++++++++++++++++++++++++++
4 files changed, 725 insertions(+)
create mode 100644 drivers/clk/clk-sp7021.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 28948357e..63aa492a4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2833,6 +2833,7 @@ W: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
F: Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml
+F: drivers/clk/clk-sp7021.c
F: drivers/reset/reset-sunplus.c
F: include/dt-bindings/clock/sunplus,sp7021-clkc.h
F: include/dt-bindings/reset/sunplus,sp7021-reset.h
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 48f8f4221..134919446 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -428,6 +428,16 @@ config COMMON_CLK_K210
help
Support for the Canaan Kendryte K210 RISC-V SoC clocks.
+config COMMON_CLK_SP7021
+ tristate "Clock driver for Sunplus SP7021 SoC"
+ depends on SOC_SP7021 || COMPILE_TEST
+ default SOC_SP7021
+ help
+ This driver supports the Sunplus SP7021 SoC clocks.
+ It implements SP7021 PLLs/gate.
+ Not all features of the PLL are currently supported
+ by the driver.
+
source "drivers/clk/actions/Kconfig"
source "drivers/clk/analogbits/Kconfig"
source "drivers/clk/baikal-t1/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index d5db170d3..2979675a5 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o
obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o
obj-$(CONFIG_COMMON_CLK_SI544) += clk-si544.o
obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
+obj-$(CONFIG_COMMON_CLK_SP7021) += clk-sp7021.o
obj-$(CONFIG_COMMON_CLK_STM32F) += clk-stm32f4.o
obj-$(CONFIG_COMMON_CLK_STM32H7) += clk-stm32h7.o
obj-$(CONFIG_COMMON_CLK_STM32MP157) += clk-stm32mp1.o
diff --git a/drivers/clk/clk-sp7021.c b/drivers/clk/clk-sp7021.c
new file mode 100644
index 000000000..c11f32a97
--- /dev/null
+++ b/drivers/clk/clk-sp7021.c
@@ -0,0 +1,713 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ * All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/bitfield.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/sunplus,sp7021-clkc.h>
+
+/* speical div_width values for PLLTV/PLLA */
+#define DIV_TV 33
+#define DIV_A 34
+
+/* PLLTV parameters */
+enum {
+ SEL_FRA,
+ SDM_MOD,
+ PH_SEL,
+ NFRA,
+ DIVR,
+ DIVN,
+ DIVM,
+ P_MAX
+};
+
+#define MASK_SEL_FRA GENMASK(1, 1)
+#define MASK_SDM_MOD GENMASK(2, 2)
+#define MASK_PH_SEL GENMASK(4, 4)
+#define MASK_NFRA GENMASK(12, 6)
+#define MASK_DIVR GENMASK(8, 7)
+#define MASK_DIVN GENMASK(7, 0)
+#define MASK_DIVM GENMASK(14, 8)
+
+/* HIWORD_MASK FIELD_PREP */
+#define HWM_FIELD_PREP(mask, value) \
+({ \
+ u32 _m = mask; \
+ (_m << 16) | FIELD_PREP(_m, value); \
+})
+
+struct sp_pll {
+ struct clk_hw hw;
+ void __iomem *reg;
+ spinlock_t lock; /* lock for reg */
+ int div_shift;
+ int div_width;
+ int pd_bit; /* power down bit idx */
+ int bp_bit; /* bypass bit idx */
+ unsigned long brate; /* base rate, TODO: replace brate with muldiv */
+ u32 p[P_MAX]; /* for hold PLLTV/PLLA parameters */
+};
+
+#define to_sp_pll(_hw) container_of(_hw, struct sp_pll, hw)
+
+struct sp_clk_gate_info {
+ u16 reg; /* reg_index_shift */
+ u16 ext_parent; /* parent is extclk */
+};
+
+static const struct sp_clk_gate_info sp_clk_gates[] = {
+ { 0x02 },
+ { 0x05 },
+ { 0x06 },
+ { 0x07 },
+ { 0x09 },
+ { 0x0b, 1 },
+ { 0x0f, 1 },
+ { 0x14 },
+ { 0x15 },
+ { 0x16 },
+ { 0x17 },
+ { 0x18, 1 },
+ { 0x19, 1 },
+ { 0x1a, 1 },
+ { 0x1b, 1 },
+ { 0x1c, 1 },
+ { 0x1d, 1 },
+ { 0x1e },
+ { 0x1f, 1 },
+ { 0x20 },
+ { 0x21 },
+ { 0x22 },
+ { 0x23 },
+ { 0x24 },
+ { 0x25 },
+ { 0x26 },
+ { 0x2a },
+ { 0x2b },
+ { 0x2d },
+ { 0x2e },
+ { 0x30 },
+ { 0x31 },
+ { 0x32 },
+ { 0x33 },
+ { 0x3d },
+ { 0x3e },
+ { 0x3f },
+ { 0x42 },
+ { 0x44 },
+ { 0x4b },
+ { 0x4c },
+ { 0x4d },
+ { 0x4e },
+ { 0x4f },
+ { 0x50 },
+ { 0x55 },
+ { 0x60 },
+ { 0x61 },
+ { 0x6a },
+ { 0x73 },
+ { 0x86 },
+ { 0x8a },
+ { 0x8b },
+ { 0x8d },
+ { 0x8e },
+ { 0x8f },
+ { 0x90 },
+ { 0x92 },
+ { 0x93 },
+ { 0x95 },
+ { 0x96 },
+ { 0x97 },
+ { 0x98 },
+ { 0x99 },
+};
+
+#define _M 1000000UL
+#define F_27M (27 * _M)
+
+/*********************************** PLL_TV **********************************/
+
+/* TODO: set proper FVCO range */
+#define FVCO_MIN (100 * _M)
+#define FVCO_MAX (200 * _M)
+
+#define F_MIN (FVCO_MIN / 8)
+#define F_MAX (FVCO_MAX)
+
+static long plltv_integer_div(struct sp_pll *clk, unsigned long freq)
+{
+ /* valid m values: 27M must be divisible by m */
+ static const u32 m_table[] = {
+ 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32
+ };
+ u32 m, n, r;
+ unsigned long fvco, nf;
+ long ret;
+
+ freq = clamp(freq, F_MIN, F_MAX);
+
+ /* DIVR 0~3 */
+ for (r = 0; r <= 3; r++) {
+ fvco = freq << r;
+ if (fvco <= FVCO_MAX)
+ break;
+ }
+
+ /* DIVM */
+ for (m = 0; m < ARRAY_SIZE(m_table); m++) {
+ nf = fvco * m_table[m];
+ n = nf / F_27M;
+ if ((n * F_27M) == nf)
+ break;
+ }
+ m = m_table[m];
+
+ if (!m) {
+ ret = -EINVAL;
+ goto err_not_found;
+ }
+
+ /* save parameters */
+ clk->p[SEL_FRA] = 0;
+ clk->p[DIVR] = r;
+ clk->p[DIVN] = n;
+ clk->p[DIVM] = m;
+
+ return freq;
+
+err_not_found:
+ pr_err("%s: %s freq:%lu not found a valid setting\n",
+ __func__, clk_hw_get_name(&clk->hw), freq);
+
+ return ret;
+}
+
+/* parameters for PLLTV fractional divider */
+static const u32 pt[][5] = {
+ /* conventional fractional */
+ {
+ 1, /* factor */
+ 5, /* 5 * p0 (nint) */
+ 1, /* 1 * p0 */
+ F_27M, /* F_27M / p0 */
+ 1, /* p0 / p2 */
+ },
+ /* phase rotation */
+ {
+ 10, /* factor */
+ 54, /* 5.4 * p0 (nint) */
+ 2, /* 0.2 * p0 */
+ F_27M / 10, /* F_27M / p0 */
+ 5, /* p0 / p2 */
+ },
+};
+
+static const u32 sdm_mod_vals[] = { 91, 55 };
+
+static long plltv_fractional_div(struct sp_pll *clk, unsigned long freq)
+{
+ u32 m, r;
+ u32 nint, nfra;
+ u32 df_quotient_min = 210000000;
+ u32 df_remainder_min = 0;
+ unsigned long fvco, nf, f, fout = 0;
+ int sdm, ph;
+
+ freq = clamp(freq, F_MIN, F_MAX);
+
+ /* DIVR 0~3 */
+ for (r = 0; r <= 3; r++) {
+ fvco = freq << r;
+ if (fvco <= FVCO_MAX)
+ break;
+ }
+ f = F_27M >> r;
+
+ /* PH_SEL */
+ for (ph = ARRAY_SIZE(pt) - 1; ph >= 0; ph--) {
+ const u32 *pp = pt[ph];
+
+ /* SDM_MOD */
+ for (sdm = 0; sdm < ARRAY_SIZE(sdm_mod_vals); sdm++) {
+ u32 mod = sdm_mod_vals[sdm];
+
+ /* DIVM 1~32 */
+ for (m = 1; m <= 32; m++) {
+ u32 df; /* diff freq */
+ u32 df_quotient, df_remainder;
+
+ nf = fvco * m;
+ nint = nf / pp[3];
+
+ if (nint < pp[1])
+ continue;
+ if (nint > pp[1])
+ break;
+
+ nfra = (((nf % pp[3]) * mod * pp[4]) + (F_27M / 2)) / F_27M;
+ if (nfra) {
+ u32 df0 = f * (nint + pp[2]) / pp[0];
+ u32 df1 = f * (mod - nfra) / mod / pp[4];
+
+ df = df0 - df1;
+ } else {
+ df = f * (nint) / pp[0];
+ }
+
+ df_quotient = df / m;
+ df_remainder = ((df % m) * 1000) / m;
+
+ if (freq > df_quotient) {
+ df_quotient = freq - df_quotient - 1;
+ df_remainder = 1000 - df_remainder;
+ } else {
+ df_quotient = df_quotient - freq;
+ }
+
+ if (df_quotient_min > df_quotient ||
+ (df_quotient_min == df_quotient &&
+ df_remainder_min > df_remainder)) {
+ /* found a closer freq, save parameters */
+ clk->p[SEL_FRA] = 1;
+ clk->p[SDM_MOD] = sdm;
+ clk->p[PH_SEL] = ph;
+ clk->p[NFRA] = nfra;
+ clk->p[DIVR] = r;
+ clk->p[DIVM] = m;
+
+ fout = df / m;
+ df_quotient_min = df_quotient;
+ df_remainder_min = df_remainder;
+ }
+ }
+ }
+ }
+
+ if (!fout) {
+ pr_err("%s: %s freq:%lu not found a valid setting\n",
+ __func__, clk_hw_get_name(&clk->hw), freq);
+ return -EINVAL;
+ }
+
+ return fout;
+}
+
+static long plltv_div(struct sp_pll *clk, unsigned long freq)
+{
+ if (freq % 100)
+ return plltv_fractional_div(clk, freq);
+
+ return plltv_integer_div(clk, freq);
+}
+
+static int plltv_set_rate(struct sp_pll *clk)
+{
+ unsigned long flags;
+ u32 r0, r1, r2;
+
+ r0 = BIT(clk->bp_bit + 16);
+ r0 |= HWM_FIELD_PREP(MASK_SEL_FRA, clk->p[SEL_FRA]);
+ r0 |= HWM_FIELD_PREP(MASK_SDM_MOD, clk->p[SDM_MOD]);
+ r0 |= HWM_FIELD_PREP(MASK_PH_SEL, clk->p[PH_SEL]);
+ r0 |= HWM_FIELD_PREP(MASK_NFRA, clk->p[NFRA]);
+
+ r1 = HWM_FIELD_PREP(MASK_DIVR, clk->p[DIVR]);
+
+ r2 = HWM_FIELD_PREP(MASK_DIVN, clk->p[DIVN] - 1);
+ r2 |= HWM_FIELD_PREP(MASK_DIVM, clk->p[DIVM] - 1);
+
+ spin_lock_irqsave(&clk->lock, flags);
+ writel(r0, clk->reg);
+ writel(r1, clk->reg + 4);
+ writel(r2, clk->reg + 8);
+ spin_unlock_irqrestore(&clk->lock, flags);
+
+ return 0;
+}
+
+/*********************************** PLL_A ***********************************/
+
+/* from Q628_PLLs_REG_setting.xlsx */
+static const struct {
+ u32 rate;
+ u32 regs[5];
+} pa[] = {
+ {
+ .rate = 135475200,
+ .regs = {
+ 0x4801,
+ 0x02df,
+ 0x248f,
+ 0x0211,
+ 0x33e9
+ }
+ },
+ {
+ .rate = 147456000,
+ .regs = {
+ 0x4801,
+ 0x1adf,
+ 0x2490,
+ 0x0349,
+ 0x33e9
+ }
+ },
+ {
+ .rate = 196608000,
+ .regs = {
+ 0x4801,
+ 0x42ef,
+ 0x2495,
+ 0x01c6,
+ 0x33e9
+ }
+ },
+};
+
+static int plla_set_rate(struct sp_pll *clk)
+{
+ const u32 *pp = pa[clk->p[0]].regs;
+ unsigned long flags;
+ int i;
+
+ spin_lock_irqsave(&clk->lock, flags);
+ for (i = 0; i < ARRAY_SIZE(pa->regs); i++)
+ writel(0xffff0000 | pp[i], clk->reg + (i * 4));
+ spin_unlock_irqrestore(&clk->lock, flags);
+
+ return 0;
+}
+
+static long plla_round_rate(struct sp_pll *clk, unsigned long rate)
+{
+ int i = ARRAY_SIZE(pa);
+
+ while (--i) {
+ if (rate >= pa[i].rate)
+ break;
+ }
+ clk->p[0] = i;
+
+ return pa[i].rate;
+}
+
+/********************************** SP_PLL ***********************************/
+
+static long sp_pll_calc_div(struct sp_pll *clk, unsigned long rate)
+{
+ u32 fbdiv;
+ u32 max = 1 << clk->div_width;
+
+ fbdiv = DIV_ROUND_CLOSEST(rate, clk->brate);
+ if (fbdiv > max)
+ fbdiv = max;
+
+ return fbdiv;
+}
+
+static long sp_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct sp_pll *clk = to_sp_pll(hw);
+ long ret;
+
+ if (rate == *prate) {
+ ret = *prate; /* bypass */
+ } else if (clk->div_width == DIV_A) {
+ ret = plla_round_rate(clk, rate);
+ } else if (clk->div_width == DIV_TV) {
+ ret = plltv_div(clk, rate);
+ if (ret < 0)
+ ret = *prate;
+ } else {
+ ret = sp_pll_calc_div(clk, rate) * clk->brate;
+ }
+
+ return ret;
+}
+
+static unsigned long sp_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long prate)
+{
+ struct sp_pll *clk = to_sp_pll(hw);
+ u32 reg = readl(clk->reg);
+ unsigned long ret;
+
+ if (reg & BIT(clk->bp_bit)) {
+ ret = prate; /* bypass */
+ } else if (clk->div_width == DIV_A) {
+ ret = pa[clk->p[0]].rate;
+ } else if (clk->div_width == DIV_TV) {
+ u32 m, r, reg2;
+
+ r = FIELD_GET(MASK_DIVR, readl(clk->reg + 4));
+ reg2 = readl(clk->reg + 8);
+ m = FIELD_GET(MASK_DIVM, reg2) + 1;
+
+ if (reg & MASK_SEL_FRA) {
+ /* fractional divider */
+ u32 sdm = FIELD_GET(MASK_SDM_MOD, reg);
+ u32 ph = FIELD_GET(MASK_PH_SEL, reg);
+ u32 nfra = FIELD_GET(MASK_NFRA, reg);
+ const u32 *pp = pt[ph];
+ unsigned long r0, r1;
+
+ ret = prate >> r;
+ r0 = ret * (pp[1] + pp[2]) / pp[0];
+ r1 = ret * (sdm_mod_vals[sdm] - nfra) / sdm_mod_vals[sdm] / pp[4];
+ ret = (r0 - r1) / m;
+ } else {
+ /* integer divider */
+ u32 n = FIELD_GET(MASK_DIVN, reg2) + 1;
+
+ ret = (prate / m * n) >> r;
+ }
+ } else {
+ u32 fbdiv = ((reg >> clk->div_shift) & ((1 << clk->div_width) - 1)) + 1;
+
+ ret = clk->brate * fbdiv;
+ }
+
+ return ret;
+}
+
+static int sp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long prate)
+{
+ struct sp_pll *clk = to_sp_pll(hw);
+ unsigned long flags;
+ u32 reg;
+
+ reg = BIT(clk->bp_bit + 16); /* HIWORD_MASK */
+
+ if (rate == prate) {
+ reg |= BIT(clk->bp_bit); /* bypass */
+ } else if (clk->div_width == DIV_A) {
+ return plla_set_rate(clk);
+ } else if (clk->div_width == DIV_TV) {
+ return plltv_set_rate(clk);
+ } else if (clk->div_width) {
+ u32 fbdiv = sp_pll_calc_div(clk, rate);
+ u32 mask = GENMASK(clk->div_shift + clk->div_width - 1, clk->div_shift);
+
+ reg |= mask << 16;
+ reg |= ((fbdiv - 1) << clk->div_shift) & mask;
+ }
+
+ spin_lock_irqsave(&clk->lock, flags);
+ writel(reg, clk->reg);
+ spin_unlock_irqrestore(&clk->lock, flags);
+
+ return 0;
+}
+
+static int sp_pll_enable(struct clk_hw *hw)
+{
+ struct sp_pll *clk = to_sp_pll(hw);
+
+ writel(BIT(clk->pd_bit + 16) | BIT(clk->pd_bit), clk->reg);
+
+ return 0;
+}
+
+static void sp_pll_disable(struct clk_hw *hw)
+{
+ struct sp_pll *clk = to_sp_pll(hw);
+
+ writel(BIT(clk->pd_bit + 16), clk->reg);
+}
+
+static int sp_pll_is_enabled(struct clk_hw *hw)
+{
+ struct sp_pll *clk = to_sp_pll(hw);
+
+ return readl(clk->reg) & BIT(clk->pd_bit);
+}
+
+static const struct clk_ops sp_pll_ops = {
+ .enable = sp_pll_enable,
+ .disable = sp_pll_disable,
+ .is_enabled = sp_pll_is_enabled,
+ .round_rate = sp_pll_round_rate,
+ .recalc_rate = sp_pll_recalc_rate,
+ .set_rate = sp_pll_set_rate
+};
+
+static const struct clk_ops sp_pll_sub_ops = {
+ .enable = sp_pll_enable,
+ .disable = sp_pll_disable,
+ .is_enabled = sp_pll_is_enabled,
+ .recalc_rate = sp_pll_recalc_rate,
+};
+
+static struct clk_hw *sp_pll_register(struct device *dev, const char *name,
+ const struct clk_parent_data *parent_data,
+ void __iomem *reg, int pd_bit, int bp_bit,
+ unsigned long brate, int shift, int width,
+ unsigned long flags)
+{
+ struct sp_pll *pll;
+ struct clk_hw *hw;
+ struct clk_init_data initd = {
+ .name = name,
+ .parent_data = parent_data,
+ .ops = (bp_bit >= 0) ? &sp_pll_ops : &sp_pll_sub_ops,
+ .num_parents = 1,
+ .flags = flags,
+ };
+ int ret;
+
+ pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ pll->hw.init = &initd;
+ pll->reg = reg;
+ pll->pd_bit = pd_bit;
+ pll->bp_bit = bp_bit;
+ pll->brate = brate;
+ pll->div_shift = shift;
+ pll->div_width = width;
+ spin_lock_init(&pll->lock);
+
+ hw = &pll->hw;
+ ret = devm_clk_hw_register(dev, hw);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return hw;
+}
+
+#define PLLA_CTL (pll_base + 0x1c)
+#define PLLE_CTL (pll_base + 0x30)
+#define PLLF_CTL (pll_base + 0x34)
+#define PLLTV_CTL (pll_base + 0x38)
+
+static int sp7021_clk_probe(struct platform_device *pdev)
+{
+ static const u32 sp_clken[] = {
+ 0x67ef, 0x03ff, 0xff03, 0xfff0, 0x0004, /* G0.1~5 */
+ 0x0000, 0x8000, 0xffff, 0x0040, 0x0000, /* G0.6~10 */
+ };
+ static struct clk_parent_data pd_ext, pd_sys, pd_e;
+ struct device *dev = &pdev->dev;
+ void __iomem *clk_base, *pll_base, *sys_base;
+ struct clk_hw_onecell_data *clk_data;
+ struct clk_hw **hws;
+ int i;
+
+ clk_base = devm_platform_ioremap_resource(pdev, 0);
+ if (!clk_base)
+ return -ENXIO;
+ pll_base = devm_platform_ioremap_resource(pdev, 1);
+ if (!pll_base)
+ return -ENXIO;
+ sys_base = devm_platform_ioremap_resource(pdev, 2);
+ if (!sys_base)
+ return -ENXIO;
+
+ /* enable default clks */
+ for (i = 0; i < ARRAY_SIZE(sp_clken); i++)
+ writel((sp_clken[i] << 16) | sp_clken[i], clk_base + i * 4);
+
+ clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, CLK_MAX),
+ GFP_KERNEL);
+ if (!clk_data)
+ return -ENOMEM;
+
+ hws = clk_data->hws;
+ pd_ext.index = 0;
+
+ /* PLLs */
+ hws[PLL_A] = sp_pll_register(dev, "plla", &pd_ext, PLLA_CTL,
+ 11, 12, 27000000, 0, DIV_A, 0);
+ if (IS_ERR(hws[PLL_A]))
+ return PTR_ERR(hws[PLL_A]);
+
+ hws[PLL_E] = sp_pll_register(dev, "plle", &pd_ext, PLLE_CTL,
+ 6, 2, 50000000, 0, 0, 0);
+ if (IS_ERR(hws[PLL_E]))
+ return PTR_ERR(hws[PLL_E]);
+ pd_e.hw = hws[PLL_E];
+ hws[PLL_E_2P5] = sp_pll_register(dev, "plle_2p5", &pd_e, PLLE_CTL,
+ 13, -1, 2500000, 0, 0, 0);
+ if (IS_ERR(hws[PLL_E_2P5]))
+ return PTR_ERR(hws[PLL_E_2P5]);
+ hws[PLL_E_25] = sp_pll_register(dev, "plle_25", &pd_e, PLLE_CTL,
+ 12, -1, 25000000, 0, 0, 0);
+ if (IS_ERR(hws[PLL_E_25]))
+ return PTR_ERR(hws[PLL_E_25]);
+ hws[PLL_E_112P5] = sp_pll_register(dev, "plle_112p5", &pd_e, PLLE_CTL,
+ 11, -1, 112500000, 0, 0, 0);
+ if (IS_ERR(hws[PLL_E_112P5]))
+ return PTR_ERR(hws[PLL_E_112P5]);
+
+ hws[PLL_F] = sp_pll_register(dev, "pllf", &pd_ext, PLLF_CTL,
+ 0, 10, 13500000, 1, 4, 0);
+ if (IS_ERR(hws[PLL_F]))
+ return PTR_ERR(hws[PLL_F]);
+
+ hws[PLL_TV] = sp_pll_register(dev, "plltv", &pd_ext, PLLTV_CTL,
+ 0, 15, 27000000, 0, DIV_TV, 0);
+ if (IS_ERR(hws[PLL_TV]))
+ return PTR_ERR(hws[PLL_TV]);
+ hws[PLL_TV_A] = devm_clk_hw_register_divider(dev, "plltv_a", "plltv", 0,
+ PLLTV_CTL + 4, 5, 1,
+ CLK_DIVIDER_POWER_OF_TWO,
+ &to_sp_pll(hws[PLL_TV])->lock);
+ if (IS_ERR(hws[PLL_TV_A]))
+ return PTR_ERR(hws[PLL_TV_A]);
+
+ /* system clock, should not be disabled */
+ hws[PLL_SYS] = sp_pll_register(dev, "pllsys", &pd_ext, sys_base,
+ 10, 9, 13500000, 0, 4, CLK_IS_CRITICAL);
+ if (IS_ERR(hws[PLL_SYS]))
+ return PTR_ERR(hws[PLL_SYS]);
+ pd_sys.hw = hws[PLL_SYS];
+
+ /* gates */
+ for (i = 0; i < ARRAY_SIZE(sp_clk_gates); i++) {
+ char name[10];
+ u32 j = sp_clk_gates[i].reg;
+ struct clk_parent_data *pd = sp_clk_gates[i].ext_parent ? &pd_ext : &pd_sys;
+
+ sprintf(name, "%02d_0x%02x", i, j);
+ hws[i] = devm_clk_hw_register_gate_parent_data(dev, name, pd, 0,
+ clk_base + (j >> 4) * 4,
+ j & 0x0f,
+ CLK_GATE_HIWORD_MASK,
+ NULL);
+ if (IS_ERR(hws[i]))
+ return PTR_ERR(hws[i]);
+ }
+
+ clk_data->num = CLK_MAX;
+ return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
+}
+
+static const struct of_device_id sp7021_clk_dt_ids[] = {
+ { .compatible = "sunplus,sp7021-clkc" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, sp7021_clk_dt_ids);
+
+static struct platform_driver sp7021_clk_driver = {
+ .probe = sp7021_clk_probe,
+ .driver = {
+ .name = "sp7021-clk",
+ .of_match_table = sp7021_clk_dt_ids,
+ },
+};
+module_platform_driver(sp7021_clk_driver);
+
+MODULE_AUTHOR("Sunplus Technology");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Clock driver for Sunplus SP7021 SoC");
--
2.33.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 07/11] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
2022-06-28 6:26 ` Qin Jian
@ 2022-06-28 6:26 ` Qin Jian
-1 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian, Rob Herring
Add documentation to describe Sunplus SP7021 interrupt controller bindings.
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
.../sunplus,sp7021-intc.yaml | 62 +++++++++++++++++++
MAINTAINERS | 5 ++
2 files changed, 67 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
diff --git a/Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
new file mode 100644
index 000000000..bd0021dba
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) Sunplus Co., Ltd. 2021
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/sunplus,sp7021-intc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sunplus SP7021 SoC Interrupt Controller
+
+maintainers:
+ - Qin Jian <qinjian@cqplus1.com>
+
+properties:
+ compatible:
+ items:
+ - const: sunplus,sp7021-intc
+
+ reg:
+ maxItems: 2
+ description:
+ Specifies base physical address(s) and size of the controller regs.
+ The 1st region include type/polarity/priority/mask regs.
+ The 2nd region include clear/masked_ext0/masked_ext1/group regs.
+
+ interrupt-controller: true
+
+ "#interrupt-cells":
+ const: 2
+ description:
+ The first cell is the IRQ number, the second cell is the trigger
+ type as defined in interrupt.txt in this directory.
+
+ interrupts:
+ maxItems: 2
+ description:
+ EXT_INT0 & EXT_INT1, 2 interrupts references to primary interrupt
+ controller.
+
+required:
+ - compatible
+ - reg
+ - interrupt-controller
+ - "#interrupt-cells"
+ - interrupts
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ intc: interrupt-controller@9c000780 {
+ compatible = "sunplus,sp7021-intc";
+ reg = <0x9c000780 0x80>, <0x9c000a80 0x80>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>, /* EXT_INT0 */
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; /* EXT_INT1 */
+ };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 63aa492a4..ca11740e8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2832,8 +2832,13 @@ S: Maintained
W: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
F: Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
+F: Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml
+F: arch/arm/boot/dts/sunplus-sp7021*.dts*
+F: arch/arm/configs/sp7021_*defconfig
+F: arch/arm/mach-sunplus/
F: drivers/clk/clk-sp7021.c
+F: drivers/irqchip/irq-sp7021-intc.c
F: drivers/reset/reset-sunplus.c
F: include/dt-bindings/clock/sunplus,sp7021-clkc.h
F: include/dt-bindings/reset/sunplus,sp7021-reset.h
--
2.33.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 07/11] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
@ 2022-06-28 6:26 ` Qin Jian
0 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian, Rob Herring
Add documentation to describe Sunplus SP7021 interrupt controller bindings.
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
.../sunplus,sp7021-intc.yaml | 62 +++++++++++++++++++
MAINTAINERS | 5 ++
2 files changed, 67 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
diff --git a/Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
new file mode 100644
index 000000000..bd0021dba
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) Sunplus Co., Ltd. 2021
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/sunplus,sp7021-intc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sunplus SP7021 SoC Interrupt Controller
+
+maintainers:
+ - Qin Jian <qinjian@cqplus1.com>
+
+properties:
+ compatible:
+ items:
+ - const: sunplus,sp7021-intc
+
+ reg:
+ maxItems: 2
+ description:
+ Specifies base physical address(s) and size of the controller regs.
+ The 1st region include type/polarity/priority/mask regs.
+ The 2nd region include clear/masked_ext0/masked_ext1/group regs.
+
+ interrupt-controller: true
+
+ "#interrupt-cells":
+ const: 2
+ description:
+ The first cell is the IRQ number, the second cell is the trigger
+ type as defined in interrupt.txt in this directory.
+
+ interrupts:
+ maxItems: 2
+ description:
+ EXT_INT0 & EXT_INT1, 2 interrupts references to primary interrupt
+ controller.
+
+required:
+ - compatible
+ - reg
+ - interrupt-controller
+ - "#interrupt-cells"
+ - interrupts
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ intc: interrupt-controller@9c000780 {
+ compatible = "sunplus,sp7021-intc";
+ reg = <0x9c000780 0x80>, <0x9c000a80 0x80>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>, /* EXT_INT0 */
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; /* EXT_INT1 */
+ };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 63aa492a4..ca11740e8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2832,8 +2832,13 @@ S: Maintained
W: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
F: Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
+F: Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml
+F: arch/arm/boot/dts/sunplus-sp7021*.dts*
+F: arch/arm/configs/sp7021_*defconfig
+F: arch/arm/mach-sunplus/
F: drivers/clk/clk-sp7021.c
+F: drivers/irqchip/irq-sp7021-intc.c
F: drivers/reset/reset-sunplus.c
F: include/dt-bindings/clock/sunplus,sp7021-clkc.h
F: include/dt-bindings/reset/sunplus,sp7021-reset.h
--
2.33.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 08/11] irqchip: Add Sunplus SP7021 interrupt controller driver
2022-06-28 6:26 ` Qin Jian
@ 2022-06-28 6:26 ` Qin Jian
-1 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian, Marc Zyngier
Add interrupt controller driver for Sunplus SP7021 SoC.
This is the interrupt controller in P-chip which collects all interrupt
sources in P-chip and routes them to parent interrupt controller in C-chip.
Acked-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
MAINTAINERS | 3 -
drivers/irqchip/Kconfig | 9 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-sp7021-intc.c | 278 ++++++++++++++++++++++++++++++
4 files changed, 288 insertions(+), 3 deletions(-)
create mode 100644 drivers/irqchip/irq-sp7021-intc.c
diff --git a/MAINTAINERS b/MAINTAINERS
index ca11740e8..a3eeb3a5a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2834,9 +2834,6 @@ F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
F: Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
F: Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml
-F: arch/arm/boot/dts/sunplus-sp7021*.dts*
-F: arch/arm/configs/sp7021_*defconfig
-F: arch/arm/mach-sunplus/
F: drivers/clk/clk-sp7021.c
F: drivers/irqchip/irq-sp7021-intc.c
F: drivers/reset/reset-sunplus.c
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 1f23a6be7..4dd4f2108 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -627,4 +627,13 @@ config MCHP_EIC
help
Support for Microchip External Interrupt Controller.
+config SUNPLUS_SP7021_INTC
+ bool "Sunplus SP7021 interrupt controller" if COMPILE_TEST
+ default SOC_SP7021
+ help
+ Support for the Sunplus SP7021 Interrupt Controller IP core.
+ SP7021 SoC has 2 Chips: C-Chip & P-Chip. This is used as a
+ chained controller, routing all interrupt source in P-Chip to
+ the primary controller on C-Chip.
+
endmenu
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 5b67450a9..cb12a1526 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -115,3 +115,4 @@ obj-$(CONFIG_WPCM450_AIC) += irq-wpcm450-aic.o
obj-$(CONFIG_IRQ_IDT3243X) += irq-idt3243x.o
obj-$(CONFIG_APPLE_AIC) += irq-apple-aic.o
obj-$(CONFIG_MCHP_EIC) += irq-mchp-eic.o
+obj-$(CONFIG_SUNPLUS_SP7021_INTC) += irq-sp7021-intc.o
diff --git a/drivers/irqchip/irq-sp7021-intc.c b/drivers/irqchip/irq-sp7021-intc.c
new file mode 100644
index 000000000..bed78d1de
--- /dev/null
+++ b/drivers/irqchip/irq-sp7021-intc.c
@@ -0,0 +1,278 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ * All rights reserved.
+ */
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/io.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#define SP_INTC_HWIRQ_MIN 0
+#define SP_INTC_HWIRQ_MAX 223
+
+#define SP_INTC_NR_IRQS (SP_INTC_HWIRQ_MAX - SP_INTC_HWIRQ_MIN + 1)
+#define SP_INTC_NR_GROUPS DIV_ROUND_UP(SP_INTC_NR_IRQS, 32)
+#define SP_INTC_REG_SIZE (SP_INTC_NR_GROUPS * 4)
+
+/* REG_GROUP_0 regs */
+#define REG_INTR_TYPE (sp_intc.g0)
+#define REG_INTR_POLARITY (REG_INTR_TYPE + SP_INTC_REG_SIZE)
+#define REG_INTR_PRIORITY (REG_INTR_POLARITY + SP_INTC_REG_SIZE)
+#define REG_INTR_MASK (REG_INTR_PRIORITY + SP_INTC_REG_SIZE)
+
+/* REG_GROUP_1 regs */
+#define REG_INTR_CLEAR (sp_intc.g1)
+#define REG_MASKED_EXT1 (REG_INTR_CLEAR + SP_INTC_REG_SIZE)
+#define REG_MASKED_EXT0 (REG_MASKED_EXT1 + SP_INTC_REG_SIZE)
+#define REG_INTR_GROUP (REG_INTR_CLEAR + 31 * 4)
+
+#define GROUP_MASK (BIT(SP_INTC_NR_GROUPS) - 1)
+#define GROUP_SHIFT_EXT1 (0)
+#define GROUP_SHIFT_EXT0 (8)
+
+/*
+ * When GPIO_INT0~7 set to edge trigger, doesn't work properly.
+ * WORKAROUND: change it to level trigger, and toggle the polarity
+ * at ACK/Handler to make the HW work.
+ */
+#define GPIO_INT0_HWIRQ 120
+#define GPIO_INT7_HWIRQ 127
+#define IS_GPIO_INT(irq) \
+({ \
+ u32 i = irq; \
+ (i >= GPIO_INT0_HWIRQ) && (i <= GPIO_INT7_HWIRQ); \
+})
+
+/* index of states */
+enum {
+ _IS_EDGE = 0,
+ _IS_LOW,
+ _IS_ACTIVE
+};
+
+#define STATE_BIT(irq, idx) (((irq) - GPIO_INT0_HWIRQ) * 3 + (idx))
+#define ASSIGN_STATE(irq, idx, v) assign_bit(STATE_BIT(irq, idx), sp_intc.states, v)
+#define TEST_STATE(irq, idx) test_bit(STATE_BIT(irq, idx), sp_intc.states)
+
+static struct sp_intctl {
+ /*
+ * REG_GROUP_0: include type/polarity/priority/mask regs.
+ * REG_GROUP_1: include clear/masked_ext0/masked_ext1/group regs.
+ */
+ void __iomem *g0; // REG_GROUP_0 base
+ void __iomem *g1; // REG_GROUP_1 base
+
+ struct irq_domain *domain;
+ raw_spinlock_t lock;
+
+ /*
+ * store GPIO_INT states
+ * each interrupt has 3 states: is_edge, is_low, is_active
+ */
+ DECLARE_BITMAP(states, (GPIO_INT7_HWIRQ - GPIO_INT0_HWIRQ + 1) * 3);
+} sp_intc;
+
+static struct irq_chip sp_intc_chip;
+
+static void sp_intc_assign_bit(u32 hwirq, void __iomem *base, bool value)
+{
+ u32 offset, mask;
+ unsigned long flags;
+ void __iomem *reg;
+
+ offset = (hwirq / 32) * 4;
+ reg = base + offset;
+
+ raw_spin_lock_irqsave(&sp_intc.lock, flags);
+ mask = readl_relaxed(reg);
+ if (value)
+ mask |= BIT(hwirq % 32);
+ else
+ mask &= ~BIT(hwirq % 32);
+ writel_relaxed(mask, reg);
+ raw_spin_unlock_irqrestore(&sp_intc.lock, flags);
+}
+
+static void sp_intc_ack_irq(struct irq_data *d)
+{
+ u32 hwirq = d->hwirq;
+
+ if (unlikely(IS_GPIO_INT(hwirq) && TEST_STATE(hwirq, _IS_EDGE))) { // WORKAROUND
+ sp_intc_assign_bit(hwirq, REG_INTR_POLARITY, !TEST_STATE(hwirq, _IS_LOW));
+ ASSIGN_STATE(hwirq, _IS_ACTIVE, true);
+ }
+
+ sp_intc_assign_bit(hwirq, REG_INTR_CLEAR, 1);
+}
+
+static void sp_intc_mask_irq(struct irq_data *d)
+{
+ sp_intc_assign_bit(d->hwirq, REG_INTR_MASK, 0);
+}
+
+static void sp_intc_unmask_irq(struct irq_data *d)
+{
+ sp_intc_assign_bit(d->hwirq, REG_INTR_MASK, 1);
+}
+
+static int sp_intc_set_type(struct irq_data *d, unsigned int type)
+{
+ u32 hwirq = d->hwirq;
+ bool is_edge = !(type & IRQ_TYPE_LEVEL_MASK);
+ bool is_low = (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING);
+
+ irq_set_handler_locked(d, is_edge ? handle_edge_irq : handle_level_irq);
+
+ if (unlikely(IS_GPIO_INT(hwirq) && is_edge)) { // WORKAROUND
+ /* store states */
+ ASSIGN_STATE(hwirq, _IS_EDGE, is_edge);
+ ASSIGN_STATE(hwirq, _IS_LOW, is_low);
+ ASSIGN_STATE(hwirq, _IS_ACTIVE, false);
+ /* change to level */
+ is_edge = false;
+ }
+
+ sp_intc_assign_bit(hwirq, REG_INTR_TYPE, is_edge);
+ sp_intc_assign_bit(hwirq, REG_INTR_POLARITY, is_low);
+
+ return 0;
+}
+
+static int sp_intc_get_ext_irq(int ext_num)
+{
+ void __iomem *base = ext_num ? REG_MASKED_EXT1 : REG_MASKED_EXT0;
+ u32 shift = ext_num ? GROUP_SHIFT_EXT1 : GROUP_SHIFT_EXT0;
+ u32 groups;
+ u32 pending_group;
+ u32 group;
+ u32 pending_irq;
+
+ groups = readl_relaxed(REG_INTR_GROUP);
+ pending_group = (groups >> shift) & GROUP_MASK;
+ if (!pending_group)
+ return -1;
+
+ group = fls(pending_group) - 1;
+ pending_irq = readl_relaxed(base + group * 4);
+ if (!pending_irq)
+ return -1;
+
+ return (group * 32) + fls(pending_irq) - 1;
+}
+
+static void sp_intc_handle_ext_cascaded(struct irq_desc *desc)
+{
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ int ext_num = (uintptr_t)irq_desc_get_handler_data(desc);
+ int hwirq;
+
+ chained_irq_enter(chip, desc);
+
+ while ((hwirq = sp_intc_get_ext_irq(ext_num)) >= 0) {
+ if (unlikely(IS_GPIO_INT(hwirq) && TEST_STATE(hwirq, _IS_ACTIVE))) { // WORKAROUND
+ ASSIGN_STATE(hwirq, _IS_ACTIVE, false);
+ sp_intc_assign_bit(hwirq, REG_INTR_POLARITY, TEST_STATE(hwirq, _IS_LOW));
+ } else {
+ generic_handle_domain_irq(sp_intc.domain, hwirq);
+ }
+ }
+
+ chained_irq_exit(chip, desc);
+}
+
+static struct irq_chip sp_intc_chip = {
+ .name = "sp_intc",
+ .irq_ack = sp_intc_ack_irq,
+ .irq_mask = sp_intc_mask_irq,
+ .irq_unmask = sp_intc_unmask_irq,
+ .irq_set_type = sp_intc_set_type,
+};
+
+static int sp_intc_irq_domain_map(struct irq_domain *domain,
+ unsigned int irq, irq_hw_number_t hwirq)
+{
+ irq_set_chip_and_handler(irq, &sp_intc_chip, handle_level_irq);
+ irq_set_chip_data(irq, &sp_intc_chip);
+ irq_set_noprobe(irq);
+
+ return 0;
+}
+
+static const struct irq_domain_ops sp_intc_dm_ops = {
+ .xlate = irq_domain_xlate_twocell,
+ .map = sp_intc_irq_domain_map,
+};
+
+static int sp_intc_irq_map(struct device_node *node, int i)
+{
+ unsigned int irq;
+
+ irq = irq_of_parse_and_map(node, i);
+ if (!irq)
+ return -ENOENT;
+
+ irq_set_chained_handler_and_data(irq, sp_intc_handle_ext_cascaded, (void *)(uintptr_t)i);
+
+ return 0;
+}
+
+static int __init sp_intc_init_dt(struct device_node *node, struct device_node *parent)
+{
+ int i, ret;
+
+ sp_intc.g0 = of_iomap(node, 0);
+ if (!sp_intc.g0)
+ return -ENXIO;
+
+ sp_intc.g1 = of_iomap(node, 1);
+ if (!sp_intc.g1) {
+ ret = -ENXIO;
+ goto out_unmap0;
+ }
+
+ ret = sp_intc_irq_map(node, 0); // EXT_INT0
+ if (ret)
+ goto out_unmap1;
+
+ ret = sp_intc_irq_map(node, 1); // EXT_INT1
+ if (ret)
+ goto out_unmap1;
+
+ /* initial regs */
+ for (i = 0; i < SP_INTC_NR_GROUPS; i++) {
+ /* all mask */
+ writel_relaxed(0, REG_INTR_MASK + i * 4);
+ /* all edge */
+ writel_relaxed(~0, REG_INTR_TYPE + i * 4);
+ /* all high-active */
+ writel_relaxed(0, REG_INTR_POLARITY + i * 4);
+ /* all EXT_INT0 */
+ writel_relaxed(~0, REG_INTR_PRIORITY + i * 4);
+ /* all clear */
+ writel_relaxed(~0, REG_INTR_CLEAR + i * 4);
+ }
+
+ sp_intc.domain = irq_domain_add_linear(node, SP_INTC_NR_IRQS,
+ &sp_intc_dm_ops, &sp_intc);
+ if (!sp_intc.domain) {
+ ret = -ENOMEM;
+ goto out_unmap1;
+ }
+
+ raw_spin_lock_init(&sp_intc.lock);
+
+ return 0;
+
+out_unmap1:
+ iounmap(sp_intc.g1);
+out_unmap0:
+ iounmap(sp_intc.g0);
+
+ return ret;
+}
+
+IRQCHIP_DECLARE(sp_intc, "sunplus,sp7021-intc", sp_intc_init_dt);
--
2.33.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 08/11] irqchip: Add Sunplus SP7021 interrupt controller driver
@ 2022-06-28 6:26 ` Qin Jian
0 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian, Marc Zyngier
Add interrupt controller driver for Sunplus SP7021 SoC.
This is the interrupt controller in P-chip which collects all interrupt
sources in P-chip and routes them to parent interrupt controller in C-chip.
Acked-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
MAINTAINERS | 3 -
drivers/irqchip/Kconfig | 9 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-sp7021-intc.c | 278 ++++++++++++++++++++++++++++++
4 files changed, 288 insertions(+), 3 deletions(-)
create mode 100644 drivers/irqchip/irq-sp7021-intc.c
diff --git a/MAINTAINERS b/MAINTAINERS
index ca11740e8..a3eeb3a5a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2834,9 +2834,6 @@ F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
F: Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
F: Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml
-F: arch/arm/boot/dts/sunplus-sp7021*.dts*
-F: arch/arm/configs/sp7021_*defconfig
-F: arch/arm/mach-sunplus/
F: drivers/clk/clk-sp7021.c
F: drivers/irqchip/irq-sp7021-intc.c
F: drivers/reset/reset-sunplus.c
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 1f23a6be7..4dd4f2108 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -627,4 +627,13 @@ config MCHP_EIC
help
Support for Microchip External Interrupt Controller.
+config SUNPLUS_SP7021_INTC
+ bool "Sunplus SP7021 interrupt controller" if COMPILE_TEST
+ default SOC_SP7021
+ help
+ Support for the Sunplus SP7021 Interrupt Controller IP core.
+ SP7021 SoC has 2 Chips: C-Chip & P-Chip. This is used as a
+ chained controller, routing all interrupt source in P-Chip to
+ the primary controller on C-Chip.
+
endmenu
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 5b67450a9..cb12a1526 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -115,3 +115,4 @@ obj-$(CONFIG_WPCM450_AIC) += irq-wpcm450-aic.o
obj-$(CONFIG_IRQ_IDT3243X) += irq-idt3243x.o
obj-$(CONFIG_APPLE_AIC) += irq-apple-aic.o
obj-$(CONFIG_MCHP_EIC) += irq-mchp-eic.o
+obj-$(CONFIG_SUNPLUS_SP7021_INTC) += irq-sp7021-intc.o
diff --git a/drivers/irqchip/irq-sp7021-intc.c b/drivers/irqchip/irq-sp7021-intc.c
new file mode 100644
index 000000000..bed78d1de
--- /dev/null
+++ b/drivers/irqchip/irq-sp7021-intc.c
@@ -0,0 +1,278 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ * All rights reserved.
+ */
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/io.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#define SP_INTC_HWIRQ_MIN 0
+#define SP_INTC_HWIRQ_MAX 223
+
+#define SP_INTC_NR_IRQS (SP_INTC_HWIRQ_MAX - SP_INTC_HWIRQ_MIN + 1)
+#define SP_INTC_NR_GROUPS DIV_ROUND_UP(SP_INTC_NR_IRQS, 32)
+#define SP_INTC_REG_SIZE (SP_INTC_NR_GROUPS * 4)
+
+/* REG_GROUP_0 regs */
+#define REG_INTR_TYPE (sp_intc.g0)
+#define REG_INTR_POLARITY (REG_INTR_TYPE + SP_INTC_REG_SIZE)
+#define REG_INTR_PRIORITY (REG_INTR_POLARITY + SP_INTC_REG_SIZE)
+#define REG_INTR_MASK (REG_INTR_PRIORITY + SP_INTC_REG_SIZE)
+
+/* REG_GROUP_1 regs */
+#define REG_INTR_CLEAR (sp_intc.g1)
+#define REG_MASKED_EXT1 (REG_INTR_CLEAR + SP_INTC_REG_SIZE)
+#define REG_MASKED_EXT0 (REG_MASKED_EXT1 + SP_INTC_REG_SIZE)
+#define REG_INTR_GROUP (REG_INTR_CLEAR + 31 * 4)
+
+#define GROUP_MASK (BIT(SP_INTC_NR_GROUPS) - 1)
+#define GROUP_SHIFT_EXT1 (0)
+#define GROUP_SHIFT_EXT0 (8)
+
+/*
+ * When GPIO_INT0~7 set to edge trigger, doesn't work properly.
+ * WORKAROUND: change it to level trigger, and toggle the polarity
+ * at ACK/Handler to make the HW work.
+ */
+#define GPIO_INT0_HWIRQ 120
+#define GPIO_INT7_HWIRQ 127
+#define IS_GPIO_INT(irq) \
+({ \
+ u32 i = irq; \
+ (i >= GPIO_INT0_HWIRQ) && (i <= GPIO_INT7_HWIRQ); \
+})
+
+/* index of states */
+enum {
+ _IS_EDGE = 0,
+ _IS_LOW,
+ _IS_ACTIVE
+};
+
+#define STATE_BIT(irq, idx) (((irq) - GPIO_INT0_HWIRQ) * 3 + (idx))
+#define ASSIGN_STATE(irq, idx, v) assign_bit(STATE_BIT(irq, idx), sp_intc.states, v)
+#define TEST_STATE(irq, idx) test_bit(STATE_BIT(irq, idx), sp_intc.states)
+
+static struct sp_intctl {
+ /*
+ * REG_GROUP_0: include type/polarity/priority/mask regs.
+ * REG_GROUP_1: include clear/masked_ext0/masked_ext1/group regs.
+ */
+ void __iomem *g0; // REG_GROUP_0 base
+ void __iomem *g1; // REG_GROUP_1 base
+
+ struct irq_domain *domain;
+ raw_spinlock_t lock;
+
+ /*
+ * store GPIO_INT states
+ * each interrupt has 3 states: is_edge, is_low, is_active
+ */
+ DECLARE_BITMAP(states, (GPIO_INT7_HWIRQ - GPIO_INT0_HWIRQ + 1) * 3);
+} sp_intc;
+
+static struct irq_chip sp_intc_chip;
+
+static void sp_intc_assign_bit(u32 hwirq, void __iomem *base, bool value)
+{
+ u32 offset, mask;
+ unsigned long flags;
+ void __iomem *reg;
+
+ offset = (hwirq / 32) * 4;
+ reg = base + offset;
+
+ raw_spin_lock_irqsave(&sp_intc.lock, flags);
+ mask = readl_relaxed(reg);
+ if (value)
+ mask |= BIT(hwirq % 32);
+ else
+ mask &= ~BIT(hwirq % 32);
+ writel_relaxed(mask, reg);
+ raw_spin_unlock_irqrestore(&sp_intc.lock, flags);
+}
+
+static void sp_intc_ack_irq(struct irq_data *d)
+{
+ u32 hwirq = d->hwirq;
+
+ if (unlikely(IS_GPIO_INT(hwirq) && TEST_STATE(hwirq, _IS_EDGE))) { // WORKAROUND
+ sp_intc_assign_bit(hwirq, REG_INTR_POLARITY, !TEST_STATE(hwirq, _IS_LOW));
+ ASSIGN_STATE(hwirq, _IS_ACTIVE, true);
+ }
+
+ sp_intc_assign_bit(hwirq, REG_INTR_CLEAR, 1);
+}
+
+static void sp_intc_mask_irq(struct irq_data *d)
+{
+ sp_intc_assign_bit(d->hwirq, REG_INTR_MASK, 0);
+}
+
+static void sp_intc_unmask_irq(struct irq_data *d)
+{
+ sp_intc_assign_bit(d->hwirq, REG_INTR_MASK, 1);
+}
+
+static int sp_intc_set_type(struct irq_data *d, unsigned int type)
+{
+ u32 hwirq = d->hwirq;
+ bool is_edge = !(type & IRQ_TYPE_LEVEL_MASK);
+ bool is_low = (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING);
+
+ irq_set_handler_locked(d, is_edge ? handle_edge_irq : handle_level_irq);
+
+ if (unlikely(IS_GPIO_INT(hwirq) && is_edge)) { // WORKAROUND
+ /* store states */
+ ASSIGN_STATE(hwirq, _IS_EDGE, is_edge);
+ ASSIGN_STATE(hwirq, _IS_LOW, is_low);
+ ASSIGN_STATE(hwirq, _IS_ACTIVE, false);
+ /* change to level */
+ is_edge = false;
+ }
+
+ sp_intc_assign_bit(hwirq, REG_INTR_TYPE, is_edge);
+ sp_intc_assign_bit(hwirq, REG_INTR_POLARITY, is_low);
+
+ return 0;
+}
+
+static int sp_intc_get_ext_irq(int ext_num)
+{
+ void __iomem *base = ext_num ? REG_MASKED_EXT1 : REG_MASKED_EXT0;
+ u32 shift = ext_num ? GROUP_SHIFT_EXT1 : GROUP_SHIFT_EXT0;
+ u32 groups;
+ u32 pending_group;
+ u32 group;
+ u32 pending_irq;
+
+ groups = readl_relaxed(REG_INTR_GROUP);
+ pending_group = (groups >> shift) & GROUP_MASK;
+ if (!pending_group)
+ return -1;
+
+ group = fls(pending_group) - 1;
+ pending_irq = readl_relaxed(base + group * 4);
+ if (!pending_irq)
+ return -1;
+
+ return (group * 32) + fls(pending_irq) - 1;
+}
+
+static void sp_intc_handle_ext_cascaded(struct irq_desc *desc)
+{
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ int ext_num = (uintptr_t)irq_desc_get_handler_data(desc);
+ int hwirq;
+
+ chained_irq_enter(chip, desc);
+
+ while ((hwirq = sp_intc_get_ext_irq(ext_num)) >= 0) {
+ if (unlikely(IS_GPIO_INT(hwirq) && TEST_STATE(hwirq, _IS_ACTIVE))) { // WORKAROUND
+ ASSIGN_STATE(hwirq, _IS_ACTIVE, false);
+ sp_intc_assign_bit(hwirq, REG_INTR_POLARITY, TEST_STATE(hwirq, _IS_LOW));
+ } else {
+ generic_handle_domain_irq(sp_intc.domain, hwirq);
+ }
+ }
+
+ chained_irq_exit(chip, desc);
+}
+
+static struct irq_chip sp_intc_chip = {
+ .name = "sp_intc",
+ .irq_ack = sp_intc_ack_irq,
+ .irq_mask = sp_intc_mask_irq,
+ .irq_unmask = sp_intc_unmask_irq,
+ .irq_set_type = sp_intc_set_type,
+};
+
+static int sp_intc_irq_domain_map(struct irq_domain *domain,
+ unsigned int irq, irq_hw_number_t hwirq)
+{
+ irq_set_chip_and_handler(irq, &sp_intc_chip, handle_level_irq);
+ irq_set_chip_data(irq, &sp_intc_chip);
+ irq_set_noprobe(irq);
+
+ return 0;
+}
+
+static const struct irq_domain_ops sp_intc_dm_ops = {
+ .xlate = irq_domain_xlate_twocell,
+ .map = sp_intc_irq_domain_map,
+};
+
+static int sp_intc_irq_map(struct device_node *node, int i)
+{
+ unsigned int irq;
+
+ irq = irq_of_parse_and_map(node, i);
+ if (!irq)
+ return -ENOENT;
+
+ irq_set_chained_handler_and_data(irq, sp_intc_handle_ext_cascaded, (void *)(uintptr_t)i);
+
+ return 0;
+}
+
+static int __init sp_intc_init_dt(struct device_node *node, struct device_node *parent)
+{
+ int i, ret;
+
+ sp_intc.g0 = of_iomap(node, 0);
+ if (!sp_intc.g0)
+ return -ENXIO;
+
+ sp_intc.g1 = of_iomap(node, 1);
+ if (!sp_intc.g1) {
+ ret = -ENXIO;
+ goto out_unmap0;
+ }
+
+ ret = sp_intc_irq_map(node, 0); // EXT_INT0
+ if (ret)
+ goto out_unmap1;
+
+ ret = sp_intc_irq_map(node, 1); // EXT_INT1
+ if (ret)
+ goto out_unmap1;
+
+ /* initial regs */
+ for (i = 0; i < SP_INTC_NR_GROUPS; i++) {
+ /* all mask */
+ writel_relaxed(0, REG_INTR_MASK + i * 4);
+ /* all edge */
+ writel_relaxed(~0, REG_INTR_TYPE + i * 4);
+ /* all high-active */
+ writel_relaxed(0, REG_INTR_POLARITY + i * 4);
+ /* all EXT_INT0 */
+ writel_relaxed(~0, REG_INTR_PRIORITY + i * 4);
+ /* all clear */
+ writel_relaxed(~0, REG_INTR_CLEAR + i * 4);
+ }
+
+ sp_intc.domain = irq_domain_add_linear(node, SP_INTC_NR_IRQS,
+ &sp_intc_dm_ops, &sp_intc);
+ if (!sp_intc.domain) {
+ ret = -ENOMEM;
+ goto out_unmap1;
+ }
+
+ raw_spin_lock_init(&sp_intc.lock);
+
+ return 0;
+
+out_unmap1:
+ iounmap(sp_intc.g1);
+out_unmap0:
+ iounmap(sp_intc.g0);
+
+ return ret;
+}
+
+IRQCHIP_DECLARE(sp_intc, "sunplus,sp7021-intc", sp_intc_init_dt);
--
2.33.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 09/11] ARM: sunplus: Add initial support for Sunplus SP7021 SoC
2022-06-28 6:26 ` Qin Jian
@ 2022-06-28 6:26 ` Qin Jian
-1 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian
This patch aims to add an initial support for Sunplus SP7021 SoC.
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
MAINTAINERS | 1 +
arch/arm/Kconfig | 2 ++
arch/arm/Makefile | 1 +
arch/arm/mach-sunplus/Kconfig | 27 +++++++++++++++++++++++++++
arch/arm/mach-sunplus/Makefile | 8 ++++++++
arch/arm/mach-sunplus/sp7021.c | 16 ++++++++++++++++
6 files changed, 55 insertions(+)
create mode 100644 arch/arm/mach-sunplus/Kconfig
create mode 100644 arch/arm/mach-sunplus/Makefile
create mode 100644 arch/arm/mach-sunplus/sp7021.c
diff --git a/MAINTAINERS b/MAINTAINERS
index a3eeb3a5a..495bfe0f9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2834,6 +2834,7 @@ F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
F: Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
F: Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml
+F: arch/arm/mach-sunplus/
F: drivers/clk/clk-sp7021.c
F: drivers/irqchip/irq-sp7021-intc.c
F: drivers/reset/reset-sunplus.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 7630ba9cb..cb37b1722 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -588,6 +588,8 @@ source "arch/arm/mach-sti/Kconfig"
source "arch/arm/mach-stm32/Kconfig"
+source "arch/arm/mach-sunplus/Kconfig"
+
source "arch/arm/mach-sunxi/Kconfig"
source "arch/arm/mach-tegra/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index c8e3633f5..56f655dee 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -215,6 +215,7 @@ machine-$(CONFIG_ARCH_RENESAS) += shmobile
machine-$(CONFIG_ARCH_INTEL_SOCFPGA) += socfpga
machine-$(CONFIG_ARCH_STI) += sti
machine-$(CONFIG_ARCH_STM32) += stm32
+machine-$(CONFIG_ARCH_SUNPLUS) += sunplus
machine-$(CONFIG_ARCH_SUNXI) += sunxi
machine-$(CONFIG_ARCH_TEGRA) += tegra
machine-$(CONFIG_ARCH_U8500) += ux500
diff --git a/arch/arm/mach-sunplus/Kconfig b/arch/arm/mach-sunplus/Kconfig
new file mode 100644
index 000000000..926cde5e3
--- /dev/null
+++ b/arch/arm/mach-sunplus/Kconfig
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+menuconfig ARCH_SUNPLUS
+ bool "Sunplus SoCs"
+ depends on ARCH_MULTI_V7
+ help
+ Support for Sunplus SoC family: SP7021 and succeeding SoC-based systems,
+ such as the Banana Pi BPI-F2S development board (and derivatives).
+ (<http://www.sinovoip.com.cn/ecp_view.asp?id=586>)
+ (<https://tibbo.com/store/plus1.html>)
+
+config SOC_SP7021
+ bool "Sunplus SP7021 SoC support"
+ depends on ARCH_SUNPLUS
+ default ARCH_SUNPLUS
+ select HAVE_ARM_ARCH_TIMER
+ select ARM_GIC
+ select ARM_PSCI
+ select PINCTRL
+ select PINCTRL_SPPCTL
+ select SERIAL_SUNPLUS
+ select SERIAL_SUNPLUS_CONSOLE
+ help
+ Support for Sunplus SP7021 SoC. It is based on ARM 4-core
+ Cortex-A7 with various peripherals (e.g.: I2C, SPI, SDIO,
+ Ethernet, etc.), FPGA interface, chip-to-chip bus.
+ It is designed for industrial control.
diff --git a/arch/arm/mach-sunplus/Makefile b/arch/arm/mach-sunplus/Makefile
new file mode 100644
index 000000000..d211de6af
--- /dev/null
+++ b/arch/arm/mach-sunplus/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-$(CONFIG_SOC_SP7021) += sp7021.o
diff --git a/arch/arm/mach-sunplus/sp7021.c b/arch/arm/mach-sunplus/sp7021.c
new file mode 100644
index 000000000..774d0a5bd
--- /dev/null
+++ b/arch/arm/mach-sunplus/sp7021.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ * All rights reserved.
+ */
+#include <linux/kernel.h>
+#include <asm/mach/arch.h>
+
+static const char *sp7021_compat[] __initconst = {
+ "sunplus,sp7021",
+ NULL
+};
+
+DT_MACHINE_START(SP7021_DT, "SP7021")
+ .dt_compat = sp7021_compat,
+MACHINE_END
--
2.33.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 09/11] ARM: sunplus: Add initial support for Sunplus SP7021 SoC
@ 2022-06-28 6:26 ` Qin Jian
0 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian
This patch aims to add an initial support for Sunplus SP7021 SoC.
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
MAINTAINERS | 1 +
arch/arm/Kconfig | 2 ++
arch/arm/Makefile | 1 +
arch/arm/mach-sunplus/Kconfig | 27 +++++++++++++++++++++++++++
arch/arm/mach-sunplus/Makefile | 8 ++++++++
arch/arm/mach-sunplus/sp7021.c | 16 ++++++++++++++++
6 files changed, 55 insertions(+)
create mode 100644 arch/arm/mach-sunplus/Kconfig
create mode 100644 arch/arm/mach-sunplus/Makefile
create mode 100644 arch/arm/mach-sunplus/sp7021.c
diff --git a/MAINTAINERS b/MAINTAINERS
index a3eeb3a5a..495bfe0f9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2834,6 +2834,7 @@ F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
F: Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
F: Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml
+F: arch/arm/mach-sunplus/
F: drivers/clk/clk-sp7021.c
F: drivers/irqchip/irq-sp7021-intc.c
F: drivers/reset/reset-sunplus.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 7630ba9cb..cb37b1722 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -588,6 +588,8 @@ source "arch/arm/mach-sti/Kconfig"
source "arch/arm/mach-stm32/Kconfig"
+source "arch/arm/mach-sunplus/Kconfig"
+
source "arch/arm/mach-sunxi/Kconfig"
source "arch/arm/mach-tegra/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index c8e3633f5..56f655dee 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -215,6 +215,7 @@ machine-$(CONFIG_ARCH_RENESAS) += shmobile
machine-$(CONFIG_ARCH_INTEL_SOCFPGA) += socfpga
machine-$(CONFIG_ARCH_STI) += sti
machine-$(CONFIG_ARCH_STM32) += stm32
+machine-$(CONFIG_ARCH_SUNPLUS) += sunplus
machine-$(CONFIG_ARCH_SUNXI) += sunxi
machine-$(CONFIG_ARCH_TEGRA) += tegra
machine-$(CONFIG_ARCH_U8500) += ux500
diff --git a/arch/arm/mach-sunplus/Kconfig b/arch/arm/mach-sunplus/Kconfig
new file mode 100644
index 000000000..926cde5e3
--- /dev/null
+++ b/arch/arm/mach-sunplus/Kconfig
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+menuconfig ARCH_SUNPLUS
+ bool "Sunplus SoCs"
+ depends on ARCH_MULTI_V7
+ help
+ Support for Sunplus SoC family: SP7021 and succeeding SoC-based systems,
+ such as the Banana Pi BPI-F2S development board (and derivatives).
+ (<http://www.sinovoip.com.cn/ecp_view.asp?id=586>)
+ (<https://tibbo.com/store/plus1.html>)
+
+config SOC_SP7021
+ bool "Sunplus SP7021 SoC support"
+ depends on ARCH_SUNPLUS
+ default ARCH_SUNPLUS
+ select HAVE_ARM_ARCH_TIMER
+ select ARM_GIC
+ select ARM_PSCI
+ select PINCTRL
+ select PINCTRL_SPPCTL
+ select SERIAL_SUNPLUS
+ select SERIAL_SUNPLUS_CONSOLE
+ help
+ Support for Sunplus SP7021 SoC. It is based on ARM 4-core
+ Cortex-A7 with various peripherals (e.g.: I2C, SPI, SDIO,
+ Ethernet, etc.), FPGA interface, chip-to-chip bus.
+ It is designed for industrial control.
diff --git a/arch/arm/mach-sunplus/Makefile b/arch/arm/mach-sunplus/Makefile
new file mode 100644
index 000000000..d211de6af
--- /dev/null
+++ b/arch/arm/mach-sunplus/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-$(CONFIG_SOC_SP7021) += sp7021.o
diff --git a/arch/arm/mach-sunplus/sp7021.c b/arch/arm/mach-sunplus/sp7021.c
new file mode 100644
index 000000000..774d0a5bd
--- /dev/null
+++ b/arch/arm/mach-sunplus/sp7021.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ * All rights reserved.
+ */
+#include <linux/kernel.h>
+#include <asm/mach/arch.h>
+
+static const char *sp7021_compat[] __initconst = {
+ "sunplus,sp7021",
+ NULL
+};
+
+DT_MACHINE_START(SP7021_DT, "SP7021")
+ .dt_compat = sp7021_compat,
+MACHINE_END
--
2.33.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 10/11] ARM: sp7021_defconfig: Add Sunplus SP7021 defconfig
2022-06-28 6:26 ` Qin Jian
@ 2022-06-28 6:26 ` Qin Jian
-1 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian
Add generic Sunplus SP7021 based board defconfig
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
MAINTAINERS | 1 +
arch/arm/configs/multi_v7_defconfig | 1 +
arch/arm/configs/sp7021_defconfig | 59 +++++++++++++++++++++++++++++
3 files changed, 61 insertions(+)
create mode 100644 arch/arm/configs/sp7021_defconfig
diff --git a/MAINTAINERS b/MAINTAINERS
index 495bfe0f9..6a8936b86 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2834,6 +2834,7 @@ F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
F: Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
F: Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml
+F: arch/arm/configs/sp7021_*defconfig
F: arch/arm/mach-sunplus/
F: drivers/clk/clk-sp7021.c
F: drivers/irqchip/irq-sp7021-intc.c
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index ce9826bce..1a796b16e 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -94,6 +94,7 @@ CONFIG_MACH_SPEAR1310=y
CONFIG_MACH_SPEAR1340=y
CONFIG_ARCH_STI=y
CONFIG_ARCH_STM32=y
+CONFIG_ARCH_SUNPLUS=y
CONFIG_ARCH_SUNXI=y
CONFIG_ARCH_TEGRA=y
CONFIG_ARCH_UNIPHIER=y
diff --git a/arch/arm/configs/sp7021_defconfig b/arch/arm/configs/sp7021_defconfig
new file mode 100644
index 000000000..703b9aaa4
--- /dev/null
+++ b/arch/arm/configs/sp7021_defconfig
@@ -0,0 +1,59 @@
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_RD_GZIP is not set
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_PERF_EVENTS=y
+CONFIG_SLAB=y
+CONFIG_ARCH_SUNPLUS=y
+# CONFIG_VDSO is not set
+CONFIG_SMP=y
+CONFIG_THUMB2_KERNEL=y
+CONFIG_FORCE_MAX_ZONEORDER=12
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_UEVENT_HELPER=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_INPUT_SPARSEKMAP=y
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_RESET_CONTROLLER=y
+CONFIG_EXT4_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_FANOTIFY=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_IOCHARSET="utf8"
+CONFIG_EXFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_USER=y
--
2.33.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 10/11] ARM: sp7021_defconfig: Add Sunplus SP7021 defconfig
@ 2022-06-28 6:26 ` Qin Jian
0 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian
Add generic Sunplus SP7021 based board defconfig
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
MAINTAINERS | 1 +
arch/arm/configs/multi_v7_defconfig | 1 +
arch/arm/configs/sp7021_defconfig | 59 +++++++++++++++++++++++++++++
3 files changed, 61 insertions(+)
create mode 100644 arch/arm/configs/sp7021_defconfig
diff --git a/MAINTAINERS b/MAINTAINERS
index 495bfe0f9..6a8936b86 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2834,6 +2834,7 @@ F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
F: Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
F: Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml
+F: arch/arm/configs/sp7021_*defconfig
F: arch/arm/mach-sunplus/
F: drivers/clk/clk-sp7021.c
F: drivers/irqchip/irq-sp7021-intc.c
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index ce9826bce..1a796b16e 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -94,6 +94,7 @@ CONFIG_MACH_SPEAR1310=y
CONFIG_MACH_SPEAR1340=y
CONFIG_ARCH_STI=y
CONFIG_ARCH_STM32=y
+CONFIG_ARCH_SUNPLUS=y
CONFIG_ARCH_SUNXI=y
CONFIG_ARCH_TEGRA=y
CONFIG_ARCH_UNIPHIER=y
diff --git a/arch/arm/configs/sp7021_defconfig b/arch/arm/configs/sp7021_defconfig
new file mode 100644
index 000000000..703b9aaa4
--- /dev/null
+++ b/arch/arm/configs/sp7021_defconfig
@@ -0,0 +1,59 @@
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_RD_GZIP is not set
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_PERF_EVENTS=y
+CONFIG_SLAB=y
+CONFIG_ARCH_SUNPLUS=y
+# CONFIG_VDSO is not set
+CONFIG_SMP=y
+CONFIG_THUMB2_KERNEL=y
+CONFIG_FORCE_MAX_ZONEORDER=12
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_UEVENT_HELPER=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_INPUT_SPARSEKMAP=y
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_RESET_CONTROLLER=y
+CONFIG_EXT4_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_FANOTIFY=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_IOCHARSET="utf8"
+CONFIG_EXFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_USER=y
--
2.33.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 11/11] ARM: dts: Add Sunplus SP7021-Demo-V3 board device tree
2022-06-28 6:26 ` Qin Jian
@ 2022-06-28 6:26 ` Qin Jian
-1 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian, Krzysztof Kozlowski
Add the basic support for Sunplus SP7021-Demo-V3 board.
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
Addressed Arnd's comments
---
MAINTAINERS | 1 +
arch/arm/boot/dts/Makefile | 2 +
arch/arm/boot/dts/sunplus-sp7021-achip.dtsi | 84 +++++
arch/arm/boot/dts/sunplus-sp7021-demo-v3.dts | 30 ++
arch/arm/boot/dts/sunplus-sp7021.dtsi | 310 +++++++++++++++++++
5 files changed, 427 insertions(+)
create mode 100644 arch/arm/boot/dts/sunplus-sp7021-achip.dtsi
create mode 100644 arch/arm/boot/dts/sunplus-sp7021-demo-v3.dts
create mode 100644 arch/arm/boot/dts/sunplus-sp7021.dtsi
diff --git a/MAINTAINERS b/MAINTAINERS
index 6a8936b86..ca11740e8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2834,6 +2834,7 @@ F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
F: Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
F: Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml
+F: arch/arm/boot/dts/sunplus-sp7021*.dts*
F: arch/arm/configs/sp7021_*defconfig
F: arch/arm/mach-sunplus/
F: drivers/clk/clk-sp7021.c
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 5112f493f..e8f31aa96 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -79,6 +79,8 @@ dtb-$(CONFIG_SOC_SAM_V7) += \
at91-vinco.dtb
dtb-$(CONFIG_SOC_SAMA7G5) += \
at91-sama7g5ek.dtb
+dtb-$(CONFIG_SOC_SP7021) += \
+ sunplus-sp7021-demo-v3.dtb
dtb-$(CONFIG_ARCH_AXXIA) += \
axm5516-amarillo.dtb
dtb-$(CONFIG_ARCH_BCM2835) += \
diff --git a/arch/arm/boot/dts/sunplus-sp7021-achip.dtsi b/arch/arm/boot/dts/sunplus-sp7021-achip.dtsi
new file mode 100644
index 000000000..493d32357
--- /dev/null
+++ b/arch/arm/boot/dts/sunplus-sp7021-achip.dtsi
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for Sunplus SP7021
+ *
+ * Copyright (C) 2021 Sunplus Technology Co.
+ */
+
+#include "sunplus-sp7021.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "sunplus,sp7021-achip", "sunplus,sp7021";
+ model = "Sunplus SP7021 (CA7)";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&gic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0>;
+ clock-frequency = <931000000>;
+ };
+ cpu1: cpu@1 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <1>;
+ clock-frequency = <931000000>;
+ };
+ cpu2: cpu@2 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <2>;
+ clock-frequency = <931000000>;
+ };
+ cpu3: cpu@3 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <3>;
+ clock-frequency = <931000000>;
+ };
+ };
+
+ gic: interrupt-controller@9f101000 {
+ compatible = "arm,cortex-a7-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x9f101000 0x1000>,
+ <0x9f102000 0x2000>,
+ <0x9f104000 0x2000>,
+ <0x9f106000 0x2000>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ clock-frequency = <XTAL>;
+ arm,cpu-registers-not-fw-configured;
+ };
+
+ arm-pmu {
+ compatible = "arm,cortex-a7-pmu";
+ interrupts = <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+ };
+
+ soc@9c000000 {
+ intc: interrupt-controller@780 {
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>, /* EXT_INT0 */
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; /* EXT_INT1 */
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sunplus-sp7021-demo-v3.dts b/arch/arm/boot/dts/sunplus-sp7021-demo-v3.dts
new file mode 100644
index 000000000..d5c5ffc20
--- /dev/null
+++ b/arch/arm/boot/dts/sunplus-sp7021-demo-v3.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for Sunplus SP7021 Demo V3 SBC board
+ *
+ * Copyright (C) Sunplus Technology Co.
+ */
+
+/dts-v1/;
+
+#include "sunplus-sp7021-achip.dtsi"
+
+/ {
+ compatible = "sunplus,sp7021-demo-v3", "sunplus,sp7021";
+ model = "Sunplus SP7021/CA7/Demo_V3";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/sunplus-sp7021.dtsi b/arch/arm/boot/dts/sunplus-sp7021.dtsi
new file mode 100644
index 000000000..7dc4ce361
--- /dev/null
+++ b/arch/arm/boot/dts/sunplus-sp7021.dtsi
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for Sunplus SP7021
+ *
+ * Copyright (C) 2021 Sunplus Technology Co.
+ */
+
+#include <dt-bindings/clock/sunplus,sp7021-clkc.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/reset/sunplus,sp7021-reset.h>
+#include <dt-bindings/pinctrl/sppctl-sp7021.h>
+#include <dt-bindings/gpio/gpio.h>
+
+#define XTAL 27000000
+
+/ {
+ compatible = "sunplus,sp7021";
+ model = "Sunplus SP7021";
+
+ clocks {
+ extclk: osc0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <XTAL>;
+ clock-output-names = "extclk";
+ };
+ };
+
+ soc@9c000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x9c000000 0x400000>;
+ interrupt-parent = <&intc>;
+
+ clkc: clock-controller@4 {
+ compatible = "sunplus,sp7021-clkc";
+ reg = <0x4 0x28>,
+ <0x200 0x44>,
+ <0x268 0x04>;
+ clocks = <&extclk>;
+ #clock-cells = <1>;
+ };
+
+ intc: interrupt-controller@780 {
+ compatible = "sunplus,sp7021-intc";
+ reg = <0x780 0x80>, <0xa80 0x80>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ otp: otp@af00 {
+ compatible = "sunplus,sp7021-ocotp";
+ reg = <0xaf00 0x34>, <0xaf80 0x58>;
+ reg-names = "hb_gpio", "otprx";
+ clocks = <&clkc CLK_OTPRX>;
+ resets = <&rstc RST_OTPRX>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ therm_calib: thermal-calibration@14 {
+ reg = <0x14 0x3>;
+ };
+ disc_vol: disconnect-voltage@18 {
+ reg = <0x18 0x2>;
+ };
+ mac_addr0: mac-address0@34 {
+ reg = <0x34 0x6>;
+ };
+ mac_addr1: mac-address1@3a {
+ reg = <0x3a 0x6>;
+ };
+ };
+
+ pctl: pinctrl@100 {
+ compatible = "sunplus,sp7021-pctl";
+ reg = <0x100 0x100>,
+ <0x300 0x100>,
+ <0x32e4 0x1C>,
+ <0x80 0x20>;
+ reg-names = "moon2", "gpioxt", "first", "moon1";
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clkc CLK_GPIO>;
+ resets = <&rstc RST_GPIO>;
+
+ emac_pins: pinmux-emac-pins {
+ sunplus,pins = <
+ SPPCTL_IOPAD(49,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_CLK_OUT,0)
+ SPPCTL_IOPAD(44,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_MAC_SMI_MDC,0)
+ SPPCTL_IOPAD(43,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_MAC_SMI_MDIO,0)
+ SPPCTL_IOPAD(52,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_TXEN,0)
+ SPPCTL_IOPAD(50,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_TXD0,0)
+ SPPCTL_IOPAD(51,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_TXD1,0)
+ SPPCTL_IOPAD(46,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_CRSDV,0)
+ SPPCTL_IOPAD(47,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_RXD0,0)
+ SPPCTL_IOPAD(48,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_RXD1,0)
+ SPPCTL_IOPAD(45,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_RXER,0)
+ SPPCTL_IOPAD(59,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P1_MAC_RMII_TXEN,0)
+ SPPCTL_IOPAD(57,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P1_MAC_RMII_TXD0,0)
+ SPPCTL_IOPAD(58,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P1_MAC_RMII_TXD1,0)
+ SPPCTL_IOPAD(54,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P1_MAC_RMII_CRSDV,0)
+ SPPCTL_IOPAD(55,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P1_MAC_RMII_RXD0,0)
+ SPPCTL_IOPAD(56,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P1_MAC_RMII_RXD1,0)
+ SPPCTL_IOPAD(53,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P1_MAC_RMII_RXER,0)
+ >;
+ sunplus,zerofunc = <
+ MUXF_L2SW_LED_FLASH0
+ MUXF_L2SW_LED_FLASH1
+ MUXF_L2SW_LED_ON0
+ MUXF_L2SW_LED_ON1
+ MUXF_DAISY_MODE
+ >;
+ };
+
+ emmc_pins: pinmux-emmc-pins {
+ function = "CARD0_EMMC";
+ groups = "CARD0_EMMC";
+ };
+
+ leds_pins: pinmux-leds-pins {
+ sunplus,pins = < SPPCTL_IOPAD(0,SPPCTL_PCTL_G_GPIO,0,SPPCTL_PCTL_L_OUT) >;
+ };
+
+ sdcard_pins: pinmux-sdcard-pins {
+ function = "SD_CARD";
+ groups = "SD_CARD";
+ sunplus,pins = < SPPCTL_IOPAD(91, SPPCTL_PCTL_G_GPIO, 0, 0) >;
+ };
+
+ spi0_pins: pinmux-spi0-pins {
+ sunplus,pins = <
+ SPPCTL_IOPAD(26,SPPCTL_PCTL_G_GPIO,0,0)
+ SPPCTL_IOPAD(28,SPPCTL_PCTL_G_GPIO,0,0)
+ SPPCTL_IOPAD(23,SPPCTL_PCTL_G_PMUX,MUXF_SPI0S_DO,0)
+ SPPCTL_IOPAD(25,SPPCTL_PCTL_G_PMUX,MUXF_SPI0S_DI,0)
+ SPPCTL_IOPAD(27,SPPCTL_PCTL_G_PMUX,MUXF_SPI0S_CLK,0)
+ >;
+ };
+
+ uart0_pins: pinmux-uart0-pins {
+ function = "UA0";
+ groups = "UA0";
+ };
+
+ uart1_pins: pinmux-uart1-pins {
+ sunplus,pins = <
+ SPPCTL_IOPAD(14,SPPCTL_PCTL_G_PMUX,MUXF_UA4_TX,0)
+ SPPCTL_IOPAD(16,SPPCTL_PCTL_G_PMUX,MUXF_UA4_RX,0)
+ >;
+ };
+
+ uart2_pins: pinmux-uart2-pins {
+ sunplus,pins = <
+ SPPCTL_IOPAD(16,SPPCTL_PCTL_G_PMUX,MUXF_UA2_TX,0)
+ SPPCTL_IOPAD(17,SPPCTL_PCTL_G_PMUX,MUXF_UA2_RX,0)
+ SPPCTL_IOPAD(18,SPPCTL_PCTL_G_PMUX,MUXF_UA2_RTS,0)
+ SPPCTL_IOPAD(19,SPPCTL_PCTL_G_PMUX,MUXF_UA2_CTS,0)
+ >;
+ };
+
+ uart4_pins: pinmux-uart4-pins {
+ sunplus,pins = <
+ SPPCTL_IOPAD(22,SPPCTL_PCTL_G_PMUX,MUXF_UA4_TX,0)
+ SPPCTL_IOPAD(20,SPPCTL_PCTL_G_PMUX,MUXF_UA4_RX,0)
+ SPPCTL_IOPAD(23,SPPCTL_PCTL_G_PMUX,MUXF_UA4_RTS,0)
+ SPPCTL_IOPAD(21,SPPCTL_PCTL_G_PMUX,MUXF_UA4_CTS,0)
+ >;
+ };
+ };
+
+ rstc: reset@54 {
+ compatible = "sunplus,sp7021-reset";
+ reg = <0x54 0x28>;
+ #reset-cells = <1>;
+ };
+
+ rtc: rtc@3a00 {
+ compatible = "sunplus,sp7021-rtc";
+ reg = <0x3a00 0x80>;
+ reg-names = "rtc";
+ clocks = <&clkc CLK_RTC>;
+ resets = <&rstc RST_RTC>;
+ interrupts = <163 IRQ_TYPE_EDGE_RISING>;
+ };
+
+ spi_controller0: spi@2d80 {
+ compatible = "sunplus,sp7021-spi";
+ reg = <0x2d80 0x80>, <0x2e00 0x80>;
+ reg-names = "master", "slave";
+ interrupts = <144 IRQ_TYPE_LEVEL_HIGH>,
+ <146 IRQ_TYPE_LEVEL_HIGH>,
+ <145 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dma_w", "master_risc", "slave_risc";
+ clocks = <&clkc CLK_SPI_COMBO_0>;
+ resets = <&rstc RST_SPI_COMBO_0>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+ cs-gpios = <&pctl 26 GPIO_ACTIVE_LOW>,
+ <&pctl 28 GPIO_ACTIVE_LOW>;
+ };
+
+ spi_controller1: spi@f480 {
+ compatible = "sunplus,sp7021-spi";
+ reg = <0xf480 0x80>, <0xf500 0x80>;
+ reg-names = "master", "slave";
+ interrupts = <67 IRQ_TYPE_LEVEL_HIGH>,
+ <69 IRQ_TYPE_LEVEL_HIGH>,
+ <68 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dma_w", "master_risc", "slave_risc";
+ clocks = <&clkc CLK_SPI_COMBO_1>;
+ resets = <&rstc RST_SPI_COMBO_1>;
+ spi-max-frequency = <25000000>;
+ status = "disabled";
+ };
+
+ spi_controller2: spi@f600 {
+ compatible = "sunplus,sp7021-spi";
+ reg = <0xf600 0x80>, <0xf680 0x80>;
+ reg-names = "master", "slave";
+ interrupts = <70 IRQ_TYPE_LEVEL_HIGH>,
+ <72 IRQ_TYPE_LEVEL_HIGH>,
+ <71 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dma_w", "master_risc", "slave_risc";
+ clocks = <&clkc CLK_SPI_COMBO_2>;
+ resets = <&rstc RST_SPI_COMBO_2>;
+ spi-max-frequency = <25000000>;
+ status = "disabled";
+ };
+
+ spi_controller3: spi@f780 {
+ compatible = "sunplus,sp7021-spi";
+ reg = <0xf780 0x80>, <0xf800 0x80>;
+ reg-names = "master", "slave";
+ interrupts = <73 IRQ_TYPE_LEVEL_HIGH>,
+ <75 IRQ_TYPE_LEVEL_HIGH>,
+ <74 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dma_w", "master_risc", "slave_risc";
+ clocks = <&clkc CLK_SPI_COMBO_3>;
+ resets = <&rstc RST_SPI_COMBO_3>;
+ spi-max-frequency = <25000000>;
+ status = "disabled";
+ };
+
+ uart0: serial@900 {
+ compatible = "sunplus,sp7021-uart";
+ reg = <0x900 0x80>;
+ interrupts = <53 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc CLK_UA0>;
+ resets = <&rstc RST_UA0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ };
+
+ uart1: serial@980 {
+ compatible = "sunplus,sp7021-uart";
+ reg = <0x980 0x80>;
+ interrupts = <54 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc CLK_UA1>;
+ resets = <&rstc RST_UA1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "disabled";
+ };
+
+ uart2: serial@800 {
+ compatible = "sunplus,sp7021-uart";
+ reg = <0x800 0x80>;
+ interrupts = <55 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc CLK_UA2>;
+ resets = <&rstc RST_UA2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+ status = "disabled";
+ };
+
+ uart3: serial@880 {
+ compatible = "sunplus,sp7021-uart";
+ reg = <0x880 0x80>;
+ interrupts = <56 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc CLK_UA3>;
+ resets = <&rstc RST_UA3>;
+ status = "disabled";
+ };
+
+ uart4: serial@8780 {
+ compatible = "sunplus,sp7021-uart";
+ reg = <0x8780 0x80>;
+ interrupts = <134 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc CLK_UA4>;
+ resets = <&rstc RST_UA4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_pins>;
+ status = "disabled";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_pins>;
+ system-led {
+ label = "system-led";
+ gpios = <&pctl 0 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
--
2.33.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v20 11/11] ARM: dts: Add Sunplus SP7021-Demo-V3 board device tree
@ 2022-06-28 6:26 ` Qin Jian
0 siblings, 0 replies; 28+ messages in thread
From: Qin Jian @ 2022-06-28 6:26 UTC (permalink / raw)
To: sboyd
Cc: krzysztof.kozlowski+dt, robh+dt, mturquette, linux, arnd, olof,
soc, linux-arm-kernel, devicetree, linux-kernel, linux-clk,
Qin Jian, Krzysztof Kozlowski
Add the basic support for Sunplus SP7021-Demo-V3 board.
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
Addressed Arnd's comments
---
MAINTAINERS | 1 +
arch/arm/boot/dts/Makefile | 2 +
arch/arm/boot/dts/sunplus-sp7021-achip.dtsi | 84 +++++
arch/arm/boot/dts/sunplus-sp7021-demo-v3.dts | 30 ++
arch/arm/boot/dts/sunplus-sp7021.dtsi | 310 +++++++++++++++++++
5 files changed, 427 insertions(+)
create mode 100644 arch/arm/boot/dts/sunplus-sp7021-achip.dtsi
create mode 100644 arch/arm/boot/dts/sunplus-sp7021-demo-v3.dts
create mode 100644 arch/arm/boot/dts/sunplus-sp7021.dtsi
diff --git a/MAINTAINERS b/MAINTAINERS
index 6a8936b86..ca11740e8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2834,6 +2834,7 @@ F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
F: Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
F: Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml
+F: arch/arm/boot/dts/sunplus-sp7021*.dts*
F: arch/arm/configs/sp7021_*defconfig
F: arch/arm/mach-sunplus/
F: drivers/clk/clk-sp7021.c
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 5112f493f..e8f31aa96 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -79,6 +79,8 @@ dtb-$(CONFIG_SOC_SAM_V7) += \
at91-vinco.dtb
dtb-$(CONFIG_SOC_SAMA7G5) += \
at91-sama7g5ek.dtb
+dtb-$(CONFIG_SOC_SP7021) += \
+ sunplus-sp7021-demo-v3.dtb
dtb-$(CONFIG_ARCH_AXXIA) += \
axm5516-amarillo.dtb
dtb-$(CONFIG_ARCH_BCM2835) += \
diff --git a/arch/arm/boot/dts/sunplus-sp7021-achip.dtsi b/arch/arm/boot/dts/sunplus-sp7021-achip.dtsi
new file mode 100644
index 000000000..493d32357
--- /dev/null
+++ b/arch/arm/boot/dts/sunplus-sp7021-achip.dtsi
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for Sunplus SP7021
+ *
+ * Copyright (C) 2021 Sunplus Technology Co.
+ */
+
+#include "sunplus-sp7021.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "sunplus,sp7021-achip", "sunplus,sp7021";
+ model = "Sunplus SP7021 (CA7)";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&gic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0>;
+ clock-frequency = <931000000>;
+ };
+ cpu1: cpu@1 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <1>;
+ clock-frequency = <931000000>;
+ };
+ cpu2: cpu@2 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <2>;
+ clock-frequency = <931000000>;
+ };
+ cpu3: cpu@3 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <3>;
+ clock-frequency = <931000000>;
+ };
+ };
+
+ gic: interrupt-controller@9f101000 {
+ compatible = "arm,cortex-a7-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x9f101000 0x1000>,
+ <0x9f102000 0x2000>,
+ <0x9f104000 0x2000>,
+ <0x9f106000 0x2000>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ clock-frequency = <XTAL>;
+ arm,cpu-registers-not-fw-configured;
+ };
+
+ arm-pmu {
+ compatible = "arm,cortex-a7-pmu";
+ interrupts = <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+ };
+
+ soc@9c000000 {
+ intc: interrupt-controller@780 {
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>, /* EXT_INT0 */
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; /* EXT_INT1 */
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sunplus-sp7021-demo-v3.dts b/arch/arm/boot/dts/sunplus-sp7021-demo-v3.dts
new file mode 100644
index 000000000..d5c5ffc20
--- /dev/null
+++ b/arch/arm/boot/dts/sunplus-sp7021-demo-v3.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for Sunplus SP7021 Demo V3 SBC board
+ *
+ * Copyright (C) Sunplus Technology Co.
+ */
+
+/dts-v1/;
+
+#include "sunplus-sp7021-achip.dtsi"
+
+/ {
+ compatible = "sunplus,sp7021-demo-v3", "sunplus,sp7021";
+ model = "Sunplus SP7021/CA7/Demo_V3";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/sunplus-sp7021.dtsi b/arch/arm/boot/dts/sunplus-sp7021.dtsi
new file mode 100644
index 000000000..7dc4ce361
--- /dev/null
+++ b/arch/arm/boot/dts/sunplus-sp7021.dtsi
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for Sunplus SP7021
+ *
+ * Copyright (C) 2021 Sunplus Technology Co.
+ */
+
+#include <dt-bindings/clock/sunplus,sp7021-clkc.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/reset/sunplus,sp7021-reset.h>
+#include <dt-bindings/pinctrl/sppctl-sp7021.h>
+#include <dt-bindings/gpio/gpio.h>
+
+#define XTAL 27000000
+
+/ {
+ compatible = "sunplus,sp7021";
+ model = "Sunplus SP7021";
+
+ clocks {
+ extclk: osc0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <XTAL>;
+ clock-output-names = "extclk";
+ };
+ };
+
+ soc@9c000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x9c000000 0x400000>;
+ interrupt-parent = <&intc>;
+
+ clkc: clock-controller@4 {
+ compatible = "sunplus,sp7021-clkc";
+ reg = <0x4 0x28>,
+ <0x200 0x44>,
+ <0x268 0x04>;
+ clocks = <&extclk>;
+ #clock-cells = <1>;
+ };
+
+ intc: interrupt-controller@780 {
+ compatible = "sunplus,sp7021-intc";
+ reg = <0x780 0x80>, <0xa80 0x80>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ otp: otp@af00 {
+ compatible = "sunplus,sp7021-ocotp";
+ reg = <0xaf00 0x34>, <0xaf80 0x58>;
+ reg-names = "hb_gpio", "otprx";
+ clocks = <&clkc CLK_OTPRX>;
+ resets = <&rstc RST_OTPRX>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ therm_calib: thermal-calibration@14 {
+ reg = <0x14 0x3>;
+ };
+ disc_vol: disconnect-voltage@18 {
+ reg = <0x18 0x2>;
+ };
+ mac_addr0: mac-address0@34 {
+ reg = <0x34 0x6>;
+ };
+ mac_addr1: mac-address1@3a {
+ reg = <0x3a 0x6>;
+ };
+ };
+
+ pctl: pinctrl@100 {
+ compatible = "sunplus,sp7021-pctl";
+ reg = <0x100 0x100>,
+ <0x300 0x100>,
+ <0x32e4 0x1C>,
+ <0x80 0x20>;
+ reg-names = "moon2", "gpioxt", "first", "moon1";
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clkc CLK_GPIO>;
+ resets = <&rstc RST_GPIO>;
+
+ emac_pins: pinmux-emac-pins {
+ sunplus,pins = <
+ SPPCTL_IOPAD(49,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_CLK_OUT,0)
+ SPPCTL_IOPAD(44,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_MAC_SMI_MDC,0)
+ SPPCTL_IOPAD(43,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_MAC_SMI_MDIO,0)
+ SPPCTL_IOPAD(52,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_TXEN,0)
+ SPPCTL_IOPAD(50,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_TXD0,0)
+ SPPCTL_IOPAD(51,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_TXD1,0)
+ SPPCTL_IOPAD(46,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_CRSDV,0)
+ SPPCTL_IOPAD(47,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_RXD0,0)
+ SPPCTL_IOPAD(48,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_RXD1,0)
+ SPPCTL_IOPAD(45,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_RXER,0)
+ SPPCTL_IOPAD(59,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P1_MAC_RMII_TXEN,0)
+ SPPCTL_IOPAD(57,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P1_MAC_RMII_TXD0,0)
+ SPPCTL_IOPAD(58,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P1_MAC_RMII_TXD1,0)
+ SPPCTL_IOPAD(54,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P1_MAC_RMII_CRSDV,0)
+ SPPCTL_IOPAD(55,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P1_MAC_RMII_RXD0,0)
+ SPPCTL_IOPAD(56,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P1_MAC_RMII_RXD1,0)
+ SPPCTL_IOPAD(53,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P1_MAC_RMII_RXER,0)
+ >;
+ sunplus,zerofunc = <
+ MUXF_L2SW_LED_FLASH0
+ MUXF_L2SW_LED_FLASH1
+ MUXF_L2SW_LED_ON0
+ MUXF_L2SW_LED_ON1
+ MUXF_DAISY_MODE
+ >;
+ };
+
+ emmc_pins: pinmux-emmc-pins {
+ function = "CARD0_EMMC";
+ groups = "CARD0_EMMC";
+ };
+
+ leds_pins: pinmux-leds-pins {
+ sunplus,pins = < SPPCTL_IOPAD(0,SPPCTL_PCTL_G_GPIO,0,SPPCTL_PCTL_L_OUT) >;
+ };
+
+ sdcard_pins: pinmux-sdcard-pins {
+ function = "SD_CARD";
+ groups = "SD_CARD";
+ sunplus,pins = < SPPCTL_IOPAD(91, SPPCTL_PCTL_G_GPIO, 0, 0) >;
+ };
+
+ spi0_pins: pinmux-spi0-pins {
+ sunplus,pins = <
+ SPPCTL_IOPAD(26,SPPCTL_PCTL_G_GPIO,0,0)
+ SPPCTL_IOPAD(28,SPPCTL_PCTL_G_GPIO,0,0)
+ SPPCTL_IOPAD(23,SPPCTL_PCTL_G_PMUX,MUXF_SPI0S_DO,0)
+ SPPCTL_IOPAD(25,SPPCTL_PCTL_G_PMUX,MUXF_SPI0S_DI,0)
+ SPPCTL_IOPAD(27,SPPCTL_PCTL_G_PMUX,MUXF_SPI0S_CLK,0)
+ >;
+ };
+
+ uart0_pins: pinmux-uart0-pins {
+ function = "UA0";
+ groups = "UA0";
+ };
+
+ uart1_pins: pinmux-uart1-pins {
+ sunplus,pins = <
+ SPPCTL_IOPAD(14,SPPCTL_PCTL_G_PMUX,MUXF_UA4_TX,0)
+ SPPCTL_IOPAD(16,SPPCTL_PCTL_G_PMUX,MUXF_UA4_RX,0)
+ >;
+ };
+
+ uart2_pins: pinmux-uart2-pins {
+ sunplus,pins = <
+ SPPCTL_IOPAD(16,SPPCTL_PCTL_G_PMUX,MUXF_UA2_TX,0)
+ SPPCTL_IOPAD(17,SPPCTL_PCTL_G_PMUX,MUXF_UA2_RX,0)
+ SPPCTL_IOPAD(18,SPPCTL_PCTL_G_PMUX,MUXF_UA2_RTS,0)
+ SPPCTL_IOPAD(19,SPPCTL_PCTL_G_PMUX,MUXF_UA2_CTS,0)
+ >;
+ };
+
+ uart4_pins: pinmux-uart4-pins {
+ sunplus,pins = <
+ SPPCTL_IOPAD(22,SPPCTL_PCTL_G_PMUX,MUXF_UA4_TX,0)
+ SPPCTL_IOPAD(20,SPPCTL_PCTL_G_PMUX,MUXF_UA4_RX,0)
+ SPPCTL_IOPAD(23,SPPCTL_PCTL_G_PMUX,MUXF_UA4_RTS,0)
+ SPPCTL_IOPAD(21,SPPCTL_PCTL_G_PMUX,MUXF_UA4_CTS,0)
+ >;
+ };
+ };
+
+ rstc: reset@54 {
+ compatible = "sunplus,sp7021-reset";
+ reg = <0x54 0x28>;
+ #reset-cells = <1>;
+ };
+
+ rtc: rtc@3a00 {
+ compatible = "sunplus,sp7021-rtc";
+ reg = <0x3a00 0x80>;
+ reg-names = "rtc";
+ clocks = <&clkc CLK_RTC>;
+ resets = <&rstc RST_RTC>;
+ interrupts = <163 IRQ_TYPE_EDGE_RISING>;
+ };
+
+ spi_controller0: spi@2d80 {
+ compatible = "sunplus,sp7021-spi";
+ reg = <0x2d80 0x80>, <0x2e00 0x80>;
+ reg-names = "master", "slave";
+ interrupts = <144 IRQ_TYPE_LEVEL_HIGH>,
+ <146 IRQ_TYPE_LEVEL_HIGH>,
+ <145 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dma_w", "master_risc", "slave_risc";
+ clocks = <&clkc CLK_SPI_COMBO_0>;
+ resets = <&rstc RST_SPI_COMBO_0>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+ cs-gpios = <&pctl 26 GPIO_ACTIVE_LOW>,
+ <&pctl 28 GPIO_ACTIVE_LOW>;
+ };
+
+ spi_controller1: spi@f480 {
+ compatible = "sunplus,sp7021-spi";
+ reg = <0xf480 0x80>, <0xf500 0x80>;
+ reg-names = "master", "slave";
+ interrupts = <67 IRQ_TYPE_LEVEL_HIGH>,
+ <69 IRQ_TYPE_LEVEL_HIGH>,
+ <68 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dma_w", "master_risc", "slave_risc";
+ clocks = <&clkc CLK_SPI_COMBO_1>;
+ resets = <&rstc RST_SPI_COMBO_1>;
+ spi-max-frequency = <25000000>;
+ status = "disabled";
+ };
+
+ spi_controller2: spi@f600 {
+ compatible = "sunplus,sp7021-spi";
+ reg = <0xf600 0x80>, <0xf680 0x80>;
+ reg-names = "master", "slave";
+ interrupts = <70 IRQ_TYPE_LEVEL_HIGH>,
+ <72 IRQ_TYPE_LEVEL_HIGH>,
+ <71 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dma_w", "master_risc", "slave_risc";
+ clocks = <&clkc CLK_SPI_COMBO_2>;
+ resets = <&rstc RST_SPI_COMBO_2>;
+ spi-max-frequency = <25000000>;
+ status = "disabled";
+ };
+
+ spi_controller3: spi@f780 {
+ compatible = "sunplus,sp7021-spi";
+ reg = <0xf780 0x80>, <0xf800 0x80>;
+ reg-names = "master", "slave";
+ interrupts = <73 IRQ_TYPE_LEVEL_HIGH>,
+ <75 IRQ_TYPE_LEVEL_HIGH>,
+ <74 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dma_w", "master_risc", "slave_risc";
+ clocks = <&clkc CLK_SPI_COMBO_3>;
+ resets = <&rstc RST_SPI_COMBO_3>;
+ spi-max-frequency = <25000000>;
+ status = "disabled";
+ };
+
+ uart0: serial@900 {
+ compatible = "sunplus,sp7021-uart";
+ reg = <0x900 0x80>;
+ interrupts = <53 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc CLK_UA0>;
+ resets = <&rstc RST_UA0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ };
+
+ uart1: serial@980 {
+ compatible = "sunplus,sp7021-uart";
+ reg = <0x980 0x80>;
+ interrupts = <54 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc CLK_UA1>;
+ resets = <&rstc RST_UA1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "disabled";
+ };
+
+ uart2: serial@800 {
+ compatible = "sunplus,sp7021-uart";
+ reg = <0x800 0x80>;
+ interrupts = <55 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc CLK_UA2>;
+ resets = <&rstc RST_UA2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+ status = "disabled";
+ };
+
+ uart3: serial@880 {
+ compatible = "sunplus,sp7021-uart";
+ reg = <0x880 0x80>;
+ interrupts = <56 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc CLK_UA3>;
+ resets = <&rstc RST_UA3>;
+ status = "disabled";
+ };
+
+ uart4: serial@8780 {
+ compatible = "sunplus,sp7021-uart";
+ reg = <0x8780 0x80>;
+ interrupts = <134 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc CLK_UA4>;
+ resets = <&rstc RST_UA4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_pins>;
+ status = "disabled";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_pins>;
+ system-led {
+ label = "system-led";
+ gpios = <&pctl 0 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
--
2.33.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH v20 00/11] Add Sunplus SP7021 SoC Support
2022-06-28 6:26 ` Qin Jian
@ 2022-07-06 15:01 ` Arnd Bergmann
-1 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2022-07-06 15:01 UTC (permalink / raw)
To: Qin Jian
Cc: Stephen Boyd, Krzysztof Kozlowski, Rob Herring,
Michael Turquette, Russell King - ARM Linux, Arnd Bergmann,
Olof Johansson, SoC Team, Linux ARM, DTML,
Linux Kernel Mailing List, linux-clk
On Tue, Jun 28, 2022 at 8:26 AM Qin Jian <qinjian@cqplus1.com> wrote:
>
> This patch series add Sunplus SP7021 SoC support.
>
> Sunplus SP7021 is an ARM Cortex A7 (4 cores) based SoC. It integrates many
> peripherals (ex: UART, I2C, SPI, SDIO, eMMC, USB, SD card and etc.) into a
> single chip. It is designed for industrial control.
>
> SP7021 consists of two chips (dies) in a package. One is called C-chip
> (computing chip). It is a 4-core ARM Cortex A7 CPU. It adopts high-level
> process (22 nm) for high performance computing. The other is called P-
> chip (peripheral chip). It has many peripherals and an ARM A926 added
> especially for real-time control. P-chip is made for customers. It adopts
> low-level process (ex: 0.11 um) to reduce cost.
>
As far as I can tell, all review comments have been fully addressed,
but I'm missing an Ack from Stephen Boyd so I can apply it through
the SoC tree.
Arnd
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v20 00/11] Add Sunplus SP7021 SoC Support
@ 2022-07-06 15:01 ` Arnd Bergmann
0 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2022-07-06 15:01 UTC (permalink / raw)
To: Qin Jian
Cc: Stephen Boyd, Krzysztof Kozlowski, Rob Herring,
Michael Turquette, Russell King - ARM Linux, Arnd Bergmann,
Olof Johansson, SoC Team, Linux ARM, DTML,
Linux Kernel Mailing List, linux-clk
On Tue, Jun 28, 2022 at 8:26 AM Qin Jian <qinjian@cqplus1.com> wrote:
>
> This patch series add Sunplus SP7021 SoC support.
>
> Sunplus SP7021 is an ARM Cortex A7 (4 cores) based SoC. It integrates many
> peripherals (ex: UART, I2C, SPI, SDIO, eMMC, USB, SD card and etc.) into a
> single chip. It is designed for industrial control.
>
> SP7021 consists of two chips (dies) in a package. One is called C-chip
> (computing chip). It is a 4-core ARM Cortex A7 CPU. It adopts high-level
> process (22 nm) for high performance computing. The other is called P-
> chip (peripheral chip). It has many peripherals and an ARM A926 added
> especially for real-time control. P-chip is made for customers. It adopts
> low-level process (ex: 0.11 um) to reduce cost.
>
As far as I can tell, all review comments have been fully addressed,
but I'm missing an Ack from Stephen Boyd so I can apply it through
the SoC tree.
Arnd
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v20 00/11] Add Sunplus SP7021 SoC Support
2022-07-06 15:01 ` Arnd Bergmann
@ 2022-07-18 11:24 ` Arnd Bergmann
-1 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2022-07-18 11:24 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Qin Jian, Stephen Boyd, Krzysztof Kozlowski, Rob Herring,
Michael Turquette, Russell King - ARM Linux, Olof Johansson,
SoC Team, Linux ARM, DTML, Linux Kernel Mailing List, linux-clk
On Wed, Jul 6, 2022 at 5:01 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Tue, Jun 28, 2022 at 8:26 AM Qin Jian <qinjian@cqplus1.com> wrote:
> >
> > This patch series add Sunplus SP7021 SoC support.
> >
> > Sunplus SP7021 is an ARM Cortex A7 (4 cores) based SoC. It integrates many
> > peripherals (ex: UART, I2C, SPI, SDIO, eMMC, USB, SD card and etc.) into a
> > single chip. It is designed for industrial control.
> >
> > SP7021 consists of two chips (dies) in a package. One is called C-chip
> > (computing chip). It is a 4-core ARM Cortex A7 CPU. It adopts high-level
> > process (22 nm) for high performance computing. The other is called P-
> > chip (peripheral chip). It has many peripherals and an ARM A926 added
> > especially for real-time control. P-chip is made for customers. It adopts
> > low-level process (ex: 0.11 um) to reduce cost.
> >
>
> As far as I can tell, all review comments have been fully addressed,
> but I'm missing an Ack from Stephen Boyd so I can apply it through
> the SoC tree.
I ended up applying the series without the clk driver now, please see
https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git/commit/?h=arm/newsoc&id=7cb7b8fe63393d77
No need to resend the series any more, please just work with
the clk maintainers to get that driver included through their tree.
If there are any issues with the patches that I merged, it's best
to send bugfix patches that can be applied on top of the branch
listed above, or a pull request based on that commit.
For new features to be merged in a later release, e.g. patches to
add device tree nodes for other on-chip components, or additional
dts files, please base them on the coming -rc1 release when that
is out.
Arnd
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v20 00/11] Add Sunplus SP7021 SoC Support
@ 2022-07-18 11:24 ` Arnd Bergmann
0 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2022-07-18 11:24 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Qin Jian, Stephen Boyd, Krzysztof Kozlowski, Rob Herring,
Michael Turquette, Russell King - ARM Linux, Olof Johansson,
SoC Team, Linux ARM, DTML, Linux Kernel Mailing List, linux-clk
On Wed, Jul 6, 2022 at 5:01 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Tue, Jun 28, 2022 at 8:26 AM Qin Jian <qinjian@cqplus1.com> wrote:
> >
> > This patch series add Sunplus SP7021 SoC support.
> >
> > Sunplus SP7021 is an ARM Cortex A7 (4 cores) based SoC. It integrates many
> > peripherals (ex: UART, I2C, SPI, SDIO, eMMC, USB, SD card and etc.) into a
> > single chip. It is designed for industrial control.
> >
> > SP7021 consists of two chips (dies) in a package. One is called C-chip
> > (computing chip). It is a 4-core ARM Cortex A7 CPU. It adopts high-level
> > process (22 nm) for high performance computing. The other is called P-
> > chip (peripheral chip). It has many peripherals and an ARM A926 added
> > especially for real-time control. P-chip is made for customers. It adopts
> > low-level process (ex: 0.11 um) to reduce cost.
> >
>
> As far as I can tell, all review comments have been fully addressed,
> but I'm missing an Ack from Stephen Boyd so I can apply it through
> the SoC tree.
I ended up applying the series without the clk driver now, please see
https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git/commit/?h=arm/newsoc&id=7cb7b8fe63393d77
No need to resend the series any more, please just work with
the clk maintainers to get that driver included through their tree.
If there are any issues with the patches that I merged, it's best
to send bugfix patches that can be applied on top of the branch
listed above, or a pull request based on that commit.
For new features to be merged in a later release, e.g. patches to
add device tree nodes for other on-chip components, or additional
dts files, please base them on the coming -rc1 release when that
is out.
Arnd
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2022-07-18 11:26 UTC | newest]
Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-28 6:26 [PATCH v20 00/11] Add Sunplus SP7021 SoC Support Qin Jian
2022-06-28 6:26 ` Qin Jian
2022-06-28 6:26 ` [PATCH v20 01/11] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards Qin Jian
2022-06-28 6:26 ` Qin Jian
2022-06-28 6:26 ` [PATCH v20 02/11] dt-bindings: reset: Add bindings for SP7021 reset driver Qin Jian
2022-06-28 6:26 ` Qin Jian
2022-06-28 6:26 ` [PATCH v20 03/11] reset: Add Sunplus " Qin Jian
2022-06-28 6:26 ` Qin Jian
2022-06-28 6:26 ` [PATCH v20 04/11] dt-bindings: clock: Add bindings for SP7021 clock driver Qin Jian
2022-06-28 6:26 ` Qin Jian
2022-06-28 6:26 ` [PATCH v20 05/11] clk: gate: Add devm_clk_hw_register_gate_parent_data() Qin Jian
2022-06-28 6:26 ` Qin Jian
2022-06-28 6:26 ` [PATCH v20 06/11] clk: Add Sunplus SP7021 clock driver Qin Jian
2022-06-28 6:26 ` Qin Jian
2022-06-28 6:26 ` [PATCH v20 07/11] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller Qin Jian
2022-06-28 6:26 ` Qin Jian
2022-06-28 6:26 ` [PATCH v20 08/11] irqchip: Add Sunplus SP7021 interrupt controller driver Qin Jian
2022-06-28 6:26 ` Qin Jian
2022-06-28 6:26 ` [PATCH v20 09/11] ARM: sunplus: Add initial support for Sunplus SP7021 SoC Qin Jian
2022-06-28 6:26 ` Qin Jian
2022-06-28 6:26 ` [PATCH v20 10/11] ARM: sp7021_defconfig: Add Sunplus SP7021 defconfig Qin Jian
2022-06-28 6:26 ` Qin Jian
2022-06-28 6:26 ` [PATCH v20 11/11] ARM: dts: Add Sunplus SP7021-Demo-V3 board device tree Qin Jian
2022-06-28 6:26 ` Qin Jian
2022-07-06 15:01 ` [PATCH v20 00/11] Add Sunplus SP7021 SoC Support Arnd Bergmann
2022-07-06 15:01 ` Arnd Bergmann
2022-07-18 11:24 ` Arnd Bergmann
2022-07-18 11:24 ` Arnd Bergmann
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.