All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v12 0/9] Add Sunplus SP7021 SoC Support
@ 2022-03-31  8:29 ` Qin Jian
  0 siblings, 0 replies; 58+ messages in thread
From: Qin Jian @ 2022-03-31  8:29 UTC (permalink / raw)
  To: krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	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 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 (9):
  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: 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

 .../bindings/arm/sunplus,sp7021.yaml          |  28 +
 .../bindings/clock/sunplus,sp7021-clkc.yaml   |  39 +
 .../sunplus,sp7021-intc.yaml                  |  62 ++
 .../bindings/reset/sunplus,reset.yaml         |  38 +
 MAINTAINERS                                   |  17 +
 arch/arm/Kconfig                              |   2 +
 arch/arm/Makefile                             |   1 +
 arch/arm/configs/multi_v7_defconfig           |   1 +
 arch/arm/configs/sp7021_defconfig             |  61 ++
 arch/arm/mach-sunplus/Kconfig                 |  26 +
 arch/arm/mach-sunplus/Makefile                |   9 +
 arch/arm/mach-sunplus/sp7021.c                |  16 +
 drivers/clk/Kconfig                           |  10 +
 drivers/clk/Makefile                          |   1 +
 drivers/clk/clk-sp7021.c                      | 736 ++++++++++++++++++
 drivers/irqchip/Kconfig                       |   9 +
 drivers/irqchip/Makefile                      |   2 +
 drivers/irqchip/irq-sp7021-intc.c             | 288 +++++++
 drivers/reset/Kconfig                         |   9 +
 drivers/reset/Makefile                        |   1 +
 drivers/reset/reset-sunplus.c                 | 130 ++++
 include/dt-bindings/clock/sp-sp7021.h         | 112 +++
 include/dt-bindings/reset/sp-sp7021.h         |  97 +++
 23 files changed, 1695 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/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/sp-sp7021.h
 create mode 100644 include/dt-bindings/reset/sp-sp7021.h

-- 
2.33.1


^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v12 0/9] Add Sunplus SP7021 SoC Support
@ 2022-03-31  8:29 ` Qin Jian
  0 siblings, 0 replies; 58+ messages in thread
From: Qin Jian @ 2022-03-31  8:29 UTC (permalink / raw)
  To: krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	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 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 (9):
  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: 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

 .../bindings/arm/sunplus,sp7021.yaml          |  28 +
 .../bindings/clock/sunplus,sp7021-clkc.yaml   |  39 +
 .../sunplus,sp7021-intc.yaml                  |  62 ++
 .../bindings/reset/sunplus,reset.yaml         |  38 +
 MAINTAINERS                                   |  17 +
 arch/arm/Kconfig                              |   2 +
 arch/arm/Makefile                             |   1 +
 arch/arm/configs/multi_v7_defconfig           |   1 +
 arch/arm/configs/sp7021_defconfig             |  61 ++
 arch/arm/mach-sunplus/Kconfig                 |  26 +
 arch/arm/mach-sunplus/Makefile                |   9 +
 arch/arm/mach-sunplus/sp7021.c                |  16 +
 drivers/clk/Kconfig                           |  10 +
 drivers/clk/Makefile                          |   1 +
 drivers/clk/clk-sp7021.c                      | 736 ++++++++++++++++++
 drivers/irqchip/Kconfig                       |   9 +
 drivers/irqchip/Makefile                      |   2 +
 drivers/irqchip/irq-sp7021-intc.c             | 288 +++++++
 drivers/reset/Kconfig                         |   9 +
 drivers/reset/Makefile                        |   1 +
 drivers/reset/reset-sunplus.c                 | 130 ++++
 include/dt-bindings/clock/sp-sp7021.h         | 112 +++
 include/dt-bindings/reset/sp-sp7021.h         |  97 +++
 23 files changed, 1695 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/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/sp-sp7021.h
 create mode 100644 include/dt-bindings/reset/sp-sp7021.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] 58+ messages in thread

* [PATCH v12 1/9] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards
  2022-03-31  8:29 ` Qin Jian
@ 2022-03-31  8:29   ` Qin Jian
  -1 siblings, 0 replies; 58+ messages in thread
From: Qin Jian @ 2022-03-31  8:29 UTC (permalink / raw)
  To: krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, Qin Jian

This introduces bindings for boards based Sunplus SP7021 SoC.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../bindings/arm/sunplus,sp7021.yaml          | 28 +++++++++++++++++++
 MAINTAINERS                                   |  7 +++++
 2 files changed, 35 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..ef48fb270
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
@@ -0,0 +1,28 @@
+# 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 Device Tree Bindings
+
+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
+      - const: sunplus,sp7021
+
+additionalProperties: true
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index cd0f68d4a..8b5e2e639 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2738,6 +2738,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] 58+ messages in thread

* [PATCH v12 1/9] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards
@ 2022-03-31  8:29   ` Qin Jian
  0 siblings, 0 replies; 58+ messages in thread
From: Qin Jian @ 2022-03-31  8:29 UTC (permalink / raw)
  To: krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, Qin Jian

This introduces bindings for boards based Sunplus SP7021 SoC.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../bindings/arm/sunplus,sp7021.yaml          | 28 +++++++++++++++++++
 MAINTAINERS                                   |  7 +++++
 2 files changed, 35 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..ef48fb270
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
@@ -0,0 +1,28 @@
+# 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 Device Tree Bindings
+
+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
+      - const: sunplus,sp7021
+
+additionalProperties: true
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index cd0f68d4a..8b5e2e639 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2738,6 +2738,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] 58+ messages in thread

* [PATCH v12 2/9] dt-bindings: reset: Add bindings for SP7021 reset driver
  2022-03-31  8:29 ` Qin Jian
@ 2022-03-31  8:29   ` Qin Jian
  -1 siblings, 0 replies; 58+ messages in thread
From: Qin Jian @ 2022-03-31  8:29 UTC (permalink / raw)
  To: krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, Qin Jian

Add documentation to describe Sunplus SP7021 reset driver bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
Move "reg' after 'compatible'
---
 .../bindings/reset/sunplus,reset.yaml         | 38 ++++++++
 MAINTAINERS                                   |  2 +
 include/dt-bindings/reset/sp-sp7021.h         | 97 +++++++++++++++++++
 3 files changed, 137 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reset/sunplus,reset.yaml
 create mode 100644 include/dt-bindings/reset/sp-sp7021.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 8b5e2e639..a8be86b25 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2744,6 +2744,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/sp-sp7021.h
 
 ARM/Synaptics SoC support
 M:	Jisheng Zhang <jszhang@kernel.org>
diff --git a/include/dt-bindings/reset/sp-sp7021.h b/include/dt-bindings/reset/sp-sp7021.h
new file mode 100644
index 000000000..fd2a50327
--- /dev/null
+++ b/include/dt-bindings/reset/sp-sp7021.h
@@ -0,0 +1,97 @@
+/* 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
+
+/* mo_reset0 ~ mo_reset9 */
+#define RST_SYSTEM		0x00
+#define RST_RTC			0x02
+#define RST_IOCTL		0x03
+#define RST_IOP			0x04
+#define RST_OTPRX		0x05
+#define RST_NOC			0x06
+#define RST_BR			0x07
+#define RST_RBUS_L00	        0x08
+#define RST_SPIFL		0x09
+#define RST_SDCTRL0		0x0a
+#define RST_PERI0		0x0b
+#define RST_A926		0x0d
+#define RST_UMCTL2		0x0e
+#define RST_PERI1		0x0f
+
+#define RST_DDR_PHY0	        0x10
+#define RST_ACHIP		0x12
+#define RST_STC0		0x14
+#define RST_STC_AV0		0x15
+#define RST_STC_AV1		0x16
+#define RST_STC_AV2		0x17
+#define RST_UA0			0x18
+#define RST_UA1			0x19
+#define RST_UA2			0x1a
+#define RST_UA3			0x1b
+#define RST_UA4			0x1c
+#define RST_HWUA		0x1d
+#define RST_DDC0		0x1e
+#define RST_UADMA		0x1f
+
+#define RST_CBDMA0		0x20
+#define RST_CBDMA1		0x21
+#define RST_SPI_COMBO_0	        0x22
+#define RST_SPI_COMBO_1	        0x23
+#define RST_SPI_COMBO_2	        0x24
+#define RST_SPI_COMBO_3	        0x25
+#define RST_AUD			0x26
+#define RST_USBC0		0x2a
+#define RST_USBC1		0x2b
+#define RST_UPHY0		0x2d
+#define RST_UPHY1		0x2e
+
+#define RST_I2CM0		0x30
+#define RST_I2CM1		0x31
+#define RST_I2CM2		0x32
+#define RST_I2CM3		0x33
+#define RST_PMC			0x3d
+#define RST_CARD_CTL0	        0x3e
+#define RST_CARD_CTL1	        0x3f
+
+#define RST_CARD_CTL4	        0x42
+#define RST_BCH			0x44
+#define RST_DDFCH		0x4b
+#define RST_CSIIW0		0x4c
+#define RST_CSIIW1		0x4d
+#define RST_MIPICSI0	        0x4e
+#define RST_MIPICSI1	        0x4f
+
+#define RST_HDMI_TX		0x50
+#define RST_VPOST		0x55
+
+#define RST_TGEN		0x60
+#define RST_DMIX		0x61
+#define RST_TCON		0x6a
+#define RST_INTERRUPT	        0x6f
+
+#define RST_RGST		0x70
+#define RST_GPIO		0x73
+#define RST_RBUS_TOP	        0x74
+
+#define RST_MAILBOX		0x86
+#define RST_SPIND		0x8a
+#define RST_I2C2CBUS	        0x8b
+#define RST_SEC			0x8d
+#define RST_DVE			0x8e
+#define RST_GPOST0		0x8f
+
+#define RST_OSD0		0x90
+#define RST_DISP_PWM	        0x92
+#define RST_UADBG		0x93
+#define RST_DUMMY_MASTER	0x94
+#define RST_FIO_CTL		0x95
+#define RST_FPGA		0x96
+#define RST_L2SW		0x97
+#define RST_ICM			0x98
+#define RST_AXI_GLOBAL	        0x99
+
+#endif
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v12 2/9] dt-bindings: reset: Add bindings for SP7021 reset driver
@ 2022-03-31  8:29   ` Qin Jian
  0 siblings, 0 replies; 58+ messages in thread
From: Qin Jian @ 2022-03-31  8:29 UTC (permalink / raw)
  To: krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, Qin Jian

Add documentation to describe Sunplus SP7021 reset driver bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
Move "reg' after 'compatible'
---
 .../bindings/reset/sunplus,reset.yaml         | 38 ++++++++
 MAINTAINERS                                   |  2 +
 include/dt-bindings/reset/sp-sp7021.h         | 97 +++++++++++++++++++
 3 files changed, 137 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reset/sunplus,reset.yaml
 create mode 100644 include/dt-bindings/reset/sp-sp7021.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 8b5e2e639..a8be86b25 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2744,6 +2744,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/sp-sp7021.h
 
 ARM/Synaptics SoC support
 M:	Jisheng Zhang <jszhang@kernel.org>
diff --git a/include/dt-bindings/reset/sp-sp7021.h b/include/dt-bindings/reset/sp-sp7021.h
new file mode 100644
index 000000000..fd2a50327
--- /dev/null
+++ b/include/dt-bindings/reset/sp-sp7021.h
@@ -0,0 +1,97 @@
+/* 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
+
+/* mo_reset0 ~ mo_reset9 */
+#define RST_SYSTEM		0x00
+#define RST_RTC			0x02
+#define RST_IOCTL		0x03
+#define RST_IOP			0x04
+#define RST_OTPRX		0x05
+#define RST_NOC			0x06
+#define RST_BR			0x07
+#define RST_RBUS_L00	        0x08
+#define RST_SPIFL		0x09
+#define RST_SDCTRL0		0x0a
+#define RST_PERI0		0x0b
+#define RST_A926		0x0d
+#define RST_UMCTL2		0x0e
+#define RST_PERI1		0x0f
+
+#define RST_DDR_PHY0	        0x10
+#define RST_ACHIP		0x12
+#define RST_STC0		0x14
+#define RST_STC_AV0		0x15
+#define RST_STC_AV1		0x16
+#define RST_STC_AV2		0x17
+#define RST_UA0			0x18
+#define RST_UA1			0x19
+#define RST_UA2			0x1a
+#define RST_UA3			0x1b
+#define RST_UA4			0x1c
+#define RST_HWUA		0x1d
+#define RST_DDC0		0x1e
+#define RST_UADMA		0x1f
+
+#define RST_CBDMA0		0x20
+#define RST_CBDMA1		0x21
+#define RST_SPI_COMBO_0	        0x22
+#define RST_SPI_COMBO_1	        0x23
+#define RST_SPI_COMBO_2	        0x24
+#define RST_SPI_COMBO_3	        0x25
+#define RST_AUD			0x26
+#define RST_USBC0		0x2a
+#define RST_USBC1		0x2b
+#define RST_UPHY0		0x2d
+#define RST_UPHY1		0x2e
+
+#define RST_I2CM0		0x30
+#define RST_I2CM1		0x31
+#define RST_I2CM2		0x32
+#define RST_I2CM3		0x33
+#define RST_PMC			0x3d
+#define RST_CARD_CTL0	        0x3e
+#define RST_CARD_CTL1	        0x3f
+
+#define RST_CARD_CTL4	        0x42
+#define RST_BCH			0x44
+#define RST_DDFCH		0x4b
+#define RST_CSIIW0		0x4c
+#define RST_CSIIW1		0x4d
+#define RST_MIPICSI0	        0x4e
+#define RST_MIPICSI1	        0x4f
+
+#define RST_HDMI_TX		0x50
+#define RST_VPOST		0x55
+
+#define RST_TGEN		0x60
+#define RST_DMIX		0x61
+#define RST_TCON		0x6a
+#define RST_INTERRUPT	        0x6f
+
+#define RST_RGST		0x70
+#define RST_GPIO		0x73
+#define RST_RBUS_TOP	        0x74
+
+#define RST_MAILBOX		0x86
+#define RST_SPIND		0x8a
+#define RST_I2C2CBUS	        0x8b
+#define RST_SEC			0x8d
+#define RST_DVE			0x8e
+#define RST_GPOST0		0x8f
+
+#define RST_OSD0		0x90
+#define RST_DISP_PWM	        0x92
+#define RST_UADBG		0x93
+#define RST_DUMMY_MASTER	0x94
+#define RST_FIO_CTL		0x95
+#define RST_FPGA		0x96
+#define RST_L2SW		0x97
+#define RST_ICM			0x98
+#define RST_AXI_GLOBAL	        0x99
+
+#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] 58+ messages in thread

* [PATCH v12 3/9] reset: Add Sunplus SP7021 reset driver
  2022-03-31  8:29 ` Qin Jian
@ 2022-03-31  8:29   ` Qin Jian
  -1 siblings, 0 replies; 58+ messages in thread
From: Qin Jian @ 2022-03-31  8:29 UTC (permalink / raw)
  To: krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, Qin Jian

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 | 130 ++++++++++++++++++++++++++++++++++
 4 files changed, 141 insertions(+)
 create mode 100644 drivers/reset/reset-sunplus.c

diff --git a/MAINTAINERS b/MAINTAINERS
index a8be86b25..26066f199 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2745,6 +2745,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/sp-sp7021.h
 
 ARM/Synaptics SoC support
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 6f8ba0ddc..36825787e 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 hold 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 bd0a97be1..cadc46d3e 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..113b36b57
--- /dev/null
+++ b/drivers/reset/reset-sunplus.c
@@ -0,0 +1,130 @@
+// 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
+
+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 = id / BITS_PER_HWM_REG;
+	int shift = 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 = id / BITS_PER_HWM_REG;
+	int shift = 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] 58+ messages in thread

* [PATCH v12 3/9] reset: Add Sunplus SP7021 reset driver
@ 2022-03-31  8:29   ` Qin Jian
  0 siblings, 0 replies; 58+ messages in thread
From: Qin Jian @ 2022-03-31  8:29 UTC (permalink / raw)
  To: krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, Qin Jian

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 | 130 ++++++++++++++++++++++++++++++++++
 4 files changed, 141 insertions(+)
 create mode 100644 drivers/reset/reset-sunplus.c

diff --git a/MAINTAINERS b/MAINTAINERS
index a8be86b25..26066f199 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2745,6 +2745,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/sp-sp7021.h
 
 ARM/Synaptics SoC support
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 6f8ba0ddc..36825787e 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 hold 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 bd0a97be1..cadc46d3e 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..113b36b57
--- /dev/null
+++ b/drivers/reset/reset-sunplus.c
@@ -0,0 +1,130 @@
+// 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
+
+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 = id / BITS_PER_HWM_REG;
+	int shift = 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 = id / BITS_PER_HWM_REG;
+	int shift = 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] 58+ messages in thread

* [PATCH v12 4/9] dt-bindings: clock: Add bindings for SP7021 clock driver
  2022-03-31  8:29 ` Qin Jian
