From 08ab70ec4fede1dd058f93b13332fc7c911ff4df Mon Sep 17 00:00:00 2001 From: Wu Jinyong Date: Tue, 5 Nov 2024 09:13:48 +0800 Subject: [PATCH 1/2] dt-bindings:reset: Add bindings for phytium reset controller. This patch documents the DT binding for the Phytium reset drivers. Signed-off-by: Wu Jinyong Signed-off-by: Wang Yinfeng Signed-off-by: Malloy Liu --- .../bindings/reset/phytium,reset.yaml | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/reset/phytium,reset.yaml diff --git a/Documentation/devicetree/bindings/reset/phytium,reset.yaml b/Documentation/devicetree/bindings/reset/phytium,reset.yaml new file mode 100644 index 000000000000..82171da5f5e9 --- /dev/null +++ b/Documentation/devicetree/bindings/reset/phytium,reset.yaml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +title: Phytium Reset Controller +====================================== + +This binding describes a reset-controller for Phytium SoCs. + +Required properties: +- compatible: + Usage: required + Value type: + Definition: must be: + "phytium,reset" + +- reg: + Usage: required + Value type: + Definition: must specify the base address and size of the register + space. + +- #reset-cells: + Usage: required + Value type: + Definition: must be 1; cell entry represents the reset index. + +Example: + +reset: reset@2807e000 { + compatible = "phytium,reset"; + reg = <0x0 0x2807e000 0x0 0x10>; + #reset-cells = <1>; +}; + +Specifying reset lines connected to IP modules +============================================== + +Device nodes that need access to reset lines should +specify them as a reset phandle in their corresponding node. + +Example: + +i2c0: i2c@28011000 { + ... + + resets = <&reset 0>; + + ... +}; -- Gitee From bca7f943c6ab4d88a0d1d1f9f5e8e2847a362a86 Mon Sep 17 00:00:00 2001 From: Wu Jinyong Date: Tue, 5 Nov 2024 09:16:47 +0800 Subject: [PATCH 2/2] reset:phytium: Add the driver for reset controller. This patch adds the driver for phytium reset controller. Signed-off-by: Wu Jinyong Signed-off-by: Wang Yinfeng Signed-off-by: Malloy Liu --- drivers/reset/Kconfig | 8 +++ drivers/reset/Makefile | 1 + drivers/reset/reset-phytium.c | 130 ++++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 drivers/reset/reset-phytium.c diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index ecb28ede9a6c..749d3425ef27 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -292,6 +292,14 @@ config RESET_TN48M_CPLD This driver can also be built as a module. If so, the module will be called reset-tn48m. +config RESET_PHYTIUM + bool "PHYTIUM Reset Driver" + default ARCH_PHYTIUM + help + This enables the reset driver for phytium SoCs. If you wish + to use the reset framework for such memory-mapped devices, + say Y here. Otherwise, say N. + 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 9222d045b874..72e2b2a54091 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o 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_PHYTIUM) += reset-phytium.o obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o obj-$(CONFIG_RESET_SUNPLUS) += reset-sunplus.o obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o diff --git a/drivers/reset/reset-phytium.c b/drivers/reset/reset-phytium.c new file mode 100644 index 000000000000..bdb907beafb0 --- /dev/null +++ b/drivers/reset/reset-phytium.c @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Phytium Reset Driver. + * + * Copyright (c) 2024, Phytium Technology Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RESET_PHYTIUM_DRV_VERSION "1.0.0" + +#define PHYTIUM_RESET_MAX_CNTS (19) +#define PHYTIUM_I2C_RESET_ID0 (3) +#define PHYTIUM_RESET_OFFSET_0 (0) +#define PHYTIUM_RESET_OFFSET_1 (4) + +struct reset_phytium_dev { + void __iomem *base; + struct device *dev; + struct reset_controller_dev rcdev; +}; + +struct reset_reg_info { + u32 reg_offset; + u32 data; +}; + +static struct reset_reg_info reset_mng[PHYTIUM_RESET_MAX_CNTS] = { + {PHYTIUM_RESET_OFFSET_0, (u32)BIT(28)}, + {PHYTIUM_RESET_OFFSET_0, (u32)BIT(29)}, + {PHYTIUM_RESET_OFFSET_0, (u32)BIT(30)}, + {PHYTIUM_RESET_OFFSET_1, (u32)BIT(16)}, + {PHYTIUM_RESET_OFFSET_1, (u32)BIT(17)}, + {PHYTIUM_RESET_OFFSET_1, (u32)BIT(18)}, + {PHYTIUM_RESET_OFFSET_1, (u32)BIT(19)}, + {PHYTIUM_RESET_OFFSET_1, (u32)BIT(20)}, + {PHYTIUM_RESET_OFFSET_1, (u32)BIT(21)}, + {PHYTIUM_RESET_OFFSET_1, (u32)BIT(22)}, + {PHYTIUM_RESET_OFFSET_1, (u32)BIT(23)}, + {PHYTIUM_RESET_OFFSET_1, (u32)BIT(24)}, + {PHYTIUM_RESET_OFFSET_1, (u32)BIT(25)}, + {PHYTIUM_RESET_OFFSET_1, (u32)BIT(26)}, + {PHYTIUM_RESET_OFFSET_1, (u32)BIT(27)}, + {PHYTIUM_RESET_OFFSET_1, (u32)BIT(28)}, + {PHYTIUM_RESET_OFFSET_1, (u32)BIT(29)}, + {PHYTIUM_RESET_OFFSET_1, (u32)BIT(30)}, + {PHYTIUM_RESET_OFFSET_1, (u32)BIT(31)} + }; + +static inline struct reset_phytium_dev * +to_reset_phytium_data(struct reset_controller_dev *rcdev) +{ + return container_of(rcdev, struct reset_phytium_dev, rcdev); +} + +static int reset_phytium_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct reset_phytium_dev *rdev = to_reset_phytium_data(rcdev); + u32 reg_val, reset_reg_val; + + if (id >= PHYTIUM_RESET_MAX_CNTS) { + dev_err(rdev->dev, "The reset id is out of range %ld\n", id); + return -EINVAL; + } + + reg_val = readl_relaxed(rdev->base + reset_mng[id].reg_offset); + reset_reg_val = reg_val; + reg_val &= ~reset_mng[id].data; + writel_relaxed(reg_val, rdev->base + reset_mng[id].reg_offset); + writel_relaxed(reset_reg_val, rdev->base + reset_mng[id].reg_offset); + + return 0; +} + +const struct reset_control_ops reset_phytium_ops = { + .reset = reset_phytium_reset, +}; +EXPORT_SYMBOL_GPL(reset_phytium_ops); + +static const struct of_device_id reset_phytium_dt_ids[] = { + { .compatible = "phytium,reset", }, + { /* sentinel */ }, +}; + +static int reset_phytium_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct reset_phytium_dev *rdev; + struct resource *res; + + rdev = devm_kzalloc(dev, sizeof(*rdev), GFP_KERNEL); + if (!rdev) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + rdev->base = devm_ioremap_resource(dev, res); + if (IS_ERR(rdev->base)) + return PTR_ERR(rdev->base); + + rdev->rcdev.owner = THIS_MODULE; + rdev->rcdev.nr_resets = PHYTIUM_RESET_MAX_CNTS; + rdev->rcdev.ops = &reset_phytium_ops; + rdev->rcdev.of_node = dev->of_node; + rdev->dev = &pdev->dev; + + return devm_reset_controller_register(dev, &rdev->rcdev); +} + +static struct platform_driver reset_phytium_driver = { + .probe = reset_phytium_probe, + .driver = { + .name = "phytium-reset", + .of_match_table = reset_phytium_dt_ids, + }, +}; +builtin_platform_driver(reset_phytium_driver); + +MODULE_AUTHOR("Wu Jinyong "); +MODULE_DESCRIPTION("Phytium reset"); +MODULE_LICENSE("GPL"); -- Gitee