1*57c73515SYidi Lin /* 2*57c73515SYidi Lin * Copyright (c) 2025, MediaTek Inc. All rights reserved. 3*57c73515SYidi Lin * 4*57c73515SYidi Lin * SPDX-License-Identifier: BSD-3-Clause 5*57c73515SYidi Lin */ 6*57c73515SYidi Lin 7*57c73515SYidi Lin #include <common/debug.h> 8*57c73515SYidi Lin 9*57c73515SYidi Lin /* MTK header */ 10*57c73515SYidi Lin #include <drivers/pmic/pmic_swap_api.h> 11*57c73515SYidi Lin #include <mtk_bl31_interface.h> 12*57c73515SYidi Lin #include <mtk_sip_svc.h> 13*57c73515SYidi Lin 14*57c73515SYidi Lin /* UFS generic control flags */ 15*57c73515SYidi Lin #define UFS_MTK_SIP_VA09_PWR_CTRL BIT(0) 16*57c73515SYidi Lin #define UFS_MTK_SIP_DEVICE_RESET BIT(1) 17*57c73515SYidi Lin #define UFS_MTK_SIP_CRYPTO_CTRL BIT(2) 18*57c73515SYidi Lin #define UFS_MTK_SIP_REF_CLK_NOTIFICATION BIT(3) 19*57c73515SYidi Lin #define UFS_MTK_SIP_SRAM_PWR_CTRL BIT(5) 20*57c73515SYidi Lin #define UFS_MTK_SIP_GET_VCC_INFO BIT(6) 21*57c73515SYidi Lin #define UFS_MTK_SIP_DEVICE_PWR_CTRL BIT(7) 22*57c73515SYidi Lin #define UFS_MTK_SIP_MPHY_CTRL BIT(8) 23*57c73515SYidi Lin #define UFS_MTK_SIP_MTCMOS_CTRL BIT(9) 24*57c73515SYidi Lin 25*57c73515SYidi Lin enum { 26*57c73515SYidi Lin VCC_NONE = 0, 27*57c73515SYidi Lin VCC_1, 28*57c73515SYidi Lin VCC_2, 29*57c73515SYidi Lin }; 30*57c73515SYidi Lin 31*57c73515SYidi Lin static void ufs_get_vcc_info(struct smccc_res *smccc_ret) 32*57c73515SYidi Lin { 33*57c73515SYidi Lin if (smccc_ret == NULL) 34*57c73515SYidi Lin return; 35*57c73515SYidi Lin 36*57c73515SYidi Lin if (is_second_pmic_pp_swap()) 37*57c73515SYidi Lin smccc_ret->a1 = VCC_2; 38*57c73515SYidi Lin else 39*57c73515SYidi Lin smccc_ret->a1 = VCC_1; 40*57c73515SYidi Lin } 41*57c73515SYidi Lin 42*57c73515SYidi Lin static u_register_t ufs_knl_ctrl(u_register_t x1, 43*57c73515SYidi Lin u_register_t x2, 44*57c73515SYidi Lin u_register_t x3, 45*57c73515SYidi Lin u_register_t x4, 46*57c73515SYidi Lin void *handle, 47*57c73515SYidi Lin struct smccc_res *smccc_ret) 48*57c73515SYidi Lin { 49*57c73515SYidi Lin uint64_t ret = 0; 50*57c73515SYidi Lin 51*57c73515SYidi Lin switch (x1) { 52*57c73515SYidi Lin case UFS_MTK_SIP_VA09_PWR_CTRL: 53*57c73515SYidi Lin ufs_mphy_va09_cg_ctrl((bool)!!x2); 54*57c73515SYidi Lin break; 55*57c73515SYidi Lin case UFS_MTK_SIP_DEVICE_RESET: 56*57c73515SYidi Lin ufs_device_reset_ctrl((bool)!!x2); 57*57c73515SYidi Lin break; 58*57c73515SYidi Lin case UFS_MTK_SIP_CRYPTO_CTRL: 59*57c73515SYidi Lin ufs_crypto_hie_init(); 60*57c73515SYidi Lin break; 61*57c73515SYidi Lin case UFS_MTK_SIP_REF_CLK_NOTIFICATION: 62*57c73515SYidi Lin ufs_ref_clk_status(x2, x3); 63*57c73515SYidi Lin break; 64*57c73515SYidi Lin case UFS_MTK_SIP_SRAM_PWR_CTRL: 65*57c73515SYidi Lin ufs_sram_pwr_ctrl(x2); 66*57c73515SYidi Lin break; 67*57c73515SYidi Lin case UFS_MTK_SIP_GET_VCC_INFO: 68*57c73515SYidi Lin ufs_get_vcc_info(smccc_ret); 69*57c73515SYidi Lin break; 70*57c73515SYidi Lin case UFS_MTK_SIP_DEVICE_PWR_CTRL: 71*57c73515SYidi Lin ufs_device_pwr_ctrl(x2, x3); 72*57c73515SYidi Lin break; 73*57c73515SYidi Lin case UFS_MTK_SIP_MPHY_CTRL: 74*57c73515SYidi Lin ufs_mphy_ctrl(x2); 75*57c73515SYidi Lin break; 76*57c73515SYidi Lin case UFS_MTK_SIP_MTCMOS_CTRL: 77*57c73515SYidi Lin ufs_mtcmos_ctrl(x2); 78*57c73515SYidi Lin break; 79*57c73515SYidi Lin default: 80*57c73515SYidi Lin ret = -1; 81*57c73515SYidi Lin WARN("[UFS] invalid argument 0x%lx from kernel\n", x1); 82*57c73515SYidi Lin break; 83*57c73515SYidi Lin } 84*57c73515SYidi Lin 85*57c73515SYidi Lin return ret; 86*57c73515SYidi Lin } 87*57c73515SYidi Lin 88*57c73515SYidi Lin static u_register_t ufs_bl_ctrl(u_register_t x1, 89*57c73515SYidi Lin u_register_t x2, 90*57c73515SYidi Lin u_register_t x3, 91*57c73515SYidi Lin u_register_t x4, 92*57c73515SYidi Lin void *handle, 93*57c73515SYidi Lin struct smccc_res *smccc_ret) 94*57c73515SYidi Lin { 95*57c73515SYidi Lin uint64_t ret = 0; 96*57c73515SYidi Lin 97*57c73515SYidi Lin switch (x1) { 98*57c73515SYidi Lin case UFS_MTK_SIP_DEVICE_RESET: 99*57c73515SYidi Lin ufs_device_reset_ctrl(x2); 100*57c73515SYidi Lin break; 101*57c73515SYidi Lin default: 102*57c73515SYidi Lin ret = -1; 103*57c73515SYidi Lin WARN("[UFS] invalid argument 0x%lx from bootloader\n", x1); 104*57c73515SYidi Lin break; 105*57c73515SYidi Lin } 106*57c73515SYidi Lin 107*57c73515SYidi Lin return ret; 108*57c73515SYidi Lin } 109*57c73515SYidi Lin 110*57c73515SYidi Lin DECLARE_SMC_HANDLER(MTK_SIP_KERNEL_UFS_CONTROL, ufs_knl_ctrl); 111*57c73515SYidi Lin DECLARE_SMC_HANDLER(MTK_SIP_BL_UFS_CONTROL, ufs_bl_ctrl); 112