diff options
| author | Miguel Ojeda <ojeda@kernel.org> | 2026-08-16 15:32:33 +0200 |
|---|---|---|
| committer | Miguel Ojeda <ojeda@kernel.org> | 2026-08-23 21:27:17 +0200 |
| commit | 5febf432df1cfa5b25d99b54c32103fafbdd0eb9 (patch) | |
| tree | 93a1ed1d337bc53adf1e572c2586d347703b286e /drivers/reset/reset-th1520.c | |
| download | linux-stable-5febf432df1cfa5b25d99b54c32103fafbdd0eb9.tar.gz linux-stable-5febf432df1cfa5b25d99b54c32103fafbdd0eb9.zip | |
kbuild: rust: keep Rust objects out of Clang LTO with inline helpersgrafted
Under `CONFIG_LTO_CLANG` + `CONFIG_RUST_INLINE_HELPERS`, one may hit
`objtool` errors such as:
vmlinux.o: error: objtool: _R..._3Gsp4boot+0xd6a:
can't find jump dest instruction at .text._R..._3Gsp4boot+0x1dfd
The reason is that in such builds, the Clang invocation that compiles
the combined Rust plus helpers bitcode emits LLVM bitcode (again) --
the final code generation happens in the linker's LTO step, which the
`-mllvm` trap options passed to Clang do not reach.
This, in turn, means that unreachable traps are missing, and the
impossible paths do not merely fallthrough to the next symbol, but past
the end of their own section, since LTO builds place each function in
its own section.
Thus filter `CC_FLAGS_LTO` out of the Clang invocation, so that it always
emits machine code directly, with the traps in place.
Assisted-by: LLM
Cc: Gary Guo <gary@garyguo.net>
Cc: Boqun Feng <boqun@kernel.org>
Cc: Alice Ryhl <aliceryhl@google.com>
Cc: Matthew Maurer <mmaurer@google.com>
Cc: Josh Poimboeuf <jpoimboe@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: stable@vger.kernel.org
Fixes: 3a2486cc1da5 ("kbuild: rust: provide an option to inline C helpers into Rust")
Acked-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260816133233.197500-2-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'drivers/reset/reset-th1520.c')
| -rw-r--r-- | drivers/reset/reset-th1520.c | 983 |
1 files changed, 983 insertions, 0 deletions
diff --git a/drivers/reset/reset-th1520.c b/drivers/reset/reset-th1520.c new file mode 100644 index 000000000..fd32e991c --- /dev/null +++ b/drivers/reset/reset-th1520.c @@ -0,0 +1,983 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. + * Author: Michal Wilczynski <m.wilczynski@samsung.com> + */ + +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/reset-controller.h> +#include <linux/regmap.h> + +#include <dt-bindings/reset/thead,th1520-reset.h> + + /* register offset in RSTGEN_R */ +#define TH1520_BROM_RST_CFG 0x0 +#define TH1520_C910_RST_CFG 0x4 +#define TH1520_CHIP_DBG_RST_CFG 0xc +#define TH1520_AXI4_CPUSYS2_RST_CFG 0x10 +#define TH1520_X2H_CPUSYS_RST_CFG 0x18 +#define TH1520_AHB2_CPUSYS_RST_CFG 0x1c +#define TH1520_APB3_CPUSYS_RST_CFG 0x20 +#define TH1520_MBOX0_RST_CFG 0x24 +#define TH1520_MBOX1_RST_CFG 0x28 +#define TH1520_MBOX2_RST_CFG 0x2c +#define TH1520_MBOX3_RST_CFG 0x30 +#define TH1520_WDT0_RST_CFG 0x34 +#define TH1520_WDT1_RST_CFG 0x38 +#define TH1520_TIMER0_RST_CFG 0x3c +#define TH1520_TIMER1_RST_CFG 0x40 +#define TH1520_PERISYS_AHB_RST_CFG 0x44 +#define TH1520_PERISYS_APB1_RST_CFG 0x48 +#define TH1520_PERISYS_APB2_RST_CFG 0x4c +#define TH1520_GMAC0_RST_CFG 0x68 +#define TH1520_UART0_RST_CFG 0x70 +#define TH1520_UART1_RST_CFG 0x74 +#define TH1520_UART2_RST_CFG 0x78 +#define TH1520_UART3_RST_CFG 0x7c +#define TH1520_UART4_RST_CFG 0x80 +#define TH1520_UART5_RST_CFG 0x84 +#define TH1520_QSPI0_RST_CFG 0x8c +#define TH1520_QSPI1_RST_CFG 0x90 +#define TH1520_SPI_RST_CFG 0x94 +#define TH1520_I2C0_RST_CFG 0x98 +#define TH1520_I2C1_RST_CFG 0x9c +#define TH1520_I2C2_RST_CFG 0xa0 +#define TH1520_I2C3_RST_CFG 0xa4 +#define TH1520_I2C4_RST_CFG 0xa8 +#define TH1520_I2C5_RST_CFG 0xac +#define TH1520_GPIO0_RST_CFG 0xb0 +#define TH1520_GPIO1_RST_CFG 0xb4 +#define TH1520_GPIO2_RST_CFG 0xb8 +#define TH1520_PWM_RST_CFG 0xc0 +#define TH1520_PADCTRL0_APSYS_RST_CFG 0xc4 +#define TH1520_CPU2PERI_X2H_RST_CFG 0xcc +#define TH1520_CPU2AON_X2H_RST_CFG 0xe4 +#define TH1520_AON2CPU_A2X_RST_CFG 0xfc +#define TH1520_NPUSYS_AXI_RST_CFG 0x128 +#define TH1520_CPU2VP_X2P_RST_CFG 0x12c +#define TH1520_CPU2VI_X2H_RST_CFG 0x138 +#define TH1520_BMU_C910_RST_CFG 0x148 +#define TH1520_DMAC_CPUSYS_RST_CFG 0x14c +#define TH1520_SPINLOCK_RST_CFG 0x178 +#define TH1520_CFG2TEE_X2H_RST_CFG 0x188 +#define TH1520_DSMART_RST_CFG 0x18c +#define TH1520_GPIO3_RST_CFG 0x1a8 +#define TH1520_I2S_RST_CFG 0x1ac +#define TH1520_IMG_NNA_RST_CFG 0x1b0 +#define TH1520_PERI_APB3_RST_CFG 0x1dc +#define TH1520_VP_SUBSYS_RST_CFG 0x1ec +#define TH1520_PERISYS_APB4_RST_CFG 0x1f8 +#define TH1520_GMAC1_RST_CFG 0x204 +#define TH1520_GMAC_AXI_RST_CFG 0x208 +#define TH1520_PADCTRL1_APSYS_RST_CFG 0x20c +#define TH1520_VOSYS_AXI_RST_CFG 0x210 +#define TH1520_VOSYS_X2X_RST_CFG 0x214 +#define TH1520_MISC2VP_X2X_RST_CFG 0x218 +#define TH1520_SUBSYS_RST_CFG 0x220 + + /* register offset in DSP_REGMAP */ +#define TH1520_DSPSYS_RST_CFG 0x0 + + /* register offset in MISCSYS_REGMAP */ +#define TH1520_EMMC_RST_CFG 0x0 +#define TH1520_MISCSYS_AXI_RST_CFG 0x8 +#define TH1520_SDIO0_RST_CFG 0xc +#define TH1520_SDIO1_RST_CFG 0x10 +#define TH1520_USB3_DRD_RST_CFG 0x14 + + /* register offset in VISYS_REGMAP */ +#define TH1520_VISYS_RST_CFG 0x0 +#define TH1520_VISYS_2_RST_CFG 0x4 + + /* register offset in VOSYS_REGMAP */ +#define TH1520_GPU_RST_CFG 0x0 +#define TH1520_GPU_RST_CFG_MASK GENMASK(1, 0) +#define TH1520_DPU_RST_CFG 0x4 +#define TH1520_DSI0_RST_CFG 0x8 +#define TH1520_DSI1_RST_CFG 0xc +#define TH1520_HDMI_RST_CFG 0x14 +#define TH1520_AXI4_VO_DW_AXI_RST_CFG 0x18 +#define TH1520_X2H_X4_VOSYS_DW_RST_CFG 0x20 + +/* register values */ +#define TH1520_GPU_SW_GPU_RST BIT(0) +#define TH1520_GPU_SW_CLKGEN_RST BIT(1) +#define TH1520_DPU_SW_DPU_HRST BIT(0) +#define TH1520_DPU_SW_DPU_ARST BIT(1) +#define TH1520_DPU_SW_DPU_CRST BIT(2) +#define TH1520_DSI_SW_DSI_PRST BIT(0) +#define TH1520_HDMI_SW_MAIN_RST BIT(0) +#define TH1520_HDMI_SW_PRST BIT(1) + + /* register offset in VPSYS_REGMAP */ +#define TH1520_AXIBUS_RST_CFG 0x0 +#define TH1520_FCE_RST_CFG 0x4 +#define TH1520_G2D_RST_CFG 0x8 +#define TH1520_VDEC_RST_CFG 0xc +#define TH1520_VENC_RST_CFG 0x10 + +struct th1520_reset_map { + u32 bit; + u32 reg; +}; + +struct th1520_reset_priv { + struct reset_controller_dev rcdev; + struct regmap *map; + const struct th1520_reset_map *resets; +}; + +struct th1520_reset_data { + const struct th1520_reset_map *resets; + size_t num; +}; + +static const struct th1520_reset_map th1520_resets[] = { + [TH1520_RESET_ID_GPU] = { + .bit = TH1520_GPU_SW_GPU_RST, + .reg = TH1520_GPU_RST_CFG, + }, + [TH1520_RESET_ID_GPU_CLKGEN] = { + .bit = TH1520_GPU_SW_CLKGEN_RST, + .reg = TH1520_GPU_RST_CFG, + }, + [TH1520_RESET_ID_DPU_AHB] = { + .bit = TH1520_DPU_SW_DPU_HRST, + .reg = TH1520_DPU_RST_CFG, + }, + [TH1520_RESET_ID_DPU_AXI] = { + .bit = TH1520_DPU_SW_DPU_ARST, + .reg = TH1520_DPU_RST_CFG, + }, + [TH1520_RESET_ID_DPU_CORE] = { + .bit = TH1520_DPU_SW_DPU_CRST, + .reg = TH1520_DPU_RST_CFG, + }, + [TH1520_RESET_ID_DSI0_APB] = { + .bit = TH1520_DSI_SW_DSI_PRST, + .reg = TH1520_DSI0_RST_CFG, + }, + [TH1520_RESET_ID_DSI1_APB] = { + .bit = TH1520_DSI_SW_DSI_PRST, + .reg = TH1520_DSI1_RST_CFG, + }, + [TH1520_RESET_ID_HDMI] = { + .bit = TH1520_HDMI_SW_MAIN_RST, + .reg = TH1520_HDMI_RST_CFG, + }, + [TH1520_RESET_ID_HDMI_APB] = { + .bit = TH1520_HDMI_SW_PRST, + .reg = TH1520_HDMI_RST_CFG, + }, + [TH1520_RESET_ID_VOAXI] = { + .bit = BIT(0), + .reg = TH1520_AXI4_VO_DW_AXI_RST_CFG, + }, + [TH1520_RESET_ID_VOAXI_APB] = { + .bit = BIT(1), + .reg = TH1520_AXI4_VO_DW_AXI_RST_CFG, + }, + [TH1520_RESET_ID_X2H_DPU_AXI] = { + .bit = BIT(0), + .reg = TH1520_X2H_X4_VOSYS_DW_RST_CFG, + }, + [TH1520_RESET_ID_X2H_DPU_AHB] = { + .bit = BIT(1), + .reg = TH1520_X2H_X4_VOSYS_DW_RST_CFG, + }, + [TH1520_RESET_ID_X2H_DPU1_AXI] = { + .bit = BIT(2), + .reg = TH1520_X2H_X4_VOSYS_DW_RST_CFG, + }, + [TH1520_RESET_ID_X2H_DPU1_AHB] = { + .bit = BIT(3), + .reg = TH1520_X2H_X4_VOSYS_DW_RST_CFG, + }, +}; + +static const struct th1520_reset_map th1520_ap_resets[] = { + [TH1520_RESET_ID_BROM] = { + .bit = BIT(0), + .reg = TH1520_BROM_RST_CFG, + }, + [TH1520_RESET_ID_C910_TOP] = { + .bit = BIT(0), + .reg = TH1520_C910_RST_CFG, + }, + [TH1520_RESET_ID_NPU] = { + .bit = BIT(0), + .reg = TH1520_IMG_NNA_RST_CFG, + }, + [TH1520_RESET_ID_WDT0] = { + .bit = BIT(0), + .reg = TH1520_WDT0_RST_CFG, + }, + [TH1520_RESET_ID_WDT1] = { + .bit = BIT(0), + .reg = TH1520_WDT1_RST_CFG, + }, + [TH1520_RESET_ID_C910_C0] = { + .bit = BIT(1), + .reg = TH1520_C910_RST_CFG, + }, + [TH1520_RESET_ID_C910_C1] = { + .bit = BIT(2), + .reg = TH1520_C910_RST_CFG, + }, + [TH1520_RESET_ID_C910_C2] = { + .bit = BIT(3), + .reg = TH1520_C910_RST_CFG, + }, + [TH1520_RESET_ID_C910_C3] = { + .bit = BIT(4), + .reg = TH1520_C910_RST_CFG, + }, + [TH1520_RESET_ID_CHIP_DBG_CORE] = { + .bit = BIT(0), + .reg = TH1520_CHIP_DBG_RST_CFG, + }, + [TH1520_RESET_ID_CHIP_DBG_AXI] = { + .bit = BIT(1), + .reg = TH1520_CHIP_DBG_RST_CFG, + }, + [TH1520_RESET_ID_AXI4_CPUSYS2_AXI] = { + .bit = BIT(0), + .reg = TH1520_AXI4_CPUSYS2_RST_CFG, + }, + [TH1520_RESET_ID_AXI4_CPUSYS2_APB] = { + .bit = BIT(1), + .reg = TH1520_AXI4_CPUSYS2_RST_CFG, + }, + [TH1520_RESET_ID_X2H_CPUSYS] = { + .bit = BIT(0), + .reg = TH1520_X2H_CPUSYS_RST_CFG, + }, + [TH1520_RESET_ID_AHB2_CPUSYS] = { + .bit = BIT(0), + .reg = TH1520_AHB2_CPUSYS_RST_CFG, + }, + [TH1520_RESET_ID_APB3_CPUSYS] = { + .bit = BIT(0), + .reg = TH1520_APB3_CPUSYS_RST_CFG, + }, + [TH1520_RESET_ID_MBOX0_APB] = { + .bit = BIT(0), + .reg = TH1520_MBOX0_RST_CFG, + }, + [TH1520_RESET_ID_MBOX1_APB] = { + .bit = BIT(0), + .reg = TH1520_MBOX1_RST_CFG, + }, + [TH1520_RESET_ID_MBOX2_APB] = { + .bit = BIT(0), + .reg = TH1520_MBOX2_RST_CFG, + }, + [TH1520_RESET_ID_MBOX3_APB] = { + .bit = BIT(0), + .reg = TH1520_MBOX3_RST_CFG, + }, + [TH1520_RESET_ID_TIMER0_APB] = { + .bit = BIT(0), + .reg = TH1520_TIMER0_RST_CFG, + }, + [TH1520_RESET_ID_TIMER0_CORE] = { + .bit = BIT(1), + .reg = TH1520_TIMER0_RST_CFG, + }, + [TH1520_RESET_ID_TIMER1_APB] = { + .bit = BIT(0), + .reg = TH1520_TIMER1_RST_CFG, + }, + [TH1520_RESET_ID_TIMER1_CORE] = { + .bit = BIT(1), + .reg = TH1520_TIMER1_RST_CFG, + }, + [TH1520_RESET_ID_PERISYS_AHB] = { + .bit = BIT(0), + .reg = TH1520_PERISYS_AHB_RST_CFG, + }, + [TH1520_RESET_ID_PERISYS_APB1] = { + .bit = BIT(0), + .reg = TH1520_PERISYS_APB1_RST_CFG, + }, + [TH1520_RESET_ID_PERISYS_APB2] = { + .bit = BIT(0), + .reg = TH1520_PERISYS_APB2_RST_CFG, + }, + [TH1520_RESET_ID_GMAC0_APB] = { + .bit = BIT(0), + .reg = TH1520_GMAC0_RST_CFG, + }, + [TH1520_RESET_ID_GMAC0_AHB] = { + .bit = BIT(1), + .reg = TH1520_GMAC0_RST_CFG, + }, + [TH1520_RESET_ID_GMAC0_CLKGEN] = { + .bit = BIT(2), + .reg = TH1520_GMAC0_RST_CFG, + }, + [TH1520_RESET_ID_GMAC0_AXI] = { + .bit = BIT(3), + .reg = TH1520_GMAC0_RST_CFG, + }, + [TH1520_RESET_ID_UART0_APB] = { + .bit = BIT(0), + .reg = TH1520_UART0_RST_CFG, + }, + [TH1520_RESET_ID_UART0_IF] = { + .bit = BIT(1), + .reg = TH1520_UART0_RST_CFG, + }, + [TH1520_RESET_ID_UART1_APB] = { + .bit = BIT(0), + .reg = TH1520_UART1_RST_CFG, + }, + [TH1520_RESET_ID_UART1_IF] = { + .bit = BIT(1), + .reg = TH1520_UART1_RST_CFG, + }, + [TH1520_RESET_ID_UART2_APB] = { + .bit = BIT(0), + .reg = TH1520_UART2_RST_CFG, + }, + [TH1520_RESET_ID_UART2_IF] = { + .bit = BIT(1), + .reg = TH1520_UART2_RST_CFG, + }, + [TH1520_RESET_ID_UART3_APB] = { + .bit = BIT(0), + .reg = TH1520_UART3_RST_CFG, + }, + [TH1520_RESET_ID_UART3_IF] = { + .bit = BIT(1), + .reg = TH1520_UART3_RST_CFG, + }, + [TH1520_RESET_ID_UART4_APB] = { + .bit = BIT(0), + .reg = TH1520_UART4_RST_CFG, + }, + [TH1520_RESET_ID_UART4_IF] = { + .bit = BIT(1), + .reg = TH1520_UART4_RST_CFG, + }, + [TH1520_RESET_ID_UART5_APB] = { + .bit = BIT(0), + .reg = TH1520_UART5_RST_CFG, + }, + [TH1520_RESET_ID_UART5_IF] = { + .bit = BIT(1), + .reg = TH1520_UART5_RST_CFG, + }, + [TH1520_RESET_ID_QSPI0_IF] = { + .bit = BIT(0), + .reg = TH1520_QSPI0_RST_CFG, + }, + [TH1520_RESET_ID_QSPI0_APB] = { + .bit = BIT(1), + .reg = TH1520_QSPI0_RST_CFG, + }, + [TH1520_RESET_ID_QSPI1_IF] = { + .bit = BIT(0), + .reg = TH1520_QSPI1_RST_CFG, + }, + [TH1520_RESET_ID_QSPI1_APB] = { + .bit = BIT(1), + .reg = TH1520_QSPI1_RST_CFG, + }, + [TH1520_RESET_ID_SPI_IF] = { + .bit = BIT(0), + .reg = TH1520_SPI_RST_CFG, + }, + [TH1520_RESET_ID_SPI_APB] = { + .bit = BIT(1), + .reg = TH1520_SPI_RST_CFG, + }, + [TH1520_RESET_ID_I2C0_APB] = { + .bit = BIT(0), + .reg = TH1520_I2C0_RST_CFG, + }, + [TH1520_RESET_ID_I2C0_CORE] = { + .bit = BIT(1), + .reg = TH1520_I2C0_RST_CFG, + }, + [TH1520_RESET_ID_I2C1_APB] = { + .bit = BIT(0), + .reg = TH1520_I2C1_RST_CFG, + }, + [TH1520_RESET_ID_I2C1_CORE] = { + .bit = BIT(1), + .reg = TH1520_I2C1_RST_CFG, + }, + [TH1520_RESET_ID_I2C2_APB] = { + .bit = BIT(0), + .reg = TH1520_I2C2_RST_CFG, + }, + [TH1520_RESET_ID_I2C2_CORE] = { + .bit = BIT(1), + .reg = TH1520_I2C2_RST_CFG, + }, + [TH1520_RESET_ID_I2C3_APB] = { + .bit = BIT(0), + .reg = TH1520_I2C3_RST_CFG, + }, + [TH1520_RESET_ID_I2C3_CORE] = { + .bit = BIT(1), + .reg = TH1520_I2C3_RST_CFG, + }, + [TH1520_RESET_ID_I2C4_APB] = { + .bit = BIT(0), + .reg = TH1520_I2C4_RST_CFG, + }, + [TH1520_RESET_ID_I2C4_CORE] = { + .bit = BIT(1), + .reg = TH1520_I2C4_RST_CFG, + }, + [TH1520_RESET_ID_I2C5_APB] = { + .bit = BIT(0), + .reg = TH1520_I2C5_RST_CFG, + }, + [TH1520_RESET_ID_I2C5_CORE] = { + .bit = BIT(1), + .reg = TH1520_I2C5_RST_CFG, + }, + [TH1520_RESET_ID_GPIO0_DB] = { + .bit = BIT(0), + .reg = TH1520_GPIO0_RST_CFG, + }, + [TH1520_RESET_ID_GPIO0_APB] = { + .bit = BIT(1), + .reg = TH1520_GPIO0_RST_CFG, + }, + [TH1520_RESET_ID_GPIO1_DB] = { + .bit = BIT(0), + .reg = TH1520_GPIO1_RST_CFG, + }, + [TH1520_RESET_ID_GPIO1_APB] = { + .bit = BIT(1), + .reg = TH1520_GPIO1_RST_CFG, + }, + [TH1520_RESET_ID_GPIO2_DB] = { + .bit = BIT(0), + .reg = TH1520_GPIO2_RST_CFG, + }, + [TH1520_RESET_ID_GPIO2_APB] = { + .bit = BIT(1), + .reg = TH1520_GPIO2_RST_CFG, + }, + [TH1520_RESET_ID_PWM_COUNTER] = { + .bit = BIT(0), + .reg = TH1520_PWM_RST_CFG, + }, + [TH1520_RESET_ID_PWM_APB] = { + .bit = BIT(1), + .reg = TH1520_PWM_RST_CFG, + }, + [TH1520_RESET_ID_PADCTRL0_APB] = { + .bit = BIT(0), + .reg = TH1520_PADCTRL0_APSYS_RST_CFG, + }, + [TH1520_RESET_ID_CPU2PERI_X2H] = { + .bit = BIT(1), + .reg = TH1520_CPU2PERI_X2H_RST_CFG, + }, + [TH1520_RESET_ID_CPU2AON_X2H] = { + .bit = BIT(0), + .reg = TH1520_CPU2AON_X2H_RST_CFG, + }, + [TH1520_RESET_ID_AON2CPU_A2X] = { + .bit = BIT(0), + .reg = TH1520_AON2CPU_A2X_RST_CFG, + }, + [TH1520_RESET_ID_NPUSYS_AXI] = { + .bit = BIT(0), + .reg = TH1520_NPUSYS_AXI_RST_CFG, + }, + [TH1520_RESET_ID_NPUSYS_AXI_APB] = { + .bit = BIT(1), + .reg = TH1520_NPUSYS_AXI_RST_CFG, + }, + [TH1520_RESET_ID_CPU2VP_X2P] = { + .bit = BIT(0), + .reg = TH1520_CPU2VP_X2P_RST_CFG, + }, + [TH1520_RESET_ID_CPU2VI_X2H] = { + .bit = BIT(0), + .reg = TH1520_CPU2VI_X2H_RST_CFG, + }, + [TH1520_RESET_ID_BMU_AXI] = { + .bit = BIT(0), + .reg = TH1520_BMU_C910_RST_CFG, + }, + [TH1520_RESET_ID_BMU_APB] = { + .bit = BIT(1), + .reg = TH1520_BMU_C910_RST_CFG, + }, + [TH1520_RESET_ID_DMAC_CPUSYS_AXI] = { + .bit = BIT(0), + .reg = TH1520_DMAC_CPUSYS_RST_CFG, + }, + [TH1520_RESET_ID_DMAC_CPUSYS_AHB] = { + .bit = BIT(1), + .reg = TH1520_DMAC_CPUSYS_RST_CFG, + }, + [TH1520_RESET_ID_SPINLOCK] = { + .bit = BIT(0), + .reg = TH1520_SPINLOCK_RST_CFG, + }, + [TH1520_RESET_ID_CFG2TEE] = { + .bit = BIT(0), + .reg = TH1520_CFG2TEE_X2H_RST_CFG, + }, + [TH1520_RESET_ID_DSMART] = { + .bit = BIT(0), + .reg = TH1520_DSMART_RST_CFG, + }, + [TH1520_RESET_ID_GPIO3_DB] = { + .bit = BIT(0), + .reg = TH1520_GPIO3_RST_CFG, + }, + [TH1520_RESET_ID_GPIO3_APB] = { + .bit = BIT(1), + .reg = TH1520_GPIO3_RST_CFG, + }, + [TH1520_RESET_ID_PERI_I2S] = { + .bit = BIT(0), + .reg = TH1520_I2S_RST_CFG, + }, + [TH1520_RESET_ID_PERI_APB3] = { + .bit = BIT(0), + .reg = TH1520_PERI_APB3_RST_CFG, + }, + [TH1520_RESET_ID_PERI2PERI1_APB] = { + .bit = BIT(1), + .reg = TH1520_PERI_APB3_RST_CFG, + }, + [TH1520_RESET_ID_VPSYS_APB] = { + .bit = BIT(0), + .reg = TH1520_VP_SUBSYS_RST_CFG, + }, + [TH1520_RESET_ID_PERISYS_APB4] = { + .bit = BIT(0), + .reg = TH1520_PERISYS_APB4_RST_CFG, + }, + [TH1520_RESET_ID_GMAC1_APB] = { + .bit = BIT(0), + .reg = TH1520_GMAC1_RST_CFG, + }, + [TH1520_RESET_ID_GMAC1_AHB] = { + .bit = BIT(1), + .reg = TH1520_GMAC1_RST_CFG, + }, + [TH1520_RESET_ID_GMAC1_CLKGEN] = { + .bit = BIT(2), + .reg = TH1520_GMAC1_RST_CFG, + }, + [TH1520_RESET_ID_GMAC1_AXI] = { + .bit = BIT(3), + .reg = TH1520_GMAC1_RST_CFG, + }, + [TH1520_RESET_ID_GMAC_AXI] = { + .bit = BIT(0), + .reg = TH1520_GMAC_AXI_RST_CFG, + }, + [TH1520_RESET_ID_GMAC_AXI_APB] = { + .bit = BIT(1), + .reg = TH1520_GMAC_AXI_RST_CFG, + }, + [TH1520_RESET_ID_PADCTRL1_APB] = { + .bit = BIT(0), + .reg = TH1520_PADCTRL1_APSYS_RST_CFG, + }, + [TH1520_RESET_ID_VOSYS_AXI] = { + .bit = BIT(0), + .reg = TH1520_VOSYS_AXI_RST_CFG, + }, + [TH1520_RESET_ID_VOSYS_AXI_APB] = { + .bit = BIT(1), + .reg = TH1520_VOSYS_AXI_RST_CFG, + }, + [TH1520_RESET_ID_VOSYS_AXI_X2X] = { + .bit = BIT(0), + .reg = TH1520_VOSYS_X2X_RST_CFG, + }, + [TH1520_RESET_ID_MISC2VP_X2X] = { + .bit = BIT(0), + .reg = TH1520_MISC2VP_X2X_RST_CFG, + }, + [TH1520_RESET_ID_DSPSYS] = { + .bit = BIT(0), + .reg = TH1520_SUBSYS_RST_CFG, + }, + [TH1520_RESET_ID_VISYS] = { + .bit = BIT(1), + .reg = TH1520_SUBSYS_RST_CFG, + }, + [TH1520_RESET_ID_VOSYS] = { + .bit = BIT(2), + .reg = TH1520_SUBSYS_RST_CFG, + }, + [TH1520_RESET_ID_VPSYS] = { + .bit = BIT(3), + .reg = TH1520_SUBSYS_RST_CFG, + }, +}; + +static const struct th1520_reset_map th1520_dsp_resets[] = { + [TH1520_RESET_ID_X2X_DSP1] = { + .bit = BIT(0), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_X2X_DSP0] = { + .bit = BIT(1), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_X2X_SLAVE_DSP1] = { + .bit = BIT(2), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_X2X_SLAVE_DSP0] = { + .bit = BIT(3), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_DSP0_CORE] = { + .bit = BIT(8), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_DSP0_DEBUG] = { + .bit = BIT(9), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_DSP0_APB] = { + .bit = BIT(10), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_DSP1_CORE] = { + .bit = BIT(12), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_DSP1_DEBUG] = { + .bit = BIT(13), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_DSP1_APB] = { + .bit = BIT(14), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_DSPSYS_APB] = { + .bit = BIT(16), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_AXI4_DSPSYS_SLV] = { + .bit = BIT(20), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_AXI4_DSPSYS] = { + .bit = BIT(24), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_AXI4_DSP_RS] = { + .bit = BIT(26), + .reg = TH1520_DSPSYS_RST_CFG, + }, +}; + +static const struct th1520_reset_map th1520_misc_resets[] = { + [TH1520_RESET_ID_EMMC_SDIO_CLKGEN] = { + .bit = BIT(0), + .reg = TH1520_EMMC_RST_CFG, + }, + [TH1520_RESET_ID_EMMC] = { + .bit = BIT(1), + .reg = TH1520_EMMC_RST_CFG, + }, + [TH1520_RESET_ID_MISCSYS_AXI] = { + .bit = BIT(0), + .reg = TH1520_MISCSYS_AXI_RST_CFG, + }, + [TH1520_RESET_ID_MISCSYS_AXI_APB] = { + .bit = BIT(1), + .reg = TH1520_MISCSYS_AXI_RST_CFG, + }, + [TH1520_RESET_ID_SDIO0] = { + .bit = BIT(0), + .reg = TH1520_SDIO0_RST_CFG, + }, + [TH1520_RESET_ID_SDIO1] = { + .bit = BIT(1), + .reg = TH1520_SDIO1_RST_CFG, + }, + [TH1520_RESET_ID_USB3_APB] = { + .bit = BIT(0), + .reg = TH1520_USB3_DRD_RST_CFG, + }, + [TH1520_RESET_ID_USB3_PHY] = { + .bit = BIT(1), + .reg = TH1520_USB3_DRD_RST_CFG, + }, + [TH1520_RESET_ID_USB3_VCC] = { + .bit = BIT(2), + .reg = TH1520_USB3_DRD_RST_CFG, + }, +}; + +static const struct th1520_reset_map th1520_vi_resets[] = { + [TH1520_RESET_ID_ISP0] = { + .bit = BIT(0), + .reg = TH1520_VISYS_RST_CFG, + }, + [TH1520_RESET_ID_ISP1] = { + .bit = BIT(4), + .reg = TH1520_VISYS_RST_CFG, + }, + [TH1520_RESET_ID_CSI0_APB] = { + .bit = BIT(16), + .reg = TH1520_VISYS_RST_CFG, + }, + [TH1520_RESET_ID_CSI1_APB] = { + .bit = BIT(17), + .reg = TH1520_VISYS_RST_CFG, + }, + [TH1520_RESET_ID_CSI2_APB] = { + .bit = BIT(18), + .reg = TH1520_VISYS_RST_CFG, + }, + [TH1520_RESET_ID_MIPI_FIFO] = { + .bit = BIT(20), + .reg = TH1520_VISYS_RST_CFG, + }, + [TH1520_RESET_ID_ISP_VENC_APB] = { + .bit = BIT(24), + .reg = TH1520_VISYS_RST_CFG, + }, + [TH1520_RESET_ID_VIPRE_APB] = { + .bit = BIT(28), + .reg = TH1520_VISYS_RST_CFG, + }, + [TH1520_RESET_ID_VIPRE_AXI] = { + .bit = BIT(29), + .reg = TH1520_VISYS_RST_CFG, + }, + [TH1520_RESET_ID_DW200_APB] = { + .bit = BIT(31), + .reg = TH1520_VISYS_RST_CFG, + }, + [TH1520_RESET_ID_VISYS3_AXI] = { + .bit = BIT(8), + .reg = TH1520_VISYS_2_RST_CFG, + }, + [TH1520_RESET_ID_VISYS2_AXI] = { + .bit = BIT(9), + .reg = TH1520_VISYS_2_RST_CFG, + }, + [TH1520_RESET_ID_VISYS1_AXI] = { + .bit = BIT(10), + .reg = TH1520_VISYS_2_RST_CFG, + }, + [TH1520_RESET_ID_VISYS_AXI] = { + .bit = BIT(12), + .reg = TH1520_VISYS_2_RST_CFG, + }, + [TH1520_RESET_ID_VISYS_APB] = { + .bit = BIT(16), + .reg = TH1520_VISYS_2_RST_CFG, + }, + [TH1520_RESET_ID_ISP_VENC_AXI] = { + .bit = BIT(20), + .reg = TH1520_VISYS_2_RST_CFG, + }, +}; + +static const struct th1520_reset_map th1520_vp_resets[] = { + [TH1520_RESET_ID_VPSYS_AXI_APB] = { + .bit = BIT(0), + .reg = TH1520_AXIBUS_RST_CFG, + }, + [TH1520_RESET_ID_VPSYS_AXI] = { + .bit = BIT(1), + .reg = TH1520_AXIBUS_RST_CFG, + }, + [TH1520_RESET_ID_FCE_APB] = { + .bit = BIT(0), + .reg = TH1520_FCE_RST_CFG, + }, + [TH1520_RESET_ID_FCE_CORE] = { + .bit = BIT(1), + .reg = TH1520_FCE_RST_CFG, + }, + [TH1520_RESET_ID_FCE_X2X_MASTER] = { + .bit = BIT(4), + .reg = TH1520_FCE_RST_CFG, + }, + [TH1520_RESET_ID_FCE_X2X_SLAVE] = { + .bit = BIT(5), + .reg = TH1520_FCE_RST_CFG, + }, + [TH1520_RESET_ID_G2D_APB] = { + .bit = BIT(0), + .reg = TH1520_G2D_RST_CFG, + }, + [TH1520_RESET_ID_G2D_ACLK] = { + .bit = BIT(1), + .reg = TH1520_G2D_RST_CFG, + }, + [TH1520_RESET_ID_G2D_CORE] = { + .bit = BIT(2), + .reg = TH1520_G2D_RST_CFG, + }, + [TH1520_RESET_ID_VDEC_APB] = { + .bit = BIT(0), + .reg = TH1520_VDEC_RST_CFG, + }, + [TH1520_RESET_ID_VDEC_ACLK] = { + .bit = BIT(1), + .reg = TH1520_VDEC_RST_CFG, + }, + [TH1520_RESET_ID_VDEC_CORE] = { + .bit = BIT(2), + .reg = TH1520_VDEC_RST_CFG, + }, + [TH1520_RESET_ID_VENC_APB] = { + .bit = BIT(0), + .reg = TH1520_VENC_RST_CFG, + }, + [TH1520_RESET_ID_VENC_CORE] = { + .bit = BIT(1), + .reg = TH1520_VENC_RST_CFG, + }, +}; + +static inline struct th1520_reset_priv * +to_th1520_reset(struct reset_controller_dev *rcdev) +{ + return container_of(rcdev, struct th1520_reset_priv, rcdev); +} + +static int th1520_reset_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct th1520_reset_priv *priv = to_th1520_reset(rcdev); + const struct th1520_reset_map *reset; + + reset = &priv->resets[id]; + + return regmap_update_bits(priv->map, reset->reg, reset->bit, 0); +} + +static int th1520_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct th1520_reset_priv *priv = to_th1520_reset(rcdev); + const struct th1520_reset_map *reset; + + reset = &priv->resets[id]; + + return regmap_update_bits(priv->map, reset->reg, reset->bit, + reset->bit); +} + +static const struct reset_control_ops th1520_reset_ops = { + .assert = th1520_reset_assert, + .deassert = th1520_reset_deassert, +}; + +static const struct regmap_config th1520_reset_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, +}; + +static int th1520_reset_probe(struct platform_device *pdev) +{ + const struct th1520_reset_data *data; + struct device *dev = &pdev->dev; + struct th1520_reset_priv *priv; + void __iomem *base; + int ret; + + data = device_get_match_data(dev); + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + priv->map = devm_regmap_init_mmio(dev, base, + &th1520_reset_regmap_config); + if (IS_ERR(priv->map)) + return PTR_ERR(priv->map); + + if (of_device_is_compatible(dev->of_node, "thead,th1520-reset")) { + /* Initialize GPU resets to asserted state */ + ret = regmap_update_bits(priv->map, TH1520_GPU_RST_CFG, + TH1520_GPU_RST_CFG_MASK, 0); + if (ret) + return ret; + } + + priv->rcdev.owner = THIS_MODULE; + priv->rcdev.nr_resets = data->num; + priv->rcdev.ops = &th1520_reset_ops; + priv->rcdev.of_node = dev->of_node; + + priv->resets = data->resets; + + return devm_reset_controller_register(dev, &priv->rcdev); +} + +static const struct th1520_reset_data th1520_reset_data = { + .resets = th1520_resets, + .num = ARRAY_SIZE(th1520_resets), +}; + +static const struct th1520_reset_data th1520_ap_reset_data = { + .resets = th1520_ap_resets, + .num = ARRAY_SIZE(th1520_ap_resets), +}; + +static const struct th1520_reset_data th1520_dsp_reset_data = { + .resets = th1520_dsp_resets, + .num = ARRAY_SIZE(th1520_dsp_resets), +}; + +static const struct th1520_reset_data th1520_misc_reset_data = { + .resets = th1520_misc_resets, + .num = ARRAY_SIZE(th1520_misc_resets), +}; + +static const struct th1520_reset_data th1520_vi_reset_data = { + .resets = th1520_vi_resets, + .num = ARRAY_SIZE(th1520_vi_resets), +}; + +static const struct th1520_reset_data th1520_vp_reset_data = { + .resets = th1520_vp_resets, + .num = ARRAY_SIZE(th1520_vp_resets), +}; + +static const struct of_device_id th1520_reset_match[] = { + { .compatible = "thead,th1520-reset", .data = &th1520_reset_data }, + { .compatible = "thead,th1520-reset-ap", .data = &th1520_ap_reset_data }, + { .compatible = "thead,th1520-reset-dsp", .data = &th1520_dsp_reset_data }, + { .compatible = "thead,th1520-reset-misc", .data = &th1520_misc_reset_data }, + { .compatible = "thead,th1520-reset-vi", .data = &th1520_vi_reset_data }, + { .compatible = "thead,th1520-reset-vp", .data = &th1520_vp_reset_data }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, th1520_reset_match); + +static struct platform_driver th1520_reset_driver = { + .driver = { + .name = "th1520-reset", + .of_match_table = th1520_reset_match, + }, + .probe = th1520_reset_probe, +}; +module_platform_driver(th1520_reset_driver); + +MODULE_AUTHOR("Michal Wilczynski <m.wilczynski@samsung.com>"); +MODULE_DESCRIPTION("T-HEAD TH1520 SoC reset controller"); +MODULE_LICENSE("GPL"); |
