From 3c2968fcd72c4b130894d1a2b835e18474c559e2 Mon Sep 17 00:00:00 2001 From: Junhui Liu Date: Fri, 13 Jun 2025 16:49:23 +0800 Subject: [PATCH 01/10] dt-bindings: reset: add support for canaan,k230-rst Introduces a reset controller driver for the Kendryte K230 SoC, resposible for managing the reset functionality of the CPUs and various sub-modules. Reviewed-by: Conor Dooley Reviewed-by: Chen Wang Signed-off-by: Junhui Liu Link: https://lore.kernel.org/r/20250613-k230-reset-v4-1-e5266d2be440@pigmoral.tech Signed-off-by: Philipp Zabel --- .../bindings/reset/canaan,k230-rst.yaml | 39 ++++++++ include/dt-bindings/reset/canaan,k230-rst.h | 90 +++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 Documentation/devicetree/bindings/reset/canaan,k230-rst.yaml create mode 100644 include/dt-bindings/reset/canaan,k230-rst.h diff --git a/Documentation/devicetree/bindings/reset/canaan,k230-rst.yaml b/Documentation/devicetree/bindings/reset/canaan,k230-rst.yaml new file mode 100644 index 000000000000..d352d0e12d81 --- /dev/null +++ b/Documentation/devicetree/bindings/reset/canaan,k230-rst.yaml @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/reset/canaan,k230-rst.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Canaan Kendryte K230 Reset Controller + +maintainers: + - Junhui Liu + +description: + The Canaan Kendryte K230 reset controller is part of the SoC's system + controller and controls the reset registers for CPUs and various peripherals. + +properties: + compatible: + const: canaan,k230-rst + + reg: + maxItems: 1 + + '#reset-cells': + const: 1 + +required: + - compatible + - reg + - '#reset-cells' + +additionalProperties: false + +examples: + - | + reset-controller@91101000 { + compatible = "canaan,k230-rst"; + reg = <0x91101000 0x1000>; + #reset-cells = <1>; + }; diff --git a/include/dt-bindings/reset/canaan,k230-rst.h b/include/dt-bindings/reset/canaan,k230-rst.h new file mode 100644 index 000000000000..e4f6612607fe --- /dev/null +++ b/include/dt-bindings/reset/canaan,k230-rst.h @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) 2023-2024 Canaan Bright Sight Co., Ltd + * Copyright (C) 2024-2025 Junhui Liu + */ +#ifndef _DT_BINDINGS_CANAAN_K230_RST_H_ +#define _DT_BINDINGS_CANAAN_K230_RST_H_ + +#define RST_CPU0 0 +#define RST_CPU1 1 +#define RST_CPU0_FLUSH 2 +#define RST_CPU1_FLUSH 3 +#define RST_AI 4 +#define RST_VPU 5 +#define RST_HISYS 6 +#define RST_HISYS_AHB 7 +#define RST_SDIO0 8 +#define RST_SDIO1 9 +#define RST_SDIO_AXI 10 +#define RST_USB0 11 +#define RST_USB1 12 +#define RST_USB0_AHB 13 +#define RST_USB1_AHB 14 +#define RST_SPI0 15 +#define RST_SPI1 16 +#define RST_SPI2 17 +#define RST_SEC 18 +#define RST_PDMA 19 +#define RST_SDMA 20 +#define RST_DECOMPRESS 21 +#define RST_SRAM 22 +#define RST_SHRM_AXIM 23 +#define RST_SHRM_AXIS 24 +#define RST_NONAI2D 25 +#define RST_MCTL 26 +#define RST_ISP 27 +#define RST_ISP_DW 28 +#define RST_DPU 29 +#define RST_DISP 30 +#define RST_GPU 31 +#define RST_AUDIO 32 +#define RST_TIMER0 33 +#define RST_TIMER1 34 +#define RST_TIMER2 35 +#define RST_TIMER3 36 +#define RST_TIMER4 37 +#define RST_TIMER5 38 +#define RST_TIMER_APB 39 +#define RST_HDI 40 +#define RST_WDT0 41 +#define RST_WDT1 42 +#define RST_WDT0_APB 43 +#define RST_WDT1_APB 44 +#define RST_TS_APB 45 +#define RST_MAILBOX 46 +#define RST_STC 47 +#define RST_PMU 48 +#define RST_LOSYS_APB 49 +#define RST_UART0 50 +#define RST_UART1 51 +#define RST_UART2 52 +#define RST_UART3 53 +#define RST_UART4 54 +#define RST_I2C0 55 +#define RST_I2C1 56 +#define RST_I2C2 57 +#define RST_I2C3 58 +#define RST_I2C4 59 +#define RST_JAMLINK0_APB 60 +#define RST_JAMLINK1_APB 61 +#define RST_JAMLINK2_APB 62 +#define RST_JAMLINK3_APB 63 +#define RST_CODEC_APB 64 +#define RST_GPIO_DB 65 +#define RST_GPIO_APB 66 +#define RST_ADC 67 +#define RST_ADC_APB 68 +#define RST_PWM_APB 69 +#define RST_SHRM_APB 70 +#define RST_CSI0 71 +#define RST_CSI1 72 +#define RST_CSI2 73 +#define RST_CSI_DPHY 74 +#define RST_ISP_AHB 75 +#define RST_M0 76 +#define RST_M1 77 +#define RST_M2 78 +#define RST_SPI2AXI 79 + +#endif From 360a7a64775944e3a784cb2e3cffb15af5f328e5 Mon Sep 17 00:00:00 2001 From: Junhui Liu Date: Fri, 13 Jun 2025 16:49:24 +0800 Subject: [PATCH 02/10] reset: canaan: add reset driver for Kendryte K230 Add support for the resets on Canaan Kendryte K230 SoC. The driver support CPU0, CPU1, L2 cache flush, hardware auto clear and software clear resets. Tested-by: Chen Wang Reviewed-by: Philipp Zabel Signed-off-by: Junhui Liu Link: https://lore.kernel.org/r/20250613-k230-reset-v4-2-e5266d2be440@pigmoral.tech Signed-off-by: Philipp Zabel --- drivers/reset/Kconfig | 9 + drivers/reset/Makefile | 1 + drivers/reset/reset-k230.c | 371 +++++++++++++++++++++++++++++++++++++ 3 files changed, 381 insertions(+) create mode 100644 drivers/reset/reset-k230.c diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index d85be5899da6..4649c72e9b6e 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -140,6 +140,15 @@ config RESET_K210 Say Y if you want to control reset signals provided by this controller. +config RESET_K230 + tristate "Reset controller driver for Canaan Kendryte K230 SoC" + depends on ARCH_CANAAN || COMPILE_TEST + depends on OF + help + Support for the Canaan Kendryte K230 RISC-V SoC reset controller. + Say Y if you want to control reset signals provided by this + controller. + config RESET_LANTIQ bool "Lantiq XWAY Reset Driver" if COMPILE_TEST default SOC_TYPE_XWAY diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 91e6348e3351..82488dac0f35 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_RESET_IMX7) += reset-imx7.o obj-$(CONFIG_RESET_IMX8MP_AUDIOMIX) += reset-imx8mp-audiomix.o obj-$(CONFIG_RESET_INTEL_GW) += reset-intel-gw.o obj-$(CONFIG_RESET_K210) += reset-k210.o +obj-$(CONFIG_RESET_K230) += reset-k230.o obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o obj-$(CONFIG_RESET_MCHP_SPARX5) += reset-microchip-sparx5.o diff --git a/drivers/reset/reset-k230.c b/drivers/reset/reset-k230.c new file mode 100644 index 000000000000..c81045bb4a14 --- /dev/null +++ b/drivers/reset/reset-k230.c @@ -0,0 +1,371 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2022-2024 Canaan Bright Sight Co., Ltd + * Copyright (C) 2024-2025 Junhui Liu + * + * The reset management module in the K230 SoC provides reset time control + * registers. For RST_TYPE_CPU0, RST_TYPE_CPU1 and RST_TYPE_SW_DONE, the period + * during which reset is applied or removed while the clock is stopped can be + * set up to 15 * 0.25 = 3.75 µs. For RST_TYPE_HW_DONE, that period can be set + * up to 255 * 0.25 = 63.75 µs. For RST_TYPE_FLUSH, the reset bit is + * automatically cleared by hardware when flush completes. + * + * Although this driver does not configure the reset time registers, delays have + * been added to the assert, deassert, and reset operations to cover the maximum + * reset time. Some reset types include done bits whose toggle does not + * unambiguously signal whether hardware reset removal or clock-stop period + * expiration occurred first. Delays are therefore retained for types with done + * bits to ensure safe timing. + * + * Reference: K230 Technical Reference Manual V0.3.1 + * https://kendryte-download.canaan-creative.com/developer/k230/HDK/K230%E7%A1%AC%E4%BB%B6%E6%96%87%E6%A1%A3/K230_Technical_Reference_Manual_V0.3.1_20241118.pdf + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + * enum k230_rst_type - K230 reset types + * @RST_TYPE_CPU0: Reset type for CPU0 + * Automatically clears, has write enable and done bit, active high + * @RST_TYPE_CPU1: Reset type for CPU1 + * Manually clears, has write enable and done bit, active high + * @RST_TYPE_FLUSH: Reset type for CPU L2 cache flush + * Automatically clears, has write enable, no done bit, active high + * @RST_TYPE_HW_DONE: Reset type for hardware auto clear + * Automatically clears, no write enable, has done bit, active high + * @RST_TYPE_SW_DONE: Reset type for software manual clear + * Manually clears, no write enable and done bit, + * active high if ID is RST_SPI2AXI, otherwise active low + */ +enum k230_rst_type { + RST_TYPE_CPU0, + RST_TYPE_CPU1, + RST_TYPE_FLUSH, + RST_TYPE_HW_DONE, + RST_TYPE_SW_DONE, +}; + +struct k230_rst_map { + u32 offset; + enum k230_rst_type type; + u32 done; + u32 reset; +}; + +struct k230_rst { + struct reset_controller_dev rcdev; + void __iomem *base; + /* protect register read-modify-write */ + spinlock_t lock; +}; + +static const struct k230_rst_map k230_resets[] = { + [RST_CPU0] = { 0x4, RST_TYPE_CPU0, BIT(12), BIT(0) }, + [RST_CPU1] = { 0xc, RST_TYPE_CPU1, BIT(12), BIT(0) }, + [RST_CPU0_FLUSH] = { 0x4, RST_TYPE_FLUSH, 0, BIT(4) }, + [RST_CPU1_FLUSH] = { 0xc, RST_TYPE_FLUSH, 0, BIT(4) }, + [RST_AI] = { 0x14, RST_TYPE_HW_DONE, BIT(31), BIT(0) }, + [RST_VPU] = { 0x1c, RST_TYPE_HW_DONE, BIT(31), BIT(0) }, + [RST_HISYS] = { 0x2c, RST_TYPE_HW_DONE, BIT(4), BIT(0) }, + [RST_HISYS_AHB] = { 0x2c, RST_TYPE_HW_DONE, BIT(5), BIT(1) }, + [RST_SDIO0] = { 0x34, RST_TYPE_HW_DONE, BIT(28), BIT(0) }, + [RST_SDIO1] = { 0x34, RST_TYPE_HW_DONE, BIT(29), BIT(1) }, + [RST_SDIO_AXI] = { 0x34, RST_TYPE_HW_DONE, BIT(30), BIT(2) }, + [RST_USB0] = { 0x3c, RST_TYPE_HW_DONE, BIT(28), BIT(0) }, + [RST_USB1] = { 0x3c, RST_TYPE_HW_DONE, BIT(29), BIT(1) }, + [RST_USB0_AHB] = { 0x3c, RST_TYPE_HW_DONE, BIT(30), BIT(0) }, + [RST_USB1_AHB] = { 0x3c, RST_TYPE_HW_DONE, BIT(31), BIT(1) }, + [RST_SPI0] = { 0x44, RST_TYPE_HW_DONE, BIT(28), BIT(0) }, + [RST_SPI1] = { 0x44, RST_TYPE_HW_DONE, BIT(29), BIT(1) }, + [RST_SPI2] = { 0x44, RST_TYPE_HW_DONE, BIT(30), BIT(2) }, + [RST_SEC] = { 0x4c, RST_TYPE_HW_DONE, BIT(31), BIT(0) }, + [RST_PDMA] = { 0x54, RST_TYPE_HW_DONE, BIT(28), BIT(0) }, + [RST_SDMA] = { 0x54, RST_TYPE_HW_DONE, BIT(29), BIT(1) }, + [RST_DECOMPRESS] = { 0x5c, RST_TYPE_HW_DONE, BIT(31), BIT(0) }, + [RST_SRAM] = { 0x64, RST_TYPE_HW_DONE, BIT(28), BIT(0) }, + [RST_SHRM_AXIM] = { 0x64, RST_TYPE_HW_DONE, BIT(30), BIT(2) }, + [RST_SHRM_AXIS] = { 0x64, RST_TYPE_HW_DONE, BIT(31), BIT(3) }, + [RST_NONAI2D] = { 0x6c, RST_TYPE_HW_DONE, BIT(31), BIT(0) }, + [RST_MCTL] = { 0x74, RST_TYPE_HW_DONE, BIT(31), BIT(0) }, + [RST_ISP] = { 0x80, RST_TYPE_HW_DONE, BIT(29), BIT(6) }, + [RST_ISP_DW] = { 0x80, RST_TYPE_HW_DONE, BIT(28), BIT(5) }, + [RST_DPU] = { 0x88, RST_TYPE_HW_DONE, BIT(31), BIT(0) }, + [RST_DISP] = { 0x90, RST_TYPE_HW_DONE, BIT(31), BIT(0) }, + [RST_GPU] = { 0x98, RST_TYPE_HW_DONE, BIT(31), BIT(0) }, + [RST_AUDIO] = { 0xa4, RST_TYPE_HW_DONE, BIT(31), BIT(0) }, + [RST_TIMER0] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(0) }, + [RST_TIMER1] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(1) }, + [RST_TIMER2] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(2) }, + [RST_TIMER3] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(3) }, + [RST_TIMER4] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(4) }, + [RST_TIMER5] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(5) }, + [RST_TIMER_APB] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(6) }, + [RST_HDI] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(7) }, + [RST_WDT0] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(12) }, + [RST_WDT1] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(13) }, + [RST_WDT0_APB] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(14) }, + [RST_WDT1_APB] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(15) }, + [RST_TS_APB] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(16) }, + [RST_MAILBOX] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(17) }, + [RST_STC] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(18) }, + [RST_PMU] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(19) }, + [RST_LOSYS_APB] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(0) }, + [RST_UART0] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(1) }, + [RST_UART1] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(2) }, + [RST_UART2] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(3) }, + [RST_UART3] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(4) }, + [RST_UART4] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(5) }, + [RST_I2C0] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(6) }, + [RST_I2C1] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(7) }, + [RST_I2C2] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(8) }, + [RST_I2C3] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(9) }, + [RST_I2C4] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(10) }, + [RST_JAMLINK0_APB] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(11) }, + [RST_JAMLINK1_APB] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(12) }, + [RST_JAMLINK2_APB] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(13) }, + [RST_JAMLINK3_APB] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(14) }, + [RST_CODEC_APB] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(17) }, + [RST_GPIO_DB] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(18) }, + [RST_GPIO_APB] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(19) }, + [RST_ADC] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(20) }, + [RST_ADC_APB] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(21) }, + [RST_PWM_APB] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(22) }, + [RST_SHRM_APB] = { 0x64, RST_TYPE_SW_DONE, 0, BIT(1) }, + [RST_CSI0] = { 0x80, RST_TYPE_SW_DONE, 0, BIT(0) }, + [RST_CSI1] = { 0x80, RST_TYPE_SW_DONE, 0, BIT(1) }, + [RST_CSI2] = { 0x80, RST_TYPE_SW_DONE, 0, BIT(2) }, + [RST_CSI_DPHY] = { 0x80, RST_TYPE_SW_DONE, 0, BIT(3) }, + [RST_ISP_AHB] = { 0x80, RST_TYPE_SW_DONE, 0, BIT(4) }, + [RST_M0] = { 0x80, RST_TYPE_SW_DONE, 0, BIT(7) }, + [RST_M1] = { 0x80, RST_TYPE_SW_DONE, 0, BIT(8) }, + [RST_M2] = { 0x80, RST_TYPE_SW_DONE, 0, BIT(9) }, + [RST_SPI2AXI] = { 0xa8, RST_TYPE_SW_DONE, 0, BIT(0) } +}; + +static inline struct k230_rst *to_k230_rst(struct reset_controller_dev *rcdev) +{ + return container_of(rcdev, struct k230_rst, rcdev); +} + +static void k230_rst_clear_done(struct k230_rst *rstc, unsigned long id, + bool write_en) +{ + const struct k230_rst_map *rmap = &k230_resets[id]; + u32 reg; + + guard(spinlock_irqsave)(&rstc->lock); + + reg = readl(rstc->base + rmap->offset); + reg |= rmap->done; /* write 1 to clear */ + if (write_en) + reg |= rmap->done << 16; + writel(reg, rstc->base + rmap->offset); +} + +static int k230_rst_wait_and_clear_done(struct k230_rst *rstc, unsigned long id, + bool write_en) +{ + const struct k230_rst_map *rmap = &k230_resets[id]; + u32 reg; + int ret; + + ret = readl_poll_timeout(rstc->base + rmap->offset, reg, + reg & rmap->done, 10, 1000); + if (ret) { + dev_err(rstc->rcdev.dev, "Wait for reset done timeout\n"); + return ret; + } + + k230_rst_clear_done(rstc, id, write_en); + + return 0; +} + +static void k230_rst_update(struct k230_rst *rstc, unsigned long id, + bool assert, bool write_en, bool active_low) +{ + const struct k230_rst_map *rmap = &k230_resets[id]; + u32 reg; + + guard(spinlock_irqsave)(&rstc->lock); + + reg = readl(rstc->base + rmap->offset); + if (assert ^ active_low) + reg |= rmap->reset; + else + reg &= ~rmap->reset; + if (write_en) + reg |= rmap->reset << 16; + writel(reg, rstc->base + rmap->offset); +} + +static int k230_rst_assert(struct reset_controller_dev *rcdev, unsigned long id) +{ + struct k230_rst *rstc = to_k230_rst(rcdev); + + switch (k230_resets[id].type) { + case RST_TYPE_CPU1: + k230_rst_update(rstc, id, true, true, false); + break; + case RST_TYPE_SW_DONE: + k230_rst_update(rstc, id, true, false, + id == RST_SPI2AXI ? false : true); + break; + case RST_TYPE_CPU0: + case RST_TYPE_FLUSH: + case RST_TYPE_HW_DONE: + return -EOPNOTSUPP; + } + + /* + * The time period when reset is applied but the clock is stopped for + * RST_TYPE_CPU1 and RST_TYPE_SW_DONE can be set up to 3.75us. Delay + * 10us to ensure proper reset timing. + */ + udelay(10); + + return 0; +} + +static int k230_rst_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct k230_rst *rstc = to_k230_rst(rcdev); + int ret = 0; + + switch (k230_resets[id].type) { + case RST_TYPE_CPU1: + k230_rst_update(rstc, id, false, true, false); + ret = k230_rst_wait_and_clear_done(rstc, id, true); + break; + case RST_TYPE_SW_DONE: + k230_rst_update(rstc, id, false, false, + id == RST_SPI2AXI ? false : true); + break; + case RST_TYPE_CPU0: + case RST_TYPE_FLUSH: + case RST_TYPE_HW_DONE: + return -EOPNOTSUPP; + } + + /* + * The time period when reset is removed but the clock is stopped for + * RST_TYPE_CPU1 and RST_TYPE_SW_DONE can be set up to 3.75us. Delay + * 10us to ensure proper reset timing. + */ + udelay(10); + + return ret; +} + +static int k230_rst_reset(struct reset_controller_dev *rcdev, unsigned long id) +{ + struct k230_rst *rstc = to_k230_rst(rcdev); + const struct k230_rst_map *rmap = &k230_resets[id]; + u32 reg; + int ret = 0; + + switch (rmap->type) { + case RST_TYPE_CPU0: + k230_rst_clear_done(rstc, id, true); + k230_rst_update(rstc, id, true, true, false); + ret = k230_rst_wait_and_clear_done(rstc, id, true); + + /* + * The time period when reset is applied and removed but the + * clock is stopped for RST_TYPE_CPU0 can be set up to 7.5us. + * Delay 10us to ensure proper reset timing. + */ + udelay(10); + + break; + case RST_TYPE_FLUSH: + k230_rst_update(rstc, id, true, true, false); + + /* Wait flush request bit auto cleared by hardware */ + ret = readl_poll_timeout(rstc->base + rmap->offset, reg, + !(reg & rmap->reset), 10, 1000); + if (ret) + dev_err(rcdev->dev, "Wait for flush done timeout\n"); + + break; + case RST_TYPE_HW_DONE: + k230_rst_clear_done(rstc, id, false); + k230_rst_update(rstc, id, true, false, false); + ret = k230_rst_wait_and_clear_done(rstc, id, false); + + /* + * The time period when reset is applied and removed but the + * clock is stopped for RST_TYPE_HW_DONE can be set up to + * 127.5us. Delay 200us to ensure proper reset timing. + */ + fsleep(200); + + break; + case RST_TYPE_CPU1: + case RST_TYPE_SW_DONE: + k230_rst_assert(rcdev, id); + ret = k230_rst_deassert(rcdev, id); + break; + } + + return ret; +} + +static const struct reset_control_ops k230_rst_ops = { + .reset = k230_rst_reset, + .assert = k230_rst_assert, + .deassert = k230_rst_deassert, +}; + +static int k230_rst_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct k230_rst *rstc; + + rstc = devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL); + if (!rstc) + return -ENOMEM; + + rstc->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(rstc->base)) + return PTR_ERR(rstc->base); + + spin_lock_init(&rstc->lock); + + rstc->rcdev.dev = dev; + rstc->rcdev.owner = THIS_MODULE; + rstc->rcdev.ops = &k230_rst_ops; + rstc->rcdev.nr_resets = ARRAY_SIZE(k230_resets); + rstc->rcdev.of_node = dev->of_node; + + return devm_reset_controller_register(dev, &rstc->rcdev); +} + +static const struct of_device_id k230_rst_match[] = { + { .compatible = "canaan,k230-rst", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, k230_rst_match); + +static struct platform_driver k230_rst_driver = { + .probe = k230_rst_probe, + .driver = { + .name = "k230-rst", + .of_match_table = k230_rst_match, + } +}; +module_platform_driver(k230_rst_driver); + +MODULE_AUTHOR("Junhui Liu "); +MODULE_DESCRIPTION("Canaan K230 reset driver"); +MODULE_LICENSE("GPL"); From e73bfb4ca5229e09b20bd6b4543308b9a71f9426 Mon Sep 17 00:00:00 2001 From: Drew Fustini Date: Sun, 1 Jun 2025 11:08:26 -0700 Subject: [PATCH 03/10] reset: thead: Fix TH1520 typo Fix trivial typo in the Kconfig entry for RESET_TH1520. Fixes: 4a65326311ab ("reset: thead: Add TH1520 reset controller driver") Signed-off-by: Drew Fustini Link: https://lore.kernel.org/r/20250601181000.166088-1-drew@pdp7.com Signed-off-by: Philipp Zabel --- drivers/reset/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 4649c72e9b6e..e2cf29e742d0 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -296,7 +296,7 @@ config RESET_SUNXI This enables the reset driver for Allwinner SoCs. config RESET_TH1520 - tristate "T-HEAD 1520 reset controller" + tristate "T-HEAD TH1520 reset controller" depends on ARCH_THEAD || COMPILE_TEST select REGMAP_MMIO help From 25ef956349a5c439f4dec30fb207ed3b7d586e14 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Mon, 2 Jun 2025 10:40:45 -0400 Subject: [PATCH 04/10] dt-bindings: reset: convert nxp,lpc1850-rgu.txt to yaml format Convert nxp,lpc1850-rgu.txt to yaml format. Additional changes: - remove label in example. - remove reset consumer in example. Signed-off-by: Frank Li Reviewed-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20250602144046.943982-1-Frank.Li@nxp.com Signed-off-by: Philipp Zabel --- .../bindings/reset/nxp,lpc1850-rgu.txt | 83 -------------- .../bindings/reset/nxp,lpc1850-rgu.yaml | 101 ++++++++++++++++++ 2 files changed, 101 insertions(+), 83 deletions(-) delete mode 100644 Documentation/devicetree/bindings/reset/nxp,lpc1850-rgu.txt create mode 100644 Documentation/devicetree/bindings/reset/nxp,lpc1850-rgu.yaml diff --git a/Documentation/devicetree/bindings/reset/nxp,lpc1850-rgu.txt b/Documentation/devicetree/bindings/reset/nxp,lpc1850-rgu.txt deleted file mode 100644 index 05d5be48dae4..000000000000 --- a/Documentation/devicetree/bindings/reset/nxp,lpc1850-rgu.txt +++ /dev/null @@ -1,83 +0,0 @@ -NXP LPC1850 Reset Generation Unit (RGU) -======================================== - -Please also refer to reset.txt in this directory for common reset -controller binding usage. - -Required properties: -- compatible: Should be "nxp,lpc1850-rgu" -- reg: register base and length -- clocks: phandle and clock specifier to RGU clocks -- clock-names: should contain "delay" and "reg" -- #reset-cells: should be 1 - -See table below for valid peripheral reset numbers. Numbers not -in the table below are either reserved or not applicable for -normal operation. - -Reset Peripheral - 9 System control unit (SCU) - 12 ARM Cortex-M0 subsystem core (LPC43xx only) - 13 CPU core - 16 LCD controller - 17 USB0 - 18 USB1 - 19 DMA - 20 SDIO - 21 External memory controller (EMC) - 22 Ethernet - 25 Flash bank A - 27 EEPROM - 28 GPIO - 29 Flash bank B - 32 Timer0 - 33 Timer1 - 34 Timer2 - 35 Timer3 - 36 Repetitive Interrupt timer (RIT) - 37 State Configurable Timer (SCT) - 38 Motor control PWM (MCPWM) - 39 QEI - 40 ADC0 - 41 ADC1 - 42 DAC - 44 USART0 - 45 UART1 - 46 USART2 - 47 USART3 - 48 I2C0 - 49 I2C1 - 50 SSP0 - 51 SSP1 - 52 I2S0 and I2S1 - 53 Serial Flash Interface (SPIFI) - 54 C_CAN1 - 55 C_CAN0 - 56 ARM Cortex-M0 application core (LPC4370 only) - 57 SGPIO (LPC43xx only) - 58 SPI (LPC43xx only) - 60 ADCHS (12-bit ADC) (LPC4370 only) - -Refer to NXP LPC18xx or LPC43xx user manual for more details about -the reset signals and the connected block/peripheral. - -Reset provider example: -rgu: reset-controller@40053000 { - compatible = "nxp,lpc1850-rgu"; - reg = <0x40053000 0x1000>; - clocks = <&cgu BASE_SAFE_CLK>, <&ccu1 CLK_CPU_BUS>; - clock-names = "delay", "reg"; - #reset-cells = <1>; -}; - -Reset consumer example: -mac: ethernet@40010000 { - compatible = "nxp,lpc1850-dwmac", "snps,dwmac-3.611", "snps,dwmac"; - reg = <0x40010000 0x2000>; - interrupts = <5>; - interrupt-names = "macirq"; - clocks = <&ccu1 CLK_CPU_ETHERNET>; - clock-names = "stmmaceth"; - resets = <&rgu 22>; - reset-names = "stmmaceth"; -}; diff --git a/Documentation/devicetree/bindings/reset/nxp,lpc1850-rgu.yaml b/Documentation/devicetree/bindings/reset/nxp,lpc1850-rgu.yaml new file mode 100644 index 000000000000..9c3c13c543c7 --- /dev/null +++ b/Documentation/devicetree/bindings/reset/nxp,lpc1850-rgu.yaml @@ -0,0 +1,101 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/reset/nxp,lpc1850-rgu.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP LPC1850 Reset Generation Unit (RGU) + +maintainers: + - Frank Li + +properties: + compatible: + const: nxp,lpc1850-rgu + + reg: + maxItems: 1 + + clocks: + maxItems: 2 + + clock-names: + items: + - const: delay + - const: reg + + '#reset-cells': + const: 1 + description: | + See table below for valid peripheral reset numbers. Numbers not + in the table below are either reserved or not applicable for + normal operation. + + Reset Peripheral + 9 System control unit (SCU) + 12 ARM Cortex-M0 subsystem core (LPC43xx only) + 13 CPU core + 16 LCD controller + 17 USB0 + 18 USB1 + 19 DMA + 20 SDIO + 21 External memory controller (EMC) + 22 Ethernet + 25 Flash bank A + 27 EEPROM + 28 GPIO + 29 Flash bank B + 32 Timer0 + 33 Timer1 + 34 Timer2 + 35 Timer3 + 36 Repetitive Interrupt timer (RIT) + 37 State Configurable Timer (SCT) + 38 Motor control PWM (MCPWM) + 39 QEI + 40 ADC0 + 41 ADC1 + 42 DAC + 44 USART0 + 45 UART1 + 46 USART2 + 47 USART3 + 48 I2C0 + 49 I2C1 + 50 SSP0 + 51 SSP1 + 52 I2S0 and I2S1 + 53 Serial Flash Interface (SPIFI) + 54 C_CAN1 + 55 C_CAN0 + 56 ARM Cortex-M0 application core (LPC4370 only) + 57 SGPIO (LPC43xx only) + 58 SPI (LPC43xx only) + 60 ADCHS (12-bit ADC) (LPC4370 only) + + Refer to NXP LPC18xx or LPC43xx user manual for more details about + the reset signals and the connected block/peripheral. + +required: + - compatible + - reg + - clocks + - clock-names + - '#reset-cells' + +additionalProperties: false + +examples: + - | + #include + #include + + reset-controller@40053000 { + compatible = "nxp,lpc1850-rgu"; + reg = <0x40053000 0x1000>; + clocks = <&cgu BASE_SAFE_CLK>, <&ccu1 CLK_CPU_BUS>; + clock-names = "delay", "reg"; + #reset-cells = <1>; + }; + From fd4a06a2e1661893c5353f8b01bf6ae44cbe094d Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Wed, 28 May 2025 14:30:31 +0100 Subject: [PATCH 05/10] dt-bindings: reset: renesas,rzv2h-usb2phy: Document RZ/V2N SoC support Document support for the USB2PHY reset controller found on the Renesas RZ/V2N (R9A09G056) SoC. The reset controller IP is functionally identical to that on the RZ/V2H(P) SoC, so no driver changes are needed. The existing `renesas,r9a09g057-usb2phy-reset` compatible will be used as a fallback for the RZ/V2N SoC. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Acked-by: Conor Dooley Link: https://lore.kernel.org/r/20250528133031.167647-1-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Philipp Zabel --- .../bindings/reset/renesas,rzv2h-usb2phy-reset.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml b/Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml index c79f61c2373b..c1b800a10b53 100644 --- a/Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml +++ b/Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml @@ -15,7 +15,12 @@ description: properties: compatible: - const: renesas,r9a09g057-usb2phy-reset # RZ/V2H(P) + oneOf: + - items: + - const: renesas,r9a09g056-usb2phy-reset # RZ/V2N + - const: renesas,r9a09g057-usb2phy-reset + + - const: renesas,r9a09g057-usb2phy-reset # RZ/V2H(P) reg: maxItems: 1 From 9d33595c022763822a01889708d0ed24c59fa144 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Wed, 11 Jun 2025 12:06:04 +0200 Subject: [PATCH 06/10] reset: mpfs: use the auxiliary device creation The auxiliary device creation of this driver is simple enough to use the available auxiliary device creation helper. Use it and remove some boilerplate code. Acked-by: Conor Dooley Reviewed-by: Philipp Zabel Signed-off-by: Jerome Brunet Link: https://lore.kernel.org/r/20250611-rst-mpfs-aux-v1-1-c86534b473c3@baylibre.com Signed-off-by: Philipp Zabel --- drivers/reset/reset-mpfs.c | 56 ++++---------------------------------- 1 file changed, 5 insertions(+), 51 deletions(-) diff --git a/drivers/reset/reset-mpfs.c b/drivers/reset/reset-mpfs.c index 574e59db83a4..f6fa10e03ea8 100644 --- a/drivers/reset/reset-mpfs.c +++ b/drivers/reset/reset-mpfs.c @@ -155,62 +155,16 @@ static int mpfs_reset_probe(struct auxiliary_device *adev, return devm_reset_controller_register(dev, rcdev); } -static void mpfs_reset_unregister_adev(void *_adev) -{ - struct auxiliary_device *adev = _adev; - - auxiliary_device_delete(adev); - auxiliary_device_uninit(adev); -} - -static void mpfs_reset_adev_release(struct device *dev) -{ - struct auxiliary_device *adev = to_auxiliary_dev(dev); - - kfree(adev); -} - -static struct auxiliary_device *mpfs_reset_adev_alloc(struct device *clk_dev) -{ - struct auxiliary_device *adev; - int ret; - - adev = kzalloc(sizeof(*adev), GFP_KERNEL); - if (!adev) - return ERR_PTR(-ENOMEM); - - adev->name = "reset-mpfs"; - adev->dev.parent = clk_dev; - adev->dev.release = mpfs_reset_adev_release; - adev->id = 666u; - - ret = auxiliary_device_init(adev); - if (ret) { - kfree(adev); - return ERR_PTR(ret); - } - - return adev; -} - int mpfs_reset_controller_register(struct device *clk_dev, void __iomem *base) { struct auxiliary_device *adev; - int ret; - adev = mpfs_reset_adev_alloc(clk_dev); - if (IS_ERR(adev)) - return PTR_ERR(adev); + adev = devm_auxiliary_device_create(clk_dev, "reset-mpfs", + (__force void *)base); + if (!adev) + return -ENODEV; - ret = auxiliary_device_add(adev); - if (ret) { - auxiliary_device_uninit(adev); - return ret; - } - - adev->dev.platform_data = (__force void *)base; - - return devm_add_action_or_reset(clk_dev, mpfs_reset_unregister_adev, adev); + return 0; } EXPORT_SYMBOL_NS_GPL(mpfs_reset_controller_register, "MCHP_CLK_MPFS"); From 5a5c61f7ef967edac4e88a645f08b5889e824cf0 Mon Sep 17 00:00:00 2001 From: Inochi Amaoto Date: Tue, 17 Jun 2025 15:01:39 +0800 Subject: [PATCH 07/10] dt-bindings: reset: sophgo: Add CV1800B support Add bindings for the reset generator on the SOPHGO CV1800B RISC-V SoC. Signed-off-by: Inochi Amaoto Acked-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20250617070144.1149926-2-inochiama@gmail.com Signed-off-by: Philipp Zabel --- .../devicetree/bindings/reset/sophgo,sg2042-reset.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/reset/sophgo,sg2042-reset.yaml b/Documentation/devicetree/bindings/reset/sophgo,sg2042-reset.yaml index 1d1b84575960..08d28313b870 100644 --- a/Documentation/devicetree/bindings/reset/sophgo,sg2042-reset.yaml +++ b/Documentation/devicetree/bindings/reset/sophgo,sg2042-reset.yaml @@ -16,7 +16,9 @@ properties: - enum: - sophgo,sg2044-reset - const: sophgo,sg2042-reset - - const: sophgo,sg2042-reset + - enum: + - sophgo,cv1800b-reset + - sophgo,sg2042-reset reg: maxItems: 1 From 811fe8ad1db9b5e2fb20c2610f35e3a364bef620 Mon Sep 17 00:00:00 2001 From: Inochi Amaoto Date: Tue, 17 Jun 2025 15:01:40 +0800 Subject: [PATCH 08/10] reset: simple: add support for Sophgo CV1800B Reuse reset-simple driver for the Sophgo CV1800B reset generator. Signed-off-by: Inochi Amaoto Reviewed-by: Alexander Sverdlin Tested-by: Alexander Sverdlin Link: https://lore.kernel.org/r/20250617070144.1149926-3-inochiama@gmail.com Signed-off-by: Philipp Zabel --- drivers/reset/reset-simple.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/reset/reset-simple.c b/drivers/reset/reset-simple.c index 276067839830..79e94ecfe4f5 100644 --- a/drivers/reset/reset-simple.c +++ b/drivers/reset/reset-simple.c @@ -151,6 +151,8 @@ static const struct of_device_id reset_simple_dt_ids[] = { { .compatible = "snps,dw-high-reset" }, { .compatible = "snps,dw-low-reset", .data = &reset_simple_active_low }, + { .compatible = "sophgo,cv1800b-reset", + .data = &reset_simple_active_low }, { .compatible = "sophgo,sg2042-reset", .data = &reset_simple_active_low }, { /* sentinel */ }, From 1d99f92f71b6b4b2eee776562c991428490f71ef Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Mon, 30 Jun 2025 18:52:58 +0100 Subject: [PATCH 09/10] reset: brcmstb: Enable reset drivers for ARCH_BCM2835 The BRCMSTB and BRCMSTB_RESCAL reset drivers are also used in the BCM2712, AKA the RPi5. The RPi platforms have typically used the ARCH_BCM2835, and the PCIe support for this SoC can use this config which depends on these drivers so enable building them when just that arch option is enabled to ensure the platform works as expected. Signed-off-by: Peter Robinson Acked-by: Florian Fainelli Link: https://lore.kernel.org/r/20250630175301.846082-1-pbrobinson@gmail.com Signed-off-by: Philipp Zabel --- drivers/reset/Kconfig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index e2cf29e742d0..ba4bb07309a1 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -51,8 +51,8 @@ config RESET_BERLIN config RESET_BRCMSTB tristate "Broadcom STB reset controller" - depends on ARCH_BRCMSTB || COMPILE_TEST - default ARCH_BRCMSTB + depends on ARCH_BRCMSTB || ARCH_BCM2835 || COMPILE_TEST + default ARCH_BRCMSTB || ARCH_BCM2835 help This enables the reset controller driver for Broadcom STB SoCs using a SUN_TOP_CTRL_SW_INIT style controller. @@ -60,11 +60,11 @@ config RESET_BRCMSTB config RESET_BRCMSTB_RESCAL tristate "Broadcom STB RESCAL reset controller" depends on HAS_IOMEM - depends on ARCH_BRCMSTB || COMPILE_TEST - default ARCH_BRCMSTB + depends on ARCH_BRCMSTB || ARCH_BCM2835 || COMPILE_TEST + default ARCH_BRCMSTB || ARCH_BCM2835 help This enables the RESCAL reset controller for SATA, PCIe0, or PCIe1 on - BCM7216. + BCM7216 or the BCM2712. config RESET_EYEQ bool "Mobileye EyeQ reset controller" From 196dbace08243bbd4639cdb3d8ec655b2da361bd Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Wed, 2 Jul 2025 17:26:08 -0500 Subject: [PATCH 10/10] dt-bindings: reset: Convert snps,dw-reset to DT schema Convert the Synopsys Designware Reset Controller binding to schema. It is a straight forward conversion. Signed-off-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20250702222609.2760718-1-robh@kernel.org Signed-off-by: Philipp Zabel --- .../bindings/reset/snps,dw-reset.txt | 30 -------------- .../bindings/reset/snps,dw-reset.yaml | 39 +++++++++++++++++++ 2 files changed, 39 insertions(+), 30 deletions(-) delete mode 100644 Documentation/devicetree/bindings/reset/snps,dw-reset.txt create mode 100644 Documentation/devicetree/bindings/reset/snps,dw-reset.yaml diff --git a/Documentation/devicetree/bindings/reset/snps,dw-reset.txt b/Documentation/devicetree/bindings/reset/snps,dw-reset.txt deleted file mode 100644 index 0c241d4aae76..000000000000 --- a/Documentation/devicetree/bindings/reset/snps,dw-reset.txt +++ /dev/null @@ -1,30 +0,0 @@ -Synopsys DesignWare Reset controller -======================================= - -Please also refer to reset.txt in this directory for common reset -controller binding usage. - -Required properties: - -- compatible: should be one of the following. - "snps,dw-high-reset" - for active high configuration - "snps,dw-low-reset" - for active low configuration - -- reg: physical base address of the controller and length of memory mapped - region. - -- #reset-cells: must be 1. - -example: - - dw_rst_1: reset-controller@0000 { - compatible = "snps,dw-high-reset"; - reg = <0x0000 0x4>; - #reset-cells = <1>; - }; - - dw_rst_2: reset-controller@1000 { - compatible = "snps,dw-low-reset"; - reg = <0x1000 0x8>; - #reset-cells = <1>; - }; diff --git a/Documentation/devicetree/bindings/reset/snps,dw-reset.yaml b/Documentation/devicetree/bindings/reset/snps,dw-reset.yaml new file mode 100644 index 000000000000..1dde7b6e8623 --- /dev/null +++ b/Documentation/devicetree/bindings/reset/snps,dw-reset.yaml @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/reset/snps,dw-reset.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Synopsys DesignWare Reset controller + +maintainers: + - Philipp Zabel + +properties: + compatible: + enum: + - snps,dw-high-reset + - snps,dw-low-reset + + reg: + maxItems: 1 + + '#reset-cells': + const: 1 + + reset-controller: true + +required: + - compatible + - reg + - '#reset-cells' + +additionalProperties: false + +examples: + - | + reset-controller@0 { + compatible = "snps,dw-high-reset"; + reg = <0x0000 0x4>; + #reset-cells = <1>; + };