diff options
author | Marcin Bukat <marcin.bukat@gmail.com> | 2012-02-28 15:51:36 +0100 |
---|---|---|
committer | Marcin Bukat <marcin.bukat@gmail.com> | 2012-03-04 00:35:48 +0100 |
commit | 0263fe37e4a0f7db5e647c171afafda9783fc97b (patch) | |
tree | 1c7fc8275bc38ba71af3c555bdfdcee233163c6f /bootloader/rk27xx.c | |
parent | 587f52f50e24be1b1efcadff06168f3570487f4e (diff) | |
download | rockbox-0263fe37e4a0f7db5e647c171afafda9783fc97b.tar.gz rockbox-0263fe37e4a0f7db5e647c171afafda9783fc97b.zip |
rk27xx: Implement dualboot capable bootloader
Change-Id: I399e10635f611bdf6f7c1bd5843fa132dc88bfb4
Diffstat (limited to 'bootloader/rk27xx.c')
-rw-r--r-- | bootloader/rk27xx.c | 252 |
1 files changed, 89 insertions, 163 deletions
diff --git a/bootloader/rk27xx.c b/bootloader/rk27xx.c index b74526fe90..c1c8110831 100644 --- a/bootloader/rk27xx.c +++ b/bootloader/rk27xx.c | |||
@@ -1,184 +1,110 @@ | |||
1 | #include "config.h" | ||
2 | #include <stdlib.h> | ||
3 | #include <stdio.h> | 1 | #include <stdio.h> |
4 | #include <string.h> | 2 | #include <system.h> |
5 | #include "inttypes.h" | 3 | #include <inttypes.h> |
6 | #include "string.h" | 4 | #include "config.h" |
7 | #include "cpu.h" | 5 | #include "gcc_extensions.h" |
8 | #include "system.h" | ||
9 | #include "lcd.h" | 6 | #include "lcd.h" |
10 | #include "kernel.h" | ||
11 | #include "thread.h" | ||
12 | #include "backlight.h" | ||
13 | #include "backlight-target.h" | ||
14 | #include "font.h" | 7 | #include "font.h" |
8 | #include "backlight.h" | ||
9 | #include "adc.h" | ||
10 | #include "button-target.h" | ||
11 | #include "button.h" | ||
15 | #include "common.h" | 12 | #include "common.h" |
16 | #include "version.h" | 13 | #include "storage.h" |
17 | 14 | #include "disk.h" | |
18 | // 441 Hz samples table, 44100 Hz and 441 Hz -> 100 samples | 15 | #include "panic.h" |
19 | const int16_t samples[] = { | 16 | #include "power.h" |
20 | 0, 2057, 4106, 6139, 8148, 10125, 12062, 13951, 15785, 17557, | 17 | #include "string.h" |
21 | 19259, 20886, 22430, 23886, 25247, 26509, 27666, 28713, 29648, 30465, | 18 | #include "file.h" |
22 | 31163, 31737, 32186, 32508, 32702, 32767, 32702, 32508, 32186, 31737, | 19 | #include "crc32-rkw.h" |
23 | 31163, 30465, 29648, 28713, 27666, 26509, 25247, 23886, 22430, 20886, | 20 | #include "rkw.h" |
24 | 19259, 17557, 15785, 13951, 12062, 10125, 8148, 6139, 4106, 2057, | ||
25 | 0, -2057, -4106, -6139, -8148, -10125, -12062, -13951, -15785, -17557, | ||
26 | -19259, -20886, -22430, -23886, -25247, -26509, -27666, -28713, -29648, -30465, | ||
27 | -31163, -31737, -32186, -32508, -32702, -32767, -32702, -32508, -32186, -31737, | ||
28 | -31163, -30465, -29648, -28713, -27666, -26509, -25247, -23886, -22430, -20886, | ||
29 | -19259, -17557, -15785, -13951, -12062, -10125, -8148, -6139, -4106, -2057 }; | ||
30 | |||
31 | extern void show_logo( void ); | ||
32 | 21 | ||
33 | void INT_HDMA(void) | 22 | #define DRAM_ORIG 0x60000000 |
34 | { | 23 | #define LOAD_SIZE 0x700000 |
35 | #if 0 | ||
36 | // static uint32_t i; | ||
37 | // printf("hdma int: %d", i++); | ||
38 | |||
39 | HDMA_ISRC0 = (uint32_t)&samples; | ||
40 | HDMA_IDST0 = (uint32_t)&I2S_TXR; | ||
41 | HDMA_ICNT0 = (sizeof(samples)/4) - 1; | ||
42 | HDMA_CON0 = (1<<22)| // slice mode | ||
43 | (1<<21)| // channel enable | ||
44 | (1<<18)| // interrupt mode | ||
45 | (5<<13)| // transfer mode inc8 | ||
46 | (6<<9) | // hdreq from i2s tx | ||
47 | (0<<7) | // source address increment | ||
48 | (1<<5) | // destination address fixed | ||
49 | (2<<3) | // data size word | ||
50 | (1<<0); // enable hardware triggered dma | ||
51 | |||
52 | HDMA_ISR = (1<<13) | // mask ch1 page overflow | ||
53 | (1<<11) | // mask ch1 page count down | ||
54 | (1<<9); // mask ch1 interrupts | ||
55 | #endif | ||
56 | return; | ||
57 | } | ||
58 | 24 | ||
59 | static int codec_write(uint8_t reg, uint8_t data) | 25 | extern void show_logo( void ); |
60 | { | ||
61 | uint8_t tmp = data; | ||
62 | return i2c_write(0x27<<1, reg<<1, 1, &tmp); | ||
63 | } | ||
64 | 26 | ||
27 | void main(void) NORETURN_ATTR; | ||
65 | void main(void) | 28 | void main(void) |
66 | { | 29 | { |
67 | int i; | 30 | char filename[MAX_PATH]; |
68 | 31 | unsigned char* loadbuffer; | |
69 | _backlight_init(); | 32 | void(*kernel_entry)(void); |
33 | int ret; | ||
34 | enum {rb, of} boot = rb; | ||
70 | 35 | ||
36 | power_init(); | ||
71 | system_init(); | 37 | system_init(); |
72 | kernel_init(); | 38 | kernel_init(); |
73 | enable_irq(); | 39 | enable_irq(); |
74 | 40 | ||
75 | lcd_init_device(); | 41 | adc_init(); |
76 | _backlight_on(); | 42 | lcd_init(); |
43 | backlight_init(); | ||
44 | button_init_device(); | ||
45 | |||
77 | font_init(); | 46 | font_init(); |
78 | lcd_setfont(FONT_SYSFIXED); | 47 | lcd_setfont(FONT_SYSFIXED); |
79 | 48 | ||
80 | show_logo(); | 49 | show_logo(); |
81 | sleep(HZ*2); | 50 | |
82 | 51 | int btn = button_read_device(); | |
83 | printf("show logo passed"); | 52 | |
84 | // I2S init | 53 | /* if there is some other button pressed |
85 | SCU_CLKCFG &= ~((1<<17) | (1<<16)); // enable i2s, i2c pclk | 54 | * besides POWER/PLAY we boot into OF |
86 | //SCU_CLKCFG |= ((1<<17) | (1<<16)); | 55 | */ |
87 | I2S_OPR = (1<<17) | // reset Tx | 56 | if ((btn & ~POWEROFF_BUTTON)) |
88 | (1<<16) | // reset Rx | 57 | boot = of; |
89 | (1<<6) | // disable HDMA Req1 | 58 | |
90 | (1<<5); // disable HDMA Req2 | 59 | /* if we are woken up by USB insert boot into OF */ |
91 | 60 | if (DEV_INFO & (1<<20)) | |
92 | I2S_TXCTL = (1<<16) | // LRCK/SCLK = 64 | 61 | boot = of; |
93 | (4<<8) | // MCLK/SCK = 4 | 62 | |
94 | (1<<4) | // 16bit samples | 63 | lcd_clear_display(); |
95 | (0<<3) | // stereo mode | 64 | |
96 | (0<<1); // I2S | 65 | ret = storage_init(); |
97 | 66 | if(ret < 0) | |
98 | I2S_RXCTL = (1<<16) | // LRCK/SCLK = 64 | 67 | error(EATA, ret, true); |
99 | (4<<8) | // MCLK/SCK = 4 | 68 | |
100 | (1<<4) | // 16bit samples | 69 | while(!disk_init(IF_MV(0))) |
101 | (0<<3) | // stereo mode | 70 | panicf("disk_init failed!"); |
102 | (0<<1); // I2S | 71 | |
103 | 72 | while((ret = disk_mount_all()) <= 0) | |
104 | I2S_FIFOSTS = (1<<18) | // Tx int trigger half full | 73 | error(EDISK, ret, true); |
105 | (1<<16); // Rx int trigger half full | 74 | |
106 | 75 | loadbuffer = (unsigned char*)DRAM_ORIG; /* DRAM */ | |
107 | // I2S start | 76 | |
108 | I2S_OPR = (1<<17) | (1<<16); | 77 | if (boot == rb) |
109 | sleep(HZ/100); | 78 | snprintf(filename,sizeof(filename), BOOTDIR "/%s", BOOTFILE); |
110 | 79 | else if (boot == of) | |
111 | I2S_OPR = (0<<6) | // req channel 1 enable | 80 | snprintf(filename,sizeof(filename), BOOTDIR "/%s", "BASE.RKW"); |
112 | (1<<5) | // req channel 2 disable | 81 | |
113 | (0<<4) | // HDMA req channel 1 Tx | 82 | printf("Loading: %s", filename); |
114 | (0<<2) | // normal I2S operation (no loopback) | 83 | |
115 | (1<<1); // Tx start | 84 | ret = load_rkw(loadbuffer, filename, LOAD_SIZE); |
116 | 85 | if (ret < 0) | |
117 | printf("I2S config passed"); | 86 | { |
118 | 87 | printf(rkw_strerror(ret)); | |
119 | HDMA_ISRC0 = (uint32_t)&samples; | 88 | lcd_update(); |
120 | HDMA_IDST0 = (uint32_t)&I2S_TXR; | 89 | sleep(5*HZ); |
121 | HDMA_ICNT0 = (sizeof(samples)/4) - 1; | 90 | power_off(); |
122 | HDMA_ISCNT0 = 7; | 91 | } |
123 | HDMA_IPNCNTD0 = 1; | 92 | else |
124 | HDMA_CON0 = (1<<22)| // slice mode | ||
125 | (1<<21)| // channel enable | ||
126 | (1<<18)| // interrupt mode | ||
127 | (5<<13)| // transfer mode inc8 | ||
128 | (6<<9) | // hdreq from i2s tx | ||
129 | (0<<7) | // source address increment | ||
130 | (1<<5) | // destination address fixed | ||
131 | (2<<3) | // data size word | ||
132 | (1<<0); // enable hardware triggered dma | ||
133 | |||
134 | HDMA_ISR = (1<<13) | // mask ch1 page overflow | ||
135 | (1<<11) | // mask ch1 page count down | ||
136 | (1<<9); // mask ch1 interrupts | ||
137 | |||
138 | INTC_IMR |= (1<<12); | ||
139 | INTC_IECR |= (1<<12); | ||
140 | |||
141 | printf("HDMA config passed"); | ||
142 | |||
143 | i2c_init(); | ||
144 | |||
145 | printf("I2C config passed"); | ||
146 | |||
147 | // codec init | ||
148 | codec_write(0x00, (1<<3)|(1<<2)|(1<<1)|(1<<0)); // AICR | ||
149 | codec_write(0x01, (1<<7)|(1<<5)|(1<<3)); // CR1 | ||
150 | codec_write(0x02, (1<<2)); // CR2 | ||
151 | codec_write(0x03, 0); // CCR1 | ||
152 | codec_write(0x04, (2<<4)|(2<<0)); // CCR2 | ||
153 | codec_write(0x07, (3<<5)|(3<<0)); // CCR | ||
154 | |||
155 | |||
156 | codec_write(0x0f, 0x1f|(2<<6)); // CGR6 | ||
157 | codec_write(0x14, (1<<1)); // TR1 | ||
158 | codec_write(0x05, (1<<6)|(1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1<<0)); // PMR1 | ||
159 | sleep(HZ/100); | ||
160 | |||
161 | codec_write(0x06, (1<<3)|(1<<2)|(1<<0)); // PMR2 | ||
162 | |||
163 | |||
164 | codec_write(0x05, (1<<6)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1<<0)); // PMR1 | ||
165 | codec_write(0x05, (1<<4)|(1<<3)|(1<<2)|(1<<1)|(1<<0)); // PMR1 | ||
166 | |||
167 | |||
168 | // DACout mode | ||
169 | codec_write(0x01, (1<<7)|(1<<3)|(1<<5)|(1<<4)); // CR1 | ||
170 | codec_write(0x05, (1<<4)|(1<<3)|(1<<2)|(1<<1)|(1<<0)); //PMR1 | ||
171 | // codec_write(0x06, (1<<3)|(1<<2)); // PMR2 | ||
172 | |||
173 | printf("codec init passed"); | ||
174 | |||
175 | codec_write(0x01, (1<<7)|(1<<3)); // CR1 | ||
176 | |||
177 | codec_write(0x0a, 0); // 0dB digital gain | ||
178 | codec_write(0x11, 15|(2<<6)); // | ||
179 | |||
180 | while(1) | ||
181 | { | 93 | { |
182 | printf("HDMA_CCNT0: 0x%0x FIFOSTS: 0x%0x", HDMA_CCNT0, I2S_FIFOSTS); | 94 | printf(rkw_strerror(0)); |
95 | sleep(HZ); | ||
183 | } | 96 | } |
97 | |||
98 | kernel_entry = (void*) loadbuffer; | ||
99 | commit_discard_idcache(); | ||
100 | |||
101 | printf("Executing"); | ||
102 | kernel_entry(); | ||
103 | |||
104 | printf("ERR: Failed to boot"); | ||
105 | sleep(5*HZ); | ||
106 | power_off(); | ||
107 | |||
108 | /* hang */ | ||
109 | while(1); | ||
184 | } | 110 | } |