@ 2022-03-31  8:29   ` Qin Jian
  -1 siblings, 0 replies; 58+ messages in thread
From: Qin Jian @ 2022-03-31  8:29 UTC (permalink / raw)
  To: krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, Qin Jian

Add documentation to describe Sunplus SP7021 clock driver bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
Move 'reg' after 'compatible'
---
 .../bindings/clock/sunplus,sp7021-clkc.yaml   |  39 ++++++
 MAINTAINERS                                   |   2 +
 include/dt-bindings/clock/sp-sp7021.h         | 112 ++++++++++++++++++
 3 files changed, 153 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
 create mode 100644 include/dt-bindings/clock/sp-sp7021.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..41e73a088
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
@@ -0,0 +1,39 @@
+# 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 Binding
+
+maintainers:
+  - Qin Jian <qinjian@cqplus1.com>
+
+properties:
+  compatible:
+    const: sunplus,sp7021-clkc
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+
+    clkc: clock-controller@9c000000 {
+      compatible = "sunplus,sp7021-clkc";
+      reg = <0x9c000000 0x280>;
+      #clock-cells = <1>;
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 26066f199..5d8b420d0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2744,8 +2744,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/sp-sp7021.h
 F:	include/dt-bindings/reset/sp-sp7021.h
 
 ARM/Synaptics SoC support
diff --git a/include/dt-bindings/clock/sp-sp7021.h b/include/dt-bindings/clock/sp-sp7021.h
new file mode 100644
index 000000000..45dac6de8
--- /dev/null
+++ b/include/dt-bindings/clock/sp-sp7021.h
@@ -0,0 +1,112 @@
+/* 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
+
+#define XTAL			27000000
+
+/* plls */
+#define PLL_A			0
+#define PLL_E			1
+#define PLL_E_2P5		2
+#define PLL_E_25		3
+#define PLL_E_112P5		4
+#define PLL_F			5
+#define PLL_TV			6
+#define PLL_TV_A		7
+#define PLL_SYS			8
+
+/* gates: mo_clken0 ~ mo_clken9 */
+#define CLK_SYSTEM		0x10
+#define CLK_RTC			0x12
+#define CLK_IOCTL		0x13
+#define CLK_IOP			0x14
+#define CLK_OTPRX		0x15
+#define CLK_NOC			0x16
+#define CLK_BR			0x17
+#define CLK_RBUS_L00	        0x18
+#define CLK_SPIFL		0x19
+#define CLK_SDCTRL0		0x1a
+#define CLK_PERI0		0x1b
+#define CLK_A926		0x1d
+#define CLK_UMCTL2		0x1e
+#define CLK_PERI1		0x1f
+
+#define CLK_DDR_PHY0	        0x20
+#define CLK_ACHIP		0x22
+#define CLK_STC0		0x24
+#define CLK_STC_AV0		0x25
+#define CLK_STC_AV1		0x26
+#define CLK_STC_AV2		0x27
+#define CLK_UA0			0x28
+#define CLK_UA1			0x29
+#define CLK_UA2			0x2a
+#define CLK_UA3			0x2b
+#define CLK_UA4			0x2c
+#define CLK_HWUA		0x2d
+#define CLK_DDC0		0x2e
+#define CLK_UADMA		0x2f
+
+#define CLK_CBDMA0		0x30
+#define CLK_CBDMA1		0x31
+#define CLK_SPI_COMBO_0	        0x32
+#define CLK_SPI_COMBO_1	        0x33
+#define CLK_SPI_COMBO_2	        0x34
+#define CLK_SPI_COMBO_3	        0x35
+#define CLK_AUD			0x36
+#define CLK_USBC0		0x3a
+#define CLK_USBC1		0x3b
+#define CLK_UPHY0		0x3d
+#define CLK_UPHY1		0x3e
+
+#define CLK_I2CM0		0x40
+#define CLK_I2CM1		0x41
+#define CLK_I2CM2		0x42
+#define CLK_I2CM3		0x43
+#define CLK_PMC			0x4d
+#define CLK_CARD_CTL0	        0x4e
+#define CLK_CARD_CTL1	        0x4f
+
+#define CLK_CARD_CTL4	        0x52
+#define CLK_BCH			0x54
+#define CLK_DDFCH		0x5b
+#define CLK_CSIIW0		0x5c
+#define CLK_CSIIW1		0x5d
+#define CLK_MIPICSI0	        0x5e
+#define CLK_MIPICSI1	        0x5f
+
+#define CLK_HDMI_TX		0x60
+#define CLK_VPOST		0x65
+
+#define CLK_TGEN		0x70
+#define CLK_DMIX		0x71
+#define CLK_TCON		0x7a
+#define CLK_INTERRUPT	        0x7f
+
+#define CLK_RGST		0x80
+#define CLK_GPIO		0x83
+#define CLK_RBUS_TOP	        0x84
+
+#define CLK_MAILBOX		0x96
+#define CLK_SPIND		0x9a
+#define CLK_I2C2CBUS	        0x9b
+#define CLK_SEC			0x9d
+#define CLK_DVE			0x9e
+#define CLK_GPOST0		0x9f
+
+#define CLK_OSD0		0xa0
+#define CLK_DISP_PWM	        0xa2
+#define CLK_UADBG		0xa3
+#define CLK_DUMMY_MASTER	0xa4
+#define CLK_FIO_CTL		0xa5
+#define CLK_FPGA		0xa6
+#define CLK_L2SW		0xa7
+#define CLK_ICM			0xa8
+#define CLK_AXI_GLOBAL	        0xa9
+
+#define CLK_MAX			0xb0
+
+#endif
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v12 4/9] dt-bindings: clock: Add bindings for SP7021 clock driver
@ 2022-03-31  8:29   ` Qin Jian
  0 siblings, 0 replies; 58+ messages in thread
From: Qin Jian @ 2022-03-31  8:29 UTC (permalink / raw)
  To: krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, Qin Jian

