* [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
* 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: 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 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
* [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
* [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
* 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
* [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
* 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
* [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
* 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
* 答复: [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-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
* 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
* 答复: [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 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
* 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
* [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
* 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: 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 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
* [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
* 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 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: 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 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 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: 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 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 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: 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-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-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 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
* 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
* [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
* 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
* [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
* 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
* [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
* 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
* [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
* 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 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: 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 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 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: 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 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
* [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
* 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
* [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
* 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
* [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
* 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 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: 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 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
* [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 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
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.