hc
2023-05-31 43fd8d44e8182b691c8ee61d487cec02ca11afd2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
 * (C) Copyright 2017 Rockchip Electronics Co., Ltd
 *
 * SPDX-License-Identifier:     GPL-2.0+
 */
 
#include <asm/arch/rockchip_smccc.h>
#include <asm/io.h>
#include <asm/psci.h>
#include <asm/suspend.h>
#include <linux/io.h>
 
#ifdef CONFIG_ARM64
#define ARM_PSCI_1_0_SYSTEM_SUSPEND    ARM_PSCI_1_0_FN64_SYSTEM_SUSPEND
#define ARM_PSCI_0_2_CPU_ON        ARM_PSCI_0_2_FN64_CPU_ON
#else
#define ARM_PSCI_1_0_SYSTEM_SUSPEND    ARM_PSCI_1_0_FN_SYSTEM_SUSPEND
#define ARM_PSCI_0_2_CPU_ON        ARM_PSCI_0_2_FN_CPU_ON
#endif
 
#define SIZE_PAGE(n)    ((n) << 12)
 
static struct arm_smccc_res __invoke_sip_fn_smc(unsigned long function_id,
                       unsigned long arg0,
                       unsigned long arg1,
                       unsigned long arg2)
{
   struct arm_smccc_res res;
 
   arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
   return res;
}
 
int psci_cpu_on(unsigned long cpuid, unsigned long entry_point)
{
   struct arm_smccc_res res;
 
   res = __invoke_sip_fn_smc(ARM_PSCI_0_2_CPU_ON, cpuid, entry_point, 0);
 
   return res.a0;
}
 
#ifdef CONFIG_ARM_CPU_SUSPEND
int psci_system_suspend(unsigned long unused)
{
   struct arm_smccc_res res;
 
   res = __invoke_sip_fn_smc(ARM_PSCI_1_0_SYSTEM_SUSPEND,
                 virt_to_phys(cpu_resume), 0, 0);
   return res.a0;
}
#endif
 
int sip_smc_set_suspend_mode(unsigned long ctrl,
                unsigned long config1,
                unsigned long config2)
{
   struct arm_smccc_res res;
 
   res = __invoke_sip_fn_smc(SIP_SUSPEND_MODE, ctrl, config1, config2);
   return res.a0;
}
 
int sip_smc_amp_cfg(unsigned long func, unsigned long arg0, unsigned long arg1,
           unsigned long arg2)
{
   struct arm_smccc_res res;
 
   arm_smccc_smc(SIP_AMP_CFG, func, arg0, arg1, arg2, 0, 0, 0, &res);
   return res.a0;
}
 
struct arm_smccc_res sip_smc_dram(unsigned long arg0,
                 unsigned long arg1,
                 unsigned long arg2)
{
   return __invoke_sip_fn_smc(SIP_DRAM_CONFIG, arg0, arg1, arg2);
}
 
struct arm_smccc_res sip_smc_request_share_mem(unsigned long page_num,
                          share_page_type_t page_type)
{
   struct arm_smccc_res res;
   unsigned long share_mem_phy;
 
   res = __invoke_sip_fn_smc(SIP_SHARE_MEM, page_num, page_type, 0);
   if (IS_SIP_ERROR(res.a0))
       goto error;
 
   share_mem_phy = res.a1;
   res.a1 = (unsigned long)ioremap(share_mem_phy, SIZE_PAGE(page_num));
 
error:
   return res;
}
 
struct arm_smccc_res sip_smc_secure_reg_read(unsigned long addr_phy)
{
   struct arm_smccc_res res;
 
   res = __invoke_sip_fn_smc(SIP_ACCESS_REG, 0, addr_phy, SECURE_REG_RD);
   return res;
}
 
int sip_smc_secure_reg_write(unsigned long addr_phy, unsigned long val)
{
   struct arm_smccc_res res;
 
   res = __invoke_sip_fn_smc(SIP_ACCESS_REG, val, addr_phy, SECURE_REG_WR);
   return res.a0;
}
 
int sip_smc_hdcp_config(unsigned long func, unsigned long arg1, unsigned long arg2)
{
   struct arm_smccc_res res;
 
   res = __invoke_sip_fn_smc(SIP_HDCP_CONFIG, func, arg1, arg2);
   return res.a0;
}
 
struct arm_smccc_res sip_smc_get_sip_version(void)
{
   return __invoke_sip_fn_smc(SIP_SIP_VERSION, 0, 0, 0);
}
 
/*
 * OP-TEE works both for kernel 3.10 and 4.4, and these two kernels have
 * different sip implement that 3.10 uses SIP_IMPLEMENT_V1 and 4.4 uses
 * SIP_IMPLEMENT_V2. So we should tell OP-TEE the current rockchip sip
 * version(default SIP_IMPLEMENT_V1) before use.
 */
int sip_smc_set_sip_version(unsigned long version)
{
   struct arm_smccc_res res;
 
   res = __invoke_sip_fn_smc(SIP_SIP_VERSION, version, SECURE_REG_WR, 0);
   if (IS_SIP_ERROR(res.a0)) {
       printf("%s: set rockchip sip version v%ld failed\n",
              __func__, version);
       return res.a0;
   }
 
   return 0;
}