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_rsc_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