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 dsb(); 92 udelay(RESET_DEALY_US); 93 94 mmio_write_32(MD32_SYS_CTRL, MD32_G2B_CG_EN | MD32_DBG_EN | MD32_DM_AWUSER_IOMMU_EN | 95 MD32_DM_ARUSER_IOMMU_EN | MD32_PM_AWUSER_IOMMU_EN | MD32_PM_ARUSER_IOMMU_EN | 96 MD32_SOFT_RSTN); 97 98 mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN); 99 mmio_write_32(UP_WAKE_HOST_MASK0, WDT_IRQ_EN); 100 mmio_write_32(UP_WAKE_HOST_MASK1, MBOX0_IRQ_EN | MBOX1_IRQ_EN | MBOX2_IRQ_EN); 101 102 spin_unlock(&apusys_rv_lock); 103 104 return 0; 105 } 106 107 int apusys_kernel_apusys_rv_setup_boot(void) 108 { 109 static bool apusys_rv_setup_boot_called; 110 111 spin_lock(&apusys_rv_lock); 112 113 if (apusys_rv_setup_boot_called) { 114 WARN(MODULE_TAG "%s: already initialized\n", __func__); 115 spin_unlock(&apusys_rv_lock); 116 return -1; 117 } 118 119 apusys_rv_setup_boot_called = true; 120 121 mmio_write_32(MD32_BOOT_CTRL, APU_SEC_FW_IOVA); 122 123 mmio_write_32(MD32_PRE_DEFINE, (PREDEFINE_CACHE_TCM << PREDEF_1G_OFS) | 124 (PREDEFINE_CACHE << PREDEF_2G_OFS) | (PREDEFINE_CACHE << PREDEF_3G_OFS) | 125 (PREDEFINE_CACHE << PREDEF_4G_OFS)); 126 127 spin_unlock(&apusys_rv_lock); 128 return 0; 129 } 130 131 int apusys_kernel_apusys_rv_start_mp(void) 132 { 133 static bool apusys_rv_start_mp_called; 134 135 spin_lock(&apusys_rv_lock); 136 137 if (apusys_rv_start_mp_called) { 138 WARN(MODULE_TAG "%s: already initialized\n", __func__); 139 spin_unlock(&apusys_rv_lock); 140 return -1; 141 } 142 143 apusys_rv_start_mp_called = true; 144 145 mmio_write_32(MD32_RUNSTALL, MD32_RUN); 146 147 spin_unlock(&apusys_rv_lock); 148 149 return 0; 150 } 151 152 static bool watch_dog_is_timeout(void) 153 { 154 if (mmio_read_32(WDT_INT) != WDT_INT_W1C) { 155 ERROR(MODULE_TAG "%s: WDT does not timeout\n", __func__); 156 return false; 157 } 158 return true; 159 } 160 161 int apusys_kernel_apusys_rv_stop_mp(void) 162 { 163 static bool apusys_rv_stop_mp_called; 164 165 spin_lock(&apusys_rv_lock); 166 167 if (apusys_rv_stop_mp_called) { 168 WARN(MODULE_TAG "%s: already initialized\n", __func__); 169 spin_unlock(&apusys_rv_lock); 170 return -1; 171 } 172 173 if (watch_dog_is_timeout() == false) { 174 spin_unlock(&apusys_rv_lock); 175 return -1; 176 } 177 178 apusys_rv_stop_mp_called = true; 179 180 mmio_write_32(MD32_RUNSTALL, MD32_STALL); 181 182 spin_unlock(&apusys_rv_lock); 183 184 return 0; 185 } 186 187 int apusys_kernel_apusys_rv_setup_sec_mem(void) 188 { 189 static bool apusys_rv_setup_sec_mem_called; 190 int ret; 191 192 spin_lock(&apusys_rv_lock); 193 194 if (apusys_rv_setup_sec_mem_called) { 195 WARN(MODULE_TAG "%s: already initialized\n", __func__); 196 spin_unlock(&apusys_rv_lock); 197 return -1; 198 } 199 200 apusys_rv_setup_sec_mem_called = true; 201 202 ret = set_apu_emi_mpu_region(); 203 if (ret != 0) { 204 ERROR(MODULE_TAG "%s: set emimpu protection failed\n", __func__); 205 } 206 207 spin_unlock(&apusys_rv_lock); 208 return ret; 209 } 210 211 int apusys_kernel_apusys_rv_disable_wdt_isr(void) 212 { 213 spin_lock(&apusys_rv_lock); 214 mmio_clrbits_32(WDT_CTRL0, WDT_EN); 215 spin_unlock(&apusys_rv_lock); 216 217 return 0; 218 } 219 220 int apusys_kernel_apusys_rv_clear_wdt_isr(void) 221 { 222 spin_lock(&apusys_rv_lock); 223 mmio_clrbits_32(UP_INT_EN2, DBG_APB_EN); 224 mmio_write_32(WDT_INT, WDT_INT_W1C); 225 spin_unlock(&apusys_rv_lock); 226 227 return 0; 228 } 229 230 int apusys_kernel_apusys_rv_cg_gating(void) 231 { 232 spin_lock(&apusys_rv_lock); 233 234 if (watch_dog_is_timeout() == false) { 235 spin_unlock(&apusys_rv_lock); 236 return -1; 237 } 238 239 mmio_write_32(MD32_CLK_CTRL, MD32_CLK_DIS); 240 spin_unlock(&apusys_rv_lock); 241 242 return 0; 243 } 244 245 int apusys_kernel_apusys_rv_cg_ungating(void) 246 { 247 spin_lock(&apusys_rv_lock); 248 249 if (watch_dog_is_timeout() == false) { 250 spin_unlock(&apusys_rv_lock); 251 return -1; 252 } 253 254 mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN); 255 spin_unlock(&apusys_rv_lock); 256 257 return 0; 258 } 259