1/*
2 *  This program is distributed in the hope that it will be useful,
3 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
4 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5 *  GNU General Public License for more details.
6 *
7 *  You should have received a copy of the GNU General Public License
8 *  along with this program; if not, write to the Free Software
9 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
10 */
11/*
12 * Board specific setup info
13 *
14 ******************************************************************************
15 * ASPEED Technology Inc.
16 *
17 * Version     : 2
18 * Release date: 2019.02.19
19 *
20 * Priority of fix item:
21 * [P1] = critical
22 * [P2] = nice to have
23 * [P3] = minor
24 *
25 * Change List :
26 * V0 |2018.03.28 : 1.[P1] Initial release for simulation
27 *
28 * Optional define variable
29 *
30 ******************************************************************************
31 */
32
33#include <config.h>
34#include <version.h>
35#include <asm/secure.h>
36#include <asm/armv7.h>
37
38/*
39 *       SMP mailbox
40 * +----------------------+
41 * |                      |
42 * | mailbox insn. for    |
43 * | cpuN polling SMP go  |
44 * |                      |
45 * +----------------------+ 0xC
46 * | mailbox ready signal |
47 * +----------------------+ 0x8
48 * | cpuN GO signal       |
49 * +----------------------+ 0x4
50 * | cpuN entrypoint      |
51 * +----------------------+ AST_SMP_MAILBOX_BASE
52 */
53
54#define AST_SMP_MAILBOX_BASE            0x1E6E2180
55#define AST_SMP_MBOX_FIELD_ENTRY        (AST_SMP_MAILBOX_BASE + 0x0)
56#define AST_SMP_MBOX_FIELD_GOSIGN       (AST_SMP_MAILBOX_BASE + 0x4)
57#define AST_SMP_MBOX_FIELD_READY        (AST_SMP_MAILBOX_BASE + 0x8)
58#define AST_SMP_MBOX_FIELD_POLLINSN     (AST_SMP_MAILBOX_BASE + 0xc)
59
60/* AST2600 HW registers */
61#define AST_SCU_BASE            0x1E6E2000
62#define AST_SCU_PROT_KEY1       (AST_SCU_BASE)
63#define AST_SCU_PROT_KEY2       (AST_SCU_BASE + 0x010)
64#define AST_SCU_REV_ID          (AST_SCU_BASE + 0x014)
65
66#define AST_FMC_BASE            0x1E620000
67#define AST_FMC_WDT1_CTRL_MODE  (AST_FMC_BASE + 0x060)
68#define AST_FMC_WDT2_CTRL_MODE  (AST_FMC_BASE + 0x064)
69
70#define AST_UART_BASE           0x1E784000
71
72/* Revision ID */
73#define REV_ID_AST2600A0    0x05000303
74
75.macro timer_init
76#ifdef CONFIG_FPGA_ASPEED
77    movw    r0, #0x0
78    movt    r0, #0x2500
79#else
80    ldr     r0, =AST_SCU_REV_ID
81    ldr     r0, [r0]
82
83    ldr     r1, =REV_ID_AST2600A0
84    cmp     r0, r1
85
86    movweq  r0, #0x0800
87    movteq  r0, #0x2FAF         @; 800MHz for A0
88    movwne  r0, #0x8C00
89    movtne  r0, #0x4786         @; 1.2GHz for A1
90#endif
91    /* write CNTFRQ */
92    mcr     p15, 0, r0, c14, c0, 0
93.endm
94
95
96.globl lowlevel_init
97
98lowlevel_init:
99#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
100    mov   pc, lr
101#else
102    /* setup timer frequency for ARM generic timer */
103    timer_init
104
105    /*
106     * we treat cpu0 as the primary core and
107     * put secondary core (cpuN) to sleep
108     */
109    mrc   p15, 0, r0, c0, c0, 5             @; Read CPU ID register
110    ands  r0, r0, #0x03                     @; Mask off, leaving the CPU ID field
111
112    beq   do_primary_core_setup
113
114    /* hold cpuN until mailbox is ready */
115poll_mailbox_ready:
116    wfe
117    ldr   r0, =AST_SMP_MBOX_FIELD_READY
118    ldr   r1, =0xBABECAFE
119    ldr   r2, [r0]
120    cmp   r1, r2
121    bne   poll_mailbox_ready
122
123    /* parameters for relocated SMP go polling insn. */
124    ldr   r0, =AST_SMP_MBOX_FIELD_GOSIGN
125    ldr   r1, =AST_SMP_MBOX_FIELD_ENTRY
126    ldr   r2, =0xABBAADDA
127    ldr   r3, =AST_UART_BASE
128
129    /* no return */
130    ldr   pc, =AST_SMP_MBOX_FIELD_POLLINSN
131
132do_primary_core_setup:
133    /* unlock SCU */
134    ldr   r0, =0x1688A8A8                   @; magic key to unlock SCU
135    ldr   r1, =AST_SCU_PROT_KEY1
136    str   r0, [r1]
137    ldr   r1, =AST_SCU_PROT_KEY2
138    str   r0, [r1]
139
140    /* disable FMC WDT for SPI address mode detection */
141    mov   r0, #0
142    ldr   r1, =AST_FMC_WDT1_CTRL_MODE
143    str   r0, [r1]
144    ldr   r1, =AST_FMC_WDT2_CTRL_MODE
145    str   r0, [r1]
146
147    /* relocate mailbox insn. for cpuN polling SMP go signal */
148    adrl  r0, mailbox_insn
149    adrl  r1, mailbox_insn_end
150
151    ldr   r2, =#AST_SMP_MBOX_FIELD_POLLINSN
152
153relocate_mailbox_insn:
154    ldr   r3, [r0], #0x4
155    str   r3, [r2], #0x4
156    cmp   r0, r1
157    bne   relocate_mailbox_insn
158
159    /* notify cpuN mailbox is ready */
160    ldr   r0, =AST_SMP_MBOX_FIELD_READY
161    ldr   r1, =0xBABECAFE
162    str   r1, [r0]
163    sev
164
165    /* back to arch calling code */
166    mov   pc, lr
167
168/*
169 * insn. inside mailbox to poll SMP go signal.
170 *
171 * Note that as this code will be relocated, any
172 * pc-relative assembly should NOT be used.
173 */
174mailbox_insn:
175    /*
176     * r0 ~ r3 are parameters:
177     *   r0 = AST_SMP_MBOX_FIELD_GOSIGN
178     *   r1 = AST_SMP_MBOX_FIELD_ENTRY
179     *   r2 = 0xABBAADDA
180     *   r3 = AST_UART_BASE (for debug purpose)
181     */
182poll_mailbox_smp_go:
183    wfe
184    ldr   r4, [r0]
185    cmp   r2, r4
186    bne   poll_mailbox_smp_go
187
188    /* debug message */
189    mov   r4, #'C'
190    str   r4, [r3]
191    mov   r4, #'P'
192    str   r4, [r3]
193    mov   r4, #'U'
194    str   r4, [r3]
195    mov   r4, #'1'
196    str   r4, [r3]
197    mov   r4, #'\r'
198    str   r4, [r3]
199    mov   r4, #'\n'
200    str   r4, [r3]
201
202    /* SMP GO signal confirmed, release cpuN */
203    ldr   pc, [r1]
204
205mailbox_insn_end:
206    /* should never reach */
207    b .
208
209#endif
210