cm3_system_reset.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*
  2. * Copyright (C) 2020 Marek Behun, CZ.NIC
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. * https://spdx.org/licenses
  6. */
  7. #include <stdbool.h>
  8. #include <common/debug.h>
  9. #include <drivers/arm/gic_common.h>
  10. #include <drivers/arm/gicv3.h>
  11. #include <drivers/delay_timer.h>
  12. #include <lib/mmio.h>
  13. #include <lib/utils_def.h>
  14. #include <a3700_pm.h>
  15. #include <platform_def.h>
  16. #include <mvebu_def.h>
  17. /* IO Decoder Error Interrupt Status Registers */
  18. #define MVEBU_DEC_WIN_REGS_BASE(p) (MVEBU_REGS_BASE + 0xC000 + \
  19. (p) * 0x100)
  20. #define MVEBU_DEC_WIN_ERR_INT_STS_REG(p) (MVEBU_DEC_WIN_REGS_BASE(p) + \
  21. 0xF8)
  22. /* Cortex-M3 Secure Processor Mailbox Registers */
  23. #define MVEBU_RWTM_PARAM0_REG (MVEBU_RWTM_REG_BASE)
  24. #define MVEBU_RWTM_CMD_REG (MVEBU_RWTM_REG_BASE + 0x40)
  25. #define MVEBU_RWTM_HOST_INT_RESET_REG (MVEBU_RWTM_REG_BASE + 0xC8)
  26. #define MVEBU_RWTM_HOST_INT_MASK_REG (MVEBU_RWTM_REG_BASE + 0xCC)
  27. #define MVEBU_RWTM_HOST_INT_SP_COMPLETE BIT(0)
  28. #define MVEBU_RWTM_REBOOT_CMD 0x0009
  29. #define MVEBU_RWTM_REBOOT_MAGIC 0xDEADBEEF
  30. static inline uint32_t a3700_gicd_read(uint32_t reg)
  31. {
  32. return mmio_read_32(PLAT_MARVELL_GICD_BASE + reg);
  33. }
  34. static inline void a3700_gicd_write(uint32_t reg, uint32_t value)
  35. {
  36. mmio_write_32(PLAT_MARVELL_GICD_BASE + reg, value);
  37. }
  38. static void a3700_gicd_ctlr_clear_bits(uint32_t bits)
  39. {
  40. uint32_t val;
  41. val = a3700_gicd_read(GICD_CTLR);
  42. if ((val & bits) != 0U) {
  43. a3700_gicd_write(GICD_CTLR, val & ~bits);
  44. mdelay(1);
  45. if ((a3700_gicd_read(GICD_CTLR) & GICD_CTLR_RWP_BIT) != 0U) {
  46. ERROR("could not clear bits 0x%x in GIC distributor control\n",
  47. bits);
  48. }
  49. }
  50. }
  51. static void a3700_gic_dist_disable_irqs(void)
  52. {
  53. int i;
  54. for (i = 32; i < 224; i += 32) {
  55. a3700_gicd_write(GICD_ICENABLER + (i >> 3), GENMASK_32(31, 0));
  56. }
  57. }
  58. static inline uintptr_t a3700_rdist_base(unsigned int proc)
  59. {
  60. return PLAT_MARVELL_GICR_BASE + (proc << GICR_V3_PCPUBASE_SHIFT);
  61. }
  62. static inline uint32_t a3700_gicr_read(unsigned int proc, uint32_t reg)
  63. {
  64. return mmio_read_32(a3700_rdist_base(proc) + reg);
  65. }
  66. static inline void a3700_gicr_write(unsigned int proc, uint32_t reg,
  67. uint32_t value)
  68. {
  69. mmio_write_32(a3700_rdist_base(proc) + reg, value);
  70. }
  71. static void a3700_gic_redist_disable_irqs(unsigned int proc)
  72. {
  73. a3700_gicr_write(proc, GICR_ICENABLER0, GENMASK_32(31, 0));
  74. mdelay(1);
  75. if ((a3700_gicr_read(proc, GICR_CTLR) & GICR_CTLR_RWP_BIT) != 0U) {
  76. ERROR("could not disable core %u PPIs & SGIs\n", proc);
  77. }
  78. }
  79. static void a3700_gic_redist_mark_asleep(unsigned int proc)
  80. {
  81. a3700_gicr_write(proc, GICR_WAKER,
  82. a3700_gicr_read(proc, GICR_WAKER) | WAKER_PS_BIT);
  83. mdelay(1);
  84. if ((a3700_gicr_read(proc, GICR_WAKER) & WAKER_CA_BIT) == 0U) {
  85. ERROR("could not mark core %u redistributor asleep\n", proc);
  86. }
  87. }
  88. static void a3700_io_addr_dec_ack_err_irq(void)
  89. {
  90. unsigned int periph;
  91. for (periph = 0; periph < 16; ++periph) {
  92. /* periph 6 does not exist */
  93. if (periph == 6)
  94. continue;
  95. mmio_write_32(MVEBU_DEC_WIN_ERR_INT_STS_REG(periph),
  96. GENMASK_32(1, 0));
  97. }
  98. }
  99. static void a3700_gic_reset(void)
  100. {
  101. a3700_gic_redist_disable_irqs(0);
  102. a3700_gic_redist_disable_irqs(1);
  103. a3700_gic_redist_mark_asleep(0);
  104. a3700_gic_redist_mark_asleep(1);
  105. a3700_io_addr_dec_ack_err_irq();
  106. a3700_pm_ack_irq();
  107. a3700_gic_dist_disable_irqs();
  108. a3700_gicd_ctlr_clear_bits(CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1NS_BIT |
  109. CTLR_ENABLE_G1S_BIT);
  110. /* Clearing ARE_S and ARE_NS bits is undefined in the specification, but
  111. * works if the previous operations are successful. We need to do it in
  112. * order to put GIC into the same state it was in just after reset. If
  113. * this is successful, the rWTM firmware in the secure coprocessor will
  114. * reset all other peripherals one by one, load new firmware and boot
  115. * it, all without triggering the true warm reset via the WARM_RESET
  116. * register (which may hang the board).
  117. */
  118. a3700_gicd_ctlr_clear_bits(CTLR_ARE_S_BIT);
  119. a3700_gicd_ctlr_clear_bits(CTLR_ARE_NS_BIT);
  120. }
  121. static inline bool rwtm_completed(void)
  122. {
  123. return (mmio_read_32(MVEBU_RWTM_HOST_INT_RESET_REG) &
  124. MVEBU_RWTM_HOST_INT_SP_COMPLETE) != 0;
  125. }
  126. static bool rwtm_wait(int ms)
  127. {
  128. while (ms && !rwtm_completed()) {
  129. mdelay(1);
  130. --ms;
  131. }
  132. return rwtm_completed();
  133. }
  134. void cm3_system_reset(void)
  135. {
  136. int tries = 5;
  137. /* Put GIC into the same state it was just after reset. This is needed
  138. * for the reset issue workaround to work.
  139. */
  140. a3700_gic_reset();
  141. for (; tries > 0; --tries) {
  142. mmio_clrbits_32(MVEBU_RWTM_HOST_INT_RESET_REG,
  143. MVEBU_RWTM_HOST_INT_SP_COMPLETE);
  144. mmio_write_32(MVEBU_RWTM_PARAM0_REG, MVEBU_RWTM_REBOOT_MAGIC);
  145. mmio_write_32(MVEBU_RWTM_CMD_REG, MVEBU_RWTM_REBOOT_CMD);
  146. if (rwtm_wait(10)) {
  147. break;
  148. }
  149. mdelay(100);
  150. }
  151. /* If we reach here, the command is not implemented. */
  152. WARN("System reset command not implemented in WTMI firmware!\n");
  153. }