1 /* 2 * Copyright (c) 2025, Mediatek Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <lib/mmio.h> 8 #include <platform_def.h> 9 10 #include <lpm_v2/mt_lpm_dispatch.h> 11 #include <lpm_v2/mt_lpm_smc.h> 12 #include <mt_spm_conservation.h> 13 #include <mt_spm_dispatcher.h> 14 #include <mt_spm_internal.h> 15 #include <mt_spm_reg.h> 16 #include <mt_spm_smc.h> 17 #include <mt_spm_suspend.h> 18 #include <pcm_def.h> 19 20 #define SPM_FW_BASE_SIZE 0x100000 21 22 static void mt_spm_pcm_wdt(int enable, uint64_t time) 23 { 24 mmio_write_32(PCM_TIMER_VAL, time); 25 __spm_set_pcm_wdt(enable); 26 } 27 28 static uint32_t mt_spm_phypll_mode_check(void) 29 { 30 uint32_t val = mmio_read_32(SPM_POWER_ON_VAL0); 31 32 return val; 33 } 34 35 static uint64_t mt_spm_compatible_smc_id(uint64_t lp_id) 36 { 37 switch (lp_id) { 38 case MT_LPM_SPMC_COMPAT_LK_FW_INIT: 39 lp_id = MT_SPM_SMC_UID_FW_INIT; 40 break; 41 default: 42 break; 43 } 44 return lp_id; 45 } 46 47 uint64_t mt_spm_dispatcher(u_register_t lp_id, u_register_t act, 48 u_register_t arg1, u_register_t arg2, 49 void *handle, struct smccc_res *smccc_ret) 50 { 51 uint64_t ret = 0; 52 53 if (act & MT_LPM_SMC_ACT_COMPAT) { 54 lp_id = mt_spm_compatible_smc_id(lp_id); 55 act &= ~(MT_LPM_SMC_ACT_COMPAT); 56 } 57 58 switch (lp_id) { 59 case MT_SPM_SMC_UID_STATUS: 60 if (!(arg2 & MT_SPM_STATUS_SUSPEND_SLEEP)) 61 break; 62 if (act & MT_LPM_SMC_ACT_SET) 63 /* Legacy audio check from kernel */ 64 mt_spm_suspend_mode_set(MT_SPM_SUSPEND_SLEEP, NULL); 65 else if (act & MT_LPM_SMC_ACT_CLR) 66 mt_spm_suspend_mode_set(MT_SPM_SUSPEND_SYSTEM_PDN, 67 NULL); 68 break; 69 case MT_SPM_SMC_UID_PCM_WDT: 70 if (act & MT_LPM_SMC_ACT_SET) 71 mt_spm_pcm_wdt(1, arg2); 72 else if (act & MT_LPM_SMC_ACT_CLR) 73 mt_spm_pcm_wdt(0, arg2); 74 break; 75 case MT_SPM_SMC_UID_PHYPLL_MODE: 76 if (act & MT_LPM_SMC_ACT_GET) 77 ret = mt_spm_phypll_mode_check(); 78 break; 79 case MT_SPM_SMC_UID_SET_PENDING_IRQ_INIT: 80 spm_set_irq_num((uint32_t)arg1); 81 break; 82 default: 83 break; 84 } 85 return ret; 86 } 87 88 int mt_spm_dispatcher_init(void) 89 { 90 mt_lpm_dispatcher_registry(MT_LPM_SMC_USER_SPM, 91 mt_spm_dispatcher); 92 return 0; 93 } 94