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