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