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
mt_spm_pcm_wdt(int enable,uint64_t time)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
mt_spm_phypll_mode_check(void)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
mt_spm_compatible_smc_id(uint64_t lp_id)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
mt_spm_dispatcher(u_register_t lp_id,u_register_t act,u_register_t arg1,u_register_t arg2,void * handle,struct smccc_res * smccc_ret)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
mt_spm_dispatcher_init(void)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