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