feat(mediatek): add UFS stub implementation

Implement stub functions for UFS to ensure that the build can pass when
a prebuilt library is not available.

Change-Id: If4470cd9a5b88e869363e763aec5830c1f8411f5
Signed-off-by: Yidi Lin <yidilin@chromium.org>
diff --git a/plat/mediatek/drivers/ufs/rules.mk b/plat/mediatek/drivers/ufs/rules.mk
new file mode 100644
index 0000000..877cbc7
--- /dev/null
+++ b/plat/mediatek/drivers/ufs/rules.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2025, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := ufs
+
+PLAT_INCLUDES += -I$(LOCAL_DIR)
+PLAT_INCLUDES += -I$(MTK_PLAT)/include/drivers/
+
+LOCAL_SRCS-y := $(LOCAL_DIR)/ufs_ctrl.c
+ifeq ($(MTKLIB_PATH),)
+LOCAL_SRCS-y += $(LOCAL_DIR)/ufs_stub.c
+endif
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/ufs/ufs_ctrl.c b/plat/mediatek/drivers/ufs/ufs_ctrl.c
new file mode 100644
index 0000000..af27e67
--- /dev/null
+++ b/plat/mediatek/drivers/ufs/ufs_ctrl.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2025, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+
+/* MTK header */
+#include <drivers/pmic/pmic_swap_api.h>
+#include <mtk_bl31_interface.h>
+#include <mtk_sip_svc.h>
+
+/* UFS generic control flags */
+#define UFS_MTK_SIP_VA09_PWR_CTRL		BIT(0)
+#define UFS_MTK_SIP_DEVICE_RESET		BIT(1)
+#define UFS_MTK_SIP_CRYPTO_CTRL			BIT(2)
+#define UFS_MTK_SIP_REF_CLK_NOTIFICATION	BIT(3)
+#define UFS_MTK_SIP_SRAM_PWR_CTRL		BIT(5)
+#define UFS_MTK_SIP_GET_VCC_INFO		BIT(6)
+#define UFS_MTK_SIP_DEVICE_PWR_CTRL		BIT(7)
+#define UFS_MTK_SIP_MPHY_CTRL			BIT(8)
+#define UFS_MTK_SIP_MTCMOS_CTRL			BIT(9)
+
+enum {
+	VCC_NONE = 0,
+	VCC_1,
+	VCC_2,
+};
+
+static void ufs_get_vcc_info(struct smccc_res *smccc_ret)
+{
+	if (smccc_ret == NULL)
+		return;
+
+	if (is_second_pmic_pp_swap())
+		smccc_ret->a1 = VCC_2;
+	else
+		smccc_ret->a1 = VCC_1;
+}
+
+static u_register_t ufs_knl_ctrl(u_register_t x1,
+				 u_register_t x2,
+				 u_register_t x3,
+				 u_register_t x4,
+				 void *handle,
+				 struct smccc_res *smccc_ret)
+{
+	uint64_t ret = 0;
+
+	switch (x1) {
+	case UFS_MTK_SIP_VA09_PWR_CTRL:
+		ufs_mphy_va09_cg_ctrl((bool)!!x2);
+		break;
+	case UFS_MTK_SIP_DEVICE_RESET:
+		ufs_device_reset_ctrl((bool)!!x2);
+		break;
+	case UFS_MTK_SIP_CRYPTO_CTRL:
+		ufs_crypto_hie_init();
+		break;
+	case UFS_MTK_SIP_REF_CLK_NOTIFICATION:
+		ufs_ref_clk_status(x2, x3);
+		break;
+	case UFS_MTK_SIP_SRAM_PWR_CTRL:
+		ufs_sram_pwr_ctrl(x2);
+		break;
+	case UFS_MTK_SIP_GET_VCC_INFO:
+		ufs_get_vcc_info(smccc_ret);
+		break;
+	case UFS_MTK_SIP_DEVICE_PWR_CTRL:
+		ufs_device_pwr_ctrl(x2, x3);
+		break;
+	case UFS_MTK_SIP_MPHY_CTRL:
+		ufs_mphy_ctrl(x2);
+		break;
+	case UFS_MTK_SIP_MTCMOS_CTRL:
+		ufs_mtcmos_ctrl(x2);
+		break;
+	default:
+		ret = -1;
+		WARN("[UFS] invalid argument 0x%lx from kernel\n", x1);
+		break;
+	}
+
+	return ret;
+}
+
+static u_register_t ufs_bl_ctrl(u_register_t x1,
+				u_register_t x2,
+				u_register_t x3,
+				u_register_t x4,
+				void *handle,
+				struct smccc_res *smccc_ret)
+{
+	uint64_t ret = 0;
+
+	switch (x1) {
+	case UFS_MTK_SIP_DEVICE_RESET:
+		ufs_device_reset_ctrl(x2);
+		break;
+	default:
+		ret = -1;
+		WARN("[UFS] invalid argument 0x%lx from bootloader\n", x1);
+		break;
+	}
+
+	return ret;
+}
+
+DECLARE_SMC_HANDLER(MTK_SIP_KERNEL_UFS_CONTROL, ufs_knl_ctrl);
+DECLARE_SMC_HANDLER(MTK_SIP_BL_UFS_CONTROL, ufs_bl_ctrl);
diff --git a/plat/mediatek/drivers/ufs/ufs_stub.c b/plat/mediatek/drivers/ufs/ufs_stub.c
new file mode 100644
index 0000000..c03f27e
--- /dev/null
+++ b/plat/mediatek/drivers/ufs/ufs_stub.c
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2025, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mtk_bl31_interface.h>
+
+void ufs_mphy_va09_cg_ctrl(bool enable) {}
+void ufs_device_reset_ctrl(bool rst_n) {}
+void ufs_crypto_hie_init(void) {}
+void ufs_ref_clk_status(uint32_t on, enum ufs_notify_change_status stage) {}
+void ufs_sram_pwr_ctrl(bool on) {}
+void ufs_device_pwr_ctrl(bool vcc_on, uint64_t ufs_version) {}
+void ufs_mphy_ctrl(enum ufs_mtk_mphy_op op) {}
+void ufs_mtcmos_ctrl(bool on) {}
diff --git a/plat/mediatek/include/mtk_bl31_interface.h b/plat/mediatek/include/mtk_bl31_interface.h
new file mode 100644
index 0000000..9650f71
--- /dev/null
+++ b/plat/mediatek/include/mtk_bl31_interface.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2025, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __MTK_BL31_INTERFACE_H__
+#define __MTK_BL31_INTERFACE_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+
+/* UFS definitions */
+enum ufs_mtk_mphy_op {
+	UFS_MPHY_BACKUP = 0,
+	UFS_MPHY_RESTORE,
+};
+
+enum ufs_notify_change_status {
+	PRE_CHANGE,
+	POST_CHANGE,
+};
+
+/* UFS interfaces */
+void ufs_mphy_va09_cg_ctrl(bool enable);
+void ufs_device_reset_ctrl(bool rst_n);
+void ufs_crypto_hie_init(void);
+void ufs_ref_clk_status(uint32_t on, enum ufs_notify_change_status stage);
+void ufs_sram_pwr_ctrl(bool on);
+void ufs_device_pwr_ctrl(bool vcc_on, uint64_t ufs_version);
+void ufs_mphy_ctrl(enum ufs_mtk_mphy_op op);
+void ufs_mtcmos_ctrl(bool on);
+
+#endif /* __MTK_BL31_INTERFACE_H__ */
diff --git a/plat/mediatek/mt8196/platform.mk b/plat/mediatek/mt8196/platform.mk
index 172a074..14cd5a0 100644
--- a/plat/mediatek/mt8196/platform.mk
+++ b/plat/mediatek/mt8196/platform.mk
@@ -53,6 +53,7 @@
 MODULES-y += $(MTK_PLAT)/drivers/smmu
 MODULES-y += $(MTK_PLAT)/drivers/spm
 MODULES-y += $(MTK_PLAT)/drivers/timer
+MODULES-y += $(MTK_PLAT)/drivers/ufs
 MODULES-y += $(MTK_PLAT)/drivers/vcp
 MODULES-y += $(MTK_PLAT)/helpers
 MODULES-y += $(MTK_PLAT)/topology