Add documentation to describe Sunplus SP7021 clock driver bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
Move 'reg' after 'compatible'
---
 .../bindings/clock/sunplus,sp7021-clkc.yaml   |  39 ++++++
 MAINTAINERS                                   |   2 +
 include/dt-bindings/clock/sp-sp7021.h         | 112 ++++++++++++++++++
 3 files changed, 153 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
 create mode 100644 include/dt-bindings/clock/sp-sp7021.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..41e73a088
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
@@ -0,0 +1,39 @@
+# 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 Binding
+
+maintainers:
+  - Qin Jian <qinjian@cqplus1.com>
+
+properties:
+  compatible:
+    const: sunplus,sp7021-clkc
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+
+    clkc: clock-controller@9c000000 {
+      compatible = "sunplus,sp7021-clkc";
+      reg = <0x9c000000 0x280>;
+      #clock-cells = <1>;
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 26066f199..5d8b420d0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2744,8 +2744,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/sp-sp7021.h
 F:	include/dt-bindings/reset/sp-sp7021.h
 
 ARM/Synaptics SoC support
diff --git a/include/dt-bindings/clock/sp-sp7021.h b/include/dt-bindings/clock/sp-sp7021.h
new file mode 100644
index 000000000..45dac6de8
--- /dev/null
+++ b/include/dt-bindings/clock/sp-sp7021.h
@@ -0,0 +1,112 @@
+/* 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
+
+#define XTAL			27000000
+
+/* plls */
+#define PLL_A			0
+#define PLL_E			1
+#define PLL_E_2P5		2
+#define PLL_E_25		3
+#define PLL_E_112P5		4
+#define PLL_F			5
+#define PLL_TV			6
+#define PLL_TV_A		7
+#define PLL_SYS			8
+
+/* gates: mo_clken0 ~ mo_clken9 */
+#define CLK_SYSTEM		0x10
+#define CLK_RTC			0x12
+#define CLK_IOCTL		0x13
+#define CLK_IOP			0x14
+#define CLK_OTPRX		0x15
+#define CLK_NOC			0x16
+#define CLK_BR			0x17
+#define CLK_RBUS_L00	        0x18
+#define CLK_SPIFL		0x19
+#define CLK_SDCTRL0		0x1a
+#define CLK_PERI0		0x1b
+#define CLK_A926		0x1d
+#define CLK_UMCTL2		0x1e
+#define CLK_PERI1		0x1f
+
+#define CLK_DDR_PHY0	        0x20
+#define CLK_ACHIP		0x22
+#define CLK_STC0		0x24
+#define CLK_STC_AV0		0x25
+#define CLK_STC_AV1		0x26
+#define CLK_STC_AV2		0x27
+#define CLK_UA0			0x28
+#define CLK_UA1			0x29
+#define CLK_UA2			0x2a
+#define CLK_UA3			0x2b
+#define CLK_UA4			0x2c
+#define CLK_HWUA		0x2d
+#define CLK_DDC0		0x2e
+#define CLK_UADMA		0x2f
+
+#define CLK_CBDMA0		0x30
+#define CLK_CBDMA1		0x31
+#define CLK_SPI_COMBO_0	        0x32
+#define CLK_SPI_COMBO_1	        0x33
+#define CLK_SPI_COMBO_2	        0x34
+#define CLK_SPI_COMBO_3	        0x35
+#define CLK_AUD			0x36
+#define CLK_USBC0		0x3a
+#define CLK_USBC1		0x3b
+#define CLK_UPHY0		0x3d
+#define CLK_UPHY1		0x3e
+
+#define CLK_I2CM0		0x40
+#define CLK_I2CM1		0x41
+#define CLK_I2CM2		0x42
+#define CLK_I2CM3		0x43
+#define CLK_PMC			0x4d
+#define CLK_CARD_CTL0	        0x4e
+#define CLK_CARD_CTL1	        0x4f
+
+#define CLK_CARD_CTL4	        0x52
+#define CLK_BCH			0x54
+#define CLK_DDFCH		0x5b
+#define CLK_CSIIW0		0x5c
+#define CLK_CSIIW1		0x5d
+#define CLK_MIPICSI0	        0x5e
+#define CLK_MIPICSI1	        0x5f
+
+#define CLK_HDMI_TX		0x60
+#define CLK_VPOST		0x65
+
+#define CLK_TGEN		0x70
+#define CLK_DMIX		0x71
+#define CLK_TCON		0x7a
+#define CLK_INTERRUPT	        0x7f
+
+#define CLK_RGST		0x80
+#define CLK_GPIO		0x83
+#define CLK_RBUS_TOP	        0x84
+
+#define CLK_MAILBOX		0x96
+#define CLK_SPIND		0x9a
+#define CLK_I2C2CBUS	        0x9b
+#define CLK_SEC			0x9d
+#define CLK_DVE			0x9e
+#define CLK_GPOST0		0x9f
+
+#define CLK_OSD0		0xa0
+#define CLK_DISP_PWM	        0xa2
+#define CLK_UADBG		0xa3
+#define CLK_DUMMY_MASTER	0xa4
+#define CLK_FIO_CTL		0xa5
+#define CLK_FPGA		0xa6
+#define CLK_L2SW		0xa7
+#define CLK_ICM			0xa8
+#define CLK_AXI_GLOBAL	        0xa9
+
+#define CLK_MAX			0xb0
+
+#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] 58+ messages in thread

* [PATCH v12 5/9] clk: Add Sunplus SP7021 clock driver
  2022-03-31  8:29 ` Qin Jian
@ 2022-03-31  8:29   ` Qin Jian
  -1 siblings, 0 replies; 58+ messages in thread
From: Qin Jian @ 2022-03-31  8:29 UTC (permalink / raw)
  To: krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	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>
---
 MAINTAINERS              |   1 +
 drivers/clk/Kconfig      |  10 +
 drivers/clk/Makefile     |   1 +
 drivers/clk/clk-sp7021.c | 736 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 748 insertions(+)
 create mode 100644 drivers/clk/clk-sp7021.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 5d8b420d0..8b77f7ae4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2746,6 +2746,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/sp-sp7021.h
 F:	include/dt-bindings/reset/sp-sp7021.h
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index d4d67fbae..9eedeea78 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -351,6 +351,16 @@ config COMMON_CLK_VC5
 	  This driver supports the IDT VersaClock 5 and VersaClock 6
 	  programmable clock generators.
 
+config COMMON_CLK_SP7021
+	bool "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.
+
 config COMMON_CLK_STM32MP157
 	def_bool COMMON_CLK && MACH_STM32MP157
 	help
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 16e588630..377ea7f7b 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -61,6 +61,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..4331a9dde
--- /dev/null
+++ b/drivers/clk/clk-sp7021.c
@@ -0,0 +1,736 @@
+// 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/of_address.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/sp-sp7021.h>
+
+#define REG(i)		(pll_regs + (i) * 4)
+
+#define PLLA_CTL	REG(7)
+#define PLLE_CTL	REG(12)
+#define PLLF_CTL	REG(13)
+#define PLLTV_CTL	REG(14)
+#define PLLSYS_CTL	REG(26)
+
+/* 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)
+
+#define clk_regs	(sp_clk_base + 0x000) /* G0 ~ CLKEN */
+#define pll_regs	(sp_clk_base + 0x200) /* G4 ~ PLL */
+static void __iomem *sp_clk_base;
+static struct clk_hw_onecell_data *sp_clk_data;
+
+#define F_EXTCLK	BIT(16)	/* parent clock is EXTCLK */
+
+static const u32 sp_clk_gates[] = {
+	CLK_RTC,
+	CLK_OTPRX,
+	CLK_NOC,
+	CLK_BR,
+	CLK_SPIFL,
+	CLK_PERI0	| F_EXTCLK,
+	CLK_PERI1	| F_EXTCLK,
+
+	CLK_STC0,
+	CLK_STC_AV0,
+	CLK_STC_AV1,
+	CLK_STC_AV2,
+	CLK_UA0		| F_EXTCLK,
+	CLK_UA1		| F_EXTCLK,
+	CLK_UA2		| F_EXTCLK,
+	CLK_UA3		| F_EXTCLK,
+	CLK_UA4		| F_EXTCLK,
+	CLK_HWUA	| F_EXTCLK,
+	CLK_DDC0,
+	CLK_UADMA	| F_EXTCLK,
+
+	CLK_CBDMA0,
+	CLK_CBDMA1,
+	CLK_SPI_COMBO_0,
+	CLK_SPI_COMBO_1,
+	CLK_SPI_COMBO_2,
+	CLK_SPI_COMBO_3,
+	CLK_AUD,
+	CLK_USBC0,
+	CLK_USBC1,
+	CLK_UPHY0,
+	CLK_UPHY1,
+
+	CLK_I2CM0,
+	CLK_I2CM1,
+	CLK_I2CM2,
+	CLK_I2CM3,
+	CLK_PMC,
+	CLK_CARD_CTL0,
+	CLK_CARD_CTL1,
+
+	CLK_CARD_CTL4,
+	CLK_BCH,
+	CLK_DDFCH,
+	CLK_CSIIW0,
+	CLK_CSIIW1,
+	CLK_MIPICSI0,
+	CLK_MIPICSI1,
+
+	CLK_HDMI_TX,
+	CLK_VPOST,
+
+	CLK_TGEN,
+	CLK_DMIX,
+	CLK_TCON,
+
+	CLK_GPIO,
+
+	CLK_MAILBOX,
+	CLK_SPIND,
+	CLK_I2C2CBUS,
+	CLK_SEC,
+	CLK_GPOST0,
+	CLK_DVE,
+
+	CLK_OSD0,
+	CLK_DISP_PWM,
+	CLK_UADBG,
+	CLK_DUMMY_MASTER,
+	CLK_FIO_CTL,
+	CLK_FPGA,
+	CLK_L2SW,
+	CLK_ICM,
+	CLK_AXI_GLOBAL,
+};
+
+static DEFINE_SPINLOCK(plla_lock);
+static DEFINE_SPINLOCK(plle_lock);
+static DEFINE_SPINLOCK(pllf_lock);
+static DEFINE_SPINLOCK(pllsys_lock);
+static DEFINE_SPINLOCK(plltv_lock);
+
+#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, 0 means end */
+	static const u32 m_table[] = {
+		1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 0
+	};
+	u32 m, n, r;
+	unsigned long fvco, nf;
+
+	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_table[m]; m++) {
+		nf = fvco * m_table[m];
+		n = nf / F_27M;
+		if ((n * F_27M) == nf)
+			break;
+	}
+	m = m_table[m];
+
+	if (!m) {
+		pr_err("%s: %s freq:%lu not found a valid setting\n",
+		       __func__, clk_hw_get_name(&clk->hw), freq);
+		return -EINVAL;
+	}
+
+	/* save parameters */
+	clk->p[SEL_FRA] = 0;
+	clk->p[DIVR]    = r;
+	clk->p[DIVN]    = n;
+	clk->p[DIVM]    = m;
+
+	return freq;
+}
+
+/* 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 mods[] = { 91, 55 }; /* SDM_MOD mod values */
+
+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 1/0 */
+	for (ph = 1; ph >= 0; ph--) {
+		const u32 *pp = pt[ph];
+		u32 ms = 1;
+
+		/* SDM_MOD 0/1 */
+		for (sdm = 0; sdm <= 1; sdm++) {
+			u32 mod = mods[sdm];
+
+			/* DIVM 1~32 */
+			for (m = ms; 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)
+					df = (f * (nint + pp[2]) / pp[0]) -
+					     (f * (mod - nfra) / mod / pp[4]);
+				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 void plltv_set_rate(struct sp_pll *clk)
+{
+	u32 reg;
+
+	reg  = HWM_FIELD_PREP(MASK_SEL_FRA, clk->p[SEL_FRA]);
+	reg |= HWM_FIELD_PREP(MASK_SDM_MOD, clk->p[SDM_MOD]);
+	reg |= HWM_FIELD_PREP(MASK_PH_SEL, clk->p[PH_SEL]);
+	reg |= HWM_FIELD_PREP(MASK_NFRA, clk->p[NFRA]);
+	writel(reg, clk->reg);
+
+	reg  = HWM_FIELD_PREP(MASK_DIVR, clk->p[DIVR]);
+	writel(reg, clk->reg + 4);
+
+	reg  = HWM_FIELD_PREP(MASK_DIVN, clk->p[DIVN] - 1);
+	reg |= HWM_FIELD_PREP(MASK_DIVM, clk->p[DIVM] - 1);
+	writel(reg, clk->reg + 8);
+}
+
+/*********************************** 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 void plla_set_rate(struct sp_pll *clk)
+{
+	const u32 *pp = pa[clk->p[0]].regs;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pa->regs); i++)
+		writel(0xffff0000 | pp[i], clk->reg + (i * 4));
+}
+
+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 & BIT(1)) { /* 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];
+
+			ret = prate >> r;
+			ret = (ret * (pp[1] + pp[2]) / pp[0]) -
+				  (ret * (mods[sdm] - nfra) / mods[sdm] / pp[4]);
+			ret /= 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;
+
+	spin_lock_irqsave(clk->lock, flags);
+
+	reg = BIT(clk->bp_bit + 16); /* HIWORD_MASK */
+
+	if (rate == prate) {
+		reg |= BIT(clk->bp_bit); /* bypass */
+	} else if (clk->div_width == DIV_A) {
+		plla_set_rate(clk);
+	} else if (clk->div_width == DIV_TV) {
+		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) | (((fbdiv - 1) << clk->div_shift) & mask);
+	}
+
+	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);
+	unsigned long flags;
+
+	spin_lock_irqsave(clk->lock, flags);
+	writel(BIT(clk->pd_bit + 16) | BIT(clk->pd_bit), clk->reg); /* power up */
+	spin_unlock_irqrestore(clk->lock, flags);
+
+	return 0;
+}
+
+static void sp_pll_disable(struct clk_hw *hw)
+{
+	struct sp_pll *clk = to_sp_pll(hw);
+	unsigned long flags;
+
+	spin_lock_irqsave(clk->lock, flags);
+	writel(BIT(clk->pd_bit + 16), clk->reg); /* power down */
+	spin_unlock_irqrestore(clk->lock, flags);
+}
+
+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 void dbg_clk(struct clk_hw *hw)
+{
+	const char *name = clk_hw_get_name(hw);
+	unsigned long rate = clk_hw_get_rate(hw);
+
+	pr_debug("%-20s%lu\n", name, rate);
+}
+
+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,
+			       spinlock_t *lock)
+{
+	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,
+		/* system clock, should not be disabled */
+		.flags = (reg == PLLSYS_CTL) ? CLK_IS_CRITICAL : 0,
+	};
+	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;
+	pll->lock = lock;
+
+	hw = &pll->hw;
+	ret = devm_clk_hw_register(dev, hw);
+	if (ret) {
+		kfree(pll);
+		return ERR_PTR(ret);
+	}
+	dbg_clk(hw);
+
+	return hw;
+}
+
+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;
+	struct clk_hw **hws;
+	struct resource *res;
+	int i;
+
+	/* This memory region include multi HW regs in discontinuous order.
+	 * clk driver used some discontinuous areas in the memory region.
+	 * Using devm_platform_ioremap_resource() would conflicted with other drivers.
+	 */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	sp_clk_base = devm_ioremap(dev, res->start, resource_size(res));
+	if (!sp_clk_base)
+		return -ENXIO;
+
+	/* enable default clks */
+	for (i = 0; i < ARRAY_SIZE(sp_clken); i++)
+		writel((sp_clken[i] << 16) | sp_clken[i], sp_clk_base + 4 * (1 + i));
+
+	sp_clk_data = devm_kzalloc(dev, struct_size(sp_clk_data, hws, CLK_MAX),
+				   GFP_KERNEL);
+	if (!sp_clk_data)
+		return -ENOMEM;
+
+	hws = sp_clk_data->hws;
+	pd_ext.fw_name = "extclk";
+
+	/* PLL_A */
+	hws[PLL_A] = sp_pll_register(dev, "plla", &pd_ext, PLLA_CTL,
+				     11, 12, 27000000, 0, DIV_A, &plla_lock);
+	if (IS_ERR(hws[PLL_A]))
+		return PTR_ERR(hws[PLL_A]);
+
+	/* PLL_E */
+	hws[PLL_E] = sp_pll_register(dev, "plle", &pd_ext, PLLE_CTL,
+				     6, 2, 50000000, 0, 0, &plle_lock);
+	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, &plle_lock);
+	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, &plle_lock);
+	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, &plle_lock);
+	if (IS_ERR(hws[PLL_E_112P5]))
+		return PTR_ERR(hws[PLL_E_112P5]);
+
+	/* PLL_F */
+	hws[PLL_F] = sp_pll_register(dev, "pllf", &pd_ext, PLLF_CTL,
+				     0, 10, 13500000, 1, 4, &pllf_lock);
+	if (IS_ERR(hws[PLL_F]))
+		return PTR_ERR(hws[PLL_F]);
+
+	/* PLL_TV */
+	hws[PLL_TV] = sp_pll_register(dev, "plltv", &pd_ext, PLLTV_CTL,
+				      0, 15, 27000000, 0, DIV_TV, &plltv_lock);
+	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,
+						     &plltv_lock);
+	if (IS_ERR(hws[PLL_TV_A]))
+		return PTR_ERR(hws[PLL_TV_A]);
+	dbg_clk(hws[PLL_TV_A]);
+
+	/* PLL_SYS */
+	hws[PLL_SYS] = sp_pll_register(dev, "pllsys", &pd_ext, PLLSYS_CTL,
+				       10, 9, 13500000, 0, 4, &pllsys_lock);
+	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++) {
+		u32 f = sp_clk_gates[i];
+		int j = f & 0xffff;
+		struct clk_parent_data *pd = (f & F_EXTCLK) ? &pd_ext : &pd_sys;
+		char s[10];
+
+		sprintf(s, "clken%02x", j);
+		hws[j] = clk_hw_register_gate_parent_data(dev, s, pd, 0,
+							  clk_regs + (j >> 4) * 4,
+							  j & 0x0f,
+							  CLK_GATE_HIWORD_MASK,
+							  NULL);
+		if (IS_ERR(hws[j]))
+			return PTR_ERR(hws[j]);
+		dbg_clk(hws[j]);
+	}
+
+	sp_clk_data->num = CLK_MAX;
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, sp_clk_data);
+}
+
+static const struct of_device_id sp7021_clk_dt_ids[] = {
+	{ .compatible = "sunplus,sp7021-clkc", },
+	{ }
+};
+
+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 v2");
+MODULE_DESCRIPTION("Clock driver for Sunplus SP7021 SoC");
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v12 5/9] clk: Add Sunplus SP7021 clock driver
@ 2022-03-31  8:29   ` Qin Jian
  0 siblings, 0 replies; 58+ messages in thread
From: Qin Jian @ 2022-03-31  8:29 UTC (permalink / raw)
  To: krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	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>
---
 MAINTAINERS              |   1 +
 drivers/clk/Kconfig      |  10 +
 drivers/clk/Makefile     |   1 +
 drivers/clk/clk-sp7021.c | 736 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 748 insertions(+)
 create mode 100644 drivers/clk/clk-sp7021.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 5d8b420d0..8b77f7ae4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2746,6 +2746,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/sp-sp7021.h
 F:	include/dt-bindings/reset/sp-sp7021.h
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index d4d67fbae..9eedeea78 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -351,6 +351,16 @@ config COMMON_CLK_VC5
 	  This driver supports the IDT VersaClock 5 and VersaClock 6
 	  programmable clock generators.
 
+config COMMON_CLK_SP7021
+	bool "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.
+
 config COMMON_CLK_STM32MP157
 	def_bool COMMON_CLK && MACH_STM32MP157
 	help
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 16e588630..377ea7f7b 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -61,6 +61,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..4331a9dde
--- /dev/null
+++ b/drivers/clk/clk-sp7021.c
@@ -0,0 +1,736 @@
+// 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/of_address.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/sp-sp7021.h>
+
+#define REG(i)		(pll_regs + (i) * 4)
+
+#define PLLA_CTL	REG(7)
+#define PLLE_CTL	REG(12)
+#define PLLF_CTL	REG(13)
+#define PLLTV_CTL	REG(14)
+#define PLLSYS_CTL	REG(26)
+
+/* 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)
+
+#define clk_regs	(sp_clk_base + 0x000) /* G0 ~ CLKEN */
+#define pll_regs	(sp_clk_base + 0x200) /* G4 ~ PLL */
+static void __iomem *sp_clk_base;
+static struct clk_hw_onecell_data *sp_clk_data;
+
+#define F_EXTCLK	BIT(16)	/* parent clock is EXTCLK */
+
+static const u32 sp_clk_gates[] = {
+	CLK_RTC,
+	CLK_OTPRX,
+	CLK_NOC,
+	CLK_BR,
+	CLK_SPIFL,
+	CLK_PERI0	| F_EXTCLK,
+	CLK_PERI1	| F_EXTCLK,
+
+	CLK_STC0,
+	CLK_STC_AV0,
+	CLK_STC_AV1,
+	CLK_STC_AV2,
+	CLK_UA0		| F_EXTCLK,
+	CLK_UA1		| F_EXTCLK,
+	CLK_UA2		| F_EXTCLK,
+	CLK_UA3		| F_EXTCLK,
+	CLK_UA4		| F_EXTCLK,
+	CLK_HWUA	| F_EXTCLK,
+	CLK_DDC0,
+	CLK_UADMA	| F_EXTCLK,
+
+	CLK_CBDMA0,
+	CLK_CBDMA1,
+	CLK_SPI_COMBO_0,
+	CLK_SPI_COMBO_1,
+	CLK_SPI_COMBO_2,
+	CLK_SPI_COMBO_3,
+	CLK_AUD,
+	CLK_USBC0,
+	CLK_USBC1,
+	CLK_UPHY0,
+	CLK_UPHY1,
+
+	CLK_I2CM0,
+	CLK_I2CM1,
+	CLK_I2CM2,
+	CLK_I2CM3,
+	CLK_PMC,
+	CLK_CARD_CTL0,
+	CLK_CARD_CTL1,
+
+	CLK_CARD_CTL4,
+	CLK_BCH,
+	CLK_DDFCH,
+	CLK_CSIIW0,
+	CLK_CSIIW1,
+	CLK_MIPICSI0,
+	CLK_MIPICSI1,
+
+	CLK_HDMI_TX,
+	CLK_VPOST,
+
+	CLK_TGEN,
+	CLK_DMIX,
+	CLK_TCON,
+
+	CLK_GPIO,
+
+	CLK_MAILBOX,
+	CLK_SPIND,
+	CLK_I2C2CBUS,
+	CLK_SEC,
+	CLK_GPOST0,
+	CLK_DVE,
+
+	CLK_OSD0,
+	CLK_DISP_PWM,
+	CLK_UADBG,
+	CLK_DUMMY_MASTER,
+	CLK_FIO_CTL,
+	CLK_FPGA,
+	CLK_L2SW,
+	CLK_ICM,
+	CLK_AXI_GLOBAL,
+};
+
+static DEFINE_SPINLOCK(plla_lock);
+static DEFINE_SPINLOCK(plle_lock);
+static DEFINE_SPINLOCK(pllf_lock);
+static DEFINE_SPINLOCK(pllsys_lock);
+static DEFINE_SPINLOCK(plltv_lock);
+
+#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, 0 means end */
+	static const u32 m_table[] = {
+		1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 0
+	};
+	u32 m, n, r;
+	unsigned long fvco, nf;
+
+	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_table[m]; m++) {
+		nf = fvco * m_table[m];
+		n = nf / F_27M;
+		if ((n * F_27M) == nf)
+			break;
+	}
+	m = m_table[m];
+
+	if (!m) {
+		pr_err("%s: %s freq:%lu not found a valid setting\n",
+		       __func__, clk_hw_get_name(&clk->hw), freq);
+		return -EINVAL;
+	}
+
+	/* save parameters */
+	clk->p[SEL_FRA] = 0;
+	clk->p[DIVR]    = r;
+	clk->p[DIVN]    = n;
+	clk->p[DIVM]    = m;
+
+	return freq;
+}
+
+/* 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 mods[] = { 91, 55 }; /* SDM_MOD mod values */
+
+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 1/0 */
+	for (ph = 1; ph >= 0; ph--) {
+		const u32 *pp = pt[ph];
+		u32 ms = 1;
+
+		/* SDM_MOD 0/1 */
+		for (sdm = 0; sdm <= 1; sdm++) {
+			u32 mod = mods[sdm];
+
+			/* DIVM 1~32 */
+			for (m = ms; 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)
+					df = (f * (nint + pp[2]) / pp[0]) -
+					     (f * (mod - nfra) / mod / pp[4]);
+				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 void plltv_set_rate(struct sp_pll *clk)
+{
+	u32 reg;
+
+	reg  = HWM_FIELD_PREP(MASK_SEL_FRA, clk->p[SEL_FRA]);
+	reg |= HWM_FIELD_PREP(MASK_SDM_MOD, clk->p[SDM_MOD]);
+	reg |= HWM_FIELD_PREP(MASK_PH_SEL, clk->p[PH_SEL]);
+	reg |= HWM_FIELD_PREP(MASK_NFRA, clk->p[NFRA]);
+	writel(reg, clk->reg);
+
+	reg  = HWM_FIELD_PREP(MASK_DIVR, clk->p[DIVR]);
+	writel(reg, clk->reg + 4);
+
+	reg  = HWM_FIELD_PREP(MASK_DIVN, clk->p[DIVN] - 1);
+	reg |= HWM_FIELD_PREP(MASK_DIVM, clk->p[DIVM] - 1);
+	writel(reg, clk->reg + 8);
+}
+
+/*********************************** 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 void plla_set_rate(struct sp_pll *clk)
+{
+	const u32 *pp = pa[clk->p[0]].regs;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pa->regs); i++)
+		writel(0xffff0000 | pp[i], clk->reg + (i * 4));
+}
+
+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 & BIT(1)) { /* 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];
+
+			ret = prate >> r;
+			ret = (ret * (pp[1] + pp[2]) / pp[0]) -
+				  (ret * (mods[sdm] - nfra) / mods[sdm] / pp[4]);
+			ret /= 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;
+
+	spin_lock_irqsave(clk->lock, flags);
+
+	reg = BIT(clk->bp_bit + 16); /* HIWORD_MASK */
+
+	if (rate == prate) {
+		reg |= BIT(clk->bp_bit); /* bypass */
+	} else if (clk->div_width == DIV_A) {
+		plla_set_rate(clk);
+	} else if (clk->div_width == DIV_TV) {
+		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) | (((fbdiv - 1) << clk->div_shift) & mask);
+	}
+
+	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);
+	unsigned long flags;
+
+	spin_lock_irqsave(clk->lock, flags);
+	writel(BIT(clk->pd_bit + 16) | BIT(clk->pd_bit), clk->reg); /* power up */
+	spin_unlock_irqrestore(clk->lock, flags);
+
+	return 0;
+}
+
+static void sp_pll_disable(struct clk_hw *hw)
+{
+	struct sp_pll *clk = to_sp_pll(hw);
+	unsigned long flags;
+
+	spin_lock_irqsave(clk->lock, flags);
+	writel(BIT(clk->pd_bit + 16), clk->reg); /* power down */
+	spin_unlock_irqrestore(clk->lock, flags);
+}
+
+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 void dbg_clk(struct clk_hw *hw)
+{
+	const char *name = clk_hw_get_name(hw);
+	unsigned long rate = clk_hw_get_rate(hw);
+
+	pr_debug("%-20s%lu\n", name, rate);
+}
+
+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,
+			       spinlock_t *lock)
+{
+	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,
+		/* system clock, should not be disabled */
+		.flags = (reg == PLLSYS_CTL) ? CLK_IS_CRITICAL : 0,
+	};
+	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;
+	pll->lock = lock;
+
+	hw = &pll->hw;
+	ret = devm_clk_hw_register(dev, hw);
+	if (ret) {
+		kfree(pll);
+		return ERR_PTR(ret);
+	}
+	dbg_clk(hw);
+
+	return hw;
+}
+
+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;
+	struct clk_hw **hws;
+	struct resource *res;
+	int i;
+
+	/* This memory region include multi HW regs in discontinuous order.
+	 * clk driver used some discontinuous areas in the memory region.
+	 * Using devm_platform_ioremap_resource() would conflicted with other drivers.
+	 */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	sp_clk_base = devm_ioremap(dev, res->start, resource_size(res));
+	if (!sp_clk_base)
+		return -ENXIO;
+
+	/* enable default clks */
+	for (i = 0; i < ARRAY_SIZE(sp_clken); i++)
+		writel((sp_clken[i] << 16) | sp_clken[i], sp_clk_base + 4 * (1 + i));
+
+	sp_clk_data = devm_kzalloc(dev, struct_size(sp_clk_data, hws, CLK_MAX),
+				   GFP_KERNEL);
+	if (!sp_clk_data)
+		return -ENOMEM;
+
+	hws = sp_clk_data->hws;
+	pd_ext.fw_name = "extclk";
+
+	/* PLL_A */
+	hws[PLL_A] = sp_pll_register(dev, "plla", &pd_ext, PLLA_CTL,
+				     11, 12, 27000000, 0, DIV_A, &plla_lock);
+	if (IS_ERR(hws[PLL_A]))
+		return PTR_ERR(hws[PLL_A]);
+
+	/* PLL_E */
+	hws[PLL_E] = sp_pll_register(dev, "plle", &pd_ext, PLLE_CTL,
+				     6, 2, 50000000, 0, 0, &plle_lock);
+	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, &plle_lock);
+	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, &plle_lock);
+	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, &plle_lock);
+	if (IS_ERR(hws[PLL_E_112P5]))
+		return PTR_ERR(hws[PLL_E_112P5]);
+
+	/* PLL_F */
+	hws[PLL_F] = sp_pll_register(dev, "pllf", &pd_ext, PLLF_CTL,
+				     0, 10, 13500000, 1, 4, &pllf_lock);
+	if (IS_ERR(hws[PLL_F]))
+		return PTR_ERR(hws[PLL_F]);
+
+	/* PLL_TV */
+	hws[PLL_TV] = sp_pll_register(dev, "plltv", &pd_ext, PLLTV_CTL,
+				      0, 15, 27000000, 0, DIV_TV, &plltv_lock);
+	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,
+						     &plltv_lock);
+	if (IS_ERR(hws[PLL_TV_A]))
+		return PTR_ERR(hws[PLL_TV_A]);
+	dbg_clk(hws[PLL_TV_A]);
+
+	/* PLL_SYS */
+	hws[PLL_SYS] = sp_pll_register(dev, "pllsys", &pd_ext, PLLSYS_CTL,
+				       10, 9, 13500000, 0, 4, &pllsys_lock);
+	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++) {
+		u32 f = sp_clk_gates[i];
+		int j = f & 0xffff;
+		struct clk_parent_data *pd = (f & F_EXTCLK) ? &pd_ext : &pd_sys;
+		char s[10];
+
+		sprintf(s, "clken%02x", j);
+		hws[j] = clk_hw_register_gate_parent_data(dev, s, pd, 0,
+							  clk_regs + (j >> 4) * 4,
+							  j & 0x0f,
+							  CLK_GATE_HIWORD_MASK,
+							  NULL);
+		if (IS_ERR(hws[j]))
+			return PTR_ERR(hws[j]);
+		dbg_clk(hws[j]);
+	}
+
+	sp_clk_data->num = CLK_MAX;
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, sp_clk_data);
+}
+
+static const struct of_device_id sp7021_clk_dt_ids[] = {
+	{ .compatible = "sunplus,sp7021-clkc", },
+	{ }
+};
+
+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 v2");
+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] 58+ messages in thread

* [PATCH v12 6/9] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
  2022-03-31  8:29 ` Qin Jian
