1 /* Initializes CPU and basic hardware such as memory
2 * controllers, IRQ controller and system timer 0.
4 * (C) Copyright 2007, 2015
5 * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com
7 * SPDX-License-Identifier: GPL-2.0+
15 #include <grlib/irqmp.h>
16 #include <grlib/gptimer.h>
17 #include <debug_uart.h>
21 /* Default Plug&Play I/O area */
22 #ifndef CONFIG_AMBAPP_IOAREA
23 #define CONFIG_AMBAPP_IOAREA AMBA_DEFAULT_IOAREA
26 /* Select which TIMER that will become the time base */
27 #ifndef CONFIG_SYS_GRLIB_GPTIMER_INDEX
28 #define CONFIG_SYS_GRLIB_GPTIMER_INDEX 0
31 DECLARE_GLOBAL_DATA_PTR
;
33 ambapp_dev_irqmp
*irqmp
= NULL
;
36 * Breath some life into the CPU...
38 * Run from FLASH/PROM:
39 * - until memory controller is set up, only registers available
40 * - memory controller has already been setup up, stack can be used
41 * - no global variables available for writing
42 * - constants available
46 #ifdef CONFIG_DEBUG_UART
51 /* If cache snooping is available in hardware the result will be set
52 * to 0x800000, otherwise 0.
54 static unsigned int snoop_detect(void)
57 asm("lda [%%g0] 2, %0" : "=r"(result
));
58 return result
& 0x00800000;
61 int arch_cpu_init(void)
66 gd
->cpu_clk
= CONFIG_SYS_CLK_FREQ
;
67 gd
->bus_clk
= CONFIG_SYS_CLK_FREQ
;
68 gd
->ram_size
= CONFIG_SYS_SDRAM_SIZE
;
70 gd
->arch
.snooping_available
= snoop_detect();
72 /* Initialize the AMBA Plug & Play bus structure, the bus
73 * structure represents the AMBA bus that the CPU is located at.
75 ambapp_bus_init(CONFIG_AMBAPP_IOAREA
, CONFIG_SYS_CLK_FREQ
, &ambapp_plb
);
77 /* Initialize/clear all the timers in the system.
79 for (index
= 0; ambapp_apb_find(&ambapp_plb
, VENDOR_GAISLER
,
80 GAISLER_GPTIMER
, index
, &apbdev
) == 1; index
++) {
81 ambapp_dev_gptimer
*timer
;
82 unsigned int bus_freq
;
85 timer
= (ambapp_dev_gptimer
*)apbdev
.address
;
87 /* Different buses may have different frequency, the
88 * frequency of the bus tell in which frequency the timer
91 bus_freq
= ambapp_bus_freq(&ambapp_plb
, apbdev
.ahb_bus_index
);
93 /* Initialize prescaler common to all timers to 1MHz */
94 timer
->scalar
= timer
->scalar_reload
=
95 (((bus_freq
/ 1000) + 500) / 1000) - 1;
97 /* Clear all timers */
98 ntimers
= timer
->config
& 0x7;
99 for (i
= 0; i
< ntimers
; i
++) {
100 timer
->e
[i
].ctrl
= GPTIMER_CTRL_IP
;
102 timer
->e
[i
].ctrl
= GPTIMER_CTRL_LD
;
110 * initialize higher level parts of CPU like time base and timers
114 ambapp_apbdev apbdev
;
118 * Find AMBA APB IRQMP Controller,
120 if (ambapp_apb_find(&ambapp_plb
, VENDOR_GAISLER
,
121 GAISLER_IRQMP
, 0, &apbdev
) != 1) {
122 panic("%s: IRQ controller not found\n", __func__
);
125 irqmp
= (ambapp_dev_irqmp
*)apbdev
.address
;
127 /* initialize the IRQMP */
128 irqmp
->ilevel
= 0xf; /* all IRQ off */
131 irqmp
->iclear
= 0xfffe; /* clear all old pending interrupts */
132 for (cpu
= 0; cpu
< 16; cpu
++) {
133 /* mask and clear force for all IRQs on CPU[N] */
134 irqmp
->cpu_mask
[cpu
] = 0;
135 irqmp
->cpu_force
[cpu
] = 0;
144 ambapp_dev_gptimer_element
*tmr
;
145 ambapp_dev_gptimer
*gptimer
;
146 ambapp_apbdev apbdev
;
149 if (ambapp_apb_find(&ambapp_plb
, VENDOR_GAISLER
, GAISLER_GPTIMER
,
150 CONFIG_SYS_GRLIB_GPTIMER_INDEX
, &apbdev
) != 1) {
151 panic("%s: gptimer not found!\n", __func__
);
155 gptimer
= (ambapp_dev_gptimer
*) apbdev
.address
;
157 /* Different buses may have different frequency, the
158 * frequency of the bus tell in which frequency the timer
159 * prescaler operates.
161 bus_freq
= ambapp_bus_freq(&ambapp_plb
, apbdev
.ahb_bus_index
);
163 /* initialize prescaler common to all timers to 1MHz */
164 gptimer
->scalar
= gptimer
->scalar_reload
=
165 (((bus_freq
/ 1000) + 500) / 1000) - 1;
167 tmr
= (ambapp_dev_gptimer_element
*)&gptimer
->e
[0];
171 tmr
->ctrl
= GPTIMER_CTRL_EN
| GPTIMER_CTRL_RS
| GPTIMER_CTRL_LD
;
173 CONFIG_SYS_TIMER_COUNTER
= (void *)&tmr
->val
;