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, unsigned long arg0, unsigned long arg1,
38                                               unsigned long arg2)
39 {
40     struct arm_smccc_res res;
41 
42     arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
43     return res;
44 }
45 
sip_smc_dram(u32 arg0, u32 arg1, u32 arg2)46 struct arm_smccc_res sip_smc_dram(u32 arg0, u32 arg1, u32 arg2)
47 {
48     return invoke_sip_fn_smc(SIP_DRAM_CONFIG, arg0, arg1, arg2);
49 }
50 EXPORT_SYMBOL_GPL(sip_smc_dram);
51 
sip_smc_get_atf_version(void)52 struct arm_smccc_res sip_smc_get_atf_version(void)
53 {
54     return invoke_sip_fn_smc(SIP_ATF_VERSION, 0, 0, 0);
55 }
56 EXPORT_SYMBOL_GPL(sip_smc_get_atf_version);
57 
sip_smc_get_sip_version(void)58 struct arm_smccc_res sip_smc_get_sip_version(void)
59 {
60     return invoke_sip_fn_smc(SIP_SIP_VERSION, 0, 0, 0);
61 }
62 EXPORT_SYMBOL_GPL(sip_smc_get_sip_version);
63 
sip_smc_set_suspend_mode(u32 ctrl, u32 config1, u32 config2)64 int sip_smc_set_suspend_mode(u32 ctrl, u32 config1, u32 config2)
65 {
66     struct arm_smccc_res res;
67 
68     res = invoke_sip_fn_smc(SIP_SUSPEND_MODE, ctrl, config1, config2);
69     return res.a0;
70 }
71 EXPORT_SYMBOL_GPL(sip_smc_set_suspend_mode);
72 
sip_smc_get_suspend_info(u32 info)73 struct arm_smccc_res sip_smc_get_suspend_info(u32 info)
74 {
75     struct arm_smccc_res res;
76 
77     res = invoke_sip_fn_smc(SIP_SUSPEND_MODE, info, 0, 0);
78     return res;
79 }
80 EXPORT_SYMBOL_GPL(sip_smc_get_suspend_info);
81 
sip_smc_virtual_poweroff(void)82 int sip_smc_virtual_poweroff(void)
83 {
84     struct arm_smccc_res res;
85 
86     res = invoke_sip_fn_smc(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND), 0, 0, 0);
87     return res.a0;
88 }
89 EXPORT_SYMBOL_GPL(sip_smc_virtual_poweroff);
90 
sip_smc_remotectl_config(u32 func, u32 data)91 int sip_smc_remotectl_config(u32 func, u32 data)
92 {
93     struct arm_smccc_res res;
94 
95     res = invoke_sip_fn_smc(SIP_REMOTECTL_CFG, func, data, 0);
96 
97     return res.a0;
98 }
99 EXPORT_SYMBOL_GPL(sip_smc_remotectl_config);
100 
sip_smc_secure_reg_read(u32 addr_phy)101 u32 sip_smc_secure_reg_read(u32 addr_phy)
102 {
103     struct arm_smccc_res res;
104 
105     res = invoke_sip_fn_smc(SIP_ACCESS_REG, 0, addr_phy, SECURE_REG_RD);
106     if (res.a0) {
107         pr_err("%s error: %d, addr phy: 0x%x\n", __func__, (int)res.a0, addr_phy);
108     }
109 
110     return res.a1;
111 }
112 EXPORT_SYMBOL_GPL(sip_smc_secure_reg_read);
113 
sip_smc_secure_reg_write(u32 addr_phy, u32 val)114 int sip_smc_secure_reg_write(u32 addr_phy, u32 val)
115 {
116     struct arm_smccc_res res;
117 
118     res = invoke_sip_fn_smc(SIP_ACCESS_REG, val, addr_phy, SECURE_REG_WR);
119     if (res.a0) {
120         pr_err("%s error: %d, addr phy: 0x%x\n", __func__, (int)res.a0, addr_phy);
121     }
122 
123     return res.a0;
124 }
125 EXPORT_SYMBOL_GPL(sip_smc_secure_reg_write);
126 
sip_map(phys_addr_t start, size_t size)127 static void *sip_map(phys_addr_t start, size_t size)
128 {
129     struct page **pages;
130     phys_addr_t page_start;
131     unsigned int page_count;
132     pgprot_t prot;
133     unsigned int i;
134     void *vaddr;
135 
136     if (!pfn_valid(__phys_to_pfn(start))) {
137         return ioremap(start, size);
138     }
139 
140     page_start = start - offset_in_page(start);
141     page_count = DIV_ROUND_UP(size + offset_in_page(start), PAGE_SIZE);
142 
143     prot = pgprot_noncached(PAGE_KERNEL);
144 
145     pages = kmalloc_array(page_count, sizeof(struct page *), GFP_KERNEL);
146     if (!pages) {
147         pr_err("%s: Failed to allocate array for %u pages\n", __func__, page_count);
148         return NULL;
149     }
150 
151     for (i = 0; i < page_count; i++) {
152         pages[i] = phys_to_page(page_start + i * PAGE_SIZE);
153     }
154 
155     vaddr = vmap(pages, page_count, VM_MAP, prot);
156     kfree(pages);
157 
158     /*
159      * Since vmap() uses page granularity, we must add the offset
160      * into the page here, to get the byte granularity address
161      * into the mapping to represent the actual "start" location.
162      */
163     return vaddr + offset_in_page(start);
164 }
165 
sip_smc_request_share_mem(u32 page_num, share_page_type_t page_type)166 struct arm_smccc_res sip_smc_request_share_mem(u32 page_num, share_page_type_t page_type)
167 {
168     struct arm_smccc_res res;
169     unsigned long share_mem_phy;
170 
171     res = invoke_sip_fn_smc(SIP_SHARE_MEM, page_num, page_type, 0);
172     if (IS_SIP_ERROR(res.a0)) {
173         goto error;
174     }
175 
176     share_mem_phy = res.a1;
177     res.a1 = (unsigned long)sip_map(share_mem_phy, SIZE_PAGE(page_num));
178 
179 error:
180     return res;
181 }
182 EXPORT_SYMBOL_GPL(sip_smc_request_share_mem);
183 
sip_smc_mcu_el3fiq(u32 arg0, u32 arg1, u32 arg2)184 struct arm_smccc_res sip_smc_mcu_el3fiq(u32 arg0, u32 arg1, u32 arg2)
185 {
186     return invoke_sip_fn_smc(SIP_MCU_EL3FIQ_CFG, arg0, arg1, arg2);
187 }
188 EXPORT_SYMBOL_GPL(sip_smc_mcu_el3fiq);
189 
sip_smc_vpu_reset(u32 arg0, u32 arg1, u32 arg2)190 struct arm_smccc_res sip_smc_vpu_reset(u32 arg0, u32 arg1, u32 arg2)
191 {
192     struct arm_smccc_res res;
193 
194     res = invoke_sip_fn_smc(PSCI_SIP_VPU_RESET, arg0, arg1, arg2);
195     return res;
196 }
197 EXPORT_SYMBOL_GPL(sip_smc_vpu_reset);
198 
sip_smc_bus_config(u32 arg0, u32 arg1, u32 arg2)199 struct arm_smccc_res sip_smc_bus_config(u32 arg0, u32 arg1, u32 arg2)
200 {
201     struct arm_smccc_res res;
202 
203     res = invoke_sip_fn_smc(SIP_BUS_CFG, arg0, arg1, arg2);
204     return res;
205 }
206 EXPORT_SYMBOL_GPL(sip_smc_bus_config);
207 
sip_smc_get_dram_map(void)208 struct dram_addrmap_info *sip_smc_get_dram_map(void)
209 {
210     struct arm_smccc_res res;
211     static struct dram_addrmap_info *map;
212 
213     if (map) {
214         return map;
215     }
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, ROCKCHIP_SIP_CONFIG_DRAM_ADDRMAP_GET);
227     if (res.a0) {
228         pr_err("rockchip_sip_config_dram_init error:%lx\n", res.a0);
229         map = NULL;
230         return NULL;
231     }
232 
233     return map;
234 }
235 EXPORT_SYMBOL_GPL(sip_smc_get_dram_map);
236 
sip_smc_lastlog_request(void)237 struct arm_smccc_res sip_smc_lastlog_request(void)
238 {
239     struct arm_smccc_res res;
240     void __iomem *addr1, *addr2;
241 
242     res = invoke_sip_fn_smc(SIP_LAST_LOG, local_clock(), 0, 0);
243     if (IS_SIP_ERROR(res.a0)) {
244         return res;
245     }
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 
267 /************************** fiq debugger **************************************/
268 /*
269  * AArch32 is not allowed to call SMC64(ATF framework does not support), so we
270  * don't change SIP_UARTDBG_FN to SIP_UARTDBG_CFG64 even when cpu is AArch32
271  * mode. Let ATF support SIP_UARTDBG_CFG, and we just initialize SIP_UARTDBG_FN
272  * depends on compile option(CONFIG_ARM or CONFIG_ARM64).
273  */
274 #ifdef CONFIG_ARM64
275 #define SIP_UARTDBG_FN SIP_UARTDBG_CFG64
276 #else
277 #define SIP_UARTDBG_FN SIP_UARTDBG_CFG
278 static int firmware_64_32bit;
279 #endif
280 
281 static int fiq_sip_enabled;
282 static int fiq_target_cpu;
283 static phys_addr_t ft_fiq_mem_phy;
284 static void __iomem *ft_fiq_mem_base;
285 static void (*sip_fiq_debugger_uart_irq_tf)(struct pt_regs _pt_regs, unsigned long cpu);
sip_fiq_debugger_is_enabled(void)286 int sip_fiq_debugger_is_enabled(void)
287 {
288     return fiq_sip_enabled;
289 }
290 EXPORT_SYMBOL_GPL(sip_fiq_debugger_is_enabled);
291 
sip_fiq_debugger_get_pt_regs(void *reg_base, unsigned long sp_el1)292 static struct pt_regs sip_fiq_debugger_get_pt_regs(void *reg_base, unsigned long sp_el1)
293 {
294     struct pt_regs fiq_pt_regs;
295     __maybe_unused struct sm_nsec_ctx *nsec_ctx = reg_base;
296     __maybe_unused struct gp_regs_ctx *gp_regs = reg_base;
297 
298 #ifdef CONFIG_ARM64
299     /*
300      * 64-bit ATF + 64-bit kernel
301      */
302     /* copy cpu context: x0 ~ spsr_el3 */
303     memcpy(&fiq_pt_regs, reg_base, 0xf8);
304 
305     /* copy pstate: spsr_el3 */
306     memcpy(&fiq_pt_regs.pstate, reg_base + 0x110, 0x8);
307     fiq_pt_regs.sp = sp_el1;
308 
309     /* copy pc: elr_el3 */
310     memcpy(&fiq_pt_regs.pc, reg_base + 0x118, 0x8);
311 #else
312     if (firmware_64_32bit == FIRMWARE_ATF_64BIT) {
313         /*
314          * 64-bit ATF + 32-bit kernel
315          */
316         fiq_pt_regs.ARM_r0 = gp_regs->x0;
317         fiq_pt_regs.ARM_r1 = gp_regs->x1;
318         fiq_pt_regs.ARM_r2 = gp_regs->x2;
319         fiq_pt_regs.ARM_r3 = gp_regs->x3;
320         fiq_pt_regs.ARM_r4 = gp_regs->x4;
321         fiq_pt_regs.ARM_r5 = gp_regs->x5;
322         fiq_pt_regs.ARM_r6 = gp_regs->x6;
323         fiq_pt_regs.ARM_r7 = gp_regs->x7;
324         fiq_pt_regs.ARM_r8 = gp_regs->x8;
325         fiq_pt_regs.ARM_r9 = gp_regs->x9;
326         fiq_pt_regs.ARM_r10 = gp_regs->x10;
327         fiq_pt_regs.ARM_fp = gp_regs->x11;
328         fiq_pt_regs.ARM_ip = gp_regs->x12;
329         fiq_pt_regs.ARM_sp = gp_regs->x19; /* aarch32 svc_r13 */
330         fiq_pt_regs.ARM_lr = gp_regs->x18; /* aarch32 svc_r14 */
331         fiq_pt_regs.ARM_cpsr = gp_regs->spsr_el3;
332         fiq_pt_regs.ARM_pc = gp_regs->elr_el3;
333     } else {
334         /*
335          * 32-bit tee firmware + 32-bit kernel
336          */
337         fiq_pt_regs.ARM_r0 = nsec_ctx->r0;
338         fiq_pt_regs.ARM_r1 = nsec_ctx->r1;
339         fiq_pt_regs.ARM_r2 = nsec_ctx->r2;
340         fiq_pt_regs.ARM_r3 = nsec_ctx->r3;
341         fiq_pt_regs.ARM_r4 = nsec_ctx->r4;
342         fiq_pt_regs.ARM_r5 = nsec_ctx->r5;
343         fiq_pt_regs.ARM_r6 = nsec_ctx->r6;
344         fiq_pt_regs.ARM_r7 = nsec_ctx->r7;
345         fiq_pt_regs.ARM_r8 = nsec_ctx->r8;
346         fiq_pt_regs.ARM_r9 = nsec_ctx->r9;
347         fiq_pt_regs.ARM_r10 = nsec_ctx->r10;
348         fiq_pt_regs.ARM_fp = nsec_ctx->r11;
349         fiq_pt_regs.ARM_ip = nsec_ctx->r12;
350         fiq_pt_regs.ARM_sp = nsec_ctx->svc_sp;
351         fiq_pt_regs.ARM_lr = nsec_ctx->svc_lr;
352         fiq_pt_regs.ARM_cpsr = nsec_ctx->mon_spsr;
353 
354         /*
355          * 'nsec_ctx->mon_lr' is not the fiq break point's PC, because it will
356          * be override as 'psci_fiq_debugger_uart_irq_tf_cb' for optee-os to
357          * jump to fiq_debugger handler.
358          *
359          * As 'nsec_ctx->und_lr' is not used for kernel, so optee-os uses it to
360          * deliver fiq break point's PC.
361          *
362          */
363         fiq_pt_regs.ARM_pc = nsec_ctx->und_lr;
364     }
365 #endif
366 
367     return fiq_pt_regs;
368 }
369 
sip_fiq_debugger_uart_irq_tf_cb(unsigned long sp_el1, unsigned long offset, unsigned long cpu)370 static void sip_fiq_debugger_uart_irq_tf_cb(unsigned long sp_el1, unsigned long offset, unsigned long cpu)
371 {
372     struct pt_regs fiq_pt_regs;
373     char *cpu_context;
374 
375     /* calling fiq handler */
376     if (ft_fiq_mem_base) {
377         cpu_context = (char *)ft_fiq_mem_base + offset;
378         fiq_pt_regs = sip_fiq_debugger_get_pt_regs(cpu_context, sp_el1);
379         sip_fiq_debugger_uart_irq_tf(fiq_pt_regs, cpu);
380     }
381 
382     /* fiq handler done, return to EL3(then EL3 return to EL1 entry) */
383     invoke_sip_fn_smc(SIP_UARTDBG_FN, 0, 0, UARTDBG_CFG_OSHDL_TO_OS);
384 }
385 
sip_fiq_debugger_uart_irq_tf_init(u32 irq_id, void *callback_fn)386 int sip_fiq_debugger_uart_irq_tf_init(u32 irq_id, void *callback_fn)
387 {
388     struct arm_smccc_res res;
389 
390     fiq_target_cpu = 0;
391 
392     /* init fiq debugger callback */
393     sip_fiq_debugger_uart_irq_tf = callback_fn;
394     res = invoke_sip_fn_smc(SIP_UARTDBG_FN, irq_id, (unsigned long)sip_fiq_debugger_uart_irq_tf_cb, UARTDBG_CFG_INIT);
395     if (IS_SIP_ERROR(res.a0)) {
396         pr_err("%s error: %d\n", __func__, (int)res.a0);
397         return res.a0;
398     }
399 
400     /* share memory ioremap */
401     if (!ft_fiq_mem_base) {
402         ft_fiq_mem_phy = res.a1;
403         ft_fiq_mem_base = sip_map(ft_fiq_mem_phy, FIQ_UARTDBG_SHARE_MEM_SIZE);
404         if (!ft_fiq_mem_base) {
405             pr_err("%s: share memory ioremap failed\n", __func__);
406             return -ENOMEM;
407         }
408     }
409 
410     fiq_sip_enabled = 1;
411 
412     return SIP_RET_SUCCESS;
413 }
414 EXPORT_SYMBOL_GPL(sip_fiq_debugger_uart_irq_tf_init);
415 
cpu_logical_map_mpidr(u32 cpu)416 static ulong cpu_logical_map_mpidr(u32 cpu)
417 {
418 #ifdef MODULE
419     /* Empirically, local "cpu_logical_map()" for rockchip platforms */
420     ulong mpidr = 0x00;
421 
422     if (cpu < 0x4) {
423         /* 0x00, 0x01, 0x02, 0x03 */
424         mpidr = cpu;
425     } else if (cpu < 0x8) {
426         /* 0x100, 0x101, 0x102, 0x103 */
427         mpidr = 0x100 | (cpu - 0x4);
428     } else {
429         pr_err("Unsupported map cpu: %d\n", cpu);
430     }
431 
432     return mpidr;
433 #else
434     return cpu_logical_map(cpu);
435 #endif
436 }
437 
sip_fiq_debugger_switch_cpu(u32 cpu)438 int sip_fiq_debugger_switch_cpu(u32 cpu)
439 {
440     struct arm_smccc_res res;
441 
442     fiq_target_cpu = cpu;
443     res = invoke_sip_fn_smc(SIP_UARTDBG_FN, cpu_logical_map_mpidr(cpu), 0, UARTDBG_CFG_OSHDL_CPUSW);
444     return res.a0;
445 }
446 
sip_fiq_debugger_sdei_switch_cpu(u32 cur_cpu, u32 target_cpu, u32 flag)447 int sip_fiq_debugger_sdei_switch_cpu(u32 cur_cpu, u32 target_cpu, u32 flag)
448 {
449     struct arm_smccc_res res;
450 
451     res = invoke_sip_fn_smc(SIP_SDEI_FIQ_DBG_SWITCH_CPU, cur_cpu, target_cpu, flag);
452     return res.a0;
453 }
454 
sip_fiq_debugger_sdei_get_event_id(u32 *fiq, u32 *sw_cpu, u32 *flag)455 int sip_fiq_debugger_sdei_get_event_id(u32 *fiq, u32 *sw_cpu, u32 *flag)
456 {
457     struct arm_smccc_res res;
458 
459     res = invoke_sip_fn_smc(SIP_SDEI_FIQ_DBG_GET_EVENT_ID, 0, 0, 0);
460     *fiq = res.a1;
461     *sw_cpu = res.a2;
462     if (flag) {
463         *flag = res.a3;
464     }
465 
466     return res.a0;
467 }
468 
469 EXPORT_SYMBOL_GPL(sip_fiq_debugger_switch_cpu);
470 
sip_fiq_debugger_enable_debug(bool enable)471 void sip_fiq_debugger_enable_debug(bool enable)
472 {
473     unsigned long val;
474 
475     val = enable ? UARTDBG_CFG_OSHDL_DEBUG_ENABLE : UARTDBG_CFG_OSHDL_DEBUG_DISABLE;
476 
477     invoke_sip_fn_smc(SIP_UARTDBG_FN, 0, 0, val);
478 }
479 EXPORT_SYMBOL_GPL(sip_fiq_debugger_enable_debug);
480 
sip_fiq_debugger_set_print_port(u32 port_phyaddr, u32 baudrate)481 int sip_fiq_debugger_set_print_port(u32 port_phyaddr, u32 baudrate)
482 {
483     struct arm_smccc_res res;
484 
485     res = invoke_sip_fn_smc(SIP_UARTDBG_FN, port_phyaddr, baudrate, UARTDBG_CFG_PRINT_PORT);
486     return res.a0;
487 }
488 EXPORT_SYMBOL_GPL(sip_fiq_debugger_set_print_port);
489 
sip_fiq_debugger_request_share_memory(void)490 int sip_fiq_debugger_request_share_memory(void)
491 {
492     struct arm_smccc_res res;
493 
494     /* request page share memory */
495     res = sip_smc_request_share_mem(FIQ_UARTDBG_PAGE_NUMS, SHARE_PAGE_TYPE_UARTDBG);
496     if (IS_SIP_ERROR(res.a0)) {
497         return res.a0;
498     }
499 
500     return SIP_RET_SUCCESS;
501 }
502 EXPORT_SYMBOL_GPL(sip_fiq_debugger_request_share_memory);
503 
sip_fiq_debugger_get_target_cpu(void)504 int sip_fiq_debugger_get_target_cpu(void)
505 {
506     return fiq_target_cpu;
507 }
508 EXPORT_SYMBOL_GPL(sip_fiq_debugger_get_target_cpu);
509 
sip_fiq_debugger_enable_fiq(bool enable, uint32_t tgt_cpu)510 void sip_fiq_debugger_enable_fiq(bool enable, uint32_t tgt_cpu)
511 {
512     u32 en;
513 
514     fiq_target_cpu = tgt_cpu;
515     en = enable ? UARTDBG_CFG_FIQ_ENABEL : UARTDBG_CFG_FIQ_DISABEL;
516     invoke_sip_fn_smc(SIP_UARTDBG_FN, tgt_cpu, 0, en);
517 }
518 EXPORT_SYMBOL_GPL(sip_fiq_debugger_enable_fiq);
519 
520 /******************************************************************************/
521 #ifdef CONFIG_ARM
sip_firmware_init(void)522 static __init int sip_firmware_init(void)
523 {
524     struct arm_smccc_res res;
525 
526     if (!psci_smp_available()) {
527         return 0;
528     }
529 
530     /*
531      * OP-TEE works on kernel 3.10 and 4.4 and we have different sip
532      * implement. We should tell OP-TEE the current rockchip sip version.
533      */
534     res = invoke_sip_fn_smc(SIP_SIP_VERSION, SIP_IMPLEMENT_V2, SECURE_REG_WR, 0);
535     if (IS_SIP_ERROR(res.a0)) {
536         pr_err("%s: set rockchip sip version v2 failed\n", __func__);
537     }
538 
539     /*
540      * Currently, we support:
541      *
542      *    1. 64-bit ATF + 64-bit kernel;
543      *    2. 64-bit ATF + 32-bit kernel;
544      *    3. 32-bit TEE + 32-bit kernel;
545      *
546      * We need to detect which case of above and record in firmware_64_32bit
547      * We get info from cpuid and compare with all supported ARMv7 cpu.
548      */
549     switch (read_cpuid_part()) {
550         case ARM_CPU_PART_CORTEX_A7:
551         case ARM_CPU_PART_CORTEX_A8:
552         case ARM_CPU_PART_CORTEX_A9:
553         case ARM_CPU_PART_CORTEX_A12:
554         case ARM_CPU_PART_CORTEX_A15:
555         case ARM_CPU_PART_CORTEX_A17:
556             firmware_64_32bit = FIRMWARE_TEE_32BIT;
557             break;
558         default:
559             firmware_64_32bit = FIRMWARE_ATF_64BIT;
560             break;
561     }
562 
563     return 0;
564 }
565 arch_initcall(sip_firmware_init);
566 #endif
567 
568 MODULE_DESCRIPTION("Rockchip SIP Call");
569 MODULE_LICENSE("GPL");
570