1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * TI CPUFreq/OPP hw-supported driver 4 * 5 * Copyright (C) 2016-2017 Texas Instruments, Inc. 6 * Dave Gerlach <d-gerlach@ti.com> 7 */ 8 9 #include <linux/cpu.h> 10 #include <linux/io.h> 11 #include <linux/mfd/syscon.h> 12 #include <linux/module.h> 13 #include <linux/init.h> 14 #include <linux/of.h> 15 #include <linux/of_platform.h> 16 #include <linux/pm_opp.h> 17 #include <linux/regmap.h> 18 #include <linux/slab.h> 19 20 #define REVISION_MASK 0xF 21 #define REVISION_SHIFT 28 22 23 #define AM33XX_800M_ARM_MPU_MAX_FREQ 0x1E2F 24 #define AM43XX_600M_ARM_MPU_MAX_FREQ 0xFFA 25 26 #define DRA7_EFUSE_HAS_OD_MPU_OPP 11 27 #define DRA7_EFUSE_HAS_HIGH_MPU_OPP 15 28 #define DRA76_EFUSE_HAS_PLUS_MPU_OPP 18 29 #define DRA7_EFUSE_HAS_ALL_MPU_OPP 23 30 #define DRA76_EFUSE_HAS_ALL_MPU_OPP 24 31 32 #define DRA7_EFUSE_NOM_MPU_OPP BIT(0) 33 #define DRA7_EFUSE_OD_MPU_OPP BIT(1) 34 #define DRA7_EFUSE_HIGH_MPU_OPP BIT(2) 35 #define DRA76_EFUSE_PLUS_MPU_OPP BIT(3) 36 37 #define OMAP3_CONTROL_DEVICE_STATUS 0x4800244C 38 #define OMAP3_CONTROL_IDCODE 0x4830A204 39 #define OMAP34xx_ProdID_SKUID 0x4830A20C 40 #define OMAP3_SYSCON_BASE (0x48000000 + 0x2000 + 0x270) 41 42 #define VERSION_COUNT 2 43 44 struct ti_cpufreq_data; 45 46 struct ti_cpufreq_soc_data { 47 const char * const *reg_names; 48 unsigned long (*efuse_xlate)(struct ti_cpufreq_data *opp_data, 49 unsigned long efuse); 50 unsigned long efuse_fallback; 51 unsigned long efuse_offset; 52 unsigned long efuse_mask; 53 unsigned long efuse_shift; 54 unsigned long rev_offset; 55 bool multi_regulator; 56 }; 57 58 struct ti_cpufreq_data { 59 struct device *cpu_dev; 60 struct device_node *opp_node; 61 struct regmap *syscon; 62 const struct ti_cpufreq_soc_data *soc_data; 63 }; 64 65 static unsigned long amx3_efuse_xlate(struct ti_cpufreq_data *opp_data, 66 unsigned long efuse) 67 { 68 if (!efuse) 69 efuse = opp_data->soc_data->efuse_fallback; 70 /* AM335x and AM437x use "OPP disable" bits, so invert */ 71 return ~efuse; 72 } 73 74 static unsigned long dra7_efuse_xlate(struct ti_cpufreq_data *opp_data, 75 unsigned long efuse) 76 { 77 unsigned long calculated_efuse = DRA7_EFUSE_NOM_MPU_OPP; 78 79 /* 80 * The efuse on dra7 and am57 parts contains a specific 81 * value indicating the highest available OPP. 82 */ 83 84 switch (efuse) { 85 case DRA76_EFUSE_HAS_PLUS_MPU_OPP: 86 case DRA76_EFUSE_HAS_ALL_MPU_OPP: 87 calculated_efuse |= DRA76_EFUSE_PLUS_MPU_OPP; 88 fallthrough; 89 case DRA7_EFUSE_HAS_ALL_MPU_OPP: 90 case DRA7_EFUSE_HAS_HIGH_MPU_OPP: 91 calculated_efuse |= DRA7_EFUSE_HIGH_MPU_OPP; 92 fallthrough; 93 case DRA7_EFUSE_HAS_OD_MPU_OPP: 94 calculated_efuse |= DRA7_EFUSE_OD_MPU_OPP; 95 } 96 97 return calculated_efuse; 98 } 99 100 static unsigned long omap3_efuse_xlate(struct ti_cpufreq_data *opp_data, 101 unsigned long efuse) 102 { 103 /* OPP enable bit ("Speed Binned") */ 104 return BIT(efuse); 105 } 106 107 static struct ti_cpufreq_soc_data am3x_soc_data = { 108 .efuse_xlate = amx3_efuse_xlate, 109 .efuse_fallback = AM33XX_800M_ARM_MPU_MAX_FREQ, 110 .efuse_offset = 0x07fc, 111 .efuse_mask = 0x1fff, 112 .rev_offset = 0x600, 113 .multi_regulator = false, 114 }; 115 116 static struct ti_cpufreq_soc_data am4x_soc_data = { 117 .efuse_xlate = amx3_efuse_xlate, 118 .efuse_fallback = AM43XX_600M_ARM_MPU_MAX_FREQ, 119 .efuse_offset = 0x0610, 120 .efuse_mask = 0x3f, 121 .rev_offset = 0x600, 122 .multi_regulator = false, 123 }; 124 125 static struct ti_cpufreq_soc_data dra7_soc_data = { 126 .efuse_xlate = dra7_efuse_xlate, 127 .efuse_offset = 0x020c, 128 .efuse_mask = 0xf80000, 129 .efuse_shift = 19, 130 .rev_offset = 0x204, 131 .multi_regulator = true, 132 }; 133 134 /* 135 * OMAP35x TRM (SPRUF98K): 136 * CONTROL_IDCODE (0x4830 A204) describes Silicon revisions. 137 * Control OMAP Status Register 15:0 (Address 0x4800 244C) 138 * to separate between omap3503, omap3515, omap3525, omap3530 139 * and feature presence. 140 * There are encodings for versions limited to 400/266MHz 141 * but we ignore. 142 * Not clear if this also holds for omap34xx. 143 * some eFuse values e.g. CONTROL_FUSE_OPP1_VDD1 144 * are stored in the SYSCON register range 145 * Register 0x4830A20C [ProdID.SKUID] [0:3] 146 * 0x0 for normal 600/430MHz device. 147 * 0x8 for 720/520MHz device. 148 * Not clear what omap34xx value is. 149 */ 150 151 static struct ti_cpufreq_soc_data omap34xx_soc_data = { 152 .efuse_xlate = omap3_efuse_xlate, 153 .efuse_offset = OMAP34xx_ProdID_SKUID - OMAP3_SYSCON_BASE, 154 .efuse_shift = 3, 155 .efuse_mask = BIT(3), 156 .rev_offset = OMAP3_CONTROL_IDCODE - OMAP3_SYSCON_BASE, 157 .multi_regulator = false, 158 }; 159 160 /* 161 * AM/DM37x TRM (SPRUGN4M) 162 * CONTROL_IDCODE (0x4830 A204) describes Silicon revisions. 163 * Control Device Status Register 15:0 (Address 0x4800 244C) 164 * to separate between am3703, am3715, dm3725, dm3730 165 * and feature presence. 166 * Speed Binned = Bit 9 167 * 0 800/600 MHz 168 * 1 1000/800 MHz 169 * some eFuse values e.g. CONTROL_FUSE_OPP 1G_VDD1 170 * are stored in the SYSCON register range. 171 * There is no 0x4830A20C [ProdID.SKUID] register (exists but 172 * seems to always read as 0). 173 */ 174 175 static const char * const omap3_reg_names[] = {"cpu0", "vbb", NULL}; 176 177 static struct ti_cpufreq_soc_data omap36xx_soc_data = { 178 .reg_names = omap3_reg_names, 179 .efuse_xlate = omap3_efuse_xlate, 180 .efuse_offset = OMAP3_CONTROL_DEVICE_STATUS - OMAP3_SYSCON_BASE, 181 .efuse_shift = 9, 182 .efuse_mask = BIT(9), 183 .rev_offset = OMAP3_CONTROL_IDCODE - OMAP3_SYSCON_BASE, 184 .multi_regulator = true, 185 }; 186 187 /* 188 * AM3517 is quite similar to AM/DM37x except that it has no 189 * high speed grade eFuse and no abb ldo 190 */ 191 192 static struct ti_cpufreq_soc_data am3517_soc_data = { 193 .efuse_xlate = omap3_efuse_xlate, 194 .efuse_offset = OMAP3_CONTROL_DEVICE_STATUS - OMAP3_SYSCON_BASE, 195 .efuse_shift = 0, 196 .efuse_mask = 0, 197 .rev_offset = OMAP3_CONTROL_IDCODE - OMAP3_SYSCON_BASE, 198 .multi_regulator = false, 199 }; 200 201 202 /** 203 * ti_cpufreq_get_efuse() - Parse and return efuse value present on SoC 204 * @opp_data: pointer to ti_cpufreq_data context 205 * @efuse_value: Set to the value parsed from efuse 206 * 207 * Returns error code if efuse not read properly. 208 */ 209 static int ti_cpufreq_get_efuse(struct ti_cpufreq_data *opp_data, 210 u32 *efuse_value) 211 { 212 struct device *dev = opp_data->cpu_dev; 213 u32 efuse; 214 int ret; 215 216 ret = regmap_read(opp_data->syscon, opp_data->soc_data->efuse_offset, 217 &efuse); 218 if (ret == -EIO) { 219 /* not a syscon register! */ 220 void __iomem *regs = ioremap(OMAP3_SYSCON_BASE + 221 opp_data->soc_data->efuse_offset, 4); 222 223 if (!regs) 224 return -ENOMEM; 225 efuse = readl(regs); 226 iounmap(regs); 227 } 228 else if (ret) { 229 dev_err(dev, 230 "Failed to read the efuse value from syscon: %d\n", 231 ret); 232 return ret; 233 } 234 235 efuse = (efuse & opp_data->soc_data->efuse_mask); 236 efuse >>= opp_data->soc_data->efuse_shift; 237 238 *efuse_value = opp_data->soc_data->efuse_xlate(opp_data, efuse); 239 240 return 0; 241 } 242 243 /** 244 * ti_cpufreq_get_rev() - Parse and return rev value present on SoC 245 * @opp_data: pointer to ti_cpufreq_data context 246 * @revision_value: Set to the value parsed from revision register 247 * 248 * Returns error code if revision not read properly. 249 */ 250 static int ti_cpufreq_get_rev(struct ti_cpufreq_data *opp_data, 251 u32 *revision_value) 252 { 253 struct device *dev = opp_data->cpu_dev; 254 u32 revision; 255 int ret; 256 257 ret = regmap_read(opp_data->syscon, opp_data->soc_data->rev_offset, 258 &revision); 259 if (ret == -EIO) { 260 /* not a syscon register! */ 261 void __iomem *regs = ioremap(OMAP3_SYSCON_BASE + 262 opp_data->soc_data->rev_offset, 4); 263 264 if (!regs) 265 return -ENOMEM; 266 revision = readl(regs); 267 iounmap(regs); 268 } 269 else if (ret) { 270 dev_err(dev, 271 "Failed to read the revision number from syscon: %d\n", 272 ret); 273 return ret; 274 } 275 276 *revision_value = BIT((revision >> REVISION_SHIFT) & REVISION_MASK); 277 278 return 0; 279 } 280 281 static int ti_cpufreq_setup_syscon_register(struct ti_cpufreq_data *opp_data) 282 { 283 struct device *dev = opp_data->cpu_dev; 284 struct device_node *np = opp_data->opp_node; 285 286 opp_data->syscon = syscon_regmap_lookup_by_phandle(np, 287 "syscon"); 288 if (IS_ERR(opp_data->syscon)) { 289 dev_err(dev, 290 "\"syscon\" is missing, cannot use OPPv2 table.\n"); 291 return PTR_ERR(opp_data->syscon); 292 } 293 294 return 0; 295 } 296 297 static const struct of_device_id ti_cpufreq_of_match[] = { 298 { .compatible = "ti,am33xx", .data = &am3x_soc_data, }, 299 { .compatible = "ti,am3517", .data = &am3517_soc_data, }, 300 { .compatible = "ti,am43", .data = &am4x_soc_data, }, 301 { .compatible = "ti,dra7", .data = &dra7_soc_data }, 302 { .compatible = "ti,omap34xx", .data = &omap34xx_soc_data, }, 303 { .compatible = "ti,omap36xx", .data = &omap36xx_soc_data, }, 304 /* legacy */ 305 { .compatible = "ti,omap3430", .data = &omap34xx_soc_data, }, 306 { .compatible = "ti,omap3630", .data = &omap36xx_soc_data, }, 307 {}, 308 }; 309 310 static const struct of_device_id *ti_cpufreq_match_node(void) 311 { 312 struct device_node *np; 313 const struct of_device_id *match; 314 315 np = of_find_node_by_path("/"); 316 match = of_match_node(ti_cpufreq_of_match, np); 317 of_node_put(np); 318 319 return match; 320 } 321 322 static int ti_cpufreq_probe(struct platform_device *pdev) 323 { 324 u32 version[VERSION_COUNT]; 325 const struct of_device_id *match; 326 struct ti_cpufreq_data *opp_data; 327 const char * const default_reg_names[] = {"vdd", "vbb", NULL}; 328 int ret; 329 struct dev_pm_opp_config config = { 330 .supported_hw = version, 331 .supported_hw_count = ARRAY_SIZE(version), 332 }; 333 334 match = dev_get_platdata(&pdev->dev); 335 if (!match) 336 return -ENODEV; 337 338 opp_data = devm_kzalloc(&pdev->dev, sizeof(*opp_data), GFP_KERNEL); 339 if (!opp_data) 340 return -ENOMEM; 341 342 opp_data->soc_data = match->data; 343 344 opp_data->cpu_dev = get_cpu_device(0); 345 if (!opp_data->cpu_dev) { 346 pr_err("%s: Failed to get device for CPU0\n", __func__); 347 return -ENODEV; 348 } 349 350 opp_data->opp_node = dev_pm_opp_of_get_opp_desc_node(opp_data->cpu_dev); 351 if (!opp_data->opp_node) { 352 dev_info(opp_data->cpu_dev, 353 "OPP-v2 not supported, cpufreq-dt will attempt to use legacy tables.\n"); 354 goto register_cpufreq_dt; 355 } 356 357 ret = ti_cpufreq_setup_syscon_register(opp_data); 358 if (ret) 359 goto fail_put_node; 360 361 /* 362 * OPPs determine whether or not they are supported based on 363 * two metrics: 364 * 0 - SoC Revision 365 * 1 - eFuse value 366 */ 367 ret = ti_cpufreq_get_rev(opp_data, &version[0]); 368 if (ret) 369 goto fail_put_node; 370 371 ret = ti_cpufreq_get_efuse(opp_data, &version[1]); 372 if (ret) 373 goto fail_put_node; 374 375 if (opp_data->soc_data->multi_regulator) { 376 if (opp_data->soc_data->reg_names) 377 config.regulator_names = opp_data->soc_data->reg_names; 378 else 379 config.regulator_names = default_reg_names; 380 } 381 382 ret = dev_pm_opp_set_config(opp_data->cpu_dev, &config); 383 if (ret < 0) { 384 dev_err(opp_data->cpu_dev, "Failed to set OPP config\n"); 385 goto fail_put_node; 386 } 387 388 of_node_put(opp_data->opp_node); 389 390 register_cpufreq_dt: 391 platform_device_register_simple("cpufreq-dt", -1, NULL, 0); 392 393 return 0; 394 395 fail_put_node: 396 of_node_put(opp_data->opp_node); 397 398 return ret; 399 } 400 401 static int __init ti_cpufreq_init(void) 402 { 403 const struct of_device_id *match; 404 405 /* Check to ensure we are on a compatible platform */ 406 match = ti_cpufreq_match_node(); 407 if (match) 408 platform_device_register_data(NULL, "ti-cpufreq", -1, match, 409 sizeof(*match)); 410 411 return 0; 412 } 413 module_init(ti_cpufreq_init); 414 415 static struct platform_driver ti_cpufreq_driver = { 416 .probe = ti_cpufreq_probe, 417 .driver = { 418 .name = "ti-cpufreq", 419 }, 420 }; 421 builtin_platform_driver(ti_cpufreq_driver); 422 423 MODULE_DESCRIPTION("TI CPUFreq/OPP hw-supported driver"); 424 MODULE_AUTHOR("Dave Gerlach <d-gerlach@ti.com>"); 425 MODULE_LICENSE("GPL v2"); 426