xref: /rk3399_ARM-atf/plat/mediatek/drivers/spm/mt_spm_dispatcher.c (revision 52e486f6a6192bd18d36cdcbc35c59092eefc810)
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