From 0263fe37e4a0f7db5e647c171afafda9783fc97b Mon Sep 17 00:00:00 2001 From: Marcin Bukat Date: Tue, 28 Feb 2012 15:51:36 +0100 Subject: rk27xx: Implement dualboot capable bootloader Change-Id: I399e10635f611bdf6f7c1bd5843fa132dc88bfb4 --- bootloader/rk27xx.c | 252 +++++++++++++++++++--------------------------------- 1 file 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 @@ -#include "config.h" -#include #include -#include -#include "inttypes.h" -#include "string.h" -#include "cpu.h" -#include "system.h" +#include +#include +#include "config.h" +#include "gcc_extensions.h" #include "lcd.h" -#include "kernel.h" -#include "thread.h" -#include "backlight.h" -#include "backlight-target.h" #include "font.h" +#include "backlight.h" +#include "adc.h" +#include "button-target.h" +#include "button.h" #include "common.h" -#include "version.h" - -// 441 Hz samples table, 44100 Hz and 441 Hz -> 100 samples -const int16_t samples[] = { - 0, 2057, 4106, 6139, 8148, 10125, 12062, 13951, 15785, 17557, - 19259, 20886, 22430, 23886, 25247, 26509, 27666, 28713, 29648, 30465, - 31163, 31737, 32186, 32508, 32702, 32767, 32702, 32508, 32186, 31737, - 31163, 30465, 29648, 28713, 27666, 26509, 25247, 23886, 22430, 20886, - 19259, 17557, 15785, 13951, 12062, 10125, 8148, 6139, 4106, 2057, - 0, -2057, -4106, -6139, -8148, -10125, -12062, -13951, -15785, -17557, - -19259, -20886, -22430, -23886, -25247, -26509, -27666, -28713, -29648, -30465, - -31163, -31737, -32186, -32508, -32702, -32767, -32702, -32508, -32186, -31737, - -31163, -30465, -29648, -28713, -27666, -26509, -25247, -23886, -22430, -20886, - -19259, -17557, -15785, -13951, -12062, -10125, -8148, -6139, -4106, -2057 }; - -extern void show_logo( void ); +#include "storage.h" +#include "disk.h" +#include "panic.h" +#include "power.h" +#include "string.h" +#include "file.h" +#include "crc32-rkw.h" +#include "rkw.h" -void INT_HDMA(void) -{ -#if 0 -// static uint32_t i; -// printf("hdma int: %d", i++); - - HDMA_ISRC0 = (uint32_t)&samples; - HDMA_IDST0 = (uint32_t)&I2S_TXR; - HDMA_ICNT0 = (sizeof(samples)/4) - 1; - HDMA_CON0 = (1<<22)| // slice mode - (1<<21)| // channel enable - (1<<18)| // interrupt mode - (5<<13)| // transfer mode inc8 - (6<<9) | // hdreq from i2s tx - (0<<7) | // source address increment - (1<<5) | // destination address fixed - (2<<3) | // data size word - (1<<0); // enable hardware triggered dma - - HDMA_ISR = (1<<13) | // mask ch1 page overflow - (1<<11) | // mask ch1 page count down - (1<<9); // mask ch1 interrupts -#endif -return; -} +#define DRAM_ORIG 0x60000000 +#define LOAD_SIZE 0x700000 -static int codec_write(uint8_t reg, uint8_t data) -{ - uint8_t tmp = data; - return i2c_write(0x27<<1, reg<<1, 1, &tmp); -} +extern void show_logo( void ); +void main(void) NORETURN_ATTR; void main(void) { - int i; - - _backlight_init(); + char filename[MAX_PATH]; + unsigned char* loadbuffer; + void(*kernel_entry)(void); + int ret; + enum {rb, of} boot = rb; + power_init(); system_init(); kernel_init(); enable_irq(); - lcd_init_device(); - _backlight_on(); + adc_init(); + lcd_init(); + backlight_init(); + button_init_device(); + font_init(); lcd_setfont(FONT_SYSFIXED); show_logo(); - sleep(HZ*2); - -printf("show logo passed"); - // I2S init - SCU_CLKCFG &= ~((1<<17) | (1<<16)); // enable i2s, i2c pclk -//SCU_CLKCFG |= ((1<<17) | (1<<16)); - I2S_OPR = (1<<17) | // reset Tx - (1<<16) | // reset Rx - (1<<6) | // disable HDMA Req1 - (1<<5); // disable HDMA Req2 - - I2S_TXCTL = (1<<16) | // LRCK/SCLK = 64 - (4<<8) | // MCLK/SCK = 4 - (1<<4) | // 16bit samples - (0<<3) | // stereo mode - (0<<1); // I2S - - I2S_RXCTL = (1<<16) | // LRCK/SCLK = 64 - (4<<8) | // MCLK/SCK = 4 - (1<<4) | // 16bit samples - (0<<3) | // stereo mode - (0<<1); // I2S - - I2S_FIFOSTS = (1<<18) | // Tx int trigger half full - (1<<16); // Rx int trigger half full - - // I2S start - I2S_OPR = (1<<17) | (1<<16); - sleep(HZ/100); - - I2S_OPR = (0<<6) | // req channel 1 enable - (1<<5) | // req channel 2 disable - (0<<4) | // HDMA req channel 1 Tx - (0<<2) | // normal I2S operation (no loopback) - (1<<1); // Tx start - -printf("I2S config passed"); - - HDMA_ISRC0 = (uint32_t)&samples; - HDMA_IDST0 = (uint32_t)&I2S_TXR; - HDMA_ICNT0 = (sizeof(samples)/4) - 1; - HDMA_ISCNT0 = 7; - HDMA_IPNCNTD0 = 1; - HDMA_CON0 = (1<<22)| // slice mode - (1<<21)| // channel enable - (1<<18)| // interrupt mode - (5<<13)| // transfer mode inc8 - (6<<9) | // hdreq from i2s tx - (0<<7) | // source address increment - (1<<5) | // destination address fixed - (2<<3) | // data size word - (1<<0); // enable hardware triggered dma - - HDMA_ISR = (1<<13) | // mask ch1 page overflow - (1<<11) | // mask ch1 page count down - (1<<9); // mask ch1 interrupts - - INTC_IMR |= (1<<12); - INTC_IECR |= (1<<12); - -printf("HDMA config passed"); - - i2c_init(); - -printf("I2C config passed"); - - // codec init - codec_write(0x00, (1<<3)|(1<<2)|(1<<1)|(1<<0)); // AICR - codec_write(0x01, (1<<7)|(1<<5)|(1<<3)); // CR1 - codec_write(0x02, (1<<2)); // CR2 - codec_write(0x03, 0); // CCR1 - codec_write(0x04, (2<<4)|(2<<0)); // CCR2 - codec_write(0x07, (3<<5)|(3<<0)); // CCR - - - codec_write(0x0f, 0x1f|(2<<6)); // CGR6 - codec_write(0x14, (1<<1)); // TR1 - codec_write(0x05, (1<<6)|(1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1<<0)); // PMR1 - sleep(HZ/100); - - codec_write(0x06, (1<<3)|(1<<2)|(1<<0)); // PMR2 - - - codec_write(0x05, (1<<6)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1<<0)); // PMR1 - codec_write(0x05, (1<<4)|(1<<3)|(1<<2)|(1<<1)|(1<<0)); // PMR1 - - - // DACout mode - codec_write(0x01, (1<<7)|(1<<3)|(1<<5)|(1<<4)); // CR1 - codec_write(0x05, (1<<4)|(1<<3)|(1<<2)|(1<<1)|(1<<0)); //PMR1 -// codec_write(0x06, (1<<3)|(1<<2)); // PMR2 - -printf("codec init passed"); - - codec_write(0x01, (1<<7)|(1<<3)); // CR1 - - codec_write(0x0a, 0); // 0dB digital gain - codec_write(0x11, 15|(2<<6)); // - - while(1) + + int btn = button_read_device(); + + /* if there is some other button pressed + * besides POWER/PLAY we boot into OF + */ + if ((btn & ~POWEROFF_BUTTON)) + boot = of; + + /* if we are woken up by USB insert boot into OF */ + if (DEV_INFO & (1<<20)) + boot = of; + + lcd_clear_display(); + + ret = storage_init(); + if(ret < 0) + error(EATA, ret, true); + + while(!disk_init(IF_MV(0))) + panicf("disk_init failed!"); + + while((ret = disk_mount_all()) <= 0) + error(EDISK, ret, true); + + loadbuffer = (unsigned char*)DRAM_ORIG; /* DRAM */ + + if (boot == rb) + snprintf(filename,sizeof(filename), BOOTDIR "/%s", BOOTFILE); + else if (boot == of) + snprintf(filename,sizeof(filename), BOOTDIR "/%s", "BASE.RKW"); + + printf("Loading: %s", filename); + + ret = load_rkw(loadbuffer, filename, LOAD_SIZE); + if (ret < 0) + { + printf(rkw_strerror(ret)); + lcd_update(); + sleep(5*HZ); + power_off(); + } + else { - printf("HDMA_CCNT0: 0x%0x FIFOSTS: 0x%0x", HDMA_CCNT0, I2S_FIFOSTS); + printf(rkw_strerror(0)); + sleep(HZ); } + + kernel_entry = (void*) loadbuffer; + commit_discard_idcache(); + + printf("Executing"); + kernel_entry(); + + printf("ERR: Failed to boot"); + sleep(5*HZ); + power_off(); + + /* hang */ + while(1); } -- cgit v1.2.3