ASR_BASE
Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/marvell/linux/drivers/tee/optee/asr_tee_sip.c b/marvell/linux/drivers/tee/optee/asr_tee_sip.c
new file mode 100644
index 0000000..ac814bb
--- /dev/null
+++ b/marvell/linux/drivers/tee/optee/asr_tee_sip.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2024, ASR Microelectronics(Shanghai) LTD. Co.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/of_address.h>
+#include <linux/arm-smccc.h>
+#include <linux/tee_drv.h>
+#include <linux/asr_tee_sip.h>
+
+/* Power Management */
+#define ASR_CPU_POWER_DOWN (0x84000001)
+#define ASR_SYSTEM_POWER_DOWN (0x8400000e)
+#ifdef CONFIG_CPU_ASR1901
+#define ASR_CPU_POWER_ON (0x84000003)
+#define ASR_CACHE_DISABLE (0x84000015)
+#endif
+
+#define ASR_SIP_MFPR_UDR_CFG_ADD (0x82000001)
+#define ASR_SIP_WAKEUP_STATE_SET (0x82000002)
+#define ASR_SIP_MFPR_UDR_CFG_INIT (0x82000003)
+#define ASR_SIP_SOC_REG_WRITE (0x82000004)
+#define ASR_SIP_SOC_REG_READ (0x82000005)
+#define ASR_SIP_REG_CIU (1)
+#define ASR_SIP_REG_GEU (2)
+#define ASR_SIP_WAKE_STATUS_INIT (0x82000006)
+#define ASR_SIP_GPIO_EDGE_CFG (0x82000007)
+#define ASR_SIP_IRQ_WAKEUP_SET (0x82000008)
+
+#ifndef CONFIG_CPU_ASR1901
+
+int asr_tee_cpu_power_down(unsigned int cpu, unsigned long entry_point)
+{
+ struct arm_smccc_res res;
+ arm_smccc_smc(ASR_CPU_POWER_DOWN, cpu, entry_point, 0, 0, 0, 0, 0, &res);
+ return res.a0;
+}
+
+int asr_tee_system_suspend(unsigned long entry_point)
+{
+ struct arm_smccc_res res;
+ arm_smccc_smc(ASR_SYSTEM_POWER_DOWN, entry_point, 0, 0, 0, 0, 0, 0, &res);
+ return res.a0;
+ return 0;
+}
+
+#else
+
+int asr_tee_cpu_power_on(unsigned int cpu, unsigned int cluster,
+ unsigned int entry_point)
+{
+ struct arm_smccc_res res;
+ arm_smccc_smc(ASR_CPU_POWER_ON, cpu, entry_point, cluster, 0, 0, 0, 0, &res);
+ return res.a0;
+}
+
+int asr_tee_cpu_power_down(u32 state, unsigned long entry_point)
+{
+ struct arm_smccc_res res;
+ arm_smccc_smc(ASR_CPU_POWER_DOWN, state, entry_point, 0, 0, 0, 0, 0, &res);
+ return res.a0;
+}
+
+int asr_tee_cluster_power_down(u32 state, unsigned long entry_point)
+{
+ struct arm_smccc_res res;
+ arm_smccc_smc(ASR_SYSTEM_POWER_DOWN, entry_point, state, 0, 0, 0, 0, 0, &res);
+ return res.a0;
+}
+
+int asr_tee_cache_disable(int last_man, int lpm_state)
+{
+ struct arm_smccc_res res;
+ arm_smccc_smc(ASR_CACHE_DISABLE, last_man, lpm_state, 0, 0, 0, 0, 0, &res);
+ return res.a0;
+}
+
+#endif
+
+unsigned int asr_ciu_read(unsigned int offset)
+{
+ struct arm_smccc_res res;
+ arm_smccc_smc(ASR_SIP_SOC_REG_READ, ASR_SIP_REG_CIU, offset, 0, 0, 0, 0, 0, &res);
+ return res.a0;
+}
+
+void asr_ciu_write(unsigned int offset, unsigned int val)
+{
+ struct arm_smccc_res res;
+ arm_smccc_smc(ASR_SIP_SOC_REG_WRITE, ASR_SIP_REG_CIU, offset, val, 0, 0, 0, 0, &res);
+ return;
+}
+
+unsigned long asr_mfpr_udr_cfg_add(unsigned long offset, unsigned long value)
+{
+ struct arm_smccc_res res;
+ arm_smccc_smc(ASR_SIP_MFPR_UDR_CFG_ADD, offset, value, 0, 0, 0, 0, 0, &res);
+ return res.a0;
+}
+
+unsigned long asr_mfpr_udr_cfg_init(unsigned long num)
+{
+ struct arm_smccc_res res;
+ arm_smccc_smc(ASR_SIP_MFPR_UDR_CFG_INIT, num, 0, 0, 0, 0, 0, 0, &res);
+ return res.a0;
+}
+
+unsigned long asr_wakeup_state_set(unsigned long state)
+{
+ struct arm_smccc_res res;
+ arm_smccc_smc(ASR_SIP_WAKEUP_STATE_SET, state, 0, 0, 0, 0, 0, 0, &res);
+ return res.a0;
+}
+
+unsigned long asr_wake_status_init(unsigned long status_addr)
+{
+ struct arm_smccc_res res;
+ arm_smccc_smc(ASR_SIP_WAKE_STATUS_INIT, (unsigned int)status_addr, 0, 0, 0, 0, 0, 0, &res);
+ return res.a0;
+}
+
+unsigned long asr_gpio_edge_detect_add(unsigned long gpio)
+{
+ struct arm_smccc_res res;
+ arm_smccc_smc(ASR_SIP_GPIO_EDGE_CFG, 0/*add*/, gpio, 0, 0, 0, 0, 0, &res);
+ return res.a0;
+}
+
+unsigned long asr_gpio_edge_detect_remove(unsigned long gpio)
+{
+ struct arm_smccc_res res;
+ arm_smccc_smc(ASR_SIP_GPIO_EDGE_CFG, 1/*remove*/, gpio, 0, 0, 0, 0, 0, &res);
+ return res.a0;
+}
+
+unsigned long asr_gpio_edge_detect_disable(unsigned long gpio)
+{
+ struct arm_smccc_res res;
+ arm_smccc_smc(ASR_SIP_GPIO_EDGE_CFG, 2/*disable*/, gpio, 0, 0, 0, 0, 0, &res);
+ return res.a0;
+}
+
+unsigned long asr_gpio_edge_detect_enable(unsigned long gpio)
+{
+ struct arm_smccc_res res;
+ arm_smccc_smc(ASR_SIP_GPIO_EDGE_CFG, 3/*enable*/, gpio, 0, 0, 0, 0, 0, &res);
+ return res.a0;
+}
+
+unsigned long asr_irq_wake_set(unsigned long irq, unsigned long on)
+{
+ struct arm_smccc_res res;
+ arm_smccc_smc(ASR_SIP_IRQ_WAKEUP_SET, irq, on, 0, 0, 0, 0, 0, &res);
+ return res.a0;
+}
+
+