1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * OMAP2+ PRM driver 4 * 5 * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/ 6 * Tero Kristo <t-kristo@ti.com> 7 */ 8 9 #include <linux/kernel.h> 10 #include <linux/clk.h> 11 #include <linux/device.h> 12 #include <linux/io.h> 13 #include <linux/iopoll.h> 14 #include <linux/module.h> 15 #include <linux/of.h> 16 #include <linux/platform_device.h> 17 #include <linux/pm_clock.h> 18 #include <linux/pm_domain.h> 19 #include <linux/reset-controller.h> 20 #include <linux/delay.h> 21 #if IS_ENABLED(CONFIG_SUSPEND) 22 #include <linux/suspend.h> 23 #endif 24 #include <linux/platform_data/ti-prm.h> 25 26 enum omap_prm_domain_mode { 27 OMAP_PRMD_OFF, 28 OMAP_PRMD_RETENTION, 29 OMAP_PRMD_ON_INACTIVE, 30 OMAP_PRMD_ON_ACTIVE, 31 }; 32 33 struct omap_prm_domain_map { 34 unsigned int usable_modes; /* Mask of hardware supported modes */ 35 unsigned long statechange:1; /* Optional low-power state change */ 36 unsigned long logicretstate:1; /* Optional logic off mode */ 37 }; 38 39 struct omap_prm_domain { 40 struct device *dev; 41 struct omap_prm *prm; 42 struct generic_pm_domain pd; 43 u16 pwrstctrl; 44 u16 pwrstst; 45 const struct omap_prm_domain_map *cap; 46 u32 pwrstctrl_saved; 47 unsigned int uses_pm_clk:1; 48 }; 49 50 struct omap_rst_map { 51 s8 rst; 52 s8 st; 53 }; 54 55 struct omap_prm_data { 56 u32 base; 57 const char *name; 58 const char *clkdm_name; 59 u16 pwrstctrl; 60 u16 pwrstst; 61 const struct omap_prm_domain_map *dmap; 62 u16 rstctrl; 63 u16 rstst; 64 const struct omap_rst_map *rstmap; 65 u8 flags; 66 }; 67 68 struct omap_prm { 69 const struct omap_prm_data *data; 70 void __iomem *base; 71 struct omap_prm_domain *prmd; 72 }; 73 74 struct omap_reset_data { 75 struct reset_controller_dev rcdev; 76 struct omap_prm *prm; 77 u32 mask; 78 spinlock_t lock; 79 struct clockdomain *clkdm; 80 struct device *dev; 81 }; 82 83 #define genpd_to_prm_domain(gpd) container_of(gpd, struct omap_prm_domain, pd) 84 #define to_omap_reset_data(p) container_of((p), struct omap_reset_data, rcdev) 85 86 #define OMAP_MAX_RESETS 8 87 #define OMAP_RESET_MAX_WAIT 10000 88 89 #define OMAP_PRM_HAS_RSTCTRL BIT(0) 90 #define OMAP_PRM_HAS_RSTST BIT(1) 91 #define OMAP_PRM_HAS_NO_CLKDM BIT(2) 92 #define OMAP_PRM_RET_WHEN_IDLE BIT(3) 93 #define OMAP_PRM_ON_WHEN_STANDBY BIT(4) 94 95 #define OMAP_PRM_HAS_RESETS (OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_RSTST) 96 97 #define PRM_STATE_MAX_WAIT 10000 98 #define PRM_LOGICRETSTATE BIT(2) 99 #define PRM_LOWPOWERSTATECHANGE BIT(4) 100 #define PRM_POWERSTATE_MASK OMAP_PRMD_ON_ACTIVE 101 102 #define PRM_ST_INTRANSITION BIT(20) 103 104 static const struct omap_prm_domain_map omap_prm_all = { 105 .usable_modes = BIT(OMAP_PRMD_ON_ACTIVE) | BIT(OMAP_PRMD_ON_INACTIVE) | 106 BIT(OMAP_PRMD_RETENTION) | BIT(OMAP_PRMD_OFF), 107 .statechange = 1, 108 .logicretstate = 1, 109 }; 110 111 static const struct omap_prm_domain_map omap_prm_noinact = { 112 .usable_modes = BIT(OMAP_PRMD_ON_ACTIVE) | BIT(OMAP_PRMD_RETENTION) | 113 BIT(OMAP_PRMD_OFF), 114 .statechange = 1, 115 .logicretstate = 1, 116 }; 117 118 static const struct omap_prm_domain_map omap_prm_nooff = { 119 .usable_modes = BIT(OMAP_PRMD_ON_ACTIVE) | BIT(OMAP_PRMD_ON_INACTIVE) | 120 BIT(OMAP_PRMD_RETENTION), 121 .statechange = 1, 122 .logicretstate = 1, 123 }; 124 125 static const struct omap_prm_domain_map omap_prm_onoff_noauto = { 126 .usable_modes = BIT(OMAP_PRMD_ON_ACTIVE) | BIT(OMAP_PRMD_OFF), 127 .statechange = 1, 128 }; 129 130 static const struct omap_prm_domain_map omap_prm_alwon = { 131 .usable_modes = BIT(OMAP_PRMD_ON_ACTIVE), 132 }; 133 134 static const struct omap_prm_domain_map omap_prm_reton = { 135 .usable_modes = BIT(OMAP_PRMD_ON_ACTIVE) | BIT(OMAP_PRMD_RETENTION), 136 .statechange = 1, 137 .logicretstate = 1, 138 }; 139 140 static const struct omap_rst_map rst_map_0[] = { 141 { .rst = 0, .st = 0 }, 142 { .rst = -1 }, 143 }; 144 145 static const struct omap_rst_map rst_map_01[] = { 146 { .rst = 0, .st = 0 }, 147 { .rst = 1, .st = 1 }, 148 { .rst = -1 }, 149 }; 150 151 static const struct omap_rst_map rst_map_012[] = { 152 { .rst = 0, .st = 0 }, 153 { .rst = 1, .st = 1 }, 154 { .rst = 2, .st = 2 }, 155 { .rst = -1 }, 156 }; 157 158 static const struct omap_prm_data omap4_prm_data[] = { 159 { 160 .name = "mpu", .base = 0x4a306300, 161 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_reton, 162 }, 163 { 164 .name = "tesla", .base = 0x4a306400, 165 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_noinact, 166 .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 167 }, 168 { 169 .name = "abe", .base = 0x4a306500, 170 .pwrstctrl = 0, .pwrstst = 0x4, .dmap = &omap_prm_all, 171 }, 172 { 173 .name = "always_on_core", .base = 0x4a306600, 174 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon, 175 }, 176 { 177 .name = "core", .base = 0x4a306700, 178 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_reton, 179 .rstctrl = 0x210, .rstst = 0x214, .clkdm_name = "ducati", 180 .rstmap = rst_map_012, 181 .flags = OMAP_PRM_RET_WHEN_IDLE, 182 }, 183 { 184 .name = "ivahd", .base = 0x4a306f00, 185 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_noinact, 186 .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_012 187 }, 188 { 189 .name = "cam", .base = 0x4a307000, 190 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto, 191 }, 192 { 193 .name = "dss", .base = 0x4a307100, 194 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_noinact 195 }, 196 { 197 .name = "gfx", .base = 0x4a307200, 198 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto 199 }, 200 { 201 .name = "l3init", .base = 0x4a307300, 202 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_reton 203 }, 204 { 205 .name = "l4per", .base = 0x4a307400, 206 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_reton, 207 .flags = OMAP_PRM_RET_WHEN_IDLE, 208 }, 209 { 210 .name = "cefuse", .base = 0x4a307600, 211 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto 212 }, 213 { 214 .name = "wkup", .base = 0x4a307700, 215 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon 216 }, 217 { 218 .name = "emu", .base = 0x4a307900, 219 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto 220 }, 221 { 222 .name = "device", .base = 0x4a307b00, 223 .rstctrl = 0x0, .rstst = 0x4, .rstmap = rst_map_01, 224 .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM 225 }, 226 { }, 227 }; 228 229 static const struct omap_prm_data omap5_prm_data[] = { 230 { 231 .name = "mpu", .base = 0x4ae06300, 232 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_reton, 233 }, 234 { 235 .name = "dsp", .base = 0x4ae06400, 236 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_noinact, 237 .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 238 }, 239 { 240 .name = "abe", .base = 0x4ae06500, 241 .pwrstctrl = 0, .pwrstst = 0x4, .dmap = &omap_prm_nooff, 242 }, 243 { 244 .name = "coreaon", .base = 0x4ae06600, 245 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon 246 }, 247 { 248 .name = "core", .base = 0x4ae06700, 249 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_reton, 250 .rstctrl = 0x210, .rstst = 0x214, .clkdm_name = "ipu", 251 .rstmap = rst_map_012 252 }, 253 { 254 .name = "iva", .base = 0x4ae07200, 255 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_noinact, 256 .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_012 257 }, 258 { 259 .name = "cam", .base = 0x4ae07300, 260 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto 261 }, 262 { 263 .name = "dss", .base = 0x4ae07400, 264 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_noinact 265 }, 266 { 267 .name = "gpu", .base = 0x4ae07500, 268 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto 269 }, 270 { 271 .name = "l3init", .base = 0x4ae07600, 272 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_reton 273 }, 274 { 275 .name = "custefuse", .base = 0x4ae07700, 276 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto 277 }, 278 { 279 .name = "wkupaon", .base = 0x4ae07800, 280 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon 281 }, 282 { 283 .name = "emu", .base = 0x4ae07a00, 284 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto 285 }, 286 { 287 .name = "device", .base = 0x4ae07c00, 288 .rstctrl = 0x0, .rstst = 0x4, .rstmap = rst_map_01, 289 .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM 290 }, 291 { }, 292 }; 293 294 static const struct omap_prm_data dra7_prm_data[] = { 295 { 296 .name = "mpu", .base = 0x4ae06300, 297 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_reton, 298 }, 299 { 300 .name = "dsp1", .base = 0x4ae06400, 301 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto, 302 .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01, 303 }, 304 { 305 .name = "ipu", .base = 0x4ae06500, 306 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto, 307 .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_012, 308 .clkdm_name = "ipu1" 309 }, 310 { 311 .name = "coreaon", .base = 0x4ae06628, 312 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon, 313 }, 314 { 315 .name = "core", .base = 0x4ae06700, 316 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon, 317 .rstctrl = 0x210, .rstst = 0x214, .rstmap = rst_map_012, 318 .clkdm_name = "ipu2" 319 }, 320 { 321 .name = "iva", .base = 0x4ae06f00, 322 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto, 323 .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_012, 324 }, 325 { 326 .name = "cam", .base = 0x4ae07000, 327 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto, 328 }, 329 { 330 .name = "dss", .base = 0x4ae07100, 331 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto, 332 }, 333 { 334 .name = "gpu", .base = 0x4ae07200, 335 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto, 336 }, 337 { 338 .name = "l3init", .base = 0x4ae07300, 339 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon, 340 .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01, 341 .clkdm_name = "pcie" 342 }, 343 { 344 .name = "l4per", .base = 0x4ae07400, 345 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon, 346 }, 347 { 348 .name = "custefuse", .base = 0x4ae07600, 349 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto, 350 }, 351 { 352 .name = "wkupaon", .base = 0x4ae07724, 353 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon, 354 }, 355 { 356 .name = "emu", .base = 0x4ae07900, 357 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto, 358 }, 359 { 360 .name = "dsp2", .base = 0x4ae07b00, 361 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto, 362 .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 363 }, 364 { 365 .name = "eve1", .base = 0x4ae07b40, 366 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto, 367 .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 368 }, 369 { 370 .name = "eve2", .base = 0x4ae07b80, 371 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto, 372 .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 373 }, 374 { 375 .name = "eve3", .base = 0x4ae07bc0, 376 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto, 377 .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 378 }, 379 { 380 .name = "eve4", .base = 0x4ae07c00, 381 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto, 382 .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 383 }, 384 { 385 .name = "rtc", .base = 0x4ae07c60, 386 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon, 387 }, 388 { 389 .name = "vpe", .base = 0x4ae07c80, 390 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto, 391 }, 392 { }, 393 }; 394 395 static const struct omap_rst_map am3_per_rst_map[] = { 396 { .rst = 1 }, 397 { .rst = -1 }, 398 }; 399 400 static const struct omap_rst_map am3_wkup_rst_map[] = { 401 { .rst = 3, .st = 5 }, 402 { .rst = -1 }, 403 }; 404 405 static const struct omap_prm_data am3_prm_data[] = { 406 { 407 .name = "per", .base = 0x44e00c00, 408 .pwrstctrl = 0xc, .pwrstst = 0x8, .dmap = &omap_prm_noinact, 409 .rstctrl = 0x0, .rstmap = am3_per_rst_map, 410 .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_ON_WHEN_STANDBY, 411 .clkdm_name = "pruss_ocp", 412 }, 413 { 414 .name = "wkup", .base = 0x44e00d00, 415 .pwrstctrl = 0x4, .pwrstst = 0x4, .dmap = &omap_prm_alwon, 416 .rstctrl = 0x0, .rstst = 0xc, .rstmap = am3_wkup_rst_map, 417 .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM 418 }, 419 { 420 .name = "mpu", .base = 0x44e00e00, 421 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_noinact, 422 }, 423 { 424 .name = "device", .base = 0x44e00f00, 425 .rstctrl = 0x0, .rstst = 0x8, .rstmap = rst_map_01, 426 .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM 427 }, 428 { 429 .name = "rtc", .base = 0x44e01000, 430 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon, 431 }, 432 { 433 .name = "gfx", .base = 0x44e01100, 434 .pwrstctrl = 0, .pwrstst = 0x10, .dmap = &omap_prm_noinact, 435 .rstctrl = 0x4, .rstst = 0x14, .rstmap = rst_map_0, .clkdm_name = "gfx_l3", 436 }, 437 { 438 .name = "cefuse", .base = 0x44e01200, 439 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto, 440 }, 441 { }, 442 }; 443 444 static const struct omap_rst_map am4_per_rst_map[] = { 445 { .rst = 1, .st = 0 }, 446 { .rst = -1 }, 447 }; 448 449 static const struct omap_rst_map am4_device_rst_map[] = { 450 { .rst = 0, .st = 1 }, 451 { .rst = 1, .st = 0 }, 452 { .rst = -1 }, 453 }; 454 455 static const struct omap_prm_data am4_prm_data[] = { 456 { 457 .name = "mpu", .base = 0x44df0300, 458 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_noinact, 459 }, 460 { 461 .name = "gfx", .base = 0x44df0400, 462 .pwrstctrl = 0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto, 463 .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_0, .clkdm_name = "gfx_l3", 464 }, 465 { 466 .name = "rtc", .base = 0x44df0500, 467 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon, 468 }, 469 { 470 .name = "tamper", .base = 0x44df0600, 471 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon, 472 }, 473 { 474 .name = "cefuse", .base = 0x44df0700, 475 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto, 476 }, 477 { 478 .name = "per", .base = 0x44df0800, 479 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_noinact, 480 .rstctrl = 0x10, .rstst = 0x14, .rstmap = am4_per_rst_map, 481 .clkdm_name = "pruss_ocp" 482 }, 483 { 484 .name = "wkup", .base = 0x44df2000, 485 .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon, 486 .rstctrl = 0x10, .rstst = 0x14, .rstmap = am3_wkup_rst_map, 487 .flags = OMAP_PRM_HAS_NO_CLKDM 488 }, 489 { 490 .name = "device", .base = 0x44df4000, 491 .rstctrl = 0x0, .rstst = 0x4, .rstmap = am4_device_rst_map, 492 .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM 493 }, 494 { }, 495 }; 496 497 static const struct of_device_id omap_prm_id_table[] = { 498 { .compatible = "ti,omap4-prm-inst", .data = omap4_prm_data }, 499 { .compatible = "ti,omap5-prm-inst", .data = omap5_prm_data }, 500 { .compatible = "ti,dra7-prm-inst", .data = dra7_prm_data }, 501 { .compatible = "ti,am3-prm-inst", .data = am3_prm_data }, 502 { .compatible = "ti,am4-prm-inst", .data = am4_prm_data }, 503 { }, 504 }; 505 506 #ifdef DEBUG 507 static void omap_prm_domain_show_state(struct omap_prm_domain *prmd, 508 const char *desc) 509 { 510 dev_dbg(prmd->dev, "%s %s: %08x/%08x\n", 511 prmd->pd.name, desc, 512 readl_relaxed(prmd->prm->base + prmd->pwrstctrl), 513 readl_relaxed(prmd->prm->base + prmd->pwrstst)); 514 } 515 #else 516 static inline void omap_prm_domain_show_state(struct omap_prm_domain *prmd, 517 const char *desc) 518 { 519 } 520 #endif 521 522 static int omap_prm_domain_power_on(struct generic_pm_domain *domain) 523 { 524 struct omap_prm_domain *prmd; 525 int ret; 526 u32 v, mode; 527 528 prmd = genpd_to_prm_domain(domain); 529 if (!prmd->cap) 530 return 0; 531 532 omap_prm_domain_show_state(prmd, "on: previous state"); 533 534 if (prmd->pwrstctrl_saved) 535 v = prmd->pwrstctrl_saved; 536 else 537 v = readl_relaxed(prmd->prm->base + prmd->pwrstctrl); 538 539 if (prmd->prm->data->flags & OMAP_PRM_RET_WHEN_IDLE) 540 mode = OMAP_PRMD_RETENTION; 541 else 542 mode = OMAP_PRMD_ON_ACTIVE; 543 544 writel_relaxed((v & ~PRM_POWERSTATE_MASK) | mode, 545 prmd->prm->base + prmd->pwrstctrl); 546 547 /* wait for the transition bit to get cleared */ 548 ret = readl_relaxed_poll_timeout(prmd->prm->base + prmd->pwrstst, 549 v, !(v & PRM_ST_INTRANSITION), 1, 550 PRM_STATE_MAX_WAIT); 551 if (ret) 552 dev_err(prmd->dev, "%s: %s timed out\n", 553 prmd->pd.name, __func__); 554 555 omap_prm_domain_show_state(prmd, "on: new state"); 556 557 return ret; 558 } 559 560 /* No need to check for holes in the mask for the lowest mode */ 561 static int omap_prm_domain_find_lowest(struct omap_prm_domain *prmd) 562 { 563 return __ffs(prmd->cap->usable_modes); 564 } 565 566 static int omap_prm_domain_power_off(struct generic_pm_domain *domain) 567 { 568 struct omap_prm_domain *prmd; 569 int ret; 570 u32 v; 571 572 prmd = genpd_to_prm_domain(domain); 573 if (!prmd->cap) 574 return 0; 575 576 omap_prm_domain_show_state(prmd, "off: previous state"); 577 578 v = readl_relaxed(prmd->prm->base + prmd->pwrstctrl); 579 prmd->pwrstctrl_saved = v; 580 581 v &= ~PRM_POWERSTATE_MASK; 582 v |= omap_prm_domain_find_lowest(prmd); 583 584 if (prmd->cap->statechange) 585 v |= PRM_LOWPOWERSTATECHANGE; 586 if (prmd->cap->logicretstate) 587 v &= ~PRM_LOGICRETSTATE; 588 else 589 v |= PRM_LOGICRETSTATE; 590 591 writel_relaxed(v, prmd->prm->base + prmd->pwrstctrl); 592 593 /* wait for the transition bit to get cleared */ 594 ret = readl_relaxed_poll_timeout(prmd->prm->base + prmd->pwrstst, 595 v, !(v & PRM_ST_INTRANSITION), 1, 596 PRM_STATE_MAX_WAIT); 597 if (ret) 598 dev_warn(prmd->dev, "%s: %s timed out\n", 599 __func__, prmd->pd.name); 600 601 omap_prm_domain_show_state(prmd, "off: new state"); 602 603 return 0; 604 } 605 606 /* 607 * Note that ti-sysc already manages the module clocks separately so 608 * no need to manage those. Interconnect instances need clocks managed 609 * for simple-pm-bus. 610 */ 611 static int omap_prm_domain_attach_clock(struct device *dev, 612 struct omap_prm_domain *prmd) 613 { 614 struct device_node *np = dev->of_node; 615 int error; 616 617 if (!of_device_is_compatible(np, "simple-pm-bus")) 618 return 0; 619 620 if (!of_property_present(np, "clocks")) 621 return 0; 622 623 error = pm_clk_create(dev); 624 if (error) 625 return error; 626 627 error = of_pm_clk_add_clks(dev); 628 if (error < 0) { 629 pm_clk_destroy(dev); 630 return error; 631 } 632 633 prmd->uses_pm_clk = 1; 634 635 return 0; 636 } 637 638 static int omap_prm_domain_attach_dev(struct generic_pm_domain *domain, 639 struct device *dev) 640 { 641 struct generic_pm_domain_data *genpd_data; 642 struct of_phandle_args pd_args; 643 struct omap_prm_domain *prmd; 644 struct device_node *np; 645 int ret; 646 647 prmd = genpd_to_prm_domain(domain); 648 np = dev->of_node; 649 650 ret = of_parse_phandle_with_args(np, "power-domains", 651 "#power-domain-cells", 0, &pd_args); 652 if (ret < 0) 653 return ret; 654 655 if (pd_args.args_count != 0) 656 dev_warn(dev, "%s: unusupported #power-domain-cells: %i\n", 657 prmd->pd.name, pd_args.args_count); 658 659 genpd_data = dev_gpd_data(dev); 660 genpd_data->data = NULL; 661 662 ret = omap_prm_domain_attach_clock(dev, prmd); 663 if (ret) 664 return ret; 665 666 return 0; 667 } 668 669 static void omap_prm_domain_detach_dev(struct generic_pm_domain *domain, 670 struct device *dev) 671 { 672 struct generic_pm_domain_data *genpd_data; 673 struct omap_prm_domain *prmd; 674 675 prmd = genpd_to_prm_domain(domain); 676 if (prmd->uses_pm_clk) 677 pm_clk_destroy(dev); 678 genpd_data = dev_gpd_data(dev); 679 genpd_data->data = NULL; 680 } 681 682 static int omap_prm_domain_init(struct device *dev, struct omap_prm *prm) 683 { 684 struct omap_prm_domain *prmd; 685 struct device_node *np = dev->of_node; 686 const struct omap_prm_data *data; 687 const char *name; 688 int error; 689 690 if (!of_property_present(dev->of_node, "#power-domain-cells")) 691 return 0; 692 693 of_node_put(dev->of_node); 694 695 prmd = devm_kzalloc(dev, sizeof(*prmd), GFP_KERNEL); 696 if (!prmd) 697 return -ENOMEM; 698 699 data = prm->data; 700 name = devm_kasprintf(dev, GFP_KERNEL, "prm_%s", 701 data->name); 702 if (!name) 703 return -ENOMEM; 704 705 prmd->dev = dev; 706 prmd->prm = prm; 707 prmd->cap = prmd->prm->data->dmap; 708 prmd->pwrstctrl = prmd->prm->data->pwrstctrl; 709 prmd->pwrstst = prmd->prm->data->pwrstst; 710 711 prmd->pd.name = name; 712 prmd->pd.power_on = omap_prm_domain_power_on; 713 prmd->pd.power_off = omap_prm_domain_power_off; 714 prmd->pd.attach_dev = omap_prm_domain_attach_dev; 715 prmd->pd.detach_dev = omap_prm_domain_detach_dev; 716 prmd->pd.flags = GENPD_FLAG_PM_CLK; 717 718 pm_genpd_init(&prmd->pd, NULL, true); 719 error = of_genpd_add_provider_simple(np, &prmd->pd); 720 if (error) 721 pm_genpd_remove(&prmd->pd); 722 else 723 prm->prmd = prmd; 724 725 return error; 726 } 727 728 static bool _is_valid_reset(struct omap_reset_data *reset, unsigned long id) 729 { 730 if (reset->mask & BIT(id)) 731 return true; 732 733 return false; 734 } 735 736 static int omap_reset_get_st_bit(struct omap_reset_data *reset, 737 unsigned long id) 738 { 739 const struct omap_rst_map *map = reset->prm->data->rstmap; 740 741 while (map->rst >= 0) { 742 if (map->rst == id) 743 return map->st; 744 745 map++; 746 } 747 748 return id; 749 } 750 751 static int omap_reset_status(struct reset_controller_dev *rcdev, 752 unsigned long id) 753 { 754 struct omap_reset_data *reset = to_omap_reset_data(rcdev); 755 u32 v; 756 int st_bit = omap_reset_get_st_bit(reset, id); 757 bool has_rstst = reset->prm->data->rstst || 758 (reset->prm->data->flags & OMAP_PRM_HAS_RSTST); 759 760 /* Check if we have rstst */ 761 if (!has_rstst) 762 return -ENOTSUPP; 763 764 /* Check if hw reset line is asserted */ 765 v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl); 766 if (v & BIT(id)) 767 return 1; 768 769 /* 770 * Check reset status, high value means reset sequence has been 771 * completed successfully so we can return 0 here (reset deasserted) 772 */ 773 v = readl_relaxed(reset->prm->base + reset->prm->data->rstst); 774 v >>= st_bit; 775 v &= 1; 776 777 return !v; 778 } 779 780 static int omap_reset_assert(struct reset_controller_dev *rcdev, 781 unsigned long id) 782 { 783 struct omap_reset_data *reset = to_omap_reset_data(rcdev); 784 u32 v; 785 unsigned long flags; 786 787 /* assert the reset control line */ 788 spin_lock_irqsave(&reset->lock, flags); 789 v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl); 790 v |= 1 << id; 791 writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl); 792 spin_unlock_irqrestore(&reset->lock, flags); 793 794 return 0; 795 } 796 797 static int omap_reset_deassert(struct reset_controller_dev *rcdev, 798 unsigned long id) 799 { 800 struct omap_reset_data *reset = to_omap_reset_data(rcdev); 801 u32 v; 802 int st_bit; 803 bool has_rstst; 804 unsigned long flags; 805 struct ti_prm_platform_data *pdata = dev_get_platdata(reset->dev); 806 int ret = 0; 807 808 /* Nothing to do if the reset is already deasserted */ 809 if (!omap_reset_status(rcdev, id)) 810 return 0; 811 812 has_rstst = reset->prm->data->rstst || 813 (reset->prm->data->flags & OMAP_PRM_HAS_RSTST); 814 815 if (has_rstst) { 816 st_bit = omap_reset_get_st_bit(reset, id); 817 818 /* Clear the reset status by writing 1 to the status bit */ 819 v = 1 << st_bit; 820 writel_relaxed(v, reset->prm->base + reset->prm->data->rstst); 821 } 822 823 if (reset->clkdm) 824 pdata->clkdm_deny_idle(reset->clkdm); 825 826 /* de-assert the reset control line */ 827 spin_lock_irqsave(&reset->lock, flags); 828 v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl); 829 v &= ~(1 << id); 830 writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl); 831 spin_unlock_irqrestore(&reset->lock, flags); 832 833 /* wait for the reset bit to clear */ 834 ret = readl_relaxed_poll_timeout_atomic(reset->prm->base + 835 reset->prm->data->rstctrl, 836 v, !(v & BIT(id)), 1, 837 OMAP_RESET_MAX_WAIT); 838 if (ret) 839 pr_err("%s: timedout waiting for %s:%lu\n", __func__, 840 reset->prm->data->name, id); 841 842 /* wait for the status to be set */ 843 if (has_rstst) { 844 ret = readl_relaxed_poll_timeout_atomic(reset->prm->base + 845 reset->prm->data->rstst, 846 v, v & BIT(st_bit), 1, 847 OMAP_RESET_MAX_WAIT); 848 if (ret) 849 pr_err("%s: timedout waiting for %s:%lu\n", __func__, 850 reset->prm->data->name, id); 851 } 852 853 if (reset->clkdm) 854 pdata->clkdm_allow_idle(reset->clkdm); 855 856 return ret; 857 } 858 859 static const struct reset_control_ops omap_reset_ops = { 860 .assert = omap_reset_assert, 861 .deassert = omap_reset_deassert, 862 .status = omap_reset_status, 863 }; 864 865 static int omap_prm_reset_xlate(struct reset_controller_dev *rcdev, 866 const struct of_phandle_args *reset_spec) 867 { 868 struct omap_reset_data *reset = to_omap_reset_data(rcdev); 869 870 if (!_is_valid_reset(reset, reset_spec->args[0])) 871 return -EINVAL; 872 873 return reset_spec->args[0]; 874 } 875 876 static int omap_prm_reset_init(struct platform_device *pdev, 877 struct omap_prm *prm) 878 { 879 struct omap_reset_data *reset; 880 const struct omap_rst_map *map; 881 struct ti_prm_platform_data *pdata = dev_get_platdata(&pdev->dev); 882 char buf[32]; 883 u32 v; 884 885 /* 886 * Check if we have controllable resets. If either rstctrl is non-zero 887 * or OMAP_PRM_HAS_RSTCTRL flag is set, we have reset control register 888 * for the domain. 889 */ 890 if (!prm->data->rstctrl && !(prm->data->flags & OMAP_PRM_HAS_RSTCTRL)) 891 return 0; 892 893 /* Check if we have the pdata callbacks in place */ 894 if (!pdata || !pdata->clkdm_lookup || !pdata->clkdm_deny_idle || 895 !pdata->clkdm_allow_idle) 896 return -EINVAL; 897 898 map = prm->data->rstmap; 899 if (!map) 900 return -EINVAL; 901 902 reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL); 903 if (!reset) 904 return -ENOMEM; 905 906 reset->rcdev.owner = THIS_MODULE; 907 reset->rcdev.ops = &omap_reset_ops; 908 reset->rcdev.of_node = pdev->dev.of_node; 909 reset->rcdev.nr_resets = OMAP_MAX_RESETS; 910 reset->rcdev.of_xlate = omap_prm_reset_xlate; 911 reset->rcdev.of_reset_n_cells = 1; 912 reset->dev = &pdev->dev; 913 spin_lock_init(&reset->lock); 914 915 reset->prm = prm; 916 917 sprintf(buf, "%s_clkdm", prm->data->clkdm_name ? prm->data->clkdm_name : 918 prm->data->name); 919 920 if (!(prm->data->flags & OMAP_PRM_HAS_NO_CLKDM)) { 921 reset->clkdm = pdata->clkdm_lookup(buf); 922 if (!reset->clkdm) 923 return -EINVAL; 924 } 925 926 while (map->rst >= 0) { 927 reset->mask |= BIT(map->rst); 928 map++; 929 } 930 931 /* Quirk handling to assert rst_map_012 bits on reset and avoid errors */ 932 if (prm->data->rstmap == rst_map_012) { 933 v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl); 934 if ((v & reset->mask) != reset->mask) { 935 dev_dbg(&pdev->dev, "Asserting all resets: %08x\n", v); 936 writel_relaxed(reset->mask, reset->prm->base + 937 reset->prm->data->rstctrl); 938 } 939 } 940 941 return devm_reset_controller_register(&pdev->dev, &reset->rcdev); 942 } 943 944 static int omap_prm_probe(struct platform_device *pdev) 945 { 946 struct resource *res; 947 const struct omap_prm_data *data; 948 struct omap_prm *prm; 949 int ret; 950 951 data = of_device_get_match_data(&pdev->dev); 952 if (!data) 953 return -ENOTSUPP; 954 955 prm = devm_kzalloc(&pdev->dev, sizeof(*prm), GFP_KERNEL); 956 if (!prm) 957 return -ENOMEM; 958 959 prm->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 960 if (IS_ERR(prm->base)) 961 return PTR_ERR(prm->base); 962 963 while (data->base != res->start) { 964 if (!data->base) 965 return -EINVAL; 966 data++; 967 } 968 969 prm->data = data; 970 971 ret = omap_prm_domain_init(&pdev->dev, prm); 972 if (ret) 973 return ret; 974 975 ret = omap_prm_reset_init(pdev, prm); 976 if (ret) 977 goto err_domain; 978 979 return 0; 980 981 err_domain: 982 of_genpd_del_provider(pdev->dev.of_node); 983 pm_genpd_remove(&prm->prmd->pd); 984 985 return ret; 986 } 987 988 static struct platform_driver omap_prm_driver = { 989 .probe = omap_prm_probe, 990 .driver = { 991 .name = KBUILD_MODNAME, 992 .of_match_table = omap_prm_id_table, 993 }, 994 }; 995 builtin_platform_driver(omap_prm_driver); 996