1 /* 2 * Copyright (c) 2023, MediaTek Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 /* TF-A system header */ 8 #include <common/debug.h> 9 #include <drivers/delay_timer.h> 10 #include <lib/mmio.h> 11 #include <lib/spinlock.h> 12 13 /* Vendor header */ 14 #include "apusys.h" 15 #include "apusys_rv.h" 16 #include "apusys_rv_mbox_mpu.h" 17 #include "emi_mpu.h" 18 19 static spinlock_t apusys_rv_lock; 20 21 void apusys_rv_mbox_mpu_init(void) 22 { 23 int i; 24 25 for (i = 0; i < APU_MBOX_NUM; i++) { 26 mmio_write_32(APU_MBOX_FUNC_CFG(i), 27 (MBOX_CTRL_LOCK | 28 (mbox_mpu_setting_tab[i].no_mpu << MBOX_NO_MPU_SHIFT))); 29 mmio_write_32(APU_MBOX_DOMAIN_CFG(i), 30 (MBOX_CTRL_LOCK | 31 (mbox_mpu_setting_tab[i].rx_ns << MBOX_RX_NS_SHIFT) | 32 (mbox_mpu_setting_tab[i].rx_domain << MBOX_RX_DOMAIN_SHIFT) | 33 (mbox_mpu_setting_tab[i].tx_ns << MBOX_TX_NS_SHIFT) | 34 (mbox_mpu_setting_tab[i].tx_domain << MBOX_TX_DOMAIN_SHIFT))); 35 } 36 } 37 38 int apusys_kernel_apusys_rv_setup_reviser(void) 39 { 40 static bool apusys_rv_setup_reviser_called; 41 42 spin_lock(&apusys_rv_lock); 43 44 if (apusys_rv_setup_reviser_called) { 45 WARN(MODULE_TAG "%s: already initialized\n", __func__); 46 spin_unlock(&apusys_rv_lock); 47 return -1; 48 } 49 50 apusys_rv_setup_reviser_called = true; 51 52 mmio_write_32(USERFW_CTXT, CFG_4GB_SEL_EN | CFG_4GB_SEL); 53 mmio_write_32(SECUREFW_CTXT, CFG_4GB_SEL_EN | CFG_4GB_SEL); 54 55 mmio_write_32(UP_IOMMU_CTRL, MMU_CTRL_LOCK | MMU_CTRL | MMU_EN); 56 57 mmio_write_32(UP_NORMAL_DOMAIN_NS, 58 (UP_NORMAL_DOMAIN << UP_DOMAIN_SHIFT) | (UP_NORMAL_NS << UP_NS_SHIFT)); 59 mmio_write_32(UP_PRI_DOMAIN_NS, 60 (UP_PRI_DOMAIN << UP_DOMAIN_SHIFT) | (UP_PRI_NS << UP_NS_SHIFT)); 61 62 mmio_write_32(UP_CORE0_VABASE0, 63 VLD | PARTIAL_ENABLE | (THREAD_NUM_PRI << THREAD_NUM_SHIFT)); 64 mmio_write_32(UP_CORE0_MVABASE0, VASIZE_1MB | (APU_SEC_FW_IOVA >> MVA_34BIT_SHIFT)); 65 66 mmio_write_32(UP_CORE0_VABASE1, 67 VLD | PARTIAL_ENABLE | (THREAD_NUM_NORMAL << THREAD_NUM_SHIFT)); 68 mmio_write_32(UP_CORE0_MVABASE1, VASIZE_1MB | (APU_SEC_FW_IOVA >> MVA_34BIT_SHIFT)); 69 70 spin_unlock(&apusys_rv_lock); 71 72 return 0; 73 } 74 75 int apusys_kernel_apusys_rv_reset_mp(void) 76 { 77 static bool apusys_rv_reset_mp_called; 78 79 spin_lock(&apusys_rv_lock); 80 81 if (apusys_rv_reset_mp_called) { 82 WARN(MODULE_TAG "%s: already initialized\n", __func__); 83 spin_unlock(&apusys_rv_lock); 84 return -1; 85 } 86 87 apusys_rv_reset_mp_called = true; 88 89 mmio_write_32(MD32_SYS_CTRL, MD32_SYS_CTRL_RST); 90 91 udelay(RESET_DEALY_US); 92 93 mmio_write_32(MD32_SYS_CTRL, MD32_G2B_CG_EN | MD32_DBG_EN | MD32_DM_AWUSER_IOMMU_EN | 94 MD32_DM_ARUSER_IOMMU_EN | MD32_PM_AWUSER_IOMMU_EN | MD32_PM_ARUSER_IOMMU_EN | 95 MD32_SOFT_RSTN); 96 97 mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN); 98 mmio_write_32(UP_WAKE_HOST_MASK0, WDT_IRQ_EN); 99 mmio_write_32(UP_WAKE_HOST_MASK1, MBOX0_IRQ_EN | MBOX1_IRQ_EN | MBOX2_IRQ_EN); 100 101 spin_unlock(&apusys_rv_lock); 102 103 return 0; 104 } 105 106 int apusys_kernel_apusys_rv_setup_boot(void) 107 { 108 static bool apusys_rv_setup_boot_called; 109 110 spin_lock(&apusys_rv_lock); 111 112 if (apusys_rv_setup_boot_called) { 113 WARN(MODULE_TAG "%s: already initialized\n", __func__); 114 spin_unlock(&apusys_rv_lock); 115 return -1; 116 } 117 118 apusys_rv_setup_boot_called = true; 119 120 mmio_write_32(MD32_BOOT_CTRL, APU_SEC_FW_IOVA); 121 122 mmio_write_32(MD32_PRE_DEFINE, (PREDEFINE_CACHE_TCM << PREDEF_1G_OFS) | 123 (PREDEFINE_CACHE << PREDEF_2G_OFS) | (PREDEFINE_CACHE << PREDEF_3G_OFS) | 124 (PREDEFINE_CACHE << PREDEF_4G_OFS)); 125 126 spin_unlock(&apusys_rv_lock); 127 return 0; 128 } 129 130 int apusys_kernel_apusys_rv_start_mp(void) 131 { 132 static bool apusys_rv_start_mp_called; 133 134 spin_lock(&apusys_rv_lock); 135 136 if (apusys_rv_start_mp_called) { 137 WARN(MODULE_TAG "%s: already initialized\n", __func__); 138 spin_unlock(&apusys_rv_lock); 139 return -1; 140 } 141 142 apusys_rv_start_mp_called = true; 143 144 mmio_write_32(MD32_RUNSTALL, MD32_RUN); 145 146 spin_unlock(&apusys_rv_lock); 147 148 return 0; 149 } 150 151 static bool watch_dog_is_timeout(void) 152 { 153 if (mmio_read_32(WDT_INT) != WDT_INT_W1C) { 154 ERROR(MODULE_TAG "%s: WDT does not timeout\n", __func__); 155 return false; 156 } 157 return true; 158 } 159 160 int apusys_kernel_apusys_rv_stop_mp(void) 161 { 162 static bool apusys_rv_stop_mp_called; 163 164 spin_lock(&apusys_rv_lock); 165 166 if (apusys_rv_stop_mp_called) { 167 WARN(MODULE_TAG "%s: already initialized\n", __func__); 168 spin_unlock(&apusys_rv_lock); 169 return -1; 170 } 171 172 if (watch_dog_is_timeout() == false) { 173 spin_unlock(&apusys_rv_lock); 174 return -1; 175 } 176 177 apusys_rv_stop_mp_called = true; 178 179 mmio_write_32(MD32_RUNSTALL, MD32_STALL); 180 181 spin_unlock(&apusys_rv_lock); 182 183 return 0; 184 } 185 186 int apusys_kernel_apusys_rv_setup_sec_mem(void) 187 { 188 static bool apusys_rv_setup_sec_mem_called; 189 int ret; 190 191 spin_lock(&apusys_rv_lock); 192 193 if (apusys_rv_setup_sec_mem_called) { 194 WARN(MODULE_TAG "%s: already initialized\n", __func__); 195 spin_unlock(&apusys_rv_lock); 196 return -1; 197 } 198 199 apusys_rv_setup_sec_mem_called = true; 200 201 ret = set_apu_emi_mpu_region(); 202 if (ret != 0) { 203 ERROR(MODULE_TAG "%s: set emimpu protection failed\n", __func__); 204 } 205 206 spin_unlock(&apusys_rv_lock); 207 return ret; 208 } 209 210 int apusys_kernel_apusys_rv_disable_wdt_isr(void) 211 { 212 spin_lock(&apusys_rv_lock); 213 mmio_clrbits_32(WDT_CTRL0, WDT_EN); 214 spin_unlock(&apusys_rv_lock); 215 216 return 0; 217 } 218 219 int apusys_kernel_apusys_rv_clear_wdt_isr(void) 220 { 221 spin_lock(&apusys_rv_lock); 222 mmio_clrbits_32(UP_INT_EN2, DBG_APB_EN); 223 mmio_write_32(WDT_INT, WDT_INT_W1C); 224 spin_unlock(&apusys_rv_lock); 225 226 return 0; 227 } 228 229 int apusys_kernel_apusys_rv_cg_gating(void) 230 { 231 spin_lock(&apusys_rv_lock); 232 233 if (watch_dog_is_timeout() == false) { 234 spin_unlock(&apusys_rv_lock); 235 return -1; 236 } 237 238 mmio_write_32(MD32_CLK_CTRL, MD32_CLK_DIS); 239 spin_unlock(&apusys_rv_lock); 240 241 return 0; 242 } 243 244 int apusys_kernel_apusys_rv_cg_ungating(void) 245 { 246 spin_lock(&apusys_rv_lock); 247 248 if (watch_dog_is_timeout() == false) { 249 spin_unlock(&apusys_rv_lock); 250 return -1; 251 } 252 253 mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN); 254 spin_unlock(&apusys_rv_lock); 255 256 return 0; 257 } 258