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;

+}

+

+