1 /* 2 * ti-sysc.c - Texas Instruments sysc interconnect target driver 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 9 * kind, whether express or implied; without even the implied warranty 10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 */ 13 14 #include <linux/io.h> 15 #include <linux/clk.h> 16 #include <linux/module.h> 17 #include <linux/platform_device.h> 18 #include <linux/pm_runtime.h> 19 #include <linux/of_address.h> 20 #include <linux/of_platform.h> 21 22 enum sysc_registers { 23 SYSC_REVISION, 24 SYSC_SYSCONFIG, 25 SYSC_SYSSTATUS, 26 SYSC_MAX_REGS, 27 }; 28 29 static const char * const reg_names[] = { "rev", "sysc", "syss", }; 30 31 enum sysc_clocks { 32 SYSC_FCK, 33 SYSC_ICK, 34 SYSC_MAX_CLOCKS, 35 }; 36 37 static const char * const clock_names[] = { "fck", "ick", }; 38 39 /** 40 * struct sysc - TI sysc interconnect target module registers and capabilities 41 * @dev: struct device pointer 42 * @module_pa: physical address of the interconnect target module 43 * @module_size: size of the interconnect target module 44 * @module_va: virtual address of the interconnect target module 45 * @offsets: register offsets from module base 46 * @clocks: clocks used by the interconnect target module 47 * @legacy_mode: configured for legacy mode if set 48 */ 49 struct sysc { 50 struct device *dev; 51 u64 module_pa; 52 u32 module_size; 53 void __iomem *module_va; 54 int offsets[SYSC_MAX_REGS]; 55 struct clk *clocks[SYSC_MAX_CLOCKS]; 56 const char *legacy_mode; 57 }; 58 59 static u32 sysc_read_revision(struct sysc *ddata) 60 { 61 return readl_relaxed(ddata->module_va + 62 ddata->offsets[SYSC_REVISION]); 63 } 64 65 static int sysc_get_one_clock(struct sysc *ddata, 66 enum sysc_clocks index) 67 { 68 const char *name; 69 int error; 70 71 switch (index) { 72 case SYSC_FCK: 73 break; 74 case SYSC_ICK: 75 break; 76 default: 77 return -EINVAL; 78 } 79 name = clock_names[index]; 80 81 ddata->clocks[index] = devm_clk_get(ddata->dev, name); 82 if (IS_ERR(ddata->clocks[index])) { 83 if (PTR_ERR(ddata->clocks[index]) == -ENOENT) 84 return 0; 85 86 dev_err(ddata->dev, "clock get error for %s: %li\n", 87 name, PTR_ERR(ddata->clocks[index])); 88 89 return PTR_ERR(ddata->clocks[index]); 90 } 91 92 error = clk_prepare(ddata->clocks[index]); 93 if (error) { 94 dev_err(ddata->dev, "clock prepare error for %s: %i\n", 95 name, error); 96 97 return error; 98 } 99 100 return 0; 101 } 102 103 static int sysc_get_clocks(struct sysc *ddata) 104 { 105 int i, error; 106 107 if (ddata->legacy_mode) 108 return 0; 109 110 for (i = 0; i < SYSC_MAX_CLOCKS; i++) { 111 error = sysc_get_one_clock(ddata, i); 112 if (error && error != -ENOENT) 113 return error; 114 } 115 116 return 0; 117 } 118 119 /** 120 * sysc_parse_and_check_child_range - parses module IO region from ranges 121 * @ddata: device driver data 122 * 123 * In general we only need rev, syss, and sysc registers and not the whole 124 * module range. But we do want the offsets for these registers from the 125 * module base. This allows us to check them against the legacy hwmod 126 * platform data. Let's also check the ranges are configured properly. 127 */ 128 static int sysc_parse_and_check_child_range(struct sysc *ddata) 129 { 130 struct device_node *np = ddata->dev->of_node; 131 const __be32 *ranges; 132 u32 nr_addr, nr_size; 133 int len, error; 134 135 ranges = of_get_property(np, "ranges", &len); 136 if (!ranges) { 137 dev_err(ddata->dev, "missing ranges for %pOF\n", np); 138 139 return -ENOENT; 140 } 141 142 len /= sizeof(*ranges); 143 144 if (len < 3) { 145 dev_err(ddata->dev, "incomplete ranges for %pOF\n", np); 146 147 return -EINVAL; 148 } 149 150 error = of_property_read_u32(np, "#address-cells", &nr_addr); 151 if (error) 152 return -ENOENT; 153 154 error = of_property_read_u32(np, "#size-cells", &nr_size); 155 if (error) 156 return -ENOENT; 157 158 if (nr_addr != 1 || nr_size != 1) { 159 dev_err(ddata->dev, "invalid ranges for %pOF\n", np); 160 161 return -EINVAL; 162 } 163 164 ranges++; 165 ddata->module_pa = of_translate_address(np, ranges++); 166 ddata->module_size = be32_to_cpup(ranges); 167 168 dev_dbg(ddata->dev, "interconnect target 0x%llx size 0x%x for %pOF\n", 169 ddata->module_pa, ddata->module_size, np); 170 171 return 0; 172 } 173 174 /** 175 * sysc_check_one_child - check child configuration 176 * @ddata: device driver data 177 * @np: child device node 178 * 179 * Let's avoid messy situations where we have new interconnect target 180 * node but children have "ti,hwmods". These belong to the interconnect 181 * target node and are managed by this driver. 182 */ 183 static int sysc_check_one_child(struct sysc *ddata, 184 struct device_node *np) 185 { 186 const char *name; 187 188 name = of_get_property(np, "ti,hwmods", NULL); 189 if (name) 190 dev_warn(ddata->dev, "really a child ti,hwmods property?"); 191 192 return 0; 193 } 194 195 static int sysc_check_children(struct sysc *ddata) 196 { 197 struct device_node *child; 198 int error; 199 200 for_each_child_of_node(ddata->dev->of_node, child) { 201 error = sysc_check_one_child(ddata, child); 202 if (error) 203 return error; 204 } 205 206 return 0; 207 } 208 209 /** 210 * sysc_parse_one - parses the interconnect target module registers 211 * @ddata: device driver data 212 * @reg: register to parse 213 */ 214 static int sysc_parse_one(struct sysc *ddata, enum sysc_registers reg) 215 { 216 struct resource *res; 217 const char *name; 218 219 switch (reg) { 220 case SYSC_REVISION: 221 case SYSC_SYSCONFIG: 222 case SYSC_SYSSTATUS: 223 name = reg_names[reg]; 224 break; 225 default: 226 return -EINVAL; 227 } 228 229 res = platform_get_resource_byname(to_platform_device(ddata->dev), 230 IORESOURCE_MEM, name); 231 if (!res) { 232 dev_dbg(ddata->dev, "has no %s register\n", name); 233 ddata->offsets[reg] = -ENODEV; 234 235 return 0; 236 } 237 238 ddata->offsets[reg] = res->start - ddata->module_pa; 239 240 return 0; 241 } 242 243 static int sysc_parse_registers(struct sysc *ddata) 244 { 245 int i, error; 246 247 for (i = 0; i < SYSC_MAX_REGS; i++) { 248 error = sysc_parse_one(ddata, i); 249 if (error) 250 return error; 251 } 252 253 return 0; 254 } 255 256 /** 257 * sysc_check_registers - check for misconfigured register overlaps 258 * @ddata: device driver data 259 */ 260 static int sysc_check_registers(struct sysc *ddata) 261 { 262 int i, j, nr_regs = 0, nr_matches = 0; 263 264 for (i = 0; i < SYSC_MAX_REGS; i++) { 265 if (ddata->offsets[i] < 0) 266 continue; 267 268 if (ddata->offsets[i] > (ddata->module_size - 4)) { 269 dev_err(ddata->dev, "register outside module range"); 270 271 return -EINVAL; 272 } 273 274 for (j = 0; j < SYSC_MAX_REGS; j++) { 275 if (ddata->offsets[j] < 0) 276 continue; 277 278 if (ddata->offsets[i] == ddata->offsets[j]) 279 nr_matches++; 280 } 281 nr_regs++; 282 } 283 284 if (nr_regs < 1) { 285 dev_err(ddata->dev, "missing registers\n"); 286 287 return -EINVAL; 288 } 289 290 if (nr_matches > nr_regs) { 291 dev_err(ddata->dev, "overlapping registers: (%i/%i)", 292 nr_regs, nr_matches); 293 294 return -EINVAL; 295 } 296 297 return 0; 298 } 299 300 /** 301 * syc_ioremap - ioremap register space for the interconnect target module 302 * @ddata: deviec driver data 303 * 304 * Note that the interconnect target module registers can be anywhere 305 * within the first child device address space. For example, SGX has 306 * them at offset 0x1fc00 in the 32MB module address space. We just 307 * what we need around the interconnect target module registers. 308 */ 309 static int sysc_ioremap(struct sysc *ddata) 310 { 311 u32 size = 0; 312 313 if (ddata->offsets[SYSC_SYSSTATUS] >= 0) 314 size = ddata->offsets[SYSC_SYSSTATUS]; 315 else if (ddata->offsets[SYSC_SYSCONFIG] >= 0) 316 size = ddata->offsets[SYSC_SYSCONFIG]; 317 else if (ddata->offsets[SYSC_REVISION] >= 0) 318 size = ddata->offsets[SYSC_REVISION]; 319 else 320 return -EINVAL; 321 322 size &= 0xfff00; 323 size += SZ_256; 324 325 ddata->module_va = devm_ioremap(ddata->dev, 326 ddata->module_pa, 327 size); 328 if (!ddata->module_va) 329 return -EIO; 330 331 return 0; 332 } 333 334 /** 335 * sysc_map_and_check_registers - ioremap and check device registers 336 * @ddata: device driver data 337 */ 338 static int sysc_map_and_check_registers(struct sysc *ddata) 339 { 340 int error; 341 342 error = sysc_parse_and_check_child_range(ddata); 343 if (error) 344 return error; 345 346 error = sysc_check_children(ddata); 347 if (error) 348 return error; 349 350 error = sysc_parse_registers(ddata); 351 if (error) 352 return error; 353 354 error = sysc_ioremap(ddata); 355 if (error) 356 return error; 357 358 error = sysc_check_registers(ddata); 359 if (error) 360 return error; 361 362 return 0; 363 } 364 365 /** 366 * sysc_show_rev - read and show interconnect target module revision 367 * @bufp: buffer to print the information to 368 * @ddata: device driver data 369 */ 370 static int sysc_show_rev(char *bufp, struct sysc *ddata) 371 { 372 int error, len; 373 374 if (ddata->offsets[SYSC_REVISION] < 0) 375 return sprintf(bufp, ":NA"); 376 377 error = pm_runtime_get_sync(ddata->dev); 378 if (error < 0) { 379 pm_runtime_put_noidle(ddata->dev); 380 381 return 0; 382 } 383 384 len = sprintf(bufp, ":%08x", sysc_read_revision(ddata)); 385 386 pm_runtime_mark_last_busy(ddata->dev); 387 pm_runtime_put_autosuspend(ddata->dev); 388 389 return len; 390 } 391 392 static int sysc_show_reg(struct sysc *ddata, 393 char *bufp, enum sysc_registers reg) 394 { 395 if (ddata->offsets[reg] < 0) 396 return sprintf(bufp, ":NA"); 397 398 return sprintf(bufp, ":%x", ddata->offsets[reg]); 399 } 400 401 /** 402 * sysc_show_registers - show information about interconnect target module 403 * @ddata: device driver data 404 */ 405 static void sysc_show_registers(struct sysc *ddata) 406 { 407 char buf[128]; 408 char *bufp = buf; 409 int i; 410 411 for (i = 0; i < SYSC_MAX_REGS; i++) 412 bufp += sysc_show_reg(ddata, bufp, i); 413 414 bufp += sysc_show_rev(bufp, ddata); 415 416 dev_dbg(ddata->dev, "%llx:%x%s\n", 417 ddata->module_pa, ddata->module_size, 418 buf); 419 } 420 421 static int __maybe_unused sysc_runtime_suspend(struct device *dev) 422 { 423 struct sysc *ddata; 424 int i; 425 426 ddata = dev_get_drvdata(dev); 427 428 if (ddata->legacy_mode) 429 return 0; 430 431 for (i = 0; i < SYSC_MAX_CLOCKS; i++) { 432 if (IS_ERR_OR_NULL(ddata->clocks[i])) 433 continue; 434 clk_disable(ddata->clocks[i]); 435 } 436 437 return 0; 438 } 439 440 static int __maybe_unused sysc_runtime_resume(struct device *dev) 441 { 442 struct sysc *ddata; 443 int i, error; 444 445 ddata = dev_get_drvdata(dev); 446 447 if (ddata->legacy_mode) 448 return 0; 449 450 for (i = 0; i < SYSC_MAX_CLOCKS; i++) { 451 if (IS_ERR_OR_NULL(ddata->clocks[i])) 452 continue; 453 error = clk_enable(ddata->clocks[i]); 454 if (error) 455 return error; 456 } 457 458 return 0; 459 } 460 461 static const struct dev_pm_ops sysc_pm_ops = { 462 SET_RUNTIME_PM_OPS(sysc_runtime_suspend, 463 sysc_runtime_resume, 464 NULL) 465 }; 466 467 static void sysc_unprepare(struct sysc *ddata) 468 { 469 int i; 470 471 for (i = 0; i < SYSC_MAX_CLOCKS; i++) { 472 if (!IS_ERR_OR_NULL(ddata->clocks[i])) 473 clk_unprepare(ddata->clocks[i]); 474 } 475 } 476 477 static int sysc_probe(struct platform_device *pdev) 478 { 479 struct device_node *np = pdev->dev.of_node; 480 struct sysc *ddata; 481 int error; 482 483 ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL); 484 if (!ddata) 485 return -ENOMEM; 486 487 ddata->dev = &pdev->dev; 488 ddata->legacy_mode = of_get_property(np, "ti,hwmods", NULL); 489 490 error = sysc_get_clocks(ddata); 491 if (error) 492 return error; 493 494 error = sysc_map_and_check_registers(ddata); 495 if (error) 496 goto unprepare; 497 498 platform_set_drvdata(pdev, ddata); 499 500 pm_runtime_enable(ddata->dev); 501 error = pm_runtime_get_sync(ddata->dev); 502 if (error < 0) { 503 pm_runtime_put_noidle(ddata->dev); 504 pm_runtime_disable(ddata->dev); 505 goto unprepare; 506 } 507 508 pm_runtime_use_autosuspend(ddata->dev); 509 510 sysc_show_registers(ddata); 511 512 error = of_platform_populate(ddata->dev->of_node, 513 NULL, NULL, ddata->dev); 514 if (error) 515 goto err; 516 517 pm_runtime_mark_last_busy(ddata->dev); 518 pm_runtime_put_autosuspend(ddata->dev); 519 520 return 0; 521 522 err: 523 pm_runtime_dont_use_autosuspend(&pdev->dev); 524 pm_runtime_put_sync(&pdev->dev); 525 pm_runtime_disable(&pdev->dev); 526 unprepare: 527 sysc_unprepare(ddata); 528 529 return error; 530 } 531 532 static int sysc_remove(struct platform_device *pdev) 533 { 534 struct sysc *ddata = platform_get_drvdata(pdev); 535 int error; 536 537 error = pm_runtime_get_sync(ddata->dev); 538 if (error < 0) { 539 pm_runtime_put_noidle(ddata->dev); 540 pm_runtime_disable(ddata->dev); 541 goto unprepare; 542 } 543 544 of_platform_depopulate(&pdev->dev); 545 546 pm_runtime_dont_use_autosuspend(&pdev->dev); 547 pm_runtime_put_sync(&pdev->dev); 548 pm_runtime_disable(&pdev->dev); 549 550 unprepare: 551 sysc_unprepare(ddata); 552 553 return 0; 554 } 555 556 static const struct of_device_id sysc_match[] = { 557 { .compatible = "ti,sysc-omap2" }, 558 { .compatible = "ti,sysc-omap4" }, 559 { .compatible = "ti,sysc-omap4-simple" }, 560 { .compatible = "ti,sysc-omap3430-sr" }, 561 { .compatible = "ti,sysc-omap3630-sr" }, 562 { .compatible = "ti,sysc-omap4-sr" }, 563 { .compatible = "ti,sysc-omap3-sham" }, 564 { .compatible = "ti,sysc-omap-aes" }, 565 { .compatible = "ti,sysc-mcasp" }, 566 { .compatible = "ti,sysc-usb-host-fs" }, 567 { }, 568 }; 569 MODULE_DEVICE_TABLE(of, sysc_match); 570 571 static struct platform_driver sysc_driver = { 572 .probe = sysc_probe, 573 .remove = sysc_remove, 574 .driver = { 575 .name = "ti-sysc", 576 .of_match_table = sysc_match, 577 .pm = &sysc_pm_ops, 578 }, 579 }; 580 module_platform_driver(sysc_driver); 581 582 MODULE_DESCRIPTION("TI sysc interconnect target driver"); 583 MODULE_LICENSE("GPL v2"); 584