xref: /linux/drivers/soc/samsung/gs101-pmu.c (revision 208eed95fc710827b100266c9450ae84d46727bd)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright 2025 Linaro Ltd.
4  *
5  * GS101 PMU (Power Management Unit) support
6  */
7 
8 #include <linux/arm-smccc.h>
9 #include <linux/array_size.h>
10 #include <linux/soc/samsung/exynos-pmu.h>
11 #include <linux/soc/samsung/exynos-regs-pmu.h>
12 #include <linux/regmap.h>
13 
14 #include "exynos-pmu.h"
15 
16 #define PMUALIVE_MASK			GENMASK(13, 0)
17 #define TENSOR_SET_BITS			(BIT(15) | BIT(14))
18 #define TENSOR_CLR_BITS			BIT(15)
19 #define TENSOR_SMC_PMU_SEC_REG		0x82000504
20 #define TENSOR_PMUREG_READ		0
21 #define TENSOR_PMUREG_WRITE		1
22 #define TENSOR_PMUREG_RMW		2
23 
24 static const struct regmap_range gs101_pmu_registers[] = {
25 	regmap_reg_range(GS101_OM_STAT, GS101_SYSTEM_INFO),
26 	regmap_reg_range(GS101_IDLE_IP(0), GS101_IDLE_IP_MASK(3)),
27 	regmap_reg_range(GS101_DATARAM_STATE_SLC_CH(0),
28 			 GS101_PPMPURAM_INFORM_SCL_CH(3)),
29 	regmap_reg_range(GS101_INFORM0, GS101_SYSIP_DAT(0)),
30 	/* skip SYSIP_DAT1 SYSIP_DAT2 */
31 	regmap_reg_range(GS101_SYSIP_DAT(3), GS101_PWR_HOLD_SW_TRIP),
32 	regmap_reg_range(GS101_GSA_INFORM(0), GS101_GSA_INFORM(1)),
33 	regmap_reg_range(GS101_INFORM4, GS101_IROM_INFORM),
34 	regmap_reg_range(GS101_IROM_CPU_INFORM(0), GS101_IROM_CPU_INFORM(7)),
35 	regmap_reg_range(GS101_PMU_SPARE(0), GS101_PMU_SPARE(3)),
36 	/* skip most IROM_xxx registers */
37 	regmap_reg_range(GS101_DREX_CALIBRATION(0), GS101_DREX_CALIBRATION(7)),
38 
39 #define CLUSTER_CPU_RANGE(cl, cpu)					\
40 	regmap_reg_range(GS101_CLUSTER_CPU_CONFIGURATION(cl, cpu),	\
41 			 GS101_CLUSTER_CPU_OPTION(cl, cpu)),		\
42 	regmap_reg_range(GS101_CLUSTER_CPU_OUT(cl, cpu),		\
43 			 GS101_CLUSTER_CPU_IN(cl, cpu)),		\
44 	regmap_reg_range(GS101_CLUSTER_CPU_INT_IN(cl, cpu),		\
45 			 GS101_CLUSTER_CPU_INT_DIR(cl, cpu))
46 
47 	/* cluster 0..2 and cpu 0..4 or 0..1 */
48 	CLUSTER_CPU_RANGE(GS101_CLUSTER0_OFFSET, 0),
49 	CLUSTER_CPU_RANGE(GS101_CLUSTER0_OFFSET, 1),
50 	CLUSTER_CPU_RANGE(GS101_CLUSTER0_OFFSET, 2),
51 	CLUSTER_CPU_RANGE(GS101_CLUSTER0_OFFSET, 3),
52 	CLUSTER_CPU_RANGE(GS101_CLUSTER1_OFFSET, 0),
53 	CLUSTER_CPU_RANGE(GS101_CLUSTER1_OFFSET, 1),
54 	CLUSTER_CPU_RANGE(GS101_CLUSTER2_OFFSET, 0),
55 	CLUSTER_CPU_RANGE(GS101_CLUSTER2_OFFSET, 1),
56 #undef CLUSTER_CPU_RANGE
57 
58 #define CLUSTER_NONCPU_RANGE(cl)					\
59 	regmap_reg_range(GS101_CLUSTER_NONCPU_CONFIGURATION(cl),	\
60 			 GS101_CLUSTER_NONCPU_OPTION(cl)),		\
61 	regmap_reg_range(GS101_CLUSTER_NONCPU_OUT(cl),			\
62 			 GS101_CLUSTER_NONCPU_IN(cl)),			\
63 	regmap_reg_range(GS101_CLUSTER_NONCPU_INT_IN(cl),		\
64 			 GS101_CLUSTER_NONCPU_INT_DIR(cl)),		\
65 	regmap_reg_range(GS101_CLUSTER_NONCPU_DUALRAIL_CTRL_OUT(cl),	\
66 			 GS101_CLUSTER_NONCPU_DUALRAIL_POS_OUT(cl)),	\
67 	regmap_reg_range(GS101_CLUSTER_NONCPU_DUALRAIL_CTRL_IN(cl),	\
68 			 GS101_CLUSTER_NONCPU_DUALRAIL_CTRL_IN(cl))
69 
70 	CLUSTER_NONCPU_RANGE(0),
71 	regmap_reg_range(GS101_CLUSTER0_NONCPU_DSU_PCH,
72 			 GS101_CLUSTER0_NONCPU_DSU_PCH),
73 	CLUSTER_NONCPU_RANGE(1),
74 	CLUSTER_NONCPU_RANGE(2),
75 #undef CLUSTER_NONCPU_RANGE
76 
77 #define SUBBLK_RANGE(blk)						\
78 	regmap_reg_range(GS101_SUBBLK_CONFIGURATION(blk),		\
79 			 GS101_SUBBLK_CTRL(blk)),			\
80 	regmap_reg_range(GS101_SUBBLK_OUT(blk), GS101_SUBBLK_IN(blk)),	\
81 	regmap_reg_range(GS101_SUBBLK_INT_IN(blk),			\
82 			 GS101_SUBBLK_INT_DIR(blk)),			\
83 	regmap_reg_range(GS101_SUBBLK_MEMORY_OUT(blk),			\
84 			 GS101_SUBBLK_MEMORY_IN(blk))
85 
86 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_ALIVE),
87 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_AOC),
88 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_APM),
89 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CMU),
90 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_BUS0),
91 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_BUS1),
92 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_BUS2),
93 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CORE),
94 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_EH),
95 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CPUCL0),
96 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CPUCL1),
97 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CPUCL2),
98 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_G3D),
99 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_EMBEDDED_CPUCL0),
100 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_EMBEDDED_G3D),
101 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_HSI0),
102 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_HSI1),
103 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_HSI2),
104 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_DPU),
105 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_DISP),
106 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_G2D),
107 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MFC),
108 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CSIS),
109 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_PDP),
110 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_DNS),
111 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_G3AA),
112 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_IPP),
113 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_ITP),
114 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MCSC),
115 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_GDC),
116 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_TNR),
117 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_BO),
118 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_TPU),
119 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MIF0),
120 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MIF1),
121 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MIF2),
122 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MIF3),
123 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MISC),
124 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_PERIC0),
125 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_PERIC1),
126 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_S2D),
127 #undef SUBBLK_RANGE
128 
129 #define SUBBLK_CPU_RANGE(blk)						\
130 	regmap_reg_range(GS101_SUBBLK_CPU_CONFIGURATION(blk),		\
131 			 GS101_SUBBLK_CPU_OPTION(blk)),			\
132 	regmap_reg_range(GS101_SUBBLK_CPU_OUT(blk),			\
133 			 GS101_SUBBLK_CPU_IN(blk)),			\
134 	regmap_reg_range(GS101_SUBBLK_CPU_INT_IN(blk),			\
135 			 GS101_SUBBLK_CPU_INT_DIR(blk))
136 
137 	SUBBLK_CPU_RANGE(GS101_SUBBBLK_CPU_OFFSET_APM),
138 	SUBBLK_CPU_RANGE(GS101_SUBBBLK_CPU_OFFSET_DBGCORE),
139 	SUBBLK_CPU_RANGE(GS101_SUBBBLK_CPU_OFFSET_SSS),
140 #undef SUBBLK_CPU_RANGE
141 
142 	regmap_reg_range(GS101_MIF_CONFIGURATION, GS101_MIF_CTRL),
143 	regmap_reg_range(GS101_MIF_OUT, GS101_MIF_IN),
144 	regmap_reg_range(GS101_MIF_INT_IN, GS101_MIF_INT_DIR),
145 	regmap_reg_range(GS101_TOP_CONFIGURATION, GS101_TOP_OPTION),
146 	regmap_reg_range(GS101_TOP_OUT, GS101_TOP_IN),
147 	regmap_reg_range(GS101_TOP_INT_IN, GS101_WAKEUP2_STAT),
148 	regmap_reg_range(GS101_WAKEUP2_INT_IN, GS101_WAKEUP2_INT_DIR),
149 	regmap_reg_range(GS101_SYSTEM_CONFIGURATION, GS101_USER_DEFINED_OUT),
150 	regmap_reg_range(GS101_SYSTEM_OUT, GS101_SYSTEM_IN),
151 	regmap_reg_range(GS101_SYSTEM_INT_IN, GS101_EINT_WAKEUP_MASK3),
152 	regmap_reg_range(GS101_USER_DEFINED_INT_IN, GS101_SCAN2DRAM_INT_DIR),
153 	/* skip HCU_START */
154 	regmap_reg_range(GS101_CUSTOM_OUT, GS101_CUSTOM_IN),
155 	regmap_reg_range(GS101_CUSTOM_INT_IN, GS101_CUSTOM_INT_DIR),
156 	regmap_reg_range(GS101_ACK_LAST_CPU, GS101_HCU_R(3)),
157 	regmap_reg_range(GS101_HCU_SP, GS101_HCU_PC),
158 	/* skip PMU_RAM_CTRL */
159 	regmap_reg_range(GS101_APM_HCU_CTRL, GS101_APM_HCU_CTRL),
160 	regmap_reg_range(GS101_APM_NMI_ENABLE, GS101_RST_STAT_PMU),
161 	regmap_reg_range(GS101_HPM_INT_IN, GS101_BOOT_STAT),
162 	regmap_reg_range(GS101_PMLINK_OUT, GS101_PMLINK_AOC_CTRL),
163 	regmap_reg_range(GS101_TCXO_BUF_CTRL, GS101_ADD_CTRL),
164 	regmap_reg_range(GS101_HCU_TIMEOUT_RESET, GS101_HCU_TIMEOUT_SCAN2DRAM),
165 	regmap_reg_range(GS101_TIMER(0), GS101_TIMER(3)),
166 	regmap_reg_range(GS101_PPC_MIF(0), GS101_PPC_EH),
167 	/* PPC_OFFSET, skip PPC_CPUCL1_0 PPC_CPUCL1_1 */
168 	regmap_reg_range(GS101_EXT_REGULATOR_MIF_DURATION, GS101_TCXO_DURATION),
169 	regmap_reg_range(GS101_BURNIN_CTRL, GS101_TMU_SUB_TRIP),
170 	regmap_reg_range(GS101_MEMORY_CEN, GS101_MEMORY_SMX_FEEDBACK),
171 	regmap_reg_range(GS101_SLC_PCH_CHANNEL, GS101_SLC_PCH_CB),
172 	regmap_reg_range(GS101_FORCE_NOMC, GS101_FORCE_NOMC),
173 	regmap_reg_range(GS101_FORCE_BOOST, GS101_PMLINK_SLC_BUSY),
174 	regmap_reg_range(GS101_BOOTSYNC_OUT, GS101_CTRL_SECJTAG_ALIVE),
175 	regmap_reg_range(GS101_CTRL_DIV_PLL_ALV_DIVLOW, GS101_CTRL_CLKDIV__CLKRTC),
176 	regmap_reg_range(GS101_CTRL_SOC32K, GS101_CTRL_SBU_SW_EN),
177 	regmap_reg_range(GS101_PAD_CTRL_CLKOUT0, GS101_PAD_CTRL_WRESETO_n),
178 	regmap_reg_range(GS101_PHY_CTRL_USB20, GS101_PHY_CTRL_UFS),
179 };
180 
181 static const struct regmap_range gs101_pmu_ro_registers[] = {
182 	regmap_reg_range(GS101_OM_STAT, GS101_VERSION),
183 	regmap_reg_range(GS101_OTP_STATUS, GS101_OTP_STATUS),
184 
185 	regmap_reg_range(GS101_DATARAM_STATE_SLC_CH(0),
186 			 GS101_PPMPURAM_STATE_SLC_CH(0)),
187 	regmap_reg_range(GS101_DATARAM_STATE_SLC_CH(1),
188 			 GS101_PPMPURAM_STATE_SLC_CH(1)),
189 	regmap_reg_range(GS101_DATARAM_STATE_SLC_CH(2),
190 			 GS101_PPMPURAM_STATE_SLC_CH(2)),
191 	regmap_reg_range(GS101_DATARAM_STATE_SLC_CH(3),
192 			 GS101_PPMPURAM_STATE_SLC_CH(3)),
193 
194 #define CLUSTER_CPU_RANGE(cl, cpu)					\
195 	regmap_reg_range(GS101_CLUSTER_CPU_IN(cl, cpu),			\
196 			 GS101_CLUSTER_CPU_IN(cl, cpu)),		\
197 	regmap_reg_range(GS101_CLUSTER_CPU_INT_IN(cl, cpu),		\
198 			 GS101_CLUSTER_CPU_INT_IN(cl, cpu))
199 
200 	CLUSTER_CPU_RANGE(GS101_CLUSTER0_OFFSET, 0),
201 	CLUSTER_CPU_RANGE(GS101_CLUSTER0_OFFSET, 1),
202 	CLUSTER_CPU_RANGE(GS101_CLUSTER0_OFFSET, 2),
203 	CLUSTER_CPU_RANGE(GS101_CLUSTER0_OFFSET, 3),
204 	CLUSTER_CPU_RANGE(GS101_CLUSTER1_OFFSET, 0),
205 	CLUSTER_CPU_RANGE(GS101_CLUSTER1_OFFSET, 1),
206 	CLUSTER_CPU_RANGE(GS101_CLUSTER2_OFFSET, 0),
207 	CLUSTER_CPU_RANGE(GS101_CLUSTER2_OFFSET, 1),
208 #undef CLUSTER_CPU_RANGE
209 
210 #define CLUSTER_NONCPU_RANGE(cl)					\
211 	regmap_reg_range(GS101_CLUSTER_NONCPU_IN(cl),			\
212 			 GS101_CLUSTER_NONCPU_IN(cl)),			\
213 	regmap_reg_range(GS101_CLUSTER_NONCPU_INT_IN(cl),		\
214 			 GS101_CLUSTER_NONCPU_INT_IN(cl)),		\
215 	regmap_reg_range(GS101_CLUSTER_NONCPU_DUALRAIL_CTRL_IN(cl),	\
216 			 GS101_CLUSTER_NONCPU_DUALRAIL_CTRL_IN(cl))
217 
218 	CLUSTER_NONCPU_RANGE(0),
219 	CLUSTER_NONCPU_RANGE(1),
220 	CLUSTER_NONCPU_RANGE(2),
221 	regmap_reg_range(GS101_CLUSTER_NONCPU_INT_EN(2),
222 			 GS101_CLUSTER_NONCPU_INT_DIR(2)),
223 #undef CLUSTER_NONCPU_RANGE
224 
225 #define SUBBLK_RANGE(blk)						\
226 	regmap_reg_range(GS101_SUBBLK_IN(blk), GS101_SUBBLK_IN(blk)),	\
227 	regmap_reg_range(GS101_SUBBLK_INT_IN(blk),			\
228 			 GS101_SUBBLK_INT_IN(blk)),			\
229 	regmap_reg_range(GS101_SUBBLK_MEMORY_IN(blk),			\
230 			 GS101_SUBBLK_MEMORY_IN(blk))
231 
232 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_ALIVE),
233 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_AOC),
234 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_APM),
235 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CMU),
236 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_BUS0),
237 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_BUS1),
238 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_BUS2),
239 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CORE),
240 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_EH),
241 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CPUCL0),
242 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CPUCL1),
243 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CPUCL2),
244 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_G3D),
245 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_EMBEDDED_CPUCL0),
246 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_EMBEDDED_G3D),
247 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_HSI0),
248 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_HSI1),
249 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_HSI2),
250 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_DPU),
251 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_DISP),
252 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_G2D),
253 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MFC),
254 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CSIS),
255 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_PDP),
256 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_DNS),
257 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_G3AA),
258 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_IPP),
259 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_ITP),
260 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MCSC),
261 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_GDC),
262 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_TNR),
263 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_BO),
264 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_TPU),
265 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MIF0),
266 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MIF1),
267 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MIF2),
268 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MIF3),
269 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MISC),
270 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_PERIC0),
271 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_PERIC1),
272 	SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_S2D),
273 #undef SUBBLK_RANGE
274 
275 #define SUBBLK_CPU_RANGE(blk)						\
276 	regmap_reg_range(GS101_SUBBLK_CPU_IN(blk),			\
277 			 GS101_SUBBLK_CPU_IN(blk)),			\
278 	regmap_reg_range(GS101_SUBBLK_CPU_INT_IN(blk),			\
279 			 GS101_SUBBLK_CPU_INT_IN(blk))
280 
281 	SUBBLK_CPU_RANGE(GS101_SUBBBLK_CPU_OFFSET_APM),
282 	SUBBLK_CPU_RANGE(GS101_SUBBBLK_CPU_OFFSET_DBGCORE),
283 	SUBBLK_CPU_RANGE(GS101_SUBBBLK_CPU_OFFSET_SSS),
284 #undef SUBBLK_CPU_RANGE
285 
286 	regmap_reg_range(GS101_MIF_CONFIGURATION, GS101_MIF_CONFIGURATION),
287 	regmap_reg_range(GS101_MIF_IN, GS101_MIF_IN),
288 	regmap_reg_range(GS101_MIF_INT_IN, GS101_MIF_INT_IN),
289 	regmap_reg_range(GS101_TOP_IN, GS101_TOP_IN),
290 	regmap_reg_range(GS101_TOP_INT_IN, GS101_TOP_INT_IN),
291 	regmap_reg_range(GS101_WAKEUP2_INT_IN, GS101_WAKEUP2_INT_IN),
292 	regmap_reg_range(GS101_SYSTEM_IN, GS101_SYSTEM_IN),
293 	regmap_reg_range(GS101_SYSTEM_INT_IN, GS101_SYSTEM_INT_IN),
294 	regmap_reg_range(GS101_EINT_INT_IN, GS101_EINT_INT_IN),
295 	regmap_reg_range(GS101_EINT2_INT_IN, GS101_EINT2_INT_IN),
296 	regmap_reg_range(GS101_EINT3_INT_IN, GS101_EINT3_INT_IN),
297 	regmap_reg_range(GS101_USER_DEFINED_INT_IN, GS101_USER_DEFINED_INT_IN),
298 	regmap_reg_range(GS101_SCAN2DRAM_INT_IN, GS101_SCAN2DRAM_INT_IN),
299 	regmap_reg_range(GS101_CUSTOM_IN, GS101_CUSTOM_IN),
300 	regmap_reg_range(GS101_CUSTOM_INT_IN, GS101_CUSTOM_INT_IN),
301 	regmap_reg_range(GS101_HCU_R(0), GS101_HCU_R(3)),
302 	regmap_reg_range(GS101_HCU_SP, GS101_HCU_PC),
303 	regmap_reg_range(GS101_NMI_SRC_IN, GS101_NMI_SRC_IN),
304 	regmap_reg_range(GS101_HPM_INT_IN, GS101_HPM_INT_IN),
305 	regmap_reg_range(GS101_MEMORY_PGEN_FEEDBACK, GS101_MEMORY_PGEN_FEEDBACK),
306 	regmap_reg_range(GS101_MEMORY_SMX_FEEDBACK, GS101_MEMORY_SMX_FEEDBACK),
307 	regmap_reg_range(GS101_PMLINK_SLC_ACK, GS101_PMLINK_SLC_BUSY),
308 	regmap_reg_range(GS101_BOOTSYNC_IN, GS101_BOOTSYNC_IN),
309 	regmap_reg_range(GS101_SCAN_READY_IN, GS101_SCAN_READY_IN),
310 	regmap_reg_range(GS101_CTRL_PLL_ALV_LOCK, GS101_CTRL_PLL_ALV_LOCK),
311 };
312 
313 static const struct regmap_access_table gs101_pmu_rd_table = {
314 	.yes_ranges = gs101_pmu_registers,
315 	.n_yes_ranges = ARRAY_SIZE(gs101_pmu_registers),
316 };
317 
318 static const struct regmap_access_table gs101_pmu_wr_table = {
319 	.yes_ranges = gs101_pmu_registers,
320 	.n_yes_ranges = ARRAY_SIZE(gs101_pmu_registers),
321 	.no_ranges = gs101_pmu_ro_registers,
322 	.n_no_ranges = ARRAY_SIZE(gs101_pmu_ro_registers),
323 };
324 
325 const struct exynos_pmu_data gs101_pmu_data = {
326 	.pmu_secure = true,
327 	.pmu_cpuhp = true,
328 	.rd_table = &gs101_pmu_rd_table,
329 	.wr_table = &gs101_pmu_wr_table,
330 };
331 
332 /*
333  * Tensor SoCs are configured so that PMU_ALIVE registers can only be written
334  * from EL3, but are still read accessible. As Linux needs to write some of
335  * these registers, the following functions are provided and exposed via
336  * regmap.
337  *
338  * Note: This SMC interface is known to be implemented on gs101 and derivative
339  * SoCs.
340  */
341 
342 /* Write to a protected PMU register. */
tensor_sec_reg_write(void * context,unsigned int reg,unsigned int val)343 int tensor_sec_reg_write(void *context, unsigned int reg, unsigned int val)
344 {
345 	struct arm_smccc_res res;
346 	unsigned long pmu_base = (unsigned long)context;
347 
348 	arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
349 		      TENSOR_PMUREG_WRITE, val, 0, 0, 0, 0, &res);
350 
351 	/* returns -EINVAL if access isn't allowed or 0 */
352 	if (res.a0)
353 		pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
354 
355 	return (int)res.a0;
356 }
357 
358 /* Read/Modify/Write a protected PMU register. */
tensor_sec_reg_rmw(void * context,unsigned int reg,unsigned int mask,unsigned int val)359 static int tensor_sec_reg_rmw(void *context, unsigned int reg,
360 			      unsigned int mask, unsigned int val)
361 {
362 	struct arm_smccc_res res;
363 	unsigned long pmu_base = (unsigned long)context;
364 
365 	arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
366 		      TENSOR_PMUREG_RMW, mask, val, 0, 0, 0, &res);
367 
368 	/* returns -EINVAL if access isn't allowed or 0 */
369 	if (res.a0)
370 		pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
371 
372 	return (int)res.a0;
373 }
374 
375 /*
376  * Read a protected PMU register. All PMU registers can be read by Linux.
377  * Note: The SMC read register is not used, as only registers that can be
378  * written are readable via SMC.
379  */
tensor_sec_reg_read(void * context,unsigned int reg,unsigned int * val)380 int tensor_sec_reg_read(void *context, unsigned int reg, unsigned int *val)
381 {
382 	*val = pmu_raw_readl(reg);
383 	return 0;
384 }
385 
386 /*
387  * For SoCs that have set/clear bit hardware this function can be used when
388  * the PMU register will be accessed by multiple masters.
389  *
390  * For example, to set bits 13:8 in PMU reg offset 0x3e80
391  * tensor_set_bits_atomic(ctx, 0x3e80, 0x3f00, 0x3f00);
392  *
393  * Set bit 8, and clear bits 13:9 PMU reg offset 0x3e80
394  * tensor_set_bits_atomic(0x3e80, 0x100, 0x3f00);
395  */
tensor_set_bits_atomic(void * context,unsigned int offset,u32 val,u32 mask)396 static int tensor_set_bits_atomic(void *context, unsigned int offset, u32 val,
397 				  u32 mask)
398 {
399 	int ret;
400 	unsigned int i;
401 
402 	for (i = 0; i < 32; i++) {
403 		if (!(mask & BIT(i)))
404 			continue;
405 
406 		offset &= ~TENSOR_SET_BITS;
407 
408 		if (val & BIT(i))
409 			offset |= TENSOR_SET_BITS;
410 		else
411 			offset |= TENSOR_CLR_BITS;
412 
413 		ret = tensor_sec_reg_write(context, offset, i);
414 		if (ret)
415 			return ret;
416 	}
417 	return 0;
418 }
419 
tensor_is_atomic(unsigned int reg)420 static bool tensor_is_atomic(unsigned int reg)
421 {
422 	/*
423 	 * Use atomic operations for PMU_ALIVE registers (offset 0~0x3FFF)
424 	 * as the target registers can be accessed by multiple masters. SFRs
425 	 * that don't support atomic are added to the switch statement below.
426 	 */
427 	if (reg > PMUALIVE_MASK)
428 		return false;
429 
430 	switch (reg) {
431 	case GS101_SYSIP_DAT(0):
432 	case GS101_SYSTEM_CONFIGURATION:
433 		return false;
434 	default:
435 		return true;
436 	}
437 }
438 
tensor_sec_update_bits(void * context,unsigned int reg,unsigned int mask,unsigned int val)439 int tensor_sec_update_bits(void *context, unsigned int reg, unsigned int mask,
440 			   unsigned int val)
441 {
442 	if (!tensor_is_atomic(reg))
443 		return tensor_sec_reg_rmw(context, reg, mask, val);
444 
445 	return tensor_set_bits_atomic(context, reg, val, mask);
446 }
447