xref: /rk3399_ARM-atf/plat/mediatek/common/lpm_v2/mt_lpm_dispatch.c (revision cf2df874cd09305ac7282fadb0fef6be597dfffb)
1*da8cc41bSWenzhen Yu /*
2*da8cc41bSWenzhen Yu  * Copyright (c) 2025, MediaTek Inc. All rights reserved.
3*da8cc41bSWenzhen Yu  *
4*da8cc41bSWenzhen Yu  * SPDX-License-Identifier: BSD-3-Clause
5*da8cc41bSWenzhen Yu  */
6*da8cc41bSWenzhen Yu 
7*da8cc41bSWenzhen Yu #include <cdefs.h>
8*da8cc41bSWenzhen Yu 
9*da8cc41bSWenzhen Yu #include <lpm_v2/mt_lpm_dispatch.h>
10*da8cc41bSWenzhen Yu 
11*da8cc41bSWenzhen Yu /*
12*da8cc41bSWenzhen Yu  * Notice, this data don't link to bss section.
13*da8cc41bSWenzhen Yu  * It means data structure won't be set as zero.
14*da8cc41bSWenzhen Yu  * Please make sure the member will be initialized.
15*da8cc41bSWenzhen Yu  */
16*da8cc41bSWenzhen Yu struct mt_dispatch_ctrl mt_dispatcher
17*da8cc41bSWenzhen Yu __section("mt_lpm_s") = {
18*da8cc41bSWenzhen Yu 	.enable = 0,
19*da8cc41bSWenzhen Yu };
20*da8cc41bSWenzhen Yu 
21*da8cc41bSWenzhen Yu struct mt_dispatch_ctrl mt_secure_dispatcher
22*da8cc41bSWenzhen Yu __section("mt_secure_lpm_s") = {
23*da8cc41bSWenzhen Yu 	.enable = 0,
24*da8cc41bSWenzhen Yu };
25*da8cc41bSWenzhen Yu 
invoke_mt_lpm_dispatch(u_register_t x1,u_register_t x2,u_register_t x3,u_register_t x4,void * handle,struct smccc_res * smccc_ret)26*da8cc41bSWenzhen Yu u_register_t invoke_mt_lpm_dispatch(u_register_t x1, u_register_t x2,
27*da8cc41bSWenzhen Yu 				    u_register_t x3, u_register_t x4,
28*da8cc41bSWenzhen Yu 				    void *handle, struct smccc_res *smccc_ret)
29*da8cc41bSWenzhen Yu {
30*da8cc41bSWenzhen Yu 	uint64_t res = 0;
31*da8cc41bSWenzhen Yu 	uint32_t user;
32*da8cc41bSWenzhen Yu 
33*da8cc41bSWenzhen Yu 	if (!IS_MT_LPM_SMC(x1))
34*da8cc41bSWenzhen Yu 		return res;
35*da8cc41bSWenzhen Yu 
36*da8cc41bSWenzhen Yu 	user = MT_LPM_SMC_USER(x1);
37*da8cc41bSWenzhen Yu 	if ((user < MT_LPM_SMC_USER_MAX) &&
38*da8cc41bSWenzhen Yu 		(mt_dispatcher.enable & (1 << user))) {
39*da8cc41bSWenzhen Yu 		res = mt_dispatcher.fn[user](MT_LPM_SMC_USER_ID(x1),
40*da8cc41bSWenzhen Yu 					     x2, x3, x4,
41*da8cc41bSWenzhen Yu 					     handle, smccc_ret);
42*da8cc41bSWenzhen Yu 	}
43*da8cc41bSWenzhen Yu 
44*da8cc41bSWenzhen Yu 	return res;
45*da8cc41bSWenzhen Yu }
46*da8cc41bSWenzhen Yu DECLARE_SMC_HANDLER(MTK_SIP_MTK_LPM_CONTROL, invoke_mt_lpm_dispatch);
47*da8cc41bSWenzhen Yu 
invoke_mt_secure_lpm_dispatch(u_register_t x1,u_register_t x2,u_register_t x3,u_register_t x4,void * handle,struct smccc_res * smccc_ret)48*da8cc41bSWenzhen Yu u_register_t invoke_mt_secure_lpm_dispatch(u_register_t x1, u_register_t x2,
49*da8cc41bSWenzhen Yu 					   u_register_t x3, u_register_t x4,
50*da8cc41bSWenzhen Yu 					   void *handle,
51*da8cc41bSWenzhen Yu 					   struct smccc_res *smccc_ret)
52*da8cc41bSWenzhen Yu {
53*da8cc41bSWenzhen Yu 	uint64_t res = 0;
54*da8cc41bSWenzhen Yu 	unsigned int user;
55*da8cc41bSWenzhen Yu 
56*da8cc41bSWenzhen Yu 	if (!IS_MT_LPM_SMC(x1))
57*da8cc41bSWenzhen Yu 		return res;
58*da8cc41bSWenzhen Yu 
59*da8cc41bSWenzhen Yu 	user = MT_LPM_SMC_USER(x1);
60*da8cc41bSWenzhen Yu 	if (mt_secure_dispatcher.enable & (1 << user)) {
61*da8cc41bSWenzhen Yu 		res = mt_secure_dispatcher.fn[user](MT_LPM_SMC_USER_ID(x1), x2,
62*da8cc41bSWenzhen Yu 						    x3, x4, handle, smccc_ret);
63*da8cc41bSWenzhen Yu 	}
64*da8cc41bSWenzhen Yu 
65*da8cc41bSWenzhen Yu 	return res;
66*da8cc41bSWenzhen Yu }
67*da8cc41bSWenzhen Yu DECLARE_SMC_HANDLER(MTK_SIP_BL_LPM_CONTROL, invoke_mt_secure_lpm_dispatch);
68*da8cc41bSWenzhen Yu 
69*da8cc41bSWenzhen Yu /* Check lpm smc user number at compile time */
70*da8cc41bSWenzhen Yu CASSERT(MT_LPM_SMC_USER_MAX <= MTK_DISPATCH_ID_MAX,
71*da8cc41bSWenzhen Yu 	lpm_smc_user_declare_too_large);
72*da8cc41bSWenzhen Yu 
mt_lpm_dispatcher_registry(unsigned int id,mt_lpm_dispatch_fn fn)73*da8cc41bSWenzhen Yu void mt_lpm_dispatcher_registry(unsigned int id, mt_lpm_dispatch_fn fn)
74*da8cc41bSWenzhen Yu {
75*da8cc41bSWenzhen Yu 	if (id >= MT_LPM_SMC_USER_MAX)
76*da8cc41bSWenzhen Yu 		return;
77*da8cc41bSWenzhen Yu 
78*da8cc41bSWenzhen Yu 	mt_dispatcher.enable |= BIT(id);
79*da8cc41bSWenzhen Yu 	mt_dispatcher.fn[id] = fn;
80*da8cc41bSWenzhen Yu }
81*da8cc41bSWenzhen Yu 
mt_secure_lpm_dispatcher_registry(unsigned int id,mt_lpm_dispatch_fn fn)82*da8cc41bSWenzhen Yu void mt_secure_lpm_dispatcher_registry(unsigned int id, mt_lpm_dispatch_fn fn)
83*da8cc41bSWenzhen Yu {
84*da8cc41bSWenzhen Yu 	if (id >= MT_LPM_SMC_USER_MAX)
85*da8cc41bSWenzhen Yu 		return;
86*da8cc41bSWenzhen Yu 
87*da8cc41bSWenzhen Yu 	mt_secure_dispatcher.enable |= BIT(id);
88*da8cc41bSWenzhen Yu 	mt_secure_dispatcher.fn[id] = fn;
89*da8cc41bSWenzhen Yu }
90