1 /* 2 * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <errno.h> 8 9 /* TF-A system header */ 10 #include <common/debug.h> 11 #include <drivers/delay_timer.h> 12 #include <lib/mmio.h> 13 #include <lib/spinlock.h> 14 15 /* Vendor header */ 16 #include "apusys.h" 17 #include "apusys_rv.h" 18 #include "apusys_rv_mbox_mpu.h" 19 #include "apusys_rv_pwr_ctrl.h" 20 #include "apusys_rv_sec_info.h" 21 #ifdef CONFIG_MTK_APUSYS_SEC_CTRL 22 #include "apusys_security_ctrl_perm.h" 23 #endif 24 #include "apusys_security_ctrl_plat.h" 25 #include <drivers/apusys_rv_public.h> 26 #include <mtk_mmap_pool.h> 27 #include <mtk_sip_svc.h> 28 29 #ifdef CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT 30 #include "apusys_ammu.h" 31 #endif 32 33 static spinlock_t apusys_rv_lock; 34 35 void apusys_rv_mbox_mpu_init(void) 36 { 37 int i; 38 39 for (i = 0; i < APU_MBOX_NUM; i++) { 40 mmio_write_32(APU_MBOX_FUNC_CFG(i), 41 (MBOX_CTRL_LOCK | 42 (mbox_mpu_setting_tab[i].no_mpu << MBOX_NO_MPU_SHIFT))); 43 mmio_write_32(APU_MBOX_DOMAIN_CFG(i), 44 (MBOX_CTRL_LOCK | 45 (mbox_mpu_setting_tab[i].rx_ns << MBOX_RX_NS_SHIFT) | 46 (mbox_mpu_setting_tab[i].rx_domain << MBOX_RX_DOMAIN_SHIFT) | 47 (mbox_mpu_setting_tab[i].tx_ns << MBOX_TX_NS_SHIFT) | 48 (mbox_mpu_setting_tab[i].tx_domain << MBOX_TX_DOMAIN_SHIFT))); 49 } 50 } 51 52 int apusys_kernel_apusys_rv_setup_reviser(void) 53 { 54 spin_lock(&apusys_rv_lock); 55 56 mmio_write_32(USERFW_CTXT, CFG_4GB_SEL_EN | CFG_4GB_SEL); 57 mmio_write_32(SECUREFW_CTXT, CFG_4GB_SEL_EN | CFG_4GB_SEL); 58 59 mmio_write_32(UP_IOMMU_CTRL, MMU_CTRL_LOCK | MMU_CTRL | MMU_EN); 60 61 mmio_write_32(UP_NORMAL_DOMAIN_NS, 62 (UP_NORMAL_DOMAIN << UP_DOMAIN_SHIFT) | (UP_NORMAL_NS << UP_NS_SHIFT)); 63 mmio_write_32(UP_PRI_DOMAIN_NS, 64 (UP_PRI_DOMAIN << UP_DOMAIN_SHIFT) | (UP_PRI_NS << UP_NS_SHIFT)); 65 66 mmio_write_32(UP_CORE0_VABASE0, 67 VLD | PARTIAL_ENABLE | (THREAD_NUM_PRI << THREAD_NUM_SHIFT)); 68 mmio_write_32(UP_CORE0_MVABASE0, VASIZE_1MB | (APU_SEC_FW_IOVA >> MVA_34BIT_SHIFT)); 69 70 mmio_write_32(UP_CORE0_VABASE1, 71 VLD | PARTIAL_ENABLE | (THREAD_NUM_NORMAL << THREAD_NUM_SHIFT)); 72 mmio_write_32(UP_CORE0_MVABASE1, VASIZE_1MB | (APU_SEC_FW_IOVA >> MVA_34BIT_SHIFT)); 73 74 spin_unlock(&apusys_rv_lock); 75 76 return 0; 77 } 78 79 int apusys_kernel_apusys_rv_reset_mp(void) 80 { 81 spin_lock(&apusys_rv_lock); 82 83 mmio_write_32(MD32_SYS_CTRL, MD32_SYS_CTRL_RST); 84 85 dsb(); 86 udelay(RESET_DEALY_US); 87 88 mmio_write_32(MD32_SYS_CTRL, MD32_G2B_CG_EN | MD32_DBG_EN | MD32_DM_AWUSER_IOMMU_EN | 89 MD32_DM_ARUSER_IOMMU_EN | MD32_PM_AWUSER_IOMMU_EN | MD32_PM_ARUSER_IOMMU_EN | 90 MD32_SOFT_RSTN); 91 92 mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN); 93 mmio_write_32(UP_WAKE_HOST_MASK0, WDT_IRQ_EN); 94 mmio_write_32(UP_WAKE_HOST_MASK1, MBOX0_IRQ_EN | MBOX1_IRQ_EN | MBOX2_IRQ_EN); 95 96 spin_unlock(&apusys_rv_lock); 97 98 return 0; 99 } 100 101 int apusys_kernel_apusys_rv_setup_boot(void) 102 { 103 spin_lock(&apusys_rv_lock); 104 105 mmio_write_32(MD32_BOOT_CTRL, APU_SEC_FW_IOVA); 106 107 mmio_write_32(MD32_PRE_DEFINE, (PREDEFINE_CACHE_TCM << PREDEF_1G_OFS) | 108 (PREDEFINE_CACHE << PREDEF_2G_OFS) | (PREDEFINE_CACHE << PREDEF_3G_OFS) | 109 (PREDEFINE_CACHE << PREDEF_4G_OFS)); 110 111 apusys_infra_dcm_setup(); 112 113 spin_unlock(&apusys_rv_lock); 114 return 0; 115 } 116 117 int apusys_kernel_apusys_rv_start_mp(void) 118 { 119 spin_lock(&apusys_rv_lock); 120 mmio_write_32(MD32_RUNSTALL, MD32_RUN); 121 spin_unlock(&apusys_rv_lock); 122 123 return 0; 124 } 125 126 static int hw_sema2_release(uint32_t timeout) 127 { 128 #ifdef CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT 129 int ret; 130 131 ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_USER, 0, timeout, 0); 132 if (ret) { 133 ERROR("%s: HW semaphore release timeout\n", __func__); 134 } 135 136 return ret; 137 #else 138 return 0; 139 #endif 140 } 141 142 static int hw_sema2_acquire(uint32_t timeout) 143 { 144 #ifdef CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT 145 int ret; 146 147 ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_USER, 1, timeout, 0); 148 if (ret) { 149 ERROR("%s: HW semaphore acquire timeout\n", __func__); 150 } 151 152 return ret; 153 #else 154 return 0; 155 #endif 156 } 157 158 int apusys_kernel_apusys_rv_stop_mp(void) 159 { 160 int ret; 161 162 ret = hw_sema2_acquire(HW_SEM_TIMEOUT); 163 if (ret) 164 return ret; 165 166 spin_lock(&apusys_rv_lock); 167 mmio_write_32(MD32_RUNSTALL, MD32_STALL); 168 spin_unlock(&apusys_rv_lock); 169 170 ret = hw_sema2_release(HW_SEM_TIMEOUT); 171 172 return ret; 173 } 174 175 int apusys_kernel_apusys_rv_setup_sec_mem(void) 176 { 177 int ret = 0; 178 179 spin_lock(&apusys_rv_lock); 180 181 ret = apusys_plat_setup_sec_mem(); 182 if (ret != 0) 183 ERROR(MODULE_TAG "%s: set emimpu protection failed\n", __func__); 184 185 spin_unlock(&apusys_rv_lock); 186 return ret; 187 } 188 189 int apusys_kernel_apusys_rv_disable_wdt_isr(void) 190 { 191 int ret; 192 193 ret = hw_sema2_acquire(0); 194 if (ret) 195 return ret; 196 197 spin_lock(&apusys_rv_lock); 198 mmio_clrbits_32(WDT_CTRL0, WDT_EN); 199 spin_unlock(&apusys_rv_lock); 200 201 ret = hw_sema2_release(0); 202 203 return ret; 204 } 205 206 int apusys_kernel_apusys_rv_clear_wdt_isr(void) 207 { 208 int ret; 209 210 ret = hw_sema2_acquire(HW_SEM_TIMEOUT); 211 if (ret) 212 return ret; 213 214 spin_lock(&apusys_rv_lock); 215 mmio_clrbits_32(UP_INT_EN2, DBG_APB_EN); 216 mmio_write_32(WDT_INT, WDT_INT_W1C); 217 spin_unlock(&apusys_rv_lock); 218 219 ret = hw_sema2_release(HW_SEM_TIMEOUT); 220 221 return ret; 222 } 223 224 int apusys_kernel_apusys_rv_cg_gating(void) 225 { 226 int ret; 227 228 ret = hw_sema2_acquire(HW_SEM_TIMEOUT); 229 if (ret) 230 return ret; 231 232 spin_lock(&apusys_rv_lock); 233 mmio_write_32(MD32_CLK_CTRL, MD32_CLK_DIS); 234 spin_unlock(&apusys_rv_lock); 235 236 ret = hw_sema2_release(HW_SEM_TIMEOUT); 237 238 return ret; 239 } 240 241 int apusys_kernel_apusys_rv_cg_ungating(void) 242 { 243 int ret; 244 245 ret = hw_sema2_acquire(HW_SEM_TIMEOUT); 246 if (ret) 247 return ret; 248 249 spin_lock(&apusys_rv_lock); 250 mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN); 251 spin_unlock(&apusys_rv_lock); 252 253 ret = hw_sema2_release(HW_SEM_TIMEOUT); 254 255 return ret; 256 } 257 258 int apusys_kernel_apusys_rv_setup_apummu(void) 259 { 260 spin_lock(&apusys_rv_lock); 261 262 #ifdef CONFIG_MTK_APUSYS_SEC_CTRL 263 sec_set_rv_dns(); 264 #endif 265 266 #ifdef CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT 267 uint32_t apummu_tcm_sz_select = 0; 268 269 if (APU_MD32_TCM_SZ <= 0x20000) 270 apummu_tcm_sz_select = APUMMU_PAGE_LEN_128KB; 271 else if (APU_MD32_TCM_SZ <= 0x40000) 272 apummu_tcm_sz_select = APUMMU_PAGE_LEN_256KB; 273 else if (APU_MD32_TCM_SZ <= 0x80000) 274 apummu_tcm_sz_select = APUMMU_PAGE_LEN_512KB; 275 else if (APU_MD32_TCM_SZ <= 0x100000) 276 apummu_tcm_sz_select = APUMMU_PAGE_LEN_1MB; 277 else { 278 ERROR("%s: APU_MD32_TCM_SZ = 0x%x > 1MB", __func__, APU_MD32_TCM_SZ); 279 spin_unlock(&apusys_rv_lock); 280 return -EINVAL; 281 } 282 283 INFO("%s: apummu_tcm_sz_select = %u\n", __func__, apummu_tcm_sz_select); 284 rv_boot(APU_SEC_FW_IOVA, 0, APUMMU_PAGE_LEN_1MB, 285 APU_MD32_TCM, apummu_tcm_sz_select); 286 #endif 287 288 spin_unlock(&apusys_rv_lock); 289 return 0; 290 } 291 292 int apusys_kernel_apusys_rv_pwr_ctrl(enum APU_PWR_OP op) 293 { 294 return apusys_rv_pwr_ctrl(op); 295 } 296 297 #ifdef CONFIG_MTK_APUSYS_LOGTOP_SUPPORT 298 int apusys_kernel_apusys_logtop_reg_dump(uint32_t op, struct smccc_res *smccc_ret) 299 { 300 int ret = 0; 301 uint8_t smc_op; 302 uint32_t reg_addr[MAX_SMC_OP_NUM]; 303 uint32_t i; 304 305 if (op == 0) { 306 ERROR("%s empty op = 0x%08x\n", MODULE_TAG, op); 307 return -EINVAL; 308 } 309 310 for (i = 0; i < MAX_SMC_OP_NUM; i++) { 311 smc_op = (op >> (LOGTOP_OP_SHIFT * i)) & LOGTOP_OP_MASK; 312 switch (smc_op) { 313 case SMC_OP_APU_LOG_BUF_NULL: 314 reg_addr[i] = 0x0; 315 break; 316 case SMC_OP_APU_LOG_BUF_T_SIZE: 317 reg_addr[i] = APU_LOG_BUF_T_SIZE; 318 break; 319 case SMC_OP_APU_LOG_BUF_W_PTR: 320 reg_addr[i] = APU_LOG_BUF_W_PTR; 321 break; 322 case SMC_OP_APU_LOG_BUF_R_PTR: 323 reg_addr[i] = APU_LOG_BUF_R_PTR; 324 break; 325 case SMC_OP_APU_LOG_BUF_CON: 326 reg_addr[i] = APU_LOGTOP_CON; 327 break; 328 default: 329 ERROR("%s unknown op = 0x%08x\n", MODULE_TAG, smc_op); 330 return -EINVAL; 331 } 332 } 333 334 ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 1, 0, 0); 335 if (ret) 336 return ret; 337 338 for (i = 0; i < MAX_SMC_OP_NUM; i++) { 339 if (reg_addr[i] == 0) 340 continue; 341 342 switch (i) { 343 case 0: 344 smccc_ret->a1 = mmio_read_32(reg_addr[i]); 345 break; 346 case 1: 347 smccc_ret->a2 = mmio_read_32(reg_addr[i]); 348 break; 349 case 2: 350 smccc_ret->a3 = mmio_read_32(reg_addr[i]); 351 break; 352 } 353 } 354 355 ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 0, 0, 0); 356 if (ret) 357 ERROR("%s(%d): sem release timeout\n", __func__, op); 358 359 return ret; 360 } 361 362 static int apusys_kernel_apusys_logtop_reg_rw(uint32_t op, uint32_t write_val, 363 bool w1c, struct smccc_res *smccc_ret) 364 { 365 int ret = 0; 366 uint32_t reg_addr = 0, reg_val = 0; 367 368 switch (op) { 369 case SMC_OP_APU_LOG_BUF_R_PTR: 370 reg_addr = APU_LOG_BUF_R_PTR; 371 break; 372 case SMC_OP_APU_LOG_BUF_CON: 373 reg_addr = APU_LOGTOP_CON; 374 break; 375 default: 376 ERROR("%s unknown or not support op = %x\n", MODULE_TAG, op); 377 return -EINVAL; 378 } 379 380 ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 1, 0, 0); 381 if (ret) 382 return ret; 383 384 if (w1c) { 385 reg_val = mmio_read_32(reg_addr); 386 mmio_write_32(reg_addr, reg_val); 387 smccc_ret->a1 = reg_val; 388 } else { 389 mmio_write_32(reg_addr, write_val); 390 } 391 392 ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 0, 0, 0); 393 if (ret) 394 ERROR("%s(%d): sem release timeout\n", __func__, op); 395 396 return ret; 397 } 398 399 int apusys_kernel_apusys_logtop_reg_write(uint32_t op, uint32_t write_val, 400 struct smccc_res *smccc_ret) 401 { 402 return apusys_kernel_apusys_logtop_reg_rw(op, write_val, false, smccc_ret); 403 } 404 405 int apusys_kernel_apusys_logtop_reg_w1c(uint32_t op, struct smccc_res *smccc_ret) 406 { 407 return apusys_kernel_apusys_logtop_reg_rw(op, 0, true, smccc_ret); 408 } 409 410 #endif /* CONFIG_MTK_APUSYS_LOGTOP_SUPPORT */ 411 412 int apusys_rv_cold_boot_clr_mbox_dummy(void) 413 { 414 #ifdef SUPPORT_APU_CLEAR_MBOX_DUMMY 415 mmio_write_32(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_DUMMY, 0); 416 #else 417 WARN("Not support clear mbox dummy on this platform\n"); 418 #endif 419 return 0; 420 } 421 422 #ifdef CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT 423 int apusys_rv_iommu_hw_sem_trylock(void) 424 { 425 return rv_iommu_hw_sem_trylock(); 426 } 427 428 int apusys_rv_iommu_hw_sem_unlock(void) 429 { 430 return rv_iommu_hw_sem_unlock(); 431 } 432 #endif /* CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT */ 433 434 int apusys_rv_setup_ce_bin(void) 435 { 436 #ifdef CONFIG_MTK_APUSYS_CE_SUPPORT 437 uintptr_t apusys_rv_sec_buf_pa; 438 struct apusys_secure_info_t *apusys_secure_info; 439 struct ce_main_hdr_t *ce_main_hdr; 440 struct ce_sub_hdr_t *ce_sub_hdr; 441 unsigned int cnt, i, reg_val; 442 uint64_t ce_sub_hdr_bin; 443 int ret; 444 445 apusys_rv_sec_buf_pa = APU_RESERVE_MEMORY; 446 /* create mapping */ 447 ret = mmap_add_dynamic_region(apusys_rv_sec_buf_pa, apusys_rv_sec_buf_pa, 448 round_up(APU_RESERVE_SIZE, PAGE_SIZE), 449 MT_MEMORY | MT_RW | MT_NS); 450 if (ret) { 451 ERROR("%s: mmap_add_dynamic_region() fail, ret=0x%x\n", __func__, ret); 452 return ret; 453 } 454 455 apusys_secure_info = (struct apusys_secure_info_t *) 456 (apusys_rv_sec_buf_pa + APU_SEC_INFO_OFFSET); 457 458 ce_main_hdr = (struct ce_main_hdr_t *)(apusys_rv_sec_buf_pa + 459 apusys_secure_info->ce_bin_ofs); 460 ce_sub_hdr = (struct ce_sub_hdr_t *)((uintptr_t)ce_main_hdr + ce_main_hdr->hdr_size); 461 462 if (ce_main_hdr->magic != CE_MAIN_MAGIC) { 463 ERROR("%s: invalid header\n", __func__); 464 return -EINVAL; 465 } 466 467 cnt = 0; 468 469 while (ce_sub_hdr->magic == CE_SUB_MAGIC && cnt < ce_main_hdr->bin_count) { 470 VERBOSE("%s: job (%d), magic (0x%x)\n", __func__, 471 ce_sub_hdr->ce_enum, ce_sub_hdr->magic); 472 473 ce_sub_hdr_bin = (uint64_t)ce_sub_hdr + ce_sub_hdr->bin_offset; 474 475 for (i = 0; i < ce_sub_hdr->bin_size; i += sizeof(uint32_t)) { 476 reg_val = *(uint32_t *)(ce_sub_hdr_bin + i); 477 mmio_write_32(ce_sub_hdr->mem_st + i, reg_val); 478 } 479 480 if (ce_sub_hdr->hw_entry) { 481 mmio_clrsetbits_32(ce_sub_hdr->hw_entry, 482 ce_sub_hdr->hw_entry_mask << ce_sub_hdr->hw_entry_bit, 483 (ce_sub_hdr->hw_entry_val & ce_sub_hdr->hw_entry_mask) 484 << ce_sub_hdr->hw_entry_bit); 485 } 486 487 ce_sub_hdr = (struct ce_sub_hdr_t *)(ce_sub_hdr_bin + ce_sub_hdr->bin_size); 488 cnt++; 489 } 490 491 mmap_remove_dynamic_region(apusys_rv_sec_buf_pa, 492 round_up(APU_RESERVE_SIZE, PAGE_SIZE)); 493 494 INFO("%s: setup CE binary done\n", __func__); 495 #else 496 WARN("Not support CE on this platform\n"); 497 #endif 498 return 0; 499 } 500