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.
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.
11 * Copyright (C) 2016, Fuzhou Rockchip Electronics Co., Ltd
14 #include <linux/arm-smccc.h>
16 #include <linux/rockchip/rockchip_sip.h>
17 #include <asm/cputype.h>
18 #include <asm/smp_plat.h>
19 #include <uapi/linux/psci.h>
21 #define SIZE_PAGE(n) ((n) << 12)
23 static struct arm_smccc_res __invoke_sip_fn_smc(unsigned long function_id,
28 struct arm_smccc_res res;
30 arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
34 struct arm_smccc_res sip_smc_ddr_cfg(u32 arg0, u32 arg1,
37 return __invoke_sip_fn_smc(SIP_DDR_CFG32, arg0, arg1, arg2);
40 struct arm_smccc_res sip_smc_get_atf_version(void)
42 return __invoke_sip_fn_smc(SIP_ATF_VERSION32, 0, 0, 0);
45 struct arm_smccc_res sip_smc_get_sip_version(void)
47 return __invoke_sip_fn_smc(SIP_SIP_VERSION32, 0, 0, 0);
50 int sip_smc_set_suspend_mode(u32 ctrl,
54 struct arm_smccc_res res;
56 res = __invoke_sip_fn_smc(SIP_SUSPEND_MODE32, ctrl,
62 static u64 ft_fiq_mem_phy;
63 static void __iomem *ft_fiq_mem_base;
64 static void (*psci_fiq_debugger_uart_irq_tf)(void *reg_base, u64 sp_el1);
65 static u32 fig_init_flag;
67 u32 rockchip_psci_smc_get_tf_ver(void)
69 struct arm_smccc_res res;
71 arm_smccc_smc(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0, 0, 0, 0, 0, &res);
75 void psci_fiq_debugger_uart_irq_tf_cb(u64 sp_el1, u64 offset)
77 psci_fiq_debugger_uart_irq_tf((char *)ft_fiq_mem_base + offset, sp_el1);
78 __invoke_sip_fn_smc(PSCI_SIP_UARTDBG_CFG64, 0, 0,
79 UARTDBG_CFG_OSHDL_TO_OS);
82 void psci_fiq_debugger_uart_irq_tf_init(u32 irq_id, void *callback)
84 struct arm_smccc_res sip_smmc;
86 psci_fiq_debugger_uart_irq_tf = callback;
87 sip_smmc = __invoke_sip_fn_smc(PSCI_SIP_UARTDBG_CFG64, irq_id,
88 (u64)psci_fiq_debugger_uart_irq_tf_cb,
90 ft_fiq_mem_phy = sip_smmc.a0;
91 ft_fiq_mem_base = ioremap(ft_fiq_mem_phy, 8 * 1024);
95 void psci_enable_fiq(void)
100 if (fig_init_flag != 1)
102 irq_flag = *((char *)(ft_fiq_mem_base) + 8 * 1024 - 0x04);
104 cpu_id = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
105 if ((irq_flag == 0xAA) && (cpu_id == 0))
106 __invoke_sip_fn_smc(RK_SIP_ENABLE_FIQ, 0, 0, 0);
109 u32 psci_fiq_debugger_switch_cpu(u32 cpu)
111 struct arm_smccc_res sip_smmc;
113 sip_smmc = __invoke_sip_fn_smc(PSCI_SIP_UARTDBG_CFG64,
114 cpu_logical_map(cpu),
115 0, UARTDBG_CFG_OSHDL_CPUSW);
119 void psci_fiq_debugger_enable_debug(bool val)
122 __invoke_sip_fn_smc(PSCI_SIP_UARTDBG_CFG64, 0,
123 0, UARTDBG_CFG_OSHDL_DEBUG_ENABLE);
125 __invoke_sip_fn_smc(PSCI_SIP_UARTDBG_CFG64, 0,
126 0, UARTDBG_CFG_OSHDL_DEBUG_DISABLE);
129 int psci_fiq_debugger_set_print_port(u32 port, u32 baudrate)
131 struct arm_smccc_res res;
133 res = __invoke_sip_fn_smc(PSCI_SIP_UARTDBG_CFG64, port, baudrate,
134 UARTDBG_CFG_PRINT_PORT);
138 struct arm_smccc_res sip_smc_get_share_mem_page(u32 page_num,
139 share_page_type_t page_type)
141 struct arm_smccc_res res;
142 unsigned long share_mem_phy;
144 res = __invoke_sip_fn_smc(SIP_SHARE_MEM32, page_num, page_type, 0);
148 share_mem_phy = res.a1;
149 res.a1 = (unsigned long)ioremap(share_mem_phy, SIZE_PAGE(page_num));
155 struct arm_smccc_res sip_smc_get_call_count(void)
157 return __invoke_sip_fn_smc(SIP_SVC_CALL_COUNT, 0, 0, 0);