@ 2022-03-31  8:29   ` Qin Jian
  -1 siblings, 0 replies; 58+ messages in thread
From: Qin Jian @ 2022-03-31  8:29 UTC (permalink / raw)
  To: krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, Qin Jian

Add documentation to describe Sunplus SP7021 interrupt controller bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
Move 'reg' after 'compatible'
---
 .../sunplus,sp7021-intc.yaml                  | 62 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 63 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..f26d8b213
--- /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 Device Tree Bindings
+
+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 8b77f7ae4..9fba67159 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2745,6 +2745,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/clock/sunplus,sp7021-clkc.yaml
+F:	Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
 F:	Documentation/devicetree/bindings/reset/sunplus,reset.yaml
 F:	drivers/clk/clk-sp7021.c
 F:	drivers/reset/reset-sunplus.c
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v12 6/9] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
@ 2022-03-31  8:29   ` Qin Jian
  0 siblings, 0 replies; 58+ messages in thread
From: Qin Jian @ 2022-03-31  8:29 UTC (permalink / raw)
  To: krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, Qin Jian

Add documentation to describe Sunplus SP7021 interrupt controller bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
Move 'reg' after 'compatible'
---
 .../sunplus,sp7021-intc.yaml                  | 62 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 63 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..f26d8b213
--- /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 Device Tree Bindings
+
+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 8b77f7ae4..9fba67159 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2745,6 +2745,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/clock/sunplus,sp7021-clkc.yaml
+F:	Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
 F:	Documentation/devicetree/bindings/reset/sunplus,reset.yaml
 F:	drivers/clk/clk-sp7021.c
 F:	drivers/reset/reset-sunplus.c
-- 
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] 58+ messages in thread

* [PATCH v12 7/9] irqchip: Add Sunplus SP7021 interrupt controller driver
  2022-03-31  8:29 ` Qin Jian
@ 2022-03-31  8:29   ` Qin Jian
  -1 siblings, 0 replies; 58+ messages in thread
From: Qin Jian @ 2022-03-31  8:29 UTC (permalink / raw)
  To: krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, Qin Jian

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.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 MAINTAINERS                       |   1 +
 drivers/irqchip/Kconfig           |   9 +
 drivers/irqchip/Makefile          |   2 +
 drivers/irqchip/irq-sp7021-intc.c | 288 ++++++++++++++++++++++++++++++
 4 files changed, 300 insertions(+)
 create mode 100644 drivers/irqchip/irq-sp7021-intc.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 9fba67159..cf6873295 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2748,6 +2748,7 @@ 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:	drivers/clk/clk-sp7021.c
+F:	drivers/irqchip/irq-sp7021-intc.c
 F:	drivers/reset/reset-sunplus.c
 F:	include/dt-bindings/clock/sp-sp7021.h
 F:	include/dt-bindings/reset/sp-sp7021.h
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 7038957f4..f5c2596bc 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -617,4 +617,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 c1f611cbf..eb0ac83ff 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -117,3 +117,5 @@ 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..d1821a955
--- /dev/null
+++ b/drivers/irqchip/irq-sp7021-intc.c
@@ -0,0 +1,288 @@
+// 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 = (int)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);
+}
+
+#ifdef CONFIG_SMP
+static int sp_intc_set_affinity(struct irq_data *d, const struct cpumask *mask, bool force)
+{
+	return -EINVAL;
+}
+#endif
+
+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,
+#ifdef CONFIG_SMP
+	.irq_set_affinity = sp_intc_set_affinity,
+#endif
+};
+
+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 *)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] 58+ messages in thread

* [PATCH v12 7/9] irqchip: Add Sunplus SP7021 interrupt controller driver
@ 2022-03-31  8:29   ` Qin Jian
  0 siblings, 0 replies; 58+ messages in thread
From: Qin Jian @ 2022-03-31  8:29 UTC (permalink / raw)
  To: krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, Qin Jian

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.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 MAINTAINERS                       |   1 +
 drivers/irqchip/Kconfig           |   9 +
 drivers/irqchip/Makefile          |   2 +
 drivers/irqchip/irq-sp7021-intc.c | 288 ++++++++++++++++++++++++++++++
 4 files changed, 300 insertions(+)
 create mode 100644 drivers/irqchip/irq-sp7021-intc.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 9fba67159..cf6873295 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2748,6 +2748,7 @@ 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:	drivers/clk/clk-sp7021.c
+F:	drivers/irqchip/irq-sp7021-intc.c
 F:	drivers/reset/reset-sunplus.c
 F:	include/dt-bindings/clock/sp-sp7021.h
 F:	include/dt-bindings/reset/sp-sp7021.h
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 7038957f4..f5c2596bc 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -617,4 +617,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 c1f611cbf..eb0ac83ff 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -117,3 +117,5 @@ 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..d1821a955
--- /dev/null
+++ b/drivers/irqchip/irq-sp7021-intc.c
@@ -0,0 +1,288 @@
+// 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 = (int)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);
+}
+
+#ifdef CONFIG_SMP
+static int sp_intc_set_affinity(struct irq_data *d, const struct cpumask *mask, bool force)
+{
+	return -EINVAL;
+}
+#endif
+
+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,
+#ifdef CONFIG_SMP
+	.irq_set_affinity = sp_intc_set_affinity,
+#endif
+};
+
+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 *)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] 58+ messages in thread

* [PATCH v12 8/9] ARM: sunplus: Add initial support for Sunplus SP7021 SoC
  2022-03-31  8:29 ` Qin Jian
@ 2022-03-31  8:29   ` Qin Jian
  -1 siblings, 0 replies; 58+ messages in thread
From: Qin Jian @ 2022-03-31  8:29 UTC (permalink / raw)
  To: krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, Qin Jian

This patch aims to add an initial support for Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 MAINTAINERS                    |  1 +
 arch/arm/Kconfig               |  2 ++
 arch/arm/Makefile              |  1 +
 arch/arm/mach-sunplus/Kconfig  | 26 ++++++++++++++++++++++++++
 arch/arm/mach-sunplus/Makefile |  9 +++++++++
 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 cf6873295..38890c055 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2747,6 +2747,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 4c97cb40e..1ee9a27a3 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -693,6 +693,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 77172d555..1e19d2f4b 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -216,6 +216,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..e720606dd
--- /dev/null
+++ b/arch/arm/mach-sunplus/Kconfig
@@ -0,0 +1,26 @@
+# 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 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 (ex: I2C, SPI, SDIO,
+	  Ethernet and 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..c902580a7
--- /dev/null
+++ b/arch/arm/mach-sunplus/Makefile
@@ -0,0 +1,9 @@
+# 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] 58+ messages in thread

* [PATCH v12 8/9] ARM: sunplus: Add initial support for Sunplus SP7021 SoC
@ 2022-03-31  8:29   ` Qin Jian
  0 siblings, 0 replies; 58+ messages in thread
From: Qin Jian @ 2022-03-31  8:29 UTC (permalink / raw)
  To: krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, Qin Jian

This patch aims to add an initial support for Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 MAINTAINERS                    |  1 +
 arch/arm/Kconfig               |  2 ++
 arch/arm/Makefile              |  1 +
 arch/arm/mach-sunplus/Kconfig  | 26 ++++++++++++++++++++++++++
 arch/arm/mach-sunplus/Makefile |  9 +++++++++
 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 cf6873295..38890c055 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2747,6 +2747,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 4c97cb40e..1ee9a27a3 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -693,6 +693,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 77172d555..1e19d2f4b 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -216,6 +216,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..e720606dd
--- /dev/null
+++ b/arch/arm/mach-sunplus/Kconfig
@@ -0,0 +1,26 @@
+# 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 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 (ex: I2C, SPI, SDIO,
+	  Ethernet and 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..c902580a7
--- /dev/null
+++ b/arch/arm/mach-sunplus/Makefile
@@ -0,0 +1,9 @@
+# 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] 58+ messages in thread

* [PATCH v12 9/9] ARM: sp7021_defconfig: Add Sunplus SP7021 defconfig
  2022-03-31  8:29 ` Qin Jian
@ 2022-03-31  8:29   ` Qin Jian
  -1 siblings, 0 replies; 58+ messages in thread
From: Qin Jian @ 2022-03-31  8:29 UTC (permalink / raw)
  To: krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, Qin Jian

Add generic Sunplus SP7021 based board defconfig

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 MAINTAINERS                         |  1 +
 arch/arm/configs/multi_v7_defconfig |  1 +
 arch/arm/configs/sp7021_defconfig   | 61 +++++++++++++++++++++++++++++
 3 files changed, 63 insertions(+)
 create mode 100644 arch/arm/configs/sp7021_defconfig

diff --git a/MAINTAINERS b/MAINTAINERS
index 38890c055..93f4de6c1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2747,6 +2747,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 8863fa969..a3bd9dbd8 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -86,6 +86,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..cda16d33a
--- /dev/null
+++ b/arch/arm/configs/sp7021_defconfig
@@ -0,0 +1,61 @@
+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_HAVE_ARM_ARCH_TIMER=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_STAGING=y
+# 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] 58+ messages in thread

* [PATCH v12 9/9] ARM: sp7021_defconfig: Add Sunplus SP7021 defconfig
@ 2022-03-31  8:29   ` Qin Jian
  0 siblings, 0 replies; 58+ messages in thread
From: Qin Jian @ 2022-03-31  8:29 UTC (permalink / raw)
  To: krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, Qin Jian

Add generic Sunplus SP7021 based board defconfig

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 MAINTAINERS                         |  1 +
 arch/arm/configs/multi_v7_defconfig |  1 +
 arch/arm/configs/sp7021_defconfig   | 61 +++++++++++++++++++++++++++++
 3 files changed, 63 insertions(+)
 create mode 100644 arch/arm/configs/sp7021_defconfig

diff --git a/MAINTAINERS b/MAINTAINERS
index 38890c055..93f4de6c1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2747,6 +2747,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 8863fa969..a3bd9dbd8 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -86,6 +86,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..cda16d33a
--- /dev/null
+++ b/arch/arm/configs/sp7021_defconfig
@@ -0,0 +1,61 @@
+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_HAVE_ARM_ARCH_TIMER=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_STAGING=y
+# 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] 58+ messages in thread

* Re: [PATCH v12 2/9] dt-bindings: reset: Add bindings for SP7021 reset driver
  2022-03-31  8:29   ` Qin Jian
@ 2022-03-31  8:58     ` Arnd Bergmann
  -1 siblings, 0 replies; 58+ messages in thread
From: Arnd Bergmann @ 2022-03-31  8:58 UTC (permalink / raw)
  To: Qin Jian
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Arnd Bergmann, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

On Thu, Mar 31, 2022 at 10:29 AM Qin Jian <qinjian@cqplus1.com> wrote:

> +/* mo_reset0 ~ mo_reset9 */
> +#define RST_SYSTEM             0x00
> +#define RST_RTC                        0x02
> +#define RST_IOCTL              0x03
> +#define RST_IOP                        0x04
> +#define RST_OTPRX              0x05
> +#define RST_NOC                        0x06
> +#define RST_BR                 0x07
> +#define RST_RBUS_L00           0x08
> +#define RST_SPIFL              0x09
> +#define RST_SDCTRL0            0x0a
> +#define RST_PERI0              0x0b
> +#define RST_A926               0x0d
> +#define RST_UMCTL2             0x0e
> +#define RST_PERI1              0x0f
> +
> +#define RST_DDR_PHY0           0x10
> +#define RST_ACHIP              0x12
> +#define RST_STC0               0x14
> +#define RST_STC_AV0            0x15
> +#define RST_STC_AV1            0x16
> +#define RST_STC_AV2            0x17

The list looks like these definitions just match the hardware, which means you
don't have to define them as a binding at all, just use the hardware numbers
directly in the dt, as you do for interrupts or gpio numbers.

If the hardware does not have a sane way of mapping reset lines to a particular
hardware number, then you may have to define a binding, but in that case just
use consecutive integer numbers, not hexadecimal numbers.

       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] 58+ messages in thread

* Re: [PATCH v12 2/9] dt-bindings: reset: Add bindings for SP7021 reset driver
@ 2022-03-31  8:58     ` Arnd Bergmann
  0 siblings, 0 replies; 58+ messages in thread
From: Arnd Bergmann @ 2022-03-31  8:58 UTC (permalink / raw)
  To: Qin Jian
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Arnd Bergmann, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

On Thu, Mar 31, 2022 at 10:29 AM Qin Jian <qinjian@cqplus1.com> wrote:

> +/* mo_reset0 ~ mo_reset9 */
> +#define RST_SYSTEM             0x00
> +#define RST_RTC                        0x02
> +#define RST_IOCTL              0x03
> +#define RST_IOP                        0x04
> +#define RST_OTPRX              0x05
> +#define RST_NOC                        0x06
> +#define RST_BR                 0x07
> +#define RST_RBUS_L00           0x08
> +#define RST_SPIFL              0x09
> +#define RST_SDCTRL0            0x0a
> +#define RST_PERI0              0x0b
> +#define RST_A926               0x0d
> +#define RST_UMCTL2             0x0e
> +#define RST_PERI1              0x0f
> +
> +#define RST_DDR_PHY0           0x10
> +#define RST_ACHIP              0x12
> +#define RST_STC0               0x14
> +#define RST_STC_AV0            0x15
> +#define RST_STC_AV1            0x16
> +#define RST_STC_AV2            0x17

