blob: 599aa8f2ba117b1489c5ed5313e7a82041986b0e [file] [log] [blame]
David Feng0ae76532013-12-14 11:47:35 +08001/*
2 * GIC Initialization Routines.
3 *
4 * (C) Copyright 2013
5 * David Feng <fenghua@phytium.com.cn>
6 *
7 * SPDX-License-Identifier: GPL-2.0+
8 */
9
10#include <asm-offsets.h>
11#include <config.h>
12#include <linux/linkage.h>
13#include <asm/macro.h>
14#include <asm/gic.h>
15
16
17/*************************************************************************
18 *
19 * void gic_init(void) __attribute__((weak));
20 *
21 * Currently, this routine only initialize secure copy of GIC
22 * with Security Extensions at EL3.
23 *
24 *************************************************************************/
25WEAK(gic_init)
26 branch_if_slave x0, 2f
27
28 /* Initialize Distributor and SPIs */
29 ldr x1, =GICD_BASE
30 mov w0, #0x3 /* EnableGrp0 | EnableGrp1 */
31 str w0, [x1, GICD_CTLR] /* Secure GICD_CTLR */
32 ldr w0, [x1, GICD_TYPER]
33 and w2, w0, #0x1f /* ITLinesNumber */
34 cbz w2, 2f /* No SPIs */
35 add x1, x1, (GICD_IGROUPRn + 4)
36 mov w0, #~0 /* Config SPIs as Grp1 */
371: str w0, [x1], #0x4
38 sub w2, w2, #0x1
39 cbnz w2, 1b
40
41 /* Initialize SGIs and PPIs */
422: ldr x1, =GICD_BASE
43 mov w0, #~0 /* Config SGIs and PPIs as Grp1 */
44 str w0, [x1, GICD_IGROUPRn] /* GICD_IGROUPR0 */
45 mov w0, #0x1 /* Enable SGI 0 */
46 str w0, [x1, GICD_ISENABLERn]
47
48 /* Initialize Cpu Interface */
49 ldr x1, =GICC_BASE
50 mov w0, #0x1e7 /* Disable IRQ/FIQ Bypass & */
51 /* Enable Ack Group1 Interrupt & */
52 /* EnableGrp0 & EnableGrp1 */
53 str w0, [x1, GICC_CTLR] /* Secure GICC_CTLR */
54
55 mov w0, #0x1 << 7 /* Non-Secure access to GICC_PMR */
56 str w0, [x1, GICC_PMR]
57
58 ret
59ENDPROC(gic_init)
60
61
62/*************************************************************************
63 *
64 * void gic_send_sgi(u64 sgi) __attribute__((weak));
65 *
66 *************************************************************************/
67WEAK(gic_send_sgi)
68 ldr x1, =GICD_BASE
69 mov w2, #0x8000
70 movk w2, #0x100, lsl #16
71 orr w2, w2, w0
72 str w2, [x1, GICD_SGIR]
73 ret
74ENDPROC(gic_send_sgi)
75
76
77/*************************************************************************
78 *
79 * void wait_for_wakeup(void) __attribute__((weak));
80 *
81 * Wait for SGI 0 from master.
82 *
83 *************************************************************************/
84WEAK(wait_for_wakeup)
85 ldr x1, =GICC_BASE
860: wfi
87 ldr w0, [x1, GICC_AIAR]
88 str w0, [x1, GICC_AEOIR]
89 cbnz w0, 0b
90 ret
91ENDPROC(wait_for_wakeup)
92
93
94/*************************************************************************
95 *
96 * void smp_kick_all_cpus(void) __attribute__((weak));
97 *
98 *************************************************************************/
99WEAK(smp_kick_all_cpus)
100 /* Kick secondary cpus up by SGI 0 interrupt */
101 mov x0, xzr /* SGI 0 */
102 mov x29, lr /* Save LR */
103 bl gic_send_sgi
104 mov lr, x29 /* Restore LR */
105 ret
106ENDPROC(smp_kick_all_cpus)