pmc.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <arch_helpers.h>
  8. #include <common/debug.h>
  9. #include <lib/mmio.h>
  10. #include <pmc.h>
  11. #include <tegra_def.h>
  12. #define RESET_ENABLE 0x10U
  13. /* Module IDs used during power ungate procedure */
  14. static const uint32_t pmc_cpu_powergate_id[4] = {
  15. 14, /* CPU 0 */
  16. 9, /* CPU 1 */
  17. 10, /* CPU 2 */
  18. 11 /* CPU 3 */
  19. };
  20. /*******************************************************************************
  21. * Power ungate CPU to start the boot process. CPU reset vectors must be
  22. * populated before calling this function.
  23. ******************************************************************************/
  24. void tegra_pmc_cpu_on(int32_t cpu)
  25. {
  26. uint32_t val;
  27. /*
  28. * Check if CPU is already power ungated
  29. */
  30. val = tegra_pmc_read_32(PMC_PWRGATE_STATUS);
  31. if ((val & (1U << pmc_cpu_powergate_id[cpu])) == 0U) {
  32. /*
  33. * The PMC deasserts the START bit when it starts the power
  34. * ungate process. Loop till no power toggle is in progress.
  35. */
  36. do {
  37. val = tegra_pmc_read_32(PMC_PWRGATE_TOGGLE);
  38. } while ((val & PMC_TOGGLE_START) != 0U);
  39. /*
  40. * Start the power ungate procedure
  41. */
  42. val = pmc_cpu_powergate_id[cpu] | PMC_TOGGLE_START;
  43. tegra_pmc_write_32(PMC_PWRGATE_TOGGLE, val);
  44. /*
  45. * The PMC deasserts the START bit when it starts the power
  46. * ungate process. Loop till powergate START bit is asserted.
  47. */
  48. do {
  49. val = tegra_pmc_read_32(PMC_PWRGATE_TOGGLE);
  50. } while ((val & (1U << 8)) != 0U);
  51. /* loop till the CPU is power ungated */
  52. do {
  53. val = tegra_pmc_read_32(PMC_PWRGATE_STATUS);
  54. } while ((val & (1U << pmc_cpu_powergate_id[cpu])) == 0U);
  55. }
  56. }
  57. /*******************************************************************************
  58. * Setup CPU vectors for resume from deep sleep
  59. ******************************************************************************/
  60. void tegra_pmc_cpu_setup(uint64_t reset_addr)
  61. {
  62. uint32_t val;
  63. tegra_pmc_write_32(PMC_SECURE_SCRATCH34,
  64. ((uint32_t)reset_addr & 0xFFFFFFFFU) | 1U);
  65. val = (uint32_t)(reset_addr >> 32U);
  66. tegra_pmc_write_32(PMC_SECURE_SCRATCH35, val & 0x7FFU);
  67. }
  68. /*******************************************************************************
  69. * Lock CPU vectors to restrict further writes
  70. ******************************************************************************/
  71. void tegra_pmc_lock_cpu_vectors(void)
  72. {
  73. uint32_t val;
  74. /* lock PMC_SECURE_SCRATCH22 */
  75. val = tegra_pmc_read_32(PMC_SECURE_DISABLE2);
  76. val |= PMC_SECURE_DISABLE2_WRITE22_ON;
  77. tegra_pmc_write_32(PMC_SECURE_DISABLE2, val);
  78. /* lock PMC_SECURE_SCRATCH34/35 */
  79. val = tegra_pmc_read_32(PMC_SECURE_DISABLE3);
  80. val |= (PMC_SECURE_DISABLE3_WRITE34_ON |
  81. PMC_SECURE_DISABLE3_WRITE35_ON);
  82. tegra_pmc_write_32(PMC_SECURE_DISABLE3, val);
  83. }
  84. /*******************************************************************************
  85. * Find out if this is the last standing CPU
  86. ******************************************************************************/
  87. bool tegra_pmc_is_last_on_cpu(void)
  88. {
  89. int i, cpu = read_mpidr() & MPIDR_CPU_MASK;
  90. uint32_t val = tegra_pmc_read_32(PMC_PWRGATE_STATUS);
  91. bool status = true;
  92. /* check if this is the last standing CPU */
  93. for (i = 0; i < PLATFORM_MAX_CPUS_PER_CLUSTER; i++) {
  94. /* skip the current CPU */
  95. if (i == cpu)
  96. continue;
  97. /* are other CPUs already power gated? */
  98. if ((val & ((uint32_t)1 << pmc_cpu_powergate_id[i])) != 0U) {
  99. status = false;
  100. }
  101. }
  102. return status;
  103. }
  104. /*******************************************************************************
  105. * Handler to be called on exiting System suspend. Right now only DPD registers
  106. * are cleared.
  107. ******************************************************************************/
  108. void tegra_pmc_resume(void)
  109. {
  110. /* Clear DPD sample */
  111. mmio_write_32((TEGRA_PMC_BASE + PMC_IO_DPD_SAMPLE), 0x0);
  112. /* Clear DPD Enable */
  113. mmio_write_32((TEGRA_PMC_BASE + PMC_DPD_ENABLE_0), 0x0);
  114. }
  115. /*******************************************************************************
  116. * Restart the system
  117. ******************************************************************************/
  118. __dead2 void tegra_pmc_system_reset(void)
  119. {
  120. uint32_t reg;
  121. reg = tegra_pmc_read_32(PMC_CONFIG);
  122. reg |= RESET_ENABLE; /* restart */
  123. tegra_pmc_write_32(PMC_CONFIG, reg);
  124. wfi();
  125. ERROR("Tegra System Reset: operation not handled.\n");
  126. panic();
  127. }