xref: /rk3399_ARM-atf/plat/mediatek/drivers/ufs/ufs_ctrl.c (revision 8cef63d6c7184fe1eebc354716e4b3910d385f9b)
1 /*
2  * Copyright (c) 2025, MediaTek Inc. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <common/debug.h>
8 
9 /* MTK header */
10 #include <drivers/pmic/pmic_swap_api.h>
11 #include <lpm_v2/mt_lp_api.h>
12 #include <lpm_v2/mt_lp_rq.h>
13 #include <mtk_bl31_interface.h>
14 #include <mtk_sip_svc.h>
15 
16 /* UFS generic control flags */
17 #define UFS_MTK_SIP_VA09_PWR_CTRL		BIT(0)
18 #define UFS_MTK_SIP_DEVICE_RESET		BIT(1)
19 #define UFS_MTK_SIP_CRYPTO_CTRL			BIT(2)
20 #define UFS_MTK_SIP_REF_CLK_NOTIFICATION	BIT(3)
21 #define UFS_MTK_SIP_SRAM_PWR_CTRL		BIT(5)
22 #define UFS_MTK_SIP_GET_VCC_INFO		BIT(6)
23 #define UFS_MTK_SIP_DEVICE_PWR_CTRL		BIT(7)
24 #define UFS_MTK_SIP_MPHY_CTRL			BIT(8)
25 #define UFS_MTK_SIP_MTCMOS_CTRL			BIT(9)
26 
27 enum {
28 	VCC_NONE = 0,
29 	VCC_1,
30 	VCC_2,
31 };
32 
33 static void ufs_get_vcc_info(struct smccc_res *smccc_ret)
34 {
35 	if (smccc_ret == NULL)
36 		return;
37 
38 	if (is_second_pmic_pp_swap())
39 		smccc_ret->a1 = VCC_2;
40 	else
41 		smccc_ret->a1 = VCC_1;
42 }
43 
44 /* SPM resource control */
45 #define RSC_MEM			(MT_LP_RQ_DRAM | MT_LP_RQ_EMI)
46 #define RSC_PMIC		MT_LP_RQ_PMIC
47 
48 static int ufs_rsc_ctrl(unsigned int rsc, bool hold)
49 {
50 	static struct mt_lp_resource_user ufs_res_user;
51 	int ret = -1;
52 
53 	if (!ufs_res_user.uid) {
54 		ret = mt_lp_resource_user_register("UFS", &ufs_res_user);
55 
56 		if (ret) {
57 			WARN("%s: register lp resource failed\n", __func__);
58 			return ret;
59 		}
60 	}
61 
62 	if (hold)
63 		ret = ufs_res_user.request(&ufs_res_user, rsc);
64 	else
65 		ret = ufs_res_user.release(&ufs_res_user);
66 
67 	VERBOSE("%s: rsc=%d, hold=%d\n", __func__, rsc, hold);
68 
69 	if (ret)
70 		WARN("%s: RSC_%d %s failed\n", __func__, rsc, hold ? "request" : "release");
71 
72 	return ret;
73 }
74 
75 int ufs_rsc_ctrl_mem(bool hold)
76 {
77 	return ufs_rsc_ctrl(RSC_MEM, hold);
78 }
79 
80 int ufs_rcs_ctrl_pmic(bool hold)
81 {
82 	return ufs_rsc_ctrl(RSC_PMIC, hold);
83 }
84 
85 /* UFS clock status */
86 static uint32_t ufs_clk_sta = UFS_REF_CLK_ON;
87 
88 bool ufs_is_clk_status_off(void)
89 {
90 	return ufs_clk_sta == UFS_REF_CLK_OFF;
91 }
92 
93 void ufs_set_clk_status(bool on)
94 {
95 	if (on)
96 		ufs_clk_sta = UFS_REF_CLK_ON;
97 	else
98 		ufs_clk_sta = UFS_REF_CLK_OFF;
99 }
100 
101 static u_register_t ufs_knl_ctrl(u_register_t x1,
102 				 u_register_t x2,
103 				 u_register_t x3,
104 				 u_register_t x4,
105 				 void *handle,
106 				 struct smccc_res *smccc_ret)
107 {
108 	uint64_t ret = 0;
109 
110 	switch (x1) {
111 	case UFS_MTK_SIP_VA09_PWR_CTRL:
112 		ufs_mphy_va09_cg_ctrl(!!x2);
113 		break;
114 	case UFS_MTK_SIP_DEVICE_RESET:
115 		ufs_device_reset_ctrl(!!x2);
116 		break;
117 	case UFS_MTK_SIP_CRYPTO_CTRL:
118 		ufs_crypto_hie_init();
119 		break;
120 	case UFS_MTK_SIP_REF_CLK_NOTIFICATION:
121 		ufs_ref_clk_status(x2, x3);
122 		break;
123 	case UFS_MTK_SIP_SRAM_PWR_CTRL:
124 		ufs_sram_pwr_ctrl(x2);
125 		break;
126 	case UFS_MTK_SIP_GET_VCC_INFO:
127 		ufs_get_vcc_info(smccc_ret);
128 		break;
129 	case UFS_MTK_SIP_DEVICE_PWR_CTRL:
130 		ufs_device_pwr_ctrl(x2, x3);
131 		break;
132 	case UFS_MTK_SIP_MPHY_CTRL:
133 		ufs_mphy_ctrl(x2);
134 		break;
135 	case UFS_MTK_SIP_MTCMOS_CTRL:
136 #if defined(CONFIG_MTK_MTCMOS)
137 		ufs_mtcmos_ctrl(!!x2);
138 #endif
139 		break;
140 	default:
141 		ret = -1;
142 		WARN("[UFS] invalid argument 0x%lx from kernel\n", x1);
143 		break;
144 	}
145 
146 	return ret;
147 }
148 
149 static u_register_t ufs_bl_ctrl(u_register_t x1,
150 				u_register_t x2,
151 				u_register_t x3,
152 				u_register_t x4,
153 				void *handle,
154 				struct smccc_res *smccc_ret)
155 {
156 	uint64_t ret = 0;
157 
158 	switch (x1) {
159 	case UFS_MTK_SIP_DEVICE_RESET:
160 		ufs_device_reset_ctrl(x2);
161 		break;
162 	default:
163 		ret = -1;
164 		WARN("[UFS] invalid argument 0x%lx from bootloader\n", x1);
165 		break;
166 	}
167 
168 	return ret;
169 }
170 
171 DECLARE_SMC_HANDLER(MTK_SIP_KERNEL_UFS_CONTROL, ufs_knl_ctrl);
172 DECLARE_SMC_HANDLER(MTK_SIP_BL_UFS_CONTROL, ufs_bl_ctrl);
173