The list looks like these definitions just match the hardware, which means you
don't have to define them as a binding at all, just use the hardware numbers
directly in the dt, as you do for interrupts or gpio numbers.

If the hardware does not have a sane way of mapping reset lines to a particular
hardware number, then you may have to define a binding, but in that case just
use consecutive integer numbers, not hexadecimal numbers.

       Arnd

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v12 3/9] reset: Add Sunplus SP7021 reset driver
  2022-03-31  8:29   ` Qin Jian
@ 2022-03-31  8:59     ` Arnd Bergmann
  -1 siblings, 0 replies; 58+ messages in thread
From: Arnd Bergmann @ 2022-03-31  8:59 UTC (permalink / raw)
  To: Qin Jian
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Arnd Bergmann, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

On Thu, Mar 31, 2022 at 10:29 AM Qin Jian <qinjian@cqplus1.com> wrote:
> +
> +#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>
> +

As commented on the binding header -- it looks again like you are not actually
relying  on the header here, so it's almost certainly not needed.

         Arnd

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v12 3/9] reset: Add Sunplus SP7021 reset driver
@ 2022-03-31  8:59     ` Arnd Bergmann
  0 siblings, 0 replies; 58+ messages in thread
From: Arnd Bergmann @ 2022-03-31  8:59 UTC (permalink / raw)
  To: Qin Jian
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Arnd Bergmann, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

On Thu, Mar 31, 2022 at 10:29 AM Qin Jian <qinjian@cqplus1.com> wrote:
> +
> +#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>
> +

As commented on the binding header -- it looks again like you are not actually
relying  on the header here, so it's almost certainly not needed.

         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] 58+ messages in thread

* Re: [PATCH v12 8/9] ARM: sunplus: Add initial support for Sunplus SP7021 SoC
  2022-03-31  8:29   ` Qin Jian
@ 2022-03-31  9:03     ` Arnd Bergmann
  -1 siblings, 0 replies; 58+ messages in thread
From: Arnd Bergmann @ 2022-03-31  9:03 UTC (permalink / raw)
  To: Qin Jian
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Arnd Bergmann, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

On Thu, Mar 31, 2022 at 10:29 AM Qin Jian <qinjian@cqplus1.com> wrote:
>
> This patch aims to add an initial support for Sunplus SP7021 SoC.
>
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>


Reviewed-by: Arnd Bergmann <arnd@arndb.de>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v12 8/9] ARM: sunplus: Add initial support for Sunplus SP7021 SoC
@ 2022-03-31  9:03     ` Arnd Bergmann
  0 siblings, 0 replies; 58+ messages in thread
From: Arnd Bergmann @ 2022-03-31  9:03 UTC (permalink / raw)
  To: Qin Jian
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Arnd Bergmann, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

On Thu, Mar 31, 2022 at 10:29 AM Qin Jian <qinjian@cqplus1.com> wrote:
>
> This patch aims to add an initial support for Sunplus SP7021 SoC.
>
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>


Reviewed-by: Arnd Bergmann <arnd@arndb.de>

_______________________________________________
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] 58+ messages in thread

* Re: [PATCH v12 9/9] ARM: sp7021_defconfig: Add Sunplus SP7021 defconfig
  2022-03-31  8:29   ` Qin Jian
@ 2022-03-31  9:09     ` Arnd Bergmann
  -1 siblings, 0 replies; 58+ messages in thread
From: Arnd Bergmann @ 2022-03-31  9:09 UTC (permalink / raw)
  To: Qin Jian
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Arnd Bergmann, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

On Thu, Mar 31, 2022 at 10:29 AM Qin Jian <qinjian@cqplus1.com> wrote:
> Add generic Sunplus SP7021 based board defconfig

Here, you should explain why you need a custom defconfig for this SoC, as
most platforms are fine just using the generic one. Are you too memory
constrained,
or are there other problems?

> diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
> index 8863fa969..a3bd9dbd8 100644
> --- a/arch/arm/configs/multi_v7_defconfig
> +++ b/arch/arm/configs/multi_v7_defconfig
> @@ -86,6 +86,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

Don't you need any drivers here?

> diff --git a/arch/arm/configs/sp7021_defconfig b/arch/arm/configs/sp7021_defconfig
> new file mode 100644
> index 000000000..cda16d33a
> --- /dev/null
> +++ b/arch/arm/configs/sp7021_defconfig
...
> +CONFIG_HAVE_ARM_ARCH_TIMER=y

I checked this one again, as most others don't enable it in the defconfig.

I don't remember if I recommended removing the 'select' from Kconfig
in a previous round, but as that is where other platforms have it, I'd add
it there as well.

> +CONFIG_STAGING=y

Do you actually enable any staging drivers here? If not, I'd drop that bit.

          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] 58+ messages in thread

* Re: [PATCH v12 9/9] ARM: sp7021_defconfig: Add Sunplus SP7021 defconfig
@ 2022-03-31  9:09     ` Arnd Bergmann
  0 siblings, 0 replies; 58+ messages in thread
From: Arnd Bergmann @ 2022-03-31  9:09 UTC (permalink / raw)
  To: Qin Jian
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Arnd Bergmann, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

On Thu, Mar 31, 2022 at 10:29 AM Qin Jian <qinjian@cqplus1.com> wrote:
> Add generic Sunplus SP7021 based board defconfig

Here, you should explain why you need a custom defconfig for this SoC, as
most platforms are fine just using the generic one. Are you too memory
constrained,
or are there other problems?

> diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
> index 8863fa969..a3bd9dbd8 100644
> --- a/arch/arm/configs/multi_v7_defconfig
> +++ b/arch/arm/configs/multi_v7_defconfig
> @@ -86,6 +86,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

Don't you need any drivers here?

> diff --git a/arch/arm/configs/sp7021_defconfig b/arch/arm/configs/sp7021_defconfig
> new file mode 100644
> index 000000000..cda16d33a
> --- /dev/null
> +++ b/arch/arm/configs/sp7021_defconfig
...
> +CONFIG_HAVE_ARM_ARCH_TIMER=y

I checked this one again, as most others don't enable it in the defconfig.

I don't remember if I recommended removing the 'select' from Kconfig
in a previous round, but as that is where other platforms have it, I'd add
it there as well.

> +CONFIG_STAGING=y

Do you actually enable any staging drivers here? If not, I'd drop that bit.

          Arnd

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v12 7/9] irqchip: Add Sunplus SP7021 interrupt controller driver
  2022-03-31  8:29   ` Qin Jian
@ 2022-03-31  9:17     ` Arnd Bergmann
  -1 siblings, 0 replies; 58+ messages in thread
From: Arnd Bergmann @ 2022-03-31  9:17 UTC (permalink / raw)
  To: Qin Jian
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Arnd Bergmann, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

On Thu, Mar 31, 2022 at 10:29 AM Qin Jian <qinjian@cqplus1.com> wrote:

> +#ifdef CONFIG_SMP
> +static int sp_intc_set_affinity(struct irq_data *d, const struct cpumask *mask, bool force)
> +{
> +       return -EINVAL;
> +}
> +#endif
> +
> +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,
> +#ifdef CONFIG_SMP
> +       .irq_set_affinity = sp_intc_set_affinity,
> +#endif
> +};

I don't think you need to define an irq_set_affinity() callback at all if you
just return -EINVAL, all the callers should have a check already. Even
if you do need the function, I think you can remove the #ifdef, as long
as the function itself can be built that way.

      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] 58+ messages in thread

* Re: [PATCH v12 7/9] irqchip: Add Sunplus SP7021 interrupt controller driver
@ 2022-03-31  9:17     ` Arnd Bergmann
  0 siblings, 0 replies; 58+ messages in thread
From: Arnd Bergmann @ 2022-03-31  9:17 UTC (permalink / raw)
  To: Qin Jian
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Arnd Bergmann, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

On Thu, Mar 31, 2022 at 10:29 AM Qin Jian <qinjian@cqplus1.com> wrote:

> +#ifdef CONFIG_SMP
> +static int sp_intc_set_affinity(struct irq_data *d, const struct cpumask *mask, bool force)
> +{
> +       return -EINVAL;
> +}
> +#endif
> +
> +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,
> +#ifdef CONFIG_SMP
> +       .irq_set_affinity = sp_intc_set_affinity,
> +#endif
> +};

I don't think you need to define an irq_set_affinity() callback at all if you
just return -EINVAL, all the callers should have a check already. Even
if you do need the function, I think you can remove the #ifdef, as long
as the function itself can be built that way.

      Arnd

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v12 5/9] clk: Add Sunplus SP7021 clock driver
  2022-03-31  8:29   ` Qin Jian
@ 2022-03-31  9:22     ` Arnd Bergmann
  -1 siblings, 0 replies; 58+ messages in thread
From: Arnd Bergmann @ 2022-03-31  9:22 UTC (permalink / raw)
  To: Qin Jian
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Arnd Bergmann, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

On Thu, Mar 31, 2022 at 10:29 AM Qin Jian <qinjian@cqplus1.com> wrote:

> +static int sp_pll_enable(struct clk_hw *hw)
> +{
> +       struct sp_pll *clk = to_sp_pll(hw);
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(clk->lock, flags);
> +       writel(BIT(clk->pd_bit + 16) | BIT(clk->pd_bit), clk->reg); /* power up */
> +       spin_unlock_irqrestore(clk->lock, flags);
> +
> +       return 0;
> +}
> +
> +static void sp_pll_disable(struct clk_hw *hw)
> +{
> +       struct sp_pll *clk = to_sp_pll(hw);
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(clk->lock, flags);
> +       writel(BIT(clk->pd_bit + 16), clk->reg); /* power down */
> +       spin_unlock_irqrestore(clk->lock, flags);
> +}

What does the spinlock actually protect here? As writel() is posted, it
can already leak of of the lock, and the inputs would appear to be
constant.

> +       /* This memory region include multi HW regs in discontinuous order.
> +        * clk driver used some discontinuous areas in the memory region.
> +        * Using devm_platform_ioremap_resource() would conflicted with other drivers.
> +        */
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       sp_clk_base = devm_ioremap(dev, res->start, resource_size(res));
> +       if (!sp_clk_base)
> +               return -ENXIO;

Can you explain this comment in more detail? Generally, the 'reg' properties
of drivers should not overlap, so it is supposed to be safe to call
devm_platform_ioremap_resource() here.

We discussed this in the context of the iop driver that did have overlapping
registers with this driver, and that was incorrect. Are there any other drivers
that conflict with the clk driver?

      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] 58+ messages in thread

* Re: [PATCH v12 5/9] clk: Add Sunplus SP7021 clock driver
@ 2022-03-31  9:22     ` Arnd Bergmann
  0 siblings, 0 replies; 58+ messages in thread
From: Arnd Bergmann @ 2022-03-31  9:22 UTC (permalink / raw)
  To: Qin Jian
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Arnd Bergmann, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

On Thu, Mar 31, 2022 at 10:29 AM Qin Jian <qinjian@cqplus1.com> wrote:

> +static int sp_pll_enable(struct clk_hw *hw)
> +{
> +       struct sp_pll *clk = to_sp_pll(hw);
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(clk->lock, flags);
> +       writel(BIT(clk->pd_bit + 16) | BIT(clk->pd_bit), clk->reg); /* power up */
> +       spin_unlock_irqrestore(clk->lock, flags);
> +
> +       return 0;
> +}
> +
> +static void sp_pll_disable(struct clk_hw *hw)
> +{
> +       struct sp_pll *clk = to_sp_pll(hw);
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(clk->lock, flags);
> +       writel(BIT(clk->pd_bit + 16), clk->reg); /* power down */
> +       spin_unlock_irqrestore(clk->lock, flags);
> +}

What does the spinlock actually protect here? As writel() is posted, it
can already leak of of the lock, and the inputs would appear to be
constant.

> +       /* This memory region include multi HW regs in discontinuous order.
> +        * clk driver used some discontinuous areas in the memory region.
> +        * Using devm_platform_ioremap_resource() would conflicted with other drivers.
> +        */
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       sp_clk_base = devm_ioremap(dev, res->start, resource_size(res));
> +       if (!sp_clk_base)
> +               return -ENXIO;

Can you explain this comment in more detail? Generally, the 'reg' properties
of drivers should not overlap, so it is supposed to be safe to call
devm_platform_ioremap_resource() here.

We discussed this in the context of the iop driver that did have overlapping
registers with this driver, and that was incorrect. Are there any other drivers
that conflict with the clk driver?

      Arnd

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v12 4/9] dt-bindings: clock: Add bindings for SP7021 clock driver
  2022-03-31  8:29   ` Qin Jian
@ 2022-03-31 20:21     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 58+ messages in thread
From: Krzysztof Kozlowski @ 2022-03-31 20:21 UTC (permalink / raw)
  To: Qin Jian, krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk

On 31/03/2022 10:29, Qin Jian wrote:
> Add documentation to describe Sunplus SP7021 clock driver bindings.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
> Move 'reg' after 'compatible'
> ---
>  .../bindings/clock/sunplus,sp7021-clkc.yaml   |  39 ++++++
>  MAINTAINERS                                   |   2 +
>  include/dt-bindings/clock/sp-sp7021.h         | 112 ++++++++++++++++++
>  3 files changed, 153 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
>  create mode 100644 include/dt-bindings/clock/sp-sp7021.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..41e73a088
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
> @@ -0,0 +1,39 @@
> +# 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 Binding
> +
> +maintainers:
> +  - Qin Jian <qinjian@cqplus1.com>
> +
> +properties:
> +  compatible:
> +    const: sunplus,sp7021-clkc
> +
> +  reg:
> +    maxItems: 1
> +
> +  "#clock-cells":
> +    const: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - "#clock-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    clkc: clock-controller@9c000000 {
> +      compatible = "sunplus,sp7021-clkc";
> +      reg = <0x9c000000 0x280>;
> +      #clock-cells = <1>;
> +    };
> +
> +...
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 26066f199..5d8b420d0 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2744,8 +2744,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/sp-sp7021.h
>  F:	include/dt-bindings/reset/sp-sp7021.h
>  
>  ARM/Synaptics SoC support
> diff --git a/include/dt-bindings/clock/sp-sp7021.h b/include/dt-bindings/clock/sp-sp7021.h
> new file mode 100644
> index 000000000..45dac6de8
> --- /dev/null
> +++ b/include/dt-bindings/clock/sp-sp7021.h
> @@ -0,0 +1,112 @@
> +/* 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
> +
> +#define XTAL			27000000
> +
> +/* plls */
> +#define PLL_A			0
> +#define PLL_E			1
> +#define PLL_E_2P5		2
> +#define PLL_E_25		3
> +#define PLL_E_112P5		4
> +#define PLL_F			5
> +#define PLL_TV			6
> +#define PLL_TV_A		7
> +#define PLL_SYS			8
> +
> +/* gates: mo_clken0 ~ mo_clken9 */
> +#define CLK_SYSTEM		0x10
> +#define CLK_RTC			0x12

YAML looks ok, but here comment from Arnd also applies. These should be
regular decimal numbers incremented by one.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v12 4/9] dt-bindings: clock: Add bindings for SP7021 clock driver
@ 2022-03-31 20:21     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 58+ messages in thread
From: Krzysztof Kozlowski @ 2022-03-31 20:21 UTC (permalink / raw)
  To: Qin Jian, krzysztof.kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk

On 31/03/2022 10:29, Qin Jian wrote:
> Add documentation to describe Sunplus SP7021 clock driver bindings.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
> Move 'reg' after 'compatible'
> ---
>  .../bindings/clock/sunplus,sp7021-clkc.yaml   |  39 ++++++
>  MAINTAINERS                                   |   2 +
>  include/dt-bindings/clock/sp-sp7021.h         | 112 ++++++++++++++++++
>  3 files changed, 153 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
>  create mode 100644 include/dt-bindings/clock/sp-sp7021.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..41e73a088
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
> @@ -0,0 +1,39 @@
> +# 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 Binding
> +
> +maintainers:
> +  - Qin Jian <qinjian@cqplus1.com>
> +
> +properties:
> +  compatible:
> +    const: sunplus,sp7021-clkc
> +
> +  reg:
> +    maxItems: 1
> +
> +  "#clock-cells":
> +    const: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - "#clock-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    clkc: clock-controller@9c000000 {
> +      compatible = "sunplus,sp7021-clkc";
> +      reg = <0x9c000000 0x280>;
> +      #clock-cells = <1>;
> +    };
> +
> +...
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 26066f199..5d8b420d0 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2744,8 +2744,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/sp-sp7021.h
>  F:	include/dt-bindings/reset/sp-sp7021.h
>  
>  ARM/Synaptics SoC support
> diff --git a/include/dt-bindings/clock/sp-sp7021.h b/include/dt-bindings/clock/sp-sp7021.h
> new file mode 100644
> index 000000000..45dac6de8
> --- /dev/null
> +++ b/include/dt-bindings/clock/sp-sp7021.h
> @@ -0,0 +1,112 @@
> +/* 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
> +
> +#define XTAL			27000000
> +
> +/* plls */
> +#define PLL_A			0
> +#define PLL_E			1
> +#define PLL_E_2P5		2
> +#define PLL_E_25		3
> +#define PLL_E_112P5		4
> +#define PLL_F			5
> +#define PLL_TV			6
> +#define PLL_TV_A		7
> +#define PLL_SYS			8
> +
> +/* gates: mo_clken0 ~ mo_clken9 */
> +#define CLK_SYSTEM		0x10
> +#define CLK_RTC			0x12

