diff options
Diffstat (limited to 'drivers/reset')
| -rw-r--r-- | drivers/reset/Kconfig | 7 | ||||
| -rw-r--r-- | drivers/reset/Makefile | 2 | ||||
| -rw-r--r-- | drivers/reset/reset-spacemit-k1.c | 548 | ||||
| -rw-r--r-- | drivers/reset/spacemit/Makefile | 5 | ||||
| -rw-r--r-- | drivers/reset/spacemit/reset-spacemit-k1.c | 289 |
5 files changed, 295 insertions, 556 deletions
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index c851354c7a5..db764ed5ace 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -279,12 +279,5 @@ config RESET_RZG2L_USBPHY_CTRL RZ/G2L SoC. This is required for USB 2.0 functionality to work on this SoC. -config RESET_SPACEMIT_K1 - bool "Support for SPACEMIT's K1 Reset driver" - depends on DM_RESET - help - Support for SPACEMIT's K1 Reset system. Basic Assert/Deassert - is supported. - source "drivers/reset/stm32/Kconfig" endmenu diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 3fce96509cd..384f4336331 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -37,7 +37,7 @@ obj-$(CONFIG_RESET_DRA7) += reset-dra7.o obj-$(CONFIG_RESET_AT91) += reset-at91.o obj-$(CONFIG_$(PHASE_)RESET_JH7110) += reset-jh7110.o obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o -obj-$(CONFIG_RESET_SPACEMIT_K1) += reset-spacemit-k1.o +obj-$(CONFIG_CLK_SPACEMIT_K1) += spacemit/ obj-$(CONFIG_ARCH_STM32) += stm32/ obj-$(CONFIG_ARCH_STM32MP) += stm32/ diff --git a/drivers/reset/reset-spacemit-k1.c b/drivers/reset/reset-spacemit-k1.c deleted file mode 100644 index 613e002fc4f..00000000000 --- a/drivers/reset/reset-spacemit-k1.c +++ /dev/null @@ -1,548 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2022 Spacemit Inc. - * Copyright (C) 2025 Huan Zhou <[email protected]> - */ - -#include <asm/io.h> -#include <config.h> -#include <dm.h> -#include <dm/device_compat.h> -#include <dm/device-internal.h> -#include <dm/lists.h> -#include <dt-bindings/reset/spacemit-k1-reset.h> -#include <linux/bitops.h> -#include <reset-uclass.h> - -/* APBC register offset */ -#define APBC_UART1_CLK_RST 0x0 -#define APBC_UART2_CLK_RST 0x4 -#define APBC_GPIO_CLK_RST 0x8 -#define APBC_PWM0_CLK_RST 0xc -#define APBC_PWM1_CLK_RST 0x10 -#define APBC_PWM2_CLK_RST 0x14 -#define APBC_PWM3_CLK_RST 0x18 -#define APBC_TWSI8_CLK_RST 0x20 -#define APBC_UART3_CLK_RST 0x24 -#define APBC_RTC_CLK_RST 0x28 -#define APBC_TWSI0_CLK_RST 0x2c -#define APBC_TWSI1_CLK_RST 0x30 -#define APBC_TIMERS1_CLK_RST 0x34 -#define APBC_TWSI2_CLK_RST 0x38 -#define APBC_AIB_CLK_RST 0x3c -#define APBC_TWSI4_CLK_RST 0x40 -#define APBC_TIMERS2_CLK_RST 0x44 -#define APBC_ONEWIRE_CLK_RST 0x48 -#define APBC_TWSI5_CLK_RST 0x4c -#define APBC_DRO_CLK_RST 0x58 -#define APBC_IR_CLK_RST 0x5c -#define APBC_TWSI6_CLK_RST 0x60 -#define APBC_TWSI7_CLK_RST 0x68 -#define APBC_TSEN_CLK_RST 0x6c - -#define APBC_UART4_CLK_RST 0x70 -#define APBC_UART5_CLK_RST 0x74 -#define APBC_UART6_CLK_RST 0x78 -#define APBC_SSP3_CLK_RST 0x7c - -#define APBC_SSPA0_CLK_RST 0x80 -#define APBC_SSPA1_CLK_RST 0x84 - -#define APBC_IPC_AP2AUD_CLK_RST 0x90 -#define APBC_UART7_CLK_RST 0x94 -#define APBC_UART8_CLK_RST 0x98 -#define APBC_UART9_CLK_RST 0x9c - -#define APBC_CAN0_CLK_RST 0xa0 -#define APBC_PWM4_CLK_RST 0xa8 -#define APBC_PWM5_CLK_RST 0xac -#define APBC_PWM6_CLK_RST 0xb0 -#define APBC_PWM7_CLK_RST 0xb4 -#define APBC_PWM8_CLK_RST 0xb8 -#define APBC_PWM9_CLK_RST 0xbc -#define APBC_PWM10_CLK_RST 0xc0 -#define APBC_PWM11_CLK_RST 0xc4 -#define APBC_PWM12_CLK_RST 0xc8 -#define APBC_PWM13_CLK_RST 0xcc -#define APBC_PWM14_CLK_RST 0xd0 -#define APBC_PWM15_CLK_RST 0xd4 -#define APBC_PWM16_CLK_RST 0xd8 -#define APBC_PWM17_CLK_RST 0xdc -#define APBC_PWM18_CLK_RST 0xe0 -#define APBC_PWM19_CLK_RST 0xe4 -/* end of APBC register offset */ - -/* MPMU register offset */ -#define MPMU_WDTPCR 0x200 -/* end of MPMU register offset */ - -/* APMU register offset */ -#define APMU_JPG_CLK_RES_CTRL 0x20 -#define APMU_CSI_CCIC2_CLK_RES_CTRL 0x24 -#define APMU_ISP_CLK_RES_CTRL 0x38 -#define APMU_LCD_CLK_RES_CTRL1 0x44 -#define APMU_LCD_SPI_CLK_RES_CTRL 0x48 -#define APMU_LCD_CLK_RES_CTRL2 0x4c -#define APMU_CCIC_CLK_RES_CTRL 0x50 -#define APMU_SDH0_CLK_RES_CTRL 0x54 -#define APMU_SDH1_CLK_RES_CTRL 0x58 -#define APMU_USB_CLK_RES_CTRL 0x5c -#define APMU_QSPI_CLK_RES_CTRL 0x60 -#define APMU_USB_CLK_RES_CTRL 0x5c -#define APMU_DMA_CLK_RES_CTRL 0x64 -#define APMU_AES_CLK_RES_CTRL 0x68 -#define APMU_VPU_CLK_RES_CTRL 0xa4 -#define APMU_GPU_CLK_RES_CTRL 0xcc -#define APMU_SDH2_CLK_RES_CTRL 0xe0 -#define APMU_PMUA_MC_CTRL 0xe8 -#define APMU_PMU_CC2_AP 0x100 -#define APMU_PMUA_EM_CLK_RES_CTRL 0x104 - -#define APMU_AUDIO_CLK_RES_CTRL 0x14c -#define APMU_HDMI_CLK_RES_CTRL 0x1B8 - -#define APMU_PCIE_CLK_RES_CTRL_0 0x3cc -#define APMU_PCIE_CLK_RES_CTRL_1 0x3d4 -#define APMU_PCIE_CLK_RES_CTRL_2 0x3dc - -#define APMU_EMAC0_CLK_RES_CTRL 0x3e4 -#define APMU_EMAC1_CLK_RES_CTRL 0x3ec -/* end of APMU register offset */ - -/* APBC2 register offset */ -#define APBC2_UART1_CLK_RST 0x00 -#define APBC2_SSP2_CLK_RST 0x04 -#define APBC2_TWSI3_CLK_RST 0x08 -#define APBC2_RTC_CLK_RST 0x0c -#define APBC2_TIMERS0_CLK_RST 0x10 -#define APBC2_KPC_CLK_RST 0x14 -#define APBC2_GPIO_CLK_RST 0x1c -/* end of APBC2 register offset */ - -enum spacemit_reset_base_type { - RST_BASE_TYPE_MPMU = 0, - RST_BASE_TYPE_APMU = 1, - RST_BASE_TYPE_APBC = 2, - RST_BASE_TYPE_APBS = 3, - RST_BASE_TYPE_CIU = 4, - RST_BASE_TYPE_DCIU = 5, - RST_BASE_TYPE_DDRC = 6, - RST_BASE_TYPE_AUDC = 7, - RST_BASE_TYPE_APBC2 = 8, -}; - -struct spacemit_reset_signal { - u32 offset; - u32 mask; - u32 deassert_val; - u32 assert_val; - enum spacemit_reset_base_type type; -}; - -struct spacemit_reset_base { - void __iomem *mpmu_base; - void __iomem *apmu_base; - void __iomem *apbc_base; - void __iomem *apbs_base; - void __iomem *ciu_base; - void __iomem *dciu_base; - void __iomem *ddrc_base; - void __iomem *audio_ctrl_base; - void __iomem *apbc2_base; -}; - -struct spacemit_reset { - struct spacemit_reset_base io_base; - const struct spacemit_reset_signal *signals; -}; - -enum { - RESET_TWSI6_SPL = 0, - RESET_TWSI8_SPL, - RESET_SDH_AXI_SPL, - RESET_SDH0_SPL, - RESET_USB_AXI_SPL, - RESET_USBP1_AXI_SPL, - RESET_USB3_0_SPL, - RESET_QSPI_SPL, - RESET_QSPI_BUS_SPL, - RESET_AES_SPL, - RESET_SDH2_SPL, - RESET_NUMBER_SPL -}; - -static const struct spacemit_reset_signal - k1_reset_signals[RESET_NUMBER] = { - [RESET_UART1] = { APBC_UART1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_UART2] = { APBC_UART2_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_GPIO] = { APBC_GPIO_CLK_RST, BIT(2), 0, - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_PWM0] = { APBC_PWM0_CLK_RST, - BIT(2) | BIT(0), - BIT(0), - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_PWM1] = { APBC_PWM1_CLK_RST, - BIT(2) | BIT(0), - BIT(0), - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_PWM2] = { APBC_PWM2_CLK_RST, - BIT(2) | BIT(0), - BIT(0), - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_PWM3] = { APBC_PWM3_CLK_RST, - BIT(2) | BIT(0), - BIT(0), - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_PWM4] = { APBC_PWM4_CLK_RST, - BIT(2) | BIT(0), - BIT(0), - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_PWM5] = { APBC_PWM5_CLK_RST, - BIT(2) | BIT(0), - BIT(0), - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_PWM6] = { APBC_PWM6_CLK_RST, - BIT(2) | BIT(0), - BIT(0), - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_PWM7] = { APBC_PWM7_CLK_RST, - BIT(2) | BIT(0), - BIT(0), - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_PWM8] = { APBC_PWM8_CLK_RST, - BIT(2) | BIT(0), - BIT(0), - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_PWM9] = { APBC_PWM9_CLK_RST, - BIT(2) | BIT(0), - BIT(0), - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_PWM10] = { APBC_PWM10_CLK_RST, - BIT(2) | BIT(0), - BIT(0), - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_PWM11] = { APBC_PWM11_CLK_RST, - BIT(2) | BIT(0), - BIT(0), - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_PWM12] = { APBC_PWM12_CLK_RST, - BIT(2) | BIT(0), - BIT(0), - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_PWM13] = { APBC_PWM13_CLK_RST, - BIT(2) | BIT(0), - BIT(0), - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_PWM14] = { APBC_PWM14_CLK_RST, - BIT(2) | BIT(0), - BIT(0), - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_PWM15] = { APBC_PWM15_CLK_RST, - BIT(2) | BIT(0), - BIT(0), - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_PWM16] = { APBC_PWM16_CLK_RST, - BIT(2) | BIT(0), - BIT(0), - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_PWM17] = { APBC_PWM17_CLK_RST, - BIT(2) | BIT(0), - BIT(0), - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_PWM18] = { APBC_PWM18_CLK_RST, - BIT(2) | BIT(0), - BIT(0), - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_PWM19] = { APBC_PWM19_CLK_RST, - BIT(2) | BIT(0), - BIT(0), - BIT(2), - RST_BASE_TYPE_APBC }, - [RESET_SSP3] = { APBC_SSP3_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_UART3] = { APBC_UART3_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_RTC] = { APBC_RTC_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_TWSI0] = { APBC_TWSI0_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_TIMERS1] = { APBC_TIMERS1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_AIB] = { APBC_AIB_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_TIMERS2] = { APBC_TIMERS2_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_ONEWIRE] = { APBC_ONEWIRE_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_SSPA0] = { APBC_SSPA0_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_SSPA1] = { APBC_SSPA1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_DRO] = { APBC_DRO_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_IR] = { APBC_IR_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_TWSI1] = { APBC_TWSI1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_TSEN] = { APBC_TSEN_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_TWSI2] = { APBC_TWSI2_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_TWSI4] = { APBC_TWSI4_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_TWSI5] = { APBC_TWSI5_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_TWSI6] = { APBC_TWSI6_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_TWSI7] = { APBC_TWSI7_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_TWSI8] = { APBC_TWSI8_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_IPC_AP2AUD] = { APBC_IPC_AP2AUD_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_UART4] = { APBC_UART4_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_UART5] = { APBC_UART5_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_UART6] = { APBC_UART6_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_UART7] = { APBC_UART7_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_UART8] = { APBC_UART8_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_UART9] = { APBC_UART9_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - [RESET_CAN0] = { APBC_CAN0_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, - /* MPMU */ - [RESET_WDT] = { MPMU_WDTPCR, BIT(2), 0, BIT(2), RST_BASE_TYPE_MPMU }, - /* APMU */ - [RESET_JPG] = { APMU_JPG_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU }, - [RESET_CSI] = { APMU_CSI_CCIC2_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU }, - [RESET_CCIC2_PHY] = { APMU_CSI_CCIC2_CLK_RES_CTRL, - BIT(2), - BIT(2), - 0, - RST_BASE_TYPE_APMU }, - [RESET_CCIC3_PHY] = { APMU_CSI_CCIC2_CLK_RES_CTRL, - BIT(29), - BIT(29), - 0, - RST_BASE_TYPE_APMU }, - [RESET_ISP] = { APMU_ISP_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU }, - [RESET_ISP_AHB] = { APMU_ISP_CLK_RES_CTRL, BIT(3), BIT(3), 0, RST_BASE_TYPE_APMU }, - [RESET_ISP_CI] = { APMU_ISP_CLK_RES_CTRL, BIT(16), BIT(16), 0, RST_BASE_TYPE_APMU }, - [RESET_ISP_CPP] = { APMU_ISP_CLK_RES_CTRL, BIT(27), BIT(27), 0, RST_BASE_TYPE_APMU }, - [RESET_LCD] = { APMU_LCD_CLK_RES_CTRL1, BIT(4), BIT(4), 0, RST_BASE_TYPE_APMU }, - [RESET_DSI_ESC] = { APMU_LCD_CLK_RES_CTRL1, BIT(3), BIT(3), 0, RST_BASE_TYPE_APMU }, - [RESET_V2D] = { APMU_LCD_CLK_RES_CTRL1, BIT(27), BIT(27), 0, RST_BASE_TYPE_APMU }, - [RESET_MIPI] = { APMU_LCD_CLK_RES_CTRL1, BIT(15), BIT(15), 0, RST_BASE_TYPE_APMU }, - [RESET_LCD_SPI] = { APMU_LCD_SPI_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU }, - [RESET_LCD_SPI_BUS] = { APMU_LCD_SPI_CLK_RES_CTRL, - BIT(4), - BIT(4), - 0, - RST_BASE_TYPE_APMU }, - [RESET_LCD_SPI_HBUS] = { APMU_LCD_SPI_CLK_RES_CTRL, - BIT(2), - BIT(2), - 0, - RST_BASE_TYPE_APMU }, - [RESET_LCD_MCLK] = { APMU_LCD_CLK_RES_CTRL2, BIT(9), BIT(9), 0, RST_BASE_TYPE_APMU }, - [RESET_CCIC_4X] = { APMU_CCIC_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU }, - [RESET_CCIC1_PHY] = { APMU_CCIC_CLK_RES_CTRL, BIT(2), BIT(2), 0, RST_BASE_TYPE_APMU }, - [RESET_SDH_AXI] = { APMU_SDH0_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU }, - [RESET_SDH0] = { APMU_SDH0_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU }, - [RESET_SDH1] = { APMU_SDH1_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU }, - [RESET_USB_AXI] = { APMU_USB_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU }, - [RESET_USBP1_AXI] = { APMU_USB_CLK_RES_CTRL, BIT(4), BIT(4), 0, RST_BASE_TYPE_APMU }, - [RESET_USB3_0] = { APMU_USB_CLK_RES_CTRL, - BIT(9) | BIT(10) | BIT(11), - BIT(9) | BIT(10) | BIT(11), - 0, - RST_BASE_TYPE_APMU }, - [RESET_QSPI] = { APMU_QSPI_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU }, - [RESET_QSPI_BUS] = { APMU_QSPI_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU }, - [RESET_DMA] = { APMU_DMA_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU }, - [RESET_AES] = { APMU_AES_CLK_RES_CTRL, BIT(4), BIT(4), 0, RST_BASE_TYPE_APMU }, - [RESET_VPU] = { APMU_VPU_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU }, - [RESET_GPU] = { APMU_GPU_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU }, - [RESET_SDH2] = { APMU_SDH2_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU }, - [RESET_MC] = { APMU_PMUA_MC_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU }, - [RESET_EM_AXI] = { APMU_PMUA_EM_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU }, - [RESET_EM] = { APMU_PMUA_EM_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU }, - [RESET_AUDIO_SYS] = { APMU_AUDIO_CLK_RES_CTRL, - BIT(0) | BIT(2) | BIT(3), - BIT(0) | BIT(2) | BIT(3), - 0, - RST_BASE_TYPE_APMU }, - [RESET_HDMI] = { APMU_HDMI_CLK_RES_CTRL, BIT(9), BIT(9), 0, RST_BASE_TYPE_APMU }, - [RESET_PCIE0] = { APMU_PCIE_CLK_RES_CTRL_0, - BIT(3) | BIT(4) | BIT(5) | BIT(8), - BIT(3) | BIT(4) | BIT(5), - BIT(8), - RST_BASE_TYPE_APMU }, - [RESET_PCIE1] = { APMU_PCIE_CLK_RES_CTRL_1, - BIT(3) | BIT(4) | BIT(5) | BIT(8), - BIT(3) | BIT(4) | BIT(5), - BIT(8), - RST_BASE_TYPE_APMU }, - [RESET_PCIE2] = { APMU_PCIE_CLK_RES_CTRL_2, 0x138, 0x38, 0x100, RST_BASE_TYPE_APMU }, - [RESET_EMAC0] = { APMU_EMAC0_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU }, - [RESET_EMAC1] = { APMU_EMAC1_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU }, - [RESET_SEC_UART1] = { APBC2_UART1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 }, - [RESET_SEC_SSP2] = { APBC2_SSP2_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 }, - [RESET_SEC_TWSI3] = { APBC2_TWSI3_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 }, - [RESET_SEC_RTC] = { APBC2_RTC_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 }, - [RESET_SEC_TIMERS0] = { APBC2_TIMERS0_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 }, - [RESET_SEC_KPC] = { APBC2_KPC_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 }, - [RESET_SEC_GPIO] = { APBC2_GPIO_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 }, - }; - -static u32 spacemit_reset_read(struct spacemit_reset *reset, u32 id) -{ - void __iomem *base; - - switch (reset->signals[id].type) { - case RST_BASE_TYPE_APMU: - base = reset->io_base.apmu_base; - break; - case RST_BASE_TYPE_APBC: - base = reset->io_base.apbc_base; - break; - default: - base = reset->io_base.apbc_base; - break; - } - - return readl(base + reset->signals[id].offset); -} - -static void spacemit_reset_write(struct spacemit_reset *reset, u32 value, u32 id) -{ - void __iomem *base; - - switch (reset->signals[id].type) { - case RST_BASE_TYPE_APMU: - base = reset->io_base.apmu_base; - break; - case RST_BASE_TYPE_APBC: - base = reset->io_base.apbc_base; - break; - default: - base = reset->io_base.apbc_base; - break; - } - - writel(value, base + reset->signals[id].offset); -} - -static void spacemit_reset_set(struct reset_ctl *rst, u32 id, bool assert) -{ - u32 value; - struct spacemit_reset *reset = dev_get_priv(rst->dev); - - value = spacemit_reset_read(reset, id); - - if (assert) { - value &= ~reset->signals[id].mask; - value |= reset->signals[id].assert_val; - } else { - value &= ~reset->signals[id].mask; - value |= reset->signals[id].deassert_val; - } - - spacemit_reset_write(reset, value, id); -} - -static int spacemit_reset_update(struct reset_ctl *rst, bool assert) -{ - if (rst->id < RESET_UART1 || rst->id >= RESET_NUMBER) - return 0; - - /* can not write to twsi8 */ - if (rst->id == RESET_TWSI8) - return 0; - - spacemit_reset_set(rst, rst->id, assert); - return 0; -} - -static int spacemit_reset_assert(struct reset_ctl *rst) -{ - return spacemit_reset_update(rst, true); -} - -static int spacemit_reset_deassert(struct reset_ctl *rst) -{ - return spacemit_reset_update(rst, false); -} - -static int spacemit_k1_reset_probe(struct udevice *dev) -{ - struct spacemit_reset *reset = dev_get_priv(dev); - - reset->io_base.mpmu_base = (void *)dev_remap_addr_index(dev, 0); - if (!reset->io_base.mpmu_base) { - pr_err("failed to map mpmu registers\n"); - goto out; - } - - reset->io_base.apmu_base = (void *)dev_remap_addr_index(dev, 1); - if (!reset->io_base.apmu_base) { - pr_err("failed to map apmu registers\n"); - goto out; - } - - reset->io_base.apbc_base = (void *)dev_remap_addr_index(dev, 2); - if (!reset->io_base.apbc_base) { - pr_err("failed to map apbc registers\n"); - goto out; - } - - reset->io_base.apbs_base = (void *)dev_remap_addr_index(dev, 3); - if (!reset->io_base.apbs_base) { - pr_err("failed to map apbs registers\n"); - goto out; - } - - reset->io_base.ciu_base = (void *)dev_remap_addr_index(dev, 4); - if (!reset->io_base.ciu_base) { - pr_err("failed to map ciu registers\n"); - goto out; - } - - reset->io_base.dciu_base = (void *)dev_remap_addr_index(dev, 5); - if (!reset->io_base.dciu_base) { - pr_err("failed to map dragon ciu registers\n"); - goto out; - } - - reset->io_base.ddrc_base = (void *)dev_remap_addr_index(dev, 6); - if (!reset->io_base.ddrc_base) { - pr_err("failed to map ddrc registers\n"); - goto out; - } - - reset->io_base.apbc2_base = (void *)dev_remap_addr_index(dev, 7); - if (!reset->io_base.apbc2_base) { - pr_err("failed to map apbc2 registers\n"); - goto out; - } - - reset->signals = k1_reset_signals; - -out: - return 0; -} - -const struct reset_ops k1_reset_ops = { - .rst_assert = spacemit_reset_assert, - .rst_deassert = spacemit_reset_deassert, -}; - -static const struct udevice_id k1_reset_ids[] = { - { .compatible = "spacemit,k1-reset", }, - {}, -}; - -U_BOOT_DRIVER(k1_reset) = { - .name = "spacemit,k1-reset", - .id = UCLASS_RESET, - .ops = &k1_reset_ops, - .of_match = k1_reset_ids, - .probe = spacemit_k1_reset_probe, - .priv_auto = sizeof(struct spacemit_reset), -}; diff --git a/drivers/reset/spacemit/Makefile b/drivers/reset/spacemit/Makefile new file mode 100644 index 00000000000..16722c68954 --- /dev/null +++ b/drivers/reset/spacemit/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# SpacemiT reset drivers + +obj-y += reset-spacemit-k1.o diff --git a/drivers/reset/spacemit/reset-spacemit-k1.c b/drivers/reset/spacemit/reset-spacemit-k1.c new file mode 100644 index 00000000000..129e1cc96f1 --- /dev/null +++ b/drivers/reset/spacemit/reset-spacemit-k1.c @@ -0,0 +1,289 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * SpacemiT K1 reset driver (syscon-bound). + * + * Copyright (C) 2022 Spacemit Inc. + * Copyright (C) 2025 Huan Zhou <[email protected]> + * Copyright (C) 2026 RISCstar Ltd. + */ + +#include <asm/io.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <dm/lists.h> +#include <dt-bindings/clock/spacemit,k1-syscon.h> +#include <linux/bitops.h> +#include <malloc.h> +#include <reset-uclass.h> +#include <soc/spacemit/k1-reset.h> +#include <soc/spacemit/k1-syscon.h> + +/* =================================================================== + * Per-syscon reset signal tables. + * + * Indexed by the kernel-side per-syscon-local IDs from + * <dt-bindings/clock/spacemit,k1-syscon.h>. Each entry is + * (offset, assert_mask, deassert_mask): bits in assert_mask are set + * when the reset line is asserted; bits in deassert_mask are set when + * deasserted; the union (assert_mask | deassert_mask) is the set of + * bits the controller will overwrite on each transition. + * + * Layout mirrors the kernel-side K1 reset driver. + * =================================================================== + */ + +struct spacemit_k1_reset_data { + u32 offset; + u32 assert_mask; + u32 deassert_mask; +}; + +#define RESET_DATA(o, a, d) { \ + .offset = (o), .assert_mask = (a), .deassert_mask = (d) \ +} + +static const struct spacemit_k1_reset_data k1_mpmu_resets[] = { + [RESET_WDT] = RESET_DATA(MPMU_WDTPCR, BIT(2), 0), +}; + +static const struct spacemit_k1_reset_data k1_apbc_resets[] = { + [RESET_UART0] = RESET_DATA(APBC_UART1_CLK_RST, BIT(2), 0), + [RESET_UART2] = RESET_DATA(APBC_UART2_CLK_RST, BIT(2), 0), + [RESET_UART3] = RESET_DATA(APBC_UART3_CLK_RST, BIT(2), 0), + [RESET_UART4] = RESET_DATA(APBC_UART4_CLK_RST, BIT(2), 0), + [RESET_UART5] = RESET_DATA(APBC_UART5_CLK_RST, BIT(2), 0), + [RESET_UART6] = RESET_DATA(APBC_UART6_CLK_RST, BIT(2), 0), + [RESET_UART7] = RESET_DATA(APBC_UART7_CLK_RST, BIT(2), 0), + [RESET_UART8] = RESET_DATA(APBC_UART8_CLK_RST, BIT(2), 0), + [RESET_UART9] = RESET_DATA(APBC_UART9_CLK_RST, BIT(2), 0), + [RESET_GPIO] = RESET_DATA(APBC_GPIO_CLK_RST, BIT(2), 0), + [RESET_PWM0] = RESET_DATA(APBC_PWM0_CLK_RST, BIT(2), BIT(0)), + [RESET_PWM1] = RESET_DATA(APBC_PWM1_CLK_RST, BIT(2), BIT(0)), + [RESET_PWM2] = RESET_DATA(APBC_PWM2_CLK_RST, BIT(2), BIT(0)), + [RESET_PWM3] = RESET_DATA(APBC_PWM3_CLK_RST, BIT(2), BIT(0)), + [RESET_PWM4] = RESET_DATA(APBC_PWM4_CLK_RST, BIT(2), BIT(0)), + [RESET_PWM5] = RESET_DATA(APBC_PWM5_CLK_RST, BIT(2), BIT(0)), + [RESET_PWM6] = RESET_DATA(APBC_PWM6_CLK_RST, BIT(2), BIT(0)), + [RESET_PWM7] = RESET_DATA(APBC_PWM7_CLK_RST, BIT(2), BIT(0)), + [RESET_PWM8] = RESET_DATA(APBC_PWM8_CLK_RST, BIT(2), BIT(0)), + [RESET_PWM9] = RESET_DATA(APBC_PWM9_CLK_RST, BIT(2), BIT(0)), + [RESET_PWM10] = RESET_DATA(APBC_PWM10_CLK_RST, BIT(2), BIT(0)), + [RESET_PWM11] = RESET_DATA(APBC_PWM11_CLK_RST, BIT(2), BIT(0)), + [RESET_PWM12] = RESET_DATA(APBC_PWM12_CLK_RST, BIT(2), BIT(0)), + [RESET_PWM13] = RESET_DATA(APBC_PWM13_CLK_RST, BIT(2), BIT(0)), + [RESET_PWM14] = RESET_DATA(APBC_PWM14_CLK_RST, BIT(2), BIT(0)), + [RESET_PWM15] = RESET_DATA(APBC_PWM15_CLK_RST, BIT(2), BIT(0)), + [RESET_PWM16] = RESET_DATA(APBC_PWM16_CLK_RST, BIT(2), BIT(0)), + [RESET_PWM17] = RESET_DATA(APBC_PWM17_CLK_RST, BIT(2), BIT(0)), + [RESET_PWM18] = RESET_DATA(APBC_PWM18_CLK_RST, BIT(2), BIT(0)), + [RESET_PWM19] = RESET_DATA(APBC_PWM19_CLK_RST, BIT(2), BIT(0)), + [RESET_SSP3] = RESET_DATA(APBC_SSP3_CLK_RST, BIT(2), 0), + [RESET_RTC] = RESET_DATA(APBC_RTC_CLK_RST, BIT(2), 0), + [RESET_TWSI0] = RESET_DATA(APBC_TWSI0_CLK_RST, BIT(2), 0), + [RESET_TWSI1] = RESET_DATA(APBC_TWSI1_CLK_RST, BIT(2), 0), + [RESET_TWSI2] = RESET_DATA(APBC_TWSI2_CLK_RST, BIT(2), 0), + [RESET_TWSI4] = RESET_DATA(APBC_TWSI4_CLK_RST, BIT(2), 0), + [RESET_TWSI5] = RESET_DATA(APBC_TWSI5_CLK_RST, BIT(2), 0), + [RESET_TWSI6] = RESET_DATA(APBC_TWSI6_CLK_RST, BIT(2), 0), + [RESET_TWSI7] = RESET_DATA(APBC_TWSI7_CLK_RST, BIT(2), 0), + [RESET_TWSI8] = RESET_DATA(APBC_TWSI8_CLK_RST, BIT(2), 0), + [RESET_TIMERS1] = RESET_DATA(APBC_TIMERS1_CLK_RST, BIT(2), 0), + [RESET_TIMERS2] = RESET_DATA(APBC_TIMERS2_CLK_RST, BIT(2), 0), + [RESET_AIB] = RESET_DATA(APBC_AIB_CLK_RST, BIT(2), 0), + [RESET_ONEWIRE] = RESET_DATA(APBC_ONEWIRE_CLK_RST, BIT(2), 0), + [RESET_SSPA0] = RESET_DATA(APBC_SSPA0_CLK_RST, BIT(2), 0), + [RESET_SSPA1] = RESET_DATA(APBC_SSPA1_CLK_RST, BIT(2), 0), + [RESET_DRO] = RESET_DATA(APBC_DRO_CLK_RST, BIT(2), 0), + [RESET_IR] = RESET_DATA(APBC_IR_CLK_RST, BIT(2), 0), + [RESET_TSEN] = RESET_DATA(APBC_TSEN_CLK_RST, BIT(2), 0), + [RESET_IPC_AP2AUD] = RESET_DATA(APBC_IPC_AP2AUD_CLK_RST, BIT(2), 0), + [RESET_CAN0] = RESET_DATA(APBC_CAN0_CLK_RST, BIT(2), 0), +}; + +static const struct spacemit_k1_reset_data k1_apmu_resets[] = { + [RESET_CCIC_4X] = RESET_DATA(APMU_CCIC_CLK_RES_CTRL, 0, BIT(1)), + [RESET_CCIC1_PHY] = RESET_DATA(APMU_CCIC_CLK_RES_CTRL, 0, BIT(2)), + [RESET_SDH_AXI] = RESET_DATA(APMU_SDH0_CLK_RES_CTRL, 0, BIT(0)), + [RESET_SDH0] = RESET_DATA(APMU_SDH0_CLK_RES_CTRL, 0, BIT(1)), + [RESET_SDH1] = RESET_DATA(APMU_SDH1_CLK_RES_CTRL, 0, BIT(1)), + [RESET_SDH2] = RESET_DATA(APMU_SDH2_CLK_RES_CTRL, 0, BIT(1)), + [RESET_USBP1_AXI] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(4)), + [RESET_USB_AXI] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(0)), + [RESET_USB30_AHB] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(9)), + [RESET_USB30_VCC] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(10)), + [RESET_USB30_PHY] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(11)), + [RESET_QSPI] = RESET_DATA(APMU_QSPI_CLK_RES_CTRL, 0, BIT(1)), + [RESET_QSPI_BUS] = RESET_DATA(APMU_QSPI_CLK_RES_CTRL, 0, BIT(0)), + [RESET_DMA] = RESET_DATA(APMU_DMA_CLK_RES_CTRL, 0, BIT(0)), + [RESET_AES] = RESET_DATA(APMU_AES_CLK_RES_CTRL, 0, BIT(4)), + [RESET_VPU] = RESET_DATA(APMU_VPU_CLK_RES_CTRL, 0, BIT(0)), + [RESET_GPU] = RESET_DATA(APMU_GPU_CLK_RES_CTRL, 0, BIT(1)), + [RESET_EMMC] = RESET_DATA(APMU_PMUA_EM_CLK_RES_CTRL, 0, BIT(1)), + [RESET_EMMC_X] = RESET_DATA(APMU_PMUA_EM_CLK_RES_CTRL, 0, BIT(0)), + [RESET_AUDIO_SYS] = RESET_DATA(APMU_AUDIO_CLK_RES_CTRL, 0, BIT(0)), + [RESET_AUDIO_MCU] = RESET_DATA(APMU_AUDIO_CLK_RES_CTRL, 0, BIT(2)), + [RESET_AUDIO_APMU] = RESET_DATA(APMU_AUDIO_CLK_RES_CTRL, 0, BIT(3)), + [RESET_HDMI] = RESET_DATA(APMU_HDMI_CLK_RES_CTRL, 0, BIT(9)), + [RESET_PCIE0_DBI] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_0, 0, BIT(3)), + [RESET_PCIE0_SLAVE] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_0, 0, BIT(4)), + [RESET_PCIE0_MASTER] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_0, 0, BIT(5)), + [RESET_PCIE0_GLOBAL] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_0, BIT(8), 0), + [RESET_PCIE1_DBI] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_1, 0, BIT(3)), + [RESET_PCIE1_SLAVE] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_1, 0, BIT(4)), + [RESET_PCIE1_MASTER] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_1, 0, BIT(5)), + [RESET_PCIE1_GLOBAL] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_1, BIT(8), 0), + [RESET_PCIE2_DBI] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_2, 0, BIT(3)), + [RESET_PCIE2_SLAVE] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_2, 0, BIT(4)), + [RESET_PCIE2_MASTER] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_2, 0, BIT(5)), + [RESET_PCIE2_GLOBAL] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_2, BIT(8), 0), + [RESET_EMAC0] = RESET_DATA(APMU_EMAC0_CLK_RES_CTRL, 0, BIT(1)), + [RESET_EMAC1] = RESET_DATA(APMU_EMAC1_CLK_RES_CTRL, 0, BIT(1)), + [RESET_JPG] = RESET_DATA(APMU_JPG_CLK_RES_CTRL, 0, BIT(0)), + [RESET_CCIC2PHY] = RESET_DATA(APMU_CSI_CCIC2_CLK_RES_CTRL, 0, BIT(2)), + [RESET_CCIC3PHY] = RESET_DATA(APMU_CSI_CCIC2_CLK_RES_CTRL, 0, BIT(29)), + [RESET_CSI] = RESET_DATA(APMU_CSI_CCIC2_CLK_RES_CTRL, 0, BIT(1)), + [RESET_ISP] = RESET_DATA(APMU_ISP_CLK_RES_CTRL, 0, BIT(0)), + [RESET_ISP_CPP] = RESET_DATA(APMU_ISP_CLK_RES_CTRL, 0, BIT(27)), + [RESET_ISP_BUS] = RESET_DATA(APMU_ISP_CLK_RES_CTRL, 0, BIT(3)), + [RESET_ISP_CI] = RESET_DATA(APMU_ISP_CLK_RES_CTRL, 0, BIT(16)), + [RESET_DPU_MCLK] = RESET_DATA(APMU_LCD_CLK_RES_CTRL2, 0, BIT(9)), + [RESET_DPU_ESC] = RESET_DATA(APMU_LCD_CLK_RES_CTRL1, 0, BIT(3)), + [RESET_DPU_HCLK] = RESET_DATA(APMU_LCD_CLK_RES_CTRL1, 0, BIT(4)), + [RESET_DPU_SPIBUS] = RESET_DATA(APMU_LCD_SPI_CLK_RES_CTRL, 0, BIT(4)), + [RESET_DPU_SPI_HBUS] = RESET_DATA(APMU_LCD_SPI_CLK_RES_CTRL, 0, BIT(2)), + [RESET_V2D] = RESET_DATA(APMU_LCD_CLK_RES_CTRL1, 0, BIT(27)), + [RESET_MIPI] = RESET_DATA(APMU_LCD_CLK_RES_CTRL1, 0, BIT(15)), + [RESET_MC] = RESET_DATA(APMU_PMUA_MC_CTRL, 0, BIT(0)), +}; + +static const struct spacemit_k1_reset_data k1_apbc2_resets[] = { + [RESET_APBC2_UART1] = RESET_DATA(APBC2_UART1_CLK_RST, BIT(2), 0), + [RESET_APBC2_SSP2] = RESET_DATA(APBC2_SSP2_CLK_RST, BIT(2), 0), + [RESET_APBC2_TWSI3] = RESET_DATA(APBC2_TWSI3_CLK_RST, BIT(2), 0), + [RESET_APBC2_RTC] = RESET_DATA(APBC2_RTC_CLK_RST, BIT(2), 0), + [RESET_APBC2_TIMERS0] = RESET_DATA(APBC2_TIMERS0_CLK_RST, BIT(2), 0), + [RESET_APBC2_KPC] = RESET_DATA(APBC2_KPC_CLK_RST, BIT(2), 0), + [RESET_APBC2_GPIO] = RESET_DATA(APBC2_GPIO_CLK_RST, BIT(2), 0), +}; + +/* =================================================================== + * Driver + * =================================================================== + */ + +struct spacemit_k1_reset_priv { + void __iomem *base; + const struct spacemit_k1_reset_data *table; + size_t table_size; +}; + +static int spacemit_k1_reset_xfer(struct reset_ctl *rst, bool assert) +{ + struct spacemit_k1_reset_priv *priv = dev_get_priv(rst->dev); + const struct spacemit_k1_reset_data *e; + u32 v; + + if (rst->id >= priv->table_size) + return -EINVAL; + + e = &priv->table[rst->id]; + if (e->assert_mask == 0 && e->deassert_mask == 0) + return -EINVAL; /* not owned by this syscon */ + + v = readl(priv->base + e->offset); + v &= ~(e->assert_mask | e->deassert_mask); + v |= assert ? e->assert_mask : e->deassert_mask; + writel(v, priv->base + e->offset); + + return 0; +} + +static int spacemit_k1_reset_assert(struct reset_ctl *rst) +{ + return spacemit_k1_reset_xfer(rst, true); +} + +static int spacemit_k1_reset_deassert(struct reset_ctl *rst) +{ + return spacemit_k1_reset_xfer(rst, false); +} + +static int spacemit_k1_reset_request(struct reset_ctl *rst) +{ + struct spacemit_k1_reset_priv *priv = dev_get_priv(rst->dev); + + return rst->id < priv->table_size ? 0 : -EINVAL; +} + +static const struct reset_ops spacemit_k1_reset_ops = { + .request = spacemit_k1_reset_request, + .rst_assert = spacemit_k1_reset_assert, + .rst_deassert = spacemit_k1_reset_deassert, +}; + +static int spacemit_k1_reset_probe(struct udevice *dev) +{ + struct spacemit_k1_reset_priv *priv = dev_get_priv(dev); + + priv->base = (void __iomem *)dev_remap_addr(dev); + if (!priv->base) + return -ENODEV; + + return 0; +} + +U_BOOT_DRIVER(spacemit_k1_reset) = { + .name = "spacemit_k1_reset", + .id = UCLASS_RESET, + .ops = &spacemit_k1_reset_ops, + .probe = spacemit_k1_reset_probe, + .priv_auto = sizeof(struct spacemit_k1_reset_priv), + .flags = DM_FLAG_PRE_RELOC, +}; + +int spacemit_k1_reset_bind(struct udevice *parent, + enum spacemit_k1_reset_syscon syscon) +{ + struct spacemit_k1_reset_priv *priv; + struct udevice *rst_dev; + const struct spacemit_k1_reset_data *table; + size_t table_size; + int ret; + + switch (syscon) { + case SPACEMIT_K1_RESET_MPMU: + table = k1_mpmu_resets; + table_size = ARRAY_SIZE(k1_mpmu_resets); + break; + case SPACEMIT_K1_RESET_APMU: + table = k1_apmu_resets; + table_size = ARRAY_SIZE(k1_apmu_resets); + break; + case SPACEMIT_K1_RESET_APBC: + table = k1_apbc_resets; + table_size = ARRAY_SIZE(k1_apbc_resets); + break; + case SPACEMIT_K1_RESET_APBC2: + table = k1_apbc2_resets; + table_size = ARRAY_SIZE(k1_apbc2_resets); + break; + default: + return -EINVAL; + } + + ret = device_bind_driver_to_node(parent, "spacemit_k1_reset", "reset", + dev_ofnode(parent), &rst_dev); + if (ret) + return ret; + + priv = malloc(sizeof(*priv)); + if (!priv) { + device_unbind(rst_dev); + return -ENOMEM; + } + priv->table = table; + priv->table_size = table_size; + dev_set_priv(rst_dev, priv); + + return 0; +} |
