]> git.sur5r.net Git - u-boot/blob - arch/arm/mach-tegra/psci.S
tegra124: Add PSCI support for Tegra124
[u-boot] / arch / arm / mach-tegra / psci.S
1 /*
2  * Copyright (C) 2014, NVIDIA
3  * Copyright (C) 2015, Siemens AG
4  *
5  * Authors:
6  *  Thierry Reding <treding@nvidia.com>
7  *  Jan Kiszka <jan.kiszka@siemens.com>
8  *
9  * SPDX-License-Identifier:     GPL-2.0+
10  */
11
12 #include <linux/linkage.h>
13 #include <asm/macro.h>
14 #include <asm/psci.h>
15
16         .pushsection ._secure.text, "ax"
17         .arch_extension sec
18
19 #define TEGRA_SB_CSR_0                  0x6000c200
20 #define NS_RST_VEC_WR_DIS               (1 << 1)
21
22 #define TEGRA_RESET_EXCEPTION_VECTOR    0x6000f100
23
24 #define TEGRA_FLOW_CTRL_BASE            0x60007000
25 #define FLOW_CTRL_CPU_CSR               0x08
26 #define CSR_ENABLE                      (1 << 0)
27 #define CSR_IMMEDIATE_WAKE              (1 << 3)
28 #define CSR_WAIT_WFI_SHIFT              8
29 #define FLOW_CTRL_CPU1_CSR              0x18
30
31 @ converts CPU ID into FLOW_CTRL_CPUn_CSR offset
32 .macro get_csr_reg cpu, ofs, tmp
33         cmp     \cpu, #0                @ CPU0?
34         lsl     \tmp, \cpu, #3  @ multiple by 8 (register offset CPU1-3)
35         moveq   \ofs, #FLOW_CTRL_CPU_CSR
36         addne   \ofs, \tmp, #FLOW_CTRL_CPU1_CSR - 8
37 .endm
38
39 ENTRY(psci_arch_init)
40         mov     r6, lr
41
42         mrc     p15, 0, r5, c1, c1, 0   @ Read SCR
43         bic     r5, r5, #1              @ Secure mode
44         mcr     p15, 0, r5, c1, c1, 0   @ Write SCR
45         isb
46
47         @ lock reset vector for non-secure
48         ldr     r4, =TEGRA_SB_CSR_0
49         ldr     r5, [r4]
50         orr     r5, r5, #NS_RST_VEC_WR_DIS
51         str     r5, [r4]
52
53         bl      psci_get_cpu_id         @ CPU ID => r0
54         bl      psci_get_cpu_stack_top  @ stack top => r0
55         mov     sp, r0
56
57         bx      r6
58 ENDPROC(psci_arch_init)
59
60 ENTRY(psci_cpu_off)
61         bl      psci_cpu_off_common
62
63         bl      psci_get_cpu_id         @ CPU ID => r0
64
65         get_csr_reg r0, r2, r3
66
67         ldr     r6, =TEGRA_FLOW_CTRL_BASE
68         mov     r5, #(CSR_ENABLE)
69         mov     r4, #(1 << CSR_WAIT_WFI_SHIFT)
70         add     r5, r4, lsl r0
71         str     r5, [r6, r2]
72
73 _loop:  wfi
74         b       _loop
75 ENDPROC(psci_cpu_off)
76
77 ENTRY(psci_cpu_on)
78         push    {lr}
79
80         mov     r0, r1
81         bl      psci_get_cpu_stack_top  @ get stack top of target CPU
82         str     r2, [r0]                @ store target PC at stack top
83         dsb
84
85         ldr     r6, =TEGRA_RESET_EXCEPTION_VECTOR
86         ldr     r5, =psci_cpu_entry
87         str     r5, [r6]
88
89         get_csr_reg r1, r2, r3
90
91         ldr     r6, =TEGRA_FLOW_CTRL_BASE
92         mov     r5, #(CSR_IMMEDIATE_WAKE | CSR_ENABLE)
93         str     r5, [r6, r2]
94
95         mov     r0, #ARM_PSCI_RET_SUCCESS       @ Return PSCI_RET_SUCCESS
96         pop     {pc}
97 ENDPROC(psci_cpu_on)
98
99         .globl psci_text_end
100 psci_text_end:
101         .popsection