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(uint32_t arg0, uint32_t 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(uint32_t mode)
52 struct arm_smccc_res res;
54 res = __invoke_sip_fn_smc(SIP_SUSPEND_MODE32, mode, 0, 0);
59 static u64 ft_fiq_mem_phy;
60 static void __iomem *ft_fiq_mem_base;
61 static void (*psci_fiq_debugger_uart_irq_tf)(void *reg_base, u64 sp_el1);
62 static u32 fig_init_flag;
64 u32 rockchip_psci_smc_get_tf_ver(void)
66 struct arm_smccc_res res;
68 arm_smccc_smc(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0, 0, 0, 0, 0, &res);
72 void psci_fiq_debugger_uart_irq_tf_cb(u64 sp_el1, u64 offset)
74 psci_fiq_debugger_uart_irq_tf((char *)ft_fiq_mem_base + offset, sp_el1);
75 __invoke_sip_fn_smc(PSCI_SIP_UARTDBG_CFG64, 0, 0,
76 UARTDBG_CFG_OSHDL_TO_OS);
79 void psci_fiq_debugger_uart_irq_tf_init(u32 irq_id, void *callback)
81 struct arm_smccc_res sip_smmc;
83 psci_fiq_debugger_uart_irq_tf = callback;
84 sip_smmc = __invoke_sip_fn_smc(PSCI_SIP_UARTDBG_CFG64, irq_id,
85 (u64)psci_fiq_debugger_uart_irq_tf_cb,
87 ft_fiq_mem_phy = sip_smmc.a0;
88 ft_fiq_mem_base = ioremap(ft_fiq_mem_phy, 8 * 1024);
92 void psci_enable_fiq(void)
97 if (fig_init_flag != 1)
99 irq_flag = *((char *)(ft_fiq_mem_base) + 8 * 1024 - 0x04);
101 cpu_id = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
102 if ((irq_flag == 0xAA) && (cpu_id == 0))
103 __invoke_sip_fn_smc(RK_SIP_ENABLE_FIQ, 0, 0, 0);
106 u32 psci_fiq_debugger_switch_cpu(u32 cpu)
108 struct arm_smccc_res sip_smmc;
110 sip_smmc = __invoke_sip_fn_smc(PSCI_SIP_UARTDBG_CFG64,
111 cpu_logical_map(cpu),
112 0, UARTDBG_CFG_OSHDL_CPUSW);
116 void psci_fiq_debugger_enable_debug(bool val)
119 __invoke_sip_fn_smc(PSCI_SIP_UARTDBG_CFG64, 0,
120 0, UARTDBG_CFG_OSHDL_DEBUG_ENABLE);
122 __invoke_sip_fn_smc(PSCI_SIP_UARTDBG_CFG64, 0,
123 0, UARTDBG_CFG_OSHDL_DEBUG_DISABLE);
126 int psci_fiq_debugger_set_print_port(u32 port, u32 baudrate)
128 struct arm_smccc_res res;
130 res = __invoke_sip_fn_smc(PSCI_SIP_UARTDBG_CFG64, port, baudrate,
131 UARTDBG_CFG_PRINT_PORT);
135 struct arm_smccc_res sip_smc_get_share_mem_page(u32 page_num,
136 share_page_type_t page_type)
138 struct arm_smccc_res res;
139 unsigned long share_mem_phy;
141 res = __invoke_sip_fn_smc(SIP_SHARE_MEM32, page_num, page_type, 0);
145 share_mem_phy = res.a1;
146 res.a1 = (unsigned long)ioremap(share_mem_phy, SIZE_PAGE(page_num));
152 struct arm_smccc_res sip_smc_get_call_count(void)
154 return __invoke_sip_fn_smc(SIP_SVC_CALL_COUNT, 0, 0, 0);