YAML looks ok, but here comment from Arnd also applies. These should be
regular decimal numbers incremented by one.

Best regards,
Krzysztof

_______________________________________________
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] 58+ messages in thread

* Re: [PATCH v12 6/9] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
  2022-03-31  8:29   ` Qin Jian
@ 2022-03-31 20:44     ` Rob Herring
  -1 siblings, 0 replies; 58+ messages in thread
From: Rob Herring @ 2022-03-31 20:44 UTC (permalink / raw)
  To: Qin Jian
  Cc: arnd, linux-clk, p.zabel, maz, linux-kernel, mturquette, robh+dt,
	sboyd, linux, linux-arm-kernel, devicetree, krzysztof.kozlowski,
	tglx

On Thu, 31 Mar 2022 16:29:53 +0800, Qin Jian wrote:
> Add documentation to describe Sunplus SP7021 interrupt controller bindings.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
> Move 'reg' after 'compatible'
> ---
>  .../sunplus,sp7021-intc.yaml                  | 62 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  2 files changed, 63 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
> 


Please add Acked-by/Reviewed-by tags when posting new versions. However,
there's no need to repost patches *only* to add the tags. The upstream
maintainer will do that for acks received on the version they apply.

If a tag was not added on purpose, please state why and what changed.


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v12 6/9] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
@ 2022-03-31 20:44     ` Rob Herring
  0 siblings, 0 replies; 58+ messages in thread
From: Rob Herring @ 2022-03-31 20:44 UTC (permalink / raw)
  To: Qin Jian
  Cc: arnd, linux-clk, p.zabel, maz, linux-kernel, mturquette, robh+dt,
	sboyd, linux, linux-arm-kernel, devicetree, krzysztof.kozlowski,
	tglx

On Thu, 31 Mar 2022 16:29:53 +0800, Qin Jian wrote:
> Add documentation to describe Sunplus SP7021 interrupt controller bindings.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
> Move 'reg' after 'compatible'
> ---
>  .../sunplus,sp7021-intc.yaml                  | 62 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  2 files changed, 63 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
> 


Please add Acked-by/Reviewed-by tags when posting new versions. However,
there's no need to repost patches *only* to add the tags. The upstream
maintainer will do that for acks received on the version they apply.

If a tag was not added on purpose, please state why and what changed.


_______________________________________________
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] 58+ messages in thread

* RE: [PATCH v12 6/9] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
  2022-03-31 20:44     ` Rob Herring
@ 2022-04-01  2:29       ` qinjian[覃健]
  -1 siblings, 0 replies; 58+ messages in thread
From: qinjian[覃健] @ 2022-04-01  2:29 UTC (permalink / raw)
  To: Rob Herring
  Cc: arnd, linux-clk, p.zabel, maz, linux-kernel, mturquette, robh+dt,
	sboyd, linux, linux-arm-kernel, devicetree, krzysztof.kozlowski,
	tglx

> 
> On Thu, 31 Mar 2022 16:29:53 +0800, Qin Jian wrote:
> > Add documentation to describe Sunplus SP7021 interrupt controller bindings.
> >
> > Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> > ---
> > Move 'reg' after 'compatible'
> > ---
> >  .../sunplus,sp7021-intc.yaml                  | 62 +++++++++++++++++++
> >  MAINTAINERS                                   |  1 +
> >  2 files changed, 63 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
> >
> 
> 
> Please add Acked-by/Reviewed-by tags when posting new versions. However,
> there's no need to repost patches *only* to add the tags. The upstream
> maintainer will do that for acks received on the version they apply.
> 
> If a tag was not added on purpose, please state why and what changed.

Changes: Move 'reg' after 'compatible'
I did a modification based on comments from krzysztof.kozlowski@canonical.com [1]

[1] https://lore.kernel.org/all/6dbeda18-a11c-609d-7a8f-bf2e6f27aea7@kernel.org/


^ permalink raw reply	[flat|nested] 58+ messages in thread

* RE: [PATCH v12 6/9] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
@ 2022-04-01  2:29       ` qinjian[覃健]
  0 siblings, 0 replies; 58+ messages in thread
From: qinjian[覃健] @ 2022-04-01  2:29 UTC (permalink / raw)
  To: Rob Herring
  Cc: arnd, linux-clk, p.zabel, maz, linux-kernel, mturquette, robh+dt,
	sboyd, linux, linux-arm-kernel, devicetree, krzysztof.kozlowski,
	tglx

> 
> On Thu, 31 Mar 2022 16:29:53 +0800, Qin Jian wrote:
> > Add documentation to describe Sunplus SP7021 interrupt controller bindings.
> >
> > Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> > ---
> > Move 'reg' after 'compatible'
> > ---
> >  .../sunplus,sp7021-intc.yaml                  | 62 +++++++++++++++++++
> >  MAINTAINERS                                   |  1 +
> >  2 files changed, 63 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
> >
> 
> 
> Please add Acked-by/Reviewed-by tags when posting new versions. However,
> there's no need to repost patches *only* to add the tags. The upstream
> maintainer will do that for acks received on the version they apply.
> 
> If a tag was not added on purpose, please state why and what changed.

Changes: Move 'reg' after 'compatible'
I did a modification based on comments from krzysztof.kozlowski@canonical.com [1]

[1] https://lore.kernel.org/all/6dbeda18-a11c-609d-7a8f-bf2e6f27aea7@kernel.org/

_______________________________________________
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] 58+ messages in thread

* RE: [PATCH v12 9/9] ARM: sp7021_defconfig: Add Sunplus SP7021 defconfig
  2022-03-31  9:09     ` Arnd Bergmann
@ 2022-04-01  7:08       ` qinjian[覃健]
  -1 siblings, 0 replies; 58+ messages in thread
From: qinjian[覃健] @ 2022-04-01  7:08 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

> On Thu, Mar 31, 2022 at 10:29 AM Qin Jian <qinjian@cqplus1.com> wrote:
> > Add generic Sunplus SP7021 based board defconfig
> 
> Here, you should explain why you need a custom defconfig for this SoC, as
> most platforms are fine just using the generic one. Are you too memory
> constrained,
> or are there other problems?
> 

For memory constrained board only.

> > diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
> > index 8863fa969..a3bd9dbd8 100644
> > --- a/arch/arm/configs/multi_v7_defconfig
> > +++ b/arch/arm/configs/multi_v7_defconfig
> > @@ -86,6 +86,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
> 
> Don't you need any drivers here?
> 

Currently, all basic drivers auto enabled by mach-sunplus/Kconfig:
...
config SOC_SP7021
	bool "Sunplus SP7021 SoC support"
	depends on ARCH_SUNPLUS
	default ARCH_SUNPLUS
	select ARM_GIC
	select ARM_PSCI
	select PINCTRL
	select PINCTRL_SPPCTL
	select SERIAL_SUNPLUS
	select SERIAL_SUNPLUS_CONSOLE

and driver's Kconfig:
...
config RESET_SUNPLUS
        bool "Sunplus SoCs Reset Driver" if COMPILE_TEST
        default ARCH_SUNPLUS
...

> > diff --git a/arch/arm/configs/sp7021_defconfig b/arch/arm/configs/sp7021_defconfig
> > new file mode 100644
> > index 000000000..cda16d33a
> > --- /dev/null
> > +++ b/arch/arm/configs/sp7021_defconfig
> ...
> > +CONFIG_HAVE_ARM_ARCH_TIMER=y
> 
> I checked this one again, as most others don't enable it in the defconfig.
> 
> I don't remember if I recommended removing the 'select' from Kconfig
> in a previous round, but as that is where other platforms have it, I'd add
> it there as well.
> 

I'll move this to mach-sunplus/Kconfig.

> > +CONFIG_STAGING=y
> 
> Do you actually enable any staging drivers here? If not, I'd drop that bit.
> 

I’ll drop it.


Thanks all your comments.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* RE: [PATCH v12 9/9] ARM: sp7021_defconfig: Add Sunplus SP7021 defconfig
@ 2022-04-01  7:08       ` qinjian[覃健]
  0 siblings, 0 replies; 58+ messages in thread
From: qinjian[覃健] @ 2022-04-01  7:08 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

> On Thu, Mar 31, 2022 at 10:29 AM Qin Jian <qinjian@cqplus1.com> wrote:
> > Add generic Sunplus SP7021 based board defconfig
> 
> Here, you should explain why you need a custom defconfig for this SoC, as
> most platforms are fine just using the generic one. Are you too memory
> constrained,
> or are there other problems?
> 

For memory constrained board only.

> > diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
> > index 8863fa969..a3bd9dbd8 100644
> > --- a/arch/arm/configs/multi_v7_defconfig
> > +++ b/arch/arm/configs/multi_v7_defconfig
> > @@ -86,6 +86,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
> 
> Don't you need any drivers here?
> 

Currently, all basic drivers auto enabled by mach-sunplus/Kconfig:
...
config SOC_SP7021
	bool "Sunplus SP7021 SoC support"
	depends on ARCH_SUNPLUS
	default ARCH_SUNPLUS
	select ARM_GIC
	select ARM_PSCI
	select PINCTRL
	select PINCTRL_SPPCTL
	select SERIAL_SUNPLUS
	select SERIAL_SUNPLUS_CONSOLE

and driver's Kconfig:
...
config RESET_SUNPLUS
        bool "Sunplus SoCs Reset Driver" if COMPILE_TEST
        default ARCH_SUNPLUS
...

> > diff --git a/arch/arm/configs/sp7021_defconfig b/arch/arm/configs/sp7021_defconfig
> > new file mode 100644
> > index 000000000..cda16d33a
> > --- /dev/null
> > +++ b/arch/arm/configs/sp7021_defconfig
> ...
> > +CONFIG_HAVE_ARM_ARCH_TIMER=y
> 
> I checked this one again, as most others don't enable it in the defconfig.
> 
> I don't remember if I recommended removing the 'select' from Kconfig
> in a previous round, but as that is where other platforms have it, I'd add
> it there as well.
> 

I'll move this to mach-sunplus/Kconfig.

> > +CONFIG_STAGING=y
> 
> Do you actually enable any staging drivers here? If not, I'd drop that bit.
> 

I’ll drop it.


Thanks all your comments.
_______________________________________________
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] 58+ messages in thread

* RE: [PATCH v12 7/9] irqchip: Add Sunplus SP7021 interrupt controller driver
  2022-03-31  9:17     ` Arnd Bergmann
@ 2022-04-01  7:17       ` qinjian[覃健]
  -1 siblings, 0 replies; 58+ messages in thread
From: qinjian[覃健] @ 2022-04-01  7:17 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

> 
> On Thu, Mar 31, 2022 at 10:29 AM Qin Jian <qinjian@cqplus1.com> wrote:
> 
> > +#ifdef CONFIG_SMP
> > +static int sp_intc_set_affinity(struct irq_data *d, const struct cpumask *mask, bool force)
> > +{
> > +       return -EINVAL;
> > +}
> > +#endif
> > +
> > +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,
> > +#ifdef CONFIG_SMP
> > +       .irq_set_affinity = sp_intc_set_affinity,
> > +#endif
> > +};
> 
> I don't think you need to define an irq_set_affinity() callback at all if you
> just return -EINVAL, all the callers should have a check already. Even
> if you do need the function, I think you can remove the #ifdef, as long
> as the function itself can be built that way.
> 
>       Arnd

Thanks for your comments, I'll remove this empty function.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* RE: [PATCH v12 7/9] irqchip: Add Sunplus SP7021 interrupt controller driver
@ 2022-04-01  7:17       ` qinjian[覃健]
  0 siblings, 0 replies; 58+ messages in thread
From: qinjian[覃健] @ 2022-04-01  7:17 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

> 
> On Thu, Mar 31, 2022 at 10:29 AM Qin Jian <qinjian@cqplus1.com> wrote:
> 
> > +#ifdef CONFIG_SMP
> > +static int sp_intc_set_affinity(struct irq_data *d, const struct cpumask *mask, bool force)
> > +{
> > +       return -EINVAL;
> > +}
> > +#endif
> > +
> > +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,
> > +#ifdef CONFIG_SMP
> > +       .irq_set_affinity = sp_intc_set_affinity,
> > +#endif
> > +};
> 
> I don't think you need to define an irq_set_affinity() callback at all if you
> just return -EINVAL, all the callers should have a check already. Even
> if you do need the function, I think you can remove the #ifdef, as long
> as the function itself can be built that way.
> 
>       Arnd

Thanks for your comments, I'll remove this empty function.
_______________________________________________
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] 58+ messages in thread

* RE: [PATCH v12 2/9] dt-bindings: reset: Add bindings for SP7021 reset driver
  2022-03-31  8:58     ` Arnd Bergmann
@ 2022-04-01  8:24       ` qinjian[覃健]
  -1 siblings, 0 replies; 58+ messages in thread
From: qinjian[覃健] @ 2022-04-01  8:24 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

> 
> On Thu, Mar 31, 2022 at 10:29 AM Qin Jian <qinjian@cqplus1.com> wrote:
> 
> > +/* mo_reset0 ~ mo_reset9 */
> > +#define RST_SYSTEM             0x00
> > +#define RST_RTC                        0x02
> > +#define RST_IOCTL              0x03
> > +#define RST_IOP                        0x04
> > +#define RST_OTPRX              0x05
> > +#define RST_NOC                        0x06
> > +#define RST_BR                 0x07
> > +#define RST_RBUS_L00           0x08
> > +#define RST_SPIFL              0x09
> > +#define RST_SDCTRL0            0x0a
> > +#define RST_PERI0              0x0b
> > +#define RST_A926               0x0d
> > +#define RST_UMCTL2             0x0e
> > +#define RST_PERI1              0x0f
> > +
> > +#define RST_DDR_PHY0           0x10
> > +#define RST_ACHIP              0x12
> > +#define RST_STC0               0x14
> > +#define RST_STC_AV0            0x15
> > +#define RST_STC_AV1            0x16
> > +#define RST_STC_AV2            0x17
> 
> The list looks like these definitions just match the hardware, which means you
> don't have to define them as a binding at all, just use the hardware numbers
> directly in the dt, as you do for interrupts or gpio numbers.
> 
> If the hardware does not have a sane way of mapping reset lines to a particular
> hardware number, then you may have to define a binding, but in that case just
> use consecutive integer numbers, not hexadecimal numbers.
> 
>        Arnd

You are right, these definitions does match the hardware, In reset-sunplus.c:
static int sp_reset_status(struct reset_controller_dev *rcdev,
                           unsigned long id)
{
        struct sp_reset *reset = to_sp_reset(rcdev);
        int index = id / BITS_PER_HWM_REG;
        int shift = id % BITS_PER_HWM_REG;
        u32 reg;

        reg = readl(reset->base + (index * 4));

        return !!(reg & BIT(shift));
}
the 'id'  is these value passed from dt.

I'll remove this file & update dt, thanks for your comments.


^ permalink raw reply	[flat|nested] 58+ messages in thread

