* [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.