All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/8] Add Sunplus SP7021 SoC Support
@ 2021-10-29  8:44 ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-10-29  8:44 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, tglx, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, 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 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 (8):
  dt-bindings: vendor-prefixes: Add Sunplus
  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 support for Sunplus SP7021 interrupt controller

 .../bindings/arm/sunplus,sp7021.yaml          |  27 +
 .../bindings/clock/sunplus,sp7021-clkc.yaml   |  38 +
 .../sunplus,sp7021-intc.yaml                  |  59 ++
 .../bindings/reset/sunplus,reset.yaml         |  40 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 MAINTAINERS                                   |  16 +
 drivers/clk/Kconfig                           |   8 +
 drivers/clk/Makefile                          |   1 +
 drivers/clk/clk-sp7021.c                      | 770 ++++++++++++++++++
 drivers/irqchip/Kconfig                       |   9 +
 drivers/irqchip/Makefile                      |   1 +
 drivers/irqchip/irq-sp7021-intc.c             | 324 ++++++++
 drivers/reset/Kconfig                         |   9 +
 drivers/reset/Makefile                        |   1 +
 drivers/reset/reset-sunplus.c                 | 159 ++++
 include/dt-bindings/clock/sp-sp7021.h         | 112 +++
 .../interrupt-controller/sp7021-intc.h        |  24 +
 include/dt-bindings/reset/sp-sp7021.h         |  99 +++
 18 files changed, 1699 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 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/interrupt-controller/sp7021-intc.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] 124+ messages in thread

* [PATCH v2 0/8] Add Sunplus SP7021 SoC Support
@ 2021-10-29  8:44 ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-10-29  8:44 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, tglx, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, 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 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 (8):
  dt-bindings: vendor-prefixes: Add Sunplus
  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 support for Sunplus SP7021 interrupt controller

 .../bindings/arm/sunplus,sp7021.yaml          |  27 +
 .../bindings/clock/sunplus,sp7021-clkc.yaml   |  38 +
 .../sunplus,sp7021-intc.yaml                  |  59 ++
 .../bindings/reset/sunplus,reset.yaml         |  40 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 MAINTAINERS                                   |  16 +
 drivers/clk/Kconfig                           |   8 +
 drivers/clk/Makefile                          |   1 +
 drivers/clk/clk-sp7021.c                      | 770 ++++++++++++++++++
 drivers/irqchip/Kconfig                       |   9 +
 drivers/irqchip/Makefile                      |   1 +
 drivers/irqchip/irq-sp7021-intc.c             | 324 ++++++++
 drivers/reset/Kconfig                         |   9 +
 drivers/reset/Makefile                        |   1 +
 drivers/reset/reset-sunplus.c                 | 159 ++++
 include/dt-bindings/clock/sp-sp7021.h         | 112 +++
 .../interrupt-controller/sp7021-intc.h        |  24 +
 include/dt-bindings/reset/sp-sp7021.h         |  99 +++
 18 files changed, 1699 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 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/interrupt-controller/sp7021-intc.h
 create mode 100644 include/dt-bindings/reset/sp-sp7021.h

--
2.33.1

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

* [PATCH v2 1/8] dt-bindings: vendor-prefixes: Add Sunplus
  2021-10-29  8:44 ` Qin Jian
@ 2021-10-29  8:44   ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-10-29  8:44 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, tglx, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add vendor prefix for Sunplus Technology Co., Ltd. (http://www.sunplus.com)

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index a867f7102..50d4ee5ac 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1131,6 +1131,8 @@ patternProperties:
     description: Summit microelectronics
   "^sunchip,.*":
     description: Shenzhen Sunchip Technology Co., Ltd
+  "^sunplus,.*":
+    description: Sunplus Technology Co., Ltd.
   "^SUNW,.*":
     description: Sun Microsystems, Inc
   "^supermicro,.*":
-- 
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] 124+ messages in thread

* [PATCH v2 1/8] dt-bindings: vendor-prefixes: Add Sunplus
@ 2021-10-29  8:44   ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-10-29  8:44 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, tglx, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add vendor prefix for Sunplus Technology Co., Ltd. (http://www.sunplus.com)

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index a867f7102..50d4ee5ac 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1131,6 +1131,8 @@ patternProperties:
     description: Summit microelectronics
   "^sunchip,.*":
     description: Shenzhen Sunchip Technology Co., Ltd
+  "^sunplus,.*":
+    description: Sunplus Technology Co., Ltd.
   "^SUNW,.*":
     description: Sun Microsystems, Inc
   "^supermicro,.*":
-- 
2.33.1


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

* [PATCH v2 2/8] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards
  2021-10-29  8:44 ` Qin Jian
@ 2021-10-29  8:44   ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-10-29  8:44 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, tglx, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

This introduces bindings for boards based Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../bindings/arm/sunplus,sp7021.yaml          | 27 +++++++++++++++++++
 MAINTAINERS                                   |  7 +++++
 2 files changed, 34 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..5b9985b73
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
@@ -0,0 +1,27 @@
+# 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:
+    oneOf:
+      - items:
+          - const: sunplus,sp7021-achip
+
+additionalProperties: true
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index e0bca0de0..6a5422f10 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2655,6 +2655,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 <Jisheng.Zhang@synaptics.com>
 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] 124+ messages in thread

* [PATCH v2 2/8] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards
@ 2021-10-29  8:44   ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-10-29  8:44 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, tglx, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

This introduces bindings for boards based Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../bindings/arm/sunplus,sp7021.yaml          | 27 +++++++++++++++++++
 MAINTAINERS                                   |  7 +++++
 2 files changed, 34 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..5b9985b73
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
@@ -0,0 +1,27 @@
+# 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:
+    oneOf:
+      - items:
+          - const: sunplus,sp7021-achip
+
+additionalProperties: true
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index e0bca0de0..6a5422f10 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2655,6 +2655,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 <Jisheng.Zhang@synaptics.com>
 M:	Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
-- 
2.33.1


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

* [PATCH v2 3/8] dt-bindings: reset: Add bindings for SP7021 reset driver
  2021-10-29  8:44 ` Qin Jian
@ 2021-10-29  8:44   ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-10-29  8:44 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, tglx, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add documentation to describe Sunplus SP7021 reset driver bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../bindings/reset/sunplus,reset.yaml         | 40 ++++++++
 MAINTAINERS                                   |  2 +
 include/dt-bindings/reset/sp-sp7021.h         | 99 +++++++++++++++++++
 3 files changed, 141 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..bf55f4ee2
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/sunplus,reset.yaml
@@ -0,0 +1,40 @@
+# 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:
+    enum:
+      - sunplus,sp7021-reset # Reset Controller on SP7021 and compatible SoCs
+      - sunplus,q645-reset # Reset Controller on Q645 and compatible SoCs
+
+  "#reset-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#reset-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    rstc: reset@9c000054 {
+      compatible = "sunplus,sp7021-reset";
+      #reset-cells = <1>;
+      reg = <0x9c000054 0x28>;
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 6a5422f10..652f42cab 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2661,6 +2661,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 <Jisheng.Zhang@synaptics.com>
diff --git a/include/dt-bindings/reset/sp-sp7021.h b/include/dt-bindings/reset/sp-sp7021.h
new file mode 100644
index 000000000..8823d25ce
--- /dev/null
+++ b/include/dt-bindings/reset/sp-sp7021.h
@@ -0,0 +1,99 @@
+/* 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
+
+#define RST_MAX			0xA0
+
+#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] 124+ messages in thread

* [PATCH v2 3/8] dt-bindings: reset: Add bindings for SP7021 reset driver
@ 2021-10-29  8:44   ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-10-29  8:44 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, tglx, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add documentation to describe Sunplus SP7021 reset driver bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../bindings/reset/sunplus,reset.yaml         | 40 ++++++++
 MAINTAINERS                                   |  2 +
 include/dt-bindings/reset/sp-sp7021.h         | 99 +++++++++++++++++++
 3 files changed, 141 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..bf55f4ee2
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/sunplus,reset.yaml
@@ -0,0 +1,40 @@
+# 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:
+    enum:
+      - sunplus,sp7021-reset # Reset Controller on SP7021 and compatible SoCs
+      - sunplus,q645-reset # Reset Controller on Q645 and compatible SoCs
+
+  "#reset-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#reset-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    rstc: reset@9c000054 {
+      compatible = "sunplus,sp7021-reset";
+      #reset-cells = <1>;
+      reg = <0x9c000054 0x28>;
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 6a5422f10..652f42cab 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2661,6 +2661,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 <Jisheng.Zhang@synaptics.com>
diff --git a/include/dt-bindings/reset/sp-sp7021.h b/include/dt-bindings/reset/sp-sp7021.h
new file mode 100644
index 000000000..8823d25ce
--- /dev/null
+++ b/include/dt-bindings/reset/sp-sp7021.h
@@ -0,0 +1,99 @@
+/* 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
+
+#define RST_MAX			0xA0
+
+#endif
-- 
2.33.1


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

* [PATCH v2 4/8] reset: Add Sunplus SP7021 reset driver
  2021-10-29  8:44 ` Qin Jian
@ 2021-10-29  8:44   ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-10-29  8:44 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, tglx, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add reset driver for Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 MAINTAINERS                   |   1 +
 drivers/reset/Kconfig         |   9 ++
 drivers/reset/Makefile        |   1 +
 drivers/reset/reset-sunplus.c | 159 ++++++++++++++++++++++++++++++++++
 4 files changed, 170 insertions(+)
 create mode 100644 drivers/reset/reset-sunplus.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 652f42cab..6caffd6d0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2662,6 +2662,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 be799a5ab..1aec3c8af 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -249,6 +249,15 @@ config RESET_TI_SYSCON
 	  you wish to use the reset framework for such memory-mapped devices,
 	  say Y here. Otherwise, say N.
 
+config RESET_SUNPLUS
+	bool "Sunplus SoCs Reset Driver"
+	default ARCH_PENTAGRAM
+	help
+	  This enables the reset driver support for Sunplus SP7021 SoC family.
+	  Say Y if you want to control reset signals by the reset controller.
+	  Otherwise, say N.
+	  This driver is selected automatically by platform config.
+
 config RESET_UNIPHIER
 	tristate "Reset controller driver for UniPhier SoCs"
 	depends on ARCH_UNIPHIER || COMPILE_TEST
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 21d46d886..f03403e97 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o
 obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
 obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
 obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
+obj-$(CONFIG_RESET_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..696efd75e
--- /dev/null
+++ b/drivers/reset/reset-sunplus.c
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * SP7021 reset driver
+ *
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ *       All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/reboot.h>
+
+#if defined(CONFIG_SOC_SP7021)
+#include <dt-bindings/reset/sp-sp7021.h>
+#elif defined(CONFIG_SOC_Q645)
+#include <dt-bindings/reset/sp-q645.h>
+#endif
+
+#define BITASSERT(id, val)          ((1 << (16 + id)) | (val << id))
+
+
+struct sp_reset_data {
+	struct reset_controller_dev	rcdev;
+	void __iomem			*membase;
+} sp_reset;
+
+
+static inline struct sp_reset_data *
+to_sp_reset_data(struct reset_controller_dev *rcdev)
+{
+	return container_of(rcdev, struct sp_reset_data, rcdev);
+}
+
+static int sp_reset_update(struct reset_controller_dev *rcdev,
+			      unsigned long id, bool assert)
+{
+	struct sp_reset_data *data = to_sp_reset_data(rcdev);
+	int reg_width = sizeof(u32)/2;
+	int bank = id / (reg_width * BITS_PER_BYTE);
+	int offset = id % (reg_width * BITS_PER_BYTE);
+	void __iomem *addr;
+
+	addr = data->membase + (bank * 4);
+
+	if (assert)
+		writel(BITASSERT(offset, 1), addr);
+	else
+		writel(BITASSERT(offset, 0), addr);
+
+	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_data *data = to_sp_reset_data(rcdev);
+	int reg_width = sizeof(u32)/2;
+	int bank = id / (reg_width * BITS_PER_BYTE);
+	int offset = id % (reg_width * BITS_PER_BYTE);
+	u32 reg;
+
+	reg = readl(data->membase + (bank * 4));
+
+	return !!(reg & BIT(offset));
+}
+
+static int sp_restart(struct notifier_block *this, unsigned long mode,
+				void *cmd)
+{
+	sp_reset_assert(&sp_reset.rcdev, RST_SYSTEM);
+	sp_reset_deassert(&sp_reset.rcdev, RST_SYSTEM);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block sp_restart_nb = {
+	.notifier_call = sp_restart,
+	.priority = 192,
+};
+
+static const struct reset_control_ops sp_reset_ops = {
+	.assert		= sp_reset_assert,
+	.deassert	= sp_reset_deassert,
+	.status		= sp_reset_status,
+};
+
+static const struct of_device_id sp_reset_dt_ids[] = {
+	{ .compatible = "sunplus,sp7021-reset", },
+	{ .compatible = "sunplus,q645-reset", },
+	{ /* sentinel */ },
+};
+
+static int sp_reset_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct sp_reset_data *data = &sp_reset;
+	void __iomem *membase;
+	struct resource *res;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	membase = devm_ioremap(dev, res->start, resource_size(res));
+	if (IS_ERR(membase))
+		return PTR_ERR(membase);
+
+	data->membase = membase;
+	data->rcdev.owner = THIS_MODULE;
+	data->rcdev.nr_resets = RST_MAX;
+	data->rcdev.ops = &sp_reset_ops;
+	data->rcdev.of_node = dev->of_node;
+	register_restart_handler(&sp_restart_nb);
+
+	return devm_reset_controller_register(dev, &data->rcdev);
+}
+
+static struct platform_driver sp_reset_driver = {
+	.probe	= sp_reset_probe,
+	.driver = {
+		.name = "sunplus-reset",
+		.of_match_table	= sp_reset_dt_ids,
+	},
+};
+
+static int __init sp_reset_init(void)
+{
+	return platform_driver_register(&sp_reset_driver);
+}
+arch_initcall(sp_reset_init);
+
+MODULE_AUTHOR("Edwin Chiu <edwin.chiu@sunplus.com>");
+MODULE_DESCRIPTION("Sunplus Reset Driver");
+MODULE_LICENSE("GPL");
-- 
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] 124+ messages in thread

* [PATCH v2 4/8] reset: Add Sunplus SP7021 reset driver
@ 2021-10-29  8:44   ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-10-29  8:44 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, tglx, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add reset driver for Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 MAINTAINERS                   |   1 +
 drivers/reset/Kconfig         |   9 ++
 drivers/reset/Makefile        |   1 +
 drivers/reset/reset-sunplus.c | 159 ++++++++++++++++++++++++++++++++++
 4 files changed, 170 insertions(+)
 create mode 100644 drivers/reset/reset-sunplus.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 652f42cab..6caffd6d0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2662,6 +2662,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 be799a5ab..1aec3c8af 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -249,6 +249,15 @@ config RESET_TI_SYSCON
 	  you wish to use the reset framework for such memory-mapped devices,
 	  say Y here. Otherwise, say N.
 
+config RESET_SUNPLUS
+	bool "Sunplus SoCs Reset Driver"
+	default ARCH_PENTAGRAM
+	help
+	  This enables the reset driver support for Sunplus SP7021 SoC family.
+	  Say Y if you want to control reset signals by the reset controller.
+	  Otherwise, say N.
+	  This driver is selected automatically by platform config.
+
 config RESET_UNIPHIER
 	tristate "Reset controller driver for UniPhier SoCs"
 	depends on ARCH_UNIPHIER || COMPILE_TEST
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 21d46d886..f03403e97 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o
 obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
 obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
 obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
+obj-$(CONFIG_RESET_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..696efd75e
--- /dev/null
+++ b/drivers/reset/reset-sunplus.c
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * SP7021 reset driver
+ *
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ *       All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/reboot.h>
+
+#if defined(CONFIG_SOC_SP7021)
+#include <dt-bindings/reset/sp-sp7021.h>
+#elif defined(CONFIG_SOC_Q645)
+#include <dt-bindings/reset/sp-q645.h>
+#endif
+
+#define BITASSERT(id, val)          ((1 << (16 + id)) | (val << id))
+
+
+struct sp_reset_data {
+	struct reset_controller_dev	rcdev;
+	void __iomem			*membase;
+} sp_reset;
+
+
+static inline struct sp_reset_data *
+to_sp_reset_data(struct reset_controller_dev *rcdev)
+{
+	return container_of(rcdev, struct sp_reset_data, rcdev);
+}
+
+static int sp_reset_update(struct reset_controller_dev *rcdev,
+			      unsigned long id, bool assert)
+{
+	struct sp_reset_data *data = to_sp_reset_data(rcdev);
+	int reg_width = sizeof(u32)/2;
+	int bank = id / (reg_width * BITS_PER_BYTE);
+	int offset = id % (reg_width * BITS_PER_BYTE);
+	void __iomem *addr;
+
+	addr = data->membase + (bank * 4);
+
+	if (assert)
+		writel(BITASSERT(offset, 1), addr);
+	else
+		writel(BITASSERT(offset, 0), addr);
+
+	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_data *data = to_sp_reset_data(rcdev);
+	int reg_width = sizeof(u32)/2;
+	int bank = id / (reg_width * BITS_PER_BYTE);
+	int offset = id % (reg_width * BITS_PER_BYTE);
+	u32 reg;
+
+	reg = readl(data->membase + (bank * 4));
+
+	return !!(reg & BIT(offset));
+}
+
+static int sp_restart(struct notifier_block *this, unsigned long mode,
+				void *cmd)
+{
+	sp_reset_assert(&sp_reset.rcdev, RST_SYSTEM);
+	sp_reset_deassert(&sp_reset.rcdev, RST_SYSTEM);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block sp_restart_nb = {
+	.notifier_call = sp_restart,
+	.priority = 192,
+};
+
+static const struct reset_control_ops sp_reset_ops = {
+	.assert		= sp_reset_assert,
+	.deassert	= sp_reset_deassert,
+	.status		= sp_reset_status,
+};
+
+static const struct of_device_id sp_reset_dt_ids[] = {
+	{ .compatible = "sunplus,sp7021-reset", },
+	{ .compatible = "sunplus,q645-reset", },
+	{ /* sentinel */ },
+};
+
+static int sp_reset_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct sp_reset_data *data = &sp_reset;
+	void __iomem *membase;
+	struct resource *res;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	membase = devm_ioremap(dev, res->start, resource_size(res));
+	if (IS_ERR(membase))
+		return PTR_ERR(membase);
+
+	data->membase = membase;
+	data->rcdev.owner = THIS_MODULE;
+	data->rcdev.nr_resets = RST_MAX;
+	data->rcdev.ops = &sp_reset_ops;
+	data->rcdev.of_node = dev->of_node;
+	register_restart_handler(&sp_restart_nb);
+
+	return devm_reset_controller_register(dev, &data->rcdev);
+}
+
+static struct platform_driver sp_reset_driver = {
+	.probe	= sp_reset_probe,
+	.driver = {
+		.name = "sunplus-reset",
+		.of_match_table	= sp_reset_dt_ids,
+	},
+};
+
+static int __init sp_reset_init(void)
+{
+	return platform_driver_register(&sp_reset_driver);
+}
+arch_initcall(sp_reset_init);
+
+MODULE_AUTHOR("Edwin Chiu <edwin.chiu@sunplus.com>");
+MODULE_DESCRIPTION("Sunplus Reset Driver");
+MODULE_LICENSE("GPL");
-- 
2.33.1


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

* [PATCH v2 5/8] dt-bindings: clock: Add bindings for SP7021 clock driver
  2021-10-29  8:44 ` Qin Jian
@ 2021-10-29  8:44   ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-10-29  8:44 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, tglx, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add documentation to describe Sunplus SP7021 clock driver bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../bindings/clock/sunplus,sp7021-clkc.yaml   |  38 ++++++
 MAINTAINERS                                   |   2 +
 include/dt-bindings/clock/sp-sp7021.h         | 112 ++++++++++++++++++
 3 files changed, 152 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..1ce7e41d8
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.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/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
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    clkc: clkc@9c000000 {
+      compatible = "sunplus,sp7021-clkc";
+      #clock-cells = <1>;
+      reg = <0x9c000000 0x280>;
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 6caffd6d0..90ebb823f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2661,8 +2661,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..1ae9c4083
--- /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 SYSTEM		0x10
+#define RTC			0x12
+#define IOCTL		0x13
+#define IOP			0x14
+#define OTPRX		0x15
+#define NOC			0x16
+#define BR			0x17
+#define RBUS_L00	0x18
+#define SPIFL		0x19
+#define SDCTRL0		0x1a
+#define PERI0		0x1b
+#define A926		0x1d
+#define UMCTL2		0x1e
+#define PERI1		0x1f
+
+#define DDR_PHY0	0x20
+#define ACHIP		0x22
+#define STC0		0x24
+#define STC_AV0		0x25
+#define STC_AV1		0x26
+#define STC_AV2		0x27
+#define UA0			0x28
+#define UA1			0x29
+#define UA2			0x2a
+#define UA3			0x2b
+#define UA4			0x2c
+#define HWUA		0x2d
+#define DDC0		0x2e
+#define UADMA		0x2f
+
+#define CBDMA0		0x30
+#define CBDMA1		0x31
+#define SPI_COMBO_0	0x32
+#define SPI_COMBO_1	0x33
+#define SPI_COMBO_2	0x34
+#define SPI_COMBO_3	0x35
+#define AUD			0x36
+#define USBC0		0x3a
+#define USBC1		0x3b
+#define UPHY0		0x3d
+#define UPHY1		0x3e
+
+#define I2CM0		0x40
+#define I2CM1		0x41
+#define I2CM2		0x42
+#define I2CM3		0x43
+#define PMC			0x4d
+#define CARD_CTL0	0x4e
+#define CARD_CTL1	0x4f
+
+#define CARD_CTL4	0x52
+#define BCH			0x54
+#define DDFCH		0x5b
+#define CSIIW0		0x5c
+#define CSIIW1		0x5d
+#define MIPICSI0	0x5e
+#define MIPICSI1	0x5f
+
+#define HDMI_TX		0x60
+#define VPOST		0x65
+
+#define TGEN		0x70
+#define DMIX		0x71
+#define TCON		0x7a
+#define INTERRUPT	0x7f
+
+#define RGST		0x80
+#define GPIO		0x83
+#define RBUS_TOP	0x84
+
+#define MAILBOX		0x96
+#define SPIND		0x9a
+#define I2C2CBUS	0x9b
+#define SEC			0x9d
+#define DVE			0x9e
+#define GPOST0		0x9f
+
+#define OSD0		0xa0
+#define DISP_PWM	0xa2
+#define UADBG		0xa3
+#define DUMMY_MASTER	0xa4
+#define FIO_CTL		0xa5
+#define FPGA		0xa6
+#define L2SW		0xa7
+#define ICM			0xa8
+#define 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] 124+ messages in thread

* [PATCH v2 5/8] dt-bindings: clock: Add bindings for SP7021 clock driver
@ 2021-10-29  8:44   ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-10-29  8:44 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, tglx, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add documentation to describe Sunplus SP7021 clock driver bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../bindings/clock/sunplus,sp7021-clkc.yaml   |  38 ++++++
 MAINTAINERS                                   |   2 +
 include/dt-bindings/clock/sp-sp7021.h         | 112 ++++++++++++++++++
 3 files changed, 152 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..1ce7e41d8
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.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/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
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    clkc: clkc@9c000000 {
+      compatible = "sunplus,sp7021-clkc";
+      #clock-cells = <1>;
+      reg = <0x9c000000 0x280>;
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 6caffd6d0..90ebb823f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2661,8 +2661,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..1ae9c4083
--- /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 SYSTEM		0x10
+#define RTC			0x12
+#define IOCTL		0x13
+#define IOP			0x14
+#define OTPRX		0x15
+#define NOC			0x16
+#define BR			0x17
+#define RBUS_L00	0x18
+#define SPIFL		0x19
+#define SDCTRL0		0x1a
+#define PERI0		0x1b
+#define A926		0x1d
+#define UMCTL2		0x1e
+#define PERI1		0x1f
+
+#define DDR_PHY0	0x20
+#define ACHIP		0x22
+#define STC0		0x24
+#define STC_AV0		0x25
+#define STC_AV1		0x26
+#define STC_AV2		0x27
+#define UA0			0x28
+#define UA1			0x29
+#define UA2			0x2a
+#define UA3			0x2b
+#define UA4			0x2c
+#define HWUA		0x2d
+#define DDC0		0x2e
+#define UADMA		0x2f
+
+#define CBDMA0		0x30
+#define CBDMA1		0x31
+#define SPI_COMBO_0	0x32
+#define SPI_COMBO_1	0x33
+#define SPI_COMBO_2	0x34
+#define SPI_COMBO_3	0x35
+#define AUD			0x36
+#define USBC0		0x3a
+#define USBC1		0x3b
+#define UPHY0		0x3d
+#define UPHY1		0x3e
+
+#define I2CM0		0x40
+#define I2CM1		0x41
+#define I2CM2		0x42
+#define I2CM3		0x43
+#define PMC			0x4d
+#define CARD_CTL0	0x4e
+#define CARD_CTL1	0x4f
+
+#define CARD_CTL4	0x52
+#define BCH			0x54
+#define DDFCH		0x5b
+#define CSIIW0		0x5c
+#define CSIIW1		0x5d
+#define MIPICSI0	0x5e
+#define MIPICSI1	0x5f
+
+#define HDMI_TX		0x60
+#define VPOST		0x65
+
+#define TGEN		0x70
+#define DMIX		0x71
+#define TCON		0x7a
+#define INTERRUPT	0x7f
+
+#define RGST		0x80
+#define GPIO		0x83
+#define RBUS_TOP	0x84
+
+#define MAILBOX		0x96
+#define SPIND		0x9a
+#define I2C2CBUS	0x9b
+#define SEC			0x9d
+#define DVE			0x9e
+#define GPOST0		0x9f
+
+#define OSD0		0xa0
+#define DISP_PWM	0xa2
+#define UADBG		0xa3
+#define DUMMY_MASTER	0xa4
+#define FIO_CTL		0xa5
+#define FPGA		0xa6
+#define L2SW		0xa7
+#define ICM			0xa8
+#define AXI_GLOBAL	0xa9
+
+#define CLK_MAX		0xb0
+
+#endif
-- 
2.33.1


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

* [PATCH v2 6/8] clk: Add Sunplus SP7021 clock driver
  2021-10-29  8:44 ` Qin Jian
@ 2021-10-29  8:44   ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-10-29  8:44 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, tglx, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add clock driver for Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 MAINTAINERS              |   1 +
 drivers/clk/Kconfig      |   8 +
 drivers/clk/Makefile     |   1 +
 drivers/clk/clk-sp7021.c | 770 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 780 insertions(+)
 create mode 100644 drivers/clk/clk-sp7021.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 90ebb823f..5069f552f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2663,6 +2663,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 c5b3dc973..e2494c2aa 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -334,6 +334,14 @@ config COMMON_CLK_VC5
 	  This driver supports the IDT VersaClock 5 and VersaClock 6
 	  programmable clock generators.
 
+config COMMON_CLK_SP7021
+	def_bool OF && COMMON_CLK && SOC_SP7021
+	help
+	  This driver supports the Sunplus SP7021 SoC clocks.
+	  It implemented 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 e42312121..f15bb5070 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -60,6 +60,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..39ff84825
--- /dev/null
+++ b/drivers/clk/clk-sp7021.c
@@ -0,0 +1,770 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ *       All rights reserved.
+ */
+//#define DEBUG
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <dt-bindings/clock/sp-sp7021.h>
+
+//#define TRACE	pr_info("### %s:%d (%d)\n", __func__, __LINE__, (clk->reg - REG(4, 0)) / 4)
+#define TRACE
+
+#ifndef clk_readl
+#define clk_readl  readl
+#define clk_writel writel
+#endif
+
+#define MASK_SET(shift, width, value) \
+({ \
+	u32 m = ((1 << (width)) - 1) << (shift); \
+	(m << 16) | (((value) << (shift)) & m); \
+})
+#define MASK_GET(shift, width, value)	(((value) >> (shift)) & ((1 << (width)) - 1))
+
+#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)
+
+#define EXTCLK		"extclk"
+
+/* 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
+};
+
+struct sp_pll {
+	struct clk_hw	hw;
+	void __iomem	*reg;
+	spinlock_t	*lock;
+	int		pd_bit;		/* power down bit idx */
+	int		bp_bit;		/* bypass bit idx */
+	unsigned long	brate;		/* base rate, FIXME: replace brate with muldiv */
+	int		div_shift;
+	int		div_width;
+	u32		p[P_MAX];	/* for hold PLLTV/PLLA parameters */
+};
+#define to_sp_pll(_hw)	container_of(_hw, struct sp_pll, hw)
+
+#define clk_regs	(moon_regs + 0x000) /* G0 ~ CLKEN */
+#define pll_regs	(moon_regs + 0x200) /* G4 ~ PLL */
+static void __iomem *moon_regs;
+
+#define P_EXTCLK	(1 << 16)
+static const char * const parents[] = {
+	"pllsys",
+	"extclk",
+};
+
+/* FIXME: parent clk incorrect cause clk_get_rate got error value */
+static const u32 gates[] = {
+	SYSTEM,
+	RTC,
+	IOCTL,
+	IOP,
+	OTPRX,
+	NOC,
+	BR,
+	RBUS_L00,
+	SPIFL,
+	SDCTRL0,
+	PERI0 | P_EXTCLK,
+	A926,
+	UMCTL2,
+	PERI1 | P_EXTCLK,
+
+	DDR_PHY0,
+	ACHIP,
+	STC0,
+	STC_AV0,
+	STC_AV1,
+	STC_AV2,
+	UA0 | P_EXTCLK,
+	UA1 | P_EXTCLK,
+	UA2 | P_EXTCLK,
+	UA3 | P_EXTCLK,
+	UA4 | P_EXTCLK,
+	HWUA | P_EXTCLK,
+	DDC0,
+	UADMA | P_EXTCLK,
+
+	CBDMA0,
+	CBDMA1,
+	SPI_COMBO_0,
+	SPI_COMBO_1,
+	SPI_COMBO_2,
+	SPI_COMBO_3,
+	AUD,
+	USBC0,
+	USBC1,
+	UPHY0,
+	UPHY1,
+
+	I2CM0,
+	I2CM1,
+	I2CM2,
+	I2CM3,
+	PMC,
+	CARD_CTL0,
+	CARD_CTL1,
+
+	CARD_CTL4,
+	BCH,
+	DDFCH,
+	CSIIW0,
+	CSIIW1,
+	MIPICSI0,
+	MIPICSI1,
+
+	HDMI_TX,
+	VPOST,
+
+	TGEN,
+	DMIX,
+	TCON,
+	INTERRUPT,
+
+	RGST,
+	GPIO,
+	RBUS_TOP,
+
+	MAILBOX,
+	SPIND,
+	I2C2CBUS,
+	SEC,
+	GPOST0,
+	DVE,
+
+	OSD0,
+	DISP_PWM,
+	UADBG,
+	DUMMY_MASTER,
+	FIO_CTL,
+	FPGA,
+	L2SW,
+	ICM,
+	AXI_GLOBAL,
+};
+static struct clk *clks[CLK_MAX];
+static struct clk_onecell_data clk_data;
+
+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 *******************************************/
+
+//#define PLLTV_STEP_DIR (?) /* Unit: HZ */
+
+/* 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;
+#ifdef PLLTV_STEP_DIR
+	u32 step = (PLLTV_STEP_DIR > 0) ? PLLTV_STEP_DIR : -PLLTV_STEP_DIR;
+	int calc_times = 1000000 / step;
+#endif
+	unsigned long fvco, nf;
+
+	TRACE;
+
+	/* check freq */
+	if (freq < F_MIN) {
+		pr_warn("[%s:%d] freq:%lu < F_MIN:%lu, round up\n",
+			__func__, __LINE__, freq, F_MIN);
+		freq = F_MIN;
+	} else if (freq > F_MAX) {
+		pr_warn("[%s:%d] freq:%lu > F_MAX:%lu, round down\n",
+			__func__, __LINE__, freq, F_MAX);
+		freq = F_MAX;
+	}
+
+#ifdef PLLTV_STEP_DIR
+	if ((freq % step) != 0)
+		freq += step - (freq % step) + ((PLLTV_STEP_DIR > 0) ? 0 : PLLTV_STEP_DIR);
+#endif
+
+#ifdef PLLTV_STEP_DIR
+CALC:
+	if (!calc_times) {
+		pr_err("[%s:%d] freq:%lu out of recalc times\n", __func__, __LINE__, freq);
+		return -ETIMEOUT;
+	}
+#endif
+
+	/* 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) {
+#ifdef PLLTV_STEP_DIR
+		freq += PLLTV_STEP_DIR;
+		calc_times--;
+		goto CALC;
+#else
+		pr_err("[%s:%d] freq:%lu not found a valid setting\n", __func__, __LINE__, freq);
+		return -EINVAL;
+#endif
+	}
+
+	/* save parameters */
+	clk->p[SEL_FRA] = 0;
+	clk->p[DIVR]    = r;
+	clk->p[DIVN]    = n;
+	clk->p[DIVM]    = m;
+
+	pr_info("[%s:%d]   M:%u N:%u R:%u   CKREF:%lu  FVCO:%lu  FCKOUT:%lu\n",
+		__func__, __LINE__, m, n, r, (fvco / m), fvco, freq);
+
+	return freq;
+}
+
+/* parameters for PLLTV fractional divider */
+/* FIXME: better parameter naming */
+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 diff_min_quotient = 210000000, diff_min_remainder = 0;
+	u32 diff_min_sign = 0;
+	unsigned long fvco, nf, f, fout = 0;
+	int sdm, ph;
+
+	TRACE;
+	/* check freq */
+	if (freq < F_MIN) {
+		pr_warn("[%s:%d] freq:%lu < F_MIN:%lu, round up\n",
+			__func__, __LINE__, freq, F_MIN);
+		freq = F_MIN;
+	} else if (freq > F_MAX) {
+		pr_warn("[%s:%d] freq:%lu > F_MAX:%lu, round down\n",
+			__func__, __LINE__, freq, F_MAX);
+		freq = F_MAX;
+	}
+
+	/* DIVR 0~3 */
+	for (r = 0; r <= 3; r++) {
+		fvco = freq << r;
+		if (fvco <= FVCO_MAX)
+			break;
+	}
+	pr_info("freq:%lu fvco:%lu R:%u\n", freq, fvco, r);
+	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 diff_freq;
+				u32 diff_freq_quotient = 0, diff_freq_remainder = 0;
+				u32 diff_freq_sign = 0; /* 0:Positive number, 1:Negative number */
+
+				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)
+					diff_freq = (f * (nint + pp[2]) / pp[0]) -
+								(f * (mod - nfra) / mod / pp[4]);
+				else
+					diff_freq = (f * (nint) / pp[0]);
+
+				diff_freq_quotient  = diff_freq / m;
+				diff_freq_remainder = ((diff_freq % m) * 1000) / m;
+
+				pr_info("m = %d N.f = %2d.%03d%03d, nfra = %d/%d  fout = %u\n",
+					m, nint, (nfra * 1000) / mod,
+					(((nfra * 1000) % mod) * 1000) / mod,
+					nfra, mod, diff_freq_quotient);
+
+				if (freq > diff_freq_quotient) {
+					diff_freq_quotient  = freq - diff_freq_quotient - 1;
+					diff_freq_remainder = 1000 - diff_freq_remainder;
+					diff_freq_sign = 1;
+				} else {
+					diff_freq_quotient = diff_freq_quotient - freq;
+					diff_freq_sign = 0;
+				}
+
+				if ((diff_min_quotient > diff_freq_quotient) ||
+					((diff_min_quotient == diff_freq_quotient) &&
+					(diff_min_remainder > diff_freq_remainder))) {
+
+					/* found a closer freq, save parameters */
+					TRACE;
+					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 = diff_freq / m;
+					diff_min_quotient = diff_freq_quotient;
+					diff_min_remainder = diff_freq_remainder;
+					diff_min_sign = diff_freq_sign;
+				}
+			}
+		}
+	}
+
+	if (!fout) {
+		pr_err("[%s:%d] freq:%lu not found a valid setting\n", __func__, __LINE__, freq);
+		return -EINVAL;
+	}
+
+	//pr_info("MOD:%u PH_SEL:%u NFRA:%u M:%u R:%u\n",
+	//	mods[clk->p[SDM_MOD]], clk->p[PH_SEL], clk->p[NFRA], clk->p[DIVM], clk->p[DIVR]);
+
+	pr_info("[%s:%d] real out:%lu/%lu Hz(%u, %u, sign %u)\n",
+		__func__, __LINE__, fout, freq,
+		diff_min_quotient, diff_min_remainder, diff_min_sign);
+
+	return fout;
+}
+
+static long plltv_div(struct sp_pll *clk, unsigned long freq)
+{
+	TRACE;
+	if (freq % 100)
+		return plltv_fractional_div(clk, freq);
+	else
+		return plltv_integer_div(clk, freq);
+}
+
+static void plltv_set_rate(struct sp_pll *clk)
+{
+	u32 reg;
+
+	//pr_info("MOD:%u PH_SEL:%u NFRA:%u M:%u R:%u\n",
+	//	mods[clk->p[SDM_MOD]], clk->p[PH_SEL], clk->p[NFRA], clk->p[DIVM], clk->p[DIVR]);
+	reg  = MASK_SET(1, 1, clk->p[SEL_FRA]);
+	reg |= MASK_SET(2, 1, clk->p[SDM_MOD]);
+	reg |= MASK_SET(4, 1, clk->p[PH_SEL]);
+	reg |= MASK_SET(6, 7, clk->p[NFRA]);
+	clk_writel(reg, clk->reg);
+
+	reg  = MASK_SET(7, 2, clk->p[DIVR]);
+	clk_writel(reg, clk->reg + 4);
+
+	reg  = MASK_SET(0, 8, clk->p[DIVN] - 1);
+	reg |= MASK_SET(8, 7, clk->p[DIVM] - 1);
+	clk_writel(reg, clk->reg + 8);
+}
+
+/******************************************** PLL_A ********************************************/
+
+/* from Q628_PLLs_REG_setting.xlsx */
+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++) {
+		clk_writel(0xffff0000 | pp[i], clk->reg + (i * 4));
+		pr_info("%04x\n", pp[i]);
+	}
+}
+
+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;
+
+	TRACE;
+	//pr_info("round_rate: %lu %lu\n", rate, *prate);
+
+	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 = clk_readl(clk->reg);
+	unsigned long ret;
+
+	//TRACE;
+	if (reg & BIT(clk->bp_bit))
+		ret = prate; /* bypass */
+	else if (clk->div_width == DIV_A) {
+		ret = pa[clk->p[0]].rate;
+		//reg = clk_readl(clk->reg + 12); // G4.10 K_SDM_A
+	} else if (clk->div_width == DIV_TV) {
+		u32 m, r, reg2;
+
+		r = MASK_GET(7, 2, clk_readl(clk->reg + 4));
+		reg2 = clk_readl(clk->reg + 8);
+		m = MASK_GET(8, 7, reg2) + 1;
+
+		if (reg & BIT(1)) { /* SEL_FRA */
+			/* fractional divider */
+			u32 sdm  = MASK_GET(2, 1, reg);
+			u32 ph   = MASK_GET(4, 1, reg);
+			u32 nfra = MASK_GET(6, 7, 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 = MASK_GET(0, 8, reg2) + 1;
+
+			ret = (prate / m * n) >> r;
+		}
+	} else {
+		u32 fbdiv = MASK_GET(clk->div_shift, clk->div_width, reg) + 1;
+
+		ret = clk->brate * fbdiv;
+	}
+	//pr_info("recalc_rate: %lu -> %lu\n", prate, ret);
+
+	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;
+
+	//TRACE;
+	pr_info("set_rate: %lu -> %lu\n", prate, rate);
+
+	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);
+
+		reg |= MASK_SET(clk->div_shift, clk->div_width, fbdiv - 1);
+	}
+
+	clk_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;
+
+	TRACE;
+	spin_lock_irqsave(clk->lock, flags);
+	clk_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;
+
+	TRACE;
+	spin_lock_irqsave(clk->lock, flags);
+	clk_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 clk_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,
+};
+
+struct clk *clk_register_sp_pll(const char *name, const char *parent,
+		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 *clk;
+	//unsigned long flags = 0;
+	struct clk_init_data initd = {
+		.name = name,
+		.parent_names = &parent,
+		.ops = (bp_bit >= 0) ? &sp_pll_ops : &sp_pll_sub_ops,
+		.num_parents = 1,
+		.flags = CLK_IGNORE_UNUSED
+	};
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	if (reg == PLLSYS_CTL)
+		initd.flags |= CLK_IS_CRITICAL;
+
+	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;
+
+	clk = clk_register(NULL, &pll->hw);
+	if (WARN_ON(IS_ERR(clk))) {
+		kfree(pll);
+	} else {
+		pr_info("%-20s%lu\n", name, clk_get_rate(clk));
+		clk_register_clkdev(clk, NULL, name);
+	}
+
+	return clk;
+}
+
+static void __init sp_clk_setup(struct device_node *np)
+{
+	int i, j;
+
+	pr_info("sp-clkc init\n");
+
+	moon_regs = of_iomap(np, 0);
+	if (WARN_ON(!moon_regs)) {
+		pr_warn("sp-clkc regs missing.\n");
+		return; // -EIO
+	}
+
+	/* TODO: PLLs initial */
+
+	/* PLL_A */
+	clks[PLL_A] = clk_register_sp_pll("plla", EXTCLK,
+			PLLA_CTL, 11, 12, 27000000, 0, DIV_A, &plla_lock);
+
+	/* PLL_E */
+	clks[PLL_E] = clk_register_sp_pll("plle", EXTCLK,
+			PLLE_CTL, 6, 2, 50000000, 0, 0, &plle_lock);
+	clks[PLL_E_2P5] = clk_register_sp_pll("plle_2p5", "plle",
+			PLLE_CTL, 13, -1, 2500000, 0, 0, &plle_lock);
+	clks[PLL_E_25] = clk_register_sp_pll("plle_25", "plle",
+			PLLE_CTL, 12, -1, 25000000, 0, 0, &plle_lock);
+	clks[PLL_E_112P5] = clk_register_sp_pll("plle_112p5", "plle",
+			PLLE_CTL, 11, -1, 112500000, 0, 0, &plle_lock);
+
+	/* PLL_F */
+	clks[PLL_F] = clk_register_sp_pll("pllf", EXTCLK,
+			PLLF_CTL, 0, 10, 13500000, 1, 4, &pllf_lock);
+
+	/* PLL_TV */
+	clks[PLL_TV] = clk_register_sp_pll("plltv", EXTCLK,
+			PLLTV_CTL, 0, 15, 27000000, 0, DIV_TV, &plltv_lock);
+	clks[PLL_TV_A] = clk_register_divider(NULL, "plltv_a", "plltv", 0,
+			PLLTV_CTL + 4, 5, 1,
+			CLK_DIVIDER_POWER_OF_TWO, &plltv_lock);
+	clk_register_clkdev(clks[PLL_TV_A], NULL, "plltv_a");
+
+	/* PLL_SYS */
+	clks[PLL_SYS] = clk_register_sp_pll("pllsys", EXTCLK,
+			PLLSYS_CTL, 10, 9, 13500000, 0, 4, &pllsys_lock);
+
+	/* gates */
+	for (i = 0; i < ARRAY_SIZE(gates); i++) {
+		char s[10];
+
+		j = gates[i] & 0xffff;
+		sprintf(s, "clken%02x", j);
+		clks[j] = clk_register_gate(NULL, s, parents[gates[i] >> 16], CLK_IGNORE_UNUSED,
+			clk_regs + (j >> 4) * 4, j & 0x0f,
+			CLK_GATE_HIWORD_MASK, NULL);
+	}
+
+	clk_data.clks = clks;
+	clk_data.clk_num = ARRAY_SIZE(clks);
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+
+CLK_OF_DECLARE(sp_clkc, "sunplus,sp7021-clkc", sp_clk_setup);
+
+MODULE_AUTHOR("Qin Jian <qinjian@cqplus1.com>");
+MODULE_DESCRIPTION("Sunplus SP7021 Clock Driver");
+MODULE_LICENSE("GPL v2");
-- 
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] 124+ messages in thread

* [PATCH v2 6/8] clk: Add Sunplus SP7021 clock driver
@ 2021-10-29  8:44   ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-10-29  8:44 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, tglx, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add clock driver for Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 MAINTAINERS              |   1 +
 drivers/clk/Kconfig      |   8 +
 drivers/clk/Makefile     |   1 +
 drivers/clk/clk-sp7021.c | 770 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 780 insertions(+)
 create mode 100644 drivers/clk/clk-sp7021.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 90ebb823f..5069f552f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2663,6 +2663,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 c5b3dc973..e2494c2aa 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -334,6 +334,14 @@ config COMMON_CLK_VC5
 	  This driver supports the IDT VersaClock 5 and VersaClock 6
 	  programmable clock generators.
 
+config COMMON_CLK_SP7021
+	def_bool OF && COMMON_CLK && SOC_SP7021
+	help
+	  This driver supports the Sunplus SP7021 SoC clocks.
+	  It implemented 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 e42312121..f15bb5070 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -60,6 +60,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..39ff84825
--- /dev/null
+++ b/drivers/clk/clk-sp7021.c
@@ -0,0 +1,770 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ *       All rights reserved.
+ */
+//#define DEBUG
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <dt-bindings/clock/sp-sp7021.h>
+
+//#define TRACE	pr_info("### %s:%d (%d)\n", __func__, __LINE__, (clk->reg - REG(4, 0)) / 4)
+#define TRACE
+
+#ifndef clk_readl
+#define clk_readl  readl
+#define clk_writel writel
+#endif
+
+#define MASK_SET(shift, width, value) \
+({ \
+	u32 m = ((1 << (width)) - 1) << (shift); \
+	(m << 16) | (((value) << (shift)) & m); \
+})
+#define MASK_GET(shift, width, value)	(((value) >> (shift)) & ((1 << (width)) - 1))
+
+#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)
+
+#define EXTCLK		"extclk"
+
+/* 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
+};
+
+struct sp_pll {
+	struct clk_hw	hw;
+	void __iomem	*reg;
+	spinlock_t	*lock;
+	int		pd_bit;		/* power down bit idx */
+	int		bp_bit;		/* bypass bit idx */
+	unsigned long	brate;		/* base rate, FIXME: replace brate with muldiv */
+	int		div_shift;
+	int		div_width;
+	u32		p[P_MAX];	/* for hold PLLTV/PLLA parameters */
+};
+#define to_sp_pll(_hw)	container_of(_hw, struct sp_pll, hw)
+
+#define clk_regs	(moon_regs + 0x000) /* G0 ~ CLKEN */
+#define pll_regs	(moon_regs + 0x200) /* G4 ~ PLL */
+static void __iomem *moon_regs;
+
+#define P_EXTCLK	(1 << 16)
+static const char * const parents[] = {
+	"pllsys",
+	"extclk",
+};
+
+/* FIXME: parent clk incorrect cause clk_get_rate got error value */
+static const u32 gates[] = {
+	SYSTEM,
+	RTC,
+	IOCTL,
+	IOP,
+	OTPRX,
+	NOC,
+	BR,
+	RBUS_L00,
+	SPIFL,
+	SDCTRL0,
+	PERI0 | P_EXTCLK,
+	A926,
+	UMCTL2,
+	PERI1 | P_EXTCLK,
+
+	DDR_PHY0,
+	ACHIP,
+	STC0,
+	STC_AV0,
+	STC_AV1,
+	STC_AV2,
+	UA0 | P_EXTCLK,
+	UA1 | P_EXTCLK,
+	UA2 | P_EXTCLK,
+	UA3 | P_EXTCLK,
+	UA4 | P_EXTCLK,
+	HWUA | P_EXTCLK,
+	DDC0,
+	UADMA | P_EXTCLK,
+
+	CBDMA0,
+	CBDMA1,
+	SPI_COMBO_0,
+	SPI_COMBO_1,
+	SPI_COMBO_2,
+	SPI_COMBO_3,
+	AUD,
+	USBC0,
+	USBC1,
+	UPHY0,
+	UPHY1,
+
+	I2CM0,
+	I2CM1,
+	I2CM2,
+	I2CM3,
+	PMC,
+	CARD_CTL0,
+	CARD_CTL1,
+
+	CARD_CTL4,
+	BCH,
+	DDFCH,
+	CSIIW0,
+	CSIIW1,
+	MIPICSI0,
+	MIPICSI1,
+
+	HDMI_TX,
+	VPOST,
+
+	TGEN,
+	DMIX,
+	TCON,
+	INTERRUPT,
+
+	RGST,
+	GPIO,
+	RBUS_TOP,
+
+	MAILBOX,
+	SPIND,
+	I2C2CBUS,
+	SEC,
+	GPOST0,
+	DVE,
+
+	OSD0,
+	DISP_PWM,
+	UADBG,
+	DUMMY_MASTER,
+	FIO_CTL,
+	FPGA,
+	L2SW,
+	ICM,
+	AXI_GLOBAL,
+};
+static struct clk *clks[CLK_MAX];
+static struct clk_onecell_data clk_data;
+
+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 *******************************************/
+
+//#define PLLTV_STEP_DIR (?) /* Unit: HZ */
+
+/* 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;
+#ifdef PLLTV_STEP_DIR
+	u32 step = (PLLTV_STEP_DIR > 0) ? PLLTV_STEP_DIR : -PLLTV_STEP_DIR;
+	int calc_times = 1000000 / step;
+#endif
+	unsigned long fvco, nf;
+
+	TRACE;
+
+	/* check freq */
+	if (freq < F_MIN) {
+		pr_warn("[%s:%d] freq:%lu < F_MIN:%lu, round up\n",
+			__func__, __LINE__, freq, F_MIN);
+		freq = F_MIN;
+	} else if (freq > F_MAX) {
+		pr_warn("[%s:%d] freq:%lu > F_MAX:%lu, round down\n",
+			__func__, __LINE__, freq, F_MAX);
+		freq = F_MAX;
+	}
+
+#ifdef PLLTV_STEP_DIR
+	if ((freq % step) != 0)
+		freq += step - (freq % step) + ((PLLTV_STEP_DIR > 0) ? 0 : PLLTV_STEP_DIR);
+#endif
+
+#ifdef PLLTV_STEP_DIR
+CALC:
+	if (!calc_times) {
+		pr_err("[%s:%d] freq:%lu out of recalc times\n", __func__, __LINE__, freq);
+		return -ETIMEOUT;
+	}
+#endif
+
+	/* 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) {
+#ifdef PLLTV_STEP_DIR
+		freq += PLLTV_STEP_DIR;
+		calc_times--;
+		goto CALC;
+#else
+		pr_err("[%s:%d] freq:%lu not found a valid setting\n", __func__, __LINE__, freq);
+		return -EINVAL;
+#endif
+	}
+
+	/* save parameters */
+	clk->p[SEL_FRA] = 0;
+	clk->p[DIVR]    = r;
+	clk->p[DIVN]    = n;
+	clk->p[DIVM]    = m;
+
+	pr_info("[%s:%d]   M:%u N:%u R:%u   CKREF:%lu  FVCO:%lu  FCKOUT:%lu\n",
+		__func__, __LINE__, m, n, r, (fvco / m), fvco, freq);
+
+	return freq;
+}
+
+/* parameters for PLLTV fractional divider */
+/* FIXME: better parameter naming */
+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 diff_min_quotient = 210000000, diff_min_remainder = 0;
+	u32 diff_min_sign = 0;
+	unsigned long fvco, nf, f, fout = 0;
+	int sdm, ph;
+
+	TRACE;
+	/* check freq */
+	if (freq < F_MIN) {
+		pr_warn("[%s:%d] freq:%lu < F_MIN:%lu, round up\n",
+			__func__, __LINE__, freq, F_MIN);
+		freq = F_MIN;
+	} else if (freq > F_MAX) {
+		pr_warn("[%s:%d] freq:%lu > F_MAX:%lu, round down\n",
+			__func__, __LINE__, freq, F_MAX);
+		freq = F_MAX;
+	}
+
+	/* DIVR 0~3 */
+	for (r = 0; r <= 3; r++) {
+		fvco = freq << r;
+		if (fvco <= FVCO_MAX)
+			break;
+	}
+	pr_info("freq:%lu fvco:%lu R:%u\n", freq, fvco, r);
+	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 diff_freq;
+				u32 diff_freq_quotient = 0, diff_freq_remainder = 0;
+				u32 diff_freq_sign = 0; /* 0:Positive number, 1:Negative number */
+
+				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)
+					diff_freq = (f * (nint + pp[2]) / pp[0]) -
+								(f * (mod - nfra) / mod / pp[4]);
+				else
+					diff_freq = (f * (nint) / pp[0]);
+
+				diff_freq_quotient  = diff_freq / m;
+				diff_freq_remainder = ((diff_freq % m) * 1000) / m;
+
+				pr_info("m = %d N.f = %2d.%03d%03d, nfra = %d/%d  fout = %u\n",
+					m, nint, (nfra * 1000) / mod,
+					(((nfra * 1000) % mod) * 1000) / mod,
+					nfra, mod, diff_freq_quotient);
+
+				if (freq > diff_freq_quotient) {
+					diff_freq_quotient  = freq - diff_freq_quotient - 1;
+					diff_freq_remainder = 1000 - diff_freq_remainder;
+					diff_freq_sign = 1;
+				} else {
+					diff_freq_quotient = diff_freq_quotient - freq;
+					diff_freq_sign = 0;
+				}
+
+				if ((diff_min_quotient > diff_freq_quotient) ||
+					((diff_min_quotient == diff_freq_quotient) &&
+					(diff_min_remainder > diff_freq_remainder))) {
+
+					/* found a closer freq, save parameters */
+					TRACE;
+					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 = diff_freq / m;
+					diff_min_quotient = diff_freq_quotient;
+					diff_min_remainder = diff_freq_remainder;
+					diff_min_sign = diff_freq_sign;
+				}
+			}
+		}
+	}
+
+	if (!fout) {
+		pr_err("[%s:%d] freq:%lu not found a valid setting\n", __func__, __LINE__, freq);
+		return -EINVAL;
+	}
+
+	//pr_info("MOD:%u PH_SEL:%u NFRA:%u M:%u R:%u\n",
+	//	mods[clk->p[SDM_MOD]], clk->p[PH_SEL], clk->p[NFRA], clk->p[DIVM], clk->p[DIVR]);
+
+	pr_info("[%s:%d] real out:%lu/%lu Hz(%u, %u, sign %u)\n",
+		__func__, __LINE__, fout, freq,
+		diff_min_quotient, diff_min_remainder, diff_min_sign);
+
+	return fout;
+}
+
+static long plltv_div(struct sp_pll *clk, unsigned long freq)
+{
+	TRACE;
+	if (freq % 100)
+		return plltv_fractional_div(clk, freq);
+	else
+		return plltv_integer_div(clk, freq);
+}
+
+static void plltv_set_rate(struct sp_pll *clk)
+{
+	u32 reg;
+
+	//pr_info("MOD:%u PH_SEL:%u NFRA:%u M:%u R:%u\n",
+	//	mods[clk->p[SDM_MOD]], clk->p[PH_SEL], clk->p[NFRA], clk->p[DIVM], clk->p[DIVR]);
+	reg  = MASK_SET(1, 1, clk->p[SEL_FRA]);
+	reg |= MASK_SET(2, 1, clk->p[SDM_MOD]);
+	reg |= MASK_SET(4, 1, clk->p[PH_SEL]);
+	reg |= MASK_SET(6, 7, clk->p[NFRA]);
+	clk_writel(reg, clk->reg);
+
+	reg  = MASK_SET(7, 2, clk->p[DIVR]);
+	clk_writel(reg, clk->reg + 4);
+
+	reg  = MASK_SET(0, 8, clk->p[DIVN] - 1);
+	reg |= MASK_SET(8, 7, clk->p[DIVM] - 1);
+	clk_writel(reg, clk->reg + 8);
+}
+
+/******************************************** PLL_A ********************************************/
+
+/* from Q628_PLLs_REG_setting.xlsx */
+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++) {
+		clk_writel(0xffff0000 | pp[i], clk->reg + (i * 4));
+		pr_info("%04x\n", pp[i]);
+	}
+}
+
+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;
+
+	TRACE;
+	//pr_info("round_rate: %lu %lu\n", rate, *prate);
+
+	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 = clk_readl(clk->reg);
+	unsigned long ret;
+
+	//TRACE;
+	if (reg & BIT(clk->bp_bit))
+		ret = prate; /* bypass */
+	else if (clk->div_width == DIV_A) {
+		ret = pa[clk->p[0]].rate;
+		//reg = clk_readl(clk->reg + 12); // G4.10 K_SDM_A
+	} else if (clk->div_width == DIV_TV) {
+		u32 m, r, reg2;
+
+		r = MASK_GET(7, 2, clk_readl(clk->reg + 4));
+		reg2 = clk_readl(clk->reg + 8);
+		m = MASK_GET(8, 7, reg2) + 1;
+
+		if (reg & BIT(1)) { /* SEL_FRA */
+			/* fractional divider */
+			u32 sdm  = MASK_GET(2, 1, reg);
+			u32 ph   = MASK_GET(4, 1, reg);
+			u32 nfra = MASK_GET(6, 7, 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 = MASK_GET(0, 8, reg2) + 1;
+
+			ret = (prate / m * n) >> r;
+		}
+	} else {
+		u32 fbdiv = MASK_GET(clk->div_shift, clk->div_width, reg) + 1;
+
+		ret = clk->brate * fbdiv;
+	}
+	//pr_info("recalc_rate: %lu -> %lu\n", prate, ret);
+
+	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;
+
+	//TRACE;
+	pr_info("set_rate: %lu -> %lu\n", prate, rate);
+
+	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);
+
+		reg |= MASK_SET(clk->div_shift, clk->div_width, fbdiv - 1);
+	}
+
+	clk_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;
+
+	TRACE;
+	spin_lock_irqsave(clk->lock, flags);
+	clk_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;
+
+	TRACE;
+	spin_lock_irqsave(clk->lock, flags);
+	clk_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 clk_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,
+};
+
+struct clk *clk_register_sp_pll(const char *name, const char *parent,
+		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 *clk;
+	//unsigned long flags = 0;
+	struct clk_init_data initd = {
+		.name = name,
+		.parent_names = &parent,
+		.ops = (bp_bit >= 0) ? &sp_pll_ops : &sp_pll_sub_ops,
+		.num_parents = 1,
+		.flags = CLK_IGNORE_UNUSED
+	};
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	if (reg == PLLSYS_CTL)
+		initd.flags |= CLK_IS_CRITICAL;
+
+	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;
+
+	clk = clk_register(NULL, &pll->hw);
+	if (WARN_ON(IS_ERR(clk))) {
+		kfree(pll);
+	} else {
+		pr_info("%-20s%lu\n", name, clk_get_rate(clk));
+		clk_register_clkdev(clk, NULL, name);
+	}
+
+	return clk;
+}
+
+static void __init sp_clk_setup(struct device_node *np)
+{
+	int i, j;
+
+	pr_info("sp-clkc init\n");
+
+	moon_regs = of_iomap(np, 0);
+	if (WARN_ON(!moon_regs)) {
+		pr_warn("sp-clkc regs missing.\n");
+		return; // -EIO
+	}
+
+	/* TODO: PLLs initial */
+
+	/* PLL_A */
+	clks[PLL_A] = clk_register_sp_pll("plla", EXTCLK,
+			PLLA_CTL, 11, 12, 27000000, 0, DIV_A, &plla_lock);
+
+	/* PLL_E */
+	clks[PLL_E] = clk_register_sp_pll("plle", EXTCLK,
+			PLLE_CTL, 6, 2, 50000000, 0, 0, &plle_lock);
+	clks[PLL_E_2P5] = clk_register_sp_pll("plle_2p5", "plle",
+			PLLE_CTL, 13, -1, 2500000, 0, 0, &plle_lock);
+	clks[PLL_E_25] = clk_register_sp_pll("plle_25", "plle",
+			PLLE_CTL, 12, -1, 25000000, 0, 0, &plle_lock);
+	clks[PLL_E_112P5] = clk_register_sp_pll("plle_112p5", "plle",
+			PLLE_CTL, 11, -1, 112500000, 0, 0, &plle_lock);
+
+	/* PLL_F */
+	clks[PLL_F] = clk_register_sp_pll("pllf", EXTCLK,
+			PLLF_CTL, 0, 10, 13500000, 1, 4, &pllf_lock);
+
+	/* PLL_TV */
+	clks[PLL_TV] = clk_register_sp_pll("plltv", EXTCLK,
+			PLLTV_CTL, 0, 15, 27000000, 0, DIV_TV, &plltv_lock);
+	clks[PLL_TV_A] = clk_register_divider(NULL, "plltv_a", "plltv", 0,
+			PLLTV_CTL + 4, 5, 1,
+			CLK_DIVIDER_POWER_OF_TWO, &plltv_lock);
+	clk_register_clkdev(clks[PLL_TV_A], NULL, "plltv_a");
+
+	/* PLL_SYS */
+	clks[PLL_SYS] = clk_register_sp_pll("pllsys", EXTCLK,
+			PLLSYS_CTL, 10, 9, 13500000, 0, 4, &pllsys_lock);
+
+	/* gates */
+	for (i = 0; i < ARRAY_SIZE(gates); i++) {
+		char s[10];
+
+		j = gates[i] & 0xffff;
+		sprintf(s, "clken%02x", j);
+		clks[j] = clk_register_gate(NULL, s, parents[gates[i] >> 16], CLK_IGNORE_UNUSED,
+			clk_regs + (j >> 4) * 4, j & 0x0f,
+			CLK_GATE_HIWORD_MASK, NULL);
+	}
+
+	clk_data.clks = clks;
+	clk_data.clk_num = ARRAY_SIZE(clks);
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+
+CLK_OF_DECLARE(sp_clkc, "sunplus,sp7021-clkc", sp_clk_setup);
+
+MODULE_AUTHOR("Qin Jian <qinjian@cqplus1.com>");
+MODULE_DESCRIPTION("Sunplus SP7021 Clock Driver");
+MODULE_LICENSE("GPL v2");
-- 
2.33.1


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

* [PATCH v2 7/8] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
  2021-10-29  8:44 ` Qin Jian
@ 2021-10-29  8:44   ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-10-29  8:44 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, tglx, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add documentation to describe Sunplus SP7021 interrupt controller bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../sunplus,sp7021-intc.yaml                  | 59 +++++++++++++++++++
 MAINTAINERS                                   |  2 +
 .../interrupt-controller/sp7021-intc.h        | 24 ++++++++
 3 files changed, 85 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
 create mode 100644 include/dt-bindings/interrupt-controller/sp7021-intc.h

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..185c99b5e
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
@@ -0,0 +1,59 @@
+# 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
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 2
+    description:
+      The first cell is the IRQ number, the second cell the trigger
+      type as defined in interrupt.txt in this directory.
+      The MSB of second cell also indicate route to which EXT_INT.
+
+  reg:
+    maxItems: 2
+
+  interrupts:
+    maxItems: 2
+    description:
+      EXT_INT0 & EXT_INT1, 2 interrupts references to primary interrupt
+      controller.
+
+required:
+  - compatible
+  - interrupt-controller
+  - "#interrupt-cells"
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    intc: interrupt-controller@9c000780 {
+        compatible = "sunplus,sp7021-intc";
+        interrupt-controller;
+        #interrupt-cells = <2>;
+        reg = <0x9c000780 0x80>, <0x9c000a80 0x80>;
+        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 5069f552f..be0334d6a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2662,10 +2662,12 @@ 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
 F:	include/dt-bindings/clock/sp-sp7021.h
+F:	include/dt-bindings/interrupt-controller/sp7021-intc.h
 F:	include/dt-bindings/reset/sp-sp7021.h
 
 ARM/Synaptics SoC support
diff --git a/include/dt-bindings/interrupt-controller/sp7021-intc.h b/include/dt-bindings/interrupt-controller/sp7021-intc.h
new file mode 100644
index 000000000..fa2eb8100
--- /dev/null
+++ b/include/dt-bindings/interrupt-controller/sp7021-intc.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ *       All rights reserved.
+ *
+ *
+ * This header provides constants for the SP7021 INTC
+ */
+
+#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_SP7021_INTC_H
+#define _DT_BINDINGS_INTERRUPT_CONTROLLER_SP7021_INTC_H
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/*
+ * Interrupt specifier cell 1.
+ * The flags in irq.h are valid, plus those below.
+ */
+#define SP_INTC_EXT_INT0		0x00000
+#define SP_INTC_EXT_INT1		0x01000
+#define SP_INTC_EXT_INT_MASK	0xff000
+#define SP_INTC_EXT_INT_SHFIT	12
+
+#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] 124+ messages in thread

* [PATCH v2 7/8] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
@ 2021-10-29  8:44   ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-10-29  8:44 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, tglx, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add documentation to describe Sunplus SP7021 interrupt controller bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../sunplus,sp7021-intc.yaml                  | 59 +++++++++++++++++++
 MAINTAINERS                                   |  2 +
 .../interrupt-controller/sp7021-intc.h        | 24 ++++++++
 3 files changed, 85 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
 create mode 100644 include/dt-bindings/interrupt-controller/sp7021-intc.h

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..185c99b5e
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
@@ -0,0 +1,59 @@
+# 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
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 2
+    description:
+      The first cell is the IRQ number, the second cell the trigger
+      type as defined in interrupt.txt in this directory.
+      The MSB of second cell also indicate route to which EXT_INT.
+
+  reg:
+    maxItems: 2
+
+  interrupts:
+    maxItems: 2
+    description:
+      EXT_INT0 & EXT_INT1, 2 interrupts references to primary interrupt
+      controller.
+
+required:
+  - compatible
+  - interrupt-controller
+  - "#interrupt-cells"
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    intc: interrupt-controller@9c000780 {
+        compatible = "sunplus,sp7021-intc";
+        interrupt-controller;
+        #interrupt-cells = <2>;
+        reg = <0x9c000780 0x80>, <0x9c000a80 0x80>;
+        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 5069f552f..be0334d6a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2662,10 +2662,12 @@ 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
 F:	include/dt-bindings/clock/sp-sp7021.h
+F:	include/dt-bindings/interrupt-controller/sp7021-intc.h
 F:	include/dt-bindings/reset/sp-sp7021.h
 
 ARM/Synaptics SoC support
diff --git a/include/dt-bindings/interrupt-controller/sp7021-intc.h b/include/dt-bindings/interrupt-controller/sp7021-intc.h
new file mode 100644
index 000000000..fa2eb8100
--- /dev/null
+++ b/include/dt-bindings/interrupt-controller/sp7021-intc.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ *       All rights reserved.
+ *
+ *
+ * This header provides constants for the SP7021 INTC
+ */
+
+#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_SP7021_INTC_H
+#define _DT_BINDINGS_INTERRUPT_CONTROLLER_SP7021_INTC_H
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/*
+ * Interrupt specifier cell 1.
+ * The flags in irq.h are valid, plus those below.
+ */
+#define SP_INTC_EXT_INT0		0x00000
+#define SP_INTC_EXT_INT1		0x01000
+#define SP_INTC_EXT_INT_MASK	0xff000
+#define SP_INTC_EXT_INT_SHFIT	12
+
+#endif
-- 
2.33.1


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

* [PATCH v2 8/8] irqchip: Add support for Sunplus SP7021 interrupt controller
  2021-10-29  8:44 ` Qin Jian
@ 2021-10-29  8:44   ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-10-29  8:44 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, tglx, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add interrupt 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 C-chip. C-chip adopts ARM CA7
interrupt controller (compitable = "arm,cortex-a7-gic"). It is a parent
interrupt controller of P-chip interrupt controller.

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

diff --git a/MAINTAINERS b/MAINTAINERS
index be0334d6a..bfa891d86 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2665,6 +2665,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/interrupt-controller/sp7021-intc.h
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index aca7b595c..8a58dfb88 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -602,4 +602,13 @@ config APPLE_AIC
 	  Support for the Apple Interrupt Controller found on Apple Silicon SoCs,
 	  such as the M1.
 
+config SUNPLUS_SP7021_INTC
+	bool "Sunplus SP7021 interrupt controller"
+	default SOC_SP7021
+	help
+	  Support for the Sunplus SP7021 Interrupt Controller IP core.
+	  This is used as a primary controller with SP7021 ChipP and can also
+	  be used as a secondary chained controller on SP7021 ChipC.
+	  This is selected automatically by platform config.
+
 endmenu
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index f88cbf36a..75411f654 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -116,3 +116,4 @@ obj-$(CONFIG_MACH_REALTEK_RTL)		+= irq-realtek-rtl.o
 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_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..3431ec746
--- /dev/null
+++ b/drivers/irqchip/irq-sp7021-intc.c
@@ -0,0 +1,324 @@
+// 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>
+
+#include <asm/exception.h>
+#include <dt-bindings/interrupt-controller/sp7021-intc.h>
+
+#define SP_INTC_HWIRQ_MIN     0
+#define SP_INTC_HWIRQ_MAX     223
+
+/* Interrupt G0/G1 offset */
+#define INTR_REG_SIZE		(7 * 4)
+
+#define G0_INTR_TYPE		(0)
+#define G0_INTR_POLARITY	(G0_INTR_TYPE + INTR_REG_SIZE)
+#define G0_INTR_PRIORITY	(G0_INTR_POLARITY + INTR_REG_SIZE)
+#define G0_INTR_MASK		(G0_INTR_PRIORITY + INTR_REG_SIZE)
+
+#define G1_INTR_CLR			(0)
+#define G1_MASKED_EXT1		(G1_INTR_CLR + INTR_REG_SIZE)
+#define G1_MASKED_EXT0		(G1_MASKED_EXT1 + INTR_REG_SIZE)
+#define G1_INTR_GROUP		(31 * 4)
+#define G1_INTR_MASK		(0x7F)
+#define G1_EXT1_SHIFT		(0)
+#define G1_EXT0_SHIFT		(8)
+
+static struct sp_intctl {
+	void __iomem *g0;
+	void __iomem *g1;
+	struct irq_domain *domain;
+	struct device_node *node;
+	raw_spinlock_t lock;
+	int virq[2];
+} sp_intc;
+
+/* GPIO INT EDGE BUG WORKAROUND */
+#define GPIO_INT0_HWIRQ			120
+#define GPIO_INT7_HWIRQ			127
+#define GPIO_INT_EDGE_ACTIVE	BIT(31)
+#define IS_GPIO_INT(n)	(((n) >= GPIO_INT0_HWIRQ) && ((n) <= GPIO_INT7_HWIRQ))
+/* array to hold which interrupt needs to workaround the bug
+ * INT_TYPE_NONE: no need
+ * INT_TYPE_EDGE_FALLING/INT_TYPE_EDGE_RISING: need to workaround
+ * GPIO_INT_EDGE_ACTIVING: workaround is on going
+ */
+static u32 edge_trigger[SP_INTC_HWIRQ_MAX];
+
+static struct irq_chip sp_intc_chip;
+
+static void sp_intc_assign_bit(u32 hwirq, void __iomem *base, u32 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 (edge_trigger[hwirq] != IRQ_TYPE_NONE) {
+		sp_intc_assign_bit(hwirq, sp_intc.g0 + G0_INTR_POLARITY,
+			(edge_trigger[hwirq] == IRQ_TYPE_EDGE_RISING));
+		edge_trigger[hwirq] |= GPIO_INT_EDGE_ACTIVE;
+	}
+
+	sp_intc_assign_bit(hwirq, sp_intc.g1 + G1_INTR_CLR, 1);
+}
+
+static void sp_intc_mask_irq(struct irq_data *d)
+{
+	sp_intc_assign_bit(d->hwirq, sp_intc.g0 + G0_INTR_MASK, 0);
+}
+
+static void sp_intc_unmask_irq(struct irq_data *d)
+{
+	sp_intc_assign_bit(d->hwirq, sp_intc.g0 + G0_INTR_MASK, 1);
+}
+
+static void sp_intc_set_priority(u32 hwirq, u32 priority)
+{
+	sp_intc_assign_bit(hwirq, sp_intc.g0 + G0_INTR_PRIORITY, priority);
+}
+
+static int sp_intc_set_type(struct irq_data *d, unsigned int type)
+{
+	u32 intr_type;		/* 0: level			1: edge */
+	u32 intr_polarity;	/* 0: high/rising	1: low/falling */
+	u32 hwirq = d->hwirq;
+
+	/* update the chip/handler */
+	if (type & IRQ_TYPE_LEVEL_MASK)
+		irq_set_chip_handler_name_locked(d, &sp_intc_chip,
+						   handle_level_irq, NULL);
+	else
+		irq_set_chip_handler_name_locked(d, &sp_intc_chip,
+						   handle_edge_irq, NULL);
+
+	edge_trigger[hwirq] = IRQ_TYPE_NONE;
+
+	if (type & IRQ_TYPE_LEVEL_MASK)
+		intr_type = 0;
+	else if (IS_GPIO_INT(hwirq)) {
+		intr_type = 0;
+		edge_trigger[hwirq] = type;
+	} else
+		intr_type = 1;
+
+	intr_polarity = (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING);
+
+	sp_intc_assign_bit(hwirq, sp_intc.g0 + G0_INTR_TYPE, intr_type);
+	sp_intc_assign_bit(hwirq, sp_intc.g0 + G0_INTR_POLARITY, intr_polarity);
+
+	return IRQ_SET_MASK_OK;
+}
+
+static int sp_intc_get_ext_irq(int ext_num)
+{
+	u32 hwirq, mask;
+	u32 i;
+
+	i = readl_relaxed(sp_intc.g1 + G1_INTR_GROUP);
+	if (ext_num)
+		mask = (i >> G1_EXT1_SHIFT) & G1_INTR_MASK;
+	else
+		mask = (i >> G1_EXT0_SHIFT) & G1_INTR_MASK;
+	if (mask) {
+		i = fls(mask) - 1;
+		if (ext_num)
+			mask = readl_relaxed(sp_intc.g1 + G1_MASKED_EXT1 + i * 4);
+		else
+			mask = readl_relaxed(sp_intc.g1 + G1_MASKED_EXT0 + i * 4);
+		if (mask) {
+			hwirq = (i << 5) + fls(mask) - 1;
+			return hwirq;
+		}
+	}
+	return -1; /* No interrupt */
+}
+
+static void sp_intc_handle_ext_cascaded(struct irq_desc *desc)
+{
+	struct irq_chip *host_chip = irq_desc_get_chip(desc);
+	int ext_num = (int)irq_desc_get_handler_data(desc);
+	int hwirq;
+
+	chained_irq_enter(host_chip, desc);
+
+	while ((hwirq = sp_intc_get_ext_irq(ext_num)) >= 0) {
+		if (edge_trigger[hwirq] & GPIO_INT_EDGE_ACTIVE) {
+			edge_trigger[hwirq] &= ~GPIO_INT_EDGE_ACTIVE;
+			sp_intc_assign_bit(hwirq, sp_intc.g0 + G0_INTR_POLARITY,
+				(edge_trigger[hwirq] != IRQ_TYPE_EDGE_RISING));
+		} else
+			generic_handle_domain_irq(sp_intc.domain, hwirq);
+	}
+
+	chained_irq_exit(host_chip, desc);
+}
+
+static void __exception_irq_entry sp_intc_handle_irq(struct pt_regs *regs)
+{
+	int hwirq;
+
+	while ((hwirq = sp_intc_get_ext_irq(0)) >= 0)
+		generic_handle_domain_irq(sp_intc.domain, hwirq);
+}
+
+static void __init sp_intc_chip_init(void __iomem *base0, void __iomem *base1)
+{
+	int i;
+
+	sp_intc.g0 = base0;
+	sp_intc.g1 = base1;
+
+	for (i = 0; i < 7; i++) {
+		/* all mask */
+		writel_relaxed(0, sp_intc.g0 + G0_INTR_MASK + i * 4);
+		/* all edge */
+		writel_relaxed(~0, sp_intc.g0 + G0_INTR_TYPE + i * 4);
+		/* all high-active */
+		writel_relaxed(0, sp_intc.g0 + G0_INTR_POLARITY + i * 4);
+		/* all irq */
+		writel_relaxed(~0, sp_intc.g0 + G0_INTR_PRIORITY + i * 4);
+		/* all clear */
+		writel_relaxed(~0, sp_intc.g1 + G1_INTR_CLR + i * 4);
+	}
+}
+
+int sp_intc_xlate_of(struct irq_domain *d, struct device_node *node,
+			  const u32 *intspec, unsigned int intsize,
+			  irq_hw_number_t *out_hwirq, unsigned int *out_type)
+{
+	int ret;
+
+	ret = irq_domain_xlate_twocell(d, node,
+		intspec, intsize, out_hwirq, out_type);
+	if (!ret) {
+		/* intspec[1]: IRQ_TYPE | SP_INTC_EXT_INT
+		 * SP_INTC_EXT_INT: 0-1,
+		 *   to indicate route to which parent irq: EXT_INT0/EXT_INT1
+		 */
+		u32 ext_int = (intspec[1] & SP_INTC_EXT_INT_MASK) >> SP_INTC_EXT_INT_SHFIT;
+
+		/* priority = 0, route to EXT_INT1
+		 *    otherwise, route to EXT_INT0
+		 */
+		sp_intc_set_priority(*out_hwirq, 1 - ext_int);
+	}
+
+	return ret;
+}
+
+static struct irq_chip sp_intc_chip = {
+	.name = "sp_intc",
+	.irq_ack = sp_intc_ack_irq,
+	.irq_mask = sp_intc_mask_irq,
+	.irq_unmask = sp_intc_unmask_irq,
+	.irq_set_type = sp_intc_set_type,
+};
+
+static int sp_intc_irq_domain_map(struct irq_domain *domain,
+	unsigned int irq, irq_hw_number_t hwirq)
+{
+	irq_set_chip_and_handler(irq, &sp_intc_chip, handle_level_irq);
+	irq_set_chip_data(irq, &sp_intc_chip);
+	irq_set_noprobe(irq);
+
+	return 0;
+}
+
+static const struct irq_domain_ops sp_intc_dm_ops = {
+	.xlate = sp_intc_xlate_of,
+	.map = sp_intc_irq_domain_map,
+};
+
+#ifdef CONFIG_OF
+static int sp_intc_irq_map(struct device_node *node, int i)
+{
+	sp_intc.virq[i] = irq_of_parse_and_map(node, i);
+	if (!sp_intc.virq[i]) {
+		pr_err("%s: missed EXT_INT%d in DT\n", __func__, i);
+		return -ENOENT;
+	}
+
+	pr_info("%s: EXT_INT%d = %d\n", __func__, i, sp_intc.virq[i]);
+	irq_set_chained_handler_and_data(sp_intc.virq[i],
+		sp_intc_handle_ext_cascaded, (void *)i);
+
+	return 0;
+}
+
+int __init sp_intc_init_dt(
+	struct device_node *node, struct device_node *parent)
+{
+	void __iomem *base0, *base1;
+
+	base0 = of_iomap(node, 0);
+	if (!base0) {
+		pr_err("unable to map sp-intc base 0\n");
+		return -EINVAL;
+	}
+
+	base1 = of_iomap(node, 1);
+	if (!base1) {
+		pr_err("unable to map sp-intc base 1\n");
+		return -EINVAL;
+	}
+
+	sp_intc.node = node;
+
+	sp_intc_chip_init(base0, base1);
+
+	sp_intc.domain = irq_domain_add_linear(node,
+			SP_INTC_HWIRQ_MAX - SP_INTC_HWIRQ_MIN,
+			&sp_intc_dm_ops, &sp_intc);
+	if (!sp_intc.domain) {
+		pr_err("%s: unable to create linear domain\n", __func__);
+		return -EINVAL;
+	}
+
+	raw_spin_lock_init(&sp_intc.lock);
+
+	if (parent) {
+		/* secondary chained controller */
+		if (sp_intc_irq_map(node, 0)) // EXT_INT0
+			return -ENOENT;
+
+		if (sp_intc_irq_map(node, 1)) // EXT_INT1
+			return -ENOENT;
+	} else {
+		/* primary controller */
+		set_handle_irq(sp_intc_handle_irq);
+	}
+
+	return 0;
+}
+IRQCHIP_DECLARE(sp_intc, "sunplus,sp7021-intc", sp_intc_init_dt);
+#endif
+
+MODULE_AUTHOR("Qin Jian <qinjian@cqplus1.com>");
+MODULE_DESCRIPTION("Sunplus SP7021 Interrupt Controller Driver");
+MODULE_LICENSE("GPL v2");
-- 
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] 124+ messages in thread

* [PATCH v2 8/8] irqchip: Add support for Sunplus SP7021 interrupt controller
@ 2021-10-29  8:44   ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-10-29  8:44 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, tglx, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add interrupt 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 C-chip. C-chip adopts ARM CA7
interrupt controller (compitable = "arm,cortex-a7-gic"). It is a parent
interrupt controller of P-chip interrupt controller.

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

diff --git a/MAINTAINERS b/MAINTAINERS
index be0334d6a..bfa891d86 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2665,6 +2665,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/interrupt-controller/sp7021-intc.h
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index aca7b595c..8a58dfb88 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -602,4 +602,13 @@ config APPLE_AIC
 	  Support for the Apple Interrupt Controller found on Apple Silicon SoCs,
 	  such as the M1.
 
+config SUNPLUS_SP7021_INTC
+	bool "Sunplus SP7021 interrupt controller"
+	default SOC_SP7021
+	help
+	  Support for the Sunplus SP7021 Interrupt Controller IP core.
+	  This is used as a primary controller with SP7021 ChipP and can also
+	  be used as a secondary chained controller on SP7021 ChipC.
+	  This is selected automatically by platform config.
+
 endmenu
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index f88cbf36a..75411f654 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -116,3 +116,4 @@ obj-$(CONFIG_MACH_REALTEK_RTL)		+= irq-realtek-rtl.o
 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_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..3431ec746
--- /dev/null
+++ b/drivers/irqchip/irq-sp7021-intc.c
@@ -0,0 +1,324 @@
+// 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>
+
+#include <asm/exception.h>
+#include <dt-bindings/interrupt-controller/sp7021-intc.h>
+
+#define SP_INTC_HWIRQ_MIN     0
+#define SP_INTC_HWIRQ_MAX     223
+
+/* Interrupt G0/G1 offset */
+#define INTR_REG_SIZE		(7 * 4)
+
+#define G0_INTR_TYPE		(0)
+#define G0_INTR_POLARITY	(G0_INTR_TYPE + INTR_REG_SIZE)
+#define G0_INTR_PRIORITY	(G0_INTR_POLARITY + INTR_REG_SIZE)
+#define G0_INTR_MASK		(G0_INTR_PRIORITY + INTR_REG_SIZE)
+
+#define G1_INTR_CLR			(0)
+#define G1_MASKED_EXT1		(G1_INTR_CLR + INTR_REG_SIZE)
+#define G1_MASKED_EXT0		(G1_MASKED_EXT1 + INTR_REG_SIZE)
+#define G1_INTR_GROUP		(31 * 4)
+#define G1_INTR_MASK		(0x7F)
+#define G1_EXT1_SHIFT		(0)
+#define G1_EXT0_SHIFT		(8)
+
+static struct sp_intctl {
+	void __iomem *g0;
+	void __iomem *g1;
+	struct irq_domain *domain;
+	struct device_node *node;
+	raw_spinlock_t lock;
+	int virq[2];
+} sp_intc;
+
+/* GPIO INT EDGE BUG WORKAROUND */
+#define GPIO_INT0_HWIRQ			120
+#define GPIO_INT7_HWIRQ			127
+#define GPIO_INT_EDGE_ACTIVE	BIT(31)
+#define IS_GPIO_INT(n)	(((n) >= GPIO_INT0_HWIRQ) && ((n) <= GPIO_INT7_HWIRQ))
+/* array to hold which interrupt needs to workaround the bug
+ * INT_TYPE_NONE: no need
+ * INT_TYPE_EDGE_FALLING/INT_TYPE_EDGE_RISING: need to workaround
+ * GPIO_INT_EDGE_ACTIVING: workaround is on going
+ */
+static u32 edge_trigger[SP_INTC_HWIRQ_MAX];
+
+static struct irq_chip sp_intc_chip;
+
+static void sp_intc_assign_bit(u32 hwirq, void __iomem *base, u32 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 (edge_trigger[hwirq] != IRQ_TYPE_NONE) {
+		sp_intc_assign_bit(hwirq, sp_intc.g0 + G0_INTR_POLARITY,
+			(edge_trigger[hwirq] == IRQ_TYPE_EDGE_RISING));
+		edge_trigger[hwirq] |= GPIO_INT_EDGE_ACTIVE;
+	}
+
+	sp_intc_assign_bit(hwirq, sp_intc.g1 + G1_INTR_CLR, 1);
+}
+
+static void sp_intc_mask_irq(struct irq_data *d)
+{
+	sp_intc_assign_bit(d->hwirq, sp_intc.g0 + G0_INTR_MASK, 0);
+}
+
+static void sp_intc_unmask_irq(struct irq_data *d)
+{
+	sp_intc_assign_bit(d->hwirq, sp_intc.g0 + G0_INTR_MASK, 1);
+}
+
+static void sp_intc_set_priority(u32 hwirq, u32 priority)
+{
+	sp_intc_assign_bit(hwirq, sp_intc.g0 + G0_INTR_PRIORITY, priority);
+}
+
+static int sp_intc_set_type(struct irq_data *d, unsigned int type)
+{
+	u32 intr_type;		/* 0: level			1: edge */
+	u32 intr_polarity;	/* 0: high/rising	1: low/falling */
+	u32 hwirq = d->hwirq;
+
+	/* update the chip/handler */
+	if (type & IRQ_TYPE_LEVEL_MASK)
+		irq_set_chip_handler_name_locked(d, &sp_intc_chip,
+						   handle_level_irq, NULL);
+	else
+		irq_set_chip_handler_name_locked(d, &sp_intc_chip,
+						   handle_edge_irq, NULL);
+
+	edge_trigger[hwirq] = IRQ_TYPE_NONE;
+
+	if (type & IRQ_TYPE_LEVEL_MASK)
+		intr_type = 0;
+	else if (IS_GPIO_INT(hwirq)) {
+		intr_type = 0;
+		edge_trigger[hwirq] = type;
+	} else
+		intr_type = 1;
+
+	intr_polarity = (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING);
+
+	sp_intc_assign_bit(hwirq, sp_intc.g0 + G0_INTR_TYPE, intr_type);
+	sp_intc_assign_bit(hwirq, sp_intc.g0 + G0_INTR_POLARITY, intr_polarity);
+
+	return IRQ_SET_MASK_OK;
+}
+
+static int sp_intc_get_ext_irq(int ext_num)
+{
+	u32 hwirq, mask;
+	u32 i;
+
+	i = readl_relaxed(sp_intc.g1 + G1_INTR_GROUP);
+	if (ext_num)
+		mask = (i >> G1_EXT1_SHIFT) & G1_INTR_MASK;
+	else
+		mask = (i >> G1_EXT0_SHIFT) & G1_INTR_MASK;
+	if (mask) {
+		i = fls(mask) - 1;
+		if (ext_num)
+			mask = readl_relaxed(sp_intc.g1 + G1_MASKED_EXT1 + i * 4);
+		else
+			mask = readl_relaxed(sp_intc.g1 + G1_MASKED_EXT0 + i * 4);
+		if (mask) {
+			hwirq = (i << 5) + fls(mask) - 1;
+			return hwirq;
+		}
+	}
+	return -1; /* No interrupt */
+}
+
+static void sp_intc_handle_ext_cascaded(struct irq_desc *desc)
+{
+	struct irq_chip *host_chip = irq_desc_get_chip(desc);
+	int ext_num = (int)irq_desc_get_handler_data(desc);
+	int hwirq;
+
+	chained_irq_enter(host_chip, desc);
+
+	while ((hwirq = sp_intc_get_ext_irq(ext_num)) >= 0) {
+		if (edge_trigger[hwirq] & GPIO_INT_EDGE_ACTIVE) {
+			edge_trigger[hwirq] &= ~GPIO_INT_EDGE_ACTIVE;
+			sp_intc_assign_bit(hwirq, sp_intc.g0 + G0_INTR_POLARITY,
+				(edge_trigger[hwirq] != IRQ_TYPE_EDGE_RISING));
+		} else
+			generic_handle_domain_irq(sp_intc.domain, hwirq);
+	}
+
+	chained_irq_exit(host_chip, desc);
+}
+
+static void __exception_irq_entry sp_intc_handle_irq(struct pt_regs *regs)
+{
+	int hwirq;
+
+	while ((hwirq = sp_intc_get_ext_irq(0)) >= 0)
+		generic_handle_domain_irq(sp_intc.domain, hwirq);
+}
+
+static void __init sp_intc_chip_init(void __iomem *base0, void __iomem *base1)
+{
+	int i;
+
+	sp_intc.g0 = base0;
+	sp_intc.g1 = base1;
+
+	for (i = 0; i < 7; i++) {
+		/* all mask */
+		writel_relaxed(0, sp_intc.g0 + G0_INTR_MASK + i * 4);
+		/* all edge */
+		writel_relaxed(~0, sp_intc.g0 + G0_INTR_TYPE + i * 4);
+		/* all high-active */
+		writel_relaxed(0, sp_intc.g0 + G0_INTR_POLARITY + i * 4);
+		/* all irq */
+		writel_relaxed(~0, sp_intc.g0 + G0_INTR_PRIORITY + i * 4);
+		/* all clear */
+		writel_relaxed(~0, sp_intc.g1 + G1_INTR_CLR + i * 4);
+	}
+}
+
+int sp_intc_xlate_of(struct irq_domain *d, struct device_node *node,
+			  const u32 *intspec, unsigned int intsize,
+			  irq_hw_number_t *out_hwirq, unsigned int *out_type)
+{
+	int ret;
+
+	ret = irq_domain_xlate_twocell(d, node,
+		intspec, intsize, out_hwirq, out_type);
+	if (!ret) {
+		/* intspec[1]: IRQ_TYPE | SP_INTC_EXT_INT
+		 * SP_INTC_EXT_INT: 0-1,
+		 *   to indicate route to which parent irq: EXT_INT0/EXT_INT1
+		 */
+		u32 ext_int = (intspec[1] & SP_INTC_EXT_INT_MASK) >> SP_INTC_EXT_INT_SHFIT;
+
+		/* priority = 0, route to EXT_INT1
+		 *    otherwise, route to EXT_INT0
+		 */
+		sp_intc_set_priority(*out_hwirq, 1 - ext_int);
+	}
+
+	return ret;
+}
+
+static struct irq_chip sp_intc_chip = {
+	.name = "sp_intc",
+	.irq_ack = sp_intc_ack_irq,
+	.irq_mask = sp_intc_mask_irq,
+	.irq_unmask = sp_intc_unmask_irq,
+	.irq_set_type = sp_intc_set_type,
+};
+
+static int sp_intc_irq_domain_map(struct irq_domain *domain,
+	unsigned int irq, irq_hw_number_t hwirq)
+{
+	irq_set_chip_and_handler(irq, &sp_intc_chip, handle_level_irq);
+	irq_set_chip_data(irq, &sp_intc_chip);
+	irq_set_noprobe(irq);
+
+	return 0;
+}
+
+static const struct irq_domain_ops sp_intc_dm_ops = {
+	.xlate = sp_intc_xlate_of,
+	.map = sp_intc_irq_domain_map,
+};
+
+#ifdef CONFIG_OF
+static int sp_intc_irq_map(struct device_node *node, int i)
+{
+	sp_intc.virq[i] = irq_of_parse_and_map(node, i);
+	if (!sp_intc.virq[i]) {
+		pr_err("%s: missed EXT_INT%d in DT\n", __func__, i);
+		return -ENOENT;
+	}
+
+	pr_info("%s: EXT_INT%d = %d\n", __func__, i, sp_intc.virq[i]);
+	irq_set_chained_handler_and_data(sp_intc.virq[i],
+		sp_intc_handle_ext_cascaded, (void *)i);
+
+	return 0;
+}
+
+int __init sp_intc_init_dt(
+	struct device_node *node, struct device_node *parent)
+{
+	void __iomem *base0, *base1;
+
+	base0 = of_iomap(node, 0);
+	if (!base0) {
+		pr_err("unable to map sp-intc base 0\n");
+		return -EINVAL;
+	}
+
+	base1 = of_iomap(node, 1);
+	if (!base1) {
+		pr_err("unable to map sp-intc base 1\n");
+		return -EINVAL;
+	}
+
+	sp_intc.node = node;
+
+	sp_intc_chip_init(base0, base1);
+
+	sp_intc.domain = irq_domain_add_linear(node,
+			SP_INTC_HWIRQ_MAX - SP_INTC_HWIRQ_MIN,
+			&sp_intc_dm_ops, &sp_intc);
+	if (!sp_intc.domain) {
+		pr_err("%s: unable to create linear domain\n", __func__);
+		return -EINVAL;
+	}
+
+	raw_spin_lock_init(&sp_intc.lock);
+
+	if (parent) {
+		/* secondary chained controller */
+		if (sp_intc_irq_map(node, 0)) // EXT_INT0
+			return -ENOENT;
+
+		if (sp_intc_irq_map(node, 1)) // EXT_INT1
+			return -ENOENT;
+	} else {
+		/* primary controller */
+		set_handle_irq(sp_intc_handle_irq);
+	}
+
+	return 0;
+}
+IRQCHIP_DECLARE(sp_intc, "sunplus,sp7021-intc", sp_intc_init_dt);
+#endif
+
+MODULE_AUTHOR("Qin Jian <qinjian@cqplus1.com>");
+MODULE_DESCRIPTION("Sunplus SP7021 Interrupt Controller Driver");
+MODULE_LICENSE("GPL v2");
-- 
2.33.1


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

* Re: [PATCH v2 8/8] irqchip: Add support for Sunplus SP7021 interrupt controller
  2021-10-29  8:44   ` Qin Jian
@ 2021-10-29 15:25     ` Marc Zyngier
  -1 siblings, 0 replies; 124+ messages in thread
From: Marc Zyngier @ 2021-10-29 15:25 UTC (permalink / raw)
  To: Qin Jian
  Cc: robh+dt, mturquette, sboyd, tglx, p.zabel, broonie,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu

On Fri, 29 Oct 2021 09:44:34 +0100,
Qin Jian <qinjian@cqplus1.com> wrote:
> 
> Add interrupt 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 C-chip. C-chip adopts ARM CA7
> interrupt controller (compitable = "arm,cortex-a7-gic"). It is a parent

This information isn't relevant.

> interrupt controller of P-chip interrupt controller.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  MAINTAINERS                       |   1 +
>  drivers/irqchip/Kconfig           |   9 +
>  drivers/irqchip/Makefile          |   1 +
>  drivers/irqchip/irq-sp7021-intc.c | 324 ++++++++++++++++++++++++++++++
>  4 files changed, 335 insertions(+)
>  create mode 100644 drivers/irqchip/irq-sp7021-intc.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index be0334d6a..bfa891d86 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2665,6 +2665,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/interrupt-controller/sp7021-intc.h
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index aca7b595c..8a58dfb88 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -602,4 +602,13 @@ config APPLE_AIC
>  	  Support for the Apple Interrupt Controller found on Apple Silicon SoCs,
>  	  such as the M1.
>  
> +config SUNPLUS_SP7021_INTC
> +	bool "Sunplus SP7021 interrupt controller"
> +	default SOC_SP7021
> +	help
> +	  Support for the Sunplus SP7021 Interrupt Controller IP core.
> +	  This is used as a primary controller with SP7021 ChipP and can also
> +	  be used as a secondary chained controller on SP7021 ChipC.
> +	  This is selected automatically by platform config.

If it is selected, drop the default.

> +
>  endmenu
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index f88cbf36a..75411f654 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -116,3 +116,4 @@ obj-$(CONFIG_MACH_REALTEK_RTL)		+= irq-realtek-rtl.o
>  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_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..3431ec746
> --- /dev/null
> +++ b/drivers/irqchip/irq-sp7021-intc.c
> @@ -0,0 +1,324 @@
> +// 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>
> +
> +#include <asm/exception.h>
> +#include <dt-bindings/interrupt-controller/sp7021-intc.h>
> +
> +#define SP_INTC_HWIRQ_MIN     0
> +#define SP_INTC_HWIRQ_MAX     223
> +
> +/* Interrupt G0/G1 offset */
> +#define INTR_REG_SIZE		(7 * 4)

Why isn't that derived from the number of interrupts?

> +
> +#define G0_INTR_TYPE		(0)
> +#define G0_INTR_POLARITY	(G0_INTR_TYPE + INTR_REG_SIZE)
> +#define G0_INTR_PRIORITY	(G0_INTR_POLARITY + INTR_REG_SIZE)
> +#define G0_INTR_MASK		(G0_INTR_PRIORITY + INTR_REG_SIZE)
> +
> +#define G1_INTR_CLR			(0)
> +#define G1_MASKED_EXT1		(G1_INTR_CLR + INTR_REG_SIZE)
> +#define G1_MASKED_EXT0		(G1_MASKED_EXT1 + INTR_REG_SIZE)
> +#define G1_INTR_GROUP		(31 * 4)
> +#define G1_INTR_MASK		(0x7F)
> +#define G1_EXT1_SHIFT		(0)
> +#define G1_EXT0_SHIFT		(8)
> +
> +static struct sp_intctl {
> +	void __iomem *g0;
> +	void __iomem *g1;

What is G0? what is G1?

> +	struct irq_domain *domain;
> +	struct device_node *node;
> +	raw_spinlock_t lock;
> +	int virq[2];
> +} sp_intc;
> +
> +/* GPIO INT EDGE BUG WORKAROUND */
> +#define GPIO_INT0_HWIRQ			120
> +#define GPIO_INT7_HWIRQ			127
> +#define GPIO_INT_EDGE_ACTIVE	BIT(31)
> +#define IS_GPIO_INT(n)	(((n) >= GPIO_INT0_HWIRQ) && ((n) <= GPIO_INT7_HWIRQ))
> +/* array to hold which interrupt needs to workaround the bug
> + * INT_TYPE_NONE: no need
> + * INT_TYPE_EDGE_FALLING/INT_TYPE_EDGE_RISING: need to workaround
> + * GPIO_INT_EDGE_ACTIVING: workaround is on going

Please describe the nature of the workaround. s/ACTIVING/ACTIVE/.

> + */
> +static u32 edge_trigger[SP_INTC_HWIRQ_MAX];

4 states per interrupt, and yet you use a u32 for each of them...
Also, why isn't this part of your sp_intc data structure? You also
have enough space for 200+ interrupts (ignoring the obvious off-by-one
bug), and yet you are only concerned with 8 of them. Do you spot a
trend here?

> +
> +static struct irq_chip sp_intc_chip;
> +
> +static void sp_intc_assign_bit(u32 hwirq, void __iomem *base, u32 value)

If value describes a single bit, why is it a u32?

> +{
> +	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 (edge_trigger[hwirq] != IRQ_TYPE_NONE) {

Why don't you just check the irq number instead?

> +		sp_intc_assign_bit(hwirq, sp_intc.g0 + G0_INTR_POLARITY,
> +			(edge_trigger[hwirq] == IRQ_TYPE_EDGE_RISING));
> +		edge_trigger[hwirq] |= GPIO_INT_EDGE_ACTIVE;

The whole thing is terrible. For each of the 8 interrupts, you only
need to know whether:

- it is rising or falling
- it is active or not

That's a grand total of 16 bits instead of almost a 1kB worth of
nothing. Use atomic bitops, and this is done.

> +	}
> +
> +	sp_intc_assign_bit(hwirq, sp_intc.g1 + G1_INTR_CLR, 1);
> +}
> +
> +static void sp_intc_mask_irq(struct irq_data *d)
> +{
> +	sp_intc_assign_bit(d->hwirq, sp_intc.g0 + G0_INTR_MASK, 0);
> +}
> +
> +static void sp_intc_unmask_irq(struct irq_data *d)
> +{
> +	sp_intc_assign_bit(d->hwirq, sp_intc.g0 + G0_INTR_MASK, 1);
> +}
> +
> +static void sp_intc_set_priority(u32 hwirq, u32 priority)
> +{
> +	sp_intc_assign_bit(hwirq, sp_intc.g0 + G0_INTR_PRIORITY, priority);
> +}
> +
> +static int sp_intc_set_type(struct irq_data *d, unsigned int type)
> +{
> +	u32 intr_type;		/* 0: level			1: edge */
> +	u32 intr_polarity;	/* 0: high/rising	1: low/falling */

So how about giving the variables sensible names and types:

	bool is_level, is_high;

> +	u32 hwirq = d->hwirq;
> +
> +	/* update the chip/handler */
> +	if (type & IRQ_TYPE_LEVEL_MASK)
> +		irq_set_chip_handler_name_locked(d, &sp_intc_chip,
> +						   handle_level_irq, NULL);
> +	else
> +		irq_set_chip_handler_name_locked(d, &sp_intc_chip,
> +						   handle_edge_irq, NULL);
> +
> +	edge_trigger[hwirq] = IRQ_TYPE_NONE;
> +
> +	if (type & IRQ_TYPE_LEVEL_MASK)
> +		intr_type = 0;
> +	else if (IS_GPIO_INT(hwirq)) {
> +		intr_type = 0;
> +		edge_trigger[hwirq] = type;
> +	} else
> +		intr_type = 1;

Coding style.

> +
> +	intr_polarity = (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING);
> +
> +	sp_intc_assign_bit(hwirq, sp_intc.g0 + G0_INTR_TYPE, intr_type);
> +	sp_intc_assign_bit(hwirq, sp_intc.g0 + G0_INTR_POLARITY, intr_polarity);
> +
> +	return IRQ_SET_MASK_OK;
> +}
> +
> +static int sp_intc_get_ext_irq(int ext_num)
> +{
> +	u32 hwirq, mask;
> +	u32 i;
> +
> +	i = readl_relaxed(sp_intc.g1 + G1_INTR_GROUP);
> +	if (ext_num)
> +		mask = (i >> G1_EXT1_SHIFT) & G1_INTR_MASK;
> +	else
> +		mask = (i >> G1_EXT0_SHIFT) & G1_INTR_MASK;
> +	if (mask) {
> +		i = fls(mask) - 1;
> +		if (ext_num)
> +			mask = readl_relaxed(sp_intc.g1 + G1_MASKED_EXT1 + i * 4);
> +		else
> +			mask = readl_relaxed(sp_intc.g1 + G1_MASKED_EXT0 + i * 4);
> +		if (mask) {
> +			hwirq = (i << 5) + fls(mask) - 1;
> +			return hwirq;
> +		}
> +	}

What a terrible control flow. Also, variable names are cheap, and you
don't need to reuse them when they mean something different.

	if (ext_num) {
		shift = G1_EXT1_SHIFT;
		offset = G1_MASKED_EXT1;
	} else {
		[[ same thing with G0 ]
	}

	status = readl_relaxed();

	pending_summary = (status >> shift) & G1_INTR_MASK;
	if (!pending_summary)
		return -1;

	index = fls(pending_summary) - 1;
	pending = readl_relaxed(g1 + offset + index * 4);
	if (!pending)
		return -1;

	return (index << 5) | (fls(pending) - 1);

Look: no nesting, obvious names, anyone can understand it.

> +	return -1; /* No interrupt */
> +}
> +
> +static void sp_intc_handle_ext_cascaded(struct irq_desc *desc)
> +{
> +	struct irq_chip *host_chip = irq_desc_get_chip(desc);
> +	int ext_num = (int)irq_desc_get_handler_data(desc);
> +	int hwirq;
> +
> +	chained_irq_enter(host_chip, desc);
> +
> +	while ((hwirq = sp_intc_get_ext_irq(ext_num)) >= 0) {
> +		if (edge_trigger[hwirq] & GPIO_INT_EDGE_ACTIVE) {
> +			edge_trigger[hwirq] &= ~GPIO_INT_EDGE_ACTIVE;
> +			sp_intc_assign_bit(hwirq, sp_intc.g0 + G0_INTR_POLARITY,
> +				(edge_trigger[hwirq] != IRQ_TYPE_EDGE_RISING));
> +		} else
> +			generic_handle_domain_irq(sp_intc.domain, hwirq);

Coding style.

> +	}
> +
> +	chained_irq_exit(host_chip, desc);
> +}
> +
> +static void __exception_irq_entry sp_intc_handle_irq(struct pt_regs *regs)
> +{
> +	int hwirq;
> +
> +	while ((hwirq = sp_intc_get_ext_irq(0)) >= 0)
> +		generic_handle_domain_irq(sp_intc.domain, hwirq);
> +}
> +
> +static void __init sp_intc_chip_init(void __iomem *base0, void __iomem *base1)
> +{
> +	int i;
> +
> +	sp_intc.g0 = base0;
> +	sp_intc.g1 = base1;
> +
> +	for (i = 0; i < 7; i++) {
> +		/* all mask */
> +		writel_relaxed(0, sp_intc.g0 + G0_INTR_MASK + i * 4);
> +		/* all edge */
> +		writel_relaxed(~0, sp_intc.g0 + G0_INTR_TYPE + i * 4);
> +		/* all high-active */
> +		writel_relaxed(0, sp_intc.g0 + G0_INTR_POLARITY + i * 4);
> +		/* all irq */
> +		writel_relaxed(~0, sp_intc.g0 + G0_INTR_PRIORITY + i * 4);
> +		/* all clear */
> +		writel_relaxed(~0, sp_intc.g1 + G1_INTR_CLR + i * 4);
> +	}
> +}
> +
> +int sp_intc_xlate_of(struct irq_domain *d, struct device_node *node,
> +			  const u32 *intspec, unsigned int intsize,
> +			  irq_hw_number_t *out_hwirq, unsigned int *out_type)
> +{
> +	int ret;
> +
> +	ret = irq_domain_xlate_twocell(d, node,
> +		intspec, intsize, out_hwirq, out_type);
> +	if (!ret) {
> +		/* intspec[1]: IRQ_TYPE | SP_INTC_EXT_INT
> +		 * SP_INTC_EXT_INT: 0-1,
> +		 *   to indicate route to which parent irq: EXT_INT0/EXT_INT1
> +		 */

Why is that in the DT? If that's a SW decision, it doesn't belong there.

> +		u32 ext_int = (intspec[1] & SP_INTC_EXT_INT_MASK) >> SP_INTC_EXT_INT_SHFIT;
> +
> +		/* priority = 0, route to EXT_INT1
> +		 *    otherwise, route to EXT_INT0
> +		 */
> +		sp_intc_set_priority(*out_hwirq, 1 - ext_int);

I already said in the initial review that changing the HW didn't
belong in the translate callback, but should be done at map() time.

> +	}
> +
> +	return ret;
> +}
> +
> +static struct irq_chip sp_intc_chip = {
> +	.name = "sp_intc",
> +	.irq_ack = sp_intc_ack_irq,
> +	.irq_mask = sp_intc_mask_irq,
> +	.irq_unmask = sp_intc_unmask_irq,
> +	.irq_set_type = sp_intc_set_type,
> +};
> +
> +static int sp_intc_irq_domain_map(struct irq_domain *domain,
> +	unsigned int irq, irq_hw_number_t hwirq)
> +{
> +	irq_set_chip_and_handler(irq, &sp_intc_chip, handle_level_irq);
> +	irq_set_chip_data(irq, &sp_intc_chip);
> +	irq_set_noprobe(irq);
> +
> +	return 0;
> +}
> +
> +static const struct irq_domain_ops sp_intc_dm_ops = {
> +	.xlate = sp_intc_xlate_of,
> +	.map = sp_intc_irq_domain_map,
> +};
> +
> +#ifdef CONFIG_OF

Why the #ifdef? This thing doesn't work without OF anyway.

> +static int sp_intc_irq_map(struct device_node *node, int i)
> +{
> +	sp_intc.virq[i] = irq_of_parse_and_map(node, i);
> +	if (!sp_intc.virq[i]) {
> +		pr_err("%s: missed EXT_INT%d in DT\n", __func__, i);

-ENOENT is enough, no need to shout on the console.

> +		return -ENOENT;
> +	}
> +
> +	pr_info("%s: EXT_INT%d = %d\n", __func__, i, sp_intc.virq[i]);

Nobody cares about this. Get rid of it.

> +	irq_set_chained_handler_and_data(sp_intc.virq[i],
> +		sp_intc_handle_ext_cascaded, (void *)i);
> +
> +	return 0;
> +}
> +
> +int __init sp_intc_init_dt(
> +	struct device_node *node, struct device_node *parent)

Single line.

> +{
> +	void __iomem *base0, *base1;
> +
> +	base0 = of_iomap(node, 0);
> +	if (!base0) {
> +		pr_err("unable to map sp-intc base 0\n");
> +		return -EINVAL;
> +	}
> +
> +	base1 = of_iomap(node, 1);
> +	if (!base1) {
> +		pr_err("unable to map sp-intc base 1\n");
> +		return -EINVAL;
> +	}
> +
> +	sp_intc.node = node;
> +
> +	sp_intc_chip_init(base0, base1);
> +
> +	sp_intc.domain = irq_domain_add_linear(node,
> +			SP_INTC_HWIRQ_MAX - SP_INTC_HWIRQ_MIN,
> +			&sp_intc_dm_ops, &sp_intc);
> +	if (!sp_intc.domain) {
> +		pr_err("%s: unable to create linear domain\n", __func__);

Drop the error message.

> +		return -EINVAL;
> +	}
> +
> +	raw_spin_lock_init(&sp_intc.lock);
> +
> +	if (parent) {
> +		/* secondary chained controller */
> +		if (sp_intc_irq_map(node, 0)) // EXT_INT0
> +			return -ENOENT;

Just return whatever the helper returned. You don't need to
reinterpret it.

> +
> +		if (sp_intc_irq_map(node, 1)) // EXT_INT1
> +			return -ENOENT;
> +	} else {
> +		/* primary controller */
> +		set_handle_irq(sp_intc_handle_irq);
> +	}

So what happens if you have *two* of these blocks? One as the root
controller, and another implementing the chained stuff?

> +
> +	return 0;
> +}
> +IRQCHIP_DECLARE(sp_intc, "sunplus,sp7021-intc", sp_intc_init_dt);
> +#endif
> +
> +MODULE_AUTHOR("Qin Jian <qinjian@cqplus1.com>");
> +MODULE_DESCRIPTION("Sunplus SP7021 Interrupt Controller Driver");
> +MODULE_LICENSE("GPL v2");

You are using IRQCHIP_DECLARE(), so this isn't a module. Drop this.

Thankfully, it is too late for 5.16, so you have a full cycle to give
this code another major cleanup.

	M.

-- 
Without deviation from the norm, progress is not possible.

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

* Re: [PATCH v2 8/8] irqchip: Add support for Sunplus SP7021 interrupt controller
@ 2021-10-29 15:25     ` Marc Zyngier
  0 siblings, 0 replies; 124+ messages in thread
From: Marc Zyngier @ 2021-10-29 15:25 UTC (permalink / raw)
  To: Qin Jian
  Cc: robh+dt, mturquette, sboyd, tglx, p.zabel, broonie,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu

On Fri, 29 Oct 2021 09:44:34 +0100,
Qin Jian <qinjian@cqplus1.com> wrote:
> 
> Add interrupt 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 C-chip. C-chip adopts ARM CA7
> interrupt controller (compitable = "arm,cortex-a7-gic"). It is a parent

This information isn't relevant.

> interrupt controller of P-chip interrupt controller.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  MAINTAINERS                       |   1 +
>  drivers/irqchip/Kconfig           |   9 +
>  drivers/irqchip/Makefile          |   1 +
>  drivers/irqchip/irq-sp7021-intc.c | 324 ++++++++++++++++++++++++++++++
>  4 files changed, 335 insertions(+)
>  create mode 100644 drivers/irqchip/irq-sp7021-intc.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index be0334d6a..bfa891d86 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2665,6 +2665,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/interrupt-controller/sp7021-intc.h
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index aca7b595c..8a58dfb88 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -602,4 +602,13 @@ config APPLE_AIC
>  	  Support for the Apple Interrupt Controller found on Apple Silicon SoCs,
>  	  such as the M1.
>  
> +config SUNPLUS_SP7021_INTC
> +	bool "Sunplus SP7021 interrupt controller"
> +	default SOC_SP7021
> +	help
> +	  Support for the Sunplus SP7021 Interrupt Controller IP core.
> +	  This is used as a primary controller with SP7021 ChipP and can also
> +	  be used as a secondary chained controller on SP7021 ChipC.
> +	  This is selected automatically by platform config.

If it is selected, drop the default.

> +
>  endmenu
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index f88cbf36a..75411f654 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -116,3 +116,4 @@ obj-$(CONFIG_MACH_REALTEK_RTL)		+= irq-realtek-rtl.o
>  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_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..3431ec746
> --- /dev/null
> +++ b/drivers/irqchip/irq-sp7021-intc.c
> @@ -0,0 +1,324 @@
> +// 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>
> +
> +#include <asm/exception.h>
> +#include <dt-bindings/interrupt-controller/sp7021-intc.h>
> +
> +#define SP_INTC_HWIRQ_MIN     0
> +#define SP_INTC_HWIRQ_MAX     223
> +
> +/* Interrupt G0/G1 offset */
> +#define INTR_REG_SIZE		(7 * 4)

Why isn't that derived from the number of interrupts?

> +
> +#define G0_INTR_TYPE		(0)
> +#define G0_INTR_POLARITY	(G0_INTR_TYPE + INTR_REG_SIZE)
> +#define G0_INTR_PRIORITY	(G0_INTR_POLARITY + INTR_REG_SIZE)
> +#define G0_INTR_MASK		(G0_INTR_PRIORITY + INTR_REG_SIZE)
> +
> +#define G1_INTR_CLR			(0)
> +#define G1_MASKED_EXT1		(G1_INTR_CLR + INTR_REG_SIZE)
> +#define G1_MASKED_EXT0		(G1_MASKED_EXT1 + INTR_REG_SIZE)
> +#define G1_INTR_GROUP		(31 * 4)
> +#define G1_INTR_MASK		(0x7F)
> +#define G1_EXT1_SHIFT		(0)
> +#define G1_EXT0_SHIFT		(8)
> +
> +static struct sp_intctl {
> +	void __iomem *g0;
> +	void __iomem *g1;

What is G0? what is G1?

> +	struct irq_domain *domain;
> +	struct device_node *node;
> +	raw_spinlock_t lock;
> +	int virq[2];
> +} sp_intc;
> +
> +/* GPIO INT EDGE BUG WORKAROUND */
> +#define GPIO_INT0_HWIRQ			120
> +#define GPIO_INT7_HWIRQ			127
> +#define GPIO_INT_EDGE_ACTIVE	BIT(31)
> +#define IS_GPIO_INT(n)	(((n) >= GPIO_INT0_HWIRQ) && ((n) <= GPIO_INT7_HWIRQ))
> +/* array to hold which interrupt needs to workaround the bug
> + * INT_TYPE_NONE: no need
> + * INT_TYPE_EDGE_FALLING/INT_TYPE_EDGE_RISING: need to workaround
> + * GPIO_INT_EDGE_ACTIVING: workaround is on going

Please describe the nature of the workaround. s/ACTIVING/ACTIVE/.

> + */
> +static u32 edge_trigger[SP_INTC_HWIRQ_MAX];

4 states per interrupt, and yet you use a u32 for each of them...
Also, why isn't this part of your sp_intc data structure? You also
have enough space for 200+ interrupts (ignoring the obvious off-by-one
bug), and yet you are only concerned with 8 of them. Do you spot a
trend here?

> +
> +static struct irq_chip sp_intc_chip;
> +
> +static void sp_intc_assign_bit(u32 hwirq, void __iomem *base, u32 value)

If value describes a single bit, why is it a u32?

> +{
> +	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 (edge_trigger[hwirq] != IRQ_TYPE_NONE) {

Why don't you just check the irq number instead?

> +		sp_intc_assign_bit(hwirq, sp_intc.g0 + G0_INTR_POLARITY,
> +			(edge_trigger[hwirq] == IRQ_TYPE_EDGE_RISING));
> +		edge_trigger[hwirq] |= GPIO_INT_EDGE_ACTIVE;

The whole thing is terrible. For each of the 8 interrupts, you only
need to know whether:

- it is rising or falling
- it is active or not

That's a grand total of 16 bits instead of almost a 1kB worth of
nothing. Use atomic bitops, and this is done.

> +	}
> +
> +	sp_intc_assign_bit(hwirq, sp_intc.g1 + G1_INTR_CLR, 1);
> +}
> +
> +static void sp_intc_mask_irq(struct irq_data *d)
> +{
> +	sp_intc_assign_bit(d->hwirq, sp_intc.g0 + G0_INTR_MASK, 0);
> +}
> +
> +static void sp_intc_unmask_irq(struct irq_data *d)
> +{
> +	sp_intc_assign_bit(d->hwirq, sp_intc.g0 + G0_INTR_MASK, 1);
> +}
> +
> +static void sp_intc_set_priority(u32 hwirq, u32 priority)
> +{
> +	sp_intc_assign_bit(hwirq, sp_intc.g0 + G0_INTR_PRIORITY, priority);
> +}
> +
> +static int sp_intc_set_type(struct irq_data *d, unsigned int type)
> +{
> +	u32 intr_type;		/* 0: level			1: edge */
> +	u32 intr_polarity;	/* 0: high/rising	1: low/falling */

So how about giving the variables sensible names and types:

	bool is_level, is_high;

> +	u32 hwirq = d->hwirq;
> +
> +	/* update the chip/handler */
> +	if (type & IRQ_TYPE_LEVEL_MASK)
> +		irq_set_chip_handler_name_locked(d, &sp_intc_chip,
> +						   handle_level_irq, NULL);
> +	else
> +		irq_set_chip_handler_name_locked(d, &sp_intc_chip,
> +						   handle_edge_irq, NULL);
> +
> +	edge_trigger[hwirq] = IRQ_TYPE_NONE;
> +
> +	if (type & IRQ_TYPE_LEVEL_MASK)
> +		intr_type = 0;
> +	else if (IS_GPIO_INT(hwirq)) {
> +		intr_type = 0;
> +		edge_trigger[hwirq] = type;
> +	} else
> +		intr_type = 1;

Coding style.

> +
> +	intr_polarity = (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING);
> +
> +	sp_intc_assign_bit(hwirq, sp_intc.g0 + G0_INTR_TYPE, intr_type);
> +	sp_intc_assign_bit(hwirq, sp_intc.g0 + G0_INTR_POLARITY, intr_polarity);
> +
> +	return IRQ_SET_MASK_OK;
> +}
> +
> +static int sp_intc_get_ext_irq(int ext_num)
> +{
> +	u32 hwirq, mask;
> +	u32 i;
> +
> +	i = readl_relaxed(sp_intc.g1 + G1_INTR_GROUP);
> +	if (ext_num)
> +		mask = (i >> G1_EXT1_SHIFT) & G1_INTR_MASK;
> +	else
> +		mask = (i >> G1_EXT0_SHIFT) & G1_INTR_MASK;
> +	if (mask) {
> +		i = fls(mask) - 1;
> +		if (ext_num)
> +			mask = readl_relaxed(sp_intc.g1 + G1_MASKED_EXT1 + i * 4);
> +		else
> +			mask = readl_relaxed(sp_intc.g1 + G1_MASKED_EXT0 + i * 4);
> +		if (mask) {
> +			hwirq = (i << 5) + fls(mask) - 1;
> +			return hwirq;
> +		}
> +	}

What a terrible control flow. Also, variable names are cheap, and you
don't need to reuse them when they mean something different.

	if (ext_num) {
		shift = G1_EXT1_SHIFT;
		offset = G1_MASKED_EXT1;
	} else {
		[[ same thing with G0 ]
	}

	status = readl_relaxed();

	pending_summary = (status >> shift) & G1_INTR_MASK;
	if (!pending_summary)
		return -1;

	index = fls(pending_summary) - 1;
	pending = readl_relaxed(g1 + offset + index * 4);
	if (!pending)
		return -1;

	return (index << 5) | (fls(pending) - 1);

Look: no nesting, obvious names, anyone can understand it.

> +	return -1; /* No interrupt */
> +}
> +
> +static void sp_intc_handle_ext_cascaded(struct irq_desc *desc)
> +{
> +	struct irq_chip *host_chip = irq_desc_get_chip(desc);
> +	int ext_num = (int)irq_desc_get_handler_data(desc);
> +	int hwirq;
> +
> +	chained_irq_enter(host_chip, desc);
> +
> +	while ((hwirq = sp_intc_get_ext_irq(ext_num)) >= 0) {
> +		if (edge_trigger[hwirq] & GPIO_INT_EDGE_ACTIVE) {
> +			edge_trigger[hwirq] &= ~GPIO_INT_EDGE_ACTIVE;
> +			sp_intc_assign_bit(hwirq, sp_intc.g0 + G0_INTR_POLARITY,
> +				(edge_trigger[hwirq] != IRQ_TYPE_EDGE_RISING));
> +		} else
> +			generic_handle_domain_irq(sp_intc.domain, hwirq);

Coding style.

> +	}
> +
> +	chained_irq_exit(host_chip, desc);
> +}
> +
> +static void __exception_irq_entry sp_intc_handle_irq(struct pt_regs *regs)
> +{
> +	int hwirq;
> +
> +	while ((hwirq = sp_intc_get_ext_irq(0)) >= 0)
> +		generic_handle_domain_irq(sp_intc.domain, hwirq);
> +}
> +
> +static void __init sp_intc_chip_init(void __iomem *base0, void __iomem *base1)
> +{
> +	int i;
> +
> +	sp_intc.g0 = base0;
> +	sp_intc.g1 = base1;
> +
> +	for (i = 0; i < 7; i++) {
> +		/* all mask */
> +		writel_relaxed(0, sp_intc.g0 + G0_INTR_MASK + i * 4);
> +		/* all edge */
> +		writel_relaxed(~0, sp_intc.g0 + G0_INTR_TYPE + i * 4);
> +		/* all high-active */
> +		writel_relaxed(0, sp_intc.g0 + G0_INTR_POLARITY + i * 4);
> +		/* all irq */
> +		writel_relaxed(~0, sp_intc.g0 + G0_INTR_PRIORITY + i * 4);
> +		/* all clear */
> +		writel_relaxed(~0, sp_intc.g1 + G1_INTR_CLR + i * 4);
> +	}
> +}
> +
> +int sp_intc_xlate_of(struct irq_domain *d, struct device_node *node,
> +			  const u32 *intspec, unsigned int intsize,
> +			  irq_hw_number_t *out_hwirq, unsigned int *out_type)
> +{
> +	int ret;
> +
> +	ret = irq_domain_xlate_twocell(d, node,
> +		intspec, intsize, out_hwirq, out_type);
> +	if (!ret) {
> +		/* intspec[1]: IRQ_TYPE | SP_INTC_EXT_INT
> +		 * SP_INTC_EXT_INT: 0-1,
> +		 *   to indicate route to which parent irq: EXT_INT0/EXT_INT1
> +		 */

Why is that in the DT? If that's a SW decision, it doesn't belong there.

> +		u32 ext_int = (intspec[1] & SP_INTC_EXT_INT_MASK) >> SP_INTC_EXT_INT_SHFIT;
> +
> +		/* priority = 0, route to EXT_INT1
> +		 *    otherwise, route to EXT_INT0
> +		 */
> +		sp_intc_set_priority(*out_hwirq, 1 - ext_int);

I already said in the initial review that changing the HW didn't
belong in the translate callback, but should be done at map() time.

> +	}
> +
> +	return ret;
> +}
> +
> +static struct irq_chip sp_intc_chip = {
> +	.name = "sp_intc",
> +	.irq_ack = sp_intc_ack_irq,
> +	.irq_mask = sp_intc_mask_irq,
> +	.irq_unmask = sp_intc_unmask_irq,
> +	.irq_set_type = sp_intc_set_type,
> +};
> +
> +static int sp_intc_irq_domain_map(struct irq_domain *domain,
> +	unsigned int irq, irq_hw_number_t hwirq)
> +{
> +	irq_set_chip_and_handler(irq, &sp_intc_chip, handle_level_irq);
> +	irq_set_chip_data(irq, &sp_intc_chip);
> +	irq_set_noprobe(irq);
> +
> +	return 0;
> +}
> +
> +static const struct irq_domain_ops sp_intc_dm_ops = {
> +	.xlate = sp_intc_xlate_of,
> +	.map = sp_intc_irq_domain_map,
> +};
> +
> +#ifdef CONFIG_OF

Why the #ifdef? This thing doesn't work without OF anyway.

> +static int sp_intc_irq_map(struct device_node *node, int i)
> +{
> +	sp_intc.virq[i] = irq_of_parse_and_map(node, i);
> +	if (!sp_intc.virq[i]) {
> +		pr_err("%s: missed EXT_INT%d in DT\n", __func__, i);

-ENOENT is enough, no need to shout on the console.

> +		return -ENOENT;
> +	}
> +
> +	pr_info("%s: EXT_INT%d = %d\n", __func__, i, sp_intc.virq[i]);

Nobody cares about this. Get rid of it.

> +	irq_set_chained_handler_and_data(sp_intc.virq[i],
> +		sp_intc_handle_ext_cascaded, (void *)i);
> +
> +	return 0;
> +}
> +
> +int __init sp_intc_init_dt(
> +	struct device_node *node, struct device_node *parent)

Single line.

> +{
> +	void __iomem *base0, *base1;
> +
> +	base0 = of_iomap(node, 0);
> +	if (!base0) {
> +		pr_err("unable to map sp-intc base 0\n");
> +		return -EINVAL;
> +	}
> +
> +	base1 = of_iomap(node, 1);
> +	if (!base1) {
> +		pr_err("unable to map sp-intc base 1\n");
> +		return -EINVAL;
> +	}
> +
> +	sp_intc.node = node;
> +
> +	sp_intc_chip_init(base0, base1);
> +
> +	sp_intc.domain = irq_domain_add_linear(node,
> +			SP_INTC_HWIRQ_MAX - SP_INTC_HWIRQ_MIN,
> +			&sp_intc_dm_ops, &sp_intc);
> +	if (!sp_intc.domain) {
> +		pr_err("%s: unable to create linear domain\n", __func__);

Drop the error message.

> +		return -EINVAL;
> +	}
> +
> +	raw_spin_lock_init(&sp_intc.lock);
> +
> +	if (parent) {
> +		/* secondary chained controller */
> +		if (sp_intc_irq_map(node, 0)) // EXT_INT0
> +			return -ENOENT;

Just return whatever the helper returned. You don't need to
reinterpret it.

> +
> +		if (sp_intc_irq_map(node, 1)) // EXT_INT1
> +			return -ENOENT;
> +	} else {
> +		/* primary controller */
> +		set_handle_irq(sp_intc_handle_irq);
> +	}

So what happens if you have *two* of these blocks? One as the root
controller, and another implementing the chained stuff?

> +
> +	return 0;
> +}
> +IRQCHIP_DECLARE(sp_intc, "sunplus,sp7021-intc", sp_intc_init_dt);
> +#endif
> +
> +MODULE_AUTHOR("Qin Jian <qinjian@cqplus1.com>");
> +MODULE_DESCRIPTION("Sunplus SP7021 Interrupt Controller Driver");
> +MODULE_LICENSE("GPL v2");

You are using IRQCHIP_DECLARE(), so this isn't a module. Drop this.

Thankfully, it is too late for 5.16, so you have a full cycle to give
this code another major cleanup.

	M.

-- 
Without deviation from the norm, progress is not possible.

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

* Re: [PATCH v2 4/8] reset: Add Sunplus SP7021 reset driver
  2021-10-29  8:44   ` Qin Jian
  (?)
@ 2021-10-30  4:18     ` kernel test robot
  -1 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-10-30  4:18 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: kbuild-all, mturquette, sboyd, tglx, maz, p.zabel, broonie,
	linux-arm-kernel, devicetree, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 3996 bytes --]

Hi Qin,

I love your patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on pza/reset/next clk/clk-next tip/irq/core linus/master v5.15-rc7 next-20211029]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/Add-Sunplus-SP7021-SoC-Support/20211029-171054
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: arc-allyesconfig (attached as .config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/45fff7c04fb4d0ccfbd1ed11f73277d1f8742499
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/Add-Sunplus-SP7021-SoC-Support/20211029-171054
        git checkout 45fff7c04fb4d0ccfbd1ed11f73277d1f8742499
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arc SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/reset/reset-sunplus.c: In function 'sp_restart':
>> drivers/reset/reset-sunplus.c:98:42: error: 'RST_SYSTEM' undeclared (first use in this function)
      98 |         sp_reset_assert(&sp_reset.rcdev, RST_SYSTEM);
         |                                          ^~~~~~~~~~
   drivers/reset/reset-sunplus.c:98:42: note: each undeclared identifier is reported only once for each function it appears in
   drivers/reset/reset-sunplus.c: In function 'sp_reset_probe':
>> drivers/reset/reset-sunplus.c:135:33: error: 'RST_MAX' undeclared (first use in this function); did you mean 'S8_MAX'?
     135 |         data->rcdev.nr_resets = RST_MAX;
         |                                 ^~~~~~~
         |                                 S8_MAX


vim +/RST_SYSTEM +98 drivers/reset/reset-sunplus.c

    94	
    95	static int sp_restart(struct notifier_block *this, unsigned long mode,
    96					void *cmd)
    97	{
  > 98		sp_reset_assert(&sp_reset.rcdev, RST_SYSTEM);
    99		sp_reset_deassert(&sp_reset.rcdev, RST_SYSTEM);
   100	
   101		return NOTIFY_DONE;
   102	}
   103	
   104	static struct notifier_block sp_restart_nb = {
   105		.notifier_call = sp_restart,
   106		.priority = 192,
   107	};
   108	
   109	static const struct reset_control_ops sp_reset_ops = {
   110		.assert		= sp_reset_assert,
   111		.deassert	= sp_reset_deassert,
   112		.status		= sp_reset_status,
   113	};
   114	
   115	static const struct of_device_id sp_reset_dt_ids[] = {
   116		{ .compatible = "sunplus,sp7021-reset", },
   117		{ .compatible = "sunplus,q645-reset", },
   118		{ /* sentinel */ },
   119	};
   120	
   121	static int sp_reset_probe(struct platform_device *pdev)
   122	{
   123		struct device *dev = &pdev->dev;
   124		struct sp_reset_data *data = &sp_reset;
   125		void __iomem *membase;
   126		struct resource *res;
   127	
   128		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
   129		membase = devm_ioremap(dev, res->start, resource_size(res));
   130		if (IS_ERR(membase))
   131			return PTR_ERR(membase);
   132	
   133		data->membase = membase;
   134		data->rcdev.owner = THIS_MODULE;
 > 135		data->rcdev.nr_resets = RST_MAX;
   136		data->rcdev.ops = &sp_reset_ops;
   137		data->rcdev.of_node = dev->of_node;
   138		register_restart_handler(&sp_restart_nb);
   139	
   140		return devm_reset_controller_register(dev, &data->rcdev);
   141	}
   142	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 69207 bytes --]

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

* Re: [PATCH v2 4/8] reset: Add Sunplus SP7021 reset driver
@ 2021-10-30  4:18     ` kernel test robot
  0 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-10-30  4:18 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: kbuild-all, mturquette, sboyd, tglx, maz, p.zabel, broonie,
	linux-arm-kernel, devicetree, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 3996 bytes --]

Hi Qin,

I love your patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on pza/reset/next clk/clk-next tip/irq/core linus/master v5.15-rc7 next-20211029]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/Add-Sunplus-SP7021-SoC-Support/20211029-171054
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: arc-allyesconfig (attached as .config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/45fff7c04fb4d0ccfbd1ed11f73277d1f8742499
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/Add-Sunplus-SP7021-SoC-Support/20211029-171054
        git checkout 45fff7c04fb4d0ccfbd1ed11f73277d1f8742499
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arc SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/reset/reset-sunplus.c: In function 'sp_restart':
>> drivers/reset/reset-sunplus.c:98:42: error: 'RST_SYSTEM' undeclared (first use in this function)
      98 |         sp_reset_assert(&sp_reset.rcdev, RST_SYSTEM);
         |                                          ^~~~~~~~~~
   drivers/reset/reset-sunplus.c:98:42: note: each undeclared identifier is reported only once for each function it appears in
   drivers/reset/reset-sunplus.c: In function 'sp_reset_probe':
>> drivers/reset/reset-sunplus.c:135:33: error: 'RST_MAX' undeclared (first use in this function); did you mean 'S8_MAX'?
     135 |         data->rcdev.nr_resets = RST_MAX;
         |                                 ^~~~~~~
         |                                 S8_MAX


vim +/RST_SYSTEM +98 drivers/reset/reset-sunplus.c

    94	
    95	static int sp_restart(struct notifier_block *this, unsigned long mode,
    96					void *cmd)
    97	{
  > 98		sp_reset_assert(&sp_reset.rcdev, RST_SYSTEM);
    99		sp_reset_deassert(&sp_reset.rcdev, RST_SYSTEM);
   100	
   101		return NOTIFY_DONE;
   102	}
   103	
   104	static struct notifier_block sp_restart_nb = {
   105		.notifier_call = sp_restart,
   106		.priority = 192,
   107	};
   108	
   109	static const struct reset_control_ops sp_reset_ops = {
   110		.assert		= sp_reset_assert,
   111		.deassert	= sp_reset_deassert,
   112		.status		= sp_reset_status,
   113	};
   114	
   115	static const struct of_device_id sp_reset_dt_ids[] = {
   116		{ .compatible = "sunplus,sp7021-reset", },
   117		{ .compatible = "sunplus,q645-reset", },
   118		{ /* sentinel */ },
   119	};
   120	
   121	static int sp_reset_probe(struct platform_device *pdev)
   122	{
   123		struct device *dev = &pdev->dev;
   124		struct sp_reset_data *data = &sp_reset;
   125		void __iomem *membase;
   126		struct resource *res;
   127	
   128		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
   129		membase = devm_ioremap(dev, res->start, resource_size(res));
   130		if (IS_ERR(membase))
   131			return PTR_ERR(membase);
   132	
   133		data->membase = membase;
   134		data->rcdev.owner = THIS_MODULE;
 > 135		data->rcdev.nr_resets = RST_MAX;
   136		data->rcdev.ops = &sp_reset_ops;
   137		data->rcdev.of_node = dev->of_node;
   138		register_restart_handler(&sp_restart_nb);
   139	
   140		return devm_reset_controller_register(dev, &data->rcdev);
   141	}
   142	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 69207 bytes --]

[-- Attachment #3: Type: text/plain, Size: 176 bytes --]

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

* Re: [PATCH v2 4/8] reset: Add Sunplus SP7021 reset driver
@ 2021-10-30  4:18     ` kernel test robot
  0 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-10-30  4:18 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 4095 bytes --]

Hi Qin,

I love your patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on pza/reset/next clk/clk-next tip/irq/core linus/master v5.15-rc7 next-20211029]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/Add-Sunplus-SP7021-SoC-Support/20211029-171054
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: arc-allyesconfig (attached as .config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/45fff7c04fb4d0ccfbd1ed11f73277d1f8742499
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/Add-Sunplus-SP7021-SoC-Support/20211029-171054
        git checkout 45fff7c04fb4d0ccfbd1ed11f73277d1f8742499
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arc SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/reset/reset-sunplus.c: In function 'sp_restart':
>> drivers/reset/reset-sunplus.c:98:42: error: 'RST_SYSTEM' undeclared (first use in this function)
      98 |         sp_reset_assert(&sp_reset.rcdev, RST_SYSTEM);
         |                                          ^~~~~~~~~~
   drivers/reset/reset-sunplus.c:98:42: note: each undeclared identifier is reported only once for each function it appears in
   drivers/reset/reset-sunplus.c: In function 'sp_reset_probe':
>> drivers/reset/reset-sunplus.c:135:33: error: 'RST_MAX' undeclared (first use in this function); did you mean 'S8_MAX'?
     135 |         data->rcdev.nr_resets = RST_MAX;
         |                                 ^~~~~~~
         |                                 S8_MAX


vim +/RST_SYSTEM +98 drivers/reset/reset-sunplus.c

    94	
    95	static int sp_restart(struct notifier_block *this, unsigned long mode,
    96					void *cmd)
    97	{
  > 98		sp_reset_assert(&sp_reset.rcdev, RST_SYSTEM);
    99		sp_reset_deassert(&sp_reset.rcdev, RST_SYSTEM);
   100	
   101		return NOTIFY_DONE;
   102	}
   103	
   104	static struct notifier_block sp_restart_nb = {
   105		.notifier_call = sp_restart,
   106		.priority = 192,
   107	};
   108	
   109	static const struct reset_control_ops sp_reset_ops = {
   110		.assert		= sp_reset_assert,
   111		.deassert	= sp_reset_deassert,
   112		.status		= sp_reset_status,
   113	};
   114	
   115	static const struct of_device_id sp_reset_dt_ids[] = {
   116		{ .compatible = "sunplus,sp7021-reset", },
   117		{ .compatible = "sunplus,q645-reset", },
   118		{ /* sentinel */ },
   119	};
   120	
   121	static int sp_reset_probe(struct platform_device *pdev)
   122	{
   123		struct device *dev = &pdev->dev;
   124		struct sp_reset_data *data = &sp_reset;
   125		void __iomem *membase;
   126		struct resource *res;
   127	
   128		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
   129		membase = devm_ioremap(dev, res->start, resource_size(res));
   130		if (IS_ERR(membase))
   131			return PTR_ERR(membase);
   132	
   133		data->membase = membase;
   134		data->rcdev.owner = THIS_MODULE;
 > 135		data->rcdev.nr_resets = RST_MAX;
   136		data->rcdev.ops = &sp_reset_ops;
   137		data->rcdev.of_node = dev->of_node;
   138		register_restart_handler(&sp_restart_nb);
   139	
   140		return devm_reset_controller_register(dev, &data->rcdev);
   141	}
   142	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 69207 bytes --]

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

* Re: [PATCH v2 8/8] irqchip: Add support for Sunplus SP7021 interrupt controller
  2021-10-29  8:44   ` Qin Jian
  (?)
@ 2021-10-30 15:30     ` kernel test robot
  -1 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-10-30 15:30 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: kbuild-all, mturquette, sboyd, tglx, maz, p.zabel, broonie,
	linux-arm-kernel, devicetree, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1983 bytes --]

Hi Qin,

I love your patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on pza/reset/next clk/clk-next linus/master v5.15-rc7]
[cannot apply to tip/irq/core next-20211029]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/Add-Sunplus-SP7021-SoC-Support/20211029-171054
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: arc-allyesconfig (attached as .config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/91ab876ddb6d1a596c50c43a79d3e06b9695dee7
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/Add-Sunplus-SP7021-SoC-Support/20211029-171054
        git checkout 91ab876ddb6d1a596c50c43a79d3e06b9695dee7
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arc SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/irqchip/irq-sp7021-intc.c:14:10: fatal error: asm/exception.h: No such file or directory
      14 | #include <asm/exception.h>
         |          ^~~~~~~~~~~~~~~~~
   compilation terminated.


vim +14 drivers/irqchip/irq-sp7021-intc.c

    13	
  > 14	#include <asm/exception.h>
    15	#include <dt-bindings/interrupt-controller/sp7021-intc.h>
    16	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 69222 bytes --]

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

* Re: [PATCH v2 8/8] irqchip: Add support for Sunplus SP7021 interrupt controller
@ 2021-10-30 15:30     ` kernel test robot
  0 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-10-30 15:30 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: kbuild-all, mturquette, sboyd, tglx, maz, p.zabel, broonie,
	linux-arm-kernel, devicetree, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1983 bytes --]

Hi Qin,

I love your patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on pza/reset/next clk/clk-next linus/master v5.15-rc7]
[cannot apply to tip/irq/core next-20211029]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/Add-Sunplus-SP7021-SoC-Support/20211029-171054
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: arc-allyesconfig (attached as .config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/91ab876ddb6d1a596c50c43a79d3e06b9695dee7
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/Add-Sunplus-SP7021-SoC-Support/20211029-171054
        git checkout 91ab876ddb6d1a596c50c43a79d3e06b9695dee7
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arc SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/irqchip/irq-sp7021-intc.c:14:10: fatal error: asm/exception.h: No such file or directory
      14 | #include <asm/exception.h>
         |          ^~~~~~~~~~~~~~~~~
   compilation terminated.


vim +14 drivers/irqchip/irq-sp7021-intc.c

    13	
  > 14	#include <asm/exception.h>
    15	#include <dt-bindings/interrupt-controller/sp7021-intc.h>
    16	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 69222 bytes --]

[-- Attachment #3: Type: text/plain, Size: 176 bytes --]

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

* Re: [PATCH v2 8/8] irqchip: Add support for Sunplus SP7021 interrupt controller
@ 2021-10-30 15:30     ` kernel test robot
  0 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-10-30 15:30 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 2032 bytes --]

Hi Qin,

I love your patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on pza/reset/next clk/clk-next linus/master v5.15-rc7]
[cannot apply to tip/irq/core next-20211029]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/Add-Sunplus-SP7021-SoC-Support/20211029-171054
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: arc-allyesconfig (attached as .config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/91ab876ddb6d1a596c50c43a79d3e06b9695dee7
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/Add-Sunplus-SP7021-SoC-Support/20211029-171054
        git checkout 91ab876ddb6d1a596c50c43a79d3e06b9695dee7
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arc SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/irqchip/irq-sp7021-intc.c:14:10: fatal error: asm/exception.h: No such file or directory
      14 | #include <asm/exception.h>
         |          ^~~~~~~~~~~~~~~~~
   compilation terminated.


vim +14 drivers/irqchip/irq-sp7021-intc.c

    13	
  > 14	#include <asm/exception.h>
    15	#include <dt-bindings/interrupt-controller/sp7021-intc.h>
    16	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 69222 bytes --]

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

* Re: [PATCH v2 8/8] irqchip: Add support for Sunplus SP7021 interrupt controller
  2021-10-29  8:44   ` Qin Jian
@ 2021-10-30 19:29     ` kernel test robot
  -1 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-10-30 19:29 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: kbuild-all, mturquette, sboyd, tglx, maz, p.zabel, broonie,
	linux-arm-kernel, devicetree, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 5525 bytes --]

Hi Qin,

I love your patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on pza/reset/next clk/clk-next linus/master v5.15-rc7]
[cannot apply to tip/irq/core next-20211029]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/Add-Sunplus-SP7021-SoC-Support/20211029-171054
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: arm-allyesconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/91ab876ddb6d1a596c50c43a79d3e06b9695dee7
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/Add-Sunplus-SP7021-SoC-Support/20211029-171054
        git checkout 91ab876ddb6d1a596c50c43a79d3e06b9695dee7
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/irqchip/irq-sp7021-intc.c:211:5: error: no previous prototype for 'sp_intc_xlate_of' [-Werror=missing-prototypes]
     211 | int sp_intc_xlate_of(struct irq_domain *d, struct device_node *node,
         |     ^~~~~~~~~~~~~~~~
>> drivers/irqchip/irq-sp7021-intc.c:274:12: error: no previous prototype for 'sp_intc_init_dt' [-Werror=missing-prototypes]
     274 | int __init sp_intc_init_dt(
         |            ^~~~~~~~~~~~~~~
   cc1: all warnings being treated as errors


vim +/sp_intc_xlate_of +211 drivers/irqchip/irq-sp7021-intc.c

   210	
 > 211	int sp_intc_xlate_of(struct irq_domain *d, struct device_node *node,
   212				  const u32 *intspec, unsigned int intsize,
   213				  irq_hw_number_t *out_hwirq, unsigned int *out_type)
   214	{
   215		int ret;
   216	
   217		ret = irq_domain_xlate_twocell(d, node,
   218			intspec, intsize, out_hwirq, out_type);
   219		if (!ret) {
   220			/* intspec[1]: IRQ_TYPE | SP_INTC_EXT_INT
   221			 * SP_INTC_EXT_INT: 0-1,
   222			 *   to indicate route to which parent irq: EXT_INT0/EXT_INT1
   223			 */
   224			u32 ext_int = (intspec[1] & SP_INTC_EXT_INT_MASK) >> SP_INTC_EXT_INT_SHFIT;
   225	
   226			/* priority = 0, route to EXT_INT1
   227			 *    otherwise, route to EXT_INT0
   228			 */
   229			sp_intc_set_priority(*out_hwirq, 1 - ext_int);
   230		}
   231	
   232		return ret;
   233	}
   234	
   235	static struct irq_chip sp_intc_chip = {
   236		.name = "sp_intc",
   237		.irq_ack = sp_intc_ack_irq,
   238		.irq_mask = sp_intc_mask_irq,
   239		.irq_unmask = sp_intc_unmask_irq,
   240		.irq_set_type = sp_intc_set_type,
   241	};
   242	
   243	static int sp_intc_irq_domain_map(struct irq_domain *domain,
   244		unsigned int irq, irq_hw_number_t hwirq)
   245	{
   246		irq_set_chip_and_handler(irq, &sp_intc_chip, handle_level_irq);
   247		irq_set_chip_data(irq, &sp_intc_chip);
   248		irq_set_noprobe(irq);
   249	
   250		return 0;
   251	}
   252	
   253	static const struct irq_domain_ops sp_intc_dm_ops = {
   254		.xlate = sp_intc_xlate_of,
   255		.map = sp_intc_irq_domain_map,
   256	};
   257	
   258	#ifdef CONFIG_OF
   259	static int sp_intc_irq_map(struct device_node *node, int i)
   260	{
   261		sp_intc.virq[i] = irq_of_parse_and_map(node, i);
   262		if (!sp_intc.virq[i]) {
   263			pr_err("%s: missed EXT_INT%d in DT\n", __func__, i);
   264			return -ENOENT;
   265		}
   266	
   267		pr_info("%s: EXT_INT%d = %d\n", __func__, i, sp_intc.virq[i]);
   268		irq_set_chained_handler_and_data(sp_intc.virq[i],
   269			sp_intc_handle_ext_cascaded, (void *)i);
   270	
   271		return 0;
   272	}
   273	
 > 274	int __init sp_intc_init_dt(
   275		struct device_node *node, struct device_node *parent)
   276	{
   277		void __iomem *base0, *base1;
   278	
   279		base0 = of_iomap(node, 0);
   280		if (!base0) {
   281			pr_err("unable to map sp-intc base 0\n");
   282			return -EINVAL;
   283		}
   284	
   285		base1 = of_iomap(node, 1);
   286		if (!base1) {
   287			pr_err("unable to map sp-intc base 1\n");
   288			return -EINVAL;
   289		}
   290	
   291		sp_intc.node = node;
   292	
   293		sp_intc_chip_init(base0, base1);
   294	
   295		sp_intc.domain = irq_domain_add_linear(node,
   296				SP_INTC_HWIRQ_MAX - SP_INTC_HWIRQ_MIN,
   297				&sp_intc_dm_ops, &sp_intc);
   298		if (!sp_intc.domain) {
   299			pr_err("%s: unable to create linear domain\n", __func__);
   300			return -EINVAL;
   301		}
   302	
   303		raw_spin_lock_init(&sp_intc.lock);
   304	
   305		if (parent) {
   306			/* secondary chained controller */
   307			if (sp_intc_irq_map(node, 0)) // EXT_INT0
   308				return -ENOENT;
   309	
   310			if (sp_intc_irq_map(node, 1)) // EXT_INT1
   311				return -ENOENT;
   312		} else {
   313			/* primary controller */
   314			set_handle_irq(sp_intc_handle_irq);
   315		}
   316	
   317		return 0;
   318	}
   319	IRQCHIP_DECLARE(sp_intc, "sunplus,sp7021-intc", sp_intc_init_dt);
   320	#endif
   321	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 79260 bytes --]

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

* Re: [PATCH v2 8/8] irqchip: Add support for Sunplus SP7021 interrupt controller
@ 2021-10-30 19:29     ` kernel test robot
  0 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-10-30 19:29 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 5684 bytes --]

Hi Qin,

I love your patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on pza/reset/next clk/clk-next linus/master v5.15-rc7]
[cannot apply to tip/irq/core next-20211029]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/Add-Sunplus-SP7021-SoC-Support/20211029-171054
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: arm-allyesconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/91ab876ddb6d1a596c50c43a79d3e06b9695dee7
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/Add-Sunplus-SP7021-SoC-Support/20211029-171054
        git checkout 91ab876ddb6d1a596c50c43a79d3e06b9695dee7
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/irqchip/irq-sp7021-intc.c:211:5: error: no previous prototype for 'sp_intc_xlate_of' [-Werror=missing-prototypes]
     211 | int sp_intc_xlate_of(struct irq_domain *d, struct device_node *node,
         |     ^~~~~~~~~~~~~~~~
>> drivers/irqchip/irq-sp7021-intc.c:274:12: error: no previous prototype for 'sp_intc_init_dt' [-Werror=missing-prototypes]
     274 | int __init sp_intc_init_dt(
         |            ^~~~~~~~~~~~~~~
   cc1: all warnings being treated as errors


vim +/sp_intc_xlate_of +211 drivers/irqchip/irq-sp7021-intc.c

   210	
 > 211	int sp_intc_xlate_of(struct irq_domain *d, struct device_node *node,
   212				  const u32 *intspec, unsigned int intsize,
   213				  irq_hw_number_t *out_hwirq, unsigned int *out_type)
   214	{
   215		int ret;
   216	
   217		ret = irq_domain_xlate_twocell(d, node,
   218			intspec, intsize, out_hwirq, out_type);
   219		if (!ret) {
   220			/* intspec[1]: IRQ_TYPE | SP_INTC_EXT_INT
   221			 * SP_INTC_EXT_INT: 0-1,
   222			 *   to indicate route to which parent irq: EXT_INT0/EXT_INT1
   223			 */
   224			u32 ext_int = (intspec[1] & SP_INTC_EXT_INT_MASK) >> SP_INTC_EXT_INT_SHFIT;
   225	
   226			/* priority = 0, route to EXT_INT1
   227			 *    otherwise, route to EXT_INT0
   228			 */
   229			sp_intc_set_priority(*out_hwirq, 1 - ext_int);
   230		}
   231	
   232		return ret;
   233	}
   234	
   235	static struct irq_chip sp_intc_chip = {
   236		.name = "sp_intc",
   237		.irq_ack = sp_intc_ack_irq,
   238		.irq_mask = sp_intc_mask_irq,
   239		.irq_unmask = sp_intc_unmask_irq,
   240		.irq_set_type = sp_intc_set_type,
   241	};
   242	
   243	static int sp_intc_irq_domain_map(struct irq_domain *domain,
   244		unsigned int irq, irq_hw_number_t hwirq)
   245	{
   246		irq_set_chip_and_handler(irq, &sp_intc_chip, handle_level_irq);
   247		irq_set_chip_data(irq, &sp_intc_chip);
   248		irq_set_noprobe(irq);
   249	
   250		return 0;
   251	}
   252	
   253	static const struct irq_domain_ops sp_intc_dm_ops = {
   254		.xlate = sp_intc_xlate_of,
   255		.map = sp_intc_irq_domain_map,
   256	};
   257	
   258	#ifdef CONFIG_OF
   259	static int sp_intc_irq_map(struct device_node *node, int i)
   260	{
   261		sp_intc.virq[i] = irq_of_parse_and_map(node, i);
   262		if (!sp_intc.virq[i]) {
   263			pr_err("%s: missed EXT_INT%d in DT\n", __func__, i);
   264			return -ENOENT;
   265		}
   266	
   267		pr_info("%s: EXT_INT%d = %d\n", __func__, i, sp_intc.virq[i]);
   268		irq_set_chained_handler_and_data(sp_intc.virq[i],
   269			sp_intc_handle_ext_cascaded, (void *)i);
   270	
   271		return 0;
   272	}
   273	
 > 274	int __init sp_intc_init_dt(
   275		struct device_node *node, struct device_node *parent)
   276	{
   277		void __iomem *base0, *base1;
   278	
   279		base0 = of_iomap(node, 0);
   280		if (!base0) {
   281			pr_err("unable to map sp-intc base 0\n");
   282			return -EINVAL;
   283		}
   284	
   285		base1 = of_iomap(node, 1);
   286		if (!base1) {
   287			pr_err("unable to map sp-intc base 1\n");
   288			return -EINVAL;
   289		}
   290	
   291		sp_intc.node = node;
   292	
   293		sp_intc_chip_init(base0, base1);
   294	
   295		sp_intc.domain = irq_domain_add_linear(node,
   296				SP_INTC_HWIRQ_MAX - SP_INTC_HWIRQ_MIN,
   297				&sp_intc_dm_ops, &sp_intc);
   298		if (!sp_intc.domain) {
   299			pr_err("%s: unable to create linear domain\n", __func__);
   300			return -EINVAL;
   301		}
   302	
   303		raw_spin_lock_init(&sp_intc.lock);
   304	
   305		if (parent) {
   306			/* secondary chained controller */
   307			if (sp_intc_irq_map(node, 0)) // EXT_INT0
   308				return -ENOENT;
   309	
   310			if (sp_intc_irq_map(node, 1)) // EXT_INT1
   311				return -ENOENT;
   312		} else {
   313			/* primary controller */
   314			set_handle_irq(sp_intc_handle_irq);
   315		}
   316	
   317		return 0;
   318	}
   319	IRQCHIP_DECLARE(sp_intc, "sunplus,sp7021-intc", sp_intc_init_dt);
   320	#endif
   321	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 79260 bytes --]

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

* [PATCH v3 0/8] Add Sunplus SP7021 SoC Support
  2021-10-29 15:25     ` Marc Zyngier
@ 2021-11-01  5:01       ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-01  5:01 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, 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 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 (8):
  dt-bindings: vendor-prefixes: Add Sunplus
  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

 .../bindings/arm/sunplus,sp7021.yaml          |  27 +
 .../bindings/clock/sunplus,sp7021-clkc.yaml   |  38 +
 .../sunplus,sp7021-intc.yaml                  |  62 ++
 .../bindings/reset/sunplus,reset.yaml         |  40 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 MAINTAINERS                                   |  15 +
 drivers/clk/Kconfig                           |   9 +
 drivers/clk/Makefile                          |   1 +
 drivers/clk/clk-sp7021.c                      | 770 ++++++++++++++++++
 drivers/irqchip/Kconfig                       |   9 +
 drivers/irqchip/Makefile                      |   1 +
 drivers/irqchip/irq-sp7021-intc.c             | 279 +++++++
 drivers/reset/Kconfig                         |   8 +
 drivers/reset/Makefile                        |   1 +
 drivers/reset/reset-sunplus.c                 | 159 ++++
 include/dt-bindings/clock/sp-sp7021.h         | 112 +++
 include/dt-bindings/reset/sp-sp7021.h         |  99 +++
 17 files changed, 1632 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 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] 124+ messages in thread

* [PATCH v3 0/8] Add Sunplus SP7021 SoC Support
@ 2021-11-01  5:01       ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-01  5:01 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, 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 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 (8):
  dt-bindings: vendor-prefixes: Add Sunplus
  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

 .../bindings/arm/sunplus,sp7021.yaml          |  27 +
 .../bindings/clock/sunplus,sp7021-clkc.yaml   |  38 +
 .../sunplus,sp7021-intc.yaml                  |  62 ++
 .../bindings/reset/sunplus,reset.yaml         |  40 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 MAINTAINERS                                   |  15 +
 drivers/clk/Kconfig                           |   9 +
 drivers/clk/Makefile                          |   1 +
 drivers/clk/clk-sp7021.c                      | 770 ++++++++++++++++++
 drivers/irqchip/Kconfig                       |   9 +
 drivers/irqchip/Makefile                      |   1 +
 drivers/irqchip/irq-sp7021-intc.c             | 279 +++++++
 drivers/reset/Kconfig                         |   8 +
 drivers/reset/Makefile                        |   1 +
 drivers/reset/reset-sunplus.c                 | 159 ++++
 include/dt-bindings/clock/sp-sp7021.h         | 112 +++
 include/dt-bindings/reset/sp-sp7021.h         |  99 +++
 17 files changed, 1632 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 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] 124+ messages in thread

* [PATCH v3 1/8] dt-bindings: vendor-prefixes: Add Sunplus
  2021-11-01  5:01       ` Qin Jian
@ 2021-11-01  5:01         ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-01  5:01 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add vendor prefix for Sunplus Technology Co., Ltd. (http://www.sunplus.com)

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index a867f7102..50d4ee5ac 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1131,6 +1131,8 @@ patternProperties:
     description: Summit microelectronics
   "^sunchip,.*":
     description: Shenzhen Sunchip Technology Co., Ltd
+  "^sunplus,.*":
+    description: Sunplus Technology Co., Ltd.
   "^SUNW,.*":
     description: Sun Microsystems, Inc
   "^supermicro,.*":
-- 
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] 124+ messages in thread

* [PATCH v3 1/8] dt-bindings: vendor-prefixes: Add Sunplus
@ 2021-11-01  5:01         ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-01  5:01 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add vendor prefix for Sunplus Technology Co., Ltd. (http://www.sunplus.com)

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index a867f7102..50d4ee5ac 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1131,6 +1131,8 @@ patternProperties:
     description: Summit microelectronics
   "^sunchip,.*":
     description: Shenzhen Sunchip Technology Co., Ltd
+  "^sunplus,.*":
+    description: Sunplus Technology Co., Ltd.
   "^SUNW,.*":
     description: Sun Microsystems, Inc
   "^supermicro,.*":
-- 
2.33.1


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

* [PATCH v3 2/8] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards
  2021-11-01  5:01       ` Qin Jian
@ 2021-11-01  5:01         ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-01  5:01 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

This introduces bindings for boards based Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../bindings/arm/sunplus,sp7021.yaml          | 27 +++++++++++++++++++
 MAINTAINERS                                   |  7 +++++
 2 files changed, 34 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..5b9985b73
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
@@ -0,0 +1,27 @@
+# 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:
+    oneOf:
+      - items:
+          - const: sunplus,sp7021-achip
+
+additionalProperties: true
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index e0bca0de0..6a5422f10 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2655,6 +2655,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 <Jisheng.Zhang@synaptics.com>
 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] 124+ messages in thread

* [PATCH v3 2/8] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards
@ 2021-11-01  5:01         ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-01  5:01 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

This introduces bindings for boards based Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../bindings/arm/sunplus,sp7021.yaml          | 27 +++++++++++++++++++
 MAINTAINERS                                   |  7 +++++
 2 files changed, 34 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..5b9985b73
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
@@ -0,0 +1,27 @@
+# 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:
+    oneOf:
+      - items:
+          - const: sunplus,sp7021-achip
+
+additionalProperties: true
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index e0bca0de0..6a5422f10 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2655,6 +2655,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 <Jisheng.Zhang@synaptics.com>
 M:	Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
-- 
2.33.1


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

* [PATCH v3 3/8] dt-bindings: reset: Add bindings for SP7021 reset driver
  2021-11-01  5:01       ` Qin Jian
@ 2021-11-01  5:01         ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-01  5:01 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add documentation to describe Sunplus SP7021 reset driver bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../bindings/reset/sunplus,reset.yaml         | 40 ++++++++
 MAINTAINERS                                   |  2 +
 include/dt-bindings/reset/sp-sp7021.h         | 99 +++++++++++++++++++
 3 files changed, 141 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..bf55f4ee2
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/sunplus,reset.yaml
@@ -0,0 +1,40 @@
+# 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:
+    enum:
+      - sunplus,sp7021-reset # Reset Controller on SP7021 and compatible SoCs
+      - sunplus,q645-reset # Reset Controller on Q645 and compatible SoCs
+
+  "#reset-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#reset-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    rstc: reset@9c000054 {
+      compatible = "sunplus,sp7021-reset";
+      #reset-cells = <1>;
+      reg = <0x9c000054 0x28>;
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 6a5422f10..652f42cab 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2661,6 +2661,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 <Jisheng.Zhang@synaptics.com>
diff --git a/include/dt-bindings/reset/sp-sp7021.h b/include/dt-bindings/reset/sp-sp7021.h
new file mode 100644
index 000000000..8823d25ce
--- /dev/null
+++ b/include/dt-bindings/reset/sp-sp7021.h
@@ -0,0 +1,99 @@
+/* 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
+
+#define RST_MAX			0xA0
+
+#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] 124+ messages in thread

* [PATCH v3 3/8] dt-bindings: reset: Add bindings for SP7021 reset driver
@ 2021-11-01  5:01         ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-01  5:01 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add documentation to describe Sunplus SP7021 reset driver bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../bindings/reset/sunplus,reset.yaml         | 40 ++++++++
 MAINTAINERS                                   |  2 +
 include/dt-bindings/reset/sp-sp7021.h         | 99 +++++++++++++++++++
 3 files changed, 141 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..bf55f4ee2
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/sunplus,reset.yaml
@@ -0,0 +1,40 @@
+# 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:
+    enum:
+      - sunplus,sp7021-reset # Reset Controller on SP7021 and compatible SoCs
+      - sunplus,q645-reset # Reset Controller on Q645 and compatible SoCs
+
+  "#reset-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#reset-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    rstc: reset@9c000054 {
+      compatible = "sunplus,sp7021-reset";
+      #reset-cells = <1>;
+      reg = <0x9c000054 0x28>;
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 6a5422f10..652f42cab 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2661,6 +2661,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 <Jisheng.Zhang@synaptics.com>
diff --git a/include/dt-bindings/reset/sp-sp7021.h b/include/dt-bindings/reset/sp-sp7021.h
new file mode 100644
index 000000000..8823d25ce
--- /dev/null
+++ b/include/dt-bindings/reset/sp-sp7021.h
@@ -0,0 +1,99 @@
+/* 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
+
+#define RST_MAX			0xA0
+
+#endif
-- 
2.33.1


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

* [PATCH v3 4/8] reset: Add Sunplus SP7021 reset driver
  2021-11-01  5:01       ` Qin Jian
@ 2021-11-01  5:01         ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-01  5:01 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add reset driver for Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 MAINTAINERS                   |   1 +
 drivers/reset/Kconfig         |   8 ++
 drivers/reset/Makefile        |   1 +
 drivers/reset/reset-sunplus.c | 159 ++++++++++++++++++++++++++++++++++
 4 files changed, 169 insertions(+)
 create mode 100644 drivers/reset/reset-sunplus.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 652f42cab..6caffd6d0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2662,6 +2662,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 be799a5ab..50695ab47 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -249,6 +249,14 @@ config RESET_TI_SYSCON
 	  you wish to use the reset framework for such memory-mapped devices,
 	  say Y here. Otherwise, say N.
 
+config RESET_SUNPLUS
+	bool "Sunplus SoCs Reset Driver"
+	help
+	  This enables the reset driver support for Sunplus SP7021 SoC family.
+	  Say Y if you want to control reset signals by the reset controller.
+	  Otherwise, say N.
+	  This driver is selected automatically by platform config.
+
 config RESET_UNIPHIER
 	tristate "Reset controller driver for UniPhier SoCs"
 	depends on ARCH_UNIPHIER || COMPILE_TEST
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 21d46d886..f03403e97 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o
 obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
 obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
 obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
+obj-$(CONFIG_RESET_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..696efd75e
--- /dev/null
+++ b/drivers/reset/reset-sunplus.c
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * SP7021 reset driver
+ *
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ *       All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/reboot.h>
+
+#if defined(CONFIG_SOC_SP7021)
+#include <dt-bindings/reset/sp-sp7021.h>
+#elif defined(CONFIG_SOC_Q645)
+#include <dt-bindings/reset/sp-q645.h>
+#endif
+
+#define BITASSERT(id, val)          ((1 << (16 + id)) | (val << id))
+
+
+struct sp_reset_data {
+	struct reset_controller_dev	rcdev;
+	void __iomem			*membase;
+} sp_reset;
+
+
+static inline struct sp_reset_data *
+to_sp_reset_data(struct reset_controller_dev *rcdev)
+{
+	return container_of(rcdev, struct sp_reset_data, rcdev);
+}
+
+static int sp_reset_update(struct reset_controller_dev *rcdev,
+			      unsigned long id, bool assert)
+{
+	struct sp_reset_data *data = to_sp_reset_data(rcdev);
+	int reg_width = sizeof(u32)/2;
+	int bank = id / (reg_width * BITS_PER_BYTE);
+	int offset = id % (reg_width * BITS_PER_BYTE);
+	void __iomem *addr;
+
+	addr = data->membase + (bank * 4);
+
+	if (assert)
+		writel(BITASSERT(offset, 1), addr);
+	else
+		writel(BITASSERT(offset, 0), addr);
+
+	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_data *data = to_sp_reset_data(rcdev);
+	int reg_width = sizeof(u32)/2;
+	int bank = id / (reg_width * BITS_PER_BYTE);
+	int offset = id % (reg_width * BITS_PER_BYTE);
+	u32 reg;
+
+	reg = readl(data->membase + (bank * 4));
+
+	return !!(reg & BIT(offset));
+}
+
+static int sp_restart(struct notifier_block *this, unsigned long mode,
+				void *cmd)
+{
+	sp_reset_assert(&sp_reset.rcdev, RST_SYSTEM);
+	sp_reset_deassert(&sp_reset.rcdev, RST_SYSTEM);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block sp_restart_nb = {
+	.notifier_call = sp_restart,
+	.priority = 192,
+};
+
+static const struct reset_control_ops sp_reset_ops = {
+	.assert		= sp_reset_assert,
+	.deassert	= sp_reset_deassert,
+	.status		= sp_reset_status,
+};
+
+static const struct of_device_id sp_reset_dt_ids[] = {
+	{ .compatible = "sunplus,sp7021-reset", },
+	{ .compatible = "sunplus,q645-reset", },
+	{ /* sentinel */ },
+};
+
+static int sp_reset_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct sp_reset_data *data = &sp_reset;
+	void __iomem *membase;
+	struct resource *res;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	membase = devm_ioremap(dev, res->start, resource_size(res));
+	if (IS_ERR(membase))
+		return PTR_ERR(membase);
+
+	data->membase = membase;
+	data->rcdev.owner = THIS_MODULE;
+	data->rcdev.nr_resets = RST_MAX;
+	data->rcdev.ops = &sp_reset_ops;
+	data->rcdev.of_node = dev->of_node;
+	register_restart_handler(&sp_restart_nb);
+
+	return devm_reset_controller_register(dev, &data->rcdev);
+}
+
+static struct platform_driver sp_reset_driver = {
+	.probe	= sp_reset_probe,
+	.driver = {
+		.name = "sunplus-reset",
+		.of_match_table	= sp_reset_dt_ids,
+	},
+};
+
+static int __init sp_reset_init(void)
+{
+	return platform_driver_register(&sp_reset_driver);
+}
+arch_initcall(sp_reset_init);
+
+MODULE_AUTHOR("Edwin Chiu <edwin.chiu@sunplus.com>");
+MODULE_DESCRIPTION("Sunplus Reset Driver");
+MODULE_LICENSE("GPL");
-- 
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] 124+ messages in thread

* [PATCH v3 4/8] reset: Add Sunplus SP7021 reset driver
@ 2021-11-01  5:01         ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-01  5:01 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add reset driver for Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 MAINTAINERS                   |   1 +
 drivers/reset/Kconfig         |   8 ++
 drivers/reset/Makefile        |   1 +
 drivers/reset/reset-sunplus.c | 159 ++++++++++++++++++++++++++++++++++
 4 files changed, 169 insertions(+)
 create mode 100644 drivers/reset/reset-sunplus.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 652f42cab..6caffd6d0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2662,6 +2662,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 be799a5ab..50695ab47 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -249,6 +249,14 @@ config RESET_TI_SYSCON
 	  you wish to use the reset framework for such memory-mapped devices,
 	  say Y here. Otherwise, say N.
 
+config RESET_SUNPLUS
+	bool "Sunplus SoCs Reset Driver"
+	help
+	  This enables the reset driver support for Sunplus SP7021 SoC family.
+	  Say Y if you want to control reset signals by the reset controller.
+	  Otherwise, say N.
+	  This driver is selected automatically by platform config.
+
 config RESET_UNIPHIER
 	tristate "Reset controller driver for UniPhier SoCs"
 	depends on ARCH_UNIPHIER || COMPILE_TEST
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 21d46d886..f03403e97 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o
 obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
 obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
 obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
+obj-$(CONFIG_RESET_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..696efd75e
--- /dev/null
+++ b/drivers/reset/reset-sunplus.c
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * SP7021 reset driver
+ *
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ *       All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/reboot.h>
+
+#if defined(CONFIG_SOC_SP7021)
+#include <dt-bindings/reset/sp-sp7021.h>
+#elif defined(CONFIG_SOC_Q645)
+#include <dt-bindings/reset/sp-q645.h>
+#endif
+
+#define BITASSERT(id, val)          ((1 << (16 + id)) | (val << id))
+
+
+struct sp_reset_data {
+	struct reset_controller_dev	rcdev;
+	void __iomem			*membase;
+} sp_reset;
+
+
+static inline struct sp_reset_data *
+to_sp_reset_data(struct reset_controller_dev *rcdev)
+{
+	return container_of(rcdev, struct sp_reset_data, rcdev);
+}
+
+static int sp_reset_update(struct reset_controller_dev *rcdev,
+			      unsigned long id, bool assert)
+{
+	struct sp_reset_data *data = to_sp_reset_data(rcdev);
+	int reg_width = sizeof(u32)/2;
+	int bank = id / (reg_width * BITS_PER_BYTE);
+	int offset = id % (reg_width * BITS_PER_BYTE);
+	void __iomem *addr;
+
+	addr = data->membase + (bank * 4);
+
+	if (assert)
+		writel(BITASSERT(offset, 1), addr);
+	else
+		writel(BITASSERT(offset, 0), addr);
+
+	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_data *data = to_sp_reset_data(rcdev);
+	int reg_width = sizeof(u32)/2;
+	int bank = id / (reg_width * BITS_PER_BYTE);
+	int offset = id % (reg_width * BITS_PER_BYTE);
+	u32 reg;
+
+	reg = readl(data->membase + (bank * 4));
+
+	return !!(reg & BIT(offset));
+}
+
+static int sp_restart(struct notifier_block *this, unsigned long mode,
+				void *cmd)
+{
+	sp_reset_assert(&sp_reset.rcdev, RST_SYSTEM);
+	sp_reset_deassert(&sp_reset.rcdev, RST_SYSTEM);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block sp_restart_nb = {
+	.notifier_call = sp_restart,
+	.priority = 192,
+};
+
+static const struct reset_control_ops sp_reset_ops = {
+	.assert		= sp_reset_assert,
+	.deassert	= sp_reset_deassert,
+	.status		= sp_reset_status,
+};
+
+static const struct of_device_id sp_reset_dt_ids[] = {
+	{ .compatible = "sunplus,sp7021-reset", },
+	{ .compatible = "sunplus,q645-reset", },
+	{ /* sentinel */ },
+};
+
+static int sp_reset_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct sp_reset_data *data = &sp_reset;
+	void __iomem *membase;
+	struct resource *res;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	membase = devm_ioremap(dev, res->start, resource_size(res));
+	if (IS_ERR(membase))
+		return PTR_ERR(membase);
+
+	data->membase = membase;
+	data->rcdev.owner = THIS_MODULE;
+	data->rcdev.nr_resets = RST_MAX;
+	data->rcdev.ops = &sp_reset_ops;
+	data->rcdev.of_node = dev->of_node;
+	register_restart_handler(&sp_restart_nb);
+
+	return devm_reset_controller_register(dev, &data->rcdev);
+}
+
+static struct platform_driver sp_reset_driver = {
+	.probe	= sp_reset_probe,
+	.driver = {
+		.name = "sunplus-reset",
+		.of_match_table	= sp_reset_dt_ids,
+	},
+};
+
+static int __init sp_reset_init(void)
+{
+	return platform_driver_register(&sp_reset_driver);
+}
+arch_initcall(sp_reset_init);
+
+MODULE_AUTHOR("Edwin Chiu <edwin.chiu@sunplus.com>");
+MODULE_DESCRIPTION("Sunplus Reset Driver");
+MODULE_LICENSE("GPL");
-- 
2.33.1


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

* [PATCH v3 5/8] dt-bindings: clock: Add bindings for SP7021 clock driver
  2021-11-01  5:01       ` Qin Jian
@ 2021-11-01  5:01         ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-01  5:01 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add documentation to describe Sunplus SP7021 clock driver bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../bindings/clock/sunplus,sp7021-clkc.yaml   |  38 ++++++
 MAINTAINERS                                   |   2 +
 include/dt-bindings/clock/sp-sp7021.h         | 112 ++++++++++++++++++
 3 files changed, 152 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..1ce7e41d8
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.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/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
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    clkc: clkc@9c000000 {
+      compatible = "sunplus,sp7021-clkc";
+      #clock-cells = <1>;
+      reg = <0x9c000000 0x280>;
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 6caffd6d0..90ebb823f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2661,8 +2661,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..1ae9c4083
--- /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 SYSTEM		0x10
+#define RTC			0x12
+#define IOCTL		0x13
+#define IOP			0x14
+#define OTPRX		0x15
+#define NOC			0x16
+#define BR			0x17
+#define RBUS_L00	0x18
+#define SPIFL		0x19
+#define SDCTRL0		0x1a
+#define PERI0		0x1b
+#define A926		0x1d
+#define UMCTL2		0x1e
+#define PERI1		0x1f
+
+#define DDR_PHY0	0x20
+#define ACHIP		0x22
+#define STC0		0x24
+#define STC_AV0		0x25
+#define STC_AV1		0x26
+#define STC_AV2		0x27
+#define UA0			0x28
+#define UA1			0x29
+#define UA2			0x2a
+#define UA3			0x2b
+#define UA4			0x2c
+#define HWUA		0x2d
+#define DDC0		0x2e
+#define UADMA		0x2f
+
+#define CBDMA0		0x30
+#define CBDMA1		0x31
+#define SPI_COMBO_0	0x32
+#define SPI_COMBO_1	0x33
+#define SPI_COMBO_2	0x34
+#define SPI_COMBO_3	0x35
+#define AUD			0x36
+#define USBC0		0x3a
+#define USBC1		0x3b
+#define UPHY0		0x3d
+#define UPHY1		0x3e
+
+#define I2CM0		0x40
+#define I2CM1		0x41
+#define I2CM2		0x42
+#define I2CM3		0x43
+#define PMC			0x4d
+#define CARD_CTL0	0x4e
+#define CARD_CTL1	0x4f
+
+#define CARD_CTL4	0x52
+#define BCH			0x54
+#define DDFCH		0x5b
+#define CSIIW0		0x5c
+#define CSIIW1		0x5d
+#define MIPICSI0	0x5e
+#define MIPICSI1	0x5f
+
+#define HDMI_TX		0x60
+#define VPOST		0x65
+
+#define TGEN		0x70
+#define DMIX		0x71
+#define TCON		0x7a
+#define INTERRUPT	0x7f
+
+#define RGST		0x80
+#define GPIO		0x83
+#define RBUS_TOP	0x84
+
+#define MAILBOX		0x96
+#define SPIND		0x9a
+#define I2C2CBUS	0x9b
+#define SEC			0x9d
+#define DVE			0x9e
+#define GPOST0		0x9f
+
+#define OSD0		0xa0
+#define DISP_PWM	0xa2
+#define UADBG		0xa3
+#define DUMMY_MASTER	0xa4
+#define FIO_CTL		0xa5
+#define FPGA		0xa6
+#define L2SW		0xa7
+#define ICM			0xa8
+#define 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] 124+ messages in thread

* [PATCH v3 5/8] dt-bindings: clock: Add bindings for SP7021 clock driver
@ 2021-11-01  5:01         ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-01  5:01 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add documentation to describe Sunplus SP7021 clock driver bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../bindings/clock/sunplus,sp7021-clkc.yaml   |  38 ++++++
 MAINTAINERS                                   |   2 +
 include/dt-bindings/clock/sp-sp7021.h         | 112 ++++++++++++++++++
 3 files changed, 152 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..1ce7e41d8
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.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/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
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    clkc: clkc@9c000000 {
+      compatible = "sunplus,sp7021-clkc";
+      #clock-cells = <1>;
+      reg = <0x9c000000 0x280>;
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 6caffd6d0..90ebb823f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2661,8 +2661,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..1ae9c4083
--- /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 SYSTEM		0x10
+#define RTC			0x12
+#define IOCTL		0x13
+#define IOP			0x14
+#define OTPRX		0x15
+#define NOC			0x16
+#define BR			0x17
+#define RBUS_L00	0x18
+#define SPIFL		0x19
+#define SDCTRL0		0x1a
+#define PERI0		0x1b
+#define A926		0x1d
+#define UMCTL2		0x1e
+#define PERI1		0x1f
+
+#define DDR_PHY0	0x20
+#define ACHIP		0x22
+#define STC0		0x24
+#define STC_AV0		0x25
+#define STC_AV1		0x26
+#define STC_AV2		0x27
+#define UA0			0x28
+#define UA1			0x29
+#define UA2			0x2a
+#define UA3			0x2b
+#define UA4			0x2c
+#define HWUA		0x2d
+#define DDC0		0x2e
+#define UADMA		0x2f
+
+#define CBDMA0		0x30
+#define CBDMA1		0x31
+#define SPI_COMBO_0	0x32
+#define SPI_COMBO_1	0x33
+#define SPI_COMBO_2	0x34
+#define SPI_COMBO_3	0x35
+#define AUD			0x36
+#define USBC0		0x3a
+#define USBC1		0x3b
+#define UPHY0		0x3d
+#define UPHY1		0x3e
+
+#define I2CM0		0x40
+#define I2CM1		0x41
+#define I2CM2		0x42
+#define I2CM3		0x43
+#define PMC			0x4d
+#define CARD_CTL0	0x4e
+#define CARD_CTL1	0x4f
+
+#define CARD_CTL4	0x52
+#define BCH			0x54
+#define DDFCH		0x5b
+#define CSIIW0		0x5c
+#define CSIIW1		0x5d
+#define MIPICSI0	0x5e
+#define MIPICSI1	0x5f
+
+#define HDMI_TX		0x60
+#define VPOST		0x65
+
+#define TGEN		0x70
+#define DMIX		0x71
+#define TCON		0x7a
+#define INTERRUPT	0x7f
+
+#define RGST		0x80
+#define GPIO		0x83
+#define RBUS_TOP	0x84
+
+#define MAILBOX		0x96
+#define SPIND		0x9a
+#define I2C2CBUS	0x9b
+#define SEC			0x9d
+#define DVE			0x9e
+#define GPOST0		0x9f
+
+#define OSD0		0xa0
+#define DISP_PWM	0xa2
+#define UADBG		0xa3
+#define DUMMY_MASTER	0xa4
+#define FIO_CTL		0xa5
+#define FPGA		0xa6
+#define L2SW		0xa7
+#define ICM			0xa8
+#define AXI_GLOBAL	0xa9
+
+#define CLK_MAX		0xb0
+
+#endif
-- 
2.33.1


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

* [PATCH v3 6/8] clk: Add Sunplus SP7021 clock driver
  2021-11-01  5:01       ` Qin Jian
@ 2021-11-01  5:01         ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-01  5:01 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add clock driver for Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 MAINTAINERS              |   1 +
 drivers/clk/Kconfig      |   9 +
 drivers/clk/Makefile     |   1 +
 drivers/clk/clk-sp7021.c | 770 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 781 insertions(+)
 create mode 100644 drivers/clk/clk-sp7021.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 90ebb823f..5069f552f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2663,6 +2663,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 c5b3dc973..1cd7ae7a3 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -334,6 +334,15 @@ 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"
+	help
+	  This driver supports the Sunplus SP7021 SoC clocks.
+	  It implemented SP7021 PLLs/gate.
+	  Not all features of the PLL are currently supported
+	  by the driver.
+	  This driver is selected automatically by platform config.
+
 config COMMON_CLK_STM32MP157
 	def_bool COMMON_CLK && MACH_STM32MP157
 	help
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index e42312121..f15bb5070 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -60,6 +60,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..39ff84825
--- /dev/null
+++ b/drivers/clk/clk-sp7021.c
@@ -0,0 +1,770 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ *       All rights reserved.
+ */
+//#define DEBUG
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <dt-bindings/clock/sp-sp7021.h>
+
+//#define TRACE	pr_info("### %s:%d (%d)\n", __func__, __LINE__, (clk->reg - REG(4, 0)) / 4)
+#define TRACE
+
+#ifndef clk_readl
+#define clk_readl  readl
+#define clk_writel writel
+#endif
+
+#define MASK_SET(shift, width, value) \
+({ \
+	u32 m = ((1 << (width)) - 1) << (shift); \
+	(m << 16) | (((value) << (shift)) & m); \
+})
+#define MASK_GET(shift, width, value)	(((value) >> (shift)) & ((1 << (width)) - 1))
+
+#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)
+
+#define EXTCLK		"extclk"
+
+/* 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
+};
+
+struct sp_pll {
+	struct clk_hw	hw;
+	void __iomem	*reg;
+	spinlock_t	*lock;
+	int		pd_bit;		/* power down bit idx */
+	int		bp_bit;		/* bypass bit idx */
+	unsigned long	brate;		/* base rate, FIXME: replace brate with muldiv */
+	int		div_shift;
+	int		div_width;
+	u32		p[P_MAX];	/* for hold PLLTV/PLLA parameters */
+};
+#define to_sp_pll(_hw)	container_of(_hw, struct sp_pll, hw)
+
+#define clk_regs	(moon_regs + 0x000) /* G0 ~ CLKEN */
+#define pll_regs	(moon_regs + 0x200) /* G4 ~ PLL */
+static void __iomem *moon_regs;
+
+#define P_EXTCLK	(1 << 16)
+static const char * const parents[] = {
+	"pllsys",
+	"extclk",
+};
+
+/* FIXME: parent clk incorrect cause clk_get_rate got error value */
+static const u32 gates[] = {
+	SYSTEM,
+	RTC,
+	IOCTL,
+	IOP,
+	OTPRX,
+	NOC,
+	BR,
+	RBUS_L00,
+	SPIFL,
+	SDCTRL0,
+	PERI0 | P_EXTCLK,
+	A926,
+	UMCTL2,
+	PERI1 | P_EXTCLK,
+
+	DDR_PHY0,
+	ACHIP,
+	STC0,
+	STC_AV0,
+	STC_AV1,
+	STC_AV2,
+	UA0 | P_EXTCLK,
+	UA1 | P_EXTCLK,
+	UA2 | P_EXTCLK,
+	UA3 | P_EXTCLK,
+	UA4 | P_EXTCLK,
+	HWUA | P_EXTCLK,
+	DDC0,
+	UADMA | P_EXTCLK,
+
+	CBDMA0,
+	CBDMA1,
+	SPI_COMBO_0,
+	SPI_COMBO_1,
+	SPI_COMBO_2,
+	SPI_COMBO_3,
+	AUD,
+	USBC0,
+	USBC1,
+	UPHY0,
+	UPHY1,
+
+	I2CM0,
+	I2CM1,
+	I2CM2,
+	I2CM3,
+	PMC,
+	CARD_CTL0,
+	CARD_CTL1,
+
+	CARD_CTL4,
+	BCH,
+	DDFCH,
+	CSIIW0,
+	CSIIW1,
+	MIPICSI0,
+	MIPICSI1,
+
+	HDMI_TX,
+	VPOST,
+
+	TGEN,
+	DMIX,
+	TCON,
+	INTERRUPT,
+
+	RGST,
+	GPIO,
+	RBUS_TOP,
+
+	MAILBOX,
+	SPIND,
+	I2C2CBUS,
+	SEC,
+	GPOST0,
+	DVE,
+
+	OSD0,
+	DISP_PWM,
+	UADBG,
+	DUMMY_MASTER,
+	FIO_CTL,
+	FPGA,
+	L2SW,
+	ICM,
+	AXI_GLOBAL,
+};
+static struct clk *clks[CLK_MAX];
+static struct clk_onecell_data clk_data;
+
+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 *******************************************/
+
+//#define PLLTV_STEP_DIR (?) /* Unit: HZ */
+
+/* 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;
+#ifdef PLLTV_STEP_DIR
+	u32 step = (PLLTV_STEP_DIR > 0) ? PLLTV_STEP_DIR : -PLLTV_STEP_DIR;
+	int calc_times = 1000000 / step;
+#endif
+	unsigned long fvco, nf;
+
+	TRACE;
+
+	/* check freq */
+	if (freq < F_MIN) {
+		pr_warn("[%s:%d] freq:%lu < F_MIN:%lu, round up\n",
+			__func__, __LINE__, freq, F_MIN);
+		freq = F_MIN;
+	} else if (freq > F_MAX) {
+		pr_warn("[%s:%d] freq:%lu > F_MAX:%lu, round down\n",
+			__func__, __LINE__, freq, F_MAX);
+		freq = F_MAX;
+	}
+
+#ifdef PLLTV_STEP_DIR
+	if ((freq % step) != 0)
+		freq += step - (freq % step) + ((PLLTV_STEP_DIR > 0) ? 0 : PLLTV_STEP_DIR);
+#endif
+
+#ifdef PLLTV_STEP_DIR
+CALC:
+	if (!calc_times) {
+		pr_err("[%s:%d] freq:%lu out of recalc times\n", __func__, __LINE__, freq);
+		return -ETIMEOUT;
+	}
+#endif
+
+	/* 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) {
+#ifdef PLLTV_STEP_DIR
+		freq += PLLTV_STEP_DIR;
+		calc_times--;
+		goto CALC;
+#else
+		pr_err("[%s:%d] freq:%lu not found a valid setting\n", __func__, __LINE__, freq);
+		return -EINVAL;
+#endif
+	}
+
+	/* save parameters */
+	clk->p[SEL_FRA] = 0;
+	clk->p[DIVR]    = r;
+	clk->p[DIVN]    = n;
+	clk->p[DIVM]    = m;
+
+	pr_info("[%s:%d]   M:%u N:%u R:%u   CKREF:%lu  FVCO:%lu  FCKOUT:%lu\n",
+		__func__, __LINE__, m, n, r, (fvco / m), fvco, freq);
+
+	return freq;
+}
+
+/* parameters for PLLTV fractional divider */
+/* FIXME: better parameter naming */
+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 diff_min_quotient = 210000000, diff_min_remainder = 0;
+	u32 diff_min_sign = 0;
+	unsigned long fvco, nf, f, fout = 0;
+	int sdm, ph;
+
+	TRACE;
+	/* check freq */
+	if (freq < F_MIN) {
+		pr_warn("[%s:%d] freq:%lu < F_MIN:%lu, round up\n",
+			__func__, __LINE__, freq, F_MIN);
+		freq = F_MIN;
+	} else if (freq > F_MAX) {
+		pr_warn("[%s:%d] freq:%lu > F_MAX:%lu, round down\n",
+			__func__, __LINE__, freq, F_MAX);
+		freq = F_MAX;
+	}
+
+	/* DIVR 0~3 */
+	for (r = 0; r <= 3; r++) {
+		fvco = freq << r;
+		if (fvco <= FVCO_MAX)
+			break;
+	}
+	pr_info("freq:%lu fvco:%lu R:%u\n", freq, fvco, r);
+	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 diff_freq;
+				u32 diff_freq_quotient = 0, diff_freq_remainder = 0;
+				u32 diff_freq_sign = 0; /* 0:Positive number, 1:Negative number */
+
+				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)
+					diff_freq = (f * (nint + pp[2]) / pp[0]) -
+								(f * (mod - nfra) / mod / pp[4]);
+				else
+					diff_freq = (f * (nint) / pp[0]);
+
+				diff_freq_quotient  = diff_freq / m;
+				diff_freq_remainder = ((diff_freq % m) * 1000) / m;
+
+				pr_info("m = %d N.f = %2d.%03d%03d, nfra = %d/%d  fout = %u\n",
+					m, nint, (nfra * 1000) / mod,
+					(((nfra * 1000) % mod) * 1000) / mod,
+					nfra, mod, diff_freq_quotient);
+
+				if (freq > diff_freq_quotient) {
+					diff_freq_quotient  = freq - diff_freq_quotient - 1;
+					diff_freq_remainder = 1000 - diff_freq_remainder;
+					diff_freq_sign = 1;
+				} else {
+					diff_freq_quotient = diff_freq_quotient - freq;
+					diff_freq_sign = 0;
+				}
+
+				if ((diff_min_quotient > diff_freq_quotient) ||
+					((diff_min_quotient == diff_freq_quotient) &&
+					(diff_min_remainder > diff_freq_remainder))) {
+
+					/* found a closer freq, save parameters */
+					TRACE;
+					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 = diff_freq / m;
+					diff_min_quotient = diff_freq_quotient;
+					diff_min_remainder = diff_freq_remainder;
+					diff_min_sign = diff_freq_sign;
+				}
+			}
+		}
+	}
+
+	if (!fout) {
+		pr_err("[%s:%d] freq:%lu not found a valid setting\n", __func__, __LINE__, freq);
+		return -EINVAL;
+	}
+
+	//pr_info("MOD:%u PH_SEL:%u NFRA:%u M:%u R:%u\n",
+	//	mods[clk->p[SDM_MOD]], clk->p[PH_SEL], clk->p[NFRA], clk->p[DIVM], clk->p[DIVR]);
+
+	pr_info("[%s:%d] real out:%lu/%lu Hz(%u, %u, sign %u)\n",
+		__func__, __LINE__, fout, freq,
+		diff_min_quotient, diff_min_remainder, diff_min_sign);
+
+	return fout;
+}
+
+static long plltv_div(struct sp_pll *clk, unsigned long freq)
+{
+	TRACE;
+	if (freq % 100)
+		return plltv_fractional_div(clk, freq);
+	else
+		return plltv_integer_div(clk, freq);
+}
+
+static void plltv_set_rate(struct sp_pll *clk)
+{
+	u32 reg;
+
+	//pr_info("MOD:%u PH_SEL:%u NFRA:%u M:%u R:%u\n",
+	//	mods[clk->p[SDM_MOD]], clk->p[PH_SEL], clk->p[NFRA], clk->p[DIVM], clk->p[DIVR]);
+	reg  = MASK_SET(1, 1, clk->p[SEL_FRA]);
+	reg |= MASK_SET(2, 1, clk->p[SDM_MOD]);
+	reg |= MASK_SET(4, 1, clk->p[PH_SEL]);
+	reg |= MASK_SET(6, 7, clk->p[NFRA]);
+	clk_writel(reg, clk->reg);
+
+	reg  = MASK_SET(7, 2, clk->p[DIVR]);
+	clk_writel(reg, clk->reg + 4);
+
+	reg  = MASK_SET(0, 8, clk->p[DIVN] - 1);
+	reg |= MASK_SET(8, 7, clk->p[DIVM] - 1);
+	clk_writel(reg, clk->reg + 8);
+}
+
+/******************************************** PLL_A ********************************************/
+
+/* from Q628_PLLs_REG_setting.xlsx */
+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++) {
+		clk_writel(0xffff0000 | pp[i], clk->reg + (i * 4));
+		pr_info("%04x\n", pp[i]);
+	}
+}
+
+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;
+
+	TRACE;
+	//pr_info("round_rate: %lu %lu\n", rate, *prate);
+
+	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 = clk_readl(clk->reg);
+	unsigned long ret;
+
+	//TRACE;
+	if (reg & BIT(clk->bp_bit))
+		ret = prate; /* bypass */
+	else if (clk->div_width == DIV_A) {
+		ret = pa[clk->p[0]].rate;
+		//reg = clk_readl(clk->reg + 12); // G4.10 K_SDM_A
+	} else if (clk->div_width == DIV_TV) {
+		u32 m, r, reg2;
+
+		r = MASK_GET(7, 2, clk_readl(clk->reg + 4));
+		reg2 = clk_readl(clk->reg + 8);
+		m = MASK_GET(8, 7, reg2) + 1;
+
+		if (reg & BIT(1)) { /* SEL_FRA */
+			/* fractional divider */
+			u32 sdm  = MASK_GET(2, 1, reg);
+			u32 ph   = MASK_GET(4, 1, reg);
+			u32 nfra = MASK_GET(6, 7, 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 = MASK_GET(0, 8, reg2) + 1;
+
+			ret = (prate / m * n) >> r;
+		}
+	} else {
+		u32 fbdiv = MASK_GET(clk->div_shift, clk->div_width, reg) + 1;
+
+		ret = clk->brate * fbdiv;
+	}
+	//pr_info("recalc_rate: %lu -> %lu\n", prate, ret);
+
+	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;
+
+	//TRACE;
+	pr_info("set_rate: %lu -> %lu\n", prate, rate);
+
+	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);
+
+		reg |= MASK_SET(clk->div_shift, clk->div_width, fbdiv - 1);
+	}
+
+	clk_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;
+
+	TRACE;
+	spin_lock_irqsave(clk->lock, flags);
+	clk_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;
+
+	TRACE;
+	spin_lock_irqsave(clk->lock, flags);
+	clk_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 clk_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,
+};
+
+struct clk *clk_register_sp_pll(const char *name, const char *parent,
+		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 *clk;
+	//unsigned long flags = 0;
+	struct clk_init_data initd = {
+		.name = name,
+		.parent_names = &parent,
+		.ops = (bp_bit >= 0) ? &sp_pll_ops : &sp_pll_sub_ops,
+		.num_parents = 1,
+		.flags = CLK_IGNORE_UNUSED
+	};
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	if (reg == PLLSYS_CTL)
+		initd.flags |= CLK_IS_CRITICAL;
+
+	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;
+
+	clk = clk_register(NULL, &pll->hw);
+	if (WARN_ON(IS_ERR(clk))) {
+		kfree(pll);
+	} else {
+		pr_info("%-20s%lu\n", name, clk_get_rate(clk));
+		clk_register_clkdev(clk, NULL, name);
+	}
+
+	return clk;
+}
+
+static void __init sp_clk_setup(struct device_node *np)
+{
+	int i, j;
+
+	pr_info("sp-clkc init\n");
+
+	moon_regs = of_iomap(np, 0);
+	if (WARN_ON(!moon_regs)) {
+		pr_warn("sp-clkc regs missing.\n");
+		return; // -EIO
+	}
+
+	/* TODO: PLLs initial */
+
+	/* PLL_A */
+	clks[PLL_A] = clk_register_sp_pll("plla", EXTCLK,
+			PLLA_CTL, 11, 12, 27000000, 0, DIV_A, &plla_lock);
+
+	/* PLL_E */
+	clks[PLL_E] = clk_register_sp_pll("plle", EXTCLK,
+			PLLE_CTL, 6, 2, 50000000, 0, 0, &plle_lock);
+	clks[PLL_E_2P5] = clk_register_sp_pll("plle_2p5", "plle",
+			PLLE_CTL, 13, -1, 2500000, 0, 0, &plle_lock);
+	clks[PLL_E_25] = clk_register_sp_pll("plle_25", "plle",
+			PLLE_CTL, 12, -1, 25000000, 0, 0, &plle_lock);
+	clks[PLL_E_112P5] = clk_register_sp_pll("plle_112p5", "plle",
+			PLLE_CTL, 11, -1, 112500000, 0, 0, &plle_lock);
+
+	/* PLL_F */
+	clks[PLL_F] = clk_register_sp_pll("pllf", EXTCLK,
+			PLLF_CTL, 0, 10, 13500000, 1, 4, &pllf_lock);
+
+	/* PLL_TV */
+	clks[PLL_TV] = clk_register_sp_pll("plltv", EXTCLK,
+			PLLTV_CTL, 0, 15, 27000000, 0, DIV_TV, &plltv_lock);
+	clks[PLL_TV_A] = clk_register_divider(NULL, "plltv_a", "plltv", 0,
+			PLLTV_CTL + 4, 5, 1,
+			CLK_DIVIDER_POWER_OF_TWO, &plltv_lock);
+	clk_register_clkdev(clks[PLL_TV_A], NULL, "plltv_a");
+
+	/* PLL_SYS */
+	clks[PLL_SYS] = clk_register_sp_pll("pllsys", EXTCLK,
+			PLLSYS_CTL, 10, 9, 13500000, 0, 4, &pllsys_lock);
+
+	/* gates */
+	for (i = 0; i < ARRAY_SIZE(gates); i++) {
+		char s[10];
+
+		j = gates[i] & 0xffff;
+		sprintf(s, "clken%02x", j);
+		clks[j] = clk_register_gate(NULL, s, parents[gates[i] >> 16], CLK_IGNORE_UNUSED,
+			clk_regs + (j >> 4) * 4, j & 0x0f,
+			CLK_GATE_HIWORD_MASK, NULL);
+	}
+
+	clk_data.clks = clks;
+	clk_data.clk_num = ARRAY_SIZE(clks);
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+
+CLK_OF_DECLARE(sp_clkc, "sunplus,sp7021-clkc", sp_clk_setup);
+
+MODULE_AUTHOR("Qin Jian <qinjian@cqplus1.com>");
+MODULE_DESCRIPTION("Sunplus SP7021 Clock Driver");
+MODULE_LICENSE("GPL v2");
-- 
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] 124+ messages in thread

* [PATCH v3 6/8] clk: Add Sunplus SP7021 clock driver
@ 2021-11-01  5:01         ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-01  5:01 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add clock driver for Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 MAINTAINERS              |   1 +
 drivers/clk/Kconfig      |   9 +
 drivers/clk/Makefile     |   1 +
 drivers/clk/clk-sp7021.c | 770 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 781 insertions(+)
 create mode 100644 drivers/clk/clk-sp7021.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 90ebb823f..5069f552f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2663,6 +2663,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 c5b3dc973..1cd7ae7a3 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -334,6 +334,15 @@ 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"
+	help
+	  This driver supports the Sunplus SP7021 SoC clocks.
+	  It implemented SP7021 PLLs/gate.
+	  Not all features of the PLL are currently supported
+	  by the driver.
+	  This driver is selected automatically by platform config.
+
 config COMMON_CLK_STM32MP157
 	def_bool COMMON_CLK && MACH_STM32MP157
 	help
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index e42312121..f15bb5070 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -60,6 +60,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..39ff84825
--- /dev/null
+++ b/drivers/clk/clk-sp7021.c
@@ -0,0 +1,770 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ *       All rights reserved.
+ */
+//#define DEBUG
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <dt-bindings/clock/sp-sp7021.h>
+
+//#define TRACE	pr_info("### %s:%d (%d)\n", __func__, __LINE__, (clk->reg - REG(4, 0)) / 4)
+#define TRACE
+
+#ifndef clk_readl
+#define clk_readl  readl
+#define clk_writel writel
+#endif
+
+#define MASK_SET(shift, width, value) \
+({ \
+	u32 m = ((1 << (width)) - 1) << (shift); \
+	(m << 16) | (((value) << (shift)) & m); \
+})
+#define MASK_GET(shift, width, value)	(((value) >> (shift)) & ((1 << (width)) - 1))
+
+#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)
+
+#define EXTCLK		"extclk"
+
+/* 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
+};
+
+struct sp_pll {
+	struct clk_hw	hw;
+	void __iomem	*reg;
+	spinlock_t	*lock;
+	int		pd_bit;		/* power down bit idx */
+	int		bp_bit;		/* bypass bit idx */
+	unsigned long	brate;		/* base rate, FIXME: replace brate with muldiv */
+	int		div_shift;
+	int		div_width;
+	u32		p[P_MAX];	/* for hold PLLTV/PLLA parameters */
+};
+#define to_sp_pll(_hw)	container_of(_hw, struct sp_pll, hw)
+
+#define clk_regs	(moon_regs + 0x000) /* G0 ~ CLKEN */
+#define pll_regs	(moon_regs + 0x200) /* G4 ~ PLL */
+static void __iomem *moon_regs;
+
+#define P_EXTCLK	(1 << 16)
+static const char * const parents[] = {
+	"pllsys",
+	"extclk",
+};
+
+/* FIXME: parent clk incorrect cause clk_get_rate got error value */
+static const u32 gates[] = {
+	SYSTEM,
+	RTC,
+	IOCTL,
+	IOP,
+	OTPRX,
+	NOC,
+	BR,
+	RBUS_L00,
+	SPIFL,
+	SDCTRL0,
+	PERI0 | P_EXTCLK,
+	A926,
+	UMCTL2,
+	PERI1 | P_EXTCLK,
+
+	DDR_PHY0,
+	ACHIP,
+	STC0,
+	STC_AV0,
+	STC_AV1,
+	STC_AV2,
+	UA0 | P_EXTCLK,
+	UA1 | P_EXTCLK,
+	UA2 | P_EXTCLK,
+	UA3 | P_EXTCLK,
+	UA4 | P_EXTCLK,
+	HWUA | P_EXTCLK,
+	DDC0,
+	UADMA | P_EXTCLK,
+
+	CBDMA0,
+	CBDMA1,
+	SPI_COMBO_0,
+	SPI_COMBO_1,
+	SPI_COMBO_2,
+	SPI_COMBO_3,
+	AUD,
+	USBC0,
+	USBC1,
+	UPHY0,
+	UPHY1,
+
+	I2CM0,
+	I2CM1,
+	I2CM2,
+	I2CM3,
+	PMC,
+	CARD_CTL0,
+	CARD_CTL1,
+
+	CARD_CTL4,
+	BCH,
+	DDFCH,
+	CSIIW0,
+	CSIIW1,
+	MIPICSI0,
+	MIPICSI1,
+
+	HDMI_TX,
+	VPOST,
+
+	TGEN,
+	DMIX,
+	TCON,
+	INTERRUPT,
+
+	RGST,
+	GPIO,
+	RBUS_TOP,
+
+	MAILBOX,
+	SPIND,
+	I2C2CBUS,
+	SEC,
+	GPOST0,
+	DVE,
+
+	OSD0,
+	DISP_PWM,
+	UADBG,
+	DUMMY_MASTER,
+	FIO_CTL,
+	FPGA,
+	L2SW,
+	ICM,
+	AXI_GLOBAL,
+};
+static struct clk *clks[CLK_MAX];
+static struct clk_onecell_data clk_data;
+
+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 *******************************************/
+
+//#define PLLTV_STEP_DIR (?) /* Unit: HZ */
+
+/* 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;
+#ifdef PLLTV_STEP_DIR
+	u32 step = (PLLTV_STEP_DIR > 0) ? PLLTV_STEP_DIR : -PLLTV_STEP_DIR;
+	int calc_times = 1000000 / step;
+#endif
+	unsigned long fvco, nf;
+
+	TRACE;
+
+	/* check freq */
+	if (freq < F_MIN) {
+		pr_warn("[%s:%d] freq:%lu < F_MIN:%lu, round up\n",
+			__func__, __LINE__, freq, F_MIN);
+		freq = F_MIN;
+	} else if (freq > F_MAX) {
+		pr_warn("[%s:%d] freq:%lu > F_MAX:%lu, round down\n",
+			__func__, __LINE__, freq, F_MAX);
+		freq = F_MAX;
+	}
+
+#ifdef PLLTV_STEP_DIR
+	if ((freq % step) != 0)
+		freq += step - (freq % step) + ((PLLTV_STEP_DIR > 0) ? 0 : PLLTV_STEP_DIR);
+#endif
+
+#ifdef PLLTV_STEP_DIR
+CALC:
+	if (!calc_times) {
+		pr_err("[%s:%d] freq:%lu out of recalc times\n", __func__, __LINE__, freq);
+		return -ETIMEOUT;
+	}
+#endif
+
+	/* 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) {
+#ifdef PLLTV_STEP_DIR
+		freq += PLLTV_STEP_DIR;
+		calc_times--;
+		goto CALC;
+#else
+		pr_err("[%s:%d] freq:%lu not found a valid setting\n", __func__, __LINE__, freq);
+		return -EINVAL;
+#endif
+	}
+
+	/* save parameters */
+	clk->p[SEL_FRA] = 0;
+	clk->p[DIVR]    = r;
+	clk->p[DIVN]    = n;
+	clk->p[DIVM]    = m;
+
+	pr_info("[%s:%d]   M:%u N:%u R:%u   CKREF:%lu  FVCO:%lu  FCKOUT:%lu\n",
+		__func__, __LINE__, m, n, r, (fvco / m), fvco, freq);
+
+	return freq;
+}
+
+/* parameters for PLLTV fractional divider */
+/* FIXME: better parameter naming */
+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 diff_min_quotient = 210000000, diff_min_remainder = 0;
+	u32 diff_min_sign = 0;
+	unsigned long fvco, nf, f, fout = 0;
+	int sdm, ph;
+
+	TRACE;
+	/* check freq */
+	if (freq < F_MIN) {
+		pr_warn("[%s:%d] freq:%lu < F_MIN:%lu, round up\n",
+			__func__, __LINE__, freq, F_MIN);
+		freq = F_MIN;
+	} else if (freq > F_MAX) {
+		pr_warn("[%s:%d] freq:%lu > F_MAX:%lu, round down\n",
+			__func__, __LINE__, freq, F_MAX);
+		freq = F_MAX;
+	}
+
+	/* DIVR 0~3 */
+	for (r = 0; r <= 3; r++) {
+		fvco = freq << r;
+		if (fvco <= FVCO_MAX)
+			break;
+	}
+	pr_info("freq:%lu fvco:%lu R:%u\n", freq, fvco, r);
+	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 diff_freq;
+				u32 diff_freq_quotient = 0, diff_freq_remainder = 0;
+				u32 diff_freq_sign = 0; /* 0:Positive number, 1:Negative number */
+
+				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)
+					diff_freq = (f * (nint + pp[2]) / pp[0]) -
+								(f * (mod - nfra) / mod / pp[4]);
+				else
+					diff_freq = (f * (nint) / pp[0]);
+
+				diff_freq_quotient  = diff_freq / m;
+				diff_freq_remainder = ((diff_freq % m) * 1000) / m;
+
+				pr_info("m = %d N.f = %2d.%03d%03d, nfra = %d/%d  fout = %u\n",
+					m, nint, (nfra * 1000) / mod,
+					(((nfra * 1000) % mod) * 1000) / mod,
+					nfra, mod, diff_freq_quotient);
+
+				if (freq > diff_freq_quotient) {
+					diff_freq_quotient  = freq - diff_freq_quotient - 1;
+					diff_freq_remainder = 1000 - diff_freq_remainder;
+					diff_freq_sign = 1;
+				} else {
+					diff_freq_quotient = diff_freq_quotient - freq;
+					diff_freq_sign = 0;
+				}
+
+				if ((diff_min_quotient > diff_freq_quotient) ||
+					((diff_min_quotient == diff_freq_quotient) &&
+					(diff_min_remainder > diff_freq_remainder))) {
+
+					/* found a closer freq, save parameters */
+					TRACE;
+					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 = diff_freq / m;
+					diff_min_quotient = diff_freq_quotient;
+					diff_min_remainder = diff_freq_remainder;
+					diff_min_sign = diff_freq_sign;
+				}
+			}
+		}
+	}
+
+	if (!fout) {
+		pr_err("[%s:%d] freq:%lu not found a valid setting\n", __func__, __LINE__, freq);
+		return -EINVAL;
+	}
+
+	//pr_info("MOD:%u PH_SEL:%u NFRA:%u M:%u R:%u\n",
+	//	mods[clk->p[SDM_MOD]], clk->p[PH_SEL], clk->p[NFRA], clk->p[DIVM], clk->p[DIVR]);
+
+	pr_info("[%s:%d] real out:%lu/%lu Hz(%u, %u, sign %u)\n",
+		__func__, __LINE__, fout, freq,
+		diff_min_quotient, diff_min_remainder, diff_min_sign);
+
+	return fout;
+}
+
+static long plltv_div(struct sp_pll *clk, unsigned long freq)
+{
+	TRACE;
+	if (freq % 100)
+		return plltv_fractional_div(clk, freq);
+	else
+		return plltv_integer_div(clk, freq);
+}
+
+static void plltv_set_rate(struct sp_pll *clk)
+{
+	u32 reg;
+
+	//pr_info("MOD:%u PH_SEL:%u NFRA:%u M:%u R:%u\n",
+	//	mods[clk->p[SDM_MOD]], clk->p[PH_SEL], clk->p[NFRA], clk->p[DIVM], clk->p[DIVR]);
+	reg  = MASK_SET(1, 1, clk->p[SEL_FRA]);
+	reg |= MASK_SET(2, 1, clk->p[SDM_MOD]);
+	reg |= MASK_SET(4, 1, clk->p[PH_SEL]);
+	reg |= MASK_SET(6, 7, clk->p[NFRA]);
+	clk_writel(reg, clk->reg);
+
+	reg  = MASK_SET(7, 2, clk->p[DIVR]);
+	clk_writel(reg, clk->reg + 4);
+
+	reg  = MASK_SET(0, 8, clk->p[DIVN] - 1);
+	reg |= MASK_SET(8, 7, clk->p[DIVM] - 1);
+	clk_writel(reg, clk->reg + 8);
+}
+
+/******************************************** PLL_A ********************************************/
+
+/* from Q628_PLLs_REG_setting.xlsx */
+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++) {
+		clk_writel(0xffff0000 | pp[i], clk->reg + (i * 4));
+		pr_info("%04x\n", pp[i]);
+	}
+}
+
+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;
+
+	TRACE;
+	//pr_info("round_rate: %lu %lu\n", rate, *prate);
+
+	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 = clk_readl(clk->reg);
+	unsigned long ret;
+
+	//TRACE;
+	if (reg & BIT(clk->bp_bit))
+		ret = prate; /* bypass */
+	else if (clk->div_width == DIV_A) {
+		ret = pa[clk->p[0]].rate;
+		//reg = clk_readl(clk->reg + 12); // G4.10 K_SDM_A
+	} else if (clk->div_width == DIV_TV) {
+		u32 m, r, reg2;
+
+		r = MASK_GET(7, 2, clk_readl(clk->reg + 4));
+		reg2 = clk_readl(clk->reg + 8);
+		m = MASK_GET(8, 7, reg2) + 1;
+
+		if (reg & BIT(1)) { /* SEL_FRA */
+			/* fractional divider */
+			u32 sdm  = MASK_GET(2, 1, reg);
+			u32 ph   = MASK_GET(4, 1, reg);
+			u32 nfra = MASK_GET(6, 7, 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 = MASK_GET(0, 8, reg2) + 1;
+
+			ret = (prate / m * n) >> r;
+		}
+	} else {
+		u32 fbdiv = MASK_GET(clk->div_shift, clk->div_width, reg) + 1;
+
+		ret = clk->brate * fbdiv;
+	}
+	//pr_info("recalc_rate: %lu -> %lu\n", prate, ret);
+
+	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;
+
+	//TRACE;
+	pr_info("set_rate: %lu -> %lu\n", prate, rate);
+
+	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);
+
+		reg |= MASK_SET(clk->div_shift, clk->div_width, fbdiv - 1);
+	}
+
+	clk_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;
+
+	TRACE;
+	spin_lock_irqsave(clk->lock, flags);
+	clk_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;
+
+	TRACE;
+	spin_lock_irqsave(clk->lock, flags);
+	clk_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 clk_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,
+};
+
+struct clk *clk_register_sp_pll(const char *name, const char *parent,
+		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 *clk;
+	//unsigned long flags = 0;
+	struct clk_init_data initd = {
+		.name = name,
+		.parent_names = &parent,
+		.ops = (bp_bit >= 0) ? &sp_pll_ops : &sp_pll_sub_ops,
+		.num_parents = 1,
+		.flags = CLK_IGNORE_UNUSED
+	};
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	if (reg == PLLSYS_CTL)
+		initd.flags |= CLK_IS_CRITICAL;
+
+	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;
+
+	clk = clk_register(NULL, &pll->hw);
+	if (WARN_ON(IS_ERR(clk))) {
+		kfree(pll);
+	} else {
+		pr_info("%-20s%lu\n", name, clk_get_rate(clk));
+		clk_register_clkdev(clk, NULL, name);
+	}
+
+	return clk;
+}
+
+static void __init sp_clk_setup(struct device_node *np)
+{
+	int i, j;
+
+	pr_info("sp-clkc init\n");
+
+	moon_regs = of_iomap(np, 0);
+	if (WARN_ON(!moon_regs)) {
+		pr_warn("sp-clkc regs missing.\n");
+		return; // -EIO
+	}
+
+	/* TODO: PLLs initial */
+
+	/* PLL_A */
+	clks[PLL_A] = clk_register_sp_pll("plla", EXTCLK,
+			PLLA_CTL, 11, 12, 27000000, 0, DIV_A, &plla_lock);
+
+	/* PLL_E */
+	clks[PLL_E] = clk_register_sp_pll("plle", EXTCLK,
+			PLLE_CTL, 6, 2, 50000000, 0, 0, &plle_lock);
+	clks[PLL_E_2P5] = clk_register_sp_pll("plle_2p5", "plle",
+			PLLE_CTL, 13, -1, 2500000, 0, 0, &plle_lock);
+	clks[PLL_E_25] = clk_register_sp_pll("plle_25", "plle",
+			PLLE_CTL, 12, -1, 25000000, 0, 0, &plle_lock);
+	clks[PLL_E_112P5] = clk_register_sp_pll("plle_112p5", "plle",
+			PLLE_CTL, 11, -1, 112500000, 0, 0, &plle_lock);
+
+	/* PLL_F */
+	clks[PLL_F] = clk_register_sp_pll("pllf", EXTCLK,
+			PLLF_CTL, 0, 10, 13500000, 1, 4, &pllf_lock);
+
+	/* PLL_TV */
+	clks[PLL_TV] = clk_register_sp_pll("plltv", EXTCLK,
+			PLLTV_CTL, 0, 15, 27000000, 0, DIV_TV, &plltv_lock);
+	clks[PLL_TV_A] = clk_register_divider(NULL, "plltv_a", "plltv", 0,
+			PLLTV_CTL + 4, 5, 1,
+			CLK_DIVIDER_POWER_OF_TWO, &plltv_lock);
+	clk_register_clkdev(clks[PLL_TV_A], NULL, "plltv_a");
+
+	/* PLL_SYS */
+	clks[PLL_SYS] = clk_register_sp_pll("pllsys", EXTCLK,
+			PLLSYS_CTL, 10, 9, 13500000, 0, 4, &pllsys_lock);
+
+	/* gates */
+	for (i = 0; i < ARRAY_SIZE(gates); i++) {
+		char s[10];
+
+		j = gates[i] & 0xffff;
+		sprintf(s, "clken%02x", j);
+		clks[j] = clk_register_gate(NULL, s, parents[gates[i] >> 16], CLK_IGNORE_UNUSED,
+			clk_regs + (j >> 4) * 4, j & 0x0f,
+			CLK_GATE_HIWORD_MASK, NULL);
+	}
+
+	clk_data.clks = clks;
+	clk_data.clk_num = ARRAY_SIZE(clks);
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+
+CLK_OF_DECLARE(sp_clkc, "sunplus,sp7021-clkc", sp_clk_setup);
+
+MODULE_AUTHOR("Qin Jian <qinjian@cqplus1.com>");
+MODULE_DESCRIPTION("Sunplus SP7021 Clock Driver");
+MODULE_LICENSE("GPL v2");
-- 
2.33.1


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

* [PATCH v3 7/8] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
  2021-11-01  5:01       ` Qin Jian
@ 2021-11-01  5:01         ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-01  5:01 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add documentation to describe Sunplus SP7021 interrupt controller bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../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..5daeab63c
--- /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
+
+  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.
+
+  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.
+
+  interrupts:
+    maxItems: 2
+    description:
+      EXT_INT0 & EXT_INT1, 2 interrupts references to primary interrupt
+      controller.
+
+required:
+  - compatible
+  - interrupt-controller
+  - "#interrupt-cells"
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    intc: interrupt-controller@9c000780 {
+        compatible = "sunplus,sp7021-intc";
+        interrupt-controller;
+        #interrupt-cells = <2>;
+        reg = <0x9c000780 0x80>, <0x9c000a80 0x80>;
+        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 5069f552f..6b3bbe021 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2662,6 +2662,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] 124+ messages in thread

* [PATCH v3 7/8] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
@ 2021-11-01  5:01         ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-01  5:01 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, Qin Jian

Add documentation to describe Sunplus SP7021 interrupt controller bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../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..5daeab63c
--- /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
+
+  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.
+
+  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.
+
+  interrupts:
+    maxItems: 2
+    description:
+      EXT_INT0 & EXT_INT1, 2 interrupts references to primary interrupt
+      controller.
+
+required:
+  - compatible
+  - interrupt-controller
+  - "#interrupt-cells"
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    intc: interrupt-controller@9c000780 {
+        compatible = "sunplus,sp7021-intc";
+        interrupt-controller;
+        #interrupt-cells = <2>;
+        reg = <0x9c000780 0x80>, <0x9c000a80 0x80>;
+        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 5069f552f..6b3bbe021 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2662,6 +2662,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] 124+ messages in thread

* [PATCH v3 8/8] irqchip: Add Sunplus SP7021 interrupt controller driver
  2021-11-01  5:01       ` Qin Jian
@ 2021-11-01  5:01         ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-01  5:01 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, 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          |   1 +
 drivers/irqchip/irq-sp7021-intc.c | 279 ++++++++++++++++++++++++++++++
 4 files changed, 290 insertions(+)
 create mode 100644 drivers/irqchip/irq-sp7021-intc.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 6b3bbe021..febbd97bf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2665,6 +2665,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 aca7b595c..6f0bc0871 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -602,4 +602,13 @@ config APPLE_AIC
 	  Support for the Apple Interrupt Controller found on Apple Silicon SoCs,
 	  such as the M1.
 
+config SUNPLUS_SP7021_INTC
+	bool "Sunplus SP7021 interrupt controller"
+	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, routed all interrupt source in P-Chip to
+	  the primary controller on C-Chip.
+	  This is selected automatically by platform config.
+
 endmenu
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index f88cbf36a..75411f654 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -116,3 +116,4 @@ obj-$(CONFIG_MACH_REALTEK_RTL)		+= irq-realtek-rtl.o
 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_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..4c995d4e3
--- /dev/null
+++ b/drivers/irqchip/irq-sp7021-intc.c
@@ -0,0 +1,279 @@
+// 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)	(((irq) >= GPIO_INT0_HWIRQ) && ((irq) <= GPIO_INT7_HWIRQ))
+/* state idx */
+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)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&sp_intc.lock, flags);
+	__assign_bit(hwirq, base, value);
+	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;
+}
+
+void sp_intc_set_ext(u32 hwirq, int ext_num)
+{
+	sp_intc_assign_bit(hwirq, REG_INTR_PRIORITY, !ext_num);
+}
+EXPORT_SYMBOL_GPL(sp_intc_set_ext);
+
+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;
+	}
+
+	/* 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);
+
+	ret = sp_intc_irq_map(node, 0); // EXT_INT0
+	if (ret)
+		goto out_domain;
+
+	ret = sp_intc_irq_map(node, 1); // EXT_INT1
+	if (ret)
+		goto out_domain;
+
+	return 0;
+
+out_domain:
+	irq_domain_remove(sp_intc.domain);
+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] 124+ messages in thread

* [PATCH v3 8/8] irqchip: Add Sunplus SP7021 interrupt controller driver
@ 2021-11-01  5:01         ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-01  5:01 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, broonie, linux-arm-kernel,
	devicetree, linux-kernel, linux-clk, wells.lu, 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          |   1 +
 drivers/irqchip/irq-sp7021-intc.c | 279 ++++++++++++++++++++++++++++++
 4 files changed, 290 insertions(+)
 create mode 100644 drivers/irqchip/irq-sp7021-intc.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 6b3bbe021..febbd97bf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2665,6 +2665,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 aca7b595c..6f0bc0871 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -602,4 +602,13 @@ config APPLE_AIC
 	  Support for the Apple Interrupt Controller found on Apple Silicon SoCs,
 	  such as the M1.
 
+config SUNPLUS_SP7021_INTC
+	bool "Sunplus SP7021 interrupt controller"
+	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, routed all interrupt source in P-Chip to
+	  the primary controller on C-Chip.
+	  This is selected automatically by platform config.
+
 endmenu
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index f88cbf36a..75411f654 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -116,3 +116,4 @@ obj-$(CONFIG_MACH_REALTEK_RTL)		+= irq-realtek-rtl.o
 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_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..4c995d4e3
--- /dev/null
+++ b/drivers/irqchip/irq-sp7021-intc.c
@@ -0,0 +1,279 @@
+// 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)	(((irq) >= GPIO_INT0_HWIRQ) && ((irq) <= GPIO_INT7_HWIRQ))
+/* state idx */
+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)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&sp_intc.lock, flags);
+	__assign_bit(hwirq, base, value);
+	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;
+}
+
+void sp_intc_set_ext(u32 hwirq, int ext_num)
+{
+	sp_intc_assign_bit(hwirq, REG_INTR_PRIORITY, !ext_num);
+}
+EXPORT_SYMBOL_GPL(sp_intc_set_ext);
+
+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;
+	}
+
+	/* 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);
+
+	ret = sp_intc_irq_map(node, 0); // EXT_INT0
+	if (ret)
+		goto out_domain;
+
+	ret = sp_intc_irq_map(node, 1); // EXT_INT1
+	if (ret)
+		goto out_domain;
+
+	return 0;
+
+out_domain:
+	irq_domain_remove(sp_intc.domain);
+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] 124+ messages in thread

* Re: [PATCH v3 8/8] irqchip: Add Sunplus SP7021 interrupt controller driver
  2021-11-01  5:01         ` Qin Jian
  (?)
@ 2021-11-01  8:27           ` kernel test robot
  -1 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-11-01  8:27 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: kbuild-all, mturquette, sboyd, maz, p.zabel, broonie,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk

[-- Attachment #1: Type: text/plain, Size: 4912 bytes --]

Hi Qin,

I love your patch! Perhaps something to improve:

[auto build test WARNING on pza/reset/next]
[also build test WARNING on robh/for-next clk/clk-next linus/master v5.15]
[cannot apply to tip/irq/core next-20211029]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211101-140155
base:   https://git.pengutronix.de/git/pza/linux reset/next
config: sparc-randconfig-r011-20211101 (attached as .config)
compiler: sparc64-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/ca53c40693bc90c44e3ec4c95c7758d7342229e2
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211101-140155
        git checkout ca53c40693bc90c44e3ec4c95c7758d7342229e2
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=sparc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/irqchip/irq-sp7021-intc.c: In function 'sp_intc_handle_ext_cascaded':
>> drivers/irqchip/irq-sp7021-intc.c:154:23: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
     154 |         int ext_num = (int)irq_desc_get_handler_data(desc);
         |                       ^
   drivers/irqchip/irq-sp7021-intc.c: In function 'sp_intc_irq_map':
>> drivers/irqchip/irq-sp7021-intc.c:212:76: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
     212 |         irq_set_chained_handler_and_data(irq, sp_intc_handle_ext_cascaded, (void *)i);
         |                                                                            ^
   drivers/irqchip/irq-sp7021-intc.c: At top level:
   drivers/irqchip/irq-sp7021-intc.c:217:6: warning: no previous prototype for 'sp_intc_set_ext' [-Wmissing-prototypes]
     217 | void sp_intc_set_ext(u32 hwirq, int ext_num)
         |      ^~~~~~~~~~~~~~~
   drivers/irqchip/irq-sp7021-intc.c:223:12: warning: no previous prototype for 'sp_intc_init_dt' [-Wmissing-prototypes]
     223 | int __init sp_intc_init_dt(struct device_node *node, struct device_node *parent)
         |            ^~~~~~~~~~~~~~~


vim +154 drivers/irqchip/irq-sp7021-intc.c

   150	
   151	static void sp_intc_handle_ext_cascaded(struct irq_desc *desc)
   152	{
   153		struct irq_chip *chip = irq_desc_get_chip(desc);
 > 154		int ext_num = (int)irq_desc_get_handler_data(desc);
   155		int hwirq;
   156	
   157		chained_irq_enter(chip, desc);
   158	
   159		while ((hwirq = sp_intc_get_ext_irq(ext_num)) >= 0) {
   160			if (unlikely(IS_GPIO_INT(hwirq) && TEST_STATE(hwirq, _IS_ACTIVE))) { // WORKAROUND
   161				ASSIGN_STATE(hwirq, _IS_ACTIVE, false);
   162				sp_intc_assign_bit(hwirq, REG_INTR_POLARITY, TEST_STATE(hwirq, _IS_LOW));
   163			} else {
   164				generic_handle_domain_irq(sp_intc.domain, hwirq);
   165			}
   166		}
   167	
   168		chained_irq_exit(chip, desc);
   169	}
   170	
   171	#ifdef CONFIG_SMP
   172	static int sp_intc_set_affinity(struct irq_data *d, const struct cpumask *mask, bool force)
   173	{
   174		return -EINVAL;
   175	}
   176	#endif
   177	
   178	static struct irq_chip sp_intc_chip = {
   179		.name = "sp_intc",
   180		.irq_ack = sp_intc_ack_irq,
   181		.irq_mask = sp_intc_mask_irq,
   182		.irq_unmask = sp_intc_unmask_irq,
   183		.irq_set_type = sp_intc_set_type,
   184	#ifdef CONFIG_SMP
   185		.irq_set_affinity = sp_intc_set_affinity,
   186	#endif
   187	};
   188	
   189	static int sp_intc_irq_domain_map(struct irq_domain *domain,
   190		unsigned int irq, irq_hw_number_t hwirq)
   191	{
   192		irq_set_chip_and_handler(irq, &sp_intc_chip, handle_level_irq);
   193		irq_set_chip_data(irq, &sp_intc_chip);
   194		irq_set_noprobe(irq);
   195	
   196		return 0;
   197	}
   198	
   199	static const struct irq_domain_ops sp_intc_dm_ops = {
   200		.xlate = irq_domain_xlate_twocell,
   201		.map = sp_intc_irq_domain_map,
   202	};
   203	
   204	static int sp_intc_irq_map(struct device_node *node, int i)
   205	{
   206		unsigned int irq;
   207	
   208		irq = irq_of_parse_and_map(node, i);
   209		if (!irq)
   210			return -ENOENT;
   211	
 > 212		irq_set_chained_handler_and_data(irq, sp_intc_handle_ext_cascaded, (void *)i);
   213	
   214		return 0;
   215	}
   216	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28757 bytes --]

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

* Re: [PATCH v3 8/8] irqchip: Add Sunplus SP7021 interrupt controller driver
@ 2021-11-01  8:27           ` kernel test robot
  0 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-11-01  8:27 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: kbuild-all, mturquette, sboyd, maz, p.zabel, broonie,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk

[-- Attachment #1: Type: text/plain, Size: 4912 bytes --]

Hi Qin,

I love your patch! Perhaps something to improve:

[auto build test WARNING on pza/reset/next]
[also build test WARNING on robh/for-next clk/clk-next linus/master v5.15]
[cannot apply to tip/irq/core next-20211029]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211101-140155
base:   https://git.pengutronix.de/git/pza/linux reset/next
config: sparc-randconfig-r011-20211101 (attached as .config)
compiler: sparc64-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/ca53c40693bc90c44e3ec4c95c7758d7342229e2
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211101-140155
        git checkout ca53c40693bc90c44e3ec4c95c7758d7342229e2
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=sparc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/irqchip/irq-sp7021-intc.c: In function 'sp_intc_handle_ext_cascaded':
>> drivers/irqchip/irq-sp7021-intc.c:154:23: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
     154 |         int ext_num = (int)irq_desc_get_handler_data(desc);
         |                       ^
   drivers/irqchip/irq-sp7021-intc.c: In function 'sp_intc_irq_map':
>> drivers/irqchip/irq-sp7021-intc.c:212:76: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
     212 |         irq_set_chained_handler_and_data(irq, sp_intc_handle_ext_cascaded, (void *)i);
         |                                                                            ^
   drivers/irqchip/irq-sp7021-intc.c: At top level:
   drivers/irqchip/irq-sp7021-intc.c:217:6: warning: no previous prototype for 'sp_intc_set_ext' [-Wmissing-prototypes]
     217 | void sp_intc_set_ext(u32 hwirq, int ext_num)
         |      ^~~~~~~~~~~~~~~
   drivers/irqchip/irq-sp7021-intc.c:223:12: warning: no previous prototype for 'sp_intc_init_dt' [-Wmissing-prototypes]
     223 | int __init sp_intc_init_dt(struct device_node *node, struct device_node *parent)
         |            ^~~~~~~~~~~~~~~


vim +154 drivers/irqchip/irq-sp7021-intc.c

   150	
   151	static void sp_intc_handle_ext_cascaded(struct irq_desc *desc)
   152	{
   153		struct irq_chip *chip = irq_desc_get_chip(desc);
 > 154		int ext_num = (int)irq_desc_get_handler_data(desc);
   155		int hwirq;
   156	
   157		chained_irq_enter(chip, desc);
   158	
   159		while ((hwirq = sp_intc_get_ext_irq(ext_num)) >= 0) {
   160			if (unlikely(IS_GPIO_INT(hwirq) && TEST_STATE(hwirq, _IS_ACTIVE))) { // WORKAROUND
   161				ASSIGN_STATE(hwirq, _IS_ACTIVE, false);
   162				sp_intc_assign_bit(hwirq, REG_INTR_POLARITY, TEST_STATE(hwirq, _IS_LOW));
   163			} else {
   164				generic_handle_domain_irq(sp_intc.domain, hwirq);
   165			}
   166		}
   167	
   168		chained_irq_exit(chip, desc);
   169	}
   170	
   171	#ifdef CONFIG_SMP
   172	static int sp_intc_set_affinity(struct irq_data *d, const struct cpumask *mask, bool force)
   173	{
   174		return -EINVAL;
   175	}
   176	#endif
   177	
   178	static struct irq_chip sp_intc_chip = {
   179		.name = "sp_intc",
   180		.irq_ack = sp_intc_ack_irq,
   181		.irq_mask = sp_intc_mask_irq,
   182		.irq_unmask = sp_intc_unmask_irq,
   183		.irq_set_type = sp_intc_set_type,
   184	#ifdef CONFIG_SMP
   185		.irq_set_affinity = sp_intc_set_affinity,
   186	#endif
   187	};
   188	
   189	static int sp_intc_irq_domain_map(struct irq_domain *domain,
   190		unsigned int irq, irq_hw_number_t hwirq)
   191	{
   192		irq_set_chip_and_handler(irq, &sp_intc_chip, handle_level_irq);
   193		irq_set_chip_data(irq, &sp_intc_chip);
   194		irq_set_noprobe(irq);
   195	
   196		return 0;
   197	}
   198	
   199	static const struct irq_domain_ops sp_intc_dm_ops = {
   200		.xlate = irq_domain_xlate_twocell,
   201		.map = sp_intc_irq_domain_map,
   202	};
   203	
   204	static int sp_intc_irq_map(struct device_node *node, int i)
   205	{
   206		unsigned int irq;
   207	
   208		irq = irq_of_parse_and_map(node, i);
   209		if (!irq)
   210			return -ENOENT;
   211	
 > 212		irq_set_chained_handler_and_data(irq, sp_intc_handle_ext_cascaded, (void *)i);
   213	
   214		return 0;
   215	}
   216	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28757 bytes --]

[-- Attachment #3: Type: text/plain, Size: 176 bytes --]

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

* Re: [PATCH v3 8/8] irqchip: Add Sunplus SP7021 interrupt controller driver
@ 2021-11-01  8:27           ` kernel test robot
  0 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-11-01  8:27 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 5034 bytes --]

Hi Qin,

I love your patch! Perhaps something to improve:

[auto build test WARNING on pza/reset/next]
[also build test WARNING on robh/for-next clk/clk-next linus/master v5.15]
[cannot apply to tip/irq/core next-20211029]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211101-140155
base:   https://git.pengutronix.de/git/pza/linux reset/next
config: sparc-randconfig-r011-20211101 (attached as .config)
compiler: sparc64-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/ca53c40693bc90c44e3ec4c95c7758d7342229e2
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211101-140155
        git checkout ca53c40693bc90c44e3ec4c95c7758d7342229e2
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=sparc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/irqchip/irq-sp7021-intc.c: In function 'sp_intc_handle_ext_cascaded':
>> drivers/irqchip/irq-sp7021-intc.c:154:23: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
     154 |         int ext_num = (int)irq_desc_get_handler_data(desc);
         |                       ^
   drivers/irqchip/irq-sp7021-intc.c: In function 'sp_intc_irq_map':
>> drivers/irqchip/irq-sp7021-intc.c:212:76: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
     212 |         irq_set_chained_handler_and_data(irq, sp_intc_handle_ext_cascaded, (void *)i);
         |                                                                            ^
   drivers/irqchip/irq-sp7021-intc.c: At top level:
   drivers/irqchip/irq-sp7021-intc.c:217:6: warning: no previous prototype for 'sp_intc_set_ext' [-Wmissing-prototypes]
     217 | void sp_intc_set_ext(u32 hwirq, int ext_num)
         |      ^~~~~~~~~~~~~~~
   drivers/irqchip/irq-sp7021-intc.c:223:12: warning: no previous prototype for 'sp_intc_init_dt' [-Wmissing-prototypes]
     223 | int __init sp_intc_init_dt(struct device_node *node, struct device_node *parent)
         |            ^~~~~~~~~~~~~~~


vim +154 drivers/irqchip/irq-sp7021-intc.c

   150	
   151	static void sp_intc_handle_ext_cascaded(struct irq_desc *desc)
   152	{
   153		struct irq_chip *chip = irq_desc_get_chip(desc);
 > 154		int ext_num = (int)irq_desc_get_handler_data(desc);
   155		int hwirq;
   156	
   157		chained_irq_enter(chip, desc);
   158	
   159		while ((hwirq = sp_intc_get_ext_irq(ext_num)) >= 0) {
   160			if (unlikely(IS_GPIO_INT(hwirq) && TEST_STATE(hwirq, _IS_ACTIVE))) { // WORKAROUND
   161				ASSIGN_STATE(hwirq, _IS_ACTIVE, false);
   162				sp_intc_assign_bit(hwirq, REG_INTR_POLARITY, TEST_STATE(hwirq, _IS_LOW));
   163			} else {
   164				generic_handle_domain_irq(sp_intc.domain, hwirq);
   165			}
   166		}
   167	
   168		chained_irq_exit(chip, desc);
   169	}
   170	
   171	#ifdef CONFIG_SMP
   172	static int sp_intc_set_affinity(struct irq_data *d, const struct cpumask *mask, bool force)
   173	{
   174		return -EINVAL;
   175	}
   176	#endif
   177	
   178	static struct irq_chip sp_intc_chip = {
   179		.name = "sp_intc",
   180		.irq_ack = sp_intc_ack_irq,
   181		.irq_mask = sp_intc_mask_irq,
   182		.irq_unmask = sp_intc_unmask_irq,
   183		.irq_set_type = sp_intc_set_type,
   184	#ifdef CONFIG_SMP
   185		.irq_set_affinity = sp_intc_set_affinity,
   186	#endif
   187	};
   188	
   189	static int sp_intc_irq_domain_map(struct irq_domain *domain,
   190		unsigned int irq, irq_hw_number_t hwirq)
   191	{
   192		irq_set_chip_and_handler(irq, &sp_intc_chip, handle_level_irq);
   193		irq_set_chip_data(irq, &sp_intc_chip);
   194		irq_set_noprobe(irq);
   195	
   196		return 0;
   197	}
   198	
   199	static const struct irq_domain_ops sp_intc_dm_ops = {
   200		.xlate = irq_domain_xlate_twocell,
   201		.map = sp_intc_irq_domain_map,
   202	};
   203	
   204	static int sp_intc_irq_map(struct device_node *node, int i)
   205	{
   206		unsigned int irq;
   207	
   208		irq = irq_of_parse_and_map(node, i);
   209		if (!irq)
   210			return -ENOENT;
   211	
 > 212		irq_set_chained_handler_and_data(irq, sp_intc_handle_ext_cascaded, (void *)i);
   213	
   214		return 0;
   215	}
   216	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 28757 bytes --]

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

* Re: [PATCH v3 6/8] clk: Add Sunplus SP7021 clock driver
  2021-11-01  5:01         ` Qin Jian
  (?)
@ 2021-11-01 10:16           ` kernel test robot
  -1 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-11-01 10:16 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: kbuild-all, mturquette, sboyd, maz, p.zabel, broonie,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk

[-- Attachment #1: Type: text/plain, Size: 3138 bytes --]

Hi Qin,

I love your patch! Perhaps something to improve:

[auto build test WARNING on pza/reset/next]
[also build test WARNING on robh/for-next clk/clk-next tip/irq/core linus/master v5.15 next-20211029]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211101-140155
base:   https://git.pengutronix.de/git/pza/linux reset/next
config: openrisc-randconfig-r015-20211101 (attached as .config)
compiler: or1k-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/9767714cf5c22192f99adb0d8e344cb5e38a2e33
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211101-140155
        git checkout 9767714cf5c22192f99adb0d8e344cb5e38a2e33
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=openrisc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/clk/clk-sp7021.c:663:13: warning: no previous prototype for 'clk_register_sp_pll' [-Wmissing-prototypes]
     663 | struct clk *clk_register_sp_pll(const char *name, const char *parent,
         |             ^~~~~~~~~~~~~~~~~~~


vim +/clk_register_sp_pll +663 drivers/clk/clk-sp7021.c

   662	
 > 663	struct clk *clk_register_sp_pll(const char *name, const char *parent,
   664			void __iomem *reg, int pd_bit, int bp_bit,
   665			unsigned long brate, int shift, int width,
   666			spinlock_t *lock)
   667	{
   668		struct sp_pll *pll;
   669		struct clk *clk;
   670		//unsigned long flags = 0;
   671		struct clk_init_data initd = {
   672			.name = name,
   673			.parent_names = &parent,
   674			.ops = (bp_bit >= 0) ? &sp_pll_ops : &sp_pll_sub_ops,
   675			.num_parents = 1,
   676			.flags = CLK_IGNORE_UNUSED
   677		};
   678	
   679		pll = kzalloc(sizeof(*pll), GFP_KERNEL);
   680		if (!pll)
   681			return ERR_PTR(-ENOMEM);
   682	
   683		if (reg == PLLSYS_CTL)
   684			initd.flags |= CLK_IS_CRITICAL;
   685	
   686		pll->hw.init = &initd;
   687		pll->reg = reg;
   688		pll->pd_bit = pd_bit;
   689		pll->bp_bit = bp_bit;
   690		pll->brate = brate;
   691		pll->div_shift = shift;
   692		pll->div_width = width;
   693		pll->lock = lock;
   694	
   695		clk = clk_register(NULL, &pll->hw);
   696		if (WARN_ON(IS_ERR(clk))) {
   697			kfree(pll);
   698		} else {
   699			pr_info("%-20s%lu\n", name, clk_get_rate(clk));
   700			clk_register_clkdev(clk, NULL, name);
   701		}
   702	
   703		return clk;
   704	}
   705	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 24931 bytes --]

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

* Re: [PATCH v3 6/8] clk: Add Sunplus SP7021 clock driver
@ 2021-11-01 10:16           ` kernel test robot
  0 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-11-01 10:16 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: kbuild-all, mturquette, sboyd, maz, p.zabel, broonie,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk

[-- Attachment #1: Type: text/plain, Size: 3138 bytes --]

Hi Qin,

I love your patch! Perhaps something to improve:

[auto build test WARNING on pza/reset/next]
[also build test WARNING on robh/for-next clk/clk-next tip/irq/core linus/master v5.15 next-20211029]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211101-140155
base:   https://git.pengutronix.de/git/pza/linux reset/next
config: openrisc-randconfig-r015-20211101 (attached as .config)
compiler: or1k-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/9767714cf5c22192f99adb0d8e344cb5e38a2e33
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211101-140155
        git checkout 9767714cf5c22192f99adb0d8e344cb5e38a2e33
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=openrisc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/clk/clk-sp7021.c:663:13: warning: no previous prototype for 'clk_register_sp_pll' [-Wmissing-prototypes]
     663 | struct clk *clk_register_sp_pll(const char *name, const char *parent,
         |             ^~~~~~~~~~~~~~~~~~~


vim +/clk_register_sp_pll +663 drivers/clk/clk-sp7021.c

   662	
 > 663	struct clk *clk_register_sp_pll(const char *name, const char *parent,
   664			void __iomem *reg, int pd_bit, int bp_bit,
   665			unsigned long brate, int shift, int width,
   666			spinlock_t *lock)
   667	{
   668		struct sp_pll *pll;
   669		struct clk *clk;
   670		//unsigned long flags = 0;
   671		struct clk_init_data initd = {
   672			.name = name,
   673			.parent_names = &parent,
   674			.ops = (bp_bit >= 0) ? &sp_pll_ops : &sp_pll_sub_ops,
   675			.num_parents = 1,
   676			.flags = CLK_IGNORE_UNUSED
   677		};
   678	
   679		pll = kzalloc(sizeof(*pll), GFP_KERNEL);
   680		if (!pll)
   681			return ERR_PTR(-ENOMEM);
   682	
   683		if (reg == PLLSYS_CTL)
   684			initd.flags |= CLK_IS_CRITICAL;
   685	
   686		pll->hw.init = &initd;
   687		pll->reg = reg;
   688		pll->pd_bit = pd_bit;
   689		pll->bp_bit = bp_bit;
   690		pll->brate = brate;
   691		pll->div_shift = shift;
   692		pll->div_width = width;
   693		pll->lock = lock;
   694	
   695		clk = clk_register(NULL, &pll->hw);
   696		if (WARN_ON(IS_ERR(clk))) {
   697			kfree(pll);
   698		} else {
   699			pr_info("%-20s%lu\n", name, clk_get_rate(clk));
   700			clk_register_clkdev(clk, NULL, name);
   701		}
   702	
   703		return clk;
   704	}
   705	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 24931 bytes --]

[-- Attachment #3: Type: text/plain, Size: 176 bytes --]

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

* Re: [PATCH v3 6/8] clk: Add Sunplus SP7021 clock driver
@ 2021-11-01 10:16           ` kernel test robot
  0 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-11-01 10:16 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 3224 bytes --]

Hi Qin,

I love your patch! Perhaps something to improve:

[auto build test WARNING on pza/reset/next]
[also build test WARNING on robh/for-next clk/clk-next tip/irq/core linus/master v5.15 next-20211029]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211101-140155
base:   https://git.pengutronix.de/git/pza/linux reset/next
config: openrisc-randconfig-r015-20211101 (attached as .config)
compiler: or1k-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/9767714cf5c22192f99adb0d8e344cb5e38a2e33
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211101-140155
        git checkout 9767714cf5c22192f99adb0d8e344cb5e38a2e33
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=openrisc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/clk/clk-sp7021.c:663:13: warning: no previous prototype for 'clk_register_sp_pll' [-Wmissing-prototypes]
     663 | struct clk *clk_register_sp_pll(const char *name, const char *parent,
         |             ^~~~~~~~~~~~~~~~~~~


vim +/clk_register_sp_pll +663 drivers/clk/clk-sp7021.c

   662	
 > 663	struct clk *clk_register_sp_pll(const char *name, const char *parent,
   664			void __iomem *reg, int pd_bit, int bp_bit,
   665			unsigned long brate, int shift, int width,
   666			spinlock_t *lock)
   667	{
   668		struct sp_pll *pll;
   669		struct clk *clk;
   670		//unsigned long flags = 0;
   671		struct clk_init_data initd = {
   672			.name = name,
   673			.parent_names = &parent,
   674			.ops = (bp_bit >= 0) ? &sp_pll_ops : &sp_pll_sub_ops,
   675			.num_parents = 1,
   676			.flags = CLK_IGNORE_UNUSED
   677		};
   678	
   679		pll = kzalloc(sizeof(*pll), GFP_KERNEL);
   680		if (!pll)
   681			return ERR_PTR(-ENOMEM);
   682	
   683		if (reg == PLLSYS_CTL)
   684			initd.flags |= CLK_IS_CRITICAL;
   685	
   686		pll->hw.init = &initd;
   687		pll->reg = reg;
   688		pll->pd_bit = pd_bit;
   689		pll->bp_bit = bp_bit;
   690		pll->brate = brate;
   691		pll->div_shift = shift;
   692		pll->div_width = width;
   693		pll->lock = lock;
   694	
   695		clk = clk_register(NULL, &pll->hw);
   696		if (WARN_ON(IS_ERR(clk))) {
   697			kfree(pll);
   698		} else {
   699			pr_info("%-20s%lu\n", name, clk_get_rate(clk));
   700			clk_register_clkdev(clk, NULL, name);
   701		}
   702	
   703		return clk;
   704	}
   705	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 24931 bytes --]

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

* Re: [PATCH v3 8/8] irqchip: Add Sunplus SP7021 interrupt controller driver
  2021-11-01  5:01         ` Qin Jian
  (?)
@ 2021-11-01 10:26           ` kernel test robot
  -1 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-11-01 10:26 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: kbuild-all, mturquette, sboyd, maz, p.zabel, broonie,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk

[-- Attachment #1: Type: text/plain, Size: 2389 bytes --]

Hi Qin,

I love your patch! Perhaps something to improve:

[auto build test WARNING on pza/reset/next]
[also build test WARNING on robh/for-next clk/clk-next linus/master v5.15]
[cannot apply to tip/irq/core next-20211029]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211101-140155
base:   https://git.pengutronix.de/git/pza/linux reset/next
config: arc-randconfig-r016-20211101 (attached as .config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/ca53c40693bc90c44e3ec4c95c7758d7342229e2
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211101-140155
        git checkout ca53c40693bc90c44e3ec4c95c7758d7342229e2
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=arc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/irqchip/irq-sp7021-intc.c:217:6: warning: no previous prototype for 'sp_intc_set_ext' [-Wmissing-prototypes]
     217 | void sp_intc_set_ext(u32 hwirq, int ext_num)
         |      ^~~~~~~~~~~~~~~
>> drivers/irqchip/irq-sp7021-intc.c:223:12: warning: no previous prototype for 'sp_intc_init_dt' [-Wmissing-prototypes]
     223 | int __init sp_intc_init_dt(struct device_node *node, struct device_node *parent)
         |            ^~~~~~~~~~~~~~~


vim +/sp_intc_set_ext +217 drivers/irqchip/irq-sp7021-intc.c

   216	
 > 217	void sp_intc_set_ext(u32 hwirq, int ext_num)
   218	{
   219		sp_intc_assign_bit(hwirq, REG_INTR_PRIORITY, !ext_num);
   220	}
   221	EXPORT_SYMBOL_GPL(sp_intc_set_ext);
   222	
 > 223	int __init sp_intc_init_dt(struct device_node *node, struct device_node *parent)

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 42320 bytes --]

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

* Re: [PATCH v3 8/8] irqchip: Add Sunplus SP7021 interrupt controller driver
@ 2021-11-01 10:26           ` kernel test robot
  0 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-11-01 10:26 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: kbuild-all, mturquette, sboyd, maz, p.zabel, broonie,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk

[-- Attachment #1: Type: text/plain, Size: 2389 bytes --]

Hi Qin,

I love your patch! Perhaps something to improve:

[auto build test WARNING on pza/reset/next]
[also build test WARNING on robh/for-next clk/clk-next linus/master v5.15]
[cannot apply to tip/irq/core next-20211029]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211101-140155
base:   https://git.pengutronix.de/git/pza/linux reset/next
config: arc-randconfig-r016-20211101 (attached as .config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/ca53c40693bc90c44e3ec4c95c7758d7342229e2
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211101-140155
        git checkout ca53c40693bc90c44e3ec4c95c7758d7342229e2
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=arc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/irqchip/irq-sp7021-intc.c:217:6: warning: no previous prototype for 'sp_intc_set_ext' [-Wmissing-prototypes]
     217 | void sp_intc_set_ext(u32 hwirq, int ext_num)
         |      ^~~~~~~~~~~~~~~
>> drivers/irqchip/irq-sp7021-intc.c:223:12: warning: no previous prototype for 'sp_intc_init_dt' [-Wmissing-prototypes]
     223 | int __init sp_intc_init_dt(struct device_node *node, struct device_node *parent)
         |            ^~~~~~~~~~~~~~~


vim +/sp_intc_set_ext +217 drivers/irqchip/irq-sp7021-intc.c

   216	
 > 217	void sp_intc_set_ext(u32 hwirq, int ext_num)
   218	{
   219		sp_intc_assign_bit(hwirq, REG_INTR_PRIORITY, !ext_num);
   220	}
   221	EXPORT_SYMBOL_GPL(sp_intc_set_ext);
   222	
 > 223	int __init sp_intc_init_dt(struct device_node *node, struct device_node *parent)

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 42320 bytes --]

[-- Attachment #3: Type: text/plain, Size: 176 bytes --]

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

* Re: [PATCH v3 8/8] irqchip: Add Sunplus SP7021 interrupt controller driver
@ 2021-11-01 10:26           ` kernel test robot
  0 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-11-01 10:26 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 2443 bytes --]

Hi Qin,

I love your patch! Perhaps something to improve:

[auto build test WARNING on pza/reset/next]
[also build test WARNING on robh/for-next clk/clk-next linus/master v5.15]
[cannot apply to tip/irq/core next-20211029]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211101-140155
base:   https://git.pengutronix.de/git/pza/linux reset/next
config: arc-randconfig-r016-20211101 (attached as .config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/ca53c40693bc90c44e3ec4c95c7758d7342229e2
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211101-140155
        git checkout ca53c40693bc90c44e3ec4c95c7758d7342229e2
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=arc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/irqchip/irq-sp7021-intc.c:217:6: warning: no previous prototype for 'sp_intc_set_ext' [-Wmissing-prototypes]
     217 | void sp_intc_set_ext(u32 hwirq, int ext_num)
         |      ^~~~~~~~~~~~~~~
>> drivers/irqchip/irq-sp7021-intc.c:223:12: warning: no previous prototype for 'sp_intc_init_dt' [-Wmissing-prototypes]
     223 | int __init sp_intc_init_dt(struct device_node *node, struct device_node *parent)
         |            ^~~~~~~~~~~~~~~


vim +/sp_intc_set_ext +217 drivers/irqchip/irq-sp7021-intc.c

   216	
 > 217	void sp_intc_set_ext(u32 hwirq, int ext_num)
   218	{
   219		sp_intc_assign_bit(hwirq, REG_INTR_PRIORITY, !ext_num);
   220	}
   221	EXPORT_SYMBOL_GPL(sp_intc_set_ext);
   222	
 > 223	int __init sp_intc_init_dt(struct device_node *node, struct device_node *parent)

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 42320 bytes --]

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

* Re: [PATCH v3 2/8] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards
  2021-11-01  5:01         ` Qin Jian
@ 2021-11-01 19:58           ` Rob Herring
  -1 siblings, 0 replies; 124+ messages in thread
From: Rob Herring @ 2021-11-01 19:58 UTC (permalink / raw)
  To: Qin Jian
  Cc: robh+dt, linux-clk, devicetree, broonie, wells.lu, sboyd,
	p.zabel, linux-arm-kernel, maz, linux-kernel, mturquette

On Mon, 01 Nov 2021 13:01:52 +0800, Qin Jian wrote:
> This introduces bindings for boards based Sunplus SP7021 SoC.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  .../bindings/arm/sunplus,sp7021.yaml          | 27 +++++++++++++++++++
>  MAINTAINERS                                   |  7 +++++
>  2 files changed, 34 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
> 

Reviewed-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH v3 2/8] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards
@ 2021-11-01 19:58           ` Rob Herring
  0 siblings, 0 replies; 124+ messages in thread
From: Rob Herring @ 2021-11-01 19:58 UTC (permalink / raw)
  To: Qin Jian
  Cc: robh+dt, linux-clk, devicetree, broonie, wells.lu, sboyd,
	p.zabel, linux-arm-kernel, maz, linux-kernel, mturquette

On Mon, 01 Nov 2021 13:01:52 +0800, Qin Jian wrote:
> This introduces bindings for boards based Sunplus SP7021 SoC.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  .../bindings/arm/sunplus,sp7021.yaml          | 27 +++++++++++++++++++
>  MAINTAINERS                                   |  7 +++++
>  2 files changed, 34 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
> 

Reviewed-by: Rob Herring <robh@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] 124+ messages in thread

* Re: [PATCH v3 5/8] dt-bindings: clock: Add bindings for SP7021 clock driver
  2021-11-01  5:01         ` Qin Jian
@ 2021-11-01 19:59           ` Rob Herring
  -1 siblings, 0 replies; 124+ messages in thread
From: Rob Herring @ 2021-11-01 19:59 UTC (permalink / raw)
  To: Qin Jian
  Cc: devicetree, sboyd, robh+dt, linux-clk, maz, wells.lu, mturquette,
	linux-kernel, p.zabel, linux-arm-kernel, broonie

On Mon, 01 Nov 2021 13:01:55 +0800, Qin Jian wrote:
> Add documentation to describe Sunplus SP7021 clock driver bindings.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  .../bindings/clock/sunplus,sp7021-clkc.yaml   |  38 ++++++
>  MAINTAINERS                                   |   2 +
>  include/dt-bindings/clock/sp-sp7021.h         | 112 ++++++++++++++++++
>  3 files changed, 152 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
>  create mode 100644 include/dt-bindings/clock/sp-sp7021.h
> 

Reviewed-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH v3 5/8] dt-bindings: clock: Add bindings for SP7021 clock driver
@ 2021-11-01 19:59           ` Rob Herring
  0 siblings, 0 replies; 124+ messages in thread
From: Rob Herring @ 2021-11-01 19:59 UTC (permalink / raw)
  To: Qin Jian
  Cc: devicetree, sboyd, robh+dt, linux-clk, maz, wells.lu, mturquette,
	linux-kernel, p.zabel, linux-arm-kernel, broonie

On Mon, 01 Nov 2021 13:01:55 +0800, Qin Jian wrote:
> Add documentation to describe Sunplus SP7021 clock driver bindings.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  .../bindings/clock/sunplus,sp7021-clkc.yaml   |  38 ++++++
>  MAINTAINERS                                   |   2 +
>  include/dt-bindings/clock/sp-sp7021.h         | 112 ++++++++++++++++++
>  3 files changed, 152 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
>  create mode 100644 include/dt-bindings/clock/sp-sp7021.h
> 

Reviewed-by: Rob Herring <robh@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] 124+ messages in thread

* Re: [PATCH v3 3/8] dt-bindings: reset: Add bindings for SP7021 reset driver
  2021-11-01  5:01         ` Qin Jian
@ 2021-11-02 11:51           ` Philipp Zabel
  -1 siblings, 0 replies; 124+ messages in thread
From: Philipp Zabel @ 2021-11-02 11:51 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: mturquette, sboyd, maz, broonie, linux-arm-kernel, devicetree,
	linux-kernel, linux-clk, wells.lu

On Mon, 2021-11-01 at 13:01 +0800, Qin Jian wrote:
> Add documentation to describe Sunplus SP7021 reset driver bindings.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  .../bindings/reset/sunplus,reset.yaml         | 40 ++++++++
>  MAINTAINERS                                   |  2 +
>  include/dt-bindings/reset/sp-sp7021.h         | 99 +++++++++++++++++++
>  3 files changed, 141 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..bf55f4ee2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/reset/sunplus,reset.yaml
> @@ -0,0 +1,40 @@
> +# 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:
> +    enum:
> +      - sunplus,sp7021-reset # Reset Controller on SP7021 and compatible SoCs
> +      - sunplus,q645-reset # Reset Controller on Q645 and compatible SoCs

The commit message only mentions SP7021. Should Q645 be added later, or
is this patch missing the binding header for Q655?

regards
Philipp

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

* Re: [PATCH v3 3/8] dt-bindings: reset: Add bindings for SP7021 reset driver
@ 2021-11-02 11:51           ` Philipp Zabel
  0 siblings, 0 replies; 124+ messages in thread
From: Philipp Zabel @ 2021-11-02 11:51 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: mturquette, sboyd, maz, broonie, linux-arm-kernel, devicetree,
	linux-kernel, linux-clk, wells.lu

On Mon, 2021-11-01 at 13:01 +0800, Qin Jian wrote:
> Add documentation to describe Sunplus SP7021 reset driver bindings.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  .../bindings/reset/sunplus,reset.yaml         | 40 ++++++++
>  MAINTAINERS                                   |  2 +
>  include/dt-bindings/reset/sp-sp7021.h         | 99 +++++++++++++++++++
>  3 files changed, 141 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..bf55f4ee2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/reset/sunplus,reset.yaml
> @@ -0,0 +1,40 @@
> +# 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:
> +    enum:
> +      - sunplus,sp7021-reset # Reset Controller on SP7021 and compatible SoCs
> +      - sunplus,q645-reset # Reset Controller on Q645 and compatible SoCs

The commit message only mentions SP7021. Should Q645 be added later, or
is this patch missing the binding header for Q655?

regards
Philipp

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

* Re: [PATCH v3 4/8] reset: Add Sunplus SP7021 reset driver
  2021-11-01  5:01         ` Qin Jian
@ 2021-11-02 12:22           ` Philipp Zabel
  -1 siblings, 0 replies; 124+ messages in thread
From: Philipp Zabel @ 2021-11-02 12:22 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: mturquette, sboyd, maz, broonie, linux-arm-kernel, devicetree,
	linux-kernel, linux-clk, wells.lu

On Mon, 2021-11-01 at 13:01 +0800, Qin Jian wrote:
> Add reset driver for Sunplus SP7021 SoC.

You don't mention Q645 here, it appears this driver supports both SoCs?

[...]
> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
> index be799a5ab..50695ab47 100644
> --- a/drivers/reset/Kconfig
> +++ b/drivers/reset/Kconfig
> @@ -249,6 +249,14 @@ config RESET_TI_SYSCON
>  	  you wish to use the reset framework for such memory-mapped devices,
>  	  say Y here. Otherwise, say N.
> 
>
> +config RESET_SUNPLUS

Please add these entries in alphabetical order.

> +	bool "Sunplus SoCs Reset Driver"

Can this be made:

	depends SOC_SP7021 || SOC_Q645 || COMPILE_TEST

?

> +	help
> +	  This enables the reset driver support for Sunplus SP7021 SoC family.
> +	  Say Y if you want to control reset signals by the reset controller.
> +	  Otherwise, say N.
> +	  This driver is selected automatically by platform config.

Which platform config?


[...]
> diff --git a/drivers/reset/reset-sunplus.c b/drivers/reset/reset-sunplus.c
> new file mode 100644
> index 000000000..696efd75e
> --- /dev/null
> +++ b/drivers/reset/reset-sunplus.c
> @@ -0,0 +1,159 @@
> +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +/*
> + * SP7021 reset driver
> + *
> + * Copyright (C) Sunplus Technology Co., Ltd.
> + *       All rights reserved.
> + *
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> + * kind, whether express or implied; without even the implied warranty
> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.

Drop this boilerplate, this is not required with the SPDX identifier
above.

> + */
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/reset-controller.h>
> +#include <linux/reboot.h>
> +
> +#if defined(CONFIG_SOC_SP7021)
> +#include <dt-bindings/reset/sp-sp7021.h>
> +#elif defined(CONFIG_SOC_Q645)
> +#include <dt-bindings/reset/sp-q645.h>
> +#endif

I'd prefer if you added namespace prefixes to the defines and included
both headers unconditionally.
These are just required for RST_MAX, correct?

> +
> +#define BITASSERT(id, val)          ((1 << (16 + id)) | (val << id))
> +
> +
> +struct sp_reset_data {
> +	struct reset_controller_dev	rcdev;
> +	void __iomem			*membase;
> +} sp_reset;

Please allocate this with devm_kzalloc in the probe function instead.

> +
> +
> +static inline struct sp_reset_data *
> +to_sp_reset_data(struct reset_controller_dev *rcdev)
> +{
> +	return container_of(rcdev, struct sp_reset_data, rcdev);
> +}
> +
> +static int sp_reset_update(struct reset_controller_dev *rcdev,
> +			      unsigned long id, bool assert)
> +{
> +	struct sp_reset_data *data = to_sp_reset_data(rcdev);
> +	int reg_width = sizeof(u32)/2;
> +	int bank = id / (reg_width * BITS_PER_BYTE);
> +	int offset = id % (reg_width * BITS_PER_BYTE);
> +	void __iomem *addr;
> +
> +	addr = data->membase + (bank * 4);
> +
> +	if (assert)
> +		writel(BITASSERT(offset, 1), addr);
> +	else
> +		writel(BITASSERT(offset, 0), addr);

Could be

	writel(BITASSERT(offset, assert), addr);

> +
> +	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_data *data = to_sp_reset_data(rcdev);
> +	int reg_width = sizeof(u32)/2;
> +	int bank = id / (reg_width * BITS_PER_BYTE);
> +	int offset = id % (reg_width * BITS_PER_BYTE);
> +	u32 reg;
> +
> +	reg = readl(data->membase + (bank * 4));
> +
> +	return !!(reg & BIT(offset));
> +}
> +
> +static int sp_restart(struct notifier_block *this, unsigned long mode,
> +				void *cmd)
> +{
> +	sp_reset_assert(&sp_reset.rcdev, RST_SYSTEM);
> +	sp_reset_deassert(&sp_reset.rcdev, RST_SYSTEM);
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block sp_restart_nb = {
> +	.notifier_call = sp_restart,
> +	.priority = 192,
> +};
> +
> +static const struct reset_control_ops sp_reset_ops = {
> +	.assert		= sp_reset_assert,
> +	.deassert	= sp_reset_deassert,
> +	.status		= sp_reset_status,
> +};
> +
> +static const struct of_device_id sp_reset_dt_ids[] = {
> +	{ .compatible = "sunplus,sp7021-reset", },
> +	{ .compatible = "sunplus,q645-reset", },
> +	{ /* sentinel */ },
> +};
> +
> +static int sp_reset_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct sp_reset_data *data = &sp_reset;
> +	void __iomem *membase;
> +	struct resource *res;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	membase = devm_ioremap(dev, res->start, resource_size(res));
> +	if (IS_ERR(membase))
> +		return PTR_ERR(membase);
> +
> +	data->membase = membase;
> +	data->rcdev.owner = THIS_MODULE;
> +	data->rcdev.nr_resets = RST_MAX;

Use of_device_get_match_data() to determine the correct number of
resets.

regards
Philipp

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

* Re: [PATCH v3 4/8] reset: Add Sunplus SP7021 reset driver
@ 2021-11-02 12:22           ` Philipp Zabel
  0 siblings, 0 replies; 124+ messages in thread
From: Philipp Zabel @ 2021-11-02 12:22 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: mturquette, sboyd, maz, broonie, linux-arm-kernel, devicetree,
	linux-kernel, linux-clk, wells.lu

On Mon, 2021-11-01 at 13:01 +0800, Qin Jian wrote:
> Add reset driver for Sunplus SP7021 SoC.

You don't mention Q645 here, it appears this driver supports both SoCs?

[...]
> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
> index be799a5ab..50695ab47 100644
> --- a/drivers/reset/Kconfig
> +++ b/drivers/reset/Kconfig
> @@ -249,6 +249,14 @@ config RESET_TI_SYSCON
>  	  you wish to use the reset framework for such memory-mapped devices,
>  	  say Y here. Otherwise, say N.
> 
>
> +config RESET_SUNPLUS

Please add these entries in alphabetical order.

> +	bool "Sunplus SoCs Reset Driver"

Can this be made:

	depends SOC_SP7021 || SOC_Q645 || COMPILE_TEST

?

> +	help
> +	  This enables the reset driver support for Sunplus SP7021 SoC family.
> +	  Say Y if you want to control reset signals by the reset controller.
> +	  Otherwise, say N.
> +	  This driver is selected automatically by platform config.

Which platform config?


[...]
> diff --git a/drivers/reset/reset-sunplus.c b/drivers/reset/reset-sunplus.c
> new file mode 100644
> index 000000000..696efd75e
> --- /dev/null
> +++ b/drivers/reset/reset-sunplus.c
> @@ -0,0 +1,159 @@
> +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +/*
> + * SP7021 reset driver
> + *
> + * Copyright (C) Sunplus Technology Co., Ltd.
> + *       All rights reserved.
> + *
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> + * kind, whether express or implied; without even the implied warranty
> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.

Drop this boilerplate, this is not required with the SPDX identifier
above.

> + */
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/reset-controller.h>
> +#include <linux/reboot.h>
> +
> +#if defined(CONFIG_SOC_SP7021)
> +#include <dt-bindings/reset/sp-sp7021.h>
> +#elif defined(CONFIG_SOC_Q645)
> +#include <dt-bindings/reset/sp-q645.h>
> +#endif

I'd prefer if you added namespace prefixes to the defines and included
both headers unconditionally.
These are just required for RST_MAX, correct?

> +
> +#define BITASSERT(id, val)          ((1 << (16 + id)) | (val << id))
> +
> +
> +struct sp_reset_data {
> +	struct reset_controller_dev	rcdev;
> +	void __iomem			*membase;
> +} sp_reset;

Please allocate this with devm_kzalloc in the probe function instead.

> +
> +
> +static inline struct sp_reset_data *
> +to_sp_reset_data(struct reset_controller_dev *rcdev)
> +{
> +	return container_of(rcdev, struct sp_reset_data, rcdev);
> +}
> +
> +static int sp_reset_update(struct reset_controller_dev *rcdev,
> +			      unsigned long id, bool assert)
> +{
> +	struct sp_reset_data *data = to_sp_reset_data(rcdev);
> +	int reg_width = sizeof(u32)/2;
> +	int bank = id / (reg_width * BITS_PER_BYTE);
> +	int offset = id % (reg_width * BITS_PER_BYTE);
> +	void __iomem *addr;
> +
> +	addr = data->membase + (bank * 4);
> +
> +	if (assert)
> +		writel(BITASSERT(offset, 1), addr);
> +	else
> +		writel(BITASSERT(offset, 0), addr);

Could be

	writel(BITASSERT(offset, assert), addr);

> +
> +	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_data *data = to_sp_reset_data(rcdev);
> +	int reg_width = sizeof(u32)/2;
> +	int bank = id / (reg_width * BITS_PER_BYTE);
> +	int offset = id % (reg_width * BITS_PER_BYTE);
> +	u32 reg;
> +
> +	reg = readl(data->membase + (bank * 4));
> +
> +	return !!(reg & BIT(offset));
> +}
> +
> +static int sp_restart(struct notifier_block *this, unsigned long mode,
> +				void *cmd)
> +{
> +	sp_reset_assert(&sp_reset.rcdev, RST_SYSTEM);
> +	sp_reset_deassert(&sp_reset.rcdev, RST_SYSTEM);
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block sp_restart_nb = {
> +	.notifier_call = sp_restart,
> +	.priority = 192,
> +};
> +
> +static const struct reset_control_ops sp_reset_ops = {
> +	.assert		= sp_reset_assert,
> +	.deassert	= sp_reset_deassert,
> +	.status		= sp_reset_status,
> +};
> +
> +static const struct of_device_id sp_reset_dt_ids[] = {
> +	{ .compatible = "sunplus,sp7021-reset", },
> +	{ .compatible = "sunplus,q645-reset", },
> +	{ /* sentinel */ },
> +};
> +
> +static int sp_reset_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct sp_reset_data *data = &sp_reset;
> +	void __iomem *membase;
> +	struct resource *res;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	membase = devm_ioremap(dev, res->start, resource_size(res));
> +	if (IS_ERR(membase))
> +		return PTR_ERR(membase);
> +
> +	data->membase = membase;
> +	data->rcdev.owner = THIS_MODULE;
> +	data->rcdev.nr_resets = RST_MAX;

Use of_device_get_match_data() to determine the correct number of
resets.

regards
Philipp

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

* Re: [PATCH v3 1/8] dt-bindings: vendor-prefixes: Add Sunplus
  2021-11-01  5:01         ` Qin Jian
@ 2021-11-02 17:44           ` Rob Herring
  -1 siblings, 0 replies; 124+ messages in thread
From: Rob Herring @ 2021-11-02 17:44 UTC (permalink / raw)
  To: Qin Jian
  Cc: p.zabel, linux-clk, broonie, linux-kernel, linux-arm-kernel,
	mturquette, sboyd, devicetree, robh+dt, wells.lu, maz

On Mon, 01 Nov 2021 13:01:51 +0800, Qin Jian wrote:
> Add vendor prefix for Sunplus Technology Co., Ltd. (http://www.sunplus.com)
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH v3 1/8] dt-bindings: vendor-prefixes: Add Sunplus
@ 2021-11-02 17:44           ` Rob Herring
  0 siblings, 0 replies; 124+ messages in thread
From: Rob Herring @ 2021-11-02 17:44 UTC (permalink / raw)
  To: Qin Jian
  Cc: p.zabel, linux-clk, broonie, linux-kernel, linux-arm-kernel,
	mturquette, sboyd, devicetree, robh+dt, wells.lu, maz

On Mon, 01 Nov 2021 13:01:51 +0800, Qin Jian wrote:
> Add vendor prefix for Sunplus Technology Co., Ltd. (http://www.sunplus.com)
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

Acked-by: Rob Herring <robh@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] 124+ messages in thread

* Re: [PATCH v3 7/8] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
  2021-11-01  5:01         ` Qin Jian
@ 2021-11-02 17:45           ` Rob Herring
  -1 siblings, 0 replies; 124+ messages in thread
From: Rob Herring @ 2021-11-02 17:45 UTC (permalink / raw)
  To: Qin Jian
  Cc: robh+dt, broonie, linux-arm-kernel, devicetree, linux-kernel,
	p.zabel, linux-clk, wells.lu, mturquette, sboyd, maz

On Mon, 01 Nov 2021 13:01:57 +0800, Qin Jian wrote:
> Add documentation to describe Sunplus SP7021 interrupt controller bindings.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  .../sunplus,sp7021-intc.yaml                  | 62 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  2 files changed, 63 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
> 

Reviewed-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH v3 7/8] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
@ 2021-11-02 17:45           ` Rob Herring
  0 siblings, 0 replies; 124+ messages in thread
From: Rob Herring @ 2021-11-02 17:45 UTC (permalink / raw)
  To: Qin Jian
  Cc: robh+dt, broonie, linux-arm-kernel, devicetree, linux-kernel,
	p.zabel, linux-clk, wells.lu, mturquette, sboyd, maz

On Mon, 01 Nov 2021 13:01:57 +0800, Qin Jian wrote:
> Add documentation to describe Sunplus SP7021 interrupt controller bindings.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  .../sunplus,sp7021-intc.yaml                  | 62 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  2 files changed, 63 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
> 

Reviewed-by: Rob Herring <robh@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] 124+ messages in thread

* 答复: [PATCH v3 3/8] dt-bindings: reset: Add bindings for SP7021 reset driver
  2021-11-02 11:51           ` Philipp Zabel
@ 2021-11-03  1:20             ` qinjian[覃健]
  -1 siblings, 0 replies; 124+ messages in thread
From: qinjian[覃健] @ 2021-11-03  1:20 UTC (permalink / raw)
  To: Philipp Zabel, robh+dt
  Cc: mturquette, sboyd, maz, broonie, linux-arm-kernel, devicetree,
	linux-kernel, linux-clk, Wells Lu 呂芳騰

> > +properties:
> > +  compatible:
> > +    enum:
> > +      - sunplus,sp7021-reset # Reset Controller on SP7021 and compatible SoCs
> > +      - sunplus,q645-reset # Reset Controller on Q645 and compatible SoCs
> 
> The commit message only mentions SP7021. Should Q645 be added later, or
> is this patch missing the binding header for Q655?
>

I'll remove the Q645 entry, which will be added later when submitting Q645 support.
Thanks for your review. 



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

* 答复: [PATCH v3 3/8] dt-bindings: reset: Add bindings for SP7021 reset driver
@ 2021-11-03  1:20             ` qinjian[覃健]
  0 siblings, 0 replies; 124+ messages in thread
From: qinjian[覃健] @ 2021-11-03  1:20 UTC (permalink / raw)
  To: Philipp Zabel, robh+dt
  Cc: mturquette, sboyd, maz, broonie, linux-arm-kernel, devicetree,
	linux-kernel, linux-clk, Wells Lu 呂芳騰

> > +properties:
> > +  compatible:
> > +    enum:
> > +      - sunplus,sp7021-reset # Reset Controller on SP7021 and compatible SoCs
> > +      - sunplus,q645-reset # Reset Controller on Q645 and compatible SoCs
> 
> The commit message only mentions SP7021. Should Q645 be added later, or
> is this patch missing the binding header for Q655?
>

I'll remove the Q645 entry, which will be added later when submitting Q645 support.
Thanks for your review. 


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

* 答复: [PATCH v3 4/8] reset: Add Sunplus SP7021 reset driver
  2021-11-02 12:22           ` Philipp Zabel
@ 2021-11-03  2:42             ` qinjian[覃健]
  -1 siblings, 0 replies; 124+ messages in thread
From: qinjian[覃健] @ 2021-11-03  2:42 UTC (permalink / raw)
  To: Philipp Zabel, robh+dt
  Cc: mturquette, sboyd, maz, broonie, linux-arm-kernel, devicetree,
	linux-kernel, linux-clk, Wells Lu 呂芳騰

> 
> > +	help
> > +	  This enables the reset driver support for Sunplus SP7021 SoC family.
> > +	  Say Y if you want to control reset signals by the reset controller.
> > +	  Otherwise, say N.
> > +	  This driver is selected automatically by platform config.
> 
> Which platform config?

arch/arm/mach-sunplus/Kconfig, which will be submit later.

Thanks for your review, I'll submit the new version based on your advice.

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

* 答复: [PATCH v3 4/8] reset: Add Sunplus SP7021 reset driver
@ 2021-11-03  2:42             ` qinjian[覃健]
  0 siblings, 0 replies; 124+ messages in thread
From: qinjian[覃健] @ 2021-11-03  2:42 UTC (permalink / raw)
  To: Philipp Zabel, robh+dt
  Cc: mturquette, sboyd, maz, broonie, linux-arm-kernel, devicetree,
	linux-kernel, linux-clk, Wells Lu 呂芳騰

> 
> > +	help
> > +	  This enables the reset driver support for Sunplus SP7021 SoC family.
> > +	  Say Y if you want to control reset signals by the reset controller.
> > +	  Otherwise, say N.
> > +	  This driver is selected automatically by platform config.
> 
> Which platform config?

arch/arm/mach-sunplus/Kconfig, which will be submit later.

Thanks for your review, I'll submit the new version based on your advice.
_______________________________________________
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] 124+ messages in thread

* [PATCH v4 00/10] Add Sunplus SP7021 SoC Support
  2021-10-29  8:44 ` Qin Jian
@ 2021-11-04  2:56   ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:56 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	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 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 (10):
  dt-bindings: vendor-prefixes: Add Sunplus
  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          |  27 +
 .../bindings/clock/sunplus,sp7021-clkc.yaml   |  38 +
 .../sunplus,sp7021-intc.yaml                  |  62 ++
 .../bindings/reset/sunplus,reset.yaml         |  38 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 MAINTAINERS                                   |  17 +
 arch/arm/Kconfig                              |  20 +
 arch/arm/Makefile                             |   2 +
 arch/arm/configs/sp7021_defconfig             | 176 +++++
 arch/arm/mach-sunplus/Kconfig                 |  20 +
 arch/arm/mach-sunplus/Makefile                |   9 +
 arch/arm/mach-sunplus/Makefile.boot           |   3 +
 arch/arm/mach-sunplus/sp7021.c                |  16 +
 drivers/clk/Kconfig                           |   9 +
 drivers/clk/Makefile                          |   1 +
 drivers/clk/clk-sp7021.c                      | 725 ++++++++++++++++++
 drivers/irqchip/Kconfig                       |   9 +
 drivers/irqchip/Makefile                      |   1 +
 drivers/irqchip/irq-sp7021-intc.c             | 279 +++++++
 drivers/reset/Kconfig                         |   9 +
 drivers/reset/Makefile                        |   1 +
 drivers/reset/reset-sunplus.c                 | 133 ++++
 include/dt-bindings/clock/sp-sp7021.h         | 112 +++
 include/dt-bindings/reset/sp-sp7021.h         |  97 +++
 24 files changed, 1806 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/Makefile.boot
 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] 124+ messages in thread

* [PATCH v4 00/10] Add Sunplus SP7021 SoC Support
@ 2021-11-04  2:56   ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:56 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	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 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 (10):
  dt-bindings: vendor-prefixes: Add Sunplus
  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          |  27 +
 .../bindings/clock/sunplus,sp7021-clkc.yaml   |  38 +
 .../sunplus,sp7021-intc.yaml                  |  62 ++
 .../bindings/reset/sunplus,reset.yaml         |  38 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 MAINTAINERS                                   |  17 +
 arch/arm/Kconfig                              |  20 +
 arch/arm/Makefile                             |   2 +
 arch/arm/configs/sp7021_defconfig             | 176 +++++
 arch/arm/mach-sunplus/Kconfig                 |  20 +
 arch/arm/mach-sunplus/Makefile                |   9 +
 arch/arm/mach-sunplus/Makefile.boot           |   3 +
 arch/arm/mach-sunplus/sp7021.c                |  16 +
 drivers/clk/Kconfig                           |   9 +
 drivers/clk/Makefile                          |   1 +
 drivers/clk/clk-sp7021.c                      | 725 ++++++++++++++++++
 drivers/irqchip/Kconfig                       |   9 +
 drivers/irqchip/Makefile                      |   1 +
 drivers/irqchip/irq-sp7021-intc.c             | 279 +++++++
 drivers/reset/Kconfig                         |   9 +
 drivers/reset/Makefile                        |   1 +
 drivers/reset/reset-sunplus.c                 | 133 ++++
 include/dt-bindings/clock/sp-sp7021.h         | 112 +++
 include/dt-bindings/reset/sp-sp7021.h         |  97 +++
 24 files changed, 1806 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/Makefile.boot
 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] 124+ messages in thread

* [PATCH v4 01/10] dt-bindings: vendor-prefixes: Add Sunplus
  2021-11-04  2:56   ` Qin Jian
@ 2021-11-04  2:56     ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:56 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	Qin Jian

Add vendor prefix for Sunplus Technology Co., Ltd. (http://www.sunplus.com)

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index a867f7102..50d4ee5ac 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1131,6 +1131,8 @@ patternProperties:
     description: Summit microelectronics
   "^sunchip,.*":
     description: Shenzhen Sunchip Technology Co., Ltd
+  "^sunplus,.*":
+    description: Sunplus Technology Co., Ltd.
   "^SUNW,.*":
     description: Sun Microsystems, Inc
   "^supermicro,.*":
-- 
2.33.1


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

* [PATCH v4 01/10] dt-bindings: vendor-prefixes: Add Sunplus
@ 2021-11-04  2:56     ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:56 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	Qin Jian

Add vendor prefix for Sunplus Technology Co., Ltd. (http://www.sunplus.com)

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index a867f7102..50d4ee5ac 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1131,6 +1131,8 @@ patternProperties:
     description: Summit microelectronics
   "^sunchip,.*":
     description: Shenzhen Sunchip Technology Co., Ltd
+  "^sunplus,.*":
+    description: Sunplus Technology Co., Ltd.
   "^SUNW,.*":
     description: Sun Microsystems, Inc
   "^supermicro,.*":
-- 
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] 124+ messages in thread

* [PATCH v4 02/10] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards
  2021-11-04  2:56   ` Qin Jian
@ 2021-11-04  2:56     ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:56 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	Qin Jian

This introduces bindings for boards based Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../bindings/arm/sunplus,sp7021.yaml          | 27 +++++++++++++++++++
 MAINTAINERS                                   |  7 +++++
 2 files changed, 34 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..5b9985b73
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
@@ -0,0 +1,27 @@
+# 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:
+    oneOf:
+      - items:
+          - const: sunplus,sp7021-achip
+
+additionalProperties: true
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index e0bca0de0..6a5422f10 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2655,6 +2655,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 <Jisheng.Zhang@synaptics.com>
 M:	Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
-- 
2.33.1


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

* [PATCH v4 02/10] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards
@ 2021-11-04  2:56     ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:56 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	Qin Jian

This introduces bindings for boards based Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../bindings/arm/sunplus,sp7021.yaml          | 27 +++++++++++++++++++
 MAINTAINERS                                   |  7 +++++
 2 files changed, 34 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..5b9985b73
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
@@ -0,0 +1,27 @@
+# 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:
+    oneOf:
+      - items:
+          - const: sunplus,sp7021-achip
+
+additionalProperties: true
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index e0bca0de0..6a5422f10 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2655,6 +2655,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 <Jisheng.Zhang@synaptics.com>
 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] 124+ messages in thread

* [PATCH v4 03/10] dt-bindings: reset: Add bindings for SP7021 reset driver
  2021-11-04  2:56   ` Qin Jian
@ 2021-11-04  2:57     ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:57 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	Qin Jian

Add documentation to describe Sunplus SP7021 reset driver bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../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..c083c821f
--- /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
+
+  "#reset-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#reset-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    rstc: reset@9c000054 {
+      compatible = "sunplus,sp7021-reset";
+      #reset-cells = <1>;
+      reg = <0x9c000054 0x28>;
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 6a5422f10..652f42cab 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2661,6 +2661,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 <Jisheng.Zhang@synaptics.com>
diff --git a/include/dt-bindings/reset/sp-sp7021.h b/include/dt-bindings/reset/sp-sp7021.h
new file mode 100644
index 000000000..c0224a960
--- /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] 124+ messages in thread

* [PATCH v4 03/10] dt-bindings: reset: Add bindings for SP7021 reset driver
@ 2021-11-04  2:57     ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:57 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	Qin Jian

Add documentation to describe Sunplus SP7021 reset driver bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../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..c083c821f
--- /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
+
+  "#reset-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#reset-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    rstc: reset@9c000054 {
+      compatible = "sunplus,sp7021-reset";
+      #reset-cells = <1>;
+      reg = <0x9c000054 0x28>;
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 6a5422f10..652f42cab 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2661,6 +2661,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 <Jisheng.Zhang@synaptics.com>
diff --git a/include/dt-bindings/reset/sp-sp7021.h b/include/dt-bindings/reset/sp-sp7021.h
new file mode 100644
index 000000000..c0224a960
--- /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] 124+ messages in thread

* [PATCH v4 04/10] reset: Add Sunplus SP7021 reset driver
  2021-11-04  2:56   ` Qin Jian
@ 2021-11-04  2:57     ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:57 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	Qin Jian

Add reset driver for Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 MAINTAINERS                   |   1 +
 drivers/reset/Kconfig         |   9 +++
 drivers/reset/Makefile        |   1 +
 drivers/reset/reset-sunplus.c | 133 ++++++++++++++++++++++++++++++++++
 4 files changed, 144 insertions(+)
 create mode 100644 drivers/reset/reset-sunplus.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 652f42cab..6caffd6d0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2662,6 +2662,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 be799a5ab..5cdd022ad 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -224,6 +224,15 @@ config RESET_SOCFPGA
 	  This enables the reset driver for the SoCFPGA ARMv7 platforms. This
 	  driver gets initialized early during platform init calls.
 
+config RESET_SUNPLUS
+	bool "Sunplus SoCs Reset Driver"
+	depends on ARCH_SUNPLUS || COMPILE_TEST
+	help
+	  This enables the reset driver support for Sunplus SP7021 SoC family.
+	  Say Y if you want to control reset signals by the reset controller.
+	  Otherwise, say N.
+	  This driver is selected automatically by arm/mach-sunplus platform config.
+
 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 21d46d886..f03403e97 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o
 obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
 obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
 obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
+obj-$(CONFIG_RESET_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..6e29407d4
--- /dev/null
+++ b/drivers/reset/reset-sunplus.c
@@ -0,0 +1,133 @@
+// 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/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/reboot.h>
+
+/* HIWORD_MASK */
+#define BITASSERT(id, val)	((1 << (16 + id)) | (val << id))
+
+struct sp_reset_data {
+	struct reset_controller_dev	rcdev;
+	void __iomem *membase;
+} *sp_reset;
+
+static inline struct sp_reset_data *
+to_sp_reset_data(struct reset_controller_dev *rcdev)
+{
+	return container_of(rcdev, struct sp_reset_data, rcdev);
+}
+
+static int sp_reset_update(struct reset_controller_dev *rcdev,
+			      unsigned long id, bool assert)
+{
+	struct sp_reset_data *data = to_sp_reset_data(rcdev);
+	int reg_width = sizeof(u32) / 2;
+	int bank = id / (reg_width * BITS_PER_BYTE);
+	int offset = id % (reg_width * BITS_PER_BYTE);
+	void __iomem *addr = data->membase + (bank * 4);
+
+	writel(BITASSERT(offset, assert), addr);
+
+	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_data *data = to_sp_reset_data(rcdev);
+	int reg_width = sizeof(u32) / 2;
+	int bank = id / (reg_width * BITS_PER_BYTE);
+	int offset = id % (reg_width * BITS_PER_BYTE);
+	u32 reg;
+
+	reg = readl(data->membase + (bank * 4));
+
+	return !!(reg & BIT(offset));
+}
+
+static int sp_restart(struct notifier_block *this, unsigned long mode,
+				void *cmd)
+{
+	sp_reset_assert(&sp_reset->rcdev, 0);
+	sp_reset_deassert(&sp_reset->rcdev, 0);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block sp_restart_nb = {
+	.notifier_call = sp_restart,
+	.priority = 192,
+};
+
+static const struct reset_control_ops sp_reset_ops = {
+	.assert		= sp_reset_assert,
+	.deassert	= sp_reset_deassert,
+	.status		= sp_reset_status,
+};
+
+static const struct of_device_id sp_reset_dt_ids[] = {
+	{ .compatible = "sunplus,sp7021-reset", },
+	{ /* sentinel */ },
+};
+
+static int sp_reset_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	void __iomem *membase;
+	struct resource *res;
+
+	sp_reset = devm_kzalloc(&pdev->dev, sizeof(*sp_reset), GFP_KERNEL);
+	if (!sp_reset)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	membase = devm_ioremap_resource(dev, res);
+	if (IS_ERR(membase))
+		return PTR_ERR(membase);
+
+	sp_reset->membase = membase;
+	sp_reset->rcdev.owner = THIS_MODULE;
+	sp_reset->rcdev.nr_resets = resource_size(res) / 4 * 16; /* HIWORD_MASK */
+	sp_reset->rcdev.ops = &sp_reset_ops;
+	sp_reset->rcdev.of_node = dev->of_node;
+	register_restart_handler(&sp_restart_nb);
+
+	return devm_reset_controller_register(dev, &sp_reset->rcdev);
+}
+
+static struct platform_driver sp_reset_driver = {
+	.probe	= sp_reset_probe,
+	.driver = {
+		.name = "sunplus-reset",
+		.of_match_table	= sp_reset_dt_ids,
+	},
+};
+module_platform_driver(sp_reset_driver);
+
+MODULE_AUTHOR("Edwin Chiu <edwin.chiu@sunplus.com>");
+MODULE_DESCRIPTION("Sunplus Reset Driver");
+MODULE_LICENSE("GPL v2");
-- 
2.33.1


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

* [PATCH v4 04/10] reset: Add Sunplus SP7021 reset driver
@ 2021-11-04  2:57     ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:57 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	Qin Jian

Add reset driver for Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 MAINTAINERS                   |   1 +
 drivers/reset/Kconfig         |   9 +++
 drivers/reset/Makefile        |   1 +
 drivers/reset/reset-sunplus.c | 133 ++++++++++++++++++++++++++++++++++
 4 files changed, 144 insertions(+)
 create mode 100644 drivers/reset/reset-sunplus.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 652f42cab..6caffd6d0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2662,6 +2662,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 be799a5ab..5cdd022ad 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -224,6 +224,15 @@ config RESET_SOCFPGA
 	  This enables the reset driver for the SoCFPGA ARMv7 platforms. This
 	  driver gets initialized early during platform init calls.
 
+config RESET_SUNPLUS
+	bool "Sunplus SoCs Reset Driver"
+	depends on ARCH_SUNPLUS || COMPILE_TEST
+	help
+	  This enables the reset driver support for Sunplus SP7021 SoC family.
+	  Say Y if you want to control reset signals by the reset controller.
+	  Otherwise, say N.
+	  This driver is selected automatically by arm/mach-sunplus platform config.
+
 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 21d46d886..f03403e97 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o
 obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
 obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
 obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
+obj-$(CONFIG_RESET_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..6e29407d4
--- /dev/null
+++ b/drivers/reset/reset-sunplus.c
@@ -0,0 +1,133 @@
+// 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/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/reboot.h>
+
+/* HIWORD_MASK */
+#define BITASSERT(id, val)	((1 << (16 + id)) | (val << id))
+
+struct sp_reset_data {
+	struct reset_controller_dev	rcdev;
+	void __iomem *membase;
+} *sp_reset;
+
+static inline struct sp_reset_data *
+to_sp_reset_data(struct reset_controller_dev *rcdev)
+{
+	return container_of(rcdev, struct sp_reset_data, rcdev);
+}
+
+static int sp_reset_update(struct reset_controller_dev *rcdev,
+			      unsigned long id, bool assert)
+{
+	struct sp_reset_data *data = to_sp_reset_data(rcdev);
+	int reg_width = sizeof(u32) / 2;
+	int bank = id / (reg_width * BITS_PER_BYTE);
+	int offset = id % (reg_width * BITS_PER_BYTE);
+	void __iomem *addr = data->membase + (bank * 4);
+
+	writel(BITASSERT(offset, assert), addr);
+
+	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_data *data = to_sp_reset_data(rcdev);
+	int reg_width = sizeof(u32) / 2;
+	int bank = id / (reg_width * BITS_PER_BYTE);
+	int offset = id % (reg_width * BITS_PER_BYTE);
+	u32 reg;
+
+	reg = readl(data->membase + (bank * 4));
+
+	return !!(reg & BIT(offset));
+}
+
+static int sp_restart(struct notifier_block *this, unsigned long mode,
+				void *cmd)
+{
+	sp_reset_assert(&sp_reset->rcdev, 0);
+	sp_reset_deassert(&sp_reset->rcdev, 0);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block sp_restart_nb = {
+	.notifier_call = sp_restart,
+	.priority = 192,
+};
+
+static const struct reset_control_ops sp_reset_ops = {
+	.assert		= sp_reset_assert,
+	.deassert	= sp_reset_deassert,
+	.status		= sp_reset_status,
+};
+
+static const struct of_device_id sp_reset_dt_ids[] = {
+	{ .compatible = "sunplus,sp7021-reset", },
+	{ /* sentinel */ },
+};
+
+static int sp_reset_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	void __iomem *membase;
+	struct resource *res;
+
+	sp_reset = devm_kzalloc(&pdev->dev, sizeof(*sp_reset), GFP_KERNEL);
+	if (!sp_reset)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	membase = devm_ioremap_resource(dev, res);
+	if (IS_ERR(membase))
+		return PTR_ERR(membase);
+
+	sp_reset->membase = membase;
+	sp_reset->rcdev.owner = THIS_MODULE;
+	sp_reset->rcdev.nr_resets = resource_size(res) / 4 * 16; /* HIWORD_MASK */
+	sp_reset->rcdev.ops = &sp_reset_ops;
+	sp_reset->rcdev.of_node = dev->of_node;
+	register_restart_handler(&sp_restart_nb);
+
+	return devm_reset_controller_register(dev, &sp_reset->rcdev);
+}
+
+static struct platform_driver sp_reset_driver = {
+	.probe	= sp_reset_probe,
+	.driver = {
+		.name = "sunplus-reset",
+		.of_match_table	= sp_reset_dt_ids,
+	},
+};
+module_platform_driver(sp_reset_driver);
+
+MODULE_AUTHOR("Edwin Chiu <edwin.chiu@sunplus.com>");
+MODULE_DESCRIPTION("Sunplus Reset Driver");
+MODULE_LICENSE("GPL v2");
-- 
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] 124+ messages in thread

* [PATCH v4 05/10] dt-bindings: clock: Add bindings for SP7021 clock driver
  2021-11-04  2:56   ` Qin Jian
@ 2021-11-04  2:57     ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:57 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	Qin Jian

Add documentation to describe Sunplus SP7021 clock driver bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../bindings/clock/sunplus,sp7021-clkc.yaml   |  38 ++++++
 MAINTAINERS                                   |   2 +
 include/dt-bindings/clock/sp-sp7021.h         | 112 ++++++++++++++++++
 3 files changed, 152 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..1ce7e41d8
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.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/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
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    clkc: clkc@9c000000 {
+      compatible = "sunplus,sp7021-clkc";
+      #clock-cells = <1>;
+      reg = <0x9c000000 0x280>;
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 6caffd6d0..90ebb823f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2661,8 +2661,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..425e2ec0f
--- /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] 124+ messages in thread

* [PATCH v4 05/10] dt-bindings: clock: Add bindings for SP7021 clock driver
@ 2021-11-04  2:57     ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:57 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	Qin Jian

Add documentation to describe Sunplus SP7021 clock driver bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../bindings/clock/sunplus,sp7021-clkc.yaml   |  38 ++++++
 MAINTAINERS                                   |   2 +
 include/dt-bindings/clock/sp-sp7021.h         | 112 ++++++++++++++++++
 3 files changed, 152 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..1ce7e41d8
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.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/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
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    clkc: clkc@9c000000 {
+      compatible = "sunplus,sp7021-clkc";
+      #clock-cells = <1>;
+      reg = <0x9c000000 0x280>;
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 6caffd6d0..90ebb823f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2661,8 +2661,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..425e2ec0f
--- /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] 124+ messages in thread

* [PATCH v4 06/10] clk: Add Sunplus SP7021 clock driver
  2021-11-04  2:56   ` Qin Jian
@ 2021-11-04  2:57     ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:57 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	Qin Jian

Add clock driver for Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 MAINTAINERS              |   1 +
 drivers/clk/Kconfig      |   9 +
 drivers/clk/Makefile     |   1 +
 drivers/clk/clk-sp7021.c | 725 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 736 insertions(+)
 create mode 100644 drivers/clk/clk-sp7021.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 90ebb823f..5069f552f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2663,6 +2663,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 c5b3dc973..1cd7ae7a3 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -334,6 +334,15 @@ 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"
+	help
+	  This driver supports the Sunplus SP7021 SoC clocks.
+	  It implemented SP7021 PLLs/gate.
+	  Not all features of the PLL are currently supported
+	  by the driver.
+	  This driver is selected automatically by platform config.
+
 config COMMON_CLK_STM32MP157
 	def_bool COMMON_CLK && MACH_STM32MP157
 	help
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index e42312121..f15bb5070 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -60,6 +60,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..e5e430a66
--- /dev/null
+++ b/drivers/clk/clk-sp7021.c
@@ -0,0 +1,725 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ *       All rights reserved.
+ */
+//#define DEBUG
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <dt-bindings/clock/sp-sp7021.h>
+
+#ifndef clk_readl
+#define clk_readl  readl
+#define clk_writel writel
+#endif
+
+#define MASK_SET(shift, width, value) \
+({ \
+	u32 m = ((1 << (width)) - 1) << (shift); \
+	(m << 16) | (((value) << (shift)) & m); \
+})
+#define MASK_GET(shift, width, value)	(((value) >> (shift)) & ((1 << (width)) - 1))
+
+#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)
+
+#define EXTCLK		"extclk"
+
+/* 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
+};
+
+struct sp_pll {
+	struct clk_hw hw;
+	void __iomem *reg;
+	spinlock_t *lock;
+	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	(moon_regs + 0x000) /* G0 ~ CLKEN */
+#define pll_regs	(moon_regs + 0x200) /* G4 ~ PLL */
+static void __iomem *moon_regs;
+
+#define P_EXTCLK	(1 << 16)
+static const char * const parents[] = {
+	"pllsys",
+	"extclk",
+};
+
+static const u32 gates[] = {
+	CLK_SYSTEM,
+	CLK_RTC,
+	CLK_IOCTL,
+	CLK_IOP,
+	CLK_OTPRX,
+	CLK_NOC,
+	CLK_BR,
+	CLK_RBUS_L00,
+	CLK_SPIFL,
+	CLK_SDCTRL0,
+	CLK_PERI0 | P_EXTCLK,
+	CLK_A926,
+	CLK_UMCTL2,
+	CLK_PERI1 | P_EXTCLK,
+
+	CLK_DDR_PHY0,
+	CLK_ACHIP,
+	CLK_STC0,
+	CLK_STC_AV0,
+	CLK_STC_AV1,
+	CLK_STC_AV2,
+	CLK_UA0 | P_EXTCLK,
+	CLK_UA1 | P_EXTCLK,
+	CLK_UA2 | P_EXTCLK,
+	CLK_UA3 | P_EXTCLK,
+	CLK_UA4 | P_EXTCLK,
+	CLK_HWUA | P_EXTCLK,
+	CLK_DDC0,
+	CLK_UADMA | P_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_INTERRUPT,
+
+	CLK_RGST,
+	CLK_GPIO,
+	CLK_RBUS_TOP,
+
+	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 struct clk *clks[CLK_MAX];
+static struct clk_onecell_data clk_data;
+
+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 *******************************************/
+
+//#define PLLTV_STEP_DIR (?) /* Unit: HZ */
+
+/* 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;
+#ifdef PLLTV_STEP_DIR
+	u32 step = (PLLTV_STEP_DIR > 0) ? PLLTV_STEP_DIR : -PLLTV_STEP_DIR;
+	int calc_times = 1000000 / step;
+#endif
+	unsigned long fvco, nf;
+
+	/* check freq */
+	if (freq < F_MIN) {
+		pr_warn("%s: %s freq:%lu < F_MIN:%lu, round up\n",
+			__func__, clk_hw_get_name(&clk->hw), freq, F_MIN);
+		freq = F_MIN;
+	} else if (freq > F_MAX) {
+		pr_warn("%s: %s freq:%lu > F_MAX:%lu, round down\n",
+			__func__, clk_hw_get_name(&clk->hw), freq, F_MAX);
+		freq = F_MAX;
+	}
+
+#ifdef PLLTV_STEP_DIR
+	if ((freq % step) != 0)
+		freq += step - (freq % step) + ((PLLTV_STEP_DIR > 0) ? 0 : PLLTV_STEP_DIR);
+#endif
+
+#ifdef PLLTV_STEP_DIR
+CALC:
+	if (!calc_times) {
+		pr_err("%s: %s freq:%lu out of recalc times\n",
+			__func__, clk_hw_get_name(&clk->hw), freq);
+		return -ETIMEOUT;
+	}
+#endif
+
+	/* 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) {
+#ifdef PLLTV_STEP_DIR
+		freq += PLLTV_STEP_DIR;
+		calc_times--;
+		goto CALC;
+#else
+		pr_err("%s: %s freq:%lu not found a valid setting\n",
+			__func__, clk_hw_get_name(&clk->hw), freq);
+		return -EINVAL;
+#endif
+	}
+
+	/* 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 diff_min_quotient = 210000000, diff_min_remainder = 0;
+	u32 diff_min_sign = 0;
+	unsigned long fvco, nf, f, fout = 0;
+	int sdm, ph;
+
+	/* check freq */
+	if (freq < F_MIN) {
+		pr_warn("%s: %s freq:%lu < F_MIN:%lu, round up\n",
+			__func__, clk_hw_get_name(&clk->hw), freq, F_MIN);
+		freq = F_MIN;
+	} else if (freq > F_MAX) {
+		pr_warn("%s: %s freq:%lu > F_MAX:%lu, round down\n",
+			__func__, clk_hw_get_name(&clk->hw), freq, F_MAX);
+		freq = 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 diff_freq;
+				u32 diff_freq_quotient = 0, diff_freq_remainder = 0;
+				u32 diff_freq_sign = 0; /* 0:Positive number, 1:Negative number */
+
+				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)
+					diff_freq = (f * (nint + pp[2]) / pp[0]) -
+								(f * (mod - nfra) / mod / pp[4]);
+				else
+					diff_freq = (f * (nint) / pp[0]);
+
+				diff_freq_quotient  = diff_freq / m;
+				diff_freq_remainder = ((diff_freq % m) * 1000) / m;
+
+				if (freq > diff_freq_quotient) {
+					diff_freq_quotient  = freq - diff_freq_quotient - 1;
+					diff_freq_remainder = 1000 - diff_freq_remainder;
+					diff_freq_sign = 1;
+				} else {
+					diff_freq_quotient = diff_freq_quotient - freq;
+					diff_freq_sign = 0;
+				}
+
+				if ((diff_min_quotient > diff_freq_quotient) ||
+					((diff_min_quotient == diff_freq_quotient) &&
+					(diff_min_remainder > diff_freq_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 = diff_freq / m;
+					diff_min_quotient = diff_freq_quotient;
+					diff_min_remainder = diff_freq_remainder;
+					diff_min_sign = diff_freq_sign;
+				}
+			}
+		}
+	}
+
+	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);
+	else
+		return plltv_integer_div(clk, freq);
+}
+
+static void plltv_set_rate(struct sp_pll *clk)
+{
+	u32 reg;
+
+	reg  = MASK_SET(1, 1, clk->p[SEL_FRA]);
+	reg |= MASK_SET(2, 1, clk->p[SDM_MOD]);
+	reg |= MASK_SET(4, 1, clk->p[PH_SEL]);
+	reg |= MASK_SET(6, 7, clk->p[NFRA]);
+	clk_writel(reg, clk->reg);
+
+	reg  = MASK_SET(7, 2, clk->p[DIVR]);
+	clk_writel(reg, clk->reg + 4);
+
+	reg  = MASK_SET(0, 8, clk->p[DIVN] - 1);
+	reg |= MASK_SET(8, 7, clk->p[DIVM] - 1);
+	clk_writel(reg, clk->reg + 8);
+}
+
+/******************************************** PLL_A ********************************************/
+
+/* from Q628_PLLs_REG_setting.xlsx */
+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++)
+		clk_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 = clk_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 = MASK_GET(7, 2, clk_readl(clk->reg + 4));
+		reg2 = clk_readl(clk->reg + 8);
+		m = MASK_GET(8, 7, reg2) + 1;
+
+		if (reg & BIT(1)) { /* SEL_FRA */
+			/* fractional divider */
+			u32 sdm  = MASK_GET(2, 1, reg);
+			u32 ph   = MASK_GET(4, 1, reg);
+			u32 nfra = MASK_GET(6, 7, 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 = MASK_GET(0, 8, reg2) + 1;
+
+			ret = (prate / m * n) >> r;
+		}
+	} else {
+		u32 fbdiv = MASK_GET(clk->div_shift, clk->div_width, reg) + 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);
+
+		reg |= MASK_SET(clk->div_shift, clk->div_width, fbdiv - 1);
+	}
+
+	clk_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);
+	clk_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);
+	clk_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 clk_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,
+};
+
+struct clk *clk_register_sp_pll(const char *name, const char *parent,
+		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 *clk;
+	struct clk_init_data initd = {
+		.name = name,
+		.parent_names = &parent,
+		.ops = (bp_bit >= 0) ? &sp_pll_ops : &sp_pll_sub_ops,
+		.num_parents = 1,
+		.flags = CLK_IGNORE_UNUSED
+	};
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	if (reg == PLLSYS_CTL)
+		initd.flags |= CLK_IS_CRITICAL;
+
+	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;
+
+	clk = clk_register(NULL, &pll->hw);
+	if (WARN_ON(IS_ERR(clk))) {
+		kfree(pll);
+	} else {
+		pr_info("%-20s%lu\n", name, clk_get_rate(clk));
+		clk_register_clkdev(clk, NULL, name);
+	}
+
+	return clk;
+}
+
+static void __init sp_clk_setup(struct device_node *np)
+{
+	int i, j;
+
+	moon_regs = of_iomap(np, 0);
+	if (WARN_ON(!moon_regs))
+		return; /* -ENXIO */
+
+	/* PLL_A */
+	clks[PLL_A] = clk_register_sp_pll("plla", EXTCLK,
+			PLLA_CTL, 11, 12, 27000000, 0, DIV_A, &plla_lock);
+
+	/* PLL_E */
+	clks[PLL_E] = clk_register_sp_pll("plle", EXTCLK,
+			PLLE_CTL, 6, 2, 50000000, 0, 0, &plle_lock);
+	clks[PLL_E_2P5] = clk_register_sp_pll("plle_2p5", "plle",
+			PLLE_CTL, 13, -1, 2500000, 0, 0, &plle_lock);
+	clks[PLL_E_25] = clk_register_sp_pll("plle_25", "plle",
+			PLLE_CTL, 12, -1, 25000000, 0, 0, &plle_lock);
+	clks[PLL_E_112P5] = clk_register_sp_pll("plle_112p5", "plle",
+			PLLE_CTL, 11, -1, 112500000, 0, 0, &plle_lock);
+
+	/* PLL_F */
+	clks[PLL_F] = clk_register_sp_pll("pllf", EXTCLK,
+			PLLF_CTL, 0, 10, 13500000, 1, 4, &pllf_lock);
+
+	/* PLL_TV */
+	clks[PLL_TV] = clk_register_sp_pll("plltv", EXTCLK,
+			PLLTV_CTL, 0, 15, 27000000, 0, DIV_TV, &plltv_lock);
+	clks[PLL_TV_A] = clk_register_divider(NULL, "plltv_a", "plltv", 0,
+			PLLTV_CTL + 4, 5, 1,
+			CLK_DIVIDER_POWER_OF_TWO, &plltv_lock);
+	clk_register_clkdev(clks[PLL_TV_A], NULL, "plltv_a");
+
+	/* PLL_SYS */
+	clks[PLL_SYS] = clk_register_sp_pll("pllsys", EXTCLK,
+			PLLSYS_CTL, 10, 9, 13500000, 0, 4, &pllsys_lock);
+
+	/* gates */
+	for (i = 0; i < ARRAY_SIZE(gates); i++) {
+		char s[10];
+
+		j = gates[i] & 0xffff;
+		sprintf(s, "clken%02x", j);
+		clks[j] = clk_register_gate(NULL, s, parents[gates[i] >> 16], CLK_IGNORE_UNUSED,
+			clk_regs + (j >> 4) * 4, j & 0x0f,
+			CLK_GATE_HIWORD_MASK, NULL);
+	}
+
+	clk_data.clks = clks;
+	clk_data.clk_num = ARRAY_SIZE(clks);
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+
+CLK_OF_DECLARE(sp_clkc, "sunplus,sp7021-clkc", sp_clk_setup);
+
+MODULE_AUTHOR("Qin Jian <qinjian@cqplus1.com>");
+MODULE_DESCRIPTION("Sunplus SP7021 Clock Driver");
+MODULE_LICENSE("GPL v2");
-- 
2.33.1


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

* [PATCH v4 06/10] clk: Add Sunplus SP7021 clock driver
@ 2021-11-04  2:57     ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:57 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	Qin Jian

Add clock driver for Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 MAINTAINERS              |   1 +
 drivers/clk/Kconfig      |   9 +
 drivers/clk/Makefile     |   1 +
 drivers/clk/clk-sp7021.c | 725 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 736 insertions(+)
 create mode 100644 drivers/clk/clk-sp7021.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 90ebb823f..5069f552f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2663,6 +2663,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 c5b3dc973..1cd7ae7a3 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -334,6 +334,15 @@ 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"
+	help
+	  This driver supports the Sunplus SP7021 SoC clocks.
+	  It implemented SP7021 PLLs/gate.
+	  Not all features of the PLL are currently supported
+	  by the driver.
+	  This driver is selected automatically by platform config.
+
 config COMMON_CLK_STM32MP157
 	def_bool COMMON_CLK && MACH_STM32MP157
 	help
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index e42312121..f15bb5070 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -60,6 +60,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..e5e430a66
--- /dev/null
+++ b/drivers/clk/clk-sp7021.c
@@ -0,0 +1,725 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ *       All rights reserved.
+ */
+//#define DEBUG
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <dt-bindings/clock/sp-sp7021.h>
+
+#ifndef clk_readl
+#define clk_readl  readl
+#define clk_writel writel
+#endif
+
+#define MASK_SET(shift, width, value) \
+({ \
+	u32 m = ((1 << (width)) - 1) << (shift); \
+	(m << 16) | (((value) << (shift)) & m); \
+})
+#define MASK_GET(shift, width, value)	(((value) >> (shift)) & ((1 << (width)) - 1))
+
+#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)
+
+#define EXTCLK		"extclk"
+
+/* 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
+};
+
+struct sp_pll {
+	struct clk_hw hw;
+	void __iomem *reg;
+	spinlock_t *lock;
+	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	(moon_regs + 0x000) /* G0 ~ CLKEN */
+#define pll_regs	(moon_regs + 0x200) /* G4 ~ PLL */
+static void __iomem *moon_regs;
+
+#define P_EXTCLK	(1 << 16)
+static const char * const parents[] = {
+	"pllsys",
+	"extclk",
+};
+
+static const u32 gates[] = {
+	CLK_SYSTEM,
+	CLK_RTC,
+	CLK_IOCTL,
+	CLK_IOP,
+	CLK_OTPRX,
+	CLK_NOC,
+	CLK_BR,
+	CLK_RBUS_L00,
+	CLK_SPIFL,
+	CLK_SDCTRL0,
+	CLK_PERI0 | P_EXTCLK,
+	CLK_A926,
+	CLK_UMCTL2,
+	CLK_PERI1 | P_EXTCLK,
+
+	CLK_DDR_PHY0,
+	CLK_ACHIP,
+	CLK_STC0,
+	CLK_STC_AV0,
+	CLK_STC_AV1,
+	CLK_STC_AV2,
+	CLK_UA0 | P_EXTCLK,
+	CLK_UA1 | P_EXTCLK,
+	CLK_UA2 | P_EXTCLK,
+	CLK_UA3 | P_EXTCLK,
+	CLK_UA4 | P_EXTCLK,
+	CLK_HWUA | P_EXTCLK,
+	CLK_DDC0,
+	CLK_UADMA | P_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_INTERRUPT,
+
+	CLK_RGST,
+	CLK_GPIO,
+	CLK_RBUS_TOP,
+
+	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 struct clk *clks[CLK_MAX];
+static struct clk_onecell_data clk_data;
+
+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 *******************************************/
+
+//#define PLLTV_STEP_DIR (?) /* Unit: HZ */
+
+/* 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;
+#ifdef PLLTV_STEP_DIR
+	u32 step = (PLLTV_STEP_DIR > 0) ? PLLTV_STEP_DIR : -PLLTV_STEP_DIR;
+	int calc_times = 1000000 / step;
+#endif
+	unsigned long fvco, nf;
+
+	/* check freq */
+	if (freq < F_MIN) {
+		pr_warn("%s: %s freq:%lu < F_MIN:%lu, round up\n",
+			__func__, clk_hw_get_name(&clk->hw), freq, F_MIN);
+		freq = F_MIN;
+	} else if (freq > F_MAX) {
+		pr_warn("%s: %s freq:%lu > F_MAX:%lu, round down\n",
+			__func__, clk_hw_get_name(&clk->hw), freq, F_MAX);
+		freq = F_MAX;
+	}
+
+#ifdef PLLTV_STEP_DIR
+	if ((freq % step) != 0)
+		freq += step - (freq % step) + ((PLLTV_STEP_DIR > 0) ? 0 : PLLTV_STEP_DIR);
+#endif
+
+#ifdef PLLTV_STEP_DIR
+CALC:
+	if (!calc_times) {
+		pr_err("%s: %s freq:%lu out of recalc times\n",
+			__func__, clk_hw_get_name(&clk->hw), freq);
+		return -ETIMEOUT;
+	}
+#endif
+
+	/* 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) {
+#ifdef PLLTV_STEP_DIR
+		freq += PLLTV_STEP_DIR;
+		calc_times--;
+		goto CALC;
+#else
+		pr_err("%s: %s freq:%lu not found a valid setting\n",
+			__func__, clk_hw_get_name(&clk->hw), freq);
+		return -EINVAL;
+#endif
+	}
+
+	/* 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 diff_min_quotient = 210000000, diff_min_remainder = 0;
+	u32 diff_min_sign = 0;
+	unsigned long fvco, nf, f, fout = 0;
+	int sdm, ph;
+
+	/* check freq */
+	if (freq < F_MIN) {
+		pr_warn("%s: %s freq:%lu < F_MIN:%lu, round up\n",
+			__func__, clk_hw_get_name(&clk->hw), freq, F_MIN);
+		freq = F_MIN;
+	} else if (freq > F_MAX) {
+		pr_warn("%s: %s freq:%lu > F_MAX:%lu, round down\n",
+			__func__, clk_hw_get_name(&clk->hw), freq, F_MAX);
+		freq = 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 diff_freq;
+				u32 diff_freq_quotient = 0, diff_freq_remainder = 0;
+				u32 diff_freq_sign = 0; /* 0:Positive number, 1:Negative number */
+
+				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)
+					diff_freq = (f * (nint + pp[2]) / pp[0]) -
+								(f * (mod - nfra) / mod / pp[4]);
+				else
+					diff_freq = (f * (nint) / pp[0]);
+
+				diff_freq_quotient  = diff_freq / m;
+				diff_freq_remainder = ((diff_freq % m) * 1000) / m;
+
+				if (freq > diff_freq_quotient) {
+					diff_freq_quotient  = freq - diff_freq_quotient - 1;
+					diff_freq_remainder = 1000 - diff_freq_remainder;
+					diff_freq_sign = 1;
+				} else {
+					diff_freq_quotient = diff_freq_quotient - freq;
+					diff_freq_sign = 0;
+				}
+
+				if ((diff_min_quotient > diff_freq_quotient) ||
+					((diff_min_quotient == diff_freq_quotient) &&
+					(diff_min_remainder > diff_freq_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 = diff_freq / m;
+					diff_min_quotient = diff_freq_quotient;
+					diff_min_remainder = diff_freq_remainder;
+					diff_min_sign = diff_freq_sign;
+				}
+			}
+		}
+	}
+
+	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);
+	else
+		return plltv_integer_div(clk, freq);
+}
+
+static void plltv_set_rate(struct sp_pll *clk)
+{
+	u32 reg;
+
+	reg  = MASK_SET(1, 1, clk->p[SEL_FRA]);
+	reg |= MASK_SET(2, 1, clk->p[SDM_MOD]);
+	reg |= MASK_SET(4, 1, clk->p[PH_SEL]);
+	reg |= MASK_SET(6, 7, clk->p[NFRA]);
+	clk_writel(reg, clk->reg);
+
+	reg  = MASK_SET(7, 2, clk->p[DIVR]);
+	clk_writel(reg, clk->reg + 4);
+
+	reg  = MASK_SET(0, 8, clk->p[DIVN] - 1);
+	reg |= MASK_SET(8, 7, clk->p[DIVM] - 1);
+	clk_writel(reg, clk->reg + 8);
+}
+
+/******************************************** PLL_A ********************************************/
+
+/* from Q628_PLLs_REG_setting.xlsx */
+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++)
+		clk_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 = clk_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 = MASK_GET(7, 2, clk_readl(clk->reg + 4));
+		reg2 = clk_readl(clk->reg + 8);
+		m = MASK_GET(8, 7, reg2) + 1;
+
+		if (reg & BIT(1)) { /* SEL_FRA */
+			/* fractional divider */
+			u32 sdm  = MASK_GET(2, 1, reg);
+			u32 ph   = MASK_GET(4, 1, reg);
+			u32 nfra = MASK_GET(6, 7, 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 = MASK_GET(0, 8, reg2) + 1;
+
+			ret = (prate / m * n) >> r;
+		}
+	} else {
+		u32 fbdiv = MASK_GET(clk->div_shift, clk->div_width, reg) + 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);
+
+		reg |= MASK_SET(clk->div_shift, clk->div_width, fbdiv - 1);
+	}
+
+	clk_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);
+	clk_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);
+	clk_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 clk_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,
+};
+
+struct clk *clk_register_sp_pll(const char *name, const char *parent,
+		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 *clk;
+	struct clk_init_data initd = {
+		.name = name,
+		.parent_names = &parent,
+		.ops = (bp_bit >= 0) ? &sp_pll_ops : &sp_pll_sub_ops,
+		.num_parents = 1,
+		.flags = CLK_IGNORE_UNUSED
+	};
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	if (reg == PLLSYS_CTL)
+		initd.flags |= CLK_IS_CRITICAL;
+
+	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;
+
+	clk = clk_register(NULL, &pll->hw);
+	if (WARN_ON(IS_ERR(clk))) {
+		kfree(pll);
+	} else {
+		pr_info("%-20s%lu\n", name, clk_get_rate(clk));
+		clk_register_clkdev(clk, NULL, name);
+	}
+
+	return clk;
+}
+
+static void __init sp_clk_setup(struct device_node *np)
+{
+	int i, j;
+
+	moon_regs = of_iomap(np, 0);
+	if (WARN_ON(!moon_regs))
+		return; /* -ENXIO */
+
+	/* PLL_A */
+	clks[PLL_A] = clk_register_sp_pll("plla", EXTCLK,
+			PLLA_CTL, 11, 12, 27000000, 0, DIV_A, &plla_lock);
+
+	/* PLL_E */
+	clks[PLL_E] = clk_register_sp_pll("plle", EXTCLK,
+			PLLE_CTL, 6, 2, 50000000, 0, 0, &plle_lock);
+	clks[PLL_E_2P5] = clk_register_sp_pll("plle_2p5", "plle",
+			PLLE_CTL, 13, -1, 2500000, 0, 0, &plle_lock);
+	clks[PLL_E_25] = clk_register_sp_pll("plle_25", "plle",
+			PLLE_CTL, 12, -1, 25000000, 0, 0, &plle_lock);
+	clks[PLL_E_112P5] = clk_register_sp_pll("plle_112p5", "plle",
+			PLLE_CTL, 11, -1, 112500000, 0, 0, &plle_lock);
+
+	/* PLL_F */
+	clks[PLL_F] = clk_register_sp_pll("pllf", EXTCLK,
+			PLLF_CTL, 0, 10, 13500000, 1, 4, &pllf_lock);
+
+	/* PLL_TV */
+	clks[PLL_TV] = clk_register_sp_pll("plltv", EXTCLK,
+			PLLTV_CTL, 0, 15, 27000000, 0, DIV_TV, &plltv_lock);
+	clks[PLL_TV_A] = clk_register_divider(NULL, "plltv_a", "plltv", 0,
+			PLLTV_CTL + 4, 5, 1,
+			CLK_DIVIDER_POWER_OF_TWO, &plltv_lock);
+	clk_register_clkdev(clks[PLL_TV_A], NULL, "plltv_a");
+
+	/* PLL_SYS */
+	clks[PLL_SYS] = clk_register_sp_pll("pllsys", EXTCLK,
+			PLLSYS_CTL, 10, 9, 13500000, 0, 4, &pllsys_lock);
+
+	/* gates */
+	for (i = 0; i < ARRAY_SIZE(gates); i++) {
+		char s[10];
+
+		j = gates[i] & 0xffff;
+		sprintf(s, "clken%02x", j);
+		clks[j] = clk_register_gate(NULL, s, parents[gates[i] >> 16], CLK_IGNORE_UNUSED,
+			clk_regs + (j >> 4) * 4, j & 0x0f,
+			CLK_GATE_HIWORD_MASK, NULL);
+	}
+
+	clk_data.clks = clks;
+	clk_data.clk_num = ARRAY_SIZE(clks);
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+
+CLK_OF_DECLARE(sp_clkc, "sunplus,sp7021-clkc", sp_clk_setup);
+
+MODULE_AUTHOR("Qin Jian <qinjian@cqplus1.com>");
+MODULE_DESCRIPTION("Sunplus SP7021 Clock Driver");
+MODULE_LICENSE("GPL v2");
-- 
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] 124+ messages in thread

* [PATCH v4 07/10] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
  2021-11-04  2:56   ` Qin Jian
@ 2021-11-04  2:57     ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:57 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	Qin Jian

Add documentation to describe Sunplus SP7021 interrupt controller bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../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..5daeab63c
--- /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
+
+  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.
+
+  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.
+
+  interrupts:
+    maxItems: 2
+    description:
+      EXT_INT0 & EXT_INT1, 2 interrupts references to primary interrupt
+      controller.
+
+required:
+  - compatible
+  - interrupt-controller
+  - "#interrupt-cells"
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    intc: interrupt-controller@9c000780 {
+        compatible = "sunplus,sp7021-intc";
+        interrupt-controller;
+        #interrupt-cells = <2>;
+        reg = <0x9c000780 0x80>, <0x9c000a80 0x80>;
+        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 5069f552f..6b3bbe021 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2662,6 +2662,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] 124+ messages in thread

* [PATCH v4 07/10] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
@ 2021-11-04  2:57     ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:57 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	Qin Jian

Add documentation to describe Sunplus SP7021 interrupt controller bindings.

Signed-off-by: Qin Jian <qinjian@cqplus1.com>
---
 .../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..5daeab63c
--- /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
+
+  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.
+
+  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.
+
+  interrupts:
+    maxItems: 2
+    description:
+      EXT_INT0 & EXT_INT1, 2 interrupts references to primary interrupt
+      controller.
+
+required:
+  - compatible
+  - interrupt-controller
+  - "#interrupt-cells"
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    intc: interrupt-controller@9c000780 {
+        compatible = "sunplus,sp7021-intc";
+        interrupt-controller;
+        #interrupt-cells = <2>;
+        reg = <0x9c000780 0x80>, <0x9c000a80 0x80>;
+        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 5069f552f..6b3bbe021 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2662,6 +2662,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] 124+ messages in thread

* [PATCH v4 08/10] irqchip: Add Sunplus SP7021 interrupt controller driver
  2021-11-04  2:56   ` Qin Jian
@ 2021-11-04  2:57     ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:57 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	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          |   1 +
 drivers/irqchip/irq-sp7021-intc.c | 279 ++++++++++++++++++++++++++++++
 4 files changed, 290 insertions(+)
 create mode 100644 drivers/irqchip/irq-sp7021-intc.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 6b3bbe021..febbd97bf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2665,6 +2665,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 aca7b595c..6f0bc0871 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -602,4 +602,13 @@ config APPLE_AIC
 	  Support for the Apple Interrupt Controller found on Apple Silicon SoCs,
 	  such as the M1.
 
+config SUNPLUS_SP7021_INTC
+	bool "Sunplus SP7021 interrupt controller"
+	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, routed all interrupt source in P-Chip to
+	  the primary controller on C-Chip.
+	  This is selected automatically by platform config.
+
 endmenu
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index f88cbf36a..75411f654 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -116,3 +116,4 @@ obj-$(CONFIG_MACH_REALTEK_RTL)		+= irq-realtek-rtl.o
 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_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..4c995d4e3
--- /dev/null
+++ b/drivers/irqchip/irq-sp7021-intc.c
@@ -0,0 +1,279 @@
+// 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)	(((irq) >= GPIO_INT0_HWIRQ) && ((irq) <= GPIO_INT7_HWIRQ))
+/* state idx */
+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)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&sp_intc.lock, flags);
+	__assign_bit(hwirq, base, value);
+	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;
+}
+
+void sp_intc_set_ext(u32 hwirq, int ext_num)
+{
+	sp_intc_assign_bit(hwirq, REG_INTR_PRIORITY, !ext_num);
+}
+EXPORT_SYMBOL_GPL(sp_intc_set_ext);
+
+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;
+	}
+
+	/* 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);
+
+	ret = sp_intc_irq_map(node, 0); // EXT_INT0
+	if (ret)
+		goto out_domain;
+
+	ret = sp_intc_irq_map(node, 1); // EXT_INT1
+	if (ret)
+		goto out_domain;
+
+	return 0;
+
+out_domain:
+	irq_domain_remove(sp_intc.domain);
+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] 124+ messages in thread

* [PATCH v4 08/10] irqchip: Add Sunplus SP7021 interrupt controller driver
@ 2021-11-04  2:57     ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:57 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	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          |   1 +
 drivers/irqchip/irq-sp7021-intc.c | 279 ++++++++++++++++++++++++++++++
 4 files changed, 290 insertions(+)
 create mode 100644 drivers/irqchip/irq-sp7021-intc.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 6b3bbe021..febbd97bf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2665,6 +2665,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 aca7b595c..6f0bc0871 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -602,4 +602,13 @@ config APPLE_AIC
 	  Support for the Apple Interrupt Controller found on Apple Silicon SoCs,
 	  such as the M1.
 
+config SUNPLUS_SP7021_INTC
+	bool "Sunplus SP7021 interrupt controller"
+	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, routed all interrupt source in P-Chip to
+	  the primary controller on C-Chip.
+	  This is selected automatically by platform config.
+
 endmenu
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index f88cbf36a..75411f654 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -116,3 +116,4 @@ obj-$(CONFIG_MACH_REALTEK_RTL)		+= irq-realtek-rtl.o
 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_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..4c995d4e3
--- /dev/null
+++ b/drivers/irqchip/irq-sp7021-intc.c
@@ -0,0 +1,279 @@
+// 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)	(((irq) >= GPIO_INT0_HWIRQ) && ((irq) <= GPIO_INT7_HWIRQ))
+/* state idx */
+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)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&sp_intc.lock, flags);
+	__assign_bit(hwirq, base, value);
+	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;
+}
+
+void sp_intc_set_ext(u32 hwirq, int ext_num)
+{
+	sp_intc_assign_bit(hwirq, REG_INTR_PRIORITY, !ext_num);
+}
+EXPORT_SYMBOL_GPL(sp_intc_set_ext);
+
+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;
+	}
+
+	/* 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);
+
+	ret = sp_intc_irq_map(node, 0); // EXT_INT0
+	if (ret)
+		goto out_domain;
+
+	ret = sp_intc_irq_map(node, 1); // EXT_INT1
+	if (ret)
+		goto out_domain;
+
+	return 0;
+
+out_domain:
+	irq_domain_remove(sp_intc.domain);
+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] 124+ messages in thread

* [PATCH v4 09/10] ARM: sunplus: Add initial support for Sunplus SP7021 SoC
  2021-11-04  2:56   ` Qin Jian
@ 2021-11-04  2:57     ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:57 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	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                    | 20 ++++++++++++++++++++
 arch/arm/Makefile                   |  2 ++
 arch/arm/mach-sunplus/Kconfig       | 20 ++++++++++++++++++++
 arch/arm/mach-sunplus/Makefile      |  9 +++++++++
 arch/arm/mach-sunplus/Makefile.boot |  3 +++
 arch/arm/mach-sunplus/sp7021.c      | 16 ++++++++++++++++
 7 files changed, 71 insertions(+)
 create mode 100644 arch/arm/mach-sunplus/Kconfig
 create mode 100644 arch/arm/mach-sunplus/Makefile
 create mode 100644 arch/arm/mach-sunplus/Makefile.boot
 create mode 100644 arch/arm/mach-sunplus/sp7021.c

diff --git a/MAINTAINERS b/MAINTAINERS
index febbd97bf..0ae537a41 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2664,6 +2664,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 59baf6c13..feba287eb 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -487,6 +487,24 @@ config ARCH_S3C24XX
 	  (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or the
 	  Samsung SMDK2410 development board (and derivatives).
 
+config ARCH_SUNPLUS
+	bool "Sunplus SoCs"
+	select CLKSRC_OF
+	select COMMON_CLK
+	select GENERIC_CLOCKEVENTS
+	select GENERIC_IRQ_CHIP
+	select GENERIC_IRQ_MULTI_HANDLER
+	select SERIAL_SUNPLUS
+	select SERIAL_SUNPLUS_CONSOLE
+	select USE_OF
+	select RTC_CLASS
+	select RESET_SUNPLUS
+	help
+	  Support for Sunplus SoC family: SP7021 and succeed SoCs 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 ARCH_OMAP1
 	bool "TI OMAP1"
 	depends on MMU
@@ -689,6 +707,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 847c31e7c..cac95a950 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -152,6 +152,7 @@ textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
 textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
 textofs-$(CONFIG_ARCH_MESON) := 0x00208000
 textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000
+textofs-$(CONFIG_ARCH_SUNPLUS) := 0x00308000
 
 # Machine directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
@@ -212,6 +213,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..f7ad76959
--- /dev/null
+++ b/arch/arm/mach-sunplus/Kconfig
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+config SOC_SP7021
+	bool "Sunplus SP7021 SoC support"
+	default y
+	select CPU_V7
+	select ARM_GIC
+	select SUNPLUS_SP7021_INTC
+	select HAVE_SMP
+	select ARM_PSCI
+	select COMMON_CLK_SP7021
+	select PINCTRL
+	select PINCTRL_SPPCTL
+	select OF_OVERLAY
+	select GPIOLIB
+	help
+	  Support for Sunplus SP7021 SoC. It is based on ARM 4-core
+	  Cotex-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/Makefile.boot b/arch/arm/mach-sunplus/Makefile.boot
new file mode 100644
index 000000000..401c30840
--- /dev/null
+++ b/arch/arm/mach-sunplus/Makefile.boot
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+zreladdr-$(CONFIG_ARCH_SUNPLUS) := 0x00308000
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] 124+ messages in thread

* [PATCH v4 09/10] ARM: sunplus: Add initial support for Sunplus SP7021 SoC
@ 2021-11-04  2:57     ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:57 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	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                    | 20 ++++++++++++++++++++
 arch/arm/Makefile                   |  2 ++
 arch/arm/mach-sunplus/Kconfig       | 20 ++++++++++++++++++++
 arch/arm/mach-sunplus/Makefile      |  9 +++++++++
 arch/arm/mach-sunplus/Makefile.boot |  3 +++
 arch/arm/mach-sunplus/sp7021.c      | 16 ++++++++++++++++
 7 files changed, 71 insertions(+)
 create mode 100644 arch/arm/mach-sunplus/Kconfig
 create mode 100644 arch/arm/mach-sunplus/Makefile
 create mode 100644 arch/arm/mach-sunplus/Makefile.boot
 create mode 100644 arch/arm/mach-sunplus/sp7021.c

diff --git a/MAINTAINERS b/MAINTAINERS
index febbd97bf..0ae537a41 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2664,6 +2664,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 59baf6c13..feba287eb 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -487,6 +487,24 @@ config ARCH_S3C24XX
 	  (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or the
 	  Samsung SMDK2410 development board (and derivatives).
 
+config ARCH_SUNPLUS
+	bool "Sunplus SoCs"
+	select CLKSRC_OF
+	select COMMON_CLK
+	select GENERIC_CLOCKEVENTS
+	select GENERIC_IRQ_CHIP
+	select GENERIC_IRQ_MULTI_HANDLER
+	select SERIAL_SUNPLUS
+	select SERIAL_SUNPLUS_CONSOLE
+	select USE_OF
+	select RTC_CLASS
+	select RESET_SUNPLUS
+	help
+	  Support for Sunplus SoC family: SP7021 and succeed SoCs 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 ARCH_OMAP1
 	bool "TI OMAP1"
 	depends on MMU
@@ -689,6 +707,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 847c31e7c..cac95a950 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -152,6 +152,7 @@ textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
 textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
 textofs-$(CONFIG_ARCH_MESON) := 0x00208000
 textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000
+textofs-$(CONFIG_ARCH_SUNPLUS) := 0x00308000
 
 # Machine directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
@@ -212,6 +213,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..f7ad76959
--- /dev/null
+++ b/arch/arm/mach-sunplus/Kconfig
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+config SOC_SP7021
+	bool "Sunplus SP7021 SoC support"
+	default y
+	select CPU_V7
+	select ARM_GIC
+	select SUNPLUS_SP7021_INTC
+	select HAVE_SMP
+	select ARM_PSCI
+	select COMMON_CLK_SP7021
+	select PINCTRL
+	select PINCTRL_SPPCTL
+	select OF_OVERLAY
+	select GPIOLIB
+	help
+	  Support for Sunplus SP7021 SoC. It is based on ARM 4-core
+	  Cotex-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/Makefile.boot b/arch/arm/mach-sunplus/Makefile.boot
new file mode 100644
index 000000000..401c30840
--- /dev/null
+++ b/arch/arm/mach-sunplus/Makefile.boot
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+zreladdr-$(CONFIG_ARCH_SUNPLUS) := 0x00308000
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] 124+ messages in thread

* [PATCH v4 10/10] ARM: sp7021_defconfig: Add Sunplus SP7021 defconfig
  2021-11-04  2:56   ` Qin Jian
@ 2021-11-04  2:57     ` Qin Jian
  -1 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:57 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	Qin Jian

Add generic Sunplus SP7021 based board defconfig

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

diff --git a/MAINTAINERS b/MAINTAINERS
index 0ae537a41..9340f8760 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2664,6 +2664,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/sp7021_defconfig b/arch/arm/configs/sp7021_defconfig
new file mode 100644
index 000000000..f337a3304
--- /dev/null
+++ b/arch/arm/configs/sp7021_defconfig
@@ -0,0 +1,176 @@
+CONFIG_DEFAULT_HOSTNAME="SP7021-Ev"
+CONFIG_SYSVIPC=y
+CONFIG_USELIB=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_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="../rootfs/initramfs/disk/ ../rootfs/initramfs/initramfs.devnodes"
+CONFIG_INITRAMFS_ROOT_UID=-1
+CONFIG_INITRAMFS_ROOT_GID=-1
+# 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_FHANDLE is not set
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=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_HIGHMEM=y
+# CONFIG_HIGHPTE is not set
+CONFIG_FORCE_MAX_ZONEORDER=12
+CONFIG_ZBOOT_ROM_TEXT=0x98307000
+CONFIG_ZBOOT_ROM_BSS=0x03400000
+CONFIG_CMDLINE="root=/dev/ram rw init=/init console=ttyS0,115200 earlyprintk mem=512M@0x0"
+CONFIG_AUTO_ZRELADDR=y
+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_NET=y
+CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_NETLINK_DIAG=y
+CONFIG_CAN=y
+CONFIG_CFG80211=m
+CONFIG_CFG80211_WEXT=y
+CONFIG_MAC80211=m
+CONFIG_CAIF=y
+CONFIG_CEPH_LIB=y
+CONFIG_CEPH_LIB_USE_DNS_RESOLVER=y
+CONFIG_UEVENT_HELPER=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_ALACRITECH is not set
+# CONFIG_NET_VENDOR_AMAZON is not set
+# CONFIG_NET_VENDOR_AQUANTIA is not set
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CADENCE is not set
+# CONFIG_NET_VENDOR_CAVIUM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_CORTINA is not set
+# CONFIG_NET_VENDOR_EZCHIP is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_GOOGLE is not set
+# CONFIG_NET_VENDOR_HISILICON is not set
+# CONFIG_NET_VENDOR_HUAWEI is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_MICROSEMI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
+# CONFIG_NET_VENDOR_NI is not set
+# CONFIG_NET_VENDOR_PENSANDO is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_RENESAS is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SOLARFLARE is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_SOCIONEXT is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SYNOPSYS is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_NET_VENDOR_XILINX is not set
+CONFIG_NET_VENDOR_SUNPLUS=y
+CONFIG_INPUT_POLLDEV=y
+CONFIG_INPUT_SPARSEKMAP=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_SUPPORT_FILTER=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_PLATFORM_SUPPORT=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=y
+CONFIG_FB=y
+CONFIG_FB_SP7021=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER=y
+CONFIG_HIDRAW=y
+CONFIG_GEMINI_USB=y
+CONFIG_USB_USE_PLATFORM_RESOURCE=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_SUNPLUS_USB_PHY=y
+CONFIG_USB_SUNPLUS_OTG=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_DEVICE_LOSE_PACKET_AFTER_SET_INTERFACE_WORKAROUND=y
+CONFIG_USB_DEVICE_EP11_NOT_AUTO_SWITCH_WORKAROUND=y
+CONFIG_USB_GADGET_SUNPLUS=y
+CONFIG_USB_ZERO=y
+CONFIG_MMC=y
+CONFIG_SP_EMMC=m
+CONFIG_STAGING=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PWM=y
+CONFIG_PWM_SP7021=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_EXT2_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_NFS_FS=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_CRC16=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
-- 
2.33.1


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

* [PATCH v4 10/10] ARM: sp7021_defconfig: Add Sunplus SP7021 defconfig
@ 2021-11-04  2:57     ` Qin Jian
  0 siblings, 0 replies; 124+ messages in thread
From: Qin Jian @ 2021-11-04  2:57 UTC (permalink / raw)
  To: robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu,
	Qin Jian

Add generic Sunplus SP7021 based board defconfig

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

diff --git a/MAINTAINERS b/MAINTAINERS
index 0ae537a41..9340f8760 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2664,6 +2664,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/sp7021_defconfig b/arch/arm/configs/sp7021_defconfig
new file mode 100644
index 000000000..f337a3304
--- /dev/null
+++ b/arch/arm/configs/sp7021_defconfig
@@ -0,0 +1,176 @@
+CONFIG_DEFAULT_HOSTNAME="SP7021-Ev"
+CONFIG_SYSVIPC=y
+CONFIG_USELIB=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_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="../rootfs/initramfs/disk/ ../rootfs/initramfs/initramfs.devnodes"
+CONFIG_INITRAMFS_ROOT_UID=-1
+CONFIG_INITRAMFS_ROOT_GID=-1
+# 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_FHANDLE is not set
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=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_HIGHMEM=y
+# CONFIG_HIGHPTE is not set
+CONFIG_FORCE_MAX_ZONEORDER=12
+CONFIG_ZBOOT_ROM_TEXT=0x98307000
+CONFIG_ZBOOT_ROM_BSS=0x03400000
+CONFIG_CMDLINE="root=/dev/ram rw init=/init console=ttyS0,115200 earlyprintk mem=512M@0x0"
+CONFIG_AUTO_ZRELADDR=y
+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_NET=y
+CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_NETLINK_DIAG=y
+CONFIG_CAN=y
+CONFIG_CFG80211=m
+CONFIG_CFG80211_WEXT=y
+CONFIG_MAC80211=m
+CONFIG_CAIF=y
+CONFIG_CEPH_LIB=y
+CONFIG_CEPH_LIB_USE_DNS_RESOLVER=y
+CONFIG_UEVENT_HELPER=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_ALACRITECH is not set
+# CONFIG_NET_VENDOR_AMAZON is not set
+# CONFIG_NET_VENDOR_AQUANTIA is not set
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CADENCE is not set
+# CONFIG_NET_VENDOR_CAVIUM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_CORTINA is not set
+# CONFIG_NET_VENDOR_EZCHIP is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_GOOGLE is not set
+# CONFIG_NET_VENDOR_HISILICON is not set
+# CONFIG_NET_VENDOR_HUAWEI is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_MICROSEMI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
+# CONFIG_NET_VENDOR_NI is not set
+# CONFIG_NET_VENDOR_PENSANDO is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_RENESAS is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SOLARFLARE is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_SOCIONEXT is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SYNOPSYS is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_NET_VENDOR_XILINX is not set
+CONFIG_NET_VENDOR_SUNPLUS=y
+CONFIG_INPUT_POLLDEV=y
+CONFIG_INPUT_SPARSEKMAP=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_SUPPORT_FILTER=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_PLATFORM_SUPPORT=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=y
+CONFIG_FB=y
+CONFIG_FB_SP7021=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER=y
+CONFIG_HIDRAW=y
+CONFIG_GEMINI_USB=y
+CONFIG_USB_USE_PLATFORM_RESOURCE=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_SUNPLUS_USB_PHY=y
+CONFIG_USB_SUNPLUS_OTG=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_DEVICE_LOSE_PACKET_AFTER_SET_INTERFACE_WORKAROUND=y
+CONFIG_USB_DEVICE_EP11_NOT_AUTO_SWITCH_WORKAROUND=y
+CONFIG_USB_GADGET_SUNPLUS=y
+CONFIG_USB_ZERO=y
+CONFIG_MMC=y
+CONFIG_SP_EMMC=m
+CONFIG_STAGING=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PWM=y
+CONFIG_PWM_SP7021=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_EXT2_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_NFS_FS=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_CRC16=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_FTRACE is not set
+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] 124+ messages in thread

* Re: [PATCH v4 09/10] ARM: sunplus: Add initial support for Sunplus SP7021 SoC
  2021-11-04  2:57     ` Qin Jian
@ 2021-11-04  5:09       ` Randy Dunlap
  -1 siblings, 0 replies; 124+ messages in thread
From: Randy Dunlap @ 2021-11-04  5:09 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu

On 11/3/21 7:57 PM, Qin Jian wrote:
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 59baf6c13..feba287eb 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -487,6 +487,24 @@ config ARCH_S3C24XX
>   	  (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or the
>   	  Samsung SMDK2410 development board (and derivatives).
>   
> +config ARCH_SUNPLUS
> +	bool "Sunplus SoCs"
> +	select CLKSRC_OF
> +	select COMMON_CLK
> +	select GENERIC_CLOCKEVENTS
> +	select GENERIC_IRQ_CHIP
> +	select GENERIC_IRQ_MULTI_HANDLER
> +	select SERIAL_SUNPLUS
> +	select SERIAL_SUNPLUS_CONSOLE
> +	select USE_OF
> +	select RTC_CLASS
> +	select RESET_SUNPLUS
> +	help
> +	  Support for Sunplus SoC family: SP7021 and succeed SoCs based systems,

	                                             succeeding or successsor or following
	                                                     SoC-based systems,

> +	  such as the Banana Pi BPI-F2S development board ( and derivatives).

	                                                  (and derivatives).

> +	  (<http://www.sinovoip.com.cn/ecp_view.asp?id=586>)
> +	  (<https://tibbo.com/store/plus1.html>)


-- 
~Randy

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

* Re: [PATCH v4 09/10] ARM: sunplus: Add initial support for Sunplus SP7021 SoC
@ 2021-11-04  5:09       ` Randy Dunlap
  0 siblings, 0 replies; 124+ messages in thread
From: Randy Dunlap @ 2021-11-04  5:09 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu

On 11/3/21 7:57 PM, Qin Jian wrote:
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 59baf6c13..feba287eb 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -487,6 +487,24 @@ config ARCH_S3C24XX
>   	  (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or the
>   	  Samsung SMDK2410 development board (and derivatives).
>   
> +config ARCH_SUNPLUS
> +	bool "Sunplus SoCs"
> +	select CLKSRC_OF
> +	select COMMON_CLK
> +	select GENERIC_CLOCKEVENTS
> +	select GENERIC_IRQ_CHIP
> +	select GENERIC_IRQ_MULTI_HANDLER
> +	select SERIAL_SUNPLUS
> +	select SERIAL_SUNPLUS_CONSOLE
> +	select USE_OF
> +	select RTC_CLASS
> +	select RESET_SUNPLUS
> +	help
> +	  Support for Sunplus SoC family: SP7021 and succeed SoCs based systems,

	                                             succeeding or successsor or following
	                                                     SoC-based systems,

> +	  such as the Banana Pi BPI-F2S development board ( and derivatives).

	                                                  (and derivatives).

> +	  (<http://www.sinovoip.com.cn/ecp_view.asp?id=586>)
> +	  (<https://tibbo.com/store/plus1.html>)


-- 
~Randy

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

* Re: [PATCH v4 09/10] ARM: sunplus: Add initial support for Sunplus SP7021 SoC
  2021-11-04  2:57     ` Qin Jian
@ 2021-11-04  5:09       ` Randy Dunlap
  -1 siblings, 0 replies; 124+ messages in thread
From: Randy Dunlap @ 2021-11-04  5:09 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu

On 11/3/21 7:57 PM, Qin Jian wrote:
> diff --git a/arch/arm/mach-sunplus/Kconfig b/arch/arm/mach-sunplus/Kconfig
> new file mode 100644
> index 000000000..f7ad76959
> --- /dev/null
> +++ b/arch/arm/mach-sunplus/Kconfig
> @@ -0,0 +1,20 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +
> +config SOC_SP7021
> +	bool "Sunplus SP7021 SoC support"
> +	default y
> +	select CPU_V7
> +	select ARM_GIC
> +	select SUNPLUS_SP7021_INTC
> +	select HAVE_SMP
> +	select ARM_PSCI
> +	select COMMON_CLK_SP7021
> +	select PINCTRL
> +	select PINCTRL_SPPCTL
> +	select OF_OVERLAY
> +	select GPIOLIB
> +	help
> +	  Support for Sunplus SP7021 SoC. It is based on ARM 4-core
> +	  Cotex-A7 with various peripherals (ex: I2C, SPI, SDIO,

Is that   Cortex-A7
?

> +	  Ethernet and etc.), FPGA interface,  chip-to-chip bus.
> +	  It is designed for industrial control.


-- 
~Randy

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

* Re: [PATCH v4 09/10] ARM: sunplus: Add initial support for Sunplus SP7021 SoC
@ 2021-11-04  5:09       ` Randy Dunlap
  0 siblings, 0 replies; 124+ messages in thread
From: Randy Dunlap @ 2021-11-04  5:09 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu

On 11/3/21 7:57 PM, Qin Jian wrote:
> diff --git a/arch/arm/mach-sunplus/Kconfig b/arch/arm/mach-sunplus/Kconfig
> new file mode 100644
> index 000000000..f7ad76959
> --- /dev/null
> +++ b/arch/arm/mach-sunplus/Kconfig
> @@ -0,0 +1,20 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +
> +config SOC_SP7021
> +	bool "Sunplus SP7021 SoC support"
> +	default y
> +	select CPU_V7
> +	select ARM_GIC
> +	select SUNPLUS_SP7021_INTC
> +	select HAVE_SMP
> +	select ARM_PSCI
> +	select COMMON_CLK_SP7021
> +	select PINCTRL
> +	select PINCTRL_SPPCTL
> +	select OF_OVERLAY
> +	select GPIOLIB
> +	help
> +	  Support for Sunplus SP7021 SoC. It is based on ARM 4-core
> +	  Cotex-A7 with various peripherals (ex: I2C, SPI, SDIO,

Is that   Cortex-A7
?

> +	  Ethernet and etc.), FPGA interface,  chip-to-chip bus.
> +	  It is designed for industrial control.


-- 
~Randy

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

* Re: [PATCH v4 08/10] irqchip: Add Sunplus SP7021 interrupt controller driver
  2021-11-04  2:57     ` Qin Jian
@ 2021-11-04  5:09       ` Randy Dunlap
  -1 siblings, 0 replies; 124+ messages in thread
From: Randy Dunlap @ 2021-11-04  5:09 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu

On 11/3/21 7:57 PM, Qin Jian wrote:
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index aca7b595c..6f0bc0871 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -602,4 +602,13 @@ config APPLE_AIC
>   	  Support for the Apple Interrupt Controller found on Apple Silicon SoCs,
>   	  such as the M1.
>   
> +config SUNPLUS_SP7021_INTC
> +	bool "Sunplus SP7021 interrupt controller"
> +	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, routed all interrupt source in P-Chip to

	                      routing all interrupt sources

> +	  the primary controller on C-Chip.
> +	  This is selected automatically by platform config.


-- 
~Randy

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

* Re: [PATCH v4 08/10] irqchip: Add Sunplus SP7021 interrupt controller driver
@ 2021-11-04  5:09       ` Randy Dunlap
  0 siblings, 0 replies; 124+ messages in thread
From: Randy Dunlap @ 2021-11-04  5:09 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu

On 11/3/21 7:57 PM, Qin Jian wrote:
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index aca7b595c..6f0bc0871 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -602,4 +602,13 @@ config APPLE_AIC
>   	  Support for the Apple Interrupt Controller found on Apple Silicon SoCs,
>   	  such as the M1.
>   
> +config SUNPLUS_SP7021_INTC
> +	bool "Sunplus SP7021 interrupt controller"
> +	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, routed all interrupt source in P-Chip to

	                      routing all interrupt sources

> +	  the primary controller on C-Chip.
> +	  This is selected automatically by platform config.


-- 
~Randy

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

* Re: [PATCH v4 06/10] clk: Add Sunplus SP7021 clock driver
  2021-11-04  2:57     ` Qin Jian
@ 2021-11-04  5:09       ` Randy Dunlap
  -1 siblings, 0 replies; 124+ messages in thread
From: Randy Dunlap @ 2021-11-04  5:09 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu

On 11/3/21 7:57 PM, Qin Jian wrote:
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index c5b3dc973..1cd7ae7a3 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -334,6 +334,15 @@ 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"
> +	help
> +	  This driver supports the Sunplus SP7021 SoC clocks.
> +	  It implemented SP7021 PLLs/gate.

	     implements

> +	  Not all features of the PLL are currently supported
> +	  by the driver.
> +	  This driver is selected automatically by platform config.


-- 
~Randy

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

* Re: [PATCH v4 06/10] clk: Add Sunplus SP7021 clock driver
@ 2021-11-04  5:09       ` Randy Dunlap
  0 siblings, 0 replies; 124+ messages in thread
From: Randy Dunlap @ 2021-11-04  5:09 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: mturquette, sboyd, maz, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu

On 11/3/21 7:57 PM, Qin Jian wrote:
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index c5b3dc973..1cd7ae7a3 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -334,6 +334,15 @@ 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"
> +	help
> +	  This driver supports the Sunplus SP7021 SoC clocks.
> +	  It implemented SP7021 PLLs/gate.

	     implements

> +	  Not all features of the PLL are currently supported
> +	  by the driver.
> +	  This driver is selected automatically by platform config.


-- 
~Randy

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

* Re: [PATCH v4 00/10] Add Sunplus SP7021 SoC Support
  2021-11-04  2:56   ` Qin Jian
@ 2021-11-04  8:22     ` Marc Zyngier
  -1 siblings, 0 replies; 124+ messages in thread
From: Marc Zyngier @ 2021-11-04  8:22 UTC (permalink / raw)
  To: Qin Jian
  Cc: robh+dt, mturquette, sboyd, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu

Qin,

On Thu, 04 Nov 2021 02:56:57 +0000,
Qin Jian <qinjian@cqplus1.com> wrote:
> 
> This patch series add Sunplus SP7021 SoC support.
> 
> Sunplus SP7021 is an ARM Cortex A7 (4 cores) based SoC. It integrates many
> peripherals (ex: UART, I2C, SPI, SDIO, eMMC, USB, SD card and etc.) into a
> single chip. It is designed for industrial control.
> 
> SP7021 consists of two chips (dies) in a package. One is called C-chip
> (computing chip). It is a 4-core ARM Cortex A7 CPU. It adopts high-level
> process (22 nm) for high performance computing. The other is called P-
> chip (peripheral chip). It has many peripherals and an ARM A926 added
> especially for real-time control. P-chip is made for customers. It adopts
> low-level process (ex: 0.11 um) to reduce cost.

That's the 3rd version of this series since Friday, two of them during
the merge window. All you are achieving is to actually *delay* the
review process (at this rate, I'll probably wait until v11 before I
take another look at it).

Documentation/process/submitting-patches.rst states it clearly:

<quote>
Wait for a minimum of one week before resubmitting
</quote>

So please leave people the time to actually do a good review job, and
take the opportunity to review your own patches before posting them
again.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.

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

* Re: [PATCH v4 00/10] Add Sunplus SP7021 SoC Support
@ 2021-11-04  8:22     ` Marc Zyngier
  0 siblings, 0 replies; 124+ messages in thread
From: Marc Zyngier @ 2021-11-04  8:22 UTC (permalink / raw)
  To: Qin Jian
  Cc: robh+dt, mturquette, sboyd, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk, wells.lu

Qin,

On Thu, 04 Nov 2021 02:56:57 +0000,
Qin Jian <qinjian@cqplus1.com> wrote:
> 
> This patch series add Sunplus SP7021 SoC support.
> 
> Sunplus SP7021 is an ARM Cortex A7 (4 cores) based SoC. It integrates many
> peripherals (ex: UART, I2C, SPI, SDIO, eMMC, USB, SD card and etc.) into a
> single chip. It is designed for industrial control.
> 
> SP7021 consists of two chips (dies) in a package. One is called C-chip
> (computing chip). It is a 4-core ARM Cortex A7 CPU. It adopts high-level
> process (22 nm) for high performance computing. The other is called P-
> chip (peripheral chip). It has many peripherals and an ARM A926 added
> especially for real-time control. P-chip is made for customers. It adopts
> low-level process (ex: 0.11 um) to reduce cost.

That's the 3rd version of this series since Friday, two of them during
the merge window. All you are achieving is to actually *delay* the
review process (at this rate, I'll probably wait until v11 before I
take another look at it).

Documentation/process/submitting-patches.rst states it clearly:

<quote>
Wait for a minimum of one week before resubmitting
</quote>

So please leave people the time to actually do a good review job, and
take the opportunity to review your own patches before posting them
again.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.

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

* 答复: [PATCH v4 00/10] Add Sunplus SP7021 SoC Support
  2021-11-04  8:22     ` Marc Zyngier
@ 2021-11-04  8:35       ` qinjian[覃健]
  -1 siblings, 0 replies; 124+ messages in thread
From: qinjian[覃健] @ 2021-11-04  8:35 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: robh+dt, mturquette, sboyd, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk,
	Wells Lu �畏简v

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="gb2312", Size: 2089 bytes --]

Marc,

Got it. Thank you for reminding me.
I'm sorry for the previous mistake.


> -----ÓʼþÔ­¼þ-----
> ·¢¼þÈË: Marc Zyngier <maz@kernel.org>
> ·¢ËÍʱ¼ä: 2021Äê11ÔÂ4ÈÕ 16:23
> ÊÕ¼þÈË: qinjian[ñû½¡] <qinjian@cqplus1.com>
> ³­ËÍ: robh+dt@kernel.org; mturquette@baylibre.com; sboyd@kernel.org; p.zabel@pengutronix.de; linux@armlinux.org.uk;
> broonie@kernel.org; arnd@arndb.de; linux-arm-kernel@lists.infradead.org; devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> linux-clk@vger.kernel.org; Wells Lu …η¼òv <wells.lu@sunplus.com>
> Ö÷Ìâ: Re: [PATCH v4 00/10] Add Sunplus SP7021 SoC Support
> 
> Qin,
> 
> On Thu, 04 Nov 2021 02:56:57 +0000,
> Qin Jian <qinjian@cqplus1.com> wrote:
> >
> > This patch series add Sunplus SP7021 SoC support.
> >
> > Sunplus SP7021 is an ARM Cortex A7 (4 cores) based SoC. It integrates many
> > peripherals (ex: UART, I2C, SPI, SDIO, eMMC, USB, SD card and etc.) into a
> > single chip. It is designed for industrial control.
> >
> > SP7021 consists of two chips (dies) in a package. One is called C-chip
> > (computing chip). It is a 4-core ARM Cortex A7 CPU. It adopts high-level
> > process (22 nm) for high performance computing. The other is called P-
> > chip (peripheral chip). It has many peripherals and an ARM A926 added
> > especially for real-time control. P-chip is made for customers. It adopts
> > low-level process (ex: 0.11 um) to reduce cost.
> 
> That's the 3rd version of this series since Friday, two of them during
> the merge window. All you are achieving is to actually *delay* the
> review process (at this rate, I'll probably wait until v11 before I
> take another look at it).
> 
> Documentation/process/submitting-patches.rst states it clearly:
> 
> <quote>
> Wait for a minimum of one week before resubmitting
> </quote>
> 
> So please leave people the time to actually do a good review job, and
> take the opportunity to review your own patches before posting them
> again.
> 
> Thanks,
> 
> 	M.
> 
> --
> Without deviation from the norm, progress is not possible.

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

* 答复: [PATCH v4 00/10] Add Sunplus SP7021 SoC Support
@ 2021-11-04  8:35       ` qinjian[覃健]
  0 siblings, 0 replies; 124+ messages in thread
From: qinjian[覃健] @ 2021-11-04  8:35 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: robh+dt, mturquette, sboyd, p.zabel, linux, broonie, arnd,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk,
	Wells Lu �畏简v

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="gb2312", Size: 2089 bytes --]

Marc,

Got it. Thank you for reminding me.
I'm sorry for the previous mistake.


> -----ÓʼþÔ­¼þ-----
> ·¢¼þÈË: Marc Zyngier <maz@kernel.org>
> ·¢ËÍʱ¼ä: 2021Äê11ÔÂ4ÈÕ 16:23
> ÊÕ¼þÈË: qinjian[ñû½¡] <qinjian@cqplus1.com>
> ³­ËÍ: robh+dt@kernel.org; mturquette@baylibre.com; sboyd@kernel.org; p.zabel@pengutronix.de; linux@armlinux.org.uk;
> broonie@kernel.org; arnd@arndb.de; linux-arm-kernel@lists.infradead.org; devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> linux-clk@vger.kernel.org; Wells Lu …η¼òv <wells.lu@sunplus.com>
> Ö÷Ìâ: Re: [PATCH v4 00/10] Add Sunplus SP7021 SoC Support
> 
> Qin,
> 
> On Thu, 04 Nov 2021 02:56:57 +0000,
> Qin Jian <qinjian@cqplus1.com> wrote:
> >
> > This patch series add Sunplus SP7021 SoC support.
> >
> > Sunplus SP7021 is an ARM Cortex A7 (4 cores) based SoC. It integrates many
> > peripherals (ex: UART, I2C, SPI, SDIO, eMMC, USB, SD card and etc.) into a
> > single chip. It is designed for industrial control.
> >
> > SP7021 consists of two chips (dies) in a package. One is called C-chip
> > (computing chip). It is a 4-core ARM Cortex A7 CPU. It adopts high-level
> > process (22 nm) for high performance computing. The other is called P-
> > chip (peripheral chip). It has many peripherals and an ARM A926 added
> > especially for real-time control. P-chip is made for customers. It adopts
> > low-level process (ex: 0.11 um) to reduce cost.
> 
> That's the 3rd version of this series since Friday, two of them during
> the merge window. All you are achieving is to actually *delay* the
> review process (at this rate, I'll probably wait until v11 before I
> take another look at it).
> 
> Documentation/process/submitting-patches.rst states it clearly:
> 
> <quote>
> Wait for a minimum of one week before resubmitting
> </quote>
> 
> So please leave people the time to actually do a good review job, and
> take the opportunity to review your own patches before posting them
> again.
> 
> Thanks,
> 
> 	M.
> 
> --
> Without deviation from the norm, progress is not possible.

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

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

* Re: [PATCH v4 06/10] clk: Add Sunplus SP7021 clock driver
  2021-11-04  2:57     ` Qin Jian
  (?)
@ 2021-11-04 11:32       ` kernel test robot
  -1 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-11-04 11:32 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: kbuild-all, mturquette, sboyd, maz, p.zabel, linux, broonie,
	arnd, linux-arm-kernel, devicetree

[-- Attachment #1: Type: text/plain, Size: 5328 bytes --]

Hi Qin,

I love your patch! Perhaps something to improve:

[auto build test WARNING on pza/reset/next]
[also build test WARNING on robh/for-next clk/clk-next tip/irq/core linus/master v5.15 next-20211104]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211104-115746
base:   https://git.pengutronix.de/git/pza/linux reset/next
config: xtensa-randconfig-r012-20211104 (attached as .config)
compiler: xtensa-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/604141a9aad536dff720a6337561171d72d63d74
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211104-115746
        git checkout 604141a9aad536dff720a6337561171d72d63d74
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=xtensa 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/clk/clk-sp7021.c: In function 'plltv_fractional_div':
>> drivers/clk/clk-sp7021.c:292:13: warning: variable 'diff_min_sign' set but not used [-Wunused-but-set-variable]
     292 |         u32 diff_min_sign = 0;
         |             ^~~~~~~~~~~~~
   drivers/clk/clk-sp7021.c: At top level:
   drivers/clk/clk-sp7021.c:625:13: warning: no previous prototype for 'clk_register_sp_pll' [-Wmissing-prototypes]
     625 | struct clk *clk_register_sp_pll(const char *name, const char *parent,
         |             ^~~~~~~~~~~~~~~~~~~


vim +/diff_min_sign +292 drivers/clk/clk-sp7021.c

   286	
   287	static long plltv_fractional_div(struct sp_pll *clk, unsigned long freq)
   288	{
   289		u32 m, r;
   290		u32 nint, nfra;
   291		u32 diff_min_quotient = 210000000, diff_min_remainder = 0;
 > 292		u32 diff_min_sign = 0;
   293		unsigned long fvco, nf, f, fout = 0;
   294		int sdm, ph;
   295	
   296		/* check freq */
   297		if (freq < F_MIN) {
   298			pr_warn("%s: %s freq:%lu < F_MIN:%lu, round up\n",
   299				__func__, clk_hw_get_name(&clk->hw), freq, F_MIN);
   300			freq = F_MIN;
   301		} else if (freq > F_MAX) {
   302			pr_warn("%s: %s freq:%lu > F_MAX:%lu, round down\n",
   303				__func__, clk_hw_get_name(&clk->hw), freq, F_MAX);
   304			freq = F_MAX;
   305		}
   306	
   307		/* DIVR 0~3 */
   308		for (r = 0; r <= 3; r++) {
   309			fvco = freq << r;
   310			if (fvco <= FVCO_MAX)
   311				break;
   312		}
   313		f = F_27M >> r;
   314	
   315		/* PH_SEL 1/0 */
   316		for (ph = 1; ph >= 0; ph--) {
   317			const u32 *pp = pt[ph];
   318			u32 ms = 1;
   319	
   320			/* SDM_MOD 0/1 */
   321			for (sdm = 0; sdm <= 1; sdm++) {
   322				u32 mod = mods[sdm];
   323	
   324				/* DIVM 1~32 */
   325				for (m = ms; m <= 32; m++) {
   326					u32 diff_freq;
   327					u32 diff_freq_quotient = 0, diff_freq_remainder = 0;
   328					u32 diff_freq_sign = 0; /* 0:Positive number, 1:Negative number */
   329	
   330					nf = fvco * m;
   331					nint = nf / pp[3];
   332	
   333					if (nint < pp[1])
   334						continue;
   335					if (nint > pp[1])
   336						break;
   337	
   338					nfra = (((nf % pp[3]) * mod * pp[4]) + (F_27M / 2)) / F_27M;
   339					if (nfra)
   340						diff_freq = (f * (nint + pp[2]) / pp[0]) -
   341									(f * (mod - nfra) / mod / pp[4]);
   342					else
   343						diff_freq = (f * (nint) / pp[0]);
   344	
   345					diff_freq_quotient  = diff_freq / m;
   346					diff_freq_remainder = ((diff_freq % m) * 1000) / m;
   347	
   348					if (freq > diff_freq_quotient) {
   349						diff_freq_quotient  = freq - diff_freq_quotient - 1;
   350						diff_freq_remainder = 1000 - diff_freq_remainder;
   351						diff_freq_sign = 1;
   352					} else {
   353						diff_freq_quotient = diff_freq_quotient - freq;
   354						diff_freq_sign = 0;
   355					}
   356	
   357					if ((diff_min_quotient > diff_freq_quotient) ||
   358						((diff_min_quotient == diff_freq_quotient) &&
   359						(diff_min_remainder > diff_freq_remainder))) {
   360	
   361						/* found a closer freq, save parameters */
   362						clk->p[SEL_FRA] = 1;
   363						clk->p[SDM_MOD] = sdm;
   364						clk->p[PH_SEL]  = ph;
   365						clk->p[NFRA]    = nfra;
   366						clk->p[DIVR]    = r;
   367						clk->p[DIVM]    = m;
   368	
   369						fout = diff_freq / m;
   370						diff_min_quotient = diff_freq_quotient;
   371						diff_min_remainder = diff_freq_remainder;
   372						diff_min_sign = diff_freq_sign;
   373					}
   374				}
   375			}
   376		}
   377	
   378		if (!fout) {
   379			pr_err("%s: %s freq:%lu not found a valid setting\n",
   380				__func__, clk_hw_get_name(&clk->hw), freq);
   381			return -EINVAL;
   382		}
   383	
   384		return fout;
   385	}
   386	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 33007 bytes --]

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

* Re: [PATCH v4 06/10] clk: Add Sunplus SP7021 clock driver
@ 2021-11-04 11:32       ` kernel test robot
  0 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-11-04 11:32 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: kbuild-all, mturquette, sboyd, maz, p.zabel, linux, broonie,
	arnd, linux-arm-kernel, devicetree

[-- Attachment #1: Type: text/plain, Size: 5328 bytes --]

Hi Qin,

I love your patch! Perhaps something to improve:

[auto build test WARNING on pza/reset/next]
[also build test WARNING on robh/for-next clk/clk-next tip/irq/core linus/master v5.15 next-20211104]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211104-115746
base:   https://git.pengutronix.de/git/pza/linux reset/next
config: xtensa-randconfig-r012-20211104 (attached as .config)
compiler: xtensa-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/604141a9aad536dff720a6337561171d72d63d74
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211104-115746
        git checkout 604141a9aad536dff720a6337561171d72d63d74
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=xtensa 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/clk/clk-sp7021.c: In function 'plltv_fractional_div':
>> drivers/clk/clk-sp7021.c:292:13: warning: variable 'diff_min_sign' set but not used [-Wunused-but-set-variable]
     292 |         u32 diff_min_sign = 0;
         |             ^~~~~~~~~~~~~
   drivers/clk/clk-sp7021.c: At top level:
   drivers/clk/clk-sp7021.c:625:13: warning: no previous prototype for 'clk_register_sp_pll' [-Wmissing-prototypes]
     625 | struct clk *clk_register_sp_pll(const char *name, const char *parent,
         |             ^~~~~~~~~~~~~~~~~~~


vim +/diff_min_sign +292 drivers/clk/clk-sp7021.c

   286	
   287	static long plltv_fractional_div(struct sp_pll *clk, unsigned long freq)
   288	{
   289		u32 m, r;
   290		u32 nint, nfra;
   291		u32 diff_min_quotient = 210000000, diff_min_remainder = 0;
 > 292		u32 diff_min_sign = 0;
   293		unsigned long fvco, nf, f, fout = 0;
   294		int sdm, ph;
   295	
   296		/* check freq */
   297		if (freq < F_MIN) {
   298			pr_warn("%s: %s freq:%lu < F_MIN:%lu, round up\n",
   299				__func__, clk_hw_get_name(&clk->hw), freq, F_MIN);
   300			freq = F_MIN;
   301		} else if (freq > F_MAX) {
   302			pr_warn("%s: %s freq:%lu > F_MAX:%lu, round down\n",
   303				__func__, clk_hw_get_name(&clk->hw), freq, F_MAX);
   304			freq = F_MAX;
   305		}
   306	
   307		/* DIVR 0~3 */
   308		for (r = 0; r <= 3; r++) {
   309			fvco = freq << r;
   310			if (fvco <= FVCO_MAX)
   311				break;
   312		}
   313		f = F_27M >> r;
   314	
   315		/* PH_SEL 1/0 */
   316		for (ph = 1; ph >= 0; ph--) {
   317			const u32 *pp = pt[ph];
   318			u32 ms = 1;
   319	
   320			/* SDM_MOD 0/1 */
   321			for (sdm = 0; sdm <= 1; sdm++) {
   322				u32 mod = mods[sdm];
   323	
   324				/* DIVM 1~32 */
   325				for (m = ms; m <= 32; m++) {
   326					u32 diff_freq;
   327					u32 diff_freq_quotient = 0, diff_freq_remainder = 0;
   328					u32 diff_freq_sign = 0; /* 0:Positive number, 1:Negative number */
   329	
   330					nf = fvco * m;
   331					nint = nf / pp[3];
   332	
   333					if (nint < pp[1])
   334						continue;
   335					if (nint > pp[1])
   336						break;
   337	
   338					nfra = (((nf % pp[3]) * mod * pp[4]) + (F_27M / 2)) / F_27M;
   339					if (nfra)
   340						diff_freq = (f * (nint + pp[2]) / pp[0]) -
   341									(f * (mod - nfra) / mod / pp[4]);
   342					else
   343						diff_freq = (f * (nint) / pp[0]);
   344	
   345					diff_freq_quotient  = diff_freq / m;
   346					diff_freq_remainder = ((diff_freq % m) * 1000) / m;
   347	
   348					if (freq > diff_freq_quotient) {
   349						diff_freq_quotient  = freq - diff_freq_quotient - 1;
   350						diff_freq_remainder = 1000 - diff_freq_remainder;
   351						diff_freq_sign = 1;
   352					} else {
   353						diff_freq_quotient = diff_freq_quotient - freq;
   354						diff_freq_sign = 0;
   355					}
   356	
   357					if ((diff_min_quotient > diff_freq_quotient) ||
   358						((diff_min_quotient == diff_freq_quotient) &&
   359						(diff_min_remainder > diff_freq_remainder))) {
   360	
   361						/* found a closer freq, save parameters */
   362						clk->p[SEL_FRA] = 1;
   363						clk->p[SDM_MOD] = sdm;
   364						clk->p[PH_SEL]  = ph;
   365						clk->p[NFRA]    = nfra;
   366						clk->p[DIVR]    = r;
   367						clk->p[DIVM]    = m;
   368	
   369						fout = diff_freq / m;
   370						diff_min_quotient = diff_freq_quotient;
   371						diff_min_remainder = diff_freq_remainder;
   372						diff_min_sign = diff_freq_sign;
   373					}
   374				}
   375			}
   376		}
   377	
   378		if (!fout) {
   379			pr_err("%s: %s freq:%lu not found a valid setting\n",
   380				__func__, clk_hw_get_name(&clk->hw), freq);
   381			return -EINVAL;
   382		}
   383	
   384		return fout;
   385	}
   386	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 33007 bytes --]

[-- Attachment #3: Type: text/plain, Size: 176 bytes --]

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

* Re: [PATCH v4 06/10] clk: Add Sunplus SP7021 clock driver
@ 2021-11-04 11:32       ` kernel test robot
  0 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-11-04 11:32 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 5476 bytes --]

Hi Qin,

I love your patch! Perhaps something to improve:

[auto build test WARNING on pza/reset/next]
[also build test WARNING on robh/for-next clk/clk-next tip/irq/core linus/master v5.15 next-20211104]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211104-115746
base:   https://git.pengutronix.de/git/pza/linux reset/next
config: xtensa-randconfig-r012-20211104 (attached as .config)
compiler: xtensa-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/604141a9aad536dff720a6337561171d72d63d74
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211104-115746
        git checkout 604141a9aad536dff720a6337561171d72d63d74
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=xtensa 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/clk/clk-sp7021.c: In function 'plltv_fractional_div':
>> drivers/clk/clk-sp7021.c:292:13: warning: variable 'diff_min_sign' set but not used [-Wunused-but-set-variable]
     292 |         u32 diff_min_sign = 0;
         |             ^~~~~~~~~~~~~
   drivers/clk/clk-sp7021.c: At top level:
   drivers/clk/clk-sp7021.c:625:13: warning: no previous prototype for 'clk_register_sp_pll' [-Wmissing-prototypes]
     625 | struct clk *clk_register_sp_pll(const char *name, const char *parent,
         |             ^~~~~~~~~~~~~~~~~~~


vim +/diff_min_sign +292 drivers/clk/clk-sp7021.c

   286	
   287	static long plltv_fractional_div(struct sp_pll *clk, unsigned long freq)
   288	{
   289		u32 m, r;
   290		u32 nint, nfra;
   291		u32 diff_min_quotient = 210000000, diff_min_remainder = 0;
 > 292		u32 diff_min_sign = 0;
   293		unsigned long fvco, nf, f, fout = 0;
   294		int sdm, ph;
   295	
   296		/* check freq */
   297		if (freq < F_MIN) {
   298			pr_warn("%s: %s freq:%lu < F_MIN:%lu, round up\n",
   299				__func__, clk_hw_get_name(&clk->hw), freq, F_MIN);
   300			freq = F_MIN;
   301		} else if (freq > F_MAX) {
   302			pr_warn("%s: %s freq:%lu > F_MAX:%lu, round down\n",
   303				__func__, clk_hw_get_name(&clk->hw), freq, F_MAX);
   304			freq = F_MAX;
   305		}
   306	
   307		/* DIVR 0~3 */
   308		for (r = 0; r <= 3; r++) {
   309			fvco = freq << r;
   310			if (fvco <= FVCO_MAX)
   311				break;
   312		}
   313		f = F_27M >> r;
   314	
   315		/* PH_SEL 1/0 */
   316		for (ph = 1; ph >= 0; ph--) {
   317			const u32 *pp = pt[ph];
   318			u32 ms = 1;
   319	
   320			/* SDM_MOD 0/1 */
   321			for (sdm = 0; sdm <= 1; sdm++) {
   322				u32 mod = mods[sdm];
   323	
   324				/* DIVM 1~32 */
   325				for (m = ms; m <= 32; m++) {
   326					u32 diff_freq;
   327					u32 diff_freq_quotient = 0, diff_freq_remainder = 0;
   328					u32 diff_freq_sign = 0; /* 0:Positive number, 1:Negative number */
   329	
   330					nf = fvco * m;
   331					nint = nf / pp[3];
   332	
   333					if (nint < pp[1])
   334						continue;
   335					if (nint > pp[1])
   336						break;
   337	
   338					nfra = (((nf % pp[3]) * mod * pp[4]) + (F_27M / 2)) / F_27M;
   339					if (nfra)
   340						diff_freq = (f * (nint + pp[2]) / pp[0]) -
   341									(f * (mod - nfra) / mod / pp[4]);
   342					else
   343						diff_freq = (f * (nint) / pp[0]);
   344	
   345					diff_freq_quotient  = diff_freq / m;
   346					diff_freq_remainder = ((diff_freq % m) * 1000) / m;
   347	
   348					if (freq > diff_freq_quotient) {
   349						diff_freq_quotient  = freq - diff_freq_quotient - 1;
   350						diff_freq_remainder = 1000 - diff_freq_remainder;
   351						diff_freq_sign = 1;
   352					} else {
   353						diff_freq_quotient = diff_freq_quotient - freq;
   354						diff_freq_sign = 0;
   355					}
   356	
   357					if ((diff_min_quotient > diff_freq_quotient) ||
   358						((diff_min_quotient == diff_freq_quotient) &&
   359						(diff_min_remainder > diff_freq_remainder))) {
   360	
   361						/* found a closer freq, save parameters */
   362						clk->p[SEL_FRA] = 1;
   363						clk->p[SDM_MOD] = sdm;
   364						clk->p[PH_SEL]  = ph;
   365						clk->p[NFRA]    = nfra;
   366						clk->p[DIVR]    = r;
   367						clk->p[DIVM]    = m;
   368	
   369						fout = diff_freq / m;
   370						diff_min_quotient = diff_freq_quotient;
   371						diff_min_remainder = diff_freq_remainder;
   372						diff_min_sign = diff_freq_sign;
   373					}
   374				}
   375			}
   376		}
   377	
   378		if (!fout) {
   379			pr_err("%s: %s freq:%lu not found a valid setting\n",
   380				__func__, clk_hw_get_name(&clk->hw), freq);
   381			return -EINVAL;
   382		}
   383	
   384		return fout;
   385	}
   386	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 33007 bytes --]

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

* Re: [PATCH v4 09/10] ARM: sunplus: Add initial support for Sunplus SP7021 SoC
  2021-11-04  2:57     ` Qin Jian
  (?)
@ 2021-11-04 15:23       ` kernel test robot
  -1 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-11-04 15:23 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: kbuild-all, mturquette, sboyd, maz, p.zabel, linux, broonie,
	arnd, linux-arm-kernel, devicetree

[-- Attachment #1: Type: text/plain, Size: 13865 bytes --]

Hi Qin,

I love your patch! Yet something to improve:

[auto build test ERROR on pza/reset/next]
[also build test ERROR on robh/for-next clk/clk-next v5.15]
[cannot apply to tip/irq/core linus/master next-20211104]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211104-115746
base:   https://git.pengutronix.de/git/pza/linux reset/next
config: arm-randconfig-c002-20211104 (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/a0450f4dfa75b60af973bceea07b1be864ae81ba
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211104-115746
        git checkout a0450f4dfa75b60af973bceea07b1be864ae81ba
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arm SHELL=/bin/bash arch/arm/kernel/ arch/arm/mm/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   arch/arm/kernel/setup.c: In function 'early_print':
   arch/arm/kernel/setup.c:372:9: warning: function 'early_print' might be a candidate for 'gnu_printf' format attribute [-Wsuggest-attribute=format]
     372 |         vsnprintf(buf, sizeof(buf), str, ap);
         |         ^~~~~~~~~
   In file included from arch/arm/kernel/setup.c:36:
   arch/arm/kernel/setup.c: In function 'cpuid_init_hwcaps':
>> arch/arm/include/asm/cputype.h:22:25: error: expected ':' or ')' before numeric constant
      22 | #define CPUID_EXT_ISAR0 0x60
         |                         ^~~~
   arch/arm/include/asm/cputype.h:135:51: note: in definition of macro 'read_cpuid_ext'
     135 |                 asm("mrc        p15, 0, %0, c0, " ext_reg               \
         |                                                   ^~~~~~~
   arch/arm/kernel/setup.c:457:17: note: in expansion of macro 'cpuid_feature_extract'
     457 |         block = cpuid_feature_extract(CPUID_EXT_ISAR0, 24);
         |                 ^~~~~~~~~~~~~~~~~~~~~
   arch/arm/kernel/setup.c:457:39: note: in expansion of macro 'CPUID_EXT_ISAR0'
     457 |         block = cpuid_feature_extract(CPUID_EXT_ISAR0, 24);
         |                                       ^~~~~~~~~~~~~~~
   arch/arm/include/asm/cputype.h:18:25: error: expected ':' or ')' before numeric constant
      18 | #define CPUID_EXT_MMFR0 0x50
         |                         ^~~~
   arch/arm/include/asm/cputype.h:135:51: note: in definition of macro 'read_cpuid_ext'
     135 |                 asm("mrc        p15, 0, %0, c0, " ext_reg               \
         |                                                   ^~~~~~~
   arch/arm/kernel/setup.c:464:17: note: in expansion of macro 'cpuid_feature_extract'
     464 |         block = cpuid_feature_extract(CPUID_EXT_MMFR0, 0);
         |                 ^~~~~~~~~~~~~~~~~~~~~
   arch/arm/kernel/setup.c:464:39: note: in expansion of macro 'CPUID_EXT_MMFR0'
     464 |         block = cpuid_feature_extract(CPUID_EXT_MMFR0, 0);
         |                                       ^~~~~~~~~~~~~~~
   arch/arm/include/asm/cputype.h:27:25: error: expected ':' or ')' before numeric constant
      27 | #define CPUID_EXT_ISAR5 0x74
         |                         ^~~~
   arch/arm/include/asm/cputype.h:135:51: note: in definition of macro 'read_cpuid_ext'
     135 |                 asm("mrc        p15, 0, %0, c0, " ext_reg               \
         |                                                   ^~~~~~~
   arch/arm/kernel/setup.c:469:32: note: in expansion of macro 'CPUID_EXT_ISAR5'
     469 |         isar5 = read_cpuid_ext(CPUID_EXT_ISAR5);
         |                                ^~~~~~~~~~~~~~~
   arch/arm/kernel/setup.c: In function 'elf_hwcap_fixup':
   arch/arm/include/asm/cputype.h:25:25: error: expected ':' or ')' before numeric constant
      25 | #define CPUID_EXT_ISAR3 0x6c
         |                         ^~~~
   arch/arm/include/asm/cputype.h:135:51: note: in definition of macro 'read_cpuid_ext'
     135 |                 asm("mrc        p15, 0, %0, c0, " ext_reg               \
         |                                                   ^~~~~~~
   arch/arm/kernel/setup.c:513:13: note: in expansion of macro 'cpuid_feature_extract'
     513 |         if (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) > 1 ||
         |             ^~~~~~~~~~~~~~~~~~~~~
   arch/arm/kernel/setup.c:513:35: note: in expansion of macro 'CPUID_EXT_ISAR3'
     513 |         if (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) > 1 ||
         |                                   ^~~~~~~~~~~~~~~
   arch/arm/include/asm/cputype.h:25:25: error: expected ':' or ')' before numeric constant
      25 | #define CPUID_EXT_ISAR3 0x6c
         |                         ^~~~
   arch/arm/include/asm/cputype.h:135:51: note: in definition of macro 'read_cpuid_ext'
     135 |                 asm("mrc        p15, 0, %0, c0, " ext_reg               \
         |                                                   ^~~~~~~
   arch/arm/kernel/setup.c:514:14: note: in expansion of macro 'cpuid_feature_extract'
     514 |             (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) == 1 &&
         |              ^~~~~~~~~~~~~~~~~~~~~
   arch/arm/kernel/setup.c:514:36: note: in expansion of macro 'CPUID_EXT_ISAR3'
     514 |             (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) == 1 &&
         |                                    ^~~~~~~~~~~~~~~
   arch/arm/include/asm/cputype.h:26:25: error: expected ':' or ')' before numeric constant
      26 | #define CPUID_EXT_ISAR4 0x70
         |                         ^~~~
   arch/arm/include/asm/cputype.h:135:51: note: in definition of macro 'read_cpuid_ext'
     135 |                 asm("mrc        p15, 0, %0, c0, " ext_reg               \
         |                                                   ^~~~~~~
   arch/arm/kernel/setup.c:515:14: note: in expansion of macro 'cpuid_feature_extract'
     515 |              cpuid_feature_extract(CPUID_EXT_ISAR4, 20) >= 3))
         |              ^~~~~~~~~~~~~~~~~~~~~
   arch/arm/kernel/setup.c:515:36: note: in expansion of macro 'CPUID_EXT_ISAR4'
     515 |              cpuid_feature_extract(CPUID_EXT_ISAR4, 20) >= 3))
         |                                    ^~~~~~~~~~~~~~~
   In file included from arch/arm/include/asm/efi.h:12,
                    from arch/arm/kernel/setup.c:37:
   At top level:
   arch/arm/include/asm/fixmap.h:39:35: warning: '__end_of_fixed_addresses' defined but not used [-Wunused-const-variable=]
      39 | static const enum fixed_addresses __end_of_fixed_addresses =
         |                                   ^~~~~~~~~~~~~~~~~~~~~~~~
--
   arch/arm/mm/pmsa-v8.c: In function 'prlar_read':
>> arch/arm/mm/pmsa-v8.c:53:16: error: implicit declaration of function 'readl_relaxed' [-Werror=implicit-function-declaration]
      53 |         return readl_relaxed(BASEADDR_V7M_SCB + PMSAv8_RLAR);
         |                ^~~~~~~~~~~~~
>> arch/arm/mm/pmsa-v8.c:53:30: error: 'BASEADDR_V7M_SCB' undeclared (first use in this function)
      53 |         return readl_relaxed(BASEADDR_V7M_SCB + PMSAv8_RLAR);
         |                              ^~~~~~~~~~~~~~~~
   arch/arm/mm/pmsa-v8.c:53:30: note: each undeclared identifier is reported only once for each function it appears in
>> arch/arm/mm/pmsa-v8.c:53:49: error: 'PMSAv8_RLAR' undeclared (first use in this function); did you mean 'PMSAv8_MAIR'?
      53 |         return readl_relaxed(BASEADDR_V7M_SCB + PMSAv8_RLAR);
         |                                                 ^~~~~~~~~~~
         |                                                 PMSAv8_MAIR
   arch/arm/mm/pmsa-v8.c: In function 'prbar_read':
   arch/arm/mm/pmsa-v8.c:58:30: error: 'BASEADDR_V7M_SCB' undeclared (first use in this function)
      58 |         return readl_relaxed(BASEADDR_V7M_SCB + PMSAv8_RBAR);
         |                              ^~~~~~~~~~~~~~~~
>> arch/arm/mm/pmsa-v8.c:58:49: error: 'PMSAv8_RBAR' undeclared (first use in this function); did you mean 'PMSAv8_MAIR'?
      58 |         return readl_relaxed(BASEADDR_V7M_SCB + PMSAv8_RBAR);
         |                                                 ^~~~~~~~~~~
         |                                                 PMSAv8_MAIR
   arch/arm/mm/pmsa-v8.c: In function 'prsel_write':
>> arch/arm/mm/pmsa-v8.c:63:9: error: implicit declaration of function 'writel_relaxed' [-Werror=implicit-function-declaration]
      63 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RNR);
         |         ^~~~~~~~~~~~~~
   arch/arm/mm/pmsa-v8.c:63:27: error: 'BASEADDR_V7M_SCB' undeclared (first use in this function)
      63 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RNR);
         |                           ^~~~~~~~~~~~~~~~
>> arch/arm/mm/pmsa-v8.c:63:46: error: 'PMSAv8_RNR' undeclared (first use in this function); did you mean 'PMSAv8_MAIR'?
      63 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RNR);
         |                                              ^~~~~~~~~~
         |                                              PMSAv8_MAIR
   arch/arm/mm/pmsa-v8.c: In function 'prbar_write':
   arch/arm/mm/pmsa-v8.c:68:27: error: 'BASEADDR_V7M_SCB' undeclared (first use in this function)
      68 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RBAR);
         |                           ^~~~~~~~~~~~~~~~
   arch/arm/mm/pmsa-v8.c:68:46: error: 'PMSAv8_RBAR' undeclared (first use in this function); did you mean 'PMSAv8_MAIR'?
      68 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RBAR);
         |                                              ^~~~~~~~~~~
         |                                              PMSAv8_MAIR
   arch/arm/mm/pmsa-v8.c: In function 'prlar_write':
   arch/arm/mm/pmsa-v8.c:73:27: error: 'BASEADDR_V7M_SCB' undeclared (first use in this function)
      73 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RLAR);
         |                           ^~~~~~~~~~~~~~~~
   arch/arm/mm/pmsa-v8.c:73:46: error: 'PMSAv8_RLAR' undeclared (first use in this function); did you mean 'PMSAv8_MAIR'?
      73 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RLAR);
         |                                              ^~~~~~~~~~~
         |                                              PMSAv8_MAIR
   arch/arm/mm/pmsa-v8.c: In function 'prbar_read':
   arch/arm/mm/pmsa-v8.c:59:1: error: control reaches end of non-void function [-Werror=return-type]
      59 | }
         | ^
   arch/arm/mm/pmsa-v8.c: In function 'prlar_read':
   arch/arm/mm/pmsa-v8.c:54:1: error: control reaches end of non-void function [-Werror=return-type]
      54 | }
         | ^
   cc1: some warnings being treated as errors


vim +22 arch/arm/include/asm/cputype.h

0ba8b9b273c45d Russell King     2008-08-10  12  
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  13  #ifdef CONFIG_CPU_V7M
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  14  #define CPUID_EXT_PFR0	0x40
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  15  #define CPUID_EXT_PFR1	0x44
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  16  #define CPUID_EXT_DFR0	0x48
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  17  #define CPUID_EXT_AFR0	0x4c
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  18  #define CPUID_EXT_MMFR0	0x50
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  19  #define CPUID_EXT_MMFR1	0x54
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  20  #define CPUID_EXT_MMFR2	0x58
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  21  #define CPUID_EXT_MMFR3	0x5c
6fae9cdafc92ae Uwe Kleine-König 2013-05-06 @22  #define CPUID_EXT_ISAR0	0x60
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  23  #define CPUID_EXT_ISAR1	0x64
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  24  #define CPUID_EXT_ISAR2	0x68
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  25  #define CPUID_EXT_ISAR3	0x6c
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  26  #define CPUID_EXT_ISAR4	0x70
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  27  #define CPUID_EXT_ISAR5	0x74
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  28  #else
faa7bc51c11d5b Catalin Marinas  2009-05-30  29  #define CPUID_EXT_PFR0	"c1, 0"
faa7bc51c11d5b Catalin Marinas  2009-05-30  30  #define CPUID_EXT_PFR1	"c1, 1"
faa7bc51c11d5b Catalin Marinas  2009-05-30  31  #define CPUID_EXT_DFR0	"c1, 2"
faa7bc51c11d5b Catalin Marinas  2009-05-30  32  #define CPUID_EXT_AFR0	"c1, 3"
faa7bc51c11d5b Catalin Marinas  2009-05-30  33  #define CPUID_EXT_MMFR0	"c1, 4"
faa7bc51c11d5b Catalin Marinas  2009-05-30  34  #define CPUID_EXT_MMFR1	"c1, 5"
faa7bc51c11d5b Catalin Marinas  2009-05-30  35  #define CPUID_EXT_MMFR2	"c1, 6"
faa7bc51c11d5b Catalin Marinas  2009-05-30  36  #define CPUID_EXT_MMFR3	"c1, 7"
faa7bc51c11d5b Catalin Marinas  2009-05-30  37  #define CPUID_EXT_ISAR0	"c2, 0"
faa7bc51c11d5b Catalin Marinas  2009-05-30  38  #define CPUID_EXT_ISAR1	"c2, 1"
faa7bc51c11d5b Catalin Marinas  2009-05-30  39  #define CPUID_EXT_ISAR2	"c2, 2"
faa7bc51c11d5b Catalin Marinas  2009-05-30  40  #define CPUID_EXT_ISAR3	"c2, 3"
faa7bc51c11d5b Catalin Marinas  2009-05-30  41  #define CPUID_EXT_ISAR4	"c2, 4"
faa7bc51c11d5b Catalin Marinas  2009-05-30  42  #define CPUID_EXT_ISAR5	"c2, 5"
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  43  #endif
faa7bc51c11d5b Catalin Marinas  2009-05-30  44  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 33101 bytes --]

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

* Re: [PATCH v4 09/10] ARM: sunplus: Add initial support for Sunplus SP7021 SoC
@ 2021-11-04 15:23       ` kernel test robot
  0 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-11-04 15:23 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: kbuild-all, mturquette, sboyd, maz, p.zabel, linux, broonie,
	arnd, linux-arm-kernel, devicetree

[-- Attachment #1: Type: text/plain, Size: 13865 bytes --]

Hi Qin,

I love your patch! Yet something to improve:

[auto build test ERROR on pza/reset/next]
[also build test ERROR on robh/for-next clk/clk-next v5.15]
[cannot apply to tip/irq/core linus/master next-20211104]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211104-115746
base:   https://git.pengutronix.de/git/pza/linux reset/next
config: arm-randconfig-c002-20211104 (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/a0450f4dfa75b60af973bceea07b1be864ae81ba
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211104-115746
        git checkout a0450f4dfa75b60af973bceea07b1be864ae81ba
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arm SHELL=/bin/bash arch/arm/kernel/ arch/arm/mm/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   arch/arm/kernel/setup.c: In function 'early_print':
   arch/arm/kernel/setup.c:372:9: warning: function 'early_print' might be a candidate for 'gnu_printf' format attribute [-Wsuggest-attribute=format]
     372 |         vsnprintf(buf, sizeof(buf), str, ap);
         |         ^~~~~~~~~
   In file included from arch/arm/kernel/setup.c:36:
   arch/arm/kernel/setup.c: In function 'cpuid_init_hwcaps':
>> arch/arm/include/asm/cputype.h:22:25: error: expected ':' or ')' before numeric constant
      22 | #define CPUID_EXT_ISAR0 0x60
         |                         ^~~~
   arch/arm/include/asm/cputype.h:135:51: note: in definition of macro 'read_cpuid_ext'
     135 |                 asm("mrc        p15, 0, %0, c0, " ext_reg               \
         |                                                   ^~~~~~~
   arch/arm/kernel/setup.c:457:17: note: in expansion of macro 'cpuid_feature_extract'
     457 |         block = cpuid_feature_extract(CPUID_EXT_ISAR0, 24);
         |                 ^~~~~~~~~~~~~~~~~~~~~
   arch/arm/kernel/setup.c:457:39: note: in expansion of macro 'CPUID_EXT_ISAR0'
     457 |         block = cpuid_feature_extract(CPUID_EXT_ISAR0, 24);
         |                                       ^~~~~~~~~~~~~~~
   arch/arm/include/asm/cputype.h:18:25: error: expected ':' or ')' before numeric constant
      18 | #define CPUID_EXT_MMFR0 0x50
         |                         ^~~~
   arch/arm/include/asm/cputype.h:135:51: note: in definition of macro 'read_cpuid_ext'
     135 |                 asm("mrc        p15, 0, %0, c0, " ext_reg               \
         |                                                   ^~~~~~~
   arch/arm/kernel/setup.c:464:17: note: in expansion of macro 'cpuid_feature_extract'
     464 |         block = cpuid_feature_extract(CPUID_EXT_MMFR0, 0);
         |                 ^~~~~~~~~~~~~~~~~~~~~
   arch/arm/kernel/setup.c:464:39: note: in expansion of macro 'CPUID_EXT_MMFR0'
     464 |         block = cpuid_feature_extract(CPUID_EXT_MMFR0, 0);
         |                                       ^~~~~~~~~~~~~~~
   arch/arm/include/asm/cputype.h:27:25: error: expected ':' or ')' before numeric constant
      27 | #define CPUID_EXT_ISAR5 0x74
         |                         ^~~~
   arch/arm/include/asm/cputype.h:135:51: note: in definition of macro 'read_cpuid_ext'
     135 |                 asm("mrc        p15, 0, %0, c0, " ext_reg               \
         |                                                   ^~~~~~~
   arch/arm/kernel/setup.c:469:32: note: in expansion of macro 'CPUID_EXT_ISAR5'
     469 |         isar5 = read_cpuid_ext(CPUID_EXT_ISAR5);
         |                                ^~~~~~~~~~~~~~~
   arch/arm/kernel/setup.c: In function 'elf_hwcap_fixup':
   arch/arm/include/asm/cputype.h:25:25: error: expected ':' or ')' before numeric constant
      25 | #define CPUID_EXT_ISAR3 0x6c
         |                         ^~~~
   arch/arm/include/asm/cputype.h:135:51: note: in definition of macro 'read_cpuid_ext'
     135 |                 asm("mrc        p15, 0, %0, c0, " ext_reg               \
         |                                                   ^~~~~~~
   arch/arm/kernel/setup.c:513:13: note: in expansion of macro 'cpuid_feature_extract'
     513 |         if (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) > 1 ||
         |             ^~~~~~~~~~~~~~~~~~~~~
   arch/arm/kernel/setup.c:513:35: note: in expansion of macro 'CPUID_EXT_ISAR3'
     513 |         if (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) > 1 ||
         |                                   ^~~~~~~~~~~~~~~
   arch/arm/include/asm/cputype.h:25:25: error: expected ':' or ')' before numeric constant
      25 | #define CPUID_EXT_ISAR3 0x6c
         |                         ^~~~
   arch/arm/include/asm/cputype.h:135:51: note: in definition of macro 'read_cpuid_ext'
     135 |                 asm("mrc        p15, 0, %0, c0, " ext_reg               \
         |                                                   ^~~~~~~
   arch/arm/kernel/setup.c:514:14: note: in expansion of macro 'cpuid_feature_extract'
     514 |             (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) == 1 &&
         |              ^~~~~~~~~~~~~~~~~~~~~
   arch/arm/kernel/setup.c:514:36: note: in expansion of macro 'CPUID_EXT_ISAR3'
     514 |             (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) == 1 &&
         |                                    ^~~~~~~~~~~~~~~
   arch/arm/include/asm/cputype.h:26:25: error: expected ':' or ')' before numeric constant
      26 | #define CPUID_EXT_ISAR4 0x70
         |                         ^~~~
   arch/arm/include/asm/cputype.h:135:51: note: in definition of macro 'read_cpuid_ext'
     135 |                 asm("mrc        p15, 0, %0, c0, " ext_reg               \
         |                                                   ^~~~~~~
   arch/arm/kernel/setup.c:515:14: note: in expansion of macro 'cpuid_feature_extract'
     515 |              cpuid_feature_extract(CPUID_EXT_ISAR4, 20) >= 3))
         |              ^~~~~~~~~~~~~~~~~~~~~
   arch/arm/kernel/setup.c:515:36: note: in expansion of macro 'CPUID_EXT_ISAR4'
     515 |              cpuid_feature_extract(CPUID_EXT_ISAR4, 20) >= 3))
         |                                    ^~~~~~~~~~~~~~~
   In file included from arch/arm/include/asm/efi.h:12,
                    from arch/arm/kernel/setup.c:37:
   At top level:
   arch/arm/include/asm/fixmap.h:39:35: warning: '__end_of_fixed_addresses' defined but not used [-Wunused-const-variable=]
      39 | static const enum fixed_addresses __end_of_fixed_addresses =
         |                                   ^~~~~~~~~~~~~~~~~~~~~~~~
--
   arch/arm/mm/pmsa-v8.c: In function 'prlar_read':
>> arch/arm/mm/pmsa-v8.c:53:16: error: implicit declaration of function 'readl_relaxed' [-Werror=implicit-function-declaration]
      53 |         return readl_relaxed(BASEADDR_V7M_SCB + PMSAv8_RLAR);
         |                ^~~~~~~~~~~~~
>> arch/arm/mm/pmsa-v8.c:53:30: error: 'BASEADDR_V7M_SCB' undeclared (first use in this function)
      53 |         return readl_relaxed(BASEADDR_V7M_SCB + PMSAv8_RLAR);
         |                              ^~~~~~~~~~~~~~~~
   arch/arm/mm/pmsa-v8.c:53:30: note: each undeclared identifier is reported only once for each function it appears in
>> arch/arm/mm/pmsa-v8.c:53:49: error: 'PMSAv8_RLAR' undeclared (first use in this function); did you mean 'PMSAv8_MAIR'?
      53 |         return readl_relaxed(BASEADDR_V7M_SCB + PMSAv8_RLAR);
         |                                                 ^~~~~~~~~~~
         |                                                 PMSAv8_MAIR
   arch/arm/mm/pmsa-v8.c: In function 'prbar_read':
   arch/arm/mm/pmsa-v8.c:58:30: error: 'BASEADDR_V7M_SCB' undeclared (first use in this function)
      58 |         return readl_relaxed(BASEADDR_V7M_SCB + PMSAv8_RBAR);
         |                              ^~~~~~~~~~~~~~~~
>> arch/arm/mm/pmsa-v8.c:58:49: error: 'PMSAv8_RBAR' undeclared (first use in this function); did you mean 'PMSAv8_MAIR'?
      58 |         return readl_relaxed(BASEADDR_V7M_SCB + PMSAv8_RBAR);
         |                                                 ^~~~~~~~~~~
         |                                                 PMSAv8_MAIR
   arch/arm/mm/pmsa-v8.c: In function 'prsel_write':
>> arch/arm/mm/pmsa-v8.c:63:9: error: implicit declaration of function 'writel_relaxed' [-Werror=implicit-function-declaration]
      63 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RNR);
         |         ^~~~~~~~~~~~~~
   arch/arm/mm/pmsa-v8.c:63:27: error: 'BASEADDR_V7M_SCB' undeclared (first use in this function)
      63 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RNR);
         |                           ^~~~~~~~~~~~~~~~
>> arch/arm/mm/pmsa-v8.c:63:46: error: 'PMSAv8_RNR' undeclared (first use in this function); did you mean 'PMSAv8_MAIR'?
      63 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RNR);
         |                                              ^~~~~~~~~~
         |                                              PMSAv8_MAIR
   arch/arm/mm/pmsa-v8.c: In function 'prbar_write':
   arch/arm/mm/pmsa-v8.c:68:27: error: 'BASEADDR_V7M_SCB' undeclared (first use in this function)
      68 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RBAR);
         |                           ^~~~~~~~~~~~~~~~
   arch/arm/mm/pmsa-v8.c:68:46: error: 'PMSAv8_RBAR' undeclared (first use in this function); did you mean 'PMSAv8_MAIR'?
      68 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RBAR);
         |                                              ^~~~~~~~~~~
         |                                              PMSAv8_MAIR
   arch/arm/mm/pmsa-v8.c: In function 'prlar_write':
   arch/arm/mm/pmsa-v8.c:73:27: error: 'BASEADDR_V7M_SCB' undeclared (first use in this function)
      73 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RLAR);
         |                           ^~~~~~~~~~~~~~~~
   arch/arm/mm/pmsa-v8.c:73:46: error: 'PMSAv8_RLAR' undeclared (first use in this function); did you mean 'PMSAv8_MAIR'?
      73 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RLAR);
         |                                              ^~~~~~~~~~~
         |                                              PMSAv8_MAIR
   arch/arm/mm/pmsa-v8.c: In function 'prbar_read':
   arch/arm/mm/pmsa-v8.c:59:1: error: control reaches end of non-void function [-Werror=return-type]
      59 | }
         | ^
   arch/arm/mm/pmsa-v8.c: In function 'prlar_read':
   arch/arm/mm/pmsa-v8.c:54:1: error: control reaches end of non-void function [-Werror=return-type]
      54 | }
         | ^
   cc1: some warnings being treated as errors


vim +22 arch/arm/include/asm/cputype.h

0ba8b9b273c45d Russell King     2008-08-10  12  
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  13  #ifdef CONFIG_CPU_V7M
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  14  #define CPUID_EXT_PFR0	0x40
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  15  #define CPUID_EXT_PFR1	0x44
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  16  #define CPUID_EXT_DFR0	0x48
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  17  #define CPUID_EXT_AFR0	0x4c
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  18  #define CPUID_EXT_MMFR0	0x50
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  19  #define CPUID_EXT_MMFR1	0x54
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  20  #define CPUID_EXT_MMFR2	0x58
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  21  #define CPUID_EXT_MMFR3	0x5c
6fae9cdafc92ae Uwe Kleine-König 2013-05-06 @22  #define CPUID_EXT_ISAR0	0x60
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  23  #define CPUID_EXT_ISAR1	0x64
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  24  #define CPUID_EXT_ISAR2	0x68
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  25  #define CPUID_EXT_ISAR3	0x6c
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  26  #define CPUID_EXT_ISAR4	0x70
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  27  #define CPUID_EXT_ISAR5	0x74
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  28  #else
faa7bc51c11d5b Catalin Marinas  2009-05-30  29  #define CPUID_EXT_PFR0	"c1, 0"
faa7bc51c11d5b Catalin Marinas  2009-05-30  30  #define CPUID_EXT_PFR1	"c1, 1"
faa7bc51c11d5b Catalin Marinas  2009-05-30  31  #define CPUID_EXT_DFR0	"c1, 2"
faa7bc51c11d5b Catalin Marinas  2009-05-30  32  #define CPUID_EXT_AFR0	"c1, 3"
faa7bc51c11d5b Catalin Marinas  2009-05-30  33  #define CPUID_EXT_MMFR0	"c1, 4"
faa7bc51c11d5b Catalin Marinas  2009-05-30  34  #define CPUID_EXT_MMFR1	"c1, 5"
faa7bc51c11d5b Catalin Marinas  2009-05-30  35  #define CPUID_EXT_MMFR2	"c1, 6"
faa7bc51c11d5b Catalin Marinas  2009-05-30  36  #define CPUID_EXT_MMFR3	"c1, 7"
faa7bc51c11d5b Catalin Marinas  2009-05-30  37  #define CPUID_EXT_ISAR0	"c2, 0"
faa7bc51c11d5b Catalin Marinas  2009-05-30  38  #define CPUID_EXT_ISAR1	"c2, 1"
faa7bc51c11d5b Catalin Marinas  2009-05-30  39  #define CPUID_EXT_ISAR2	"c2, 2"
faa7bc51c11d5b Catalin Marinas  2009-05-30  40  #define CPUID_EXT_ISAR3	"c2, 3"
faa7bc51c11d5b Catalin Marinas  2009-05-30  41  #define CPUID_EXT_ISAR4	"c2, 4"
faa7bc51c11d5b Catalin Marinas  2009-05-30  42  #define CPUID_EXT_ISAR5	"c2, 5"
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  43  #endif
faa7bc51c11d5b Catalin Marinas  2009-05-30  44  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 33101 bytes --]

[-- Attachment #3: Type: text/plain, Size: 176 bytes --]

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

* Re: [PATCH v4 09/10] ARM: sunplus: Add initial support for Sunplus SP7021 SoC
@ 2021-11-04 15:23       ` kernel test robot
  0 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-11-04 15:23 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 14095 bytes --]

Hi Qin,

I love your patch! Yet something to improve:

[auto build test ERROR on pza/reset/next]
[also build test ERROR on robh/for-next clk/clk-next v5.15]
[cannot apply to tip/irq/core linus/master next-20211104]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211104-115746
base:   https://git.pengutronix.de/git/pza/linux reset/next
config: arm-randconfig-c002-20211104 (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/a0450f4dfa75b60af973bceea07b1be864ae81ba
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211104-115746
        git checkout a0450f4dfa75b60af973bceea07b1be864ae81ba
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arm SHELL=/bin/bash arch/arm/kernel/ arch/arm/mm/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   arch/arm/kernel/setup.c: In function 'early_print':
   arch/arm/kernel/setup.c:372:9: warning: function 'early_print' might be a candidate for 'gnu_printf' format attribute [-Wsuggest-attribute=format]
     372 |         vsnprintf(buf, sizeof(buf), str, ap);
         |         ^~~~~~~~~
   In file included from arch/arm/kernel/setup.c:36:
   arch/arm/kernel/setup.c: In function 'cpuid_init_hwcaps':
>> arch/arm/include/asm/cputype.h:22:25: error: expected ':' or ')' before numeric constant
      22 | #define CPUID_EXT_ISAR0 0x60
         |                         ^~~~
   arch/arm/include/asm/cputype.h:135:51: note: in definition of macro 'read_cpuid_ext'
     135 |                 asm("mrc        p15, 0, %0, c0, " ext_reg               \
         |                                                   ^~~~~~~
   arch/arm/kernel/setup.c:457:17: note: in expansion of macro 'cpuid_feature_extract'
     457 |         block = cpuid_feature_extract(CPUID_EXT_ISAR0, 24);
         |                 ^~~~~~~~~~~~~~~~~~~~~
   arch/arm/kernel/setup.c:457:39: note: in expansion of macro 'CPUID_EXT_ISAR0'
     457 |         block = cpuid_feature_extract(CPUID_EXT_ISAR0, 24);
         |                                       ^~~~~~~~~~~~~~~
   arch/arm/include/asm/cputype.h:18:25: error: expected ':' or ')' before numeric constant
      18 | #define CPUID_EXT_MMFR0 0x50
         |                         ^~~~
   arch/arm/include/asm/cputype.h:135:51: note: in definition of macro 'read_cpuid_ext'
     135 |                 asm("mrc        p15, 0, %0, c0, " ext_reg               \
         |                                                   ^~~~~~~
   arch/arm/kernel/setup.c:464:17: note: in expansion of macro 'cpuid_feature_extract'
     464 |         block = cpuid_feature_extract(CPUID_EXT_MMFR0, 0);
         |                 ^~~~~~~~~~~~~~~~~~~~~
   arch/arm/kernel/setup.c:464:39: note: in expansion of macro 'CPUID_EXT_MMFR0'
     464 |         block = cpuid_feature_extract(CPUID_EXT_MMFR0, 0);
         |                                       ^~~~~~~~~~~~~~~
   arch/arm/include/asm/cputype.h:27:25: error: expected ':' or ')' before numeric constant
      27 | #define CPUID_EXT_ISAR5 0x74
         |                         ^~~~
   arch/arm/include/asm/cputype.h:135:51: note: in definition of macro 'read_cpuid_ext'
     135 |                 asm("mrc        p15, 0, %0, c0, " ext_reg               \
         |                                                   ^~~~~~~
   arch/arm/kernel/setup.c:469:32: note: in expansion of macro 'CPUID_EXT_ISAR5'
     469 |         isar5 = read_cpuid_ext(CPUID_EXT_ISAR5);
         |                                ^~~~~~~~~~~~~~~
   arch/arm/kernel/setup.c: In function 'elf_hwcap_fixup':
   arch/arm/include/asm/cputype.h:25:25: error: expected ':' or ')' before numeric constant
      25 | #define CPUID_EXT_ISAR3 0x6c
         |                         ^~~~
   arch/arm/include/asm/cputype.h:135:51: note: in definition of macro 'read_cpuid_ext'
     135 |                 asm("mrc        p15, 0, %0, c0, " ext_reg               \
         |                                                   ^~~~~~~
   arch/arm/kernel/setup.c:513:13: note: in expansion of macro 'cpuid_feature_extract'
     513 |         if (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) > 1 ||
         |             ^~~~~~~~~~~~~~~~~~~~~
   arch/arm/kernel/setup.c:513:35: note: in expansion of macro 'CPUID_EXT_ISAR3'
     513 |         if (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) > 1 ||
         |                                   ^~~~~~~~~~~~~~~
   arch/arm/include/asm/cputype.h:25:25: error: expected ':' or ')' before numeric constant
      25 | #define CPUID_EXT_ISAR3 0x6c
         |                         ^~~~
   arch/arm/include/asm/cputype.h:135:51: note: in definition of macro 'read_cpuid_ext'
     135 |                 asm("mrc        p15, 0, %0, c0, " ext_reg               \
         |                                                   ^~~~~~~
   arch/arm/kernel/setup.c:514:14: note: in expansion of macro 'cpuid_feature_extract'
     514 |             (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) == 1 &&
         |              ^~~~~~~~~~~~~~~~~~~~~
   arch/arm/kernel/setup.c:514:36: note: in expansion of macro 'CPUID_EXT_ISAR3'
     514 |             (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) == 1 &&
         |                                    ^~~~~~~~~~~~~~~
   arch/arm/include/asm/cputype.h:26:25: error: expected ':' or ')' before numeric constant
      26 | #define CPUID_EXT_ISAR4 0x70
         |                         ^~~~
   arch/arm/include/asm/cputype.h:135:51: note: in definition of macro 'read_cpuid_ext'
     135 |                 asm("mrc        p15, 0, %0, c0, " ext_reg               \
         |                                                   ^~~~~~~
   arch/arm/kernel/setup.c:515:14: note: in expansion of macro 'cpuid_feature_extract'
     515 |              cpuid_feature_extract(CPUID_EXT_ISAR4, 20) >= 3))
         |              ^~~~~~~~~~~~~~~~~~~~~
   arch/arm/kernel/setup.c:515:36: note: in expansion of macro 'CPUID_EXT_ISAR4'
     515 |              cpuid_feature_extract(CPUID_EXT_ISAR4, 20) >= 3))
         |                                    ^~~~~~~~~~~~~~~
   In file included from arch/arm/include/asm/efi.h:12,
                    from arch/arm/kernel/setup.c:37:
   At top level:
   arch/arm/include/asm/fixmap.h:39:35: warning: '__end_of_fixed_addresses' defined but not used [-Wunused-const-variable=]
      39 | static const enum fixed_addresses __end_of_fixed_addresses =
         |                                   ^~~~~~~~~~~~~~~~~~~~~~~~
--
   arch/arm/mm/pmsa-v8.c: In function 'prlar_read':
>> arch/arm/mm/pmsa-v8.c:53:16: error: implicit declaration of function 'readl_relaxed' [-Werror=implicit-function-declaration]
      53 |         return readl_relaxed(BASEADDR_V7M_SCB + PMSAv8_RLAR);
         |                ^~~~~~~~~~~~~
>> arch/arm/mm/pmsa-v8.c:53:30: error: 'BASEADDR_V7M_SCB' undeclared (first use in this function)
      53 |         return readl_relaxed(BASEADDR_V7M_SCB + PMSAv8_RLAR);
         |                              ^~~~~~~~~~~~~~~~
   arch/arm/mm/pmsa-v8.c:53:30: note: each undeclared identifier is reported only once for each function it appears in
>> arch/arm/mm/pmsa-v8.c:53:49: error: 'PMSAv8_RLAR' undeclared (first use in this function); did you mean 'PMSAv8_MAIR'?
      53 |         return readl_relaxed(BASEADDR_V7M_SCB + PMSAv8_RLAR);
         |                                                 ^~~~~~~~~~~
         |                                                 PMSAv8_MAIR
   arch/arm/mm/pmsa-v8.c: In function 'prbar_read':
   arch/arm/mm/pmsa-v8.c:58:30: error: 'BASEADDR_V7M_SCB' undeclared (first use in this function)
      58 |         return readl_relaxed(BASEADDR_V7M_SCB + PMSAv8_RBAR);
         |                              ^~~~~~~~~~~~~~~~
>> arch/arm/mm/pmsa-v8.c:58:49: error: 'PMSAv8_RBAR' undeclared (first use in this function); did you mean 'PMSAv8_MAIR'?
      58 |         return readl_relaxed(BASEADDR_V7M_SCB + PMSAv8_RBAR);
         |                                                 ^~~~~~~~~~~
         |                                                 PMSAv8_MAIR
   arch/arm/mm/pmsa-v8.c: In function 'prsel_write':
>> arch/arm/mm/pmsa-v8.c:63:9: error: implicit declaration of function 'writel_relaxed' [-Werror=implicit-function-declaration]
      63 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RNR);
         |         ^~~~~~~~~~~~~~
   arch/arm/mm/pmsa-v8.c:63:27: error: 'BASEADDR_V7M_SCB' undeclared (first use in this function)
      63 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RNR);
         |                           ^~~~~~~~~~~~~~~~
>> arch/arm/mm/pmsa-v8.c:63:46: error: 'PMSAv8_RNR' undeclared (first use in this function); did you mean 'PMSAv8_MAIR'?
      63 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RNR);
         |                                              ^~~~~~~~~~
         |                                              PMSAv8_MAIR
   arch/arm/mm/pmsa-v8.c: In function 'prbar_write':
   arch/arm/mm/pmsa-v8.c:68:27: error: 'BASEADDR_V7M_SCB' undeclared (first use in this function)
      68 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RBAR);
         |                           ^~~~~~~~~~~~~~~~
   arch/arm/mm/pmsa-v8.c:68:46: error: 'PMSAv8_RBAR' undeclared (first use in this function); did you mean 'PMSAv8_MAIR'?
      68 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RBAR);
         |                                              ^~~~~~~~~~~
         |                                              PMSAv8_MAIR
   arch/arm/mm/pmsa-v8.c: In function 'prlar_write':
   arch/arm/mm/pmsa-v8.c:73:27: error: 'BASEADDR_V7M_SCB' undeclared (first use in this function)
      73 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RLAR);
         |                           ^~~~~~~~~~~~~~~~
   arch/arm/mm/pmsa-v8.c:73:46: error: 'PMSAv8_RLAR' undeclared (first use in this function); did you mean 'PMSAv8_MAIR'?
      73 |         writel_relaxed(v, BASEADDR_V7M_SCB + PMSAv8_RLAR);
         |                                              ^~~~~~~~~~~
         |                                              PMSAv8_MAIR
   arch/arm/mm/pmsa-v8.c: In function 'prbar_read':
   arch/arm/mm/pmsa-v8.c:59:1: error: control reaches end of non-void function [-Werror=return-type]
      59 | }
         | ^
   arch/arm/mm/pmsa-v8.c: In function 'prlar_read':
   arch/arm/mm/pmsa-v8.c:54:1: error: control reaches end of non-void function [-Werror=return-type]
      54 | }
         | ^
   cc1: some warnings being treated as errors


vim +22 arch/arm/include/asm/cputype.h

0ba8b9b273c45d Russell King     2008-08-10  12  
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  13  #ifdef CONFIG_CPU_V7M
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  14  #define CPUID_EXT_PFR0	0x40
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  15  #define CPUID_EXT_PFR1	0x44
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  16  #define CPUID_EXT_DFR0	0x48
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  17  #define CPUID_EXT_AFR0	0x4c
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  18  #define CPUID_EXT_MMFR0	0x50
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  19  #define CPUID_EXT_MMFR1	0x54
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  20  #define CPUID_EXT_MMFR2	0x58
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  21  #define CPUID_EXT_MMFR3	0x5c
6fae9cdafc92ae Uwe Kleine-König 2013-05-06 @22  #define CPUID_EXT_ISAR0	0x60
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  23  #define CPUID_EXT_ISAR1	0x64
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  24  #define CPUID_EXT_ISAR2	0x68
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  25  #define CPUID_EXT_ISAR3	0x6c
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  26  #define CPUID_EXT_ISAR4	0x70
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  27  #define CPUID_EXT_ISAR5	0x74
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  28  #else
faa7bc51c11d5b Catalin Marinas  2009-05-30  29  #define CPUID_EXT_PFR0	"c1, 0"
faa7bc51c11d5b Catalin Marinas  2009-05-30  30  #define CPUID_EXT_PFR1	"c1, 1"
faa7bc51c11d5b Catalin Marinas  2009-05-30  31  #define CPUID_EXT_DFR0	"c1, 2"
faa7bc51c11d5b Catalin Marinas  2009-05-30  32  #define CPUID_EXT_AFR0	"c1, 3"
faa7bc51c11d5b Catalin Marinas  2009-05-30  33  #define CPUID_EXT_MMFR0	"c1, 4"
faa7bc51c11d5b Catalin Marinas  2009-05-30  34  #define CPUID_EXT_MMFR1	"c1, 5"
faa7bc51c11d5b Catalin Marinas  2009-05-30  35  #define CPUID_EXT_MMFR2	"c1, 6"
faa7bc51c11d5b Catalin Marinas  2009-05-30  36  #define CPUID_EXT_MMFR3	"c1, 7"
faa7bc51c11d5b Catalin Marinas  2009-05-30  37  #define CPUID_EXT_ISAR0	"c2, 0"
faa7bc51c11d5b Catalin Marinas  2009-05-30  38  #define CPUID_EXT_ISAR1	"c2, 1"
faa7bc51c11d5b Catalin Marinas  2009-05-30  39  #define CPUID_EXT_ISAR2	"c2, 2"
faa7bc51c11d5b Catalin Marinas  2009-05-30  40  #define CPUID_EXT_ISAR3	"c2, 3"
faa7bc51c11d5b Catalin Marinas  2009-05-30  41  #define CPUID_EXT_ISAR4	"c2, 4"
faa7bc51c11d5b Catalin Marinas  2009-05-30  42  #define CPUID_EXT_ISAR5	"c2, 5"
6fae9cdafc92ae Uwe Kleine-König 2013-05-06  43  #endif
faa7bc51c11d5b Catalin Marinas  2009-05-30  44  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 33101 bytes --]

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

* Re: [PATCH v4 06/10] clk: Add Sunplus SP7021 clock driver
  2021-11-04  2:57     ` Qin Jian
  (?)
@ 2021-11-05  4:02       ` kernel test robot
  -1 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-11-05  4:02 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: kbuild-all, mturquette, sboyd, maz, p.zabel, linux, broonie,
	arnd, linux-arm-kernel, devicetree

[-- Attachment #1: Type: text/plain, Size: 5350 bytes --]

Hi Qin,

I love your patch! Yet something to improve:

[auto build test ERROR on pza/reset/next]
[also build test ERROR on robh/for-next clk/clk-next tip/irq/core linus/master v5.15 next-20211104]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211104-115746
base:   https://git.pengutronix.de/git/pza/linux reset/next
config: arc-allyesconfig (attached as .config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/604141a9aad536dff720a6337561171d72d63d74
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211104-115746
        git checkout 604141a9aad536dff720a6337561171d72d63d74
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=arc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/clk/clk-sp7021.c: In function 'plltv_fractional_div':
>> drivers/clk/clk-sp7021.c:292:13: error: variable 'diff_min_sign' set but not used [-Werror=unused-but-set-variable]
     292 |         u32 diff_min_sign = 0;
         |             ^~~~~~~~~~~~~
   drivers/clk/clk-sp7021.c: At top level:
   drivers/clk/clk-sp7021.c:625:13: error: no previous prototype for 'clk_register_sp_pll' [-Werror=missing-prototypes]
     625 | struct clk *clk_register_sp_pll(const char *name, const char *parent,
         |             ^~~~~~~~~~~~~~~~~~~
   cc1: all warnings being treated as errors


vim +/diff_min_sign +292 drivers/clk/clk-sp7021.c

   286	
   287	static long plltv_fractional_div(struct sp_pll *clk, unsigned long freq)
   288	{
   289		u32 m, r;
   290		u32 nint, nfra;
   291		u32 diff_min_quotient = 210000000, diff_min_remainder = 0;
 > 292		u32 diff_min_sign = 0;
   293		unsigned long fvco, nf, f, fout = 0;
   294		int sdm, ph;
   295	
   296		/* check freq */
   297		if (freq < F_MIN) {
   298			pr_warn("%s: %s freq:%lu < F_MIN:%lu, round up\n",
   299				__func__, clk_hw_get_name(&clk->hw), freq, F_MIN);
   300			freq = F_MIN;
   301		} else if (freq > F_MAX) {
   302			pr_warn("%s: %s freq:%lu > F_MAX:%lu, round down\n",
   303				__func__, clk_hw_get_name(&clk->hw), freq, F_MAX);
   304			freq = F_MAX;
   305		}
   306	
   307		/* DIVR 0~3 */
   308		for (r = 0; r <= 3; r++) {
   309			fvco = freq << r;
   310			if (fvco <= FVCO_MAX)
   311				break;
   312		}
   313		f = F_27M >> r;
   314	
   315		/* PH_SEL 1/0 */
   316		for (ph = 1; ph >= 0; ph--) {
   317			const u32 *pp = pt[ph];
   318			u32 ms = 1;
   319	
   320			/* SDM_MOD 0/1 */
   321			for (sdm = 0; sdm <= 1; sdm++) {
   322				u32 mod = mods[sdm];
   323	
   324				/* DIVM 1~32 */
   325				for (m = ms; m <= 32; m++) {
   326					u32 diff_freq;
   327					u32 diff_freq_quotient = 0, diff_freq_remainder = 0;
   328					u32 diff_freq_sign = 0; /* 0:Positive number, 1:Negative number */
   329	
   330					nf = fvco * m;
   331					nint = nf / pp[3];
   332	
   333					if (nint < pp[1])
   334						continue;
   335					if (nint > pp[1])
   336						break;
   337	
   338					nfra = (((nf % pp[3]) * mod * pp[4]) + (F_27M / 2)) / F_27M;
   339					if (nfra)
   340						diff_freq = (f * (nint + pp[2]) / pp[0]) -
   341									(f * (mod - nfra) / mod / pp[4]);
   342					else
   343						diff_freq = (f * (nint) / pp[0]);
   344	
   345					diff_freq_quotient  = diff_freq / m;
   346					diff_freq_remainder = ((diff_freq % m) * 1000) / m;
   347	
   348					if (freq > diff_freq_quotient) {
   349						diff_freq_quotient  = freq - diff_freq_quotient - 1;
   350						diff_freq_remainder = 1000 - diff_freq_remainder;
   351						diff_freq_sign = 1;
   352					} else {
   353						diff_freq_quotient = diff_freq_quotient - freq;
   354						diff_freq_sign = 0;
   355					}
   356	
   357					if ((diff_min_quotient > diff_freq_quotient) ||
   358						((diff_min_quotient == diff_freq_quotient) &&
   359						(diff_min_remainder > diff_freq_remainder))) {
   360	
   361						/* found a closer freq, save parameters */
   362						clk->p[SEL_FRA] = 1;
   363						clk->p[SDM_MOD] = sdm;
   364						clk->p[PH_SEL]  = ph;
   365						clk->p[NFRA]    = nfra;
   366						clk->p[DIVR]    = r;
   367						clk->p[DIVM]    = m;
   368	
   369						fout = diff_freq / m;
   370						diff_min_quotient = diff_freq_quotient;
   371						diff_min_remainder = diff_freq_remainder;
   372						diff_min_sign = diff_freq_sign;
   373					}
   374				}
   375			}
   376		}
   377	
   378		if (!fout) {
   379			pr_err("%s: %s freq:%lu not found a valid setting\n",
   380				__func__, clk_hw_get_name(&clk->hw), freq);
   381			return -EINVAL;
   382		}
   383	
   384		return fout;
   385	}
   386	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 69191 bytes --]

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

* Re: [PATCH v4 06/10] clk: Add Sunplus SP7021 clock driver
@ 2021-11-05  4:02       ` kernel test robot
  0 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-11-05  4:02 UTC (permalink / raw)
  To: Qin Jian, robh+dt
  Cc: kbuild-all, mturquette, sboyd, maz, p.zabel, linux, broonie,
	arnd, linux-arm-kernel, devicetree

[-- Attachment #1: Type: text/plain, Size: 5350 bytes --]

Hi Qin,

I love your patch! Yet something to improve:

[auto build test ERROR on pza/reset/next]
[also build test ERROR on robh/for-next clk/clk-next tip/irq/core linus/master v5.15 next-20211104]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211104-115746
base:   https://git.pengutronix.de/git/pza/linux reset/next
config: arc-allyesconfig (attached as .config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/604141a9aad536dff720a6337561171d72d63d74
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211104-115746
        git checkout 604141a9aad536dff720a6337561171d72d63d74
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=arc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/clk/clk-sp7021.c: In function 'plltv_fractional_div':
>> drivers/clk/clk-sp7021.c:292:13: error: variable 'diff_min_sign' set but not used [-Werror=unused-but-set-variable]
     292 |         u32 diff_min_sign = 0;
         |             ^~~~~~~~~~~~~
   drivers/clk/clk-sp7021.c: At top level:
   drivers/clk/clk-sp7021.c:625:13: error: no previous prototype for 'clk_register_sp_pll' [-Werror=missing-prototypes]
     625 | struct clk *clk_register_sp_pll(const char *name, const char *parent,
         |             ^~~~~~~~~~~~~~~~~~~
   cc1: all warnings being treated as errors


vim +/diff_min_sign +292 drivers/clk/clk-sp7021.c

   286	
   287	static long plltv_fractional_div(struct sp_pll *clk, unsigned long freq)
   288	{
   289		u32 m, r;
   290		u32 nint, nfra;
   291		u32 diff_min_quotient = 210000000, diff_min_remainder = 0;
 > 292		u32 diff_min_sign = 0;
   293		unsigned long fvco, nf, f, fout = 0;
   294		int sdm, ph;
   295	
   296		/* check freq */
   297		if (freq < F_MIN) {
   298			pr_warn("%s: %s freq:%lu < F_MIN:%lu, round up\n",
   299				__func__, clk_hw_get_name(&clk->hw), freq, F_MIN);
   300			freq = F_MIN;
   301		} else if (freq > F_MAX) {
   302			pr_warn("%s: %s freq:%lu > F_MAX:%lu, round down\n",
   303				__func__, clk_hw_get_name(&clk->hw), freq, F_MAX);
   304			freq = F_MAX;
   305		}
   306	
   307		/* DIVR 0~3 */
   308		for (r = 0; r <= 3; r++) {
   309			fvco = freq << r;
   310			if (fvco <= FVCO_MAX)
   311				break;
   312		}
   313		f = F_27M >> r;
   314	
   315		/* PH_SEL 1/0 */
   316		for (ph = 1; ph >= 0; ph--) {
   317			const u32 *pp = pt[ph];
   318			u32 ms = 1;
   319	
   320			/* SDM_MOD 0/1 */
   321			for (sdm = 0; sdm <= 1; sdm++) {
   322				u32 mod = mods[sdm];
   323	
   324				/* DIVM 1~32 */
   325				for (m = ms; m <= 32; m++) {
   326					u32 diff_freq;
   327					u32 diff_freq_quotient = 0, diff_freq_remainder = 0;
   328					u32 diff_freq_sign = 0; /* 0:Positive number, 1:Negative number */
   329	
   330					nf = fvco * m;
   331					nint = nf / pp[3];
   332	
   333					if (nint < pp[1])
   334						continue;
   335					if (nint > pp[1])
   336						break;
   337	
   338					nfra = (((nf % pp[3]) * mod * pp[4]) + (F_27M / 2)) / F_27M;
   339					if (nfra)
   340						diff_freq = (f * (nint + pp[2]) / pp[0]) -
   341									(f * (mod - nfra) / mod / pp[4]);
   342					else
   343						diff_freq = (f * (nint) / pp[0]);
   344	
   345					diff_freq_quotient  = diff_freq / m;
   346					diff_freq_remainder = ((diff_freq % m) * 1000) / m;
   347	
   348					if (freq > diff_freq_quotient) {
   349						diff_freq_quotient  = freq - diff_freq_quotient - 1;
   350						diff_freq_remainder = 1000 - diff_freq_remainder;
   351						diff_freq_sign = 1;
   352					} else {
   353						diff_freq_quotient = diff_freq_quotient - freq;
   354						diff_freq_sign = 0;
   355					}
   356	
   357					if ((diff_min_quotient > diff_freq_quotient) ||
   358						((diff_min_quotient == diff_freq_quotient) &&
   359						(diff_min_remainder > diff_freq_remainder))) {
   360	
   361						/* found a closer freq, save parameters */
   362						clk->p[SEL_FRA] = 1;
   363						clk->p[SDM_MOD] = sdm;
   364						clk->p[PH_SEL]  = ph;
   365						clk->p[NFRA]    = nfra;
   366						clk->p[DIVR]    = r;
   367						clk->p[DIVM]    = m;
   368	
   369						fout = diff_freq / m;
   370						diff_min_quotient = diff_freq_quotient;
   371						diff_min_remainder = diff_freq_remainder;
   372						diff_min_sign = diff_freq_sign;
   373					}
   374				}
   375			}
   376		}
   377	
   378		if (!fout) {
   379			pr_err("%s: %s freq:%lu not found a valid setting\n",
   380				__func__, clk_hw_get_name(&clk->hw), freq);
   381			return -EINVAL;
   382		}
   383	
   384		return fout;
   385	}
   386	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 69191 bytes --]

[-- Attachment #3: Type: text/plain, Size: 176 bytes --]

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

* Re: [PATCH v4 06/10] clk: Add Sunplus SP7021 clock driver
@ 2021-11-05  4:02       ` kernel test robot
  0 siblings, 0 replies; 124+ messages in thread
From: kernel test robot @ 2021-11-05  4:02 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 5499 bytes --]

Hi Qin,

I love your patch! Yet something to improve:

[auto build test ERROR on pza/reset/next]
[also build test ERROR on robh/for-next clk/clk-next tip/irq/core linus/master v5.15 next-20211104]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211104-115746
base:   https://git.pengutronix.de/git/pza/linux reset/next
config: arc-allyesconfig (attached as .config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/604141a9aad536dff720a6337561171d72d63d74
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Qin-Jian/dt-bindings-vendor-prefixes-Add-Sunplus/20211104-115746
        git checkout 604141a9aad536dff720a6337561171d72d63d74
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=arc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/clk/clk-sp7021.c: In function 'plltv_fractional_div':
>> drivers/clk/clk-sp7021.c:292:13: error: variable 'diff_min_sign' set but not used [-Werror=unused-but-set-variable]
     292 |         u32 diff_min_sign = 0;
         |             ^~~~~~~~~~~~~
   drivers/clk/clk-sp7021.c: At top level:
   drivers/clk/clk-sp7021.c:625:13: error: no previous prototype for 'clk_register_sp_pll' [-Werror=missing-prototypes]
     625 | struct clk *clk_register_sp_pll(const char *name, const char *parent,
         |             ^~~~~~~~~~~~~~~~~~~
   cc1: all warnings being treated as errors


vim +/diff_min_sign +292 drivers/clk/clk-sp7021.c

   286	
   287	static long plltv_fractional_div(struct sp_pll *clk, unsigned long freq)
   288	{
   289		u32 m, r;
   290		u32 nint, nfra;
   291		u32 diff_min_quotient = 210000000, diff_min_remainder = 0;
 > 292		u32 diff_min_sign = 0;
   293		unsigned long fvco, nf, f, fout = 0;
   294		int sdm, ph;
   295	
   296		/* check freq */
   297		if (freq < F_MIN) {
   298			pr_warn("%s: %s freq:%lu < F_MIN:%lu, round up\n",
   299				__func__, clk_hw_get_name(&clk->hw), freq, F_MIN);
   300			freq = F_MIN;
   301		} else if (freq > F_MAX) {
   302			pr_warn("%s: %s freq:%lu > F_MAX:%lu, round down\n",
   303				__func__, clk_hw_get_name(&clk->hw), freq, F_MAX);
   304			freq = F_MAX;
   305		}
   306	
   307		/* DIVR 0~3 */
   308		for (r = 0; r <= 3; r++) {
   309			fvco = freq << r;
   310			if (fvco <= FVCO_MAX)
   311				break;
   312		}
   313		f = F_27M >> r;
   314	
   315		/* PH_SEL 1/0 */
   316		for (ph = 1; ph >= 0; ph--) {
   317			const u32 *pp = pt[ph];
   318			u32 ms = 1;
   319	
   320			/* SDM_MOD 0/1 */
   321			for (sdm = 0; sdm <= 1; sdm++) {
   322				u32 mod = mods[sdm];
   323	
   324				/* DIVM 1~32 */
   325				for (m = ms; m <= 32; m++) {
   326					u32 diff_freq;
   327					u32 diff_freq_quotient = 0, diff_freq_remainder = 0;
   328					u32 diff_freq_sign = 0; /* 0:Positive number, 1:Negative number */
   329	
   330					nf = fvco * m;
   331					nint = nf / pp[3];
   332	
   333					if (nint < pp[1])
   334						continue;
   335					if (nint > pp[1])
   336						break;
   337	
   338					nfra = (((nf % pp[3]) * mod * pp[4]) + (F_27M / 2)) / F_27M;
   339					if (nfra)
   340						diff_freq = (f * (nint + pp[2]) / pp[0]) -
   341									(f * (mod - nfra) / mod / pp[4]);
   342					else
   343						diff_freq = (f * (nint) / pp[0]);
   344	
   345					diff_freq_quotient  = diff_freq / m;
   346					diff_freq_remainder = ((diff_freq % m) * 1000) / m;
   347	
   348					if (freq > diff_freq_quotient) {
   349						diff_freq_quotient  = freq - diff_freq_quotient - 1;
   350						diff_freq_remainder = 1000 - diff_freq_remainder;
   351						diff_freq_sign = 1;
   352					} else {
   353						diff_freq_quotient = diff_freq_quotient - freq;
   354						diff_freq_sign = 0;
   355					}
   356	
   357					if ((diff_min_quotient > diff_freq_quotient) ||
   358						((diff_min_quotient == diff_freq_quotient) &&
   359						(diff_min_remainder > diff_freq_remainder))) {
   360	
   361						/* found a closer freq, save parameters */
   362						clk->p[SEL_FRA] = 1;
   363						clk->p[SDM_MOD] = sdm;
   364						clk->p[PH_SEL]  = ph;
   365						clk->p[NFRA]    = nfra;
   366						clk->p[DIVR]    = r;
   367						clk->p[DIVM]    = m;
   368	
   369						fout = diff_freq / m;
   370						diff_min_quotient = diff_freq_quotient;
   371						diff_min_remainder = diff_freq_remainder;
   372						diff_min_sign = diff_freq_sign;
   373					}
   374				}
   375			}
   376		}
   377	
   378		if (!fout) {
   379			pr_err("%s: %s freq:%lu not found a valid setting\n",
   380				__func__, clk_hw_get_name(&clk->hw), freq);
   381			return -EINVAL;
   382		}
   383	
   384		return fout;
   385	}
   386	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 69191 bytes --]

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

* Re: [PATCH v4 01/10] dt-bindings: vendor-prefixes: Add Sunplus
  2021-11-04  2:56     ` Qin Jian
@ 2021-11-08 17:45       ` Rob Herring
  -1 siblings, 0 replies; 124+ messages in thread
From: Rob Herring @ 2021-11-08 17:45 UTC (permalink / raw)
  To: Qin Jian
  Cc: robh+dt, linux-kernel, devicetree, sboyd, arnd, linux, p.zabel,
	linux-arm-kernel, maz, linux-clk, broonie, wells.lu, mturquette

On Thu, 04 Nov 2021 10:56:58 +0800, Qin Jian wrote:
> Add vendor prefix for Sunplus Technology Co., Ltd. (http://www.sunplus.com)
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 


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

* Re: [PATCH v4 01/10] dt-bindings: vendor-prefixes: Add Sunplus
@ 2021-11-08 17:45       ` Rob Herring
  0 siblings, 0 replies; 124+ messages in thread
From: Rob Herring @ 2021-11-08 17:45 UTC (permalink / raw)
  To: Qin Jian
  Cc: robh+dt, linux-kernel, devicetree, sboyd, arnd, linux, p.zabel,
	linux-arm-kernel, maz, linux-clk, broonie, wells.lu, mturquette

On Thu, 04 Nov 2021 10:56:58 +0800, Qin Jian wrote:
> Add vendor prefix for Sunplus Technology Co., Ltd. (http://www.sunplus.com)
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 


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

* Re: [PATCH v4 02/10] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards
  2021-11-04  2:56     ` Qin Jian
@ 2021-11-08 17:46       ` Rob Herring
  -1 siblings, 0 replies; 124+ messages in thread
From: Rob Herring @ 2021-11-08 17:46 UTC (permalink / raw)
  To: Qin Jian
  Cc: mturquette, sboyd, devicetree, linux-kernel, arnd, linux,
	p.zabel, linux-clk, robh+dt, broonie, linux-arm-kernel, maz,
	wells.lu

On Thu, 04 Nov 2021 10:56:59 +0800, Qin Jian wrote:
> This introduces bindings for boards based Sunplus SP7021 SoC.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  .../bindings/arm/sunplus,sp7021.yaml          | 27 +++++++++++++++++++
>  MAINTAINERS                                   |  7 +++++
>  2 files changed, 34 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/sunplus,sp7021.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] 124+ messages in thread

* Re: [PATCH v4 02/10] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards
@ 2021-11-08 17:46       ` Rob Herring
  0 siblings, 0 replies; 124+ messages in thread
From: Rob Herring @ 2021-11-08 17:46 UTC (permalink / raw)
  To: Qin Jian
  Cc: mturquette, sboyd, devicetree, linux-kernel, arnd, linux,
	p.zabel, linux-clk, robh+dt, broonie, linux-arm-kernel, maz,
	wells.lu

On Thu, 04 Nov 2021 10:56:59 +0800, Qin Jian wrote:
> This introduces bindings for boards based Sunplus SP7021 SoC.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  .../bindings/arm/sunplus,sp7021.yaml          | 27 +++++++++++++++++++
>  MAINTAINERS                                   |  7 +++++
>  2 files changed, 34 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/sunplus,sp7021.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] 124+ messages in thread

* Re: [PATCH v4 05/10] dt-bindings: clock: Add bindings for SP7021 clock driver
  2021-11-04  2:57     ` Qin Jian
@ 2021-11-08 17:46       ` Rob Herring
  -1 siblings, 0 replies; 124+ messages in thread
From: Rob Herring @ 2021-11-08 17:46 UTC (permalink / raw)
  To: Qin Jian
  Cc: linux-clk, sboyd, wells.lu, linux-kernel, arnd, mturquette,
	linux, p.zabel, linux-arm-kernel, devicetree, robh+dt, maz,
	broonie

On Thu, 04 Nov 2021 10:57:02 +0800, Qin Jian wrote:
> Add documentation to describe Sunplus SP7021 clock driver bindings.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  .../bindings/clock/sunplus,sp7021-clkc.yaml   |  38 ++++++
>  MAINTAINERS                                   |   2 +
>  include/dt-bindings/clock/sp-sp7021.h         | 112 ++++++++++++++++++
>  3 files changed, 152 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
>  create mode 100644 include/dt-bindings/clock/sp-sp7021.h
> 


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

* Re: [PATCH v4 05/10] dt-bindings: clock: Add bindings for SP7021 clock driver
@ 2021-11-08 17:46       ` Rob Herring
  0 siblings, 0 replies; 124+ messages in thread
From: Rob Herring @ 2021-11-08 17:46 UTC (permalink / raw)
  To: Qin Jian
  Cc: linux-clk, sboyd, wells.lu, linux-kernel, arnd, mturquette,
	linux, p.zabel, linux-arm-kernel, devicetree, robh+dt, maz,
	broonie

On Thu, 04 Nov 2021 10:57:02 +0800, Qin Jian wrote:
> Add documentation to describe Sunplus SP7021 clock driver bindings.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  .../bindings/clock/sunplus,sp7021-clkc.yaml   |  38 ++++++
>  MAINTAINERS                                   |   2 +
>  include/dt-bindings/clock/sp-sp7021.h         | 112 ++++++++++++++++++
>  3 files changed, 152 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
>  create mode 100644 include/dt-bindings/clock/sp-sp7021.h
> 


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

* Re: [PATCH v4 07/10] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
  2021-11-04  2:57     ` Qin Jian
@ 2021-11-08 17:46       ` Rob Herring
  -1 siblings, 0 replies; 124+ messages in thread
From: Rob Herring @ 2021-11-08 17:46 UTC (permalink / raw)
  To: Qin Jian
  Cc: sboyd, wells.lu, robh+dt, p.zabel, devicetree, linux-kernel,
	arnd, linux-arm-kernel, linux, maz, mturquette, linux-clk,
	broonie

On Thu, 04 Nov 2021 10:57:04 +0800, Qin Jian wrote:
> Add documentation to describe Sunplus SP7021 interrupt controller bindings.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  .../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] 124+ messages in thread

* Re: [PATCH v4 07/10] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller
@ 2021-11-08 17:46       ` Rob Herring
  0 siblings, 0 replies; 124+ messages in thread
From: Rob Herring @ 2021-11-08 17:46 UTC (permalink / raw)
  To: Qin Jian
  Cc: sboyd, wells.lu, robh+dt, p.zabel, devicetree, linux-kernel,
	arnd, linux-arm-kernel, linux, maz, mturquette, linux-clk,
	broonie

On Thu, 04 Nov 2021 10:57:04 +0800, Qin Jian wrote:
> Add documentation to describe Sunplus SP7021 interrupt controller bindings.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  .../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] 124+ messages in thread

* Re: [PATCH v4 03/10] dt-bindings: reset: Add bindings for SP7021 reset driver
  2021-11-04  2:57     ` Qin Jian
@ 2021-11-12 21:56       ` Rob Herring
  -1 siblings, 0 replies; 124+ messages in thread
From: Rob Herring @ 2021-11-12 21:56 UTC (permalink / raw)
  To: Qin Jian
  Cc: robh+dt, arnd, linux-kernel, broonie, linux-clk, p.zabel, maz,
	devicetree, wells.lu, linux-arm-kernel, sboyd, linux, mturquette

On Thu, 04 Nov 2021 10:57:00 +0800, Qin Jian wrote:
> Add documentation to describe Sunplus SP7021 reset driver bindings.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  .../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
> 

Reviewed-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH v4 03/10] dt-bindings: reset: Add bindings for SP7021 reset driver
@ 2021-11-12 21:56       ` Rob Herring
  0 siblings, 0 replies; 124+ messages in thread
From: Rob Herring @ 2021-11-12 21:56 UTC (permalink / raw)
  To: Qin Jian
  Cc: robh+dt, arnd, linux-kernel, broonie, linux-clk, p.zabel, maz,
	devicetree, wells.lu, linux-arm-kernel, sboyd, linux, mturquette

On Thu, 04 Nov 2021 10:57:00 +0800, Qin Jian wrote:
> Add documentation to describe Sunplus SP7021 reset driver bindings.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  .../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
> 

Reviewed-by: Rob Herring <robh@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] 124+ messages in thread

end of thread, other threads:[~2021-11-12 21:57 UTC | newest]

Thread overview: 124+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-29  8:44 [PATCH v2 0/8] Add Sunplus SP7021 SoC Support Qin Jian
2021-10-29  8:44 ` Qin Jian
2021-10-29  8:44 ` [PATCH v2 1/8] dt-bindings: vendor-prefixes: Add Sunplus Qin Jian
2021-10-29  8:44   ` Qin Jian
2021-10-29  8:44 ` [PATCH v2 2/8] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards Qin Jian
2021-10-29  8:44   ` Qin Jian
2021-10-29  8:44 ` [PATCH v2 3/8] dt-bindings: reset: Add bindings for SP7021 reset driver Qin Jian
2021-10-29  8:44   ` Qin Jian
2021-10-29  8:44 ` [PATCH v2 4/8] reset: Add Sunplus " Qin Jian
2021-10-29  8:44   ` Qin Jian
2021-10-30  4:18   ` kernel test robot
2021-10-30  4:18     ` kernel test robot
2021-10-30  4:18     ` kernel test robot
2021-10-29  8:44 ` [PATCH v2 5/8] dt-bindings: clock: Add bindings for SP7021 clock driver Qin Jian
2021-10-29  8:44   ` Qin Jian
2021-10-29  8:44 ` [PATCH v2 6/8] clk: Add Sunplus " Qin Jian
2021-10-29  8:44   ` Qin Jian
2021-10-29  8:44 ` [PATCH v2 7/8] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller Qin Jian
2021-10-29  8:44   ` Qin Jian
2021-10-29  8:44 ` [PATCH v2 8/8] irqchip: Add support for Sunplus " Qin Jian
2021-10-29  8:44   ` Qin Jian
2021-10-29 15:25   ` Marc Zyngier
2021-10-29 15:25     ` Marc Zyngier
2021-11-01  5:01     ` [PATCH v3 0/8] Add Sunplus SP7021 SoC Support Qin Jian
2021-11-01  5:01       ` Qin Jian
2021-11-01  5:01       ` [PATCH v3 1/8] dt-bindings: vendor-prefixes: Add Sunplus Qin Jian
2021-11-01  5:01         ` Qin Jian
2021-11-02 17:44         ` Rob Herring
2021-11-02 17:44           ` Rob Herring
2021-11-01  5:01       ` [PATCH v3 2/8] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards Qin Jian
2021-11-01  5:01         ` Qin Jian
2021-11-01 19:58         ` Rob Herring
2021-11-01 19:58           ` Rob Herring
2021-11-01  5:01       ` [PATCH v3 3/8] dt-bindings: reset: Add bindings for SP7021 reset driver Qin Jian
2021-11-01  5:01         ` Qin Jian
2021-11-02 11:51         ` Philipp Zabel
2021-11-02 11:51           ` Philipp Zabel
2021-11-03  1:20           ` 答复: " qinjian[覃健]
2021-11-03  1:20             ` qinjian[覃健]
2021-11-01  5:01       ` [PATCH v3 4/8] reset: Add Sunplus " Qin Jian
2021-11-01  5:01         ` Qin Jian
2021-11-02 12:22         ` Philipp Zabel
2021-11-02 12:22           ` Philipp Zabel
2021-11-03  2:42           ` 答复: " qinjian[覃健]
2021-11-03  2:42             ` qinjian[覃健]
2021-11-01  5:01       ` [PATCH v3 5/8] dt-bindings: clock: Add bindings for SP7021 clock driver Qin Jian
2021-11-01  5:01         ` Qin Jian
2021-11-01 19:59         ` Rob Herring
2021-11-01 19:59           ` Rob Herring
2021-11-01  5:01       ` [PATCH v3 6/8] clk: Add Sunplus " Qin Jian
2021-11-01  5:01         ` Qin Jian
2021-11-01 10:16         ` kernel test robot
2021-11-01 10:16           ` kernel test robot
2021-11-01 10:16           ` kernel test robot
2021-11-01  5:01       ` [PATCH v3 7/8] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller Qin Jian
2021-11-01  5:01         ` Qin Jian
2021-11-02 17:45         ` Rob Herring
2021-11-02 17:45           ` Rob Herring
2021-11-01  5:01       ` [PATCH v3 8/8] irqchip: Add Sunplus SP7021 interrupt controller driver Qin Jian
2021-11-01  5:01         ` Qin Jian
2021-11-01  8:27         ` kernel test robot
2021-11-01  8:27           ` kernel test robot
2021-11-01  8:27           ` kernel test robot
2021-11-01 10:26         ` kernel test robot
2021-11-01 10:26           ` kernel test robot
2021-11-01 10:26           ` kernel test robot
2021-10-30 15:30   ` [PATCH v2 8/8] irqchip: Add support for Sunplus SP7021 interrupt controller kernel test robot
2021-10-30 15:30     ` kernel test robot
2021-10-30 15:30     ` kernel test robot
2021-10-30 19:29   ` kernel test robot
2021-10-30 19:29     ` kernel test robot
2021-11-04  2:56 ` [PATCH v4 00/10] Add Sunplus SP7021 SoC Support Qin Jian
2021-11-04  2:56   ` Qin Jian
2021-11-04  2:56   ` [PATCH v4 01/10] dt-bindings: vendor-prefixes: Add Sunplus Qin Jian
2021-11-04  2:56     ` Qin Jian
2021-11-08 17:45     ` Rob Herring
2021-11-08 17:45       ` Rob Herring
2021-11-04  2:56   ` [PATCH v4 02/10] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards Qin Jian
2021-11-04  2:56     ` Qin Jian
2021-11-08 17:46     ` Rob Herring
2021-11-08 17:46       ` Rob Herring
2021-11-04  2:57   ` [PATCH v4 03/10] dt-bindings: reset: Add bindings for SP7021 reset driver Qin Jian
2021-11-04  2:57     ` Qin Jian
2021-11-12 21:56     ` Rob Herring
2021-11-12 21:56       ` Rob Herring
2021-11-04  2:57   ` [PATCH v4 04/10] reset: Add Sunplus " Qin Jian
2021-11-04  2:57     ` Qin Jian
2021-11-04  2:57   ` [PATCH v4 05/10] dt-bindings: clock: Add bindings for SP7021 clock driver Qin Jian
2021-11-04  2:57     ` Qin Jian
2021-11-08 17:46     ` Rob Herring
2021-11-08 17:46       ` Rob Herring
2021-11-04  2:57   ` [PATCH v4 06/10] clk: Add Sunplus " Qin Jian
2021-11-04  2:57     ` Qin Jian
2021-11-04  5:09     ` Randy Dunlap
2021-11-04  5:09       ` Randy Dunlap
2021-11-04 11:32     ` kernel test robot
2021-11-04 11:32       ` kernel test robot
2021-11-04 11:32       ` kernel test robot
2021-11-05  4:02     ` kernel test robot
2021-11-05  4:02       ` kernel test robot
2021-11-05  4:02       ` kernel test robot
2021-11-04  2:57   ` [PATCH v4 07/10] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller Qin Jian
2021-11-04  2:57     ` Qin Jian
2021-11-08 17:46     ` Rob Herring
2021-11-08 17:46       ` Rob Herring
2021-11-04  2:57   ` [PATCH v4 08/10] irqchip: Add Sunplus SP7021 interrupt controller driver Qin Jian
2021-11-04  2:57     ` Qin Jian
2021-11-04  5:09     ` Randy Dunlap
2021-11-04  5:09       ` Randy Dunlap
2021-11-04  2:57   ` [PATCH v4 09/10] ARM: sunplus: Add initial support for Sunplus SP7021 SoC Qin Jian
2021-11-04  2:57     ` Qin Jian
2021-11-04  5:09     ` Randy Dunlap
2021-11-04  5:09       ` Randy Dunlap
2021-11-04  5:09     ` Randy Dunlap
2021-11-04  5:09       ` Randy Dunlap
2021-11-04 15:23     ` kernel test robot
2021-11-04 15:23       ` kernel test robot
2021-11-04 15:23       ` kernel test robot
2021-11-04  2:57   ` [PATCH v4 10/10] ARM: sp7021_defconfig: Add Sunplus SP7021 defconfig Qin Jian
2021-11-04  2:57     ` Qin Jian
2021-11-04  8:22   ` [PATCH v4 00/10] Add Sunplus SP7021 SoC Support Marc Zyngier
2021-11-04  8:22     ` Marc Zyngier
2021-11-04  8:35     ` 答复: " qinjian[覃健]
2021-11-04  8:35       ` 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.