1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
/*
* Minimal bootblock for Cubieboard
* It sets up CPU clock, and enables the bootblock console.
*
* Copyright (C) 2013 Alexandru Gagniuc <mr.nuke.me@gmail.com>
* Subject to the GNU GPL v2, or (at your option) any later version.
*/
#include <arch/io.h>
#include <uart.h>
#include <console/console.h>
#include <delay.h>
#include <cpu/allwinner/a10/gpio.h>
#include <cpu/allwinner/a10/clock.h>
#include <cpu/allwinner/a10/dramc.h>
#define CPU_AHB_APB0_DEFAULT \
CPU_CLK_SRC_OSC24M \
| APB0_DIV_1 \
| AHB_DIV_2 \
| AXI_DIV_1
#define GPH_STATUS_LEDS (1 << 20) | (1 << 21)
#define GPH_LED1_PIN_NO 21
#define GPH_LED2_PIN_NO 20
#define GPB_UART0_FUNC 2
#define GPB_UART0_PINS ((1 << 22) | (1 << 23))
static void cubieboard_set_sys_clock(void)
{
u32 reg32;
struct a10_ccm *ccm = (void *)A1X_CCM_BASE;
/* Switch CPU clock to main oscillator */
write32(CPU_AHB_APB0_DEFAULT, &ccm->cpu_ahb_apb0_cfg);
/* Configure the PLL1. The value is the same one used by u-boot
* P = 1, N = 16, K = 1, M = 1 --> Output = 384 MHz
*/
write32(0xa1005000, &ccm->pll1_cfg);
/* FIXME: Delay to wait for PLL to lock */
u32 wait = 1000;
while (--wait);
/* Switch CPU to PLL clock */
reg32 = read32(&ccm->cpu_ahb_apb0_cfg);
reg32 &= ~CPU_CLK_SRC_MASK;
reg32 |= CPU_CLK_SRC_PLL1;
write32(reg32, &ccm->cpu_ahb_apb0_cfg);
}
static void cubieboard_setup_clocks(void)
{
struct a10_ccm *ccm = (void *)A1X_CCM_BASE;
cubieboard_set_sys_clock();
/* Configure the clock source for APB1. This drives our UART */
write32(APB1_CLK_SRC_OSC24M | APB1_RAT_N(0) | APB1_RAT_M(0),
&ccm->apb1_clk_div_cfg);
}
static void cubieboard_setup_gpios(void)
{
/* Mux Status LED pins */
gpio_set_multipin_func(GPH, GPH_STATUS_LEDS, GPIO_PIN_FUNC_OUTPUT);
/* Turn on green LED to let user know we're executing coreboot code */
gpio_set(GPH, GPH_LED2_PIN_NO);
/* Mux UART pins */
gpio_set_multipin_func(GPB, GPB_UART0_PINS, GPB_UART0_FUNC);
}
static void cubieboard_enable_uart(void)
{
a1x_periph_clock_enable(A1X_CLKEN_UART0);
}
static void cubieboard_raminit(void)
{
struct dram_para dram_para = {
.clock = 480,
.type = 3,
.rank_num = 1,
.density = 4096,
.io_width = 16,
.bus_width = 32,
.cas = 6,
.zq = 123,
.odt_en = 0,
.size = 1024,
.tpr0 = 0x30926692,
.tpr1 = 0x1090,
.tpr2 = 0x1a0c8,
.tpr3 = 0,
.tpr4 = 0,
.tpr5 = 0,
.emr1 = 0,
.emr2 = 0,
.emr3 = 0,
};
dramc_init(&dram_para);
/* FIXME: ram_check does not compile for ARM,
* and we didn't init console yet
*/
////void *const test_base = (void *)A1X_DRAM_BASE;
////ram_check((u32)test_base, (u32)test_base + 0x1000);
}
void bootblock_mainboard_init(void);
void bootblock_mainboard_init(void)
{
/* A10 Timer init uses the 24MHz clock, not PLLs, so we can init it very
* early on to get udelay, which is used almost everywhere else.
*/
init_timer();
cubieboard_setup_clocks();
cubieboard_setup_gpios();
cubieboard_enable_uart();
cubieboard_raminit();
}
|