Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'tegra-for-4.7-genpd' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/drivers

Merge "soc/tegra: Add generic PM domain support" from Thierry Reding:

Implements generic PM domain support on top of the existing Tegra power-
gate API. Drivers are thus allowed to move away from the Tegra-specific
API and towards using generic power domains directly.

* tag 'tegra-for-4.7-genpd' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux:
soc/tegra: pmc: Add generic PM domain support
dt-bindings: Add power domain info for NVIDIA PMC

+521 -77
+80
Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
··· 1 1 NVIDIA Tegra Power Management Controller (PMC) 2 2 3 + == Power Management Controller Node == 4 + 3 5 The PMC block interacts with an external Power Management Unit. The PMC 4 6 mostly controls the entry and exit of the system from different sleep 5 7 modes. It provides power-gating controllers for SoC and CPU power-islands. ··· 72 70 Defaults to 0. Valid values are described in section 12.5.2 73 71 "Pinmux Support" of the Tegra4 Technical Reference Manual. 74 72 73 + Optional nodes: 74 + - powergates : This node contains a hierarchy of power domain nodes, which 75 + should match the powergates on the Tegra SoC. See "Powergate 76 + Nodes" below. 77 + 75 78 Example: 76 79 77 80 / SoC dts including file ··· 122 115 }; 123 116 ... 124 117 }; 118 + 119 + 120 + == Powergate Nodes == 121 + 122 + Each of the powergate nodes represents a power-domain on the Tegra SoC 123 + that can be power-gated by the Tegra PMC. The name of the powergate node 124 + should be one of the below. Note that not every powergate is applicable 125 + to all Tegra devices and the following list shows which powergates are 126 + applicable to which devices. Please refer to the Tegra TRM for more 127 + details on the various powergates. 128 + 129 + Name Description Devices Applicable 130 + 3d 3D Graphics Tegra20/114/124/210 131 + 3d0 3D Graphics 0 Tegra30 132 + 3d1 3D Graphics 1 Tegra30 133 + aud Audio Tegra210 134 + dfd Debug Tegra210 135 + dis Display A Tegra114/124/210 136 + disb Display B Tegra114/124/210 137 + heg 2D Graphics Tegra30/114/124/210 138 + iram Internal RAM Tegra124/210 139 + mpe MPEG Encode All 140 + nvdec NVIDIA Video Decode Engine Tegra210 141 + nvjpg NVIDIA JPEG Engine Tegra210 142 + pcie PCIE Tegra20/30/124/210 143 + sata SATA Tegra30/124/210 144 + sor Display interfaces Tegra124/210 145 + ve2 Video Encode Engine 2 Tegra210 146 + venc Video Encode Engine All 147 + vdec Video Decode Engine Tegra20/30/114/124 148 + vic Video Imaging Compositor Tegra124/210 149 + xusba USB Partition A Tegra114/124/210 150 + xusbb USB Partition B Tegra114/124/210 151 + xusbc USB Partition C Tegra114/124/210 152 + 153 + Required properties: 154 + - clocks: Must contain an entry for each clock required by the PMC for 155 + controlling a power-gate. See ../clocks/clock-bindings.txt for details. 156 + - resets: Must contain an entry for each reset required by the PMC for 157 + controlling a power-gate. See ../reset/reset.txt for details. 158 + - #power-domain-cells: Must be 0. 159 + 160 + Example: 161 + 162 + pmc: pmc@7000e400 { 163 + compatible = "nvidia,tegra210-pmc"; 164 + reg = <0x0 0x7000e400 0x0 0x400>; 165 + clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>; 166 + clock-names = "pclk", "clk32k_in"; 167 + 168 + powergates { 169 + pd_audio: aud { 170 + clocks = <&tegra_car TEGRA210_CLK_APE>, 171 + <&tegra_car TEGRA210_CLK_APB2APE>; 172 + resets = <&tegra_car 198>; 173 + #power-domain-cells = <0>; 174 + }; 175 + }; 176 + }; 177 + 178 + 179 + == Powergate Clients == 180 + 181 + Hardware blocks belonging to a power domain should contain a "power-domains" 182 + property that is a phandle pointing to the corresponding powergate node. 183 + 184 + Example: 185 + 186 + adma: adma@702e2000 { 187 + ... 188 + power-domains = <&pd_audio>; 189 + ... 190 + };
+440 -77
drivers/soc/tegra/pmc.c
··· 31 31 #include <linux/iopoll.h> 32 32 #include <linux/of.h> 33 33 #include <linux/of_address.h> 34 + #include <linux/of_platform.h> 34 35 #include <linux/platform_device.h> 36 + #include <linux/pm_domain.h> 35 37 #include <linux/reboot.h> 36 38 #include <linux/reset.h> 37 39 #include <linux/seq_file.h> 40 + #include <linux/slab.h> 38 41 #include <linux/spinlock.h> 39 42 40 43 #include <soc/tegra/common.h> ··· 105 102 106 103 #define GPU_RG_CNTRL 0x2d4 107 104 105 + struct tegra_powergate { 106 + struct generic_pm_domain genpd; 107 + struct tegra_pmc *pmc; 108 + unsigned int id; 109 + struct clk **clks; 110 + unsigned int num_clks; 111 + struct reset_control **resets; 112 + unsigned int num_resets; 113 + }; 114 + 108 115 struct tegra_pmc_soc { 109 116 unsigned int num_powergates; 110 117 const char *const *powergates; ··· 145 132 * @cpu_pwr_good_en: CPU power good signal is enabled 146 133 * @lp0_vec_phys: physical base address of the LP0 warm boot code 147 134 * @lp0_vec_size: size of the LP0 warm boot code 135 + * @powergates_available: Bitmap of available power gates 148 136 * @powergates_lock: mutex for power gate register access 149 137 */ 150 138 struct tegra_pmc { ··· 170 156 bool cpu_pwr_good_en; 171 157 u32 lp0_vec_phys; 172 158 u32 lp0_vec_size; 159 + DECLARE_BITMAP(powergates_available, TEGRA_POWERGATE_MAX); 173 160 174 161 struct mutex powergates_lock; 175 162 }; ··· 179 164 .base = NULL, 180 165 .suspend_mode = TEGRA_SUSPEND_NONE, 181 166 }; 167 + 168 + static inline struct tegra_powergate * 169 + to_powergate(struct generic_pm_domain *domain) 170 + { 171 + return container_of(domain, struct tegra_powergate, genpd); 172 + } 182 173 183 174 static u32 tegra_pmc_readl(unsigned long offset) 184 175 { ··· 207 186 static inline bool tegra_powergate_is_valid(int id) 208 187 { 209 188 return (pmc->soc && pmc->soc->powergates[id]); 189 + } 190 + 191 + static inline bool tegra_powergate_is_available(int id) 192 + { 193 + return test_bit(id, pmc->powergates_available); 194 + } 195 + 196 + static int tegra_powergate_lookup(struct tegra_pmc *pmc, const char *name) 197 + { 198 + unsigned int i; 199 + 200 + if (!pmc || !pmc->soc || !name) 201 + return -EINVAL; 202 + 203 + for (i = 0; i < pmc->soc->num_powergates; i++) { 204 + if (!tegra_powergate_is_valid(i)) 205 + continue; 206 + 207 + if (!strcmp(name, pmc->soc->powergates[i])) 208 + return i; 209 + } 210 + 211 + dev_err(pmc->dev, "powergate %s not found\n", name); 212 + 213 + return -ENODEV; 210 214 } 211 215 212 216 /** ··· 264 218 return err; 265 219 } 266 220 267 - /** 268 - * tegra_powergate_power_on() - power on partition 269 - * @id: partition ID 270 - */ 271 - int tegra_powergate_power_on(unsigned int id) 272 - { 273 - if (!tegra_powergate_is_valid(id)) 274 - return -EINVAL; 275 - 276 - return tegra_powergate_set(id, true); 277 - } 278 - 279 - /** 280 - * tegra_powergate_power_off() - power off partition 281 - * @id: partition ID 282 - */ 283 - int tegra_powergate_power_off(unsigned int id) 284 - { 285 - if (!tegra_powergate_is_valid(id)) 286 - return -EINVAL; 287 - 288 - return tegra_powergate_set(id, false); 289 - } 290 - EXPORT_SYMBOL(tegra_powergate_power_off); 291 - 292 - /** 293 - * tegra_powergate_is_powered() - check if partition is powered 294 - * @id: partition ID 295 - */ 296 - int tegra_powergate_is_powered(unsigned int id) 297 - { 298 - int status; 299 - 300 - if (!tegra_powergate_is_valid(id)) 301 - return -EINVAL; 302 - 303 - mutex_lock(&pmc->powergates_lock); 304 - status = tegra_powergate_state(id); 305 - mutex_unlock(&pmc->powergates_lock); 306 - 307 - return status; 308 - } 309 - 310 - /** 311 - * tegra_powergate_remove_clamping() - remove power clamps for partition 312 - * @id: partition ID 313 - */ 314 - int tegra_powergate_remove_clamping(unsigned int id) 221 + static int __tegra_powergate_remove_clamping(unsigned int id) 315 222 { 316 223 u32 mask; 317 - 318 - if (!tegra_powergate_is_valid(id)) 319 - return -EINVAL; 320 224 321 225 mutex_lock(&pmc->powergates_lock); 322 226 ··· 299 303 300 304 return 0; 301 305 } 306 + 307 + static void tegra_powergate_disable_clocks(struct tegra_powergate *pg) 308 + { 309 + unsigned int i; 310 + 311 + for (i = 0; i < pg->num_clks; i++) 312 + clk_disable_unprepare(pg->clks[i]); 313 + } 314 + 315 + static int tegra_powergate_enable_clocks(struct tegra_powergate *pg) 316 + { 317 + unsigned int i; 318 + int err; 319 + 320 + for (i = 0; i < pg->num_clks; i++) { 321 + err = clk_prepare_enable(pg->clks[i]); 322 + if (err) 323 + goto out; 324 + } 325 + 326 + return 0; 327 + 328 + out: 329 + while (i--) 330 + clk_disable_unprepare(pg->clks[i]); 331 + 332 + return err; 333 + } 334 + 335 + static int tegra_powergate_reset_assert(struct tegra_powergate *pg) 336 + { 337 + unsigned int i; 338 + int err; 339 + 340 + for (i = 0; i < pg->num_resets; i++) { 341 + err = reset_control_assert(pg->resets[i]); 342 + if (err) 343 + return err; 344 + } 345 + 346 + return 0; 347 + } 348 + 349 + static int tegra_powergate_reset_deassert(struct tegra_powergate *pg) 350 + { 351 + unsigned int i; 352 + int err; 353 + 354 + for (i = 0; i < pg->num_resets; i++) { 355 + err = reset_control_deassert(pg->resets[i]); 356 + if (err) 357 + return err; 358 + } 359 + 360 + return 0; 361 + } 362 + 363 + static int tegra_powergate_power_up(struct tegra_powergate *pg, 364 + bool disable_clocks) 365 + { 366 + int err; 367 + 368 + err = tegra_powergate_reset_assert(pg); 369 + if (err) 370 + return err; 371 + 372 + usleep_range(10, 20); 373 + 374 + err = tegra_powergate_set(pg->id, true); 375 + if (err < 0) 376 + return err; 377 + 378 + usleep_range(10, 20); 379 + 380 + err = tegra_powergate_enable_clocks(pg); 381 + if (err) 382 + goto disable_clks; 383 + 384 + usleep_range(10, 20); 385 + 386 + err = __tegra_powergate_remove_clamping(pg->id); 387 + if (err) 388 + goto disable_clks; 389 + 390 + usleep_range(10, 20); 391 + 392 + err = tegra_powergate_reset_deassert(pg); 393 + if (err) 394 + goto powergate_off; 395 + 396 + usleep_range(10, 20); 397 + 398 + if (disable_clocks) 399 + tegra_powergate_disable_clocks(pg); 400 + 401 + return 0; 402 + 403 + disable_clks: 404 + tegra_powergate_disable_clocks(pg); 405 + usleep_range(10, 20); 406 + powergate_off: 407 + tegra_powergate_set(pg->id, false); 408 + 409 + return err; 410 + } 411 + 412 + static int tegra_powergate_power_down(struct tegra_powergate *pg) 413 + { 414 + int err; 415 + 416 + err = tegra_powergate_enable_clocks(pg); 417 + if (err) 418 + return err; 419 + 420 + usleep_range(10, 20); 421 + 422 + err = tegra_powergate_reset_assert(pg); 423 + if (err) 424 + goto disable_clks; 425 + 426 + usleep_range(10, 20); 427 + 428 + tegra_powergate_disable_clocks(pg); 429 + 430 + usleep_range(10, 20); 431 + 432 + err = tegra_powergate_set(pg->id, false); 433 + if (err) 434 + goto assert_resets; 435 + 436 + return 0; 437 + 438 + assert_resets: 439 + tegra_powergate_enable_clocks(pg); 440 + usleep_range(10, 20); 441 + tegra_powergate_reset_deassert(pg); 442 + usleep_range(10, 20); 443 + disable_clks: 444 + tegra_powergate_disable_clocks(pg); 445 + 446 + return err; 447 + } 448 + 449 + static int tegra_genpd_power_on(struct generic_pm_domain *domain) 450 + { 451 + struct tegra_powergate *pg = to_powergate(domain); 452 + struct tegra_pmc *pmc = pg->pmc; 453 + int err; 454 + 455 + err = tegra_powergate_power_up(pg, true); 456 + if (err) 457 + dev_err(pmc->dev, "failed to turn on PM domain %s: %d\n", 458 + pg->genpd.name, err); 459 + 460 + return err; 461 + } 462 + 463 + static int tegra_genpd_power_off(struct generic_pm_domain *domain) 464 + { 465 + struct tegra_powergate *pg = to_powergate(domain); 466 + struct tegra_pmc *pmc = pg->pmc; 467 + int err; 468 + 469 + err = tegra_powergate_power_down(pg); 470 + if (err) 471 + dev_err(pmc->dev, "failed to turn off PM domain %s: %d\n", 472 + pg->genpd.name, err); 473 + 474 + return err; 475 + } 476 + 477 + /** 478 + * tegra_powergate_power_on() - power on partition 479 + * @id: partition ID 480 + */ 481 + int tegra_powergate_power_on(unsigned int id) 482 + { 483 + if (!tegra_powergate_is_available(id)) 484 + return -EINVAL; 485 + 486 + return tegra_powergate_set(id, true); 487 + } 488 + 489 + /** 490 + * tegra_powergate_power_off() - power off partition 491 + * @id: partition ID 492 + */ 493 + int tegra_powergate_power_off(unsigned int id) 494 + { 495 + if (!tegra_powergate_is_available(id)) 496 + return -EINVAL; 497 + 498 + return tegra_powergate_set(id, false); 499 + } 500 + EXPORT_SYMBOL(tegra_powergate_power_off); 501 + 502 + /** 503 + * tegra_powergate_is_powered() - check if partition is powered 504 + * @id: partition ID 505 + */ 506 + int tegra_powergate_is_powered(unsigned int id) 507 + { 508 + int status; 509 + 510 + if (!tegra_powergate_is_valid(id)) 511 + return -EINVAL; 512 + 513 + mutex_lock(&pmc->powergates_lock); 514 + status = tegra_powergate_state(id); 515 + mutex_unlock(&pmc->powergates_lock); 516 + 517 + return status; 518 + } 519 + 520 + /** 521 + * tegra_powergate_remove_clamping() - remove power clamps for partition 522 + * @id: partition ID 523 + */ 524 + int tegra_powergate_remove_clamping(unsigned int id) 525 + { 526 + if (!tegra_powergate_is_available(id)) 527 + return -EINVAL; 528 + 529 + return __tegra_powergate_remove_clamping(id); 530 + } 302 531 EXPORT_SYMBOL(tegra_powergate_remove_clamping); 303 532 304 533 /** ··· 537 316 int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk, 538 317 struct reset_control *rst) 539 318 { 540 - int ret; 319 + struct tegra_powergate pg; 320 + int err; 541 321 542 - reset_control_assert(rst); 322 + pg.id = id; 323 + pg.clks = &clk; 324 + pg.num_clks = 1; 325 + pg.resets = &rst; 326 + pg.num_resets = 1; 543 327 544 - ret = tegra_powergate_power_on(id); 545 - if (ret) 546 - goto err_power; 328 + err = tegra_powergate_power_up(&pg, false); 329 + if (err) 330 + pr_err("failed to turn on partition %d: %d\n", id, err); 547 331 548 - ret = clk_prepare_enable(clk); 549 - if (ret) 550 - goto err_clk; 551 - 552 - usleep_range(10, 20); 553 - 554 - ret = tegra_powergate_remove_clamping(id); 555 - if (ret) 556 - goto err_clamp; 557 - 558 - usleep_range(10, 20); 559 - reset_control_deassert(rst); 560 - 561 - return 0; 562 - 563 - err_clamp: 564 - clk_disable_unprepare(clk); 565 - err_clk: 566 - tegra_powergate_power_off(id); 567 - err_power: 568 - return ret; 332 + return err; 569 333 } 570 334 EXPORT_SYMBOL(tegra_powergate_sequence_power_up); 571 335 ··· 690 484 return -ENOMEM; 691 485 692 486 return 0; 487 + } 488 + 489 + static int tegra_powergate_of_get_clks(struct tegra_powergate *pg, 490 + struct device_node *np) 491 + { 492 + struct clk *clk; 493 + unsigned int i, count; 494 + int err; 495 + 496 + count = of_count_phandle_with_args(np, "clocks", "#clock-cells"); 497 + if (count == 0) 498 + return -ENODEV; 499 + 500 + pg->clks = kcalloc(count, sizeof(clk), GFP_KERNEL); 501 + if (!pg->clks) 502 + return -ENOMEM; 503 + 504 + for (i = 0; i < count; i++) { 505 + pg->clks[i] = of_clk_get(np, i); 506 + if (IS_ERR(pg->clks[i])) { 507 + err = PTR_ERR(pg->clks[i]); 508 + goto err; 509 + } 510 + } 511 + 512 + pg->num_clks = count; 513 + 514 + return 0; 515 + 516 + err: 517 + while (i--) 518 + clk_put(pg->clks[i]); 519 + kfree(pg->clks); 520 + 521 + return err; 522 + } 523 + 524 + static int tegra_powergate_of_get_resets(struct tegra_powergate *pg, 525 + struct device_node *np) 526 + { 527 + struct reset_control *rst; 528 + unsigned int i, count; 529 + int err; 530 + 531 + count = of_count_phandle_with_args(np, "resets", "#reset-cells"); 532 + if (count == 0) 533 + return -ENODEV; 534 + 535 + pg->resets = kcalloc(count, sizeof(rst), GFP_KERNEL); 536 + if (!pg->resets) 537 + return -ENOMEM; 538 + 539 + for (i = 0; i < count; i++) { 540 + pg->resets[i] = of_reset_control_get_by_index(np, i); 541 + if (IS_ERR(pg->resets[i])) { 542 + err = PTR_ERR(pg->resets[i]); 543 + goto error; 544 + } 545 + } 546 + 547 + pg->num_resets = count; 548 + 549 + return 0; 550 + 551 + error: 552 + while (i--) 553 + reset_control_put(pg->resets[i]); 554 + kfree(pg->resets); 555 + 556 + return err; 557 + } 558 + 559 + static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np) 560 + { 561 + struct tegra_powergate *pg; 562 + bool off; 563 + int id; 564 + 565 + pg = kzalloc(sizeof(*pg), GFP_KERNEL); 566 + if (!pg) 567 + goto error; 568 + 569 + id = tegra_powergate_lookup(pmc, np->name); 570 + if (id < 0) 571 + goto free_mem; 572 + 573 + /* 574 + * Clear the bit for this powergate so it cannot be managed 575 + * directly via the legacy APIs for controlling powergates. 576 + */ 577 + clear_bit(id, pmc->powergates_available); 578 + 579 + pg->id = id; 580 + pg->genpd.name = np->name; 581 + pg->genpd.power_off = tegra_genpd_power_off; 582 + pg->genpd.power_on = tegra_genpd_power_on; 583 + pg->pmc = pmc; 584 + 585 + if (tegra_powergate_of_get_clks(pg, np)) 586 + goto set_available; 587 + 588 + if (tegra_powergate_of_get_resets(pg, np)) 589 + goto remove_clks; 590 + 591 + off = !tegra_powergate_is_powered(pg->id); 592 + 593 + pm_genpd_init(&pg->genpd, NULL, off); 594 + 595 + if (of_genpd_add_provider_simple(np, &pg->genpd)) 596 + goto remove_resets; 597 + 598 + dev_dbg(pmc->dev, "added power domain %s\n", pg->genpd.name); 599 + 600 + return; 601 + 602 + remove_resets: 603 + while (pg->num_resets--) 604 + reset_control_put(pg->resets[pg->num_resets]); 605 + kfree(pg->resets); 606 + 607 + remove_clks: 608 + while (pg->num_clks--) 609 + clk_put(pg->clks[pg->num_clks]); 610 + kfree(pg->clks); 611 + 612 + set_available: 613 + set_bit(id, pmc->powergates_available); 614 + 615 + free_mem: 616 + kfree(pg); 617 + 618 + error: 619 + dev_err(pmc->dev, "failed to create power domain for %s\n", np->name); 620 + } 621 + 622 + static void tegra_powergate_init(struct tegra_pmc *pmc) 623 + { 624 + struct device_node *np, *child; 625 + 626 + np = of_get_child_by_name(pmc->dev->of_node, "powergates"); 627 + if (!np) 628 + return; 629 + 630 + for_each_child_of_node(np, child) { 631 + tegra_powergate_add(pmc, child); 632 + of_node_put(child); 633 + } 634 + 635 + of_node_put(np); 693 636 } 694 637 695 638 static int tegra_io_rail_prepare(unsigned int id, unsigned long *request, ··· 1242 887 return err; 1243 888 } 1244 889 890 + tegra_powergate_init(pmc); 891 + 1245 892 mutex_lock(&pmc->powergates_lock); 1246 893 iounmap(pmc->base); 1247 894 pmc->base = base; ··· 1477 1120 const struct of_device_id *match; 1478 1121 struct device_node *np; 1479 1122 struct resource regs; 1123 + unsigned int i; 1480 1124 bool invert; 1481 1125 u32 value; 1482 1126 ··· 1526 1168 pr_err("failed to map PMC registers\n"); 1527 1169 return -ENXIO; 1528 1170 } 1171 + 1172 + /* Create a bit-map of the available and valid partitions */ 1173 + for (i = 0; i < pmc->soc->num_powergates; i++) 1174 + if (pmc->soc->powergates[i]) 1175 + set_bit(i, pmc->powergates_available); 1529 1176 1530 1177 mutex_init(&pmc->powergates_lock); 1531 1178
+1
include/soc/tegra/pmc.h
··· 72 72 #define TEGRA_POWERGATE_AUD 27 73 73 #define TEGRA_POWERGATE_DFD 28 74 74 #define TEGRA_POWERGATE_VE2 29 75 + #define TEGRA_POWERGATE_MAX TEGRA_POWERGATE_VE2 75 76 76 77 #define TEGRA_POWERGATE_3D0 TEGRA_POWERGATE_3D 77 78