1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2014,2015, Linaro Ltd. 5 * 6 * SAW power controller driver 7 */ 8 9 #include <linux/kernel.h> 10 #include <linux/init.h> 11 #include <linux/io.h> 12 #include <linux/slab.h> 13 #include <linux/of.h> 14 #include <linux/of_address.h> 15 #include <linux/of_device.h> 16 #include <linux/err.h> 17 #include <linux/platform_device.h> 18 #include <linux/cpuidle.h> 19 #include <linux/cpu_pm.h> 20 #include <linux/qcom_scm.h> 21 22 #include <asm/proc-fns.h> 23 #include <asm/suspend.h> 24 25 #include "dt_idle_states.h" 26 27 #define MAX_PMIC_DATA 2 28 #define MAX_SEQ_DATA 64 29 #define SPM_CTL_INDEX 0x7f 30 #define SPM_CTL_INDEX_SHIFT 4 31 #define SPM_CTL_EN BIT(0) 32 33 enum pm_sleep_mode { 34 PM_SLEEP_MODE_STBY, 35 PM_SLEEP_MODE_RET, 36 PM_SLEEP_MODE_SPC, 37 PM_SLEEP_MODE_PC, 38 PM_SLEEP_MODE_NR, 39 }; 40 41 enum spm_reg { 42 SPM_REG_CFG, 43 SPM_REG_SPM_CTL, 44 SPM_REG_DLY, 45 SPM_REG_PMIC_DLY, 46 SPM_REG_PMIC_DATA_0, 47 SPM_REG_PMIC_DATA_1, 48 SPM_REG_VCTL, 49 SPM_REG_SEQ_ENTRY, 50 SPM_REG_SPM_STS, 51 SPM_REG_PMIC_STS, 52 SPM_REG_NR, 53 }; 54 55 struct spm_reg_data { 56 const u8 *reg_offset; 57 u32 spm_cfg; 58 u32 spm_dly; 59 u32 pmic_dly; 60 u32 pmic_data[MAX_PMIC_DATA]; 61 u8 seq[MAX_SEQ_DATA]; 62 u8 start_index[PM_SLEEP_MODE_NR]; 63 }; 64 65 struct spm_driver_data { 66 struct cpuidle_driver cpuidle_driver; 67 void __iomem *reg_base; 68 const struct spm_reg_data *reg_data; 69 }; 70 71 static const u8 spm_reg_offset_v2_1[SPM_REG_NR] = { 72 [SPM_REG_CFG] = 0x08, 73 [SPM_REG_SPM_CTL] = 0x30, 74 [SPM_REG_DLY] = 0x34, 75 [SPM_REG_SEQ_ENTRY] = 0x80, 76 }; 77 78 /* SPM register data for 8974, 8084 */ 79 static const struct spm_reg_data spm_reg_8974_8084_cpu = { 80 .reg_offset = spm_reg_offset_v2_1, 81 .spm_cfg = 0x1, 82 .spm_dly = 0x3C102800, 83 .seq = { 0x03, 0x0B, 0x0F, 0x00, 0x20, 0x80, 0x10, 0xE8, 0x5B, 0x03, 84 0x3B, 0xE8, 0x5B, 0x82, 0x10, 0x0B, 0x30, 0x06, 0x26, 0x30, 85 0x0F }, 86 .start_index[PM_SLEEP_MODE_STBY] = 0, 87 .start_index[PM_SLEEP_MODE_SPC] = 3, 88 }; 89 90 /* SPM register data for 8226 */ 91 static const struct spm_reg_data spm_reg_8226_cpu = { 92 .reg_offset = spm_reg_offset_v2_1, 93 .spm_cfg = 0x0, 94 .spm_dly = 0x3C102800, 95 .seq = { 0x60, 0x03, 0x60, 0x0B, 0x0F, 0x20, 0x10, 0x80, 0x30, 0x90, 96 0x5B, 0x60, 0x03, 0x60, 0x3B, 0x76, 0x76, 0x0B, 0x94, 0x5B, 97 0x80, 0x10, 0x26, 0x30, 0x0F }, 98 .start_index[PM_SLEEP_MODE_STBY] = 0, 99 .start_index[PM_SLEEP_MODE_SPC] = 5, 100 }; 101 102 static const u8 spm_reg_offset_v1_1[SPM_REG_NR] = { 103 [SPM_REG_CFG] = 0x08, 104 [SPM_REG_SPM_CTL] = 0x20, 105 [SPM_REG_PMIC_DLY] = 0x24, 106 [SPM_REG_PMIC_DATA_0] = 0x28, 107 [SPM_REG_PMIC_DATA_1] = 0x2C, 108 [SPM_REG_SEQ_ENTRY] = 0x80, 109 }; 110 111 /* SPM register data for 8064 */ 112 static const struct spm_reg_data spm_reg_8064_cpu = { 113 .reg_offset = spm_reg_offset_v1_1, 114 .spm_cfg = 0x1F, 115 .pmic_dly = 0x02020004, 116 .pmic_data[0] = 0x0084009C, 117 .pmic_data[1] = 0x00A4001C, 118 .seq = { 0x03, 0x0F, 0x00, 0x24, 0x54, 0x10, 0x09, 0x03, 0x01, 119 0x10, 0x54, 0x30, 0x0C, 0x24, 0x30, 0x0F }, 120 .start_index[PM_SLEEP_MODE_STBY] = 0, 121 .start_index[PM_SLEEP_MODE_SPC] = 2, 122 }; 123 124 static inline void spm_register_write(struct spm_driver_data *drv, 125 enum spm_reg reg, u32 val) 126 { 127 if (drv->reg_data->reg_offset[reg]) 128 writel_relaxed(val, drv->reg_base + 129 drv->reg_data->reg_offset[reg]); 130 } 131 132 /* Ensure a guaranteed write, before return */ 133 static inline void spm_register_write_sync(struct spm_driver_data *drv, 134 enum spm_reg reg, u32 val) 135 { 136 u32 ret; 137 138 if (!drv->reg_data->reg_offset[reg]) 139 return; 140 141 do { 142 writel_relaxed(val, drv->reg_base + 143 drv->reg_data->reg_offset[reg]); 144 ret = readl_relaxed(drv->reg_base + 145 drv->reg_data->reg_offset[reg]); 146 if (ret == val) 147 break; 148 cpu_relax(); 149 } while (1); 150 } 151 152 static inline u32 spm_register_read(struct spm_driver_data *drv, 153 enum spm_reg reg) 154 { 155 return readl_relaxed(drv->reg_base + drv->reg_data->reg_offset[reg]); 156 } 157 158 static void spm_set_low_power_mode(struct spm_driver_data *drv, 159 enum pm_sleep_mode mode) 160 { 161 u32 start_index; 162 u32 ctl_val; 163 164 start_index = drv->reg_data->start_index[mode]; 165 166 ctl_val = spm_register_read(drv, SPM_REG_SPM_CTL); 167 ctl_val &= ~(SPM_CTL_INDEX << SPM_CTL_INDEX_SHIFT); 168 ctl_val |= start_index << SPM_CTL_INDEX_SHIFT; 169 ctl_val |= SPM_CTL_EN; 170 spm_register_write_sync(drv, SPM_REG_SPM_CTL, ctl_val); 171 } 172 173 static int qcom_pm_collapse(unsigned long int unused) 174 { 175 qcom_scm_cpu_power_down(QCOM_SCM_CPU_PWR_DOWN_L2_ON); 176 177 /* 178 * Returns here only if there was a pending interrupt and we did not 179 * power down as a result. 180 */ 181 return -1; 182 } 183 184 static int qcom_cpu_spc(struct spm_driver_data *drv) 185 { 186 int ret; 187 188 spm_set_low_power_mode(drv, PM_SLEEP_MODE_SPC); 189 ret = cpu_suspend(0, qcom_pm_collapse); 190 /* 191 * ARM common code executes WFI without calling into our driver and 192 * if the SPM mode is not reset, then we may accidently power down the 193 * cpu when we intended only to gate the cpu clock. 194 * Ensure the state is set to standby before returning. 195 */ 196 spm_set_low_power_mode(drv, PM_SLEEP_MODE_STBY); 197 198 return ret; 199 } 200 201 static int spm_enter_idle_state(struct cpuidle_device *dev, 202 struct cpuidle_driver *drv, int idx) 203 { 204 struct spm_driver_data *data = container_of(drv, struct spm_driver_data, 205 cpuidle_driver); 206 207 return CPU_PM_CPU_IDLE_ENTER_PARAM(qcom_cpu_spc, idx, data); 208 } 209 210 static struct cpuidle_driver qcom_spm_idle_driver = { 211 .name = "qcom_spm", 212 .owner = THIS_MODULE, 213 .states[0] = { 214 .enter = spm_enter_idle_state, 215 .exit_latency = 1, 216 .target_residency = 1, 217 .power_usage = UINT_MAX, 218 .name = "WFI", 219 .desc = "ARM WFI", 220 } 221 }; 222 223 static const struct of_device_id qcom_idle_state_match[] = { 224 { .compatible = "qcom,idle-state-spc", .data = spm_enter_idle_state }, 225 { }, 226 }; 227 228 static int spm_cpuidle_init(struct cpuidle_driver *drv, int cpu) 229 { 230 int ret; 231 232 memcpy(drv, &qcom_spm_idle_driver, sizeof(*drv)); 233 drv->cpumask = (struct cpumask *)cpumask_of(cpu); 234 235 /* Parse idle states from device tree */ 236 ret = dt_init_idle_driver(drv, qcom_idle_state_match, 1); 237 if (ret <= 0) 238 return ret ? : -ENODEV; 239 240 /* We have atleast one power down mode */ 241 return qcom_scm_set_warm_boot_addr(cpu_resume_arm, drv->cpumask); 242 } 243 244 static struct spm_driver_data *spm_get_drv(struct platform_device *pdev, 245 int *spm_cpu) 246 { 247 struct spm_driver_data *drv = NULL; 248 struct device_node *cpu_node, *saw_node; 249 int cpu; 250 bool found = 0; 251 252 for_each_possible_cpu(cpu) { 253 cpu_node = of_cpu_device_node_get(cpu); 254 if (!cpu_node) 255 continue; 256 saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0); 257 found = (saw_node == pdev->dev.of_node); 258 of_node_put(saw_node); 259 of_node_put(cpu_node); 260 if (found) 261 break; 262 } 263 264 if (found) { 265 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL); 266 if (drv) 267 *spm_cpu = cpu; 268 } 269 270 return drv; 271 } 272 273 static const struct of_device_id spm_match_table[] = { 274 { .compatible = "qcom,msm8226-saw2-v2.1-cpu", 275 .data = &spm_reg_8226_cpu }, 276 { .compatible = "qcom,msm8974-saw2-v2.1-cpu", 277 .data = &spm_reg_8974_8084_cpu }, 278 { .compatible = "qcom,apq8084-saw2-v2.1-cpu", 279 .data = &spm_reg_8974_8084_cpu }, 280 { .compatible = "qcom,apq8064-saw2-v1.1-cpu", 281 .data = &spm_reg_8064_cpu }, 282 { }, 283 }; 284 285 static int spm_dev_probe(struct platform_device *pdev) 286 { 287 struct spm_driver_data *drv; 288 struct resource *res; 289 const struct of_device_id *match_id; 290 void __iomem *addr; 291 int cpu, ret; 292 293 if (!qcom_scm_is_available()) 294 return -EPROBE_DEFER; 295 296 drv = spm_get_drv(pdev, &cpu); 297 if (!drv) 298 return -EINVAL; 299 platform_set_drvdata(pdev, drv); 300 301 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 302 drv->reg_base = devm_ioremap_resource(&pdev->dev, res); 303 if (IS_ERR(drv->reg_base)) 304 return PTR_ERR(drv->reg_base); 305 306 match_id = of_match_node(spm_match_table, pdev->dev.of_node); 307 if (!match_id) 308 return -ENODEV; 309 310 drv->reg_data = match_id->data; 311 312 ret = spm_cpuidle_init(&drv->cpuidle_driver, cpu); 313 if (ret) 314 return ret; 315 316 /* Write the SPM sequences first.. */ 317 addr = drv->reg_base + drv->reg_data->reg_offset[SPM_REG_SEQ_ENTRY]; 318 __iowrite32_copy(addr, drv->reg_data->seq, 319 ARRAY_SIZE(drv->reg_data->seq) / 4); 320 321 /* 322 * ..and then the control registers. 323 * On some SoC if the control registers are written first and if the 324 * CPU was held in reset, the reset signal could trigger the SPM state 325 * machine, before the sequences are completely written. 326 */ 327 spm_register_write(drv, SPM_REG_CFG, drv->reg_data->spm_cfg); 328 spm_register_write(drv, SPM_REG_DLY, drv->reg_data->spm_dly); 329 spm_register_write(drv, SPM_REG_PMIC_DLY, drv->reg_data->pmic_dly); 330 spm_register_write(drv, SPM_REG_PMIC_DATA_0, 331 drv->reg_data->pmic_data[0]); 332 spm_register_write(drv, SPM_REG_PMIC_DATA_1, 333 drv->reg_data->pmic_data[1]); 334 335 /* Set up Standby as the default low power mode */ 336 spm_set_low_power_mode(drv, PM_SLEEP_MODE_STBY); 337 338 return cpuidle_register(&drv->cpuidle_driver, NULL); 339 } 340 341 static int spm_dev_remove(struct platform_device *pdev) 342 { 343 struct spm_driver_data *drv = platform_get_drvdata(pdev); 344 345 cpuidle_unregister(&drv->cpuidle_driver); 346 return 0; 347 } 348 349 static struct platform_driver spm_driver = { 350 .probe = spm_dev_probe, 351 .remove = spm_dev_remove, 352 .driver = { 353 .name = "saw", 354 .of_match_table = spm_match_table, 355 }, 356 }; 357 358 builtin_platform_driver(spm_driver); 359