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. */ 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. */ 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 */ 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 */ 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 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 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