From 302367abd95f8d81bf1ed4bafebb6e0f71b0e5ed Mon Sep 17 00:00:00 2001 From: Kwanghoon Son Date: Mon, 18 Sep 2023 04:51:24 +0000 Subject: [PATCH 1/6] reset: Add th1520 reset driver support This driver supports th1520 T-HEAD SoC reset platform device. Signed-off-by: Kwanghoon Son --- drivers/reset/Kconfig | 10 ++++ drivers/reset/Makefile | 1 + drivers/reset/reset-th1520.c | 109 +++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 drivers/reset/reset-th1520.c diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index ccd59ddd76100..ec69e6bbba6e5 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -253,6 +253,16 @@ config RESET_SUNXI help This enables the reset driver for Allwinner SoCs. +config RESET_TH1520 + bool "TH1520 Reset Driver" + depends on (ARCH_THEAD || COMPILE_TEST) && OF + select MFD_SYSCON + default ARCH_THEAD + help + Support for the T-HEAD 1520 RISC-V SoC reset controller. + Say Y if you want to control reset signals provided by this + controller. + config RESET_TI_SCI tristate "TI System Control Interface (TI-SCI) reset driver" depends on TI_SCI_PROTOCOL || (COMPILE_TEST && TI_SCI_PROTOCOL=n) diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 8270da8a4baa6..5c858e62241a9 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -33,6 +33,7 @@ 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_TH1520) += reset-th1520.o obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o obj-$(CONFIG_RESET_TI_SYSCON) += reset-ti-syscon.o obj-$(CONFIG_RESET_TI_TPS380X) += reset-tps380x.o diff --git a/drivers/reset/reset-th1520.c b/drivers/reset/reset-th1520.c new file mode 100644 index 0000000000000..5a89d201fc0c1 --- /dev/null +++ b/drivers/reset/reset-th1520.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include +#include + +struct th1520_rst_signal { + unsigned int offset, bit; +}; + +struct th1520_rst { + struct reset_controller_dev rcdev; + struct regmap *regmap; + const struct th1520_rst_signal *signals; +}; + +enum th1520_rst_registers { + RST_WDT0 = 0x0034, + RST_WDT1 = 0x0038, +}; + +static int th1520_reset_update(struct th1520_rst *rst, unsigned long id, + unsigned int value) +{ + const struct th1520_rst_signal *signal = &rst->signals[id]; + + return regmap_update_bits(rst->regmap, signal->offset, signal->bit, + value); +} + +static const struct th1520_rst_signal th1520_rst_signals[] = { + [TH1520_RESET_WDT0] = { RST_WDT0, BIT(0) }, + [TH1520_RESET_WDT1] = { RST_WDT1, BIT(0) }, +}; + +static struct th1520_rst *to_th1520_rst(struct reset_controller_dev *rcdev) +{ + return container_of(rcdev, struct th1520_rst, rcdev); +} + +static int th1520_reset_set(struct reset_controller_dev *rcdev, + unsigned long id, bool assert) +{ + struct th1520_rst *rst = to_th1520_rst(rcdev); + const unsigned int bit = rst->signals[id].bit; + unsigned int value = assert ? bit : 0; + + return th1520_reset_update(rst, id, value); +} + +static int th1520_reset_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return th1520_reset_set(rcdev, id, false); +} + +static int th1520_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return th1520_reset_set(rcdev, id, true); +} + +static const struct reset_control_ops th1520_rst_ops = { + .assert = th1520_reset_assert, + .deassert = th1520_reset_deassert, +}; + +static int th1520_reset_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct th1520_rst *rst; + struct regmap_config config = { .name = "rst" }; + + rst = devm_kzalloc(dev, sizeof(*rst), GFP_KERNEL); + if (!rst) + return -ENOMEM; + + rst->signals = th1520_rst_signals; + rst->regmap = syscon_node_to_regmap(dev->of_node); + if (IS_ERR(rst->regmap)) + return PTR_ERR(rst->regmap); + + regmap_attach_dev(dev, rst->regmap, &config); + + rst->rcdev.owner = THIS_MODULE; + rst->rcdev.dev = dev; + rst->rcdev.of_node = dev->of_node; + rst->rcdev.ops = &th1520_rst_ops; + rst->rcdev.nr_resets = ARRAY_SIZE(th1520_rst_signals); + + return devm_reset_controller_register(dev, &rst->rcdev); +} + +static const struct of_device_id th1520_reset_dt_ids[] = { + { .compatible = "thead,th1520-reset" }, + { /* sentinel */ }, +}; + +static struct platform_driver th1520_reset_driver = { + .probe = th1520_reset_probe, + .driver = { + .name = "th1520-reset", + .of_match_table = th1520_reset_dt_ids, + }, +}; +builtin_platform_driver(th1520_reset_driver); From 14016d4a756c4f791eb8a6fcb7c1b79b080c1e02 Mon Sep 17 00:00:00 2001 From: Kwanghoon Son Date: Mon, 18 Sep 2023 04:51:23 +0000 Subject: [PATCH 2/6] dt-bindings: reset: Document th1520 reset control Add documentation to describe th1520 reset device Signed-off-by: Kwanghoon Son --- .../bindings/reset/thead,th1520-reset.yaml | 44 +++++++++++++++++++ .../dt-bindings/reset/thead,th1520-reset.h | 9 ++++ 2 files changed, 53 insertions(+) create mode 100644 Documentation/devicetree/bindings/reset/thead,th1520-reset.yaml create mode 100644 include/dt-bindings/reset/thead,th1520-reset.h diff --git a/Documentation/devicetree/bindings/reset/thead,th1520-reset.yaml b/Documentation/devicetree/bindings/reset/thead,th1520-reset.yaml new file mode 100644 index 0000000000000..49ea8c6a331f6 --- /dev/null +++ b/Documentation/devicetree/bindings/reset/thead,th1520-reset.yaml @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/reset/thead,th1520-reset.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: T-HEAD th1520 SoC Reset Controller + +maintainers: + - Kwanghoon Son + +properties: + compatible: + items: + - const: thead,th1520-reset + - const: syscon + + reg: + maxItems: 1 + + '#reset-cells': + const: 1 + +required: + - compatible + - reg + - '#reset-cells' + +additionalProperties: false + +examples: + - | + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + reset-controller@ffef014000 { + compatible = "thead,th1520-reset", "syscon"; + reg = <0xff 0xef014000 0x0 0x1000>; + #reset-cells = <1>; + }; + }; diff --git a/include/dt-bindings/reset/thead,th1520-reset.h b/include/dt-bindings/reset/thead,th1520-reset.h new file mode 100644 index 0000000000000..ec10751814e56 --- /dev/null +++ b/include/dt-bindings/reset/thead,th1520-reset.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ + +#ifndef DT_BINDING_RESET_TH1520_H +#define DT_BINDING_RESET_TH1520_H + +#define TH1520_RESET_WDT0 0 +#define TH1520_RESET_WDT1 1 + +#endif From eb0ea4de36366acd6c7c29c67ae3aa675bc918da Mon Sep 17 00:00:00 2001 From: Kwanghoon Son Date: Mon, 18 Sep 2023 04:51:25 +0000 Subject: [PATCH 3/6] riscv: dts: Add th1520 reset device tree Add reset device tree for th1520 SoC Signed-off-by: Kwanghoon Son --- arch/riscv/boot/dts/thead/th1520.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/riscv/boot/dts/thead/th1520.dtsi b/arch/riscv/boot/dts/thead/th1520.dtsi index c8e425de61439..8f467c551b632 100644 --- a/arch/riscv/boot/dts/thead/th1520.dtsi +++ b/arch/riscv/boot/dts/thead/th1520.dtsi @@ -12,6 +12,7 @@ #include #include #include +#include / { compatible = "thead,th1520"; @@ -852,5 +853,11 @@ #clock-cells = <1>; status = "okay"; }; + + rst: reset-controller@ffef014000 { + compatible = "thead,th1520-reset", "syscon"; + reg = <0xff 0xef014000 0x0 0x1000>; + #reset-cells = <1>; + }; }; }; From ef7cbab9c300fbaa35496946164678bfe7f16dbd Mon Sep 17 00:00:00 2001 From: tingming Date: Mon, 27 May 2024 10:33:51 +0800 Subject: [PATCH 4/6] reset: th1520: to support npu/fce reset feature --- arch/riscv/boot/dts/thead/th1520.dtsi | 8 +++++ drivers/reset/reset-th1520.c | 33 +++++++++++++++++-- .../dt-bindings/reset/thead,th1520-reset.h | 4 +++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/arch/riscv/boot/dts/thead/th1520.dtsi b/arch/riscv/boot/dts/thead/th1520.dtsi index 8f467c551b632..4496c51053d46 100644 --- a/arch/riscv/boot/dts/thead/th1520.dtsi +++ b/arch/riscv/boot/dts/thead/th1520.dtsi @@ -858,6 +858,14 @@ compatible = "thead,th1520-reset", "syscon"; reg = <0xff 0xef014000 0x0 0x1000>; #reset-cells = <1>; + status = "okay"; + }; + + vpsys_rst: vpsys-reset-controller@ffecc30000 { + compatible = "thead,th1520-vpsys-reset","syscon"; + reg = <0xff 0xecc30000 0x0 0x1000>; + #reset-cells = <1>; + status = "okay"; }; }; }; diff --git a/drivers/reset/reset-th1520.c b/drivers/reset/reset-th1520.c index 5a89d201fc0c1..63f1f04f6ccc2 100644 --- a/drivers/reset/reset-th1520.c +++ b/drivers/reset/reset-th1520.c @@ -11,6 +11,11 @@ struct th1520_rst_signal { unsigned int offset, bit; }; +struct th1520_rst_variant { + const struct th1520_rst_signal *signals; + unsigned int signals_num; +}; + struct th1520_rst { struct reset_controller_dev rcdev; struct regmap *regmap; @@ -20,6 +25,11 @@ struct th1520_rst { enum th1520_rst_registers { RST_WDT0 = 0x0034, RST_WDT1 = 0x0038, + RST_NPU = 0x01b0, +}; + +enum th1520_vpsys_rst_registers { + RST_FCE = 0x0004, }; static int th1520_reset_update(struct th1520_rst *rst, unsigned long id, @@ -34,6 +44,11 @@ static int th1520_reset_update(struct th1520_rst *rst, unsigned long id, static const struct th1520_rst_signal th1520_rst_signals[] = { [TH1520_RESET_WDT0] = { RST_WDT0, BIT(0) }, [TH1520_RESET_WDT1] = { RST_WDT1, BIT(0) }, + [TH1520_RESET_NPU] = { RST_NPU, BIT(0) }, +}; + +static const struct th1520_rst_signal th1520_vpsys_rst_signals[] = { + [TH1520_RESET_FCE] = { RST_FCE, BIT(0)|BIT(1)|BIT(4)|BIT(5) }, }; static struct th1520_rst *to_th1520_rst(struct reset_controller_dev *rcdev) @@ -68,17 +83,28 @@ static const struct reset_control_ops th1520_rst_ops = { .deassert = th1520_reset_deassert, }; +static const struct th1520_rst_variant variant_th1520 = { + .signals = th1520_rst_signals, + .signals_num = ARRAY_SIZE(th1520_rst_signals), +}; + +static const struct th1520_rst_variant variant_th1520_vpsys = { + .signals = th1520_vpsys_rst_signals, + .signals_num = ARRAY_SIZE(th1520_vpsys_rst_signals), +}; + static int th1520_reset_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct th1520_rst *rst; struct regmap_config config = { .name = "rst" }; + const struct th1520_rst_variant *variant = of_device_get_match_data(dev); rst = devm_kzalloc(dev, sizeof(*rst), GFP_KERNEL); if (!rst) return -ENOMEM; - rst->signals = th1520_rst_signals; + rst->signals = variant->signals; rst->regmap = syscon_node_to_regmap(dev->of_node); if (IS_ERR(rst->regmap)) return PTR_ERR(rst->regmap); @@ -89,13 +115,14 @@ static int th1520_reset_probe(struct platform_device *pdev) rst->rcdev.dev = dev; rst->rcdev.of_node = dev->of_node; rst->rcdev.ops = &th1520_rst_ops; - rst->rcdev.nr_resets = ARRAY_SIZE(th1520_rst_signals); + rst->rcdev.nr_resets = variant->signals_num; return devm_reset_controller_register(dev, &rst->rcdev); } static const struct of_device_id th1520_reset_dt_ids[] = { - { .compatible = "thead,th1520-reset" }, + { .compatible = "thead,th1520-reset", .data = &variant_th1520 }, + { .compatible = "thead,th1520-vpsys-reset", .data = &variant_th1520_vpsys }, { /* sentinel */ }, }; diff --git a/include/dt-bindings/reset/thead,th1520-reset.h b/include/dt-bindings/reset/thead,th1520-reset.h index ec10751814e56..19476bf389829 100644 --- a/include/dt-bindings/reset/thead,th1520-reset.h +++ b/include/dt-bindings/reset/thead,th1520-reset.h @@ -5,5 +5,9 @@ #define TH1520_RESET_WDT0 0 #define TH1520_RESET_WDT1 1 +#define TH1520_RESET_NPU 2 + +// vpsys reset +#define TH1520_RESET_FCE 100 #endif From 687f9e200353da29c746431c2474836dec9cf51d Mon Sep 17 00:00:00 2001 From: minghq Date: Mon, 27 May 2024 12:05:13 +0800 Subject: [PATCH 5/6] Update thead,th1520-reset.yaml --- Documentation/devicetree/bindings/reset/thead,th1520-reset.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/reset/thead,th1520-reset.yaml b/Documentation/devicetree/bindings/reset/thead,th1520-reset.yaml index 49ea8c6a331f6..b868c174b4fa7 100644 --- a/Documentation/devicetree/bindings/reset/thead,th1520-reset.yaml +++ b/Documentation/devicetree/bindings/reset/thead,th1520-reset.yaml @@ -8,6 +8,7 @@ title: T-HEAD th1520 SoC Reset Controller maintainers: - Kwanghoon Son + - Hengqiang Ming properties: compatible: From e05981b902956bfabc4bf1553a3c3c4258599b40 Mon Sep 17 00:00:00 2001 From: minghq Date: Mon, 27 May 2024 12:08:00 +0800 Subject: [PATCH 6/6] Update reset-th1520.c --- drivers/reset/reset-th1520.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/reset/reset-th1520.c b/drivers/reset/reset-th1520.c index 63f1f04f6ccc2..fb9e74ff4c83b 100644 --- a/drivers/reset/reset-th1520.c +++ b/drivers/reset/reset-th1520.c @@ -134,3 +134,7 @@ static struct platform_driver th1520_reset_driver = { }, }; builtin_platform_driver(th1520_reset_driver); + +MODULE_AUTHOR("zenglinghui.zlh "); +MODULE_DESCRIPTION("Thead th1520 reset driver"); +MODULE_LICENSE("GPL v2");