From 034dd340b08be1f2f0477ad16131d609f9dbd53c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 30 Aug 2026 09:22:00 -0700 Subject: Merge tag 'trace-v7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace Pull tracing fixes from Steven Rostedt: - Fix error output of boot instance creation failure Currently if a boot instance creation fails, instead of printing out the name of the instance that failed, it prints "(null)". That is because it prints "cur_str" that had already been processed by strsep(). Print the saved name instead. While at it, print the error code of the failure. - Fix use-after-free for same named historgrams Histograms can be named so that they can be used in multiple events. But if the named histogram has a variable attached, the second event that uses the named histogram which duplicates it and needs to free the original after duplication leaves the old variable in place and still visible. If another histogram uses than variable, it will use the stale one which will try to reference the freed duplicate histogram and crash the kernel. Free the duplicate variables along with the duplicated histogram data. - Check return value of kthread_run() in event self test The events self tests uses a kthread for testing but does not check if it succeeded in creating a kthread. If the kthread creation were to fail, the code will still try to call kthread_stop() on the error returned. - Fix race between reading trace_pipe and updating subbuffer size If a user is reading the trace_pipe file at the same time they update the ring buffer sub-buffer size, can cause the trace_pipe read to read stale data. Add trace_access_lock() around updating the ring buffer sub-buffer size. - Fix eventfs_inode on failure path in creation of the events directory In the creation of the "events" directory, if after allocating the eventfs_inode a failure is detected, it calls cleanup_ei() which calls free_ei(). The free_ei() will test if eventfs_inode being freed has no children. It is a bug if it does. But on the failure case of the creation of the "events" directory, the children lists have not yet been initialized and the free will trigger a warning because list_empty() on an uninitialized list returns false. Move the initialization into init_ei() where it makes more sense and makes sure that a created eventfs_inode has its lists initialized upon creation. - Check return value of kthread_run() in ftrace direct sample code The sample code that shows how to use the ftrace direct calls does not test the return of kthread_run() to see if it succeeds. Return a failure if the kthread_run() doesn't succeed. - Clear user events state on fork in case of alloc failure On fork, the child gets a pointer to the parent's user events state. It makes a copy of it then updates the child's pointer to it. But if the allocation fails, the duplication function leaves the child with a pointer to its parent's descriptor. When the child cleans up its data, it will free the parent's descriptor while the parent is still using it. In the duplication function, set the child's user_event_mm to NULL before testing if the allocation succeeded, and when it exits it will not free the parent's descriptor. - Fix retry exhaustion in simple ring buffer reader swap simple_ring_buffer_swap_reader_page() starts with retry set to 8 and post-decrements it only after a failed link replacement. On the final attempt, a successful replacement leaves retry at zero, while a failed replacement leaves it at -1. But the check for success expects the retry value to be non-zero and exits with an error on zero. This is the opposite result. Fix it. - Fail nicely when the remote swap_reader_page() returns an error Currently, if the swap_reader_page() of a remote buffer fails, it triggers a WARN_ON_ONCE() and continues normally. Instead, have it exit with an error and a pr_warn() print instead of a full WARNING. * tag 'trace-v7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: ring-buffer: Stop remote reader update when page swap fails tracing: Fix retry exhaustion in simple ring buffer reader swap tracing/user_events: Clear copied tracing state before fork duplication samples/ftrace: Fix kthread_stop() on ERR_PTR in ftrace-direct-multi-modify samples/ftrace: Fix kthread_stop() on ERR_PTR in ftrace-direct-modify eventfs: Initialize ei->children and ei->list in init_ei() tracing: Fix use-after-free in trace_pipe read on sub-buffer order change tracing: Fix crash passing ERR_PTR to kthread_stop() tracing: Fix use-after-free with same-name named triggers tracing: Fix logged instance name on creation failure --- drivers/reset/reset-th1520.c | 983 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 983 insertions(+) create mode 100644 drivers/reset/reset-th1520.c (limited to 'drivers/reset/reset-th1520.c') 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 + */ + +#include +#include +#include +#include + +#include + + /* 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 "); +MODULE_DESCRIPTION("T-HEAD TH1520 SoC reset controller"); +MODULE_LICENSE("GPL"); -- cgit v1.3.1