1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. */ 3 4 #include <linux/err.h> 5 #include <linux/init.h> 6 #include <linux/kernel.h> 7 #include <linux/module.h> 8 #include <linux/mutex.h> 9 #include <linux/pm_domain.h> 10 #include <linux/of.h> 11 #include <linux/platform_device.h> 12 #include <linux/pm_opp.h> 13 #include <linux/soc/qcom/smd-rpm.h> 14 15 #include <dt-bindings/power/qcom-rpmpd.h> 16 17 #define domain_to_rpmpd(domain) container_of(domain, struct rpmpd, pd) 18 19 /* Resource types: 20 * RPMPD_X is X encoded as a little-endian, lower-case, ASCII string */ 21 #define RPMPD_SMPA 0x61706d73 22 #define RPMPD_LDOA 0x616f646c 23 #define RPMPD_SMPB 0x62706d73 24 #define RPMPD_LDOB 0x626f646c 25 #define RPMPD_RWCX 0x78637772 26 #define RPMPD_RWMX 0x786d7772 27 #define RPMPD_RWLC 0x636c7772 28 #define RPMPD_RWLM 0x6d6c7772 29 #define RPMPD_RWSC 0x63737772 30 #define RPMPD_RWSM 0x6d737772 31 #define RPMPD_RWGX 0x78677772 32 33 /* Operation Keys */ 34 #define KEY_CORNER 0x6e726f63 /* corn */ 35 #define KEY_ENABLE 0x6e657773 /* swen */ 36 #define KEY_FLOOR_CORNER 0x636676 /* vfc */ 37 #define KEY_FLOOR_LEVEL 0x6c6676 /* vfl */ 38 #define KEY_LEVEL 0x6c766c76 /* vlvl */ 39 40 #define MAX_CORNER_RPMPD_STATE 6 41 42 struct rpmpd_req { 43 __le32 key; 44 __le32 nbytes; 45 __le32 value; 46 }; 47 48 struct rpmpd { 49 struct generic_pm_domain pd; 50 struct generic_pm_domain *parent; 51 struct rpmpd *peer; 52 const bool active_only; 53 unsigned int corner; 54 bool enabled; 55 const int res_type; 56 const int res_id; 57 struct qcom_smd_rpm *rpm; 58 unsigned int max_state; 59 __le32 key; 60 bool state_synced; 61 }; 62 63 struct rpmpd_desc { 64 struct rpmpd **rpmpds; 65 size_t num_pds; 66 unsigned int max_state; 67 }; 68 69 static DEFINE_MUTEX(rpmpd_lock); 70 71 /* CX */ 72 static struct rpmpd cx_rwcx0_lvl_ao; 73 static struct rpmpd cx_rwcx0_lvl = { 74 .pd = { .name = "cx", }, 75 .peer = &cx_rwcx0_lvl_ao, 76 .res_type = RPMPD_RWCX, 77 .res_id = 0, 78 .key = KEY_LEVEL, 79 }; 80 81 static struct rpmpd cx_rwcx0_lvl_ao = { 82 .pd = { .name = "cx_ao", }, 83 .peer = &cx_rwcx0_lvl, 84 .active_only = true, 85 .res_type = RPMPD_RWCX, 86 .res_id = 0, 87 .key = KEY_LEVEL, 88 }; 89 90 static struct rpmpd cx_s1a_corner_ao; 91 static struct rpmpd cx_s1a_corner = { 92 .pd = { .name = "cx", }, 93 .peer = &cx_s1a_corner_ao, 94 .res_type = RPMPD_SMPA, 95 .res_id = 1, 96 .key = KEY_CORNER, 97 }; 98 99 static struct rpmpd cx_s1a_corner_ao = { 100 .pd = { .name = "cx_ao", }, 101 .peer = &cx_s1a_corner, 102 .active_only = true, 103 .res_type = RPMPD_SMPA, 104 .res_id = 1, 105 .key = KEY_CORNER, 106 }; 107 108 static struct rpmpd cx_s2a_corner_ao; 109 static struct rpmpd cx_s2a_corner = { 110 .pd = { .name = "cx", }, 111 .peer = &cx_s2a_corner_ao, 112 .res_type = RPMPD_SMPA, 113 .res_id = 2, 114 .key = KEY_CORNER, 115 }; 116 117 static struct rpmpd cx_s2a_corner_ao = { 118 .pd = { .name = "cx_ao", }, 119 .peer = &cx_s2a_corner, 120 .active_only = true, 121 .res_type = RPMPD_SMPA, 122 .res_id = 2, 123 .key = KEY_CORNER, 124 }; 125 126 static struct rpmpd cx_s2a_lvl_ao; 127 static struct rpmpd cx_s2a_lvl = { 128 .pd = { .name = "cx", }, 129 .peer = &cx_s2a_lvl_ao, 130 .res_type = RPMPD_SMPA, 131 .res_id = 2, 132 .key = KEY_LEVEL, 133 }; 134 135 static struct rpmpd cx_s2a_lvl_ao = { 136 .pd = { .name = "cx_ao", }, 137 .peer = &cx_s2a_lvl, 138 .active_only = true, 139 .res_type = RPMPD_SMPA, 140 .res_id = 2, 141 .key = KEY_LEVEL, 142 }; 143 144 static struct rpmpd cx_s3a_lvl_ao; 145 static struct rpmpd cx_s3a_lvl = { 146 .pd = { .name = "cx", }, 147 .peer = &cx_s3a_lvl_ao, 148 .res_type = RPMPD_SMPA, 149 .res_id = 3, 150 .key = KEY_LEVEL, 151 }; 152 153 static struct rpmpd cx_s3a_lvl_ao = { 154 .pd = { .name = "cx_ao", }, 155 .peer = &cx_s3a_lvl, 156 .active_only = true, 157 .res_type = RPMPD_SMPA, 158 .res_id = 3, 159 .key = KEY_LEVEL, 160 }; 161 162 static struct rpmpd cx_rwcx0_vfl = { 163 .pd = { .name = "cx_vfl", }, 164 .res_type = RPMPD_RWCX, 165 .res_id = 0, 166 .key = KEY_FLOOR_LEVEL, 167 }; 168 169 static struct rpmpd cx_rwsc2_vfl = { 170 .pd = { .name = "cx_vfl", }, 171 .res_type = RPMPD_RWSC, 172 .res_id = 2, 173 .key = KEY_FLOOR_LEVEL, 174 }; 175 176 static struct rpmpd cx_s1a_vfc = { 177 .pd = { .name = "cx_vfc", }, 178 .res_type = RPMPD_SMPA, 179 .res_id = 1, 180 .key = KEY_FLOOR_CORNER, 181 }; 182 183 static struct rpmpd cx_s2a_vfc = { 184 .pd = { .name = "cx_vfc", }, 185 .res_type = RPMPD_SMPA, 186 .res_id = 2, 187 .key = KEY_FLOOR_CORNER, 188 }; 189 190 static struct rpmpd cx_s2a_vfl = { 191 .pd = { .name = "cx_vfl", }, 192 .res_type = RPMPD_SMPA, 193 .res_id = 2, 194 .key = KEY_FLOOR_LEVEL, 195 }; 196 197 static struct rpmpd cx_s3a_vfl = { 198 .pd = { .name = "cx_vfl", }, 199 .res_type = RPMPD_SMPA, 200 .res_id = 3, 201 .key = KEY_FLOOR_LEVEL, 202 }; 203 204 /* G(F)X */ 205 static struct rpmpd gfx_s2b_corner = { 206 .pd = { .name = "gfx", }, 207 .res_type = RPMPD_SMPB, 208 .res_id = 2, 209 .key = KEY_CORNER, 210 }; 211 212 static struct rpmpd gfx_s2b_vfc = { 213 .pd = { .name = "gfx_vfc", }, 214 .res_type = RPMPD_SMPB, 215 .res_id = 2, 216 .key = KEY_FLOOR_CORNER, 217 }; 218 219 static struct rpmpd mx_rwmx0_lvl; 220 static struct rpmpd gx_rwgx0_lvl_ao; 221 static struct rpmpd gx_rwgx0_lvl = { 222 .pd = { .name = "gx", }, 223 .peer = &gx_rwgx0_lvl_ao, 224 .res_type = RPMPD_RWGX, 225 .parent = &mx_rwmx0_lvl.pd, 226 .res_id = 0, 227 .key = KEY_LEVEL, 228 }; 229 230 static struct rpmpd mx_rwmx0_lvl_ao; 231 static struct rpmpd gx_rwgx0_lvl_ao = { 232 .pd = { .name = "gx_ao", }, 233 .peer = &gx_rwgx0_lvl, 234 .parent = &mx_rwmx0_lvl_ao.pd, 235 .active_only = true, 236 .res_type = RPMPD_RWGX, 237 .res_id = 0, 238 .key = KEY_LEVEL, 239 }; 240 241 /* MX */ 242 static struct rpmpd mx_l3a_corner_ao; 243 static struct rpmpd mx_l3a_corner = { 244 .pd = { .name = "mx", }, 245 .peer = &mx_l3a_corner_ao, 246 .res_type = RPMPD_LDOA, 247 .res_id = 3, 248 .key = KEY_CORNER, 249 }; 250 251 static struct rpmpd mx_l3a_corner_ao = { 252 .pd = { .name = "mx_ao", }, 253 .peer = &mx_l3a_corner, 254 .active_only = true, 255 .res_type = RPMPD_LDOA, 256 .res_id = 3, 257 .key = KEY_CORNER, 258 }; 259 260 static struct rpmpd mx_l12a_lvl_ao; 261 static struct rpmpd mx_l12a_lvl = { 262 .pd = { .name = "mx", }, 263 .peer = &mx_l12a_lvl_ao, 264 .res_type = RPMPD_LDOA, 265 .res_id = 12, 266 .key = KEY_LEVEL, 267 }; 268 269 static struct rpmpd mx_l12a_lvl_ao = { 270 .pd = { .name = "mx_ao", }, 271 .peer = &mx_l12a_lvl, 272 .active_only = true, 273 .res_type = RPMPD_LDOA, 274 .res_id = 12, 275 .key = KEY_LEVEL, 276 }; 277 278 static struct rpmpd mx_s2a_corner_ao; 279 static struct rpmpd mx_s2a_corner = { 280 .pd = { .name = "mx", }, 281 .peer = &mx_s2a_corner_ao, 282 .res_type = RPMPD_SMPA, 283 .res_id = 2, 284 .key = KEY_CORNER, 285 }; 286 287 static struct rpmpd mx_s2a_corner_ao = { 288 .pd = { .name = "mx_ao", }, 289 .peer = &mx_s2a_corner, 290 .active_only = true, 291 .res_type = RPMPD_SMPA, 292 .res_id = 2, 293 .key = KEY_CORNER, 294 }; 295 296 static struct rpmpd mx_rwmx0_lvl_ao; 297 static struct rpmpd mx_rwmx0_lvl = { 298 .pd = { .name = "mx", }, 299 .peer = &mx_rwmx0_lvl_ao, 300 .res_type = RPMPD_RWMX, 301 .res_id = 0, 302 .key = KEY_LEVEL, 303 }; 304 305 static struct rpmpd mx_rwmx0_lvl_ao = { 306 .pd = { .name = "mx_ao", }, 307 .peer = &mx_rwmx0_lvl, 308 .active_only = true, 309 .res_type = RPMPD_RWMX, 310 .res_id = 0, 311 .key = KEY_LEVEL, 312 }; 313 314 static struct rpmpd mx_s6a_lvl_ao; 315 static struct rpmpd mx_s6a_lvl = { 316 .pd = { .name = "mx", }, 317 .peer = &mx_s6a_lvl_ao, 318 .res_type = RPMPD_SMPA, 319 .res_id = 6, 320 .key = KEY_LEVEL, 321 }; 322 323 static struct rpmpd mx_s6a_lvl_ao = { 324 .pd = { .name = "mx_ao", }, 325 .peer = &mx_s6a_lvl, 326 .active_only = true, 327 .res_type = RPMPD_SMPA, 328 .res_id = 6, 329 .key = KEY_LEVEL, 330 }; 331 332 static struct rpmpd mx_s7a_lvl_ao; 333 static struct rpmpd mx_s7a_lvl = { 334 .pd = { .name = "mx", }, 335 .peer = &mx_s7a_lvl_ao, 336 .res_type = RPMPD_SMPA, 337 .res_id = 7, 338 .key = KEY_LEVEL, 339 }; 340 341 static struct rpmpd mx_s7a_lvl_ao = { 342 .pd = { .name = "mx_ao", }, 343 .peer = &mx_s7a_lvl, 344 .active_only = true, 345 .res_type = RPMPD_SMPA, 346 .res_id = 7, 347 .key = KEY_LEVEL, 348 }; 349 350 static struct rpmpd mx_l12a_vfl = { 351 .pd = { .name = "mx_vfl", }, 352 .res_type = RPMPD_LDOA, 353 .res_id = 12, 354 .key = KEY_FLOOR_LEVEL, 355 }; 356 357 static struct rpmpd mx_rwmx0_vfl = { 358 .pd = { .name = "mx_vfl", }, 359 .res_type = RPMPD_RWMX, 360 .res_id = 0, 361 .key = KEY_FLOOR_LEVEL, 362 }; 363 364 static struct rpmpd mx_rwsm6_vfl = { 365 .pd = { .name = "mx_vfl", }, 366 .res_type = RPMPD_RWSM, 367 .res_id = 6, 368 .key = KEY_FLOOR_LEVEL, 369 }; 370 371 /* MD */ 372 static struct rpmpd md_s1a_corner_ao; 373 static struct rpmpd md_s1a_corner = { 374 .pd = { .name = "md", }, 375 .peer = &md_s1a_corner_ao, 376 .res_type = RPMPD_SMPA, 377 .res_id = 1, 378 .key = KEY_CORNER, 379 }; 380 381 static struct rpmpd md_s1a_corner_ao = { 382 .pd = { .name = "md_ao", }, 383 .peer = &md_s1a_corner, 384 .active_only = true, 385 .res_type = RPMPD_SMPA, 386 .res_id = 1, 387 .key = KEY_CORNER, 388 }; 389 390 static struct rpmpd md_s1a_lvl_ao; 391 static struct rpmpd md_s1a_lvl = { 392 .pd = { .name = "md", }, 393 .peer = &md_s1a_lvl_ao, 394 .res_type = RPMPD_SMPA, 395 .res_id = 1, 396 .key = KEY_LEVEL, 397 }; 398 399 static struct rpmpd md_s1a_lvl_ao = { 400 .pd = { .name = "md_ao", }, 401 .peer = &md_s1a_lvl, 402 .active_only = true, 403 .res_type = RPMPD_SMPA, 404 .res_id = 1, 405 .key = KEY_LEVEL, 406 }; 407 408 static struct rpmpd md_s1a_vfc = { 409 .pd = { .name = "md_vfc", }, 410 .res_type = RPMPD_SMPA, 411 .res_id = 1, 412 .key = KEY_FLOOR_CORNER, 413 }; 414 415 /* LPI_CX */ 416 static struct rpmpd lpi_cx_rwlc0_lvl = { 417 .pd = { .name = "lpi_cx", }, 418 .res_type = RPMPD_RWLC, 419 .res_id = 0, 420 .key = KEY_LEVEL, 421 }; 422 423 static struct rpmpd lpi_cx_rwlc0_vfl = { 424 .pd = { .name = "lpi_cx_vfl", }, 425 .res_type = RPMPD_RWLC, 426 .res_id = 0, 427 .key = KEY_FLOOR_LEVEL, 428 }; 429 430 /* LPI_MX */ 431 static struct rpmpd lpi_mx_rwlm0_lvl = { 432 .pd = { .name = "lpi_mx", }, 433 .res_type = RPMPD_RWLM, 434 .res_id = 0, 435 .key = KEY_LEVEL, 436 }; 437 438 static struct rpmpd lpi_mx_rwlm0_vfl = { 439 .pd = { .name = "lpi_mx_vfl", }, 440 .res_type = RPMPD_RWLM, 441 .res_id = 0, 442 .key = KEY_FLOOR_LEVEL, 443 }; 444 445 /* SSC_CX */ 446 static struct rpmpd ssc_cx_l26a_corner = { 447 .pd = { .name = "ssc_cx", }, 448 .res_type = RPMPD_LDOA, 449 .res_id = 26, 450 .key = KEY_CORNER, 451 }; 452 453 static struct rpmpd ssc_cx_rwlc0_lvl = { 454 .pd = { .name = "ssc_cx", }, 455 .res_type = RPMPD_RWLC, 456 .res_id = 0, 457 .key = KEY_LEVEL, 458 }; 459 460 static struct rpmpd ssc_cx_rwsc0_lvl = { 461 .pd = { .name = "ssc_cx", }, 462 .res_type = RPMPD_RWSC, 463 .res_id = 0, 464 .key = KEY_LEVEL, 465 }; 466 467 static struct rpmpd ssc_cx_l26a_vfc = { 468 .pd = { .name = "ssc_cx_vfc", }, 469 .res_type = RPMPD_LDOA, 470 .res_id = 26, 471 .key = KEY_FLOOR_CORNER, 472 }; 473 474 static struct rpmpd ssc_cx_rwlc0_vfl = { 475 .pd = { .name = "ssc_cx_vfl", }, 476 .res_type = RPMPD_RWLC, 477 .res_id = 0, 478 .key = KEY_FLOOR_LEVEL, 479 }; 480 481 static struct rpmpd ssc_cx_rwsc0_vfl = { 482 .pd = { .name = "ssc_cx_vfl", }, 483 .res_type = RPMPD_RWSC, 484 .res_id = 0, 485 .key = KEY_FLOOR_LEVEL, 486 }; 487 488 /* SSC_MX */ 489 static struct rpmpd ssc_mx_rwlm0_lvl = { 490 .pd = { .name = "ssc_mx", }, 491 .res_type = RPMPD_RWLM, 492 .res_id = 0, 493 .key = KEY_LEVEL, 494 }; 495 496 static struct rpmpd ssc_mx_rwsm0_lvl = { 497 .pd = { .name = "ssc_mx", }, 498 .res_type = RPMPD_RWSM, 499 .res_id = 0, 500 .key = KEY_LEVEL, 501 }; 502 503 static struct rpmpd ssc_mx_rwlm0_vfl = { 504 .pd = { .name = "ssc_mx_vfl", }, 505 .res_type = RPMPD_RWLM, 506 .res_id = 0, 507 .key = KEY_FLOOR_LEVEL, 508 }; 509 510 static struct rpmpd ssc_mx_rwsm0_vfl = { 511 .pd = { .name = "ssc_mx_vfl", }, 512 .res_type = RPMPD_RWSM, 513 .res_id = 0, 514 .key = KEY_FLOOR_LEVEL, 515 }; 516 517 static struct rpmpd *mdm9607_rpmpds[] = { 518 [MDM9607_VDDCX] = &cx_s3a_lvl, 519 [MDM9607_VDDCX_AO] = &cx_s3a_lvl_ao, 520 [MDM9607_VDDCX_VFL] = &cx_s3a_vfl, 521 [MDM9607_VDDMX] = &mx_l12a_lvl, 522 [MDM9607_VDDMX_AO] = &mx_l12a_lvl_ao, 523 [MDM9607_VDDMX_VFL] = &mx_l12a_vfl, 524 }; 525 526 static const struct rpmpd_desc mdm9607_desc = { 527 .rpmpds = mdm9607_rpmpds, 528 .num_pds = ARRAY_SIZE(mdm9607_rpmpds), 529 .max_state = RPM_SMD_LEVEL_TURBO, 530 }; 531 532 static struct rpmpd *msm8226_rpmpds[] = { 533 [MSM8226_VDDCX] = &cx_s1a_corner, 534 [MSM8226_VDDCX_AO] = &cx_s1a_corner_ao, 535 [MSM8226_VDDCX_VFC] = &cx_s1a_vfc, 536 }; 537 538 static const struct rpmpd_desc msm8226_desc = { 539 .rpmpds = msm8226_rpmpds, 540 .num_pds = ARRAY_SIZE(msm8226_rpmpds), 541 .max_state = MAX_CORNER_RPMPD_STATE, 542 }; 543 544 static struct rpmpd *msm8939_rpmpds[] = { 545 [MSM8939_VDDMDCX] = &md_s1a_corner, 546 [MSM8939_VDDMDCX_AO] = &md_s1a_corner_ao, 547 [MSM8939_VDDMDCX_VFC] = &md_s1a_vfc, 548 [MSM8939_VDDCX] = &cx_s2a_corner, 549 [MSM8939_VDDCX_AO] = &cx_s2a_corner_ao, 550 [MSM8939_VDDCX_VFC] = &cx_s2a_vfc, 551 [MSM8939_VDDMX] = &mx_l3a_corner, 552 [MSM8939_VDDMX_AO] = &mx_l3a_corner_ao, 553 }; 554 555 static const struct rpmpd_desc msm8939_desc = { 556 .rpmpds = msm8939_rpmpds, 557 .num_pds = ARRAY_SIZE(msm8939_rpmpds), 558 .max_state = MAX_CORNER_RPMPD_STATE, 559 }; 560 561 static struct rpmpd *msm8916_rpmpds[] = { 562 [MSM8916_VDDCX] = &cx_s1a_corner, 563 [MSM8916_VDDCX_AO] = &cx_s1a_corner_ao, 564 [MSM8916_VDDCX_VFC] = &cx_s1a_vfc, 565 [MSM8916_VDDMX] = &mx_l3a_corner, 566 [MSM8916_VDDMX_AO] = &mx_l3a_corner_ao, 567 }; 568 569 static const struct rpmpd_desc msm8916_desc = { 570 .rpmpds = msm8916_rpmpds, 571 .num_pds = ARRAY_SIZE(msm8916_rpmpds), 572 .max_state = MAX_CORNER_RPMPD_STATE, 573 }; 574 575 static struct rpmpd *msm8953_rpmpds[] = { 576 [MSM8953_VDDMD] = &md_s1a_lvl, 577 [MSM8953_VDDMD_AO] = &md_s1a_lvl_ao, 578 [MSM8953_VDDCX] = &cx_s2a_lvl, 579 [MSM8953_VDDCX_AO] = &cx_s2a_lvl_ao, 580 [MSM8953_VDDCX_VFL] = &cx_s2a_vfl, 581 [MSM8953_VDDMX] = &mx_s7a_lvl, 582 [MSM8953_VDDMX_AO] = &mx_s7a_lvl_ao, 583 }; 584 585 static const struct rpmpd_desc msm8953_desc = { 586 .rpmpds = msm8953_rpmpds, 587 .num_pds = ARRAY_SIZE(msm8953_rpmpds), 588 .max_state = RPM_SMD_LEVEL_TURBO, 589 }; 590 591 static struct rpmpd *msm8976_rpmpds[] = { 592 [MSM8976_VDDCX] = &cx_s2a_lvl, 593 [MSM8976_VDDCX_AO] = &cx_s2a_lvl_ao, 594 [MSM8976_VDDCX_VFL] = &cx_rwsc2_vfl, 595 [MSM8976_VDDMX] = &mx_s6a_lvl, 596 [MSM8976_VDDMX_AO] = &mx_s6a_lvl_ao, 597 [MSM8976_VDDMX_VFL] = &mx_rwsm6_vfl, 598 }; 599 600 static const struct rpmpd_desc msm8976_desc = { 601 .rpmpds = msm8976_rpmpds, 602 .num_pds = ARRAY_SIZE(msm8976_rpmpds), 603 .max_state = RPM_SMD_LEVEL_TURBO_HIGH, 604 }; 605 606 static struct rpmpd *msm8994_rpmpds[] = { 607 [MSM8994_VDDCX] = &cx_s1a_corner, 608 [MSM8994_VDDCX_AO] = &cx_s1a_corner_ao, 609 [MSM8994_VDDCX_VFC] = &cx_s1a_vfc, 610 [MSM8994_VDDMX] = &mx_s2a_corner, 611 [MSM8994_VDDMX_AO] = &mx_s2a_corner_ao, 612 613 /* Attention! *Some* 8994 boards with pm8004 may use SMPC here! */ 614 [MSM8994_VDDGFX] = &gfx_s2b_corner, 615 [MSM8994_VDDGFX_VFC] = &gfx_s2b_vfc, 616 }; 617 618 static const struct rpmpd_desc msm8994_desc = { 619 .rpmpds = msm8994_rpmpds, 620 .num_pds = ARRAY_SIZE(msm8994_rpmpds), 621 .max_state = MAX_CORNER_RPMPD_STATE, 622 }; 623 624 static struct rpmpd *msm8996_rpmpds[] = { 625 [MSM8996_VDDCX] = &cx_s1a_corner, 626 [MSM8996_VDDCX_AO] = &cx_s1a_corner_ao, 627 [MSM8996_VDDCX_VFC] = &cx_s1a_vfc, 628 [MSM8996_VDDMX] = &mx_s2a_corner, 629 [MSM8996_VDDMX_AO] = &mx_s2a_corner_ao, 630 [MSM8996_VDDSSCX] = &ssc_cx_l26a_corner, 631 [MSM8996_VDDSSCX_VFC] = &ssc_cx_l26a_vfc, 632 }; 633 634 static const struct rpmpd_desc msm8996_desc = { 635 .rpmpds = msm8996_rpmpds, 636 .num_pds = ARRAY_SIZE(msm8996_rpmpds), 637 .max_state = MAX_CORNER_RPMPD_STATE, 638 }; 639 640 static struct rpmpd *msm8998_rpmpds[] = { 641 [MSM8998_VDDCX] = &cx_rwcx0_lvl, 642 [MSM8998_VDDCX_AO] = &cx_rwcx0_lvl_ao, 643 [MSM8998_VDDCX_VFL] = &cx_rwcx0_vfl, 644 [MSM8998_VDDMX] = &mx_rwmx0_lvl, 645 [MSM8998_VDDMX_AO] = &mx_rwmx0_lvl_ao, 646 [MSM8998_VDDMX_VFL] = &mx_rwmx0_vfl, 647 [MSM8998_SSCCX] = &ssc_cx_rwsc0_lvl, 648 [MSM8998_SSCCX_VFL] = &ssc_cx_rwsc0_vfl, 649 [MSM8998_SSCMX] = &ssc_mx_rwsm0_lvl, 650 [MSM8998_SSCMX_VFL] = &ssc_mx_rwsm0_vfl, 651 }; 652 653 static const struct rpmpd_desc msm8998_desc = { 654 .rpmpds = msm8998_rpmpds, 655 .num_pds = ARRAY_SIZE(msm8998_rpmpds), 656 .max_state = RPM_SMD_LEVEL_BINNING, 657 }; 658 659 static struct rpmpd *qcs404_rpmpds[] = { 660 [QCS404_VDDMX] = &mx_rwmx0_lvl, 661 [QCS404_VDDMX_AO] = &mx_rwmx0_lvl_ao, 662 [QCS404_VDDMX_VFL] = &mx_rwmx0_vfl, 663 [QCS404_LPICX] = &lpi_cx_rwlc0_lvl, 664 [QCS404_LPICX_VFL] = &lpi_cx_rwlc0_vfl, 665 [QCS404_LPIMX] = &lpi_mx_rwlm0_lvl, 666 [QCS404_LPIMX_VFL] = &lpi_mx_rwlm0_vfl, 667 }; 668 669 static const struct rpmpd_desc qcs404_desc = { 670 .rpmpds = qcs404_rpmpds, 671 .num_pds = ARRAY_SIZE(qcs404_rpmpds), 672 .max_state = RPM_SMD_LEVEL_BINNING, 673 }; 674 675 static struct rpmpd *sdm660_rpmpds[] = { 676 [SDM660_VDDCX] = &cx_rwcx0_lvl, 677 [SDM660_VDDCX_AO] = &cx_rwcx0_lvl_ao, 678 [SDM660_VDDCX_VFL] = &cx_rwcx0_vfl, 679 [SDM660_VDDMX] = &mx_rwmx0_lvl, 680 [SDM660_VDDMX_AO] = &mx_rwmx0_lvl_ao, 681 [SDM660_VDDMX_VFL] = &mx_rwmx0_vfl, 682 [SDM660_SSCCX] = &ssc_cx_rwlc0_lvl, 683 [SDM660_SSCCX_VFL] = &ssc_cx_rwlc0_vfl, 684 [SDM660_SSCMX] = &ssc_mx_rwlm0_lvl, 685 [SDM660_SSCMX_VFL] = &ssc_mx_rwlm0_vfl, 686 }; 687 688 static const struct rpmpd_desc sdm660_desc = { 689 .rpmpds = sdm660_rpmpds, 690 .num_pds = ARRAY_SIZE(sdm660_rpmpds), 691 .max_state = RPM_SMD_LEVEL_TURBO, 692 }; 693 694 static struct rpmpd *sm6115_rpmpds[] = { 695 [SM6115_VDDCX] = &cx_rwcx0_lvl, 696 [SM6115_VDDCX_AO] = &cx_rwcx0_lvl_ao, 697 [SM6115_VDDCX_VFL] = &cx_rwcx0_vfl, 698 [SM6115_VDDMX] = &mx_rwmx0_lvl, 699 [SM6115_VDDMX_AO] = &mx_rwmx0_lvl_ao, 700 [SM6115_VDDMX_VFL] = &mx_rwmx0_vfl, 701 [SM6115_VDD_LPI_CX] = &lpi_cx_rwlc0_lvl, 702 [SM6115_VDD_LPI_MX] = &lpi_mx_rwlm0_lvl, 703 }; 704 705 static const struct rpmpd_desc sm6115_desc = { 706 .rpmpds = sm6115_rpmpds, 707 .num_pds = ARRAY_SIZE(sm6115_rpmpds), 708 .max_state = RPM_SMD_LEVEL_TURBO_NO_CPR, 709 }; 710 711 static struct rpmpd *sm6125_rpmpds[] = { 712 [SM6125_VDDCX] = &cx_rwcx0_lvl, 713 [SM6125_VDDCX_AO] = &cx_rwcx0_lvl_ao, 714 [SM6125_VDDCX_VFL] = &cx_rwcx0_vfl, 715 [SM6125_VDDMX] = &mx_rwmx0_lvl, 716 [SM6125_VDDMX_AO] = &mx_rwmx0_lvl_ao, 717 [SM6125_VDDMX_VFL] = &mx_rwmx0_vfl, 718 }; 719 720 static const struct rpmpd_desc sm6125_desc = { 721 .rpmpds = sm6125_rpmpds, 722 .num_pds = ARRAY_SIZE(sm6125_rpmpds), 723 .max_state = RPM_SMD_LEVEL_BINNING, 724 }; 725 726 static struct rpmpd *sm6375_rpmpds[] = { 727 [SM6375_VDDCX] = &cx_rwcx0_lvl, 728 [SM6375_VDDCX_AO] = &cx_rwcx0_lvl_ao, 729 [SM6375_VDDCX_VFL] = &cx_rwcx0_vfl, 730 [SM6375_VDDMX] = &mx_rwmx0_lvl, 731 [SM6375_VDDMX_AO] = &mx_rwmx0_lvl_ao, 732 [SM6375_VDDMX_VFL] = &mx_rwmx0_vfl, 733 [SM6375_VDDGX] = &gx_rwgx0_lvl, 734 [SM6375_VDDGX_AO] = &gx_rwgx0_lvl_ao, 735 [SM6375_VDD_LPI_CX] = &lpi_cx_rwlc0_lvl, 736 [SM6375_VDD_LPI_MX] = &lpi_mx_rwlm0_lvl, 737 }; 738 739 static const struct rpmpd_desc sm6375_desc = { 740 .rpmpds = sm6375_rpmpds, 741 .num_pds = ARRAY_SIZE(sm6375_rpmpds), 742 .max_state = RPM_SMD_LEVEL_TURBO_NO_CPR, 743 }; 744 745 static struct rpmpd *qcm2290_rpmpds[] = { 746 [QCM2290_VDDCX] = &cx_rwcx0_lvl, 747 [QCM2290_VDDCX_AO] = &cx_rwcx0_lvl_ao, 748 [QCM2290_VDDCX_VFL] = &cx_rwcx0_vfl, 749 [QCM2290_VDDMX] = &mx_rwmx0_lvl, 750 [QCM2290_VDDMX_AO] = &mx_rwmx0_lvl_ao, 751 [QCM2290_VDDMX_VFL] = &mx_rwmx0_vfl, 752 [QCM2290_VDD_LPI_CX] = &lpi_cx_rwlc0_lvl, 753 [QCM2290_VDD_LPI_MX] = &lpi_mx_rwlm0_lvl, 754 }; 755 756 static const struct rpmpd_desc qcm2290_desc = { 757 .rpmpds = qcm2290_rpmpds, 758 .num_pds = ARRAY_SIZE(qcm2290_rpmpds), 759 .max_state = RPM_SMD_LEVEL_TURBO_NO_CPR, 760 }; 761 762 static const struct of_device_id rpmpd_match_table[] = { 763 { .compatible = "qcom,mdm9607-rpmpd", .data = &mdm9607_desc }, 764 { .compatible = "qcom,msm8226-rpmpd", .data = &msm8226_desc }, 765 { .compatible = "qcom,msm8909-rpmpd", .data = &msm8916_desc }, 766 { .compatible = "qcom,msm8916-rpmpd", .data = &msm8916_desc }, 767 { .compatible = "qcom,msm8939-rpmpd", .data = &msm8939_desc }, 768 { .compatible = "qcom,msm8953-rpmpd", .data = &msm8953_desc }, 769 { .compatible = "qcom,msm8976-rpmpd", .data = &msm8976_desc }, 770 { .compatible = "qcom,msm8994-rpmpd", .data = &msm8994_desc }, 771 { .compatible = "qcom,msm8996-rpmpd", .data = &msm8996_desc }, 772 { .compatible = "qcom,msm8998-rpmpd", .data = &msm8998_desc }, 773 { .compatible = "qcom,qcm2290-rpmpd", .data = &qcm2290_desc }, 774 { .compatible = "qcom,qcs404-rpmpd", .data = &qcs404_desc }, 775 { .compatible = "qcom,sdm660-rpmpd", .data = &sdm660_desc }, 776 { .compatible = "qcom,sm6115-rpmpd", .data = &sm6115_desc }, 777 { .compatible = "qcom,sm6125-rpmpd", .data = &sm6125_desc }, 778 { .compatible = "qcom,sm6375-rpmpd", .data = &sm6375_desc }, 779 { } 780 }; 781 MODULE_DEVICE_TABLE(of, rpmpd_match_table); 782 783 static int rpmpd_send_enable(struct rpmpd *pd, bool enable) 784 { 785 struct rpmpd_req req = { 786 .key = KEY_ENABLE, 787 .nbytes = cpu_to_le32(sizeof(u32)), 788 .value = cpu_to_le32(enable), 789 }; 790 791 return qcom_rpm_smd_write(pd->rpm, QCOM_SMD_RPM_ACTIVE_STATE, 792 pd->res_type, pd->res_id, &req, sizeof(req)); 793 } 794 795 static int rpmpd_send_corner(struct rpmpd *pd, int state, unsigned int corner) 796 { 797 struct rpmpd_req req = { 798 .key = pd->key, 799 .nbytes = cpu_to_le32(sizeof(u32)), 800 .value = cpu_to_le32(corner), 801 }; 802 803 return qcom_rpm_smd_write(pd->rpm, state, pd->res_type, pd->res_id, 804 &req, sizeof(req)); 805 }; 806 807 static void to_active_sleep(struct rpmpd *pd, unsigned int corner, 808 unsigned int *active, unsigned int *sleep) 809 { 810 *active = corner; 811 812 if (pd->active_only) 813 *sleep = 0; 814 else 815 *sleep = *active; 816 } 817 818 static int rpmpd_aggregate_corner(struct rpmpd *pd) 819 { 820 int ret; 821 struct rpmpd *peer = pd->peer; 822 unsigned int active_corner, sleep_corner; 823 unsigned int this_active_corner = 0, this_sleep_corner = 0; 824 unsigned int peer_active_corner = 0, peer_sleep_corner = 0; 825 826 /* Clamp to the highest corner/level if sync_state isn't done yet */ 827 if (!pd->state_synced) 828 this_active_corner = this_sleep_corner = pd->max_state - 1; 829 else 830 to_active_sleep(pd, pd->corner, &this_active_corner, &this_sleep_corner); 831 832 if (peer && peer->enabled) 833 to_active_sleep(peer, peer->corner, &peer_active_corner, 834 &peer_sleep_corner); 835 836 active_corner = max(this_active_corner, peer_active_corner); 837 838 ret = rpmpd_send_corner(pd, QCOM_SMD_RPM_ACTIVE_STATE, active_corner); 839 if (ret) 840 return ret; 841 842 sleep_corner = max(this_sleep_corner, peer_sleep_corner); 843 844 return rpmpd_send_corner(pd, QCOM_SMD_RPM_SLEEP_STATE, sleep_corner); 845 } 846 847 static int rpmpd_power_on(struct generic_pm_domain *domain) 848 { 849 int ret; 850 struct rpmpd *pd = domain_to_rpmpd(domain); 851 852 mutex_lock(&rpmpd_lock); 853 854 ret = rpmpd_send_enable(pd, true); 855 if (ret) 856 goto out; 857 858 pd->enabled = true; 859 860 if (pd->corner) 861 ret = rpmpd_aggregate_corner(pd); 862 863 out: 864 mutex_unlock(&rpmpd_lock); 865 866 return ret; 867 } 868 869 static int rpmpd_power_off(struct generic_pm_domain *domain) 870 { 871 int ret; 872 struct rpmpd *pd = domain_to_rpmpd(domain); 873 874 mutex_lock(&rpmpd_lock); 875 876 ret = rpmpd_send_enable(pd, false); 877 if (!ret) 878 pd->enabled = false; 879 880 mutex_unlock(&rpmpd_lock); 881 882 return ret; 883 } 884 885 static int rpmpd_set_performance(struct generic_pm_domain *domain, 886 unsigned int state) 887 { 888 int ret = 0; 889 struct rpmpd *pd = domain_to_rpmpd(domain); 890 891 if (state > pd->max_state) 892 state = pd->max_state; 893 894 mutex_lock(&rpmpd_lock); 895 896 pd->corner = state; 897 898 /* Always send updates for vfc and vfl */ 899 if (!pd->enabled && pd->key != cpu_to_le32(KEY_FLOOR_CORNER) && 900 pd->key != cpu_to_le32(KEY_FLOOR_LEVEL)) 901 goto out; 902 903 ret = rpmpd_aggregate_corner(pd); 904 905 out: 906 mutex_unlock(&rpmpd_lock); 907 908 return ret; 909 } 910 911 static unsigned int rpmpd_get_performance(struct generic_pm_domain *genpd, 912 struct dev_pm_opp *opp) 913 { 914 return dev_pm_opp_get_level(opp); 915 } 916 917 static int rpmpd_probe(struct platform_device *pdev) 918 { 919 int i; 920 size_t num; 921 struct genpd_onecell_data *data; 922 struct qcom_smd_rpm *rpm; 923 struct rpmpd **rpmpds; 924 const struct rpmpd_desc *desc; 925 926 rpm = dev_get_drvdata(pdev->dev.parent); 927 if (!rpm) { 928 dev_err(&pdev->dev, "Unable to retrieve handle to RPM\n"); 929 return -ENODEV; 930 } 931 932 desc = of_device_get_match_data(&pdev->dev); 933 if (!desc) 934 return -EINVAL; 935 936 rpmpds = desc->rpmpds; 937 num = desc->num_pds; 938 939 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 940 if (!data) 941 return -ENOMEM; 942 943 data->domains = devm_kcalloc(&pdev->dev, num, sizeof(*data->domains), 944 GFP_KERNEL); 945 if (!data->domains) 946 return -ENOMEM; 947 948 data->num_domains = num; 949 950 for (i = 0; i < num; i++) { 951 if (!rpmpds[i]) { 952 dev_warn(&pdev->dev, "rpmpds[] with empty entry at index=%d\n", 953 i); 954 continue; 955 } 956 957 rpmpds[i]->rpm = rpm; 958 rpmpds[i]->max_state = desc->max_state; 959 rpmpds[i]->pd.power_off = rpmpd_power_off; 960 rpmpds[i]->pd.power_on = rpmpd_power_on; 961 rpmpds[i]->pd.set_performance_state = rpmpd_set_performance; 962 rpmpds[i]->pd.opp_to_performance_state = rpmpd_get_performance; 963 pm_genpd_init(&rpmpds[i]->pd, NULL, true); 964 965 data->domains[i] = &rpmpds[i]->pd; 966 } 967 968 /* Add subdomains */ 969 for (i = 0; i < num; i++) { 970 if (!rpmpds[i]) 971 continue; 972 973 if (rpmpds[i]->parent) 974 pm_genpd_add_subdomain(rpmpds[i]->parent, &rpmpds[i]->pd); 975 } 976 977 return of_genpd_add_provider_onecell(pdev->dev.of_node, data); 978 } 979 980 static void rpmpd_sync_state(struct device *dev) 981 { 982 const struct rpmpd_desc *desc = of_device_get_match_data(dev); 983 struct rpmpd **rpmpds = desc->rpmpds; 984 struct rpmpd *pd; 985 unsigned int i; 986 int ret; 987 988 mutex_lock(&rpmpd_lock); 989 for (i = 0; i < desc->num_pds; i++) { 990 pd = rpmpds[i]; 991 if (!pd) 992 continue; 993 994 pd->state_synced = true; 995 996 if (!pd->enabled) 997 pd->corner = 0; 998 999 ret = rpmpd_aggregate_corner(pd); 1000 if (ret) 1001 dev_err(dev, "failed to sync %s: %d\n", pd->pd.name, ret); 1002 } 1003 mutex_unlock(&rpmpd_lock); 1004 } 1005 1006 static struct platform_driver rpmpd_driver = { 1007 .driver = { 1008 .name = "qcom-rpmpd", 1009 .of_match_table = rpmpd_match_table, 1010 .suppress_bind_attrs = true, 1011 .sync_state = rpmpd_sync_state, 1012 }, 1013 .probe = rpmpd_probe, 1014 }; 1015 1016 static int __init rpmpd_init(void) 1017 { 1018 return platform_driver_register(&rpmpd_driver); 1019 } 1020 core_initcall(rpmpd_init); 1021 1022 MODULE_DESCRIPTION("Qualcomm Technologies, Inc. RPM Power Domain Driver"); 1023 MODULE_LICENSE("GPL v2"); 1024