m0_ctl.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * Copyright (c) 2016, 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 <drivers/delay_timer.h>
  10. #include <lib/mmio.h>
  11. #include <m0_ctl.h>
  12. #include <plat_private.h>
  13. #include <rk3399_def.h>
  14. #include <secure.h>
  15. #include <soc.h>
  16. void m0_init(void)
  17. {
  18. /* secure config for M0 */
  19. mmio_write_32(SGRF_BASE + SGRF_PMU_CON(0), WMSK_BIT(7));
  20. mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6), WMSK_BIT(12));
  21. /* document is wrong, PMU_CRU_GATEDIS_CON0 do not need set MASK BIT */
  22. mmio_setbits_32(PMUCRU_BASE + PMUCRU_GATEDIS_CON0, 0x02);
  23. /*
  24. * To switch the parent to xin24M and div == 1,
  25. *
  26. * We need to close most of the PLLs and clocks except the OSC 24MHz
  27. * durning suspend, and this should be enough to supplies the ddrfreq,
  28. * For the simple handle, we just keep the fixed 24MHz to supply the
  29. * suspend and ddrfreq directly.
  30. */
  31. mmio_write_32(PMUCRU_BASE + PMUCRU_CLKSEL_CON0,
  32. BIT_WITH_WMSK(15) | BITS_WITH_WMASK(0x0, 0x1f, 8));
  33. mmio_write_32(PMUCRU_BASE + PMUCRU_CLKGATE_CON2, WMSK_BIT(5));
  34. }
  35. void m0_configure_execute_addr(uintptr_t addr)
  36. {
  37. /* set the execute address for M0 */
  38. mmio_write_32(SGRF_BASE + SGRF_PMU_CON(3),
  39. BITS_WITH_WMASK((addr >> 12) & 0xffff,
  40. 0xffffu, 0));
  41. mmio_write_32(SGRF_BASE + SGRF_PMU_CON(7),
  42. BITS_WITH_WMASK((addr >> 28) & 0xf,
  43. 0xfu, 0));
  44. }
  45. void m0_start(void)
  46. {
  47. /* enable clocks for M0 */
  48. mmio_write_32(PMUCRU_BASE + PMUCRU_CLKGATE_CON2,
  49. BITS_WITH_WMASK(0x0, 0xf, 0));
  50. /* clean the PARAM_M0_DONE flag, mean that M0 will start working */
  51. mmio_write_32(M0_PARAM_ADDR + PARAM_M0_DONE, 0);
  52. dmbst();
  53. mmio_write_32(PMUCRU_BASE + PMUCRU_SOFTRST_CON0,
  54. BITS_WITH_WMASK(0x0, 0x4, 0));
  55. udelay(5);
  56. /* start M0 */
  57. mmio_write_32(PMUCRU_BASE + PMUCRU_SOFTRST_CON0,
  58. BITS_WITH_WMASK(0x0, 0x20, 0));
  59. dmbst();
  60. }
  61. void m0_stop(void)
  62. {
  63. /* stop M0 */
  64. mmio_write_32(PMUCRU_BASE + PMUCRU_SOFTRST_CON0,
  65. BITS_WITH_WMASK(0x24, 0x24, 0));
  66. /* disable clocks for M0 */
  67. mmio_write_32(PMUCRU_BASE + PMUCRU_CLKGATE_CON2,
  68. BITS_WITH_WMASK(0xf, 0xf, 0));
  69. }
  70. void m0_wait_done(void)
  71. {
  72. do {
  73. /*
  74. * Don't starve the M0 for access to SRAM, so delay before
  75. * reading the PARAM_M0_DONE value again.
  76. */
  77. udelay(5);
  78. dsb();
  79. } while (mmio_read_32(M0_PARAM_ADDR + PARAM_M0_DONE) != M0_DONE_FLAG);
  80. /*
  81. * Let the M0 settle into WFI before we leave. This is so we don't reset
  82. * the M0 in a bad spot which can cause problems with the M0.
  83. */
  84. udelay(10);
  85. dsb();
  86. }