xref: /OK3568_Linux_fs/kernel/drivers/firmware/rockchip_sip.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License version 2 as
4  * published by the Free Software Foundation.
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9  * GNU General Public License for more details.
10  *
11  * Copyright (C) 2016, Fuzhou Rockchip Electronics Co., Ltd
12  */
13 
14 #include <linux/arm-smccc.h>
15 #include <linux/io.h>
16 #include <linux/module.h>
17 #include <linux/rockchip/rockchip_sip.h>
18 #include <asm/cputype.h>
19 #ifdef CONFIG_ARM
20 #include <asm/psci.h>
21 #endif
22 #include <asm/smp_plat.h>
23 #include <uapi/linux/psci.h>
24 #include <linux/ptrace.h>
25 #include <linux/sched/clock.h>
26 #include <linux/slab.h>
27 #include <soc/rockchip/rockchip_sip.h>
28 
29 #ifdef CONFIG_64BIT
30 #define PSCI_FN_NATIVE(version, name)	PSCI_##version##_FN64_##name
31 #else
32 #define PSCI_FN_NATIVE(version, name)	PSCI_##version##_FN_##name
33 #endif
34 
35 #define SIZE_PAGE(n)	((n) << 12)
36 
__invoke_sip_fn_smc(unsigned long function_id,unsigned long arg0,unsigned long arg1,unsigned long arg2)37 static struct arm_smccc_res __invoke_sip_fn_smc(unsigned long function_id,
38 						unsigned long arg0,
39 						unsigned long arg1,
40 						unsigned long arg2)
41 {
42 	struct arm_smccc_res res;
43 
44 	arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
45 	return res;
46 }
47 
sip_smc_dram(u32 arg0,u32 arg1,u32 arg2)48 struct arm_smccc_res sip_smc_dram(u32 arg0, u32 arg1, u32 arg2)
49 {
50 	return __invoke_sip_fn_smc(SIP_DRAM_CONFIG, arg0, arg1, arg2);
51 }
52 EXPORT_SYMBOL_GPL(sip_smc_dram);
53 
sip_smc_get_atf_version(void)54 struct arm_smccc_res sip_smc_get_atf_version(void)
55 {
56 	return __invoke_sip_fn_smc(SIP_ATF_VERSION, 0, 0, 0);
57 }
58 EXPORT_SYMBOL_GPL(sip_smc_get_atf_version);
59 
sip_smc_get_sip_version(void)60 struct arm_smccc_res sip_smc_get_sip_version(void)
61 {
62 	return __invoke_sip_fn_smc(SIP_SIP_VERSION, 0, 0, 0);
63 }
64 EXPORT_SYMBOL_GPL(sip_smc_get_sip_version);
65 
sip_smc_set_suspend_mode(u32 ctrl,u32 config1,u32 config2)66 int sip_smc_set_suspend_mode(u32 ctrl, u32 config1, u32 config2)
67 {
68 	struct arm_smccc_res res;
69 
70 	res = __invoke_sip_fn_smc(SIP_SUSPEND_MODE, ctrl, config1, config2);
71 	return res.a0;
72 }
73 EXPORT_SYMBOL_GPL(sip_smc_set_suspend_mode);
74 
sip_smc_get_suspend_info(u32 info)75 struct arm_smccc_res sip_smc_get_suspend_info(u32 info)
76 {
77 	struct arm_smccc_res res;
78 
79 	res = __invoke_sip_fn_smc(SIP_SUSPEND_MODE, info, 0, 0);
80 	return res;
81 }
82 EXPORT_SYMBOL_GPL(sip_smc_get_suspend_info);
83 
sip_smc_virtual_poweroff(void)84 int sip_smc_virtual_poweroff(void)
85 {
86 	struct arm_smccc_res res;
87 
88 	res = __invoke_sip_fn_smc(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND), 0, 0, 0);
89 	return res.a0;
90 }
91 EXPORT_SYMBOL_GPL(sip_smc_virtual_poweroff);
92 
sip_smc_remotectl_config(u32 func,u32 data)93 int sip_smc_remotectl_config(u32 func, u32 data)
94 {
95 	struct arm_smccc_res res;
96 
97 	res = __invoke_sip_fn_smc(SIP_REMOTECTL_CFG, func, data, 0);
98 
99 	return res.a0;
100 }
101 EXPORT_SYMBOL_GPL(sip_smc_remotectl_config);
102 
sip_smc_secure_reg_read(u32 addr_phy)103 u32 sip_smc_secure_reg_read(u32 addr_phy)
104 {
105 	struct arm_smccc_res res;
106 
107 	res = __invoke_sip_fn_smc(SIP_ACCESS_REG, 0, addr_phy, SECURE_REG_RD);
108 	if (res.a0)
109 		pr_err("%s error: %d, addr phy: 0x%x\n",
110 		       __func__, (int)res.a0, addr_phy);
111 
112 	return res.a1;
113 }
114 EXPORT_SYMBOL_GPL(sip_smc_secure_reg_read);
115 
sip_smc_secure_reg_write(u32 addr_phy,u32 val)116 int sip_smc_secure_reg_write(u32 addr_phy, u32 val)
117 {
118 	struct arm_smccc_res res;
119 
120 	res = __invoke_sip_fn_smc(SIP_ACCESS_REG, val, addr_phy, SECURE_REG_WR);
121 	if (res.a0)
122 		pr_err("%s error: %d, addr phy: 0x%x\n",
123 		       __func__, (int)res.a0, addr_phy);
124 
125 	return res.a0;
126 }
127 EXPORT_SYMBOL_GPL(sip_smc_secure_reg_write);
128 
sip_map(phys_addr_t start,size_t size)129 static void *sip_map(phys_addr_t start, size_t size)
130 {
131 	struct page **pages;
132 	phys_addr_t page_start;
133 	unsigned int page_count;
134 	pgprot_t prot;
135 	unsigned int i;
136 	void *vaddr;
137 
138 	if (!pfn_valid(__phys_to_pfn(start)))
139 		return ioremap(start, size);
140 
141 	page_start = start - offset_in_page(start);
142 	page_count = DIV_ROUND_UP(size + offset_in_page(start), PAGE_SIZE);
143 
144 	prot = pgprot_noncached(PAGE_KERNEL);
145 
146 	pages = kmalloc_array(page_count, sizeof(struct page *), GFP_KERNEL);
147 	if (!pages) {
148 		pr_err("%s: Failed to allocate array for %u pages\n",
149 		       __func__, page_count);
150 		return NULL;
151 	}
152 
153 	for (i = 0; i < page_count; i++)
154 		pages[i] = phys_to_page(page_start + i * PAGE_SIZE);
155 
156 	vaddr = vmap(pages, page_count, VM_MAP, prot);
157 	kfree(pages);
158 
159 	/*
160 	 * Since vmap() uses page granularity, we must add the offset
161 	 * into the page here, to get the byte granularity address
162 	 * into the mapping to represent the actual "start" location.
163 	 */
164 	return vaddr + offset_in_page(start);
165 }
166 
sip_smc_request_share_mem(u32 page_num,share_page_type_t page_type)167 struct arm_smccc_res sip_smc_request_share_mem(u32 page_num,
168 					       share_page_type_t page_type)
169 {
170 	struct arm_smccc_res res;
171 	unsigned long share_mem_phy;
172 
173 	res = __invoke_sip_fn_smc(SIP_SHARE_MEM, page_num, page_type, 0);
174 	if (IS_SIP_ERROR(res.a0))
175 		goto error;
176 
177 	share_mem_phy = res.a1;
178 	res.a1 = (unsigned long)sip_map(share_mem_phy, SIZE_PAGE(page_num));
179 
180 error:
181 	return res;
182 }
183 EXPORT_SYMBOL_GPL(sip_smc_request_share_mem);
184 
sip_smc_mcu_el3fiq(u32 arg0,u32 arg1,u32 arg2)185 struct arm_smccc_res sip_smc_mcu_el3fiq(u32 arg0, u32 arg1, u32 arg2)
186 {
187 	return __invoke_sip_fn_smc(SIP_MCU_EL3FIQ_CFG, arg0, arg1, arg2);
188 }
189 EXPORT_SYMBOL_GPL(sip_smc_mcu_el3fiq);
190 
sip_smc_vpu_reset(u32 arg0,u32 arg1,u32 arg2)191 struct arm_smccc_res sip_smc_vpu_reset(u32 arg0, u32 arg1, u32 arg2)
192 {
193 	struct arm_smccc_res res;
194 
195 	res = __invoke_sip_fn_smc(PSCI_SIP_VPU_RESET, arg0, arg1, arg2);
196 	return res;
197 }
198 EXPORT_SYMBOL_GPL(sip_smc_vpu_reset);
199 
sip_smc_bus_config(u32 arg0,u32 arg1,u32 arg2)200 struct arm_smccc_res sip_smc_bus_config(u32 arg0, u32 arg1, u32 arg2)
201 {
202 	struct arm_smccc_res res;
203 
204 	res = __invoke_sip_fn_smc(SIP_BUS_CFG, arg0, arg1, arg2);
205 	return res;
206 }
207 EXPORT_SYMBOL_GPL(sip_smc_bus_config);
208 
sip_smc_get_dram_map(void)209 struct dram_addrmap_info *sip_smc_get_dram_map(void)
210 {
211 	struct arm_smccc_res res;
212 	static struct dram_addrmap_info *map;
213 
214 	if (map)
215 		return map;
216 
217 	/* Request share memory size 4KB */
218 	res = sip_smc_request_share_mem(1, SHARE_PAGE_TYPE_DDR_ADDRMAP);
219 	if (res.a0 != 0) {
220 		pr_err("no ATF memory for init\n");
221 		return NULL;
222 	}
223 
224 	map = (struct dram_addrmap_info *)res.a1;
225 
226 	res = sip_smc_dram(SHARE_PAGE_TYPE_DDR_ADDRMAP, 0,
227 			   ROCKCHIP_SIP_CONFIG_DRAM_ADDRMAP_GET);
228 	if (res.a0) {
229 		pr_err("rockchip_sip_config_dram_init error:%lx\n", res.a0);
230 		map = NULL;
231 		return NULL;
232 	}
233 
234 	return map;
235 }
236 EXPORT_SYMBOL_GPL(sip_smc_get_dram_map);
237 
sip_smc_lastlog_request(void)238 struct arm_smccc_res sip_smc_lastlog_request(void)
239 {
240 	struct arm_smccc_res res;
241 	void __iomem *addr1, *addr2;
242 
243 	res = __invoke_sip_fn_smc(SIP_LAST_LOG, local_clock(), 0, 0);
244 	if (IS_SIP_ERROR(res.a0))
245 		return res;
246 
247 	addr1 = sip_map(res.a1, res.a3);
248 	if (!addr1) {
249 		pr_err("%s: share memory buffer0 ioremap failed\n", __func__);
250 		res.a0 = SIP_RET_INVALID_ADDRESS;
251 		return res;
252 	}
253 	addr2 = sip_map(res.a2, res.a3);
254 	if (!addr2) {
255 		pr_err("%s: share memory buffer1 ioremap failed\n", __func__);
256 		res.a0 = SIP_RET_INVALID_ADDRESS;
257 		return res;
258 	}
259 
260 	res.a1 = (unsigned long)addr1;
261 	res.a2 = (unsigned long)addr2;
262 
263 	return res;
264 }
265 EXPORT_SYMBOL_GPL(sip_smc_lastlog_request);
266 
sip_smc_amp_config(u32 sub_func_id,u32 arg1,u32 arg2,u32 arg3)267 int sip_smc_amp_config(u32 sub_func_id, u32 arg1, u32 arg2, u32 arg3)
268 {
269 	struct arm_smccc_res res;
270 
271 	arm_smccc_smc(RK_SIP_AMP_CFG, sub_func_id, arg1, arg2, arg3,
272 		      0, 0, 0, &res);
273 	return res.a0;
274 }
275 EXPORT_SYMBOL_GPL(sip_smc_amp_config);
276 
sip_smc_get_amp_info(u32 sub_func_id,u32 arg1)277 struct arm_smccc_res sip_smc_get_amp_info(u32 sub_func_id, u32 arg1)
278 {
279 	struct arm_smccc_res res;
280 
281 	arm_smccc_smc(RK_SIP_AMP_CFG, sub_func_id, arg1, 0, 0, 0, 0, 0, &res);
282 	return res;
283 }
284 EXPORT_SYMBOL_GPL(sip_smc_get_amp_info);
285 
sip_hdcp_request_share_memory(int id)286 void __iomem *sip_hdcp_request_share_memory(int id)
287 {
288 	static void __iomem *base;
289 	struct arm_smccc_res res;
290 
291 	if (id < 0 || id >= MAX_DEVICE) {
292 		pr_err("%s: invalid device id\n", __func__);
293 		return NULL;
294 	}
295 
296 	if (!base) {
297 		/* request page share memory */
298 		res = sip_smc_request_share_mem(2, SHARE_PAGE_TYPE_HDCP);
299 		if (IS_SIP_ERROR(res.a0))
300 			return NULL;
301 		base = (void __iomem *)res.a1;
302 	}
303 
304 	return base + id * 1024;
305 }
306 EXPORT_SYMBOL_GPL(sip_hdcp_request_share_memory);
307 
sip_hdcp_config(u32 arg0,u32 arg1,u32 arg2)308 struct arm_smccc_res sip_hdcp_config(u32 arg0, u32 arg1, u32 arg2)
309 {
310 	struct arm_smccc_res res;
311 
312 	res = __invoke_sip_fn_smc(SIP_HDCP_CONFIG, arg0, arg1, arg2);
313 	return res;
314 }
315 EXPORT_SYMBOL_GPL(sip_hdcp_config);
316 
317 /************************** fiq debugger **************************************/
318 /*
319  * AArch32 is not allowed to call SMC64(ATF framework does not support), so we
320  * don't change SIP_UARTDBG_FN to SIP_UARTDBG_CFG64 even when cpu is AArch32
321  * mode. Let ATF support SIP_UARTDBG_CFG, and we just initialize SIP_UARTDBG_FN
322  * depends on compile option(CONFIG_ARM or CONFIG_ARM64).
323  */
324 #ifdef CONFIG_ARM64
325 #define SIP_UARTDBG_FN		SIP_UARTDBG_CFG64
326 #else
327 #define SIP_UARTDBG_FN		SIP_UARTDBG_CFG
328 static int firmware_64_32bit;
329 #endif
330 
331 static int fiq_sip_enabled;
332 static int fiq_target_cpu;
333 static phys_addr_t ft_fiq_mem_phy;
334 static void __iomem *ft_fiq_mem_base;
335 static sip_fiq_debugger_uart_irq_tf_cb_t sip_fiq_debugger_uart_irq_tf;
336 static struct pt_regs fiq_pt_regs;
337 
sip_fiq_debugger_is_enabled(void)338 int sip_fiq_debugger_is_enabled(void)
339 {
340 	return fiq_sip_enabled;
341 }
342 EXPORT_SYMBOL_GPL(sip_fiq_debugger_is_enabled);
343 
sip_fiq_debugger_get_pt_regs(void * reg_base,unsigned long sp_el1)344 static void sip_fiq_debugger_get_pt_regs(void *reg_base,
345 					 unsigned long sp_el1)
346 {
347 	__maybe_unused struct sm_nsec_ctx *nsec_ctx = reg_base;
348 	__maybe_unused struct gp_regs_ctx *gp_regs = reg_base;
349 
350 #ifdef CONFIG_ARM64
351 	/*
352 	 * 64-bit ATF + 64-bit kernel
353 	 */
354 	/* copy cpu context: x0 ~ spsr_el3 */
355 	memcpy(&fiq_pt_regs, reg_base, 8 * 31);
356 
357 	/* copy pstate: spsr_el3 */
358 	memcpy(&fiq_pt_regs.pstate, reg_base + 0x110, 8);
359 	fiq_pt_regs.sp = sp_el1;
360 
361 	/* copy pc: elr_el3 */
362 	memcpy(&fiq_pt_regs.pc, reg_base + 0x118, 8);
363 #else
364 	if (firmware_64_32bit == FIRMWARE_ATF_64BIT) {
365 		/*
366 		 * 64-bit ATF + 32-bit kernel
367 		 */
368 		fiq_pt_regs.ARM_r0 = gp_regs->x0;
369 		fiq_pt_regs.ARM_r1 = gp_regs->x1;
370 		fiq_pt_regs.ARM_r2 = gp_regs->x2;
371 		fiq_pt_regs.ARM_r3 = gp_regs->x3;
372 		fiq_pt_regs.ARM_r4 = gp_regs->x4;
373 		fiq_pt_regs.ARM_r5 = gp_regs->x5;
374 		fiq_pt_regs.ARM_r6 = gp_regs->x6;
375 		fiq_pt_regs.ARM_r7 = gp_regs->x7;
376 		fiq_pt_regs.ARM_r8 = gp_regs->x8;
377 		fiq_pt_regs.ARM_r9 = gp_regs->x9;
378 		fiq_pt_regs.ARM_r10 = gp_regs->x10;
379 		fiq_pt_regs.ARM_fp = gp_regs->x11;
380 		fiq_pt_regs.ARM_ip = gp_regs->x12;
381 		fiq_pt_regs.ARM_sp = gp_regs->x19;	/* aarch32 svc_r13 */
382 		fiq_pt_regs.ARM_lr = gp_regs->x18;	/* aarch32 svc_r14 */
383 		fiq_pt_regs.ARM_cpsr = gp_regs->spsr_el3;
384 		fiq_pt_regs.ARM_pc = gp_regs->elr_el3;
385 	} else {
386 		/*
387 		 * 32-bit tee firmware + 32-bit kernel
388 		 */
389 		fiq_pt_regs.ARM_r0 = nsec_ctx->r0;
390 		fiq_pt_regs.ARM_r1 = nsec_ctx->r1;
391 		fiq_pt_regs.ARM_r2 = nsec_ctx->r2;
392 		fiq_pt_regs.ARM_r3 = nsec_ctx->r3;
393 		fiq_pt_regs.ARM_r4 = nsec_ctx->r4;
394 		fiq_pt_regs.ARM_r5 = nsec_ctx->r5;
395 		fiq_pt_regs.ARM_r6 = nsec_ctx->r6;
396 		fiq_pt_regs.ARM_r7 = nsec_ctx->r7;
397 		fiq_pt_regs.ARM_r8 = nsec_ctx->r8;
398 		fiq_pt_regs.ARM_r9 = nsec_ctx->r9;
399 		fiq_pt_regs.ARM_r10 = nsec_ctx->r10;
400 		fiq_pt_regs.ARM_fp = nsec_ctx->r11;
401 		fiq_pt_regs.ARM_ip = nsec_ctx->r12;
402 		fiq_pt_regs.ARM_sp = nsec_ctx->svc_sp;
403 		fiq_pt_regs.ARM_lr = nsec_ctx->svc_lr;
404 		fiq_pt_regs.ARM_cpsr = nsec_ctx->mon_spsr;
405 
406 		/*
407 		 * 'nsec_ctx->mon_lr' is not the fiq break point's PC, because it will
408 		 * be override as 'psci_fiq_debugger_uart_irq_tf_cb' for optee-os to
409 		 * jump to fiq_debugger handler.
410 		 *
411 		 * As 'nsec_ctx->und_lr' is not used for kernel, so optee-os uses it to
412 		 * deliver fiq break point's PC.
413 		 *
414 		 */
415 		fiq_pt_regs.ARM_pc = nsec_ctx->und_lr;
416 	}
417 #endif
418 }
419 
sip_fiq_debugger_uart_irq_tf_cb(unsigned long sp_el1,unsigned long offset,unsigned long cpu)420 static void sip_fiq_debugger_uart_irq_tf_cb(unsigned long sp_el1,
421 					    unsigned long offset,
422 					    unsigned long cpu)
423 {
424 	char *cpu_context;
425 
426 	/* calling fiq handler */
427 	if (ft_fiq_mem_base) {
428 		cpu_context = (char *)ft_fiq_mem_base + offset;
429 		sip_fiq_debugger_get_pt_regs(cpu_context, sp_el1);
430 		sip_fiq_debugger_uart_irq_tf(&fiq_pt_regs, cpu);
431 	}
432 
433 	/* fiq handler done, return to EL3(then EL3 return to EL1 entry) */
434 	__invoke_sip_fn_smc(SIP_UARTDBG_FN, 0, 0, UARTDBG_CFG_OSHDL_TO_OS);
435 }
436 
sip_fiq_debugger_uart_irq_tf_init(u32 irq_id,sip_fiq_debugger_uart_irq_tf_cb_t callback_fn)437 int sip_fiq_debugger_uart_irq_tf_init(u32 irq_id, sip_fiq_debugger_uart_irq_tf_cb_t callback_fn)
438 {
439 	struct arm_smccc_res res;
440 
441 	fiq_target_cpu = 0;
442 
443 	/* init fiq debugger callback */
444 	sip_fiq_debugger_uart_irq_tf = callback_fn;
445 	res = __invoke_sip_fn_smc(SIP_UARTDBG_FN, irq_id,
446 				  (unsigned long)sip_fiq_debugger_uart_irq_tf_cb,
447 				  UARTDBG_CFG_INIT);
448 	if (IS_SIP_ERROR(res.a0)) {
449 		pr_err("%s error: %d\n", __func__, (int)res.a0);
450 		return res.a0;
451 	}
452 
453 	/* share memory ioremap */
454 	if (!ft_fiq_mem_base) {
455 		ft_fiq_mem_phy = res.a1;
456 		ft_fiq_mem_base = sip_map(ft_fiq_mem_phy,
457 					  FIQ_UARTDBG_SHARE_MEM_SIZE);
458 		if (!ft_fiq_mem_base) {
459 			pr_err("%s: share memory ioremap failed\n", __func__);
460 			return -ENOMEM;
461 		}
462 	}
463 
464 	fiq_sip_enabled = 1;
465 
466 	return SIP_RET_SUCCESS;
467 }
468 EXPORT_SYMBOL_GPL(sip_fiq_debugger_uart_irq_tf_init);
469 
cpu_logical_map_mpidr(u32 cpu)470 static ulong cpu_logical_map_mpidr(u32 cpu)
471 {
472 #ifdef MODULE
473 	/* Empirically, local "cpu_logical_map()" for rockchip platforms */
474 	ulong mpidr = read_cpuid_mpidr();
475 
476 	if (mpidr & MPIDR_MT_BITMASK) {
477 		/* 0x100, 0x200, 0x300, 0x400 ... */
478 		mpidr = (cpu & 0xff) << 8;
479 	} else {
480 		if (cpu < 4)
481 			/* 0x00, 0x01, 0x02, 0x03 */
482 			mpidr = cpu;
483 		else if (cpu < 8)
484 			/* 0x100, 0x101, 0x102, 0x103 */
485 			mpidr = 0x100 | (cpu - 4);
486 		else
487 			pr_err("Unsupported map cpu: %d\n", cpu);
488 	}
489 
490 	return mpidr;
491 #else
492 	return cpu_logical_map(cpu);
493 #endif
494 }
495 
sip_cpu_logical_map_mpidr(u32 cpu)496 ulong sip_cpu_logical_map_mpidr(u32 cpu)
497 {
498 	return cpu_logical_map_mpidr(cpu);
499 }
500 EXPORT_SYMBOL_GPL(sip_cpu_logical_map_mpidr);
501 
sip_fiq_debugger_switch_cpu(u32 cpu)502 int sip_fiq_debugger_switch_cpu(u32 cpu)
503 {
504 	struct arm_smccc_res res;
505 
506 	fiq_target_cpu = cpu;
507 	res = __invoke_sip_fn_smc(SIP_UARTDBG_FN, cpu_logical_map_mpidr(cpu),
508 				  0, UARTDBG_CFG_OSHDL_CPUSW);
509 	return res.a0;
510 }
511 
sip_fiq_debugger_sdei_switch_cpu(u32 cur_cpu,u32 target_cpu,u32 flag)512 int sip_fiq_debugger_sdei_switch_cpu(u32 cur_cpu, u32 target_cpu, u32 flag)
513 {
514 	struct arm_smccc_res res;
515 
516 	res = __invoke_sip_fn_smc(SIP_SDEI_FIQ_DBG_SWITCH_CPU,
517 				  cur_cpu, target_cpu, flag);
518 	return res.a0;
519 }
520 
sip_fiq_debugger_sdei_get_event_id(u32 * fiq,u32 * sw_cpu,u32 * flag)521 int sip_fiq_debugger_sdei_get_event_id(u32 *fiq, u32 *sw_cpu, u32 *flag)
522 {
523 	struct arm_smccc_res res;
524 
525 	res = __invoke_sip_fn_smc(SIP_SDEI_FIQ_DBG_GET_EVENT_ID,
526 				  0, 0, 0);
527 	*fiq = res.a1;
528 	*sw_cpu = res.a2;
529 	if (flag)
530 		*flag = res.a3;
531 
532 	return res.a0;
533 }
534 
535 EXPORT_SYMBOL_GPL(sip_fiq_debugger_switch_cpu);
536 
sip_fiq_debugger_enable_debug(bool enable)537 void sip_fiq_debugger_enable_debug(bool enable)
538 {
539 	unsigned long val;
540 
541 	val = enable ? UARTDBG_CFG_OSHDL_DEBUG_ENABLE :
542 		       UARTDBG_CFG_OSHDL_DEBUG_DISABLE;
543 
544 	__invoke_sip_fn_smc(SIP_UARTDBG_FN, 0, 0, val);
545 }
546 EXPORT_SYMBOL_GPL(sip_fiq_debugger_enable_debug);
547 
sip_fiq_debugger_set_print_port(u32 port_phyaddr,u32 baudrate)548 int sip_fiq_debugger_set_print_port(u32 port_phyaddr, u32 baudrate)
549 {
550 	struct arm_smccc_res res;
551 
552 	res = __invoke_sip_fn_smc(SIP_UARTDBG_FN, port_phyaddr, baudrate,
553 				  UARTDBG_CFG_PRINT_PORT);
554 	return res.a0;
555 }
556 EXPORT_SYMBOL_GPL(sip_fiq_debugger_set_print_port);
557 
sip_fiq_debugger_request_share_memory(void)558 int sip_fiq_debugger_request_share_memory(void)
559 {
560 	struct arm_smccc_res res;
561 
562 	/* request page share memory */
563 	res = sip_smc_request_share_mem(FIQ_UARTDBG_PAGE_NUMS,
564 					SHARE_PAGE_TYPE_UARTDBG);
565 	if (IS_SIP_ERROR(res.a0))
566 		return res.a0;
567 
568 	return SIP_RET_SUCCESS;
569 }
570 EXPORT_SYMBOL_GPL(sip_fiq_debugger_request_share_memory);
571 
sip_fiq_debugger_get_target_cpu(void)572 int sip_fiq_debugger_get_target_cpu(void)
573 {
574 	return fiq_target_cpu;
575 }
576 EXPORT_SYMBOL_GPL(sip_fiq_debugger_get_target_cpu);
577 
sip_fiq_debugger_enable_fiq(bool enable,uint32_t tgt_cpu)578 void sip_fiq_debugger_enable_fiq(bool enable, uint32_t tgt_cpu)
579 {
580 	u32 en;
581 
582 	fiq_target_cpu = tgt_cpu;
583 	en = enable ? UARTDBG_CFG_FIQ_ENABEL : UARTDBG_CFG_FIQ_DISABEL;
584 	__invoke_sip_fn_smc(SIP_UARTDBG_FN, tgt_cpu, 0, en);
585 }
586 EXPORT_SYMBOL_GPL(sip_fiq_debugger_enable_fiq);
587 
sip_fiq_control(u32 sub_func,u32 irq,unsigned long data)588 int sip_fiq_control(u32 sub_func, u32 irq, unsigned long data)
589 {
590 	struct arm_smccc_res res;
591 
592 	res = __invoke_sip_fn_smc(RK_SIP_FIQ_CTRL,
593 				  sub_func, irq, data);
594 	return res.a0;
595 }
596 EXPORT_SYMBOL_GPL(sip_fiq_control);
597 
sip_wdt_config(u32 sub_func,u32 arg1,u32 arg2,u32 arg3)598 int sip_wdt_config(u32 sub_func, u32 arg1, u32 arg2, u32 arg3)
599 {
600 	struct arm_smccc_res res;
601 
602 	arm_smccc_smc(SIP_WDT_CFG, sub_func, arg1, arg2, arg3,
603 		      0, 0, 0, &res);
604 
605 	return res.a0;
606 }
607 EXPORT_SYMBOL_GPL(sip_wdt_config);
608 
sip_hdmirx_config(u32 sub_func,u32 arg1,u32 arg2,u32 arg3)609 int sip_hdmirx_config(u32 sub_func, u32 arg1, u32 arg2, u32 arg3)
610 {
611 	struct arm_smccc_res res;
612 
613 	arm_smccc_smc(SIP_HDMIRX_CFG, sub_func, arg1, arg2, arg3,
614 		      0, 0, 0, &res);
615 
616 	return res.a0;
617 }
618 EXPORT_SYMBOL_GPL(sip_hdmirx_config);
619 
sip_hdcpkey_init(u32 hdcp_id)620 int sip_hdcpkey_init(u32 hdcp_id)
621 {
622 	struct arm_smccc_res res;
623 
624 	res = __invoke_sip_fn_smc(TRUSTED_OS_HDCPKEY_INIT, hdcp_id, 0, 0);
625 
626 	return res.a0;
627 }
628 EXPORT_SYMBOL_GPL(sip_hdcpkey_init);
629 
sip_smc_mcu_config(unsigned long mcu_id,unsigned long func,unsigned long arg2)630 int sip_smc_mcu_config(unsigned long mcu_id,
631 		       unsigned long func,
632 		       unsigned long arg2)
633 {
634 	struct arm_smccc_res res;
635 
636 	res = __invoke_sip_fn_smc(SIP_MCU_CFG, mcu_id, func, arg2);
637 	return res.a0;
638 }
639 EXPORT_SYMBOL_GPL(sip_smc_mcu_config);
640 /******************************************************************************/
641 #ifdef CONFIG_ARM
sip_firmware_init(void)642 static __init int sip_firmware_init(void)
643 {
644 	struct arm_smccc_res res;
645 
646 	if (!psci_smp_available())
647 		return 0;
648 
649 	/*
650 	 * OP-TEE works on kernel 3.10 and 4.4 and we have different sip
651 	 * implement. We should tell OP-TEE the current rockchip sip version.
652 	 */
653 	res = __invoke_sip_fn_smc(SIP_SIP_VERSION, SIP_IMPLEMENT_V2,
654 				  SECURE_REG_WR, 0);
655 	if (IS_SIP_ERROR(res.a0))
656 		pr_err("%s: set rockchip sip version v2 failed\n", __func__);
657 
658 	/*
659 	 * Currently, we support:
660 	 *
661 	 *	1. 64-bit ATF + 64-bit kernel;
662 	 *	2. 64-bit ATF + 32-bit kernel;
663 	 *	3. 32-bit TEE + 32-bit kernel;
664 	 *
665 	 * We need to detect which case of above and record in firmware_64_32bit
666 	 * We get info from cpuid and compare with all supported ARMv7 cpu.
667 	 */
668 	switch (read_cpuid_part()) {
669 	case ARM_CPU_PART_CORTEX_A7:
670 	case ARM_CPU_PART_CORTEX_A8:
671 	case ARM_CPU_PART_CORTEX_A9:
672 	case ARM_CPU_PART_CORTEX_A12:
673 	case ARM_CPU_PART_CORTEX_A15:
674 	case ARM_CPU_PART_CORTEX_A17:
675 		firmware_64_32bit = FIRMWARE_TEE_32BIT;
676 		break;
677 	default:
678 		firmware_64_32bit = FIRMWARE_ATF_64BIT;
679 		break;
680 	}
681 
682 	return 0;
683 }
684 arch_initcall(sip_firmware_init);
685 #endif
686 
687 MODULE_DESCRIPTION("Rockchip SIP Call");
688 MODULE_LICENSE("GPL");
689