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