* RE: [PATCH v12 2/9] dt-bindings: reset: Add bindings for SP7021 reset driver
@ 2022-04-01  8:24       ` qinjian[覃健]
  0 siblings, 0 replies; 58+ messages in thread
From: qinjian[覃健] @ 2022-04-01  8:24 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

> 
> On Thu, Mar 31, 2022 at 10:29 AM Qin Jian <qinjian@cqplus1.com> wrote:
> 
> > +/* mo_reset0 ~ mo_reset9 */
> > +#define RST_SYSTEM             0x00
> > +#define RST_RTC                        0x02
> > +#define RST_IOCTL              0x03
> > +#define RST_IOP                        0x04
> > +#define RST_OTPRX              0x05
> > +#define RST_NOC                        0x06
> > +#define RST_BR                 0x07
> > +#define RST_RBUS_L00           0x08
> > +#define RST_SPIFL              0x09
> > +#define RST_SDCTRL0            0x0a
> > +#define RST_PERI0              0x0b
> > +#define RST_A926               0x0d
> > +#define RST_UMCTL2             0x0e
> > +#define RST_PERI1              0x0f
> > +
> > +#define RST_DDR_PHY0           0x10
> > +#define RST_ACHIP              0x12
> > +#define RST_STC0               0x14
> > +#define RST_STC_AV0            0x15
> > +#define RST_STC_AV1            0x16
> > +#define RST_STC_AV2            0x17
> 
> The list looks like these definitions just match the hardware, which means you
> don't have to define them as a binding at all, just use the hardware numbers
> directly in the dt, as you do for interrupts or gpio numbers.
> 
> If the hardware does not have a sane way of mapping reset lines to a particular
> hardware number, then you may have to define a binding, but in that case just
> use consecutive integer numbers, not hexadecimal numbers.
> 
>        Arnd

You are right, these definitions does match the hardware, In reset-sunplus.c:
static int sp_reset_status(struct reset_controller_dev *rcdev,
                           unsigned long id)
{
        struct sp_reset *reset = to_sp_reset(rcdev);
        int index = id / BITS_PER_HWM_REG;
        int shift = id % BITS_PER_HWM_REG;
        u32 reg;

        reg = readl(reset->base + (index * 4));

        return !!(reg & BIT(shift));
}
the 'id'  is these value passed from dt.

I'll remove this file & update dt, thanks for your comments.

_______________________________________________
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] 58+ messages in thread

* RE: [PATCH v12 4/9] dt-bindings: clock: Add bindings for SP7021 clock driver
  2022-03-31 20:21     ` Krzysztof Kozlowski
@ 2022-04-01  9:19       ` qinjian[覃健]
  -1 siblings, 0 replies; 58+ messages in thread
From: qinjian[覃健] @ 2022-04-01  9:19 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk

> > diff --git a/include/dt-bindings/clock/sp-sp7021.h b/include/dt-bindings/clock/sp-sp7021.h
> > new file mode 100644
> > index 000000000..45dac6de8
> > --- /dev/null
> > +++ b/include/dt-bindings/clock/sp-sp7021.h
> > @@ -0,0 +1,112 @@
> > +/* 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
> > +
> > +#define XTAL			27000000
> > +
> > +/* plls */
> > +#define PLL_A			0
> > +#define PLL_E			1
> > +#define PLL_E_2P5		2
> > +#define PLL_E_25		3
> > +#define PLL_E_112P5		4
> > +#define PLL_F			5
> > +#define PLL_TV			6
> > +#define PLL_TV_A		7
> > +#define PLL_SYS			8
> > +
> > +/* gates: mo_clken0 ~ mo_clken9 */
> > +#define CLK_SYSTEM		0x10
> > +#define CLK_RTC			0x12
> 
> YAML looks ok, but here comment from Arnd also applies. These should be
> regular decimal numbers incremented by one.
> 
> Best regards,
> Krzysztof

Yes, same as reset driver, these defines also mapping the hardware.
But different from reset driver, clk driver also used these defines.
If I removed this defines, I  must write the proper hardware number twice in dt & driver.
It's meaningless & hard to check.





^ permalink raw reply	[flat|nested] 58+ messages in thread

* RE: [PATCH v12 4/9] dt-bindings: clock: Add bindings for SP7021 clock driver
@ 2022-04-01  9:19       ` qinjian[覃健]
  0 siblings, 0 replies; 58+ messages in thread
From: qinjian[覃健] @ 2022-04-01  9:19 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk

> > diff --git a/include/dt-bindings/clock/sp-sp7021.h b/include/dt-bindings/clock/sp-sp7021.h
> > new file mode 100644
> > index 000000000..45dac6de8
> > --- /dev/null
> > +++ b/include/dt-bindings/clock/sp-sp7021.h
> > @@ -0,0 +1,112 @@
> > +/* 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
> > +
> > +#define XTAL			27000000
> > +
> > +/* plls */
> > +#define PLL_A			0
> > +#define PLL_E			1
> > +#define PLL_E_2P5		2
> > +#define PLL_E_25		3
> > +#define PLL_E_112P5		4
> > +#define PLL_F			5
> > +#define PLL_TV			6
> > +#define PLL_TV_A		7
> > +#define PLL_SYS			8
> > +
> > +/* gates: mo_clken0 ~ mo_clken9 */
> > +#define CLK_SYSTEM		0x10
> > +#define CLK_RTC			0x12
> 
> YAML looks ok, but here comment from Arnd also applies. These should be
> regular decimal numbers incremented by one.
> 
> Best regards,
> Krzysztof

Yes, same as reset driver, these defines also mapping the hardware.
But different from reset driver, clk driver also used these defines.
If I removed this defines, I  must write the proper hardware number twice in dt & driver.
It's meaningless & hard to check.




_______________________________________________
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] 58+ messages in thread

* Re: [PATCH v12 4/9] dt-bindings: clock: Add bindings for SP7021 clock driver
  2022-04-01  9:19       ` qinjian[覃健]
@ 2022-04-01  9:32         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 58+ messages in thread
From: Krzysztof Kozlowski @ 2022-04-01  9:32 UTC (permalink / raw)
  To: qinjian[覃健]
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk

On 01/04/2022 11:19, qinjian[覃健] wrote:
>>> diff --git a/include/dt-bindings/clock/sp-sp7021.h b/include/dt-bindings/clock/sp-sp7021.h
>>> new file mode 100644
>>> index 000000000..45dac6de8
>>> --- /dev/null
>>> +++ b/include/dt-bindings/clock/sp-sp7021.h
>>> @@ -0,0 +1,112 @@
>>> +/* 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
>>> +
>>> +#define XTAL			27000000
>>> +
>>> +/* plls */
>>> +#define PLL_A			0
>>> +#define PLL_E			1
>>> +#define PLL_E_2P5		2
>>> +#define PLL_E_25		3
>>> +#define PLL_E_112P5		4
>>> +#define PLL_F			5
>>> +#define PLL_TV			6
>>> +#define PLL_TV_A		7
>>> +#define PLL_SYS			8
>>> +
>>> +/* gates: mo_clken0 ~ mo_clken9 */
>>> +#define CLK_SYSTEM		0x10
>>> +#define CLK_RTC			0x12
>>
>> YAML looks ok, but here comment from Arnd also applies. These should be
>> regular decimal numbers incremented by one.
>>
>> Best regards,
>> Krzysztof
> 
> Yes, same as reset driver, these defines also mapping the hardware.
> But different from reset driver, clk driver also used these defines.
> If I removed this defines, I  must write the proper hardware number twice in dt & driver.
> It's meaningless & hard to check.

Not really... just follow what most (or all) clock drivers are doing -
incremental IDs.



Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v12 4/9] dt-bindings: clock: Add bindings for SP7021 clock driver
@ 2022-04-01  9:32         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 58+ messages in thread
From: Krzysztof Kozlowski @ 2022-04-01  9:32 UTC (permalink / raw)
  To: qinjian[覃健]
  Cc: robh+dt, mturquette, sboyd, tglx, maz, p.zabel, linux, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk

On 01/04/2022 11:19, qinjian[覃健] wrote:
>>> diff --git a/include/dt-bindings/clock/sp-sp7021.h b/include/dt-bindings/clock/sp-sp7021.h
>>> new file mode 100644
>>> index 000000000..45dac6de8
>>> --- /dev/null
>>> +++ b/include/dt-bindings/clock/sp-sp7021.h
>>> @@ -0,0 +1,112 @@
>>> +/* 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
>>> +
>>> +#define XTAL			27000000
>>> +
>>> +/* plls */
>>> +#define PLL_A			0
>>> +#define PLL_E			1
>>> +#define PLL_E_2P5		2
>>> +#define PLL_E_25		3
>>> +#define PLL_E_112P5		4
>>> +#define PLL_F			5
>>> +#define PLL_TV			6
>>> +#define PLL_TV_A		7
>>> +#define PLL_SYS			8
>>> +
>>> +/* gates: mo_clken0 ~ mo_clken9 */
>>> +#define CLK_SYSTEM		0x10
>>> +#define CLK_RTC			0x12
>>
>> YAML looks ok, but here comment from Arnd also applies. These should be
>> regular decimal numbers incremented by one.
>>
>> Best regards,
>> Krzysztof
> 
> Yes, same as reset driver, these defines also mapping the hardware.
> But different from reset driver, clk driver also used these defines.
> If I removed this defines, I  must write the proper hardware number twice in dt & driver.
> It's meaningless & hard to check.

Not really... just follow what most (or all) clock drivers are doing -
incremental IDs.



Best regards,
Krzysztof

_______________________________________________
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] 58+ messages in thread

* RE: [PATCH v12 5/9] clk: Add Sunplus SP7021 clock driver
  2022-03-31  9:22     ` Arnd Bergmann
@ 2022-04-01  9:47       ` qinjian[覃健]
  -1 siblings, 0 replies; 58+ messages in thread
From: qinjian[覃健] @ 2022-04-01  9:47 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

> 
> > +static int sp_pll_enable(struct clk_hw *hw)
> > +{
> > +       struct sp_pll *clk = to_sp_pll(hw);
> > +       unsigned long flags;
> > +
> > +       spin_lock_irqsave(clk->lock, flags);
> > +       writel(BIT(clk->pd_bit + 16) | BIT(clk->pd_bit), clk->reg); /* power up */
> > +       spin_unlock_irqrestore(clk->lock, flags);
> > +
> > +       return 0;
> > +}
> > +
> > +static void sp_pll_disable(struct clk_hw *hw)
> > +{
> > +       struct sp_pll *clk = to_sp_pll(hw);
> > +       unsigned long flags;
> > +
> > +       spin_lock_irqsave(clk->lock, flags);
> > +       writel(BIT(clk->pd_bit + 16), clk->reg); /* power down */
> > +       spin_unlock_irqrestore(clk->lock, flags);
> > +}
> 
> What does the spinlock actually protect here? As writel() is posted, it
> can already leak of of the lock, and the inputs would appear to be
> constant.
> 

These code is refered from other clk driver.
But, other driver need read then write, so need lock protected.
Our  HW is HIWORD_MASKED_REG, means modify bits no need to read, just 1 write only.
So, the lock is useless.
Did I right?

> > +       /* This memory region include multi HW regs in discontinuous order.
> > +        * clk driver used some discontinuous areas in the memory region.
> > +        * Using devm_platform_ioremap_resource() would conflicted with other drivers.
> > +        */
> > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +       sp_clk_base = devm_ioremap(dev, res->start, resource_size(res));
> > +       if (!sp_clk_base)
> > +               return -ENXIO;
> 
> Can you explain this comment in more detail? Generally, the 'reg' properties
> of drivers should not overlap, so it is supposed to be safe to call
> devm_platform_ioremap_resource() here.
> 
> We discussed this in the context of the iop driver that did have overlapping
> registers with this driver, and that was incorrect. Are there any other drivers
> that conflict with the clk driver?
> 
>       Arnd

I means, I must split up the origin reg region into 4 small pieces,
and call devm_platform_ioremap_resource() 4 times.
Did I should follow this way?

^ permalink raw reply	[flat|nested] 58+ messages in thread

* RE: [PATCH v12 5/9] clk: Add Sunplus SP7021 clock driver
@ 2022-04-01  9:47       ` qinjian[覃健]
  0 siblings, 0 replies; 58+ messages in thread
From: qinjian[覃健] @ 2022-04-01  9:47 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

> 
> > +static int sp_pll_enable(struct clk_hw *hw)
> > +{
> > +       struct sp_pll *clk = to_sp_pll(hw);
> > +       unsigned long flags;
> > +
> > +       spin_lock_irqsave(clk->lock, flags);
> > +       writel(BIT(clk->pd_bit + 16) | BIT(clk->pd_bit), clk->reg); /* power up */
> > +       spin_unlock_irqrestore(clk->lock, flags);
> > +
> > +       return 0;
> > +}
> > +
> > +static void sp_pll_disable(struct clk_hw *hw)
> > +{
> > +       struct sp_pll *clk = to_sp_pll(hw);
> > +       unsigned long flags;
> > +
> > +       spin_lock_irqsave(clk->lock, flags);
> > +       writel(BIT(clk->pd_bit + 16), clk->reg); /* power down */
> > +       spin_unlock_irqrestore(clk->lock, flags);
> > +}
> 
> What does the spinlock actually protect here? As writel() is posted, it
> can already leak of of the lock, and the inputs would appear to be
> constant.
> 

These code is refered from other clk driver.
But, other driver need read then write, so need lock protected.
Our  HW is HIWORD_MASKED_REG, means modify bits no need to read, just 1 write only.
So, the lock is useless.
Did I right?

> > +       /* This memory region include multi HW regs in discontinuous order.
> > +        * clk driver used some discontinuous areas in the memory region.
> > +        * Using devm_platform_ioremap_resource() would conflicted with other drivers.
> > +        */
> > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +       sp_clk_base = devm_ioremap(dev, res->start, resource_size(res));
> > +       if (!sp_clk_base)
> > +               return -ENXIO;
> 
> Can you explain this comment in more detail? Generally, the 'reg' properties
> of drivers should not overlap, so it is supposed to be safe to call
> devm_platform_ioremap_resource() here.
> 
> We discussed this in the context of the iop driver that did have overlapping
> registers with this driver, and that was incorrect. Are there any other drivers
> that conflict with the clk driver?
> 
>       Arnd

I means, I must split up the origin reg region into 4 small pieces,
and call devm_platform_ioremap_resource() 4 times.
Did I should follow this way?
_______________________________________________
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] 58+ messages in thread

* Re: [PATCH v12 5/9] clk: Add Sunplus SP7021 clock driver
  2022-04-01  9:47       ` qinjian[覃健]
@ 2022-04-01 10:09         ` Arnd Bergmann
  -1 siblings, 0 replies; 58+ messages in thread
From: Arnd Bergmann @ 2022-04-01 10:09 UTC (permalink / raw)
  To: qinjian[覃健]
  Cc: Arnd Bergmann, Krzysztof Kozlowski, Rob Herring,
	Michael Turquette, Stephen Boyd, Thomas Gleixner, Marc Zyngier,
	Philipp Zabel, Russell King - ARM Linux, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

On Fri, Apr 1, 2022 at 11:47 AM qinjian[覃健] <qinjian@cqplus1.com> wrote:
> > > +static int sp_pll_enable(struct clk_hw *hw)
> > > +{
> > > +       struct sp_pll *clk = to_sp_pll(hw);
> > > +       unsigned long flags;
> > > +
> > > +       spin_lock_irqsave(clk->lock, flags);
> > > +       writel(BIT(clk->pd_bit + 16) | BIT(clk->pd_bit), clk->reg); /* power up */
> > > +       spin_unlock_irqrestore(clk->lock, flags);
> > > +
> > > +       return 0;
> > > +}
> > > +
> > > +static void sp_pll_disable(struct clk_hw *hw)
> > > +{
> > > +       struct sp_pll *clk = to_sp_pll(hw);
> > > +       unsigned long flags;
> > > +
> > > +       spin_lock_irqsave(clk->lock, flags);
> > > +       writel(BIT(clk->pd_bit + 16), clk->reg); /* power down */
> > > +       spin_unlock_irqrestore(clk->lock, flags);
> > > +}
> >
> > What does the spinlock actually protect here? As writel() is posted, it
> > can already leak of of the lock, and the inputs would appear to be
> > constant.
> >
>
> These code is refered from other clk driver.
> But, other driver need read then write, so need lock protected.
> Our  HW is HIWORD_MASKED_REG, means modify bits no need to read, just 1 write only.
> So, the lock is useless.
> Did I right?

If the read-modify-write is done on a different register, then it is
fine to remove
the lock. You can also consider having shadow registers to avoid expensive
r-m-w cycles and just always write the register directly.

> > > +       /* This memory region include multi HW regs in discontinuous order.
> > > +        * clk driver used some discontinuous areas in the memory region.
> > > +        * Using devm_platform_ioremap_resource() would conflicted with other drivers.
> > > +        */
> > > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > > +       sp_clk_base = devm_ioremap(dev, res->start, resource_size(res));
> > > +       if (!sp_clk_base)
> > > +               return -ENXIO;
> >
> > Can you explain this comment in more detail? Generally, the 'reg' properties
> > of drivers should not overlap, so it is supposed to be safe to call
> > devm_platform_ioremap_resource() here.
> >
> > We discussed this in the context of the iop driver that did have overlapping
> > registers with this driver, and that was incorrect. Are there any other drivers
> > that conflict with the clk driver?
>
> I means, I must split up the origin reg region into 4 small pieces,
> and call devm_platform_ioremap_resource() 4 times.
> Did I should follow this way?

