blob: ac814bb626dcc3911e88f05224d9cae6bc862c77 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/*
2 * Copyright (C) 2024, ASR Microelectronics(Shanghai) LTD. Co.
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 and
7 * only version 2 as published by the Free Software Foundation.
8 *
9 */
10
11#include <linux/init.h>
12#include <linux/module.h>
13#include <linux/platform_device.h>
14#include <linux/fs.h>
15#include <linux/string.h>
16#include <linux/of.h>
17#include <linux/slab.h>
18#include <linux/of_address.h>
19#include <linux/arm-smccc.h>
20#include <linux/tee_drv.h>
21#include <linux/asr_tee_sip.h>
22
23/* Power Management */
24#define ASR_CPU_POWER_DOWN (0x84000001)
25#define ASR_SYSTEM_POWER_DOWN (0x8400000e)
26#ifdef CONFIG_CPU_ASR1901
27#define ASR_CPU_POWER_ON (0x84000003)
28#define ASR_CACHE_DISABLE (0x84000015)
29#endif
30
31#define ASR_SIP_MFPR_UDR_CFG_ADD (0x82000001)
32#define ASR_SIP_WAKEUP_STATE_SET (0x82000002)
33#define ASR_SIP_MFPR_UDR_CFG_INIT (0x82000003)
34#define ASR_SIP_SOC_REG_WRITE (0x82000004)
35#define ASR_SIP_SOC_REG_READ (0x82000005)
36#define ASR_SIP_REG_CIU (1)
37#define ASR_SIP_REG_GEU (2)
38#define ASR_SIP_WAKE_STATUS_INIT (0x82000006)
39#define ASR_SIP_GPIO_EDGE_CFG (0x82000007)
40#define ASR_SIP_IRQ_WAKEUP_SET (0x82000008)
41
42#ifndef CONFIG_CPU_ASR1901
43
44int asr_tee_cpu_power_down(unsigned int cpu, unsigned long entry_point)
45{
46 struct arm_smccc_res res;
47 arm_smccc_smc(ASR_CPU_POWER_DOWN, cpu, entry_point, 0, 0, 0, 0, 0, &res);
48 return res.a0;
49}
50
51int asr_tee_system_suspend(unsigned long entry_point)
52{
53 struct arm_smccc_res res;
54 arm_smccc_smc(ASR_SYSTEM_POWER_DOWN, entry_point, 0, 0, 0, 0, 0, 0, &res);
55 return res.a0;
56 return 0;
57}
58
59#else
60
61int asr_tee_cpu_power_on(unsigned int cpu, unsigned int cluster,
62 unsigned int entry_point)
63{
64 struct arm_smccc_res res;
65 arm_smccc_smc(ASR_CPU_POWER_ON, cpu, entry_point, cluster, 0, 0, 0, 0, &res);
66 return res.a0;
67}
68
69int asr_tee_cpu_power_down(u32 state, unsigned long entry_point)
70{
71 struct arm_smccc_res res;
72 arm_smccc_smc(ASR_CPU_POWER_DOWN, state, entry_point, 0, 0, 0, 0, 0, &res);
73 return res.a0;
74}
75
76int asr_tee_cluster_power_down(u32 state, unsigned long entry_point)
77{
78 struct arm_smccc_res res;
79 arm_smccc_smc(ASR_SYSTEM_POWER_DOWN, entry_point, state, 0, 0, 0, 0, 0, &res);
80 return res.a0;
81}
82
83int asr_tee_cache_disable(int last_man, int lpm_state)
84{
85 struct arm_smccc_res res;
86 arm_smccc_smc(ASR_CACHE_DISABLE, last_man, lpm_state, 0, 0, 0, 0, 0, &res);
87 return res.a0;
88}
89
90#endif
91
92unsigned int asr_ciu_read(unsigned int offset)
93{
94 struct arm_smccc_res res;
95 arm_smccc_smc(ASR_SIP_SOC_REG_READ, ASR_SIP_REG_CIU, offset, 0, 0, 0, 0, 0, &res);
96 return res.a0;
97}
98
99void asr_ciu_write(unsigned int offset, unsigned int val)
100{
101 struct arm_smccc_res res;
102 arm_smccc_smc(ASR_SIP_SOC_REG_WRITE, ASR_SIP_REG_CIU, offset, val, 0, 0, 0, 0, &res);
103 return;
104}
105
106unsigned long asr_mfpr_udr_cfg_add(unsigned long offset, unsigned long value)
107{
108 struct arm_smccc_res res;
109 arm_smccc_smc(ASR_SIP_MFPR_UDR_CFG_ADD, offset, value, 0, 0, 0, 0, 0, &res);
110 return res.a0;
111}
112
113unsigned long asr_mfpr_udr_cfg_init(unsigned long num)
114{
115 struct arm_smccc_res res;
116 arm_smccc_smc(ASR_SIP_MFPR_UDR_CFG_INIT, num, 0, 0, 0, 0, 0, 0, &res);
117 return res.a0;
118}
119
120unsigned long asr_wakeup_state_set(unsigned long state)
121{
122 struct arm_smccc_res res;
123 arm_smccc_smc(ASR_SIP_WAKEUP_STATE_SET, state, 0, 0, 0, 0, 0, 0, &res);
124 return res.a0;
125}
126
127unsigned long asr_wake_status_init(unsigned long status_addr)
128{
129 struct arm_smccc_res res;
130 arm_smccc_smc(ASR_SIP_WAKE_STATUS_INIT, (unsigned int)status_addr, 0, 0, 0, 0, 0, 0, &res);
131 return res.a0;
132}
133
134unsigned long asr_gpio_edge_detect_add(unsigned long gpio)
135{
136 struct arm_smccc_res res;
137 arm_smccc_smc(ASR_SIP_GPIO_EDGE_CFG, 0/*add*/, gpio, 0, 0, 0, 0, 0, &res);
138 return res.a0;
139}
140
141unsigned long asr_gpio_edge_detect_remove(unsigned long gpio)
142{
143 struct arm_smccc_res res;
144 arm_smccc_smc(ASR_SIP_GPIO_EDGE_CFG, 1/*remove*/, gpio, 0, 0, 0, 0, 0, &res);
145 return res.a0;
146}
147
148unsigned long asr_gpio_edge_detect_disable(unsigned long gpio)
149{
150 struct arm_smccc_res res;
151 arm_smccc_smc(ASR_SIP_GPIO_EDGE_CFG, 2/*disable*/, gpio, 0, 0, 0, 0, 0, &res);
152 return res.a0;
153}
154
155unsigned long asr_gpio_edge_detect_enable(unsigned long gpio)
156{
157 struct arm_smccc_res res;
158 arm_smccc_smc(ASR_SIP_GPIO_EDGE_CFG, 3/*enable*/, gpio, 0, 0, 0, 0, 0, &res);
159 return res.a0;
160}
161
162unsigned long asr_irq_wake_set(unsigned long irq, unsigned long on)
163{
164 struct arm_smccc_res res;
165 arm_smccc_smc(ASR_SIP_IRQ_WAKEUP_SET, irq, on, 0, 0, 0, 0, 0, &res);
166 return res.a0;
167}
168
169