xref: /rk3399_ARM-atf/plat/imx/common/imx_sip_handler.c (revision fd7b287cbe9147ca9e07dd9f30c49c58bbdd92a8)
1 /*
2  * Copyright 2019 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <services/std_svc.h>
10 #include <string.h>
11 #include <platform_def.h>
12 #include <common/debug.h>
13 #include <common/runtime_svc.h>
14 #include <imx_sip_svc.h>
15 #include <sci/sci.h>
16 
17 #ifdef PLAT_IMX8QM
18 const static int ap_cluster_index[PLATFORM_CLUSTER_COUNT] = {
19 	SC_R_A53, SC_R_A72,
20 };
21 #endif
22 
23 static int imx_srtc_set_time(uint32_t year_mon,
24 			unsigned long day_hour,
25 			unsigned long min_sec)
26 {
27 	return sc_timer_set_rtc_time(ipc_handle,
28 		year_mon >> 16, year_mon & 0xffff,
29 		day_hour >> 16, day_hour & 0xffff,
30 		min_sec >> 16, min_sec & 0xffff);
31 }
32 
33 int imx_srtc_handler(uint32_t smc_fid,
34 		    void *handle,
35 		    u_register_t x1,
36 		    u_register_t x2,
37 		    u_register_t x3,
38 		    u_register_t x4)
39 {
40 	int ret;
41 
42 	switch (x1) {
43 	case IMX_SIP_SRTC_SET_TIME:
44 		ret = imx_srtc_set_time(x2, x3, x4);
45 		break;
46 	default:
47 		ret = SMC_UNK;
48 	}
49 
50 	SMC_RET1(handle, ret);
51 }
52 
53 static void imx_cpufreq_set_target(uint32_t cluster_id, unsigned long freq)
54 {
55 	sc_pm_clock_rate_t rate = (sc_pm_clock_rate_t)freq;
56 
57 #ifdef PLAT_IMX8QM
58 	sc_pm_set_clock_rate(ipc_handle, ap_cluster_index[cluster_id], SC_PM_CLK_CPU, &rate);
59 #endif
60 #ifdef PLAT_IMX8QX
61 	sc_pm_set_clock_rate(ipc_handle, SC_R_A35, SC_PM_CLK_CPU, &rate);
62 #endif
63 }
64 
65 int imx_cpufreq_handler(uint32_t smc_fid,
66 		    u_register_t x1,
67 		    u_register_t x2,
68 		    u_register_t x3)
69 {
70 	switch (x1) {
71 	case IMX_SIP_SET_CPUFREQ:
72 		imx_cpufreq_set_target(x2, x3);
73 		break;
74 	default:
75 		return SMC_UNK;
76 	}
77 
78 	return 0;
79 }
80 
81 static bool wakeup_src_irqsteer;
82 
83 bool imx_is_wakeup_src_irqsteer(void)
84 {
85 	return wakeup_src_irqsteer;
86 }
87 
88 int imx_wakeup_src_handler(uint32_t smc_fid,
89 		    u_register_t x1,
90 		    u_register_t x2,
91 		    u_register_t x3)
92 {
93 	switch (x1) {
94 	case IMX_SIP_WAKEUP_SRC_IRQSTEER:
95 		wakeup_src_irqsteer = true;
96 		break;
97 	case IMX_SIP_WAKEUP_SRC_SCU:
98 		wakeup_src_irqsteer = false;
99 		break;
100 	default:
101 		return SMC_UNK;
102 	}
103 
104 	return SMC_OK;
105 }
106 
107 int imx_otp_handler(uint32_t smc_fid,
108 		void *handle,
109 		u_register_t x1,
110 		u_register_t x2)
111 {
112 	int ret;
113 	uint32_t fuse;
114 
115 	switch (smc_fid) {
116 	case IMX_SIP_OTP_READ:
117 		ret = sc_misc_otp_fuse_read(ipc_handle, x1, &fuse);
118 		SMC_RET2(handle, ret, fuse);
119 		break;
120 	case IMX_SIP_OTP_WRITE:
121 		ret = sc_misc_otp_fuse_write(ipc_handle, x1, x2);
122 		SMC_RET1(handle, ret);
123 		break;
124 	default:
125 		ret = SMC_UNK;
126 		SMC_RET1(handle, ret);
127 		break;
128 	}
129 
130 	return ret;
131 }
132 
133 int imx_misc_set_temp_handler(uint32_t smc_fid,
134 		    u_register_t x1,
135 		    u_register_t x2,
136 		    u_register_t x3,
137 		    u_register_t x4)
138 {
139 	return sc_misc_set_temp(ipc_handle, x1, x2, x3, x4);
140 }
141 
142 static uint64_t imx_get_commit_hash(u_register_t x2,
143 		    u_register_t x3,
144 		    u_register_t x4)
145 {
146 	/* Parse the version_string */
147 	char *parse = (char *)version_string;
148 	uint64_t hash = 0;
149 
150 	do {
151 		parse = strchr(parse, '-');
152 		if (parse) {
153 			parse += 1;
154 			if (*(parse) == 'g') {
155 				/* Default is 7 hexadecimal digits */
156 				memcpy((void *)&hash, (void *)(parse + 1), 7);
157 				break;
158 			}
159 		}
160 
161 	} while (parse != NULL);
162 
163 	return hash;
164 }
165 
166 uint64_t imx_buildinfo_handler(uint32_t smc_fid,
167 		    u_register_t x1,
168 		    u_register_t x2,
169 		    u_register_t x3,
170 		    u_register_t x4)
171 {
172 	uint64_t ret;
173 
174 	switch (x1) {
175 	case IMX_SIP_BUILDINFO_GET_COMMITHASH:
176 		ret = imx_get_commit_hash(x2, x3, x4);
177 		break;
178 	default:
179 		return SMC_UNK;
180 	}
181 
182 	return ret;
183 }
184