It depends. What are those other registers, and what drivers use them?

        Arnd

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v12 5/9] clk: Add Sunplus SP7021 clock driver
@ 2022-04-01 10:09         ` Arnd Bergmann
  0 siblings, 0 replies; 58+ messages in thread
From: Arnd Bergmann @ 2022-04-01 10:09 UTC (permalink / raw)
  To: qinjian[覃健]
  Cc: Arnd Bergmann, Krzysztof Kozlowski, Rob Herring,
	Michael Turquette, Stephen Boyd, Thomas Gleixner, Marc Zyngier,
	Philipp Zabel, Russell King - ARM Linux, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

On Fri, Apr 1, 2022 at 11:47 AM qinjian[覃健] <qinjian@cqplus1.com> wrote:
> > > +static int sp_pll_enable(struct clk_hw *hw)
> > > +{
> > > +       struct sp_pll *clk = to_sp_pll(hw);
> > > +       unsigned long flags;
> > > +
> > > +       spin_lock_irqsave(clk->lock, flags);
> > > +       writel(BIT(clk->pd_bit + 16) | BIT(clk->pd_bit), clk->reg); /* power up */
> > > +       spin_unlock_irqrestore(clk->lock, flags);
> > > +
> > > +       return 0;
> > > +}
> > > +
> > > +static void sp_pll_disable(struct clk_hw *hw)
> > > +{
> > > +       struct sp_pll *clk = to_sp_pll(hw);
> > > +       unsigned long flags;
> > > +
> > > +       spin_lock_irqsave(clk->lock, flags);
> > > +       writel(BIT(clk->pd_bit + 16), clk->reg); /* power down */
> > > +       spin_unlock_irqrestore(clk->lock, flags);
> > > +}
> >
> > What does the spinlock actually protect here? As writel() is posted, it
> > can already leak of of the lock, and the inputs would appear to be
> > constant.
> >
>
> These code is refered from other clk driver.
> But, other driver need read then write, so need lock protected.
> Our  HW is HIWORD_MASKED_REG, means modify bits no need to read, just 1 write only.
> So, the lock is useless.
> Did I right?

If the read-modify-write is done on a different register, then it is
fine to remove
the lock. You can also consider having shadow registers to avoid expensive
r-m-w cycles and just always write the register directly.

> > > +       /* This memory region include multi HW regs in discontinuous order.
> > > +        * clk driver used some discontinuous areas in the memory region.
> > > +        * Using devm_platform_ioremap_resource() would conflicted with other drivers.
> > > +        */
> > > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > > +       sp_clk_base = devm_ioremap(dev, res->start, resource_size(res));
> > > +       if (!sp_clk_base)
> > > +               return -ENXIO;
> >
> > Can you explain this comment in more detail? Generally, the 'reg' properties
> > of drivers should not overlap, so it is supposed to be safe to call
> > devm_platform_ioremap_resource() here.
> >
> > We discussed this in the context of the iop driver that did have overlapping
> > registers with this driver, and that was incorrect. Are there any other drivers
> > that conflict with the clk driver?
>
> I means, I must split up the origin reg region into 4 small pieces,
> and call devm_platform_ioremap_resource() 4 times.
> Did I should follow this way?

It depends. What are those other registers, and what drivers use them?

        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] 58+ messages in thread

* Re: [PATCH v12 6/9] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
  2022-04-01  2:29       ` qinjian[覃健]
@ 2022-04-01 17:53         ` Rob Herring
  -1 siblings, 0 replies; 58+ messages in thread
From: Rob Herring @ 2022-04-01 17:53 UTC (permalink / raw)
  To: qinjian[覃健]
  Cc: arnd, linux-clk, p.zabel, maz, linux-kernel, mturquette, sboyd,
	linux, linux-arm-kernel, devicetree, krzysztof.kozlowski, tglx

On Fri, Apr 01, 2022 at 02:29:58AM +0000, qinjian[覃健] wrote:
> > 
> > On Thu, 31 Mar 2022 16:29:53 +0800, Qin Jian wrote:
> > > Add documentation to describe Sunplus SP7021 interrupt controller bindings.
> > >
> > > Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> > > ---
> > > Move 'reg' after 'compatible'
> > > ---
> > >  .../sunplus,sp7021-intc.yaml                  | 62 +++++++++++++++++++
> > >  MAINTAINERS                                   |  1 +
> > >  2 files changed, 63 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
> > >
> > 
> > 
> > Please add Acked-by/Reviewed-by tags when posting new versions. However,
> > there's no need to repost patches *only* to add the tags. The upstream
> > maintainer will do that for acks received on the version they apply.
> > 
> > If a tag was not added on purpose, please state why and what changed.
> 
> Changes: Move 'reg' after 'compatible'
> I did a modification based on comments from krzysztof.kozlowski@canonical.com [1]
> 
> [1] https://lore.kernel.org/all/6dbeda18-a11c-609d-7a8f-bf2e6f27aea7@kernel.org/

A trivial change like that can keep a tag especially if it came after 
the comment (not sure here).

Rob

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v12 6/9] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
@ 2022-04-01 17:53         ` Rob Herring
  0 siblings, 0 replies; 58+ messages in thread
From: Rob Herring @ 2022-04-01 17:53 UTC (permalink / raw)
  To: qinjian[覃健]
  Cc: arnd, linux-clk, p.zabel, maz, linux-kernel, mturquette, sboyd,
	linux, linux-arm-kernel, devicetree, krzysztof.kozlowski, tglx

On Fri, Apr 01, 2022 at 02:29:58AM +0000, qinjian[覃健] wrote:
> > 
> > On Thu, 31 Mar 2022 16:29:53 +0800, Qin Jian wrote:
> > > Add documentation to describe Sunplus SP7021 interrupt controller bindings.
> > >
> > > Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> > > ---
> > > Move 'reg' after 'compatible'
> > > ---
> > >  .../sunplus,sp7021-intc.yaml                  | 62 +++++++++++++++++++
> > >  MAINTAINERS                                   |  1 +
> > >  2 files changed, 63 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
> > >
> > 
> > 
> > Please add Acked-by/Reviewed-by tags when posting new versions. However,
> > there's no need to repost patches *only* to add the tags. The upstream
> > maintainer will do that for acks received on the version they apply.
> > 
> > If a tag was not added on purpose, please state why and what changed.
> 
> Changes: Move 'reg' after 'compatible'
> I did a modification based on comments from krzysztof.kozlowski@canonical.com [1]
> 
> [1] https://lore.kernel.org/all/6dbeda18-a11c-609d-7a8f-bf2e6f27aea7@kernel.org/

A trivial change like that can keep a tag especially if it came after 
the comment (not sure here).

Rob

_______________________________________________
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] 58+ messages in thread

* RE: [PATCH v12 6/9] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
  2022-04-01 17:53         ` Rob Herring
@ 2022-04-02  2:43           ` qinjian[覃健]
  -1 siblings, 0 replies; 58+ messages in thread
From: qinjian[覃健] @ 2022-04-02  2:43 UTC (permalink / raw)
  To: Rob Herring
  Cc: arnd, linux-clk, p.zabel, maz, linux-kernel, mturquette, sboyd,
	linux, linux-arm-kernel, devicetree, krzysztof.kozlowski, tglx

> 
> On Fri, Apr 01, 2022 at 02:29:58AM +0000, qinjian[覃健] wrote:
> > >
> > > On Thu, 31 Mar 2022 16:29:53 +0800, Qin Jian wrote:
> > > > Add documentation to describe Sunplus SP7021 interrupt controller bindings.
> > > >
> > > > Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> > > > ---
> > > > Move 'reg' after 'compatible'
> > > > ---
> > > >  .../sunplus,sp7021-intc.yaml                  | 62 +++++++++++++++++++
> > > >  MAINTAINERS                                   |  1 +
> > > >  2 files changed, 63 insertions(+)
> > > >  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
> > > >
> > >
> > >
> > > Please add Acked-by/Reviewed-by tags when posting new versions. However,
> > > there's no need to repost patches *only* to add the tags. The upstream
> > > maintainer will do that for acks received on the version they apply.
> > >
> > > If a tag was not added on purpose, please state why and what changed.
> >
> > Changes: Move 'reg' after 'compatible'
> > I did a modification based on comments from krzysztof.kozlowski@canonical.com [1]
> >
> > [1] https://lore.kernel.org/all/6dbeda18-a11c-609d-7a8f-bf2e6f27aea7@kernel.org/
> 
> A trivial change like that can keep a tag especially if it came after
> the comment (not sure here).
> 
> Rob

I'll add back the tag next version, thanks.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* RE: [PATCH v12 6/9] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
@ 2022-04-02  2:43           ` qinjian[覃健]
  0 siblings, 0 replies; 58+ messages in thread
From: qinjian[覃健] @ 2022-04-02  2:43 UTC (permalink / raw)
  To: Rob Herring
  Cc: arnd, linux-clk, p.zabel, maz, linux-kernel, mturquette, sboyd,
	linux, linux-arm-kernel, devicetree, krzysztof.kozlowski, tglx

> 
> On Fri, Apr 01, 2022 at 02:29:58AM +0000, qinjian[覃健] wrote:
> > >
> > > On Thu, 31 Mar 2022 16:29:53 +0800, Qin Jian wrote:
> > > > Add documentation to describe Sunplus SP7021 interrupt controller bindings.
> > > >
> > > > Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> > > > ---
> > > > Move 'reg' after 'compatible'
> > > > ---
> > > >  .../sunplus,sp7021-intc.yaml                  | 62 +++++++++++++++++++
> > > >  MAINTAINERS                                   |  1 +
> > > >  2 files changed, 63 insertions(+)
> > > >  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
> > > >
> > >
> > >
> > > Please add Acked-by/Reviewed-by tags when posting new versions. However,
> > > there's no need to repost patches *only* to add the tags. The upstream
> > > maintainer will do that for acks received on the version they apply.
> > >
> > > If a tag was not added on purpose, please state why and what changed.
> >
> > Changes: Move 'reg' after 'compatible'
> > I did a modification based on comments from krzysztof.kozlowski@canonical.com [1]
> >
> > [1] https://lore.kernel.org/all/6dbeda18-a11c-609d-7a8f-bf2e6f27aea7@kernel.org/
> 
> A trivial change like that can keep a tag especially if it came after
> the comment (not sure here).
> 
> Rob

I'll add back the tag next version, thanks.
_______________________________________________
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] 58+ messages in thread

* RE: [PATCH v12 5/9] clk: Add Sunplus SP7021 clock driver
  2022-04-01 10:09         ` Arnd Bergmann
@ 2022-04-02  3:37           ` qinjian[覃健]
  -1 siblings, 0 replies; 58+ messages in thread
From: qinjian[覃健] @ 2022-04-02  3:37 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

> 
> > > > +       /* This memory region include multi HW regs in discontinuous order.
> > > > +        * clk driver used some discontinuous areas in the memory region.
> > > > +        * Using devm_platform_ioremap_resource() would conflicted with other drivers.
> > > > +        */
> > > > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > > > +       sp_clk_base = devm_ioremap(dev, res->start, resource_size(res));
> > > > +       if (!sp_clk_base)
> > > > +               return -ENXIO;
> > >
> > > Can you explain this comment in more detail? Generally, the 'reg' properties
> > > of drivers should not overlap, so it is supposed to be safe to call
> > > devm_platform_ioremap_resource() here.
> > >
> > > We discussed this in the context of the iop driver that did have overlapping
> > > registers with this driver, and that was incorrect. Are there any other drivers
> > > that conflict with the clk driver?
> >
> > I means, I must split up the origin reg region into 4 small pieces,
> > and call devm_platform_ioremap_resource() 4 times.
> > Did I should follow this way?
> 
> It depends. What are those other registers, and what drivers use them?
> 
>         Arnd

Include Reset / PinMux / USBC / UPHY regs, which used by related drivers.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* RE: [PATCH v12 5/9] clk: Add Sunplus SP7021 clock driver
@ 2022-04-02  3:37           ` qinjian[覃健]
  0 siblings, 0 replies; 58+ messages in thread
From: qinjian[覃健] @ 2022-04-02  3:37 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Krzysztof Kozlowski, Rob Herring, Michael Turquette,
	Stephen Boyd, Thomas Gleixner, Marc Zyngier, Philipp Zabel,
	Russell King - ARM Linux, Linux ARM, DTML,
	Linux Kernel Mailing List, linux-clk

> 
> > > > +       /* This memory region include multi HW regs in discontinuous order.
> > > > +        * clk driver used some discontinuous areas in the memory region.
> > > > +        * Using devm_platform_ioremap_resource() would conflicted with other drivers.
> > > > +        */
> > > > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > > > +       sp_clk_base = devm_ioremap(dev, res->start, resource_size(res));
> > > > +       if (!sp_clk_base)
> > > > +               return -ENXIO;
> > >
> > > Can you explain this comment in more detail? Generally, the 'reg' properties
> > > of drivers should not overlap, so it is supposed to be safe to call
> > > devm_platform_ioremap_resource() here.
> > >
> > > We discussed this in the context of the iop driver that did have overlapping
> > > registers with this driver, and that was incorrect. Are there any other drivers
> > > that conflict with the clk driver?
> >
> > I means, I must split up the origin reg region into 4 small pieces,
> > and call devm_platform_ioremap_resource() 4 times.
> > Did I should follow this way?
> 
> It depends. What are those other registers, and what drivers use them?
> 
>         Arnd

Include Reset / PinMux / USBC / UPHY regs, which used by related drivers.
_______________________________________________
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] 58+ messages in thread

end of thread, other threads:[~2022-04-02  3:45 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-31  8:29 [PATCH v12 0/9] Add Sunplus SP7021 SoC Support Qin Jian
2022-03-31  8:29 ` Qin Jian
2022-03-31  8:29 ` [PATCH v12 1/9] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards Qin Jian
2022-03-31  8:29   ` Qin Jian
2022-03-31  8:29 ` [PATCH v12 2/9] dt-bindings: reset: Add bindings for SP7021 reset driver Qin Jian
2022-03-31  8:29   ` Qin Jian
2022-03-31  8:58   ` Arnd Bergmann
2022-03-31  8:58     ` Arnd Bergmann
2022-04-01  8:24     ` qinjian[覃健]
2022-04-01  8:24       ` qinjian[覃健]
2022-03-31  8:29 ` [PATCH v12 3/9] reset: Add Sunplus " Qin Jian
2022-03-31  8:29   ` Qin Jian
2022-03-31  8:59   ` Arnd Bergmann
2022-03-31  8:59     ` Arnd Bergmann
2022-03-31  8:29 ` [PATCH v12 4/9] dt-bindings: clock: Add bindings for SP7021 clock driver Qin Jian
2022-03-31  8:29   ` Qin Jian
2022-03-31 20:21   ` Krzysztof Kozlowski
2022-03-31 20:21     ` Krzysztof Kozlowski
2022-04-01  9:19     ` qinjian[覃健]
2022-04-01  9:19       ` qinjian[覃健]
2022-04-01  9:32       ` Krzysztof Kozlowski
2022-04-01  9:32         ` Krzysztof Kozlowski
2022-03-31  8:29 ` [PATCH v12 5/9] clk: Add Sunplus " Qin Jian
2022-03-31  8:29   ` Qin Jian
2022-03-31  9:22   ` Arnd Bergmann
2022-03-31  9:22     ` Arnd Bergmann
2022-04-01  9:47     ` qinjian[覃健]
2022-04-01  9:47       ` qinjian[覃健]
2022-04-01 10:09       ` Arnd Bergmann
2022-04-01 10:09         ` Arnd Bergmann
2022-04-02  3:37         ` qinjian[覃健]
2022-04-02  3:37           ` qinjian[覃健]
2022-03-31  8:29 ` [PATCH v12 6/9] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller Qin Jian
2022-03-31  8:29   ` Qin Jian
2022-03-31 20:44   ` Rob Herring
2022-03-31 20:44     ` Rob Herring
2022-04-01  2:29     ` qinjian[覃健]
2022-04-01  2:29       ` qinjian[覃健]
2022-04-01 17:53       ` Rob Herring
2022-04-01 17:53         ` Rob Herring
2022-04-02  2:43         ` qinjian[覃健]
2022-04-02  2:43           ` qinjian[覃健]
2022-03-31  8:29 ` [PATCH v12 7/9] irqchip: Add Sunplus SP7021 interrupt controller driver Qin Jian
2022-03-31  8:29   ` Qin Jian
2022-03-31  9:17   ` Arnd Bergmann
2022-03-31  9:17     ` Arnd Bergmann
2022-04-01  7:17     ` qinjian[覃健]
2022-04-01  7:17       ` qinjian[覃健]
2022-03-31  8:29 ` [PATCH v12 8/9] ARM: sunplus: Add initial support for Sunplus SP7021 SoC Qin Jian
2022-03-31  8:29   ` Qin Jian
2022-03-31  9:03   ` Arnd Bergmann
2022-03-31  9:03     ` Arnd Bergmann
2022-03-31  8:29 ` [PATCH v12 9/9] ARM: sp7021_defconfig: Add Sunplus SP7021 defconfig Qin Jian
2022-03-31  8:29   ` Qin Jian
2022-03-31  9:09   ` Arnd Bergmann
2022-03-31  9:09     ` Arnd Bergmann
2022-04-01  7:08     ` qinjian[覃健]
2022-04-01  7:08       ` qinjian[覃健]

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.