Initial commit
[rpi-open-firmware.git] / romstage.c
1 /*=============================================================================
2 Copyright (C) 2016 Kristina Brooks
3 All rights reserved.
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 FILE DESCRIPTION
16 VideoCoreIV first stage bootloader.
17
18 =============================================================================*/
19
20 #include "lib/common.h"
21 #include "hardware.h"
22
23 uint32_t g_CPUID;
24
25 void uart_putc(unsigned int ch)
26 {
27 while(1) {
28 if (mmio_read32(AUX_MU_LSR_REG) & 0x20)
29 break;
30 }
31 mmio_write32(AUX_MU_IO_REG, ch);
32 }
33
34 void uart_init(void) {
35 unsigned int ra = GP_FSEL1;
36 ra &= ~(7 << 12);
37 ra |= 2 << 12;
38 GP_FSEL1 = ra;
39
40 GP_PUD = 0;
41
42 udelay(150);
43 GP_PUDCLK0 = (1 << 14) | (1 << 15);
44 udelay(150);
45 GP_PUDCLK0 = 0;
46
47 mmio_write32(AUX_ENABLES, 1);
48 mmio_write32(AUX_MU_IER_REG, 0);
49 mmio_write32(AUX_MU_CNTL_REG, 0);
50 mmio_write32(AUX_MU_LCR_REG, 3);
51 mmio_write32(AUX_MU_MCR_REG, 0);
52 mmio_write32(AUX_MU_IER_REG, 0);
53 mmio_write32(AUX_MU_IIR_REG, 0xC6);
54
55 mmio_write32(AUX_MU_BAUD_REG, 270);
56
57 mmio_write32(AUX_MU_LCR_REG, 3);
58 mmio_write32(AUX_MU_CNTL_REG, 3);
59 }
60
61 void led_init(void) {
62 unsigned int ra;
63
64 ra = GP_FSEL1;
65 ra &= ~(7 << 18);
66 ra |= 1 << 18;
67
68 GP_FSEL1 = ra;
69 }
70
71 /*
72 #define CM_PLLC_DIGRST_BITS 9:9
73 #define CM_PLLC_DIGRST_SET 0x00000200
74 #define CM_PLLC_ANARST_BITS 8:8
75 #define CM_PLLC_ANARST_SET 0x00000100
76 #define CM_PLLC_HOLDPER_BITS 7:7
77 #define CM_PLLC_HOLDPER_SET 0x00000080
78 #define CM_PLLC_LOADPER_BITS 6:6
79 #define CM_PLLC_LOADPER_SET 0x00000040
80 #define CM_PLLC_HOLDCORE2_BITS 5:5
81 #define CM_PLLC_HOLDCORE2_SET 0x00000020
82 #define CM_PLLC_LOADCORE2_BITS 4:4
83 #define CM_PLLC_LOADCORE2_SET 0x00000010
84 #define CM_PLLC_HOLDCORE1_BITS 3:3
85 #define CM_PLLC_HOLDCORE1_SET 0x00000008
86 #define CM_PLLC_LOADCORE1_BITS 2:2
87 #define CM_PLLC_LOADCORE1_SET 0x00000004
88 #define CM_PLLC_HOLDCORE0_BITS 1:1
89 #define CM_PLLC_HOLDCORE0_SET 0x00000002
90 #define CM_PLLC_LOADCORE0_BITS 0:0
91 #define CM_PLLC_LOADCORE0_SET 0x00000001
92 */
93
94 void switch_vpu_to_pllc() {
95 A2W_XOSC_CTRL |= A2W_PASSWORD | A2W_XOSC_CTRL_PLLCEN_SET;
96
97 A2W_PLLC_FRAC = A2W_PASSWORD | 87380;
98 A2W_PLLC_CTRL = A2W_PASSWORD | 52 | 0x1000;
99
100 A2W_PLLC_ANA3 = A2W_PASSWORD | 0x100;
101 A2W_PLLC_ANA2 = A2W_PASSWORD | 0x0;
102 A2W_PLLC_ANA1 = A2W_PASSWORD | 0x144000;
103 A2W_PLLC_ANA0 = A2W_PASSWORD | 0x0;
104
105 CM_PLLC = CM_PASSWORD | CM_PLLC_DIGRST_SET;
106
107 /* hold all */
108 CM_PLLC = CM_PASSWORD | CM_PLLC_DIGRST_SET |
109 CM_PLLC_HOLDPER_SET | CM_PLLC_HOLDCORE2_SET |
110 CM_PLLC_HOLDCORE1_SET | CM_PLLC_HOLDCORE0_SET;
111
112 A2W_PLLC_DIG3 = A2W_PASSWORD | 0x0;
113 A2W_PLLC_DIG2 = A2W_PASSWORD | 0x400000;
114 A2W_PLLC_DIG1 = A2W_PASSWORD | 0x5;
115 A2W_PLLC_DIG0 = A2W_PASSWORD | 52 | 0x555000;
116
117 A2W_PLLC_CTRL = A2W_PASSWORD | 52 | 0x1000 | A2W_PLLC_CTRL_PRSTN_SET;
118
119 A2W_PLLC_DIG3 = A2W_PASSWORD | 0x42;
120 A2W_PLLC_DIG2 = A2W_PASSWORD | 0x500401;
121 A2W_PLLC_DIG1 = A2W_PASSWORD | 0x4005;
122 A2W_PLLC_DIG0 = A2W_PASSWORD | 52 | 0x555000;
123
124 A2W_PLLC_CORE0 = A2W_PASSWORD | 2;
125
126 CM_PLLC = CM_PASSWORD | CM_PLLC_DIGRST_SET |
127 CM_PLLC_HOLDPER_SET | CM_PLLC_HOLDCORE2_SET |
128 CM_PLLC_HOLDCORE1_SET | CM_PLLC_HOLDCORE0_SET | CM_PLLC_LOADCORE0_SET;
129
130 CM_PLLC = CM_PASSWORD | CM_PLLC_DIGRST_SET |
131 CM_PLLC_HOLDPER_SET | CM_PLLC_HOLDCORE2_SET |
132 CM_PLLC_HOLDCORE1_SET | CM_PLLC_HOLDCORE0_SET;
133
134 CM_PLLC = CM_PASSWORD | CM_PLLC_DIGRST_SET |
135 CM_PLLC_HOLDPER_SET | CM_PLLC_HOLDCORE2_SET |
136 CM_PLLC_HOLDCORE1_SET;
137
138 CM_VPUCTL = CM_PASSWORD | CM_VPUCTL_FRAC_SET | CM_SRC_OSC | CM_VPUCTL_GATE_SET;
139 CM_VPUDIV = CM_PASSWORD | (4 << 12);
140 CM_VPUCTL = CM_PASSWORD | CM_SRC_PLLC_CORE0 | CM_VPUCTL_GATE_SET;
141 CM_VPUCTL = CM_PASSWORD | CM_SRC_PLLC_CORE0 | CM_VPUCTL_GATE_SET | 0x10; /* ENAB */
142
143 CM_TIMERDIV = CM_PASSWORD | (19 << 12) | 819;
144 CM_TIMERCTL = CM_PASSWORD | CM_SRC_OSC | 0x10;
145 }
146
147 extern void sdram_init();
148 extern void arm_init();
149
150 int _main(unsigned int cpuid, unsigned int load_address) {
151 switch_vpu_to_pllc();
152
153 led_init();
154 uart_init();
155
156 printf(
157 "=========================================================\n"
158 "::\n"
159 ":: kFW for bcm2708, Copyright 2016, Kristina Brooks. \n"
160 "::\n"
161 ":: BUILDATE : %s %s \n"
162 ":: BUILDSTYLE: %s \n"
163 "::\n"
164 "=========================================================\n",
165 __DATE__, __TIME__,
166 "OPENSOURCE"
167 );
168
169 printf("CPUID = 0x%X\n", cpuid);
170 printf("LoadAddr = 0x%X\n", load_address);
171
172 g_CPUID = cpuid;
173
174 /* bring up SDRAM */
175 sdram_init();
176 printf("SDRAM initialization completed successfully!\n");
177
178 /* bring up ARM */
179 arm_init();
180
181 panic("main exiting!");
182 }
183
This page took 0.087622 seconds and 5 git commands to generate.