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

Merge tag 'tegra-for-4.17-soc-2' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/drivers

Pull "soc/tegra: Changes for v4.17-rc1" from Thierry Reding:

This contains more Tegra194 support as well as an implementation for the
MBIST workaround needed to avoid some memory-related issues on Tegra210.

* tag 'tegra-for-4.17-soc-2' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/tegra/linux:
soc/tegra: pmc: Use the new reset APIs to manage reset controllers
soc/tegra: pmc: Pass PMC to tegra_powergate_power_up()
soc/tegra: pmc: MBIST work around for Tegra210
soc/tegra: pmc: Add Tegra194 compatibility string
soc/tegra: Add Tegra194 SoC configuration option

+38 -70
+10
drivers/soc/tegra/Kconfig
··· 104 104 multi-format support, ISP for image capture processing and BPMP for 105 105 power management. 106 106 107 + config ARCH_TEGRA_194_SOC 108 + bool "NVIDIA Tegra194 SoC" 109 + select MAILBOX 110 + select TEGRA_BPMP 111 + select TEGRA_HSP_MBOX 112 + select TEGRA_IVC 113 + select SOC_TEGRA_PMC 114 + help 115 + Enable support for the NVIDIA Tegra194 SoC. 116 + 107 117 endif 108 118 endif 109 119
+28 -70
drivers/soc/tegra/pmc.c
··· 127 127 unsigned int id; 128 128 struct clk **clks; 129 129 unsigned int num_clks; 130 - struct reset_control **resets; 131 - unsigned int num_resets; 130 + struct reset_control *reset; 132 131 }; 133 132 134 133 struct tegra_io_pad_soc { ··· 152 153 153 154 bool has_tsense_reset; 154 155 bool has_gpu_clamps; 156 + bool needs_mbist_war; 155 157 156 158 const struct tegra_io_pad_soc *io_pads; 157 159 unsigned int num_io_pads; ··· 368 368 return err; 369 369 } 370 370 371 - static int tegra_powergate_reset_assert(struct tegra_powergate *pg) 371 + int __weak tegra210_clk_handle_mbist_war(unsigned int id) 372 372 { 373 - unsigned int i; 374 - int err; 375 - 376 - for (i = 0; i < pg->num_resets; i++) { 377 - err = reset_control_assert(pg->resets[i]); 378 - if (err) 379 - return err; 380 - } 381 - 382 - return 0; 383 - } 384 - 385 - static int tegra_powergate_reset_deassert(struct tegra_powergate *pg) 386 - { 387 - unsigned int i; 388 - int err; 389 - 390 - for (i = 0; i < pg->num_resets; i++) { 391 - err = reset_control_deassert(pg->resets[i]); 392 - if (err) 393 - return err; 394 - } 395 - 396 373 return 0; 397 374 } 398 375 ··· 378 401 { 379 402 int err; 380 403 381 - err = tegra_powergate_reset_assert(pg); 404 + err = reset_control_assert(pg->reset); 382 405 if (err) 383 406 return err; 384 407 ··· 402 425 403 426 usleep_range(10, 20); 404 427 405 - err = tegra_powergate_reset_deassert(pg); 428 + err = reset_control_deassert(pg->reset); 406 429 if (err) 407 430 goto powergate_off; 408 431 409 432 usleep_range(10, 20); 433 + 434 + if (pg->pmc->soc->needs_mbist_war) 435 + err = tegra210_clk_handle_mbist_war(pg->id); 436 + if (err) 437 + goto disable_clks; 410 438 411 439 if (disable_clocks) 412 440 tegra_powergate_disable_clocks(pg); ··· 438 456 439 457 usleep_range(10, 20); 440 458 441 - err = tegra_powergate_reset_assert(pg); 459 + err = reset_control_assert(pg->reset); 442 460 if (err) 443 461 goto disable_clks; 444 462 ··· 457 475 assert_resets: 458 476 tegra_powergate_enable_clocks(pg); 459 477 usleep_range(10, 20); 460 - tegra_powergate_reset_deassert(pg); 478 + reset_control_deassert(pg->reset); 461 479 usleep_range(10, 20); 462 480 463 481 disable_clks: ··· 568 586 pg.id = id; 569 587 pg.clks = &clk; 570 588 pg.num_clks = 1; 571 - pg.resets = &rst; 572 - pg.num_resets = 1; 589 + pg.reset = rst; 590 + pg.pmc = pmc; 573 591 574 592 err = tegra_powergate_power_up(&pg, false); 575 593 if (err) ··· 757 775 static int tegra_powergate_of_get_resets(struct tegra_powergate *pg, 758 776 struct device_node *np, bool off) 759 777 { 760 - struct reset_control *rst; 761 - unsigned int i, count; 762 778 int err; 763 779 764 - count = of_count_phandle_with_args(np, "resets", "#reset-cells"); 765 - if (count == 0) 766 - return -ENODEV; 767 - 768 - pg->resets = kcalloc(count, sizeof(rst), GFP_KERNEL); 769 - if (!pg->resets) 770 - return -ENOMEM; 771 - 772 - for (i = 0; i < count; i++) { 773 - pg->resets[i] = of_reset_control_get_by_index(np, i); 774 - if (IS_ERR(pg->resets[i])) { 775 - err = PTR_ERR(pg->resets[i]); 776 - goto error; 777 - } 778 - 779 - if (off) 780 - err = reset_control_assert(pg->resets[i]); 781 - else 782 - err = reset_control_deassert(pg->resets[i]); 783 - 784 - if (err) { 785 - reset_control_put(pg->resets[i]); 786 - goto error; 787 - } 780 + pg->reset = of_reset_control_array_get_exclusive(np); 781 + if (IS_ERR(pg->reset)) { 782 + err = PTR_ERR(pg->reset); 783 + pr_err("failed to get device resets: %d\n", err); 784 + return err; 788 785 } 789 786 790 - pg->num_resets = count; 787 + if (off) 788 + err = reset_control_assert(pg->reset); 789 + else 790 + err = reset_control_deassert(pg->reset); 791 791 792 - return 0; 793 - 794 - error: 795 - while (i--) 796 - reset_control_put(pg->resets[i]); 797 - 798 - kfree(pg->resets); 792 + if (err) 793 + reset_control_put(pg->reset); 799 794 800 795 return err; 801 796 } ··· 864 905 pm_genpd_remove(&pg->genpd); 865 906 866 907 remove_resets: 867 - while (pg->num_resets--) 868 - reset_control_put(pg->resets[pg->num_resets]); 869 - 870 - kfree(pg->resets); 908 + reset_control_put(pg->reset); 871 909 872 910 remove_clks: 873 911 while (pg->num_clks--) ··· 1771 1815 .cpu_powergates = tegra210_cpu_powergates, 1772 1816 .has_tsense_reset = true, 1773 1817 .has_gpu_clamps = true, 1818 + .needs_mbist_war = true, 1774 1819 .num_io_pads = ARRAY_SIZE(tegra210_io_pads), 1775 1820 .io_pads = tegra210_io_pads, 1776 1821 .regs = &tegra20_pmc_regs, ··· 1877 1920 }; 1878 1921 1879 1922 static const struct of_device_id tegra_pmc_match[] = { 1923 + { .compatible = "nvidia,tegra194-pmc", .data = &tegra186_pmc_soc }, 1880 1924 { .compatible = "nvidia,tegra186-pmc", .data = &tegra186_pmc_soc }, 1881 1925 { .compatible = "nvidia,tegra210-pmc", .data = &tegra210_pmc_soc }, 1882 1926 { .compatible = "nvidia,tegra132-pmc", .data = &tegra124_pmc_soc },