1
0
Fork 0
forked from len0rd/rockbox

Make the meizu m3 load from flash, so interrupts work. More work is needed to get the m6sl "working" again

(patch by Denes Balatoni, FS#9499)


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18827 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Frank Gevaerts 2008-10-18 22:28:59 +00:00
parent d8b2645a64
commit 49ec9ea190
6 changed files with 404 additions and 65 deletions

View file

@ -104,43 +104,32 @@ void bl_debug_int(unsigned int input,unsigned int count)
void main(void) void main(void)
{ {
char mystring[64]; char mystring[64];
int tmpval;
/* set fclk = 200MHz, hclk = 100MHz, pclk = 50MHz, others off */
CLKCON = 0x00800080;
PLLCON = 0;
PLL0PMS = 0x1ad200;
PLL0LCNT = 8100;
PLLCON = 1;
while (!(PLLLOCK & 1)) ;
CLKCON2= 0x80;
CLKCON = 0x20803180;
/* mask all interrupts
this is done, because the lcd framebuffer
overwrites some stuff, which leads to a freeze
when an irq is generated after the dfu upload.
crt0 should have disabled irqs,
but the bootrom hands us execution in
user mode so we can't switch interrupts off */
INTMSK = 0;
//Set backlight pin to output and enable //Set backlight pin to output and enable
int oldval = PCON0; int oldval = PCON0;
PCON0 = ((oldval & ~(3 << 4)) | (1 << 4)); PCON0 = ((oldval & ~(3 << 4)) | (1 << 4));
PDAT0 |= (1 << 2); PDAT0 |= (1 << 2);
//Set PLAY to input //power on
oldval = PCON1; // oldval = PCON1;
PCON1 = ((oldval & ~(0xf << 16)) | (0 << 16)); // PCON1 = ((oldval & ~(0xf << 12)) | (1 << 12));
// PDAT1|=(1<<3);
asm volatile("mrs %0, cpsr \n\t" //Set PLAY to EINT4
: "=r" (tmpval) oldval = PCON1;
); PCON1 = ((oldval & ~(0xf << 16)) | (2 << 16));
//Set MENU to EINT0
oldval = PCON1;
PCON1 = (oldval & ~(0xf)) | 2;
// enable external interrupts
EINTPOL = 0x11;
INTMSK = 0x11;
EINTMSK = 0x11;
asm volatile("msr cpsr_c, #0x13\n\t"); // enable interrupts
lcd_init(); lcd_init();
snprintf(mystring, 64, "tmpval: %x", tmpval);
lcd_puts(0,0,mystring);
lcd_update(); lcd_update();
init_qt1106(); init_qt1106();

View file

@ -360,6 +360,8 @@ target/arm/tcc77x/crt0.S
target/arm/tcc780x/crt0.S target/arm/tcc780x/crt0.S
#elif CONFIG_CPU==IMX31L #elif CONFIG_CPU==IMX31L
target/arm/imx31/crt0.S target/arm/imx31/crt0.S
#elif CONFIG_CPU==S5L8700
target/arm/s5l8700/crt0.S
#elif defined(CPU_ARM) #elif defined(CPU_ARM)
target/arm/crt0.S target/arm/crt0.S
#endif /* defined(CPU_*) */ #endif /* defined(CPU_*) */

View file

@ -75,10 +75,10 @@ unsigned int qt1106_io(unsigned int output)
while(!RDY) {} while(!RDY) {}
delay(10); // < 470 us delay(10*100); // < 470 us
CLRSS(); CLRSS();
delay(13); // > 22 us delay(13*100); // > 22 us
for (i = 0; i < 24; i++) { for (i = 0; i < 24; i++) {
@ -90,14 +90,14 @@ unsigned int qt1106_io(unsigned int output)
CLRMOSI(); CLRMOSI();
output <<= 1; output <<= 1;
delay(20); // >> 6.7 us delay(20*100); // >> 6.7 us
SETCLK(); SETCLK();
input <<= 1; input <<= 1;
input |= MISO; input |= MISO;
delay(20); // >> 6.7 us delay(20*100); // >> 6.7 us
} }
SETSS(); SETSS();

View file

@ -1,12 +1,12 @@
#include "config.h" #include "config.h"
ENTRY(start) ENTRY(_start)
OUTPUT_FORMAT(elf32-bigarm) OUTPUT_FORMAT(elf32-bigarm)
OUTPUT_ARCH(arm) OUTPUT_ARCH(arm)
STARTUP(target/arm/crt0.o) STARTUP(target/arm/s5l8700/crt0.o)
/* DRAMORIG is in fact 0x8000000 but remapped to 0x0 */ /* DRAMORIG is in fact 0x8000000 but remapped to 0x0 */
#define DRAMORIG 0x0 #define DRAMORIG 0x8000000
#define DRAMSIZE 16M #define DRAMSIZE 16M
#define IRAMORIG 0x22000000 #define IRAMORIG 0x22000000
@ -22,41 +22,67 @@ STARTUP(target/arm/crt0.o)
#define FLASHORIG 0x24000000 #define FLASHORIG 0x24000000
#define FLASHSIZE 1M #define FLASHSIZE 1M
MEMORY
{
DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
FLASH : ORIGIN = FLASHORIG, LENGTH = FLASHSIZE
}
SECTIONS SECTIONS
{ {
/*. = IRAMORIG; */ .intvect : {
/* As long as we don't flash the code, use the DFU load address */ _intvectstart = . ;
. = DFULOADADDR; *(.intvect)
_intvectend = _newstart ;
} >IRAM AT> FLASH
_intvectcopy = LOADADDR(.intvect) ;
.text : { .text : {
*(.init.text) *(.init.text)
*(.text*) *(.text*)
} *(.glue_7*)
} > FLASH
.rodata : {
*(.rodata*)
. = ALIGN(0x4);
} > FLASH
.data : { .data : {
*(.icode) _datastart = . ;
*(.irodata) *(.irodata)
*(.icode)
*(.idata) *(.idata)
*(.data*) *(.data*)
*(.ncdata*); *(.ncdata*);
. = ALIGN(0x4);
_dataend = . ; _dataend = . ;
} } > IRAM AT> FLASH
_datacopy = LOADADDR(.data) ;
.stack : .stack :
{ {
*(.stack) *(.stack)
_stackbegin = .; _stackbegin = .;
stackbegin = .; . += 0x2000;
. += 0x1000;
_stackend = .; _stackend = .;
stackend = .; _irqstackbegin = .;
} . += 0x400;
_irqstackend = .;
_fiqstackbegin = .;
. += 0x400;
_fiqstackend = .;
} > IRAM
.bss : { .bss : {
_edata = .; _edata = .;
*(.bss*); *(.bss*);
*(.ibss); *(.ibss);
*(.ncbss*); *(.ncbss*);
*(COMMON);
. = ALIGN(0x4);
_end = .; _end = .;
} } > IRAM
} }

View file

@ -0,0 +1,320 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id: crt0.S 18776 2008-10-11 18:32:17Z gevaerts $
*
* Copyright (C) 2008 by Marcoen Hirschberg
* Copyright (C) 2008 by Denes Balatoni
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "cpu.h"
.section .intvect,"ax",%progbits
.global _start
.global _newstart
/* Exception vectors */
_start:
b _newstart
ldr pc, =undef_instr_handler
ldr pc, =software_int_handler
ldr pc, =prefetch_abort_handler
ldr pc, =data_abort_handler
ldr pc, =reserved_handler
ldr pc, =irq_handler
ldr pc, =fiq_handler
#if CONFIG_CPU==S5L8700
.word 0x43554644 /* DFUC */
#endif
.ltorg
_newstart:
ldr pc, =newstart2 // we do not want to execute from 0x0 as iram will be mapped there
.section .init.text,"ax",%progbits
newstart2:
msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
mov r1, #0x80
mrc 15, 0, r0, c1, c0, 0
orr r0, r0, r1
mcr 15, 0, r0, c1, c0, 0 // set bigendian
ldr r1, =0x3c800000 // disable watchdog
mov r0, #0xa5
str r0, [r1]
mov r0, #0
ldr r1, =0x39c00008
str r0, [r1] // mask all interrupts
ldr r1, =0x39c00020
str r0, [r1] // mask all external interrupts
mvn r0, #0
mov r1, #0x39c00000
str r0, [r1] // irq priority
ldr r1, =0x39c00010
str r0, [r1] // clear pending interrupts
ldr r1, =0x39c0001c
str r0, [r1] // clear pending external interrupts
// ldr r1, =0x3cf00000
// ldr r0, [r1]
// mvn r2, #0x30
// and r0, r0, r2
// mov r2, #0x10
// orr r0, r0, r2
// str r0, [r1]
// ldr r1, =0x3cf00004
// ldr r0, [r1]
// mov r2, #4
// orr r0, r0, r2
// str r0, [r1] // switch backlight on
ldr r1, =0x3c500000 // CLKCON
ldr r0, =0x00800080
str r0, [r1]
ldr r1, =0x3c500024 // PLLCON
mov r0, #0
str r0, [r1]
ldr r1, =0x3c500004 // PLL0PMS
ldr r0, =0x1ad200
str r0, [r1]
ldr r1, =0x3c500014 // PLL0LCNT
ldr r0, =8100
str r0, [r1]
ldr r1, =0x3c500024 // PLLCON
mov r0, #1
str r0, [r1]
ldr r1, =0x3c500020 // PLLLOCK
1:
ldr r0, [r1]
tst r0, #1
beq 1b
ldr r1, =0x3c50003c // CLKCON2
mov r0, #0x80
str r0, [r1]
ldr r1, =0x3c500000 // CLKCON
ldr r0, =0x20803180
str r0, [r1] // FCLK_CPU = 200MHz, HCLK = 100MHz, PCLK = 50MHz, other clocks off
ldr r2, =0xc0000078
mrc 15, 0, r0, c1, c0, 0
mvn r1, #0xc0000000
and r0, r0, r1
orr r0, r0, r2
mcr 15, 0, r0, c1, c0, 0 // asynchronous clocking mode
nop
nop
nop
nop
// ldr r0, =0x10100000
// ldr r1, =0x38200034
// str r0, [r1] // SRAM0/1 data width 16 bit
// ldr r0, =0x00220922
// ldr r7, =0x38200038
// str r0, [r7] // SRAM0/1 clocks
// ldr r0, =0x00220922
// ldr r9, =0x3820003c
// str r0, [r9] // SRAM2/3 clocks
// nop
// nop
// nop
// nop
ldr r1, =0x3c500000
mov r0, #0 // 0x0
str r0, [r1, #40] // enable clock for all peripherals
mov r0, #0 // 0x0
str r0, [r1, #44] // do not enter any power saving mode
mov r1, #0x1
mrc 15, 0, r0, c1, c0, 0
bic r0, r0, r1
mcr 15, 0, r0, c1, c0, 0 // disable protection unit
mov r1, #0x4
mrc 15, 0, r0, c1, c0, 0
bic r0, r0, r1
mcr 15, 0, r0, c1, c0, 0 // dcache disable
mov r1, #0x1000
mrc 15, 0, r0, c1, c0, 0
bic r0, r0, r1
mcr 15, 0, r0, c1, c0, 0 // icache disable
mov r1, #0
1:
mov r0, #0
2:
orr r2, r1, r0
mcr 15, 0, r2, c7, c14, 2 // clean and flush dcache single entry
add r0, r0, #0x10
cmp r0, #0x40
bne 2b
add r1, r1, #0x4000000
cmp r1, #0x0
bne 1b
nop
nop
mov r0, #0
mcr 15, 0, r0, c7, c10, 4 // clean and flush whole dcache
mov r0, #0
mcr 15, 0, r0, c7, c5, 0 // flush icache
mov r0, #0
mcr 15, 0, r0, c7, c6, 0 // flush dcache
mov r0, #0x3f
mcr 15, 0, r0, c6, c0, 1
mov r0, #0x2f
mcr 15, 0, r0, c6, c1, 1
ldr r0, =0x0800002f
mcr 15, 0, r0, c6, c2, 1
ldr r0, =0x22000023
mcr 15, 0, r0, c6, c3, 1
ldr r0, =0x24000027
mcr 15, 0, r0, c6, c4, 1
mov r0, #0x3f
mcr 15, 0, r0, c6, c0, 0
mov r0, #0x2f
mcr 15, 0, r0, c6, c1, 0
ldr r0, =0x0800002f
mcr 15, 0, r0, c6, c2, 0
ldr r0, =0x22000023
mcr 15, 0, r0, c6, c3, 0
ldr r0, =0x24000029
mcr 15, 0, r0, c6, c4, 0
mov r0, #0x1e
mcr 15, 0, r0, c2, c0, 1
mov r0, #0x1e
mcr 15, 0, r0, c2, c0, 0
mov r0, #0x1e
mcr 15, 0, r0, c3, c0, 0
ldr r0, =0x0000ffff
mcr 15, 0, r0, c5, c0, 1
ldr r0, =0x0000ffff
mcr 15, 0, r0, c5, c0, 0 // set up protection and caching
mov r1, #0x4
mrc 15, 0, r0, c1, c0, 0
orr r0, r0, r1
mcr 15, 0, r0, c1, c0, 0 // dcache enable
mov r1, #0x1000
mrc 15, 0, r0, c1, c0, 0
orr r0, r0, r1
mcr 15, 0, r0, c1, c0, 0 // icache enable
mov r1, #0x1
mrc 15, 0, r0, c1, c0, 0
orr r0, r0, r1
mcr 15, 0, r0, c1, c0, 0 // enable protection unit
/* Copy interrupt vectors to iram */
ldr r2, =_intvectstart
ldr r3, =_intvectend
ldr r4, =_intvectcopy
1:
cmp r3, r2
ldrhi r1, [r4], #4
strhi r1, [r2], #4
bhi 1b
/* Initialise bss section to zero */
ldr r2, =_edata
ldr r3, =_end
mov r4, #0
1:
cmp r3, r2
strhi r4, [r2], #4
bhi 1b
/* Copy icode and data to ram */
ldr r2, =_datastart
ldr r3, =_dataend
ldr r4, =_datacopy
1:
cmp r3, r2
ldrhi r1, [r4], #4
strhi r1, [r2], #4
bhi 1b
/* Set up some stack and munge it with 0xdeadbeef */
ldr sp, =_stackend
ldr r2, =_stackbegin
ldr r3, =0xdeadbeef
1:
cmp sp, r2
strhi r3, [r2], #4
bhi 1b
/* Set up stack for IRQ mode */
msr cpsr_c, #0xd2
ldr sp, =_irqstackend
/* Set up stack for FIQ mode */
msr cpsr_c, #0xd1
ldr sp, =_fiqstackend
/* Let abort and undefined modes use IRQ stack */
msr cpsr_c, #0xd7
ldr sp, =_irqstackend
msr cpsr_c, #0xdb
ldr sp, =_irqstackend
/* Switch back to supervisor mode */
msr cpsr_c, #0xd3
// if we did not switch remap on, device
// would crash when MENU is pressed,
// as that button is connected to BOOT_MODE pin
ldr r1, =0x38200000
ldr r0, [r1]
mvn r2, #0x10000
and r0, r0, r2
mov r2, #0x1
orr r0, r0, r2
str r0, [r1] // remap iram to address 0x0
bl main
.text
/* .global UIE*/
/* All illegal exceptions call into UIE with exception address as first
* parameter. This is calculated differently depending on which exception
* we're in. Second parameter is exception number, used for a string lookup
* in UIE. */
undef_instr_handler:
mov r0, lr
mov r1, #0
b UIE
/* We run supervisor mode most of the time, and should never see a software
* exception being thrown. Perhaps make it illegal and call UIE? */
software_int_handler:
reserved_handler:
movs pc, lr
prefetch_abort_handler:
sub r0, lr, #4
mov r1, #1
b UIE
data_abort_handler:
sub r0, lr, #8
mov r1, #2
b UIE

View file

@ -69,7 +69,7 @@ void lcd_set_flip(bool yesno)
static void lcd_sleep(uint32_t t) static void lcd_sleep(uint32_t t)
{ {
volatile uint32_t i; volatile uint32_t i;
for(i=0;i<t;++i) t=t; for(i=0;i<t;++i);
} }
static uint8_t lcd_readdata() static uint8_t lcd_readdata()
@ -115,6 +115,7 @@ void lcd_off() {
void lcd_init_device(void) void lcd_init_device(void)
{ {
uint8_t data[5]; uint8_t data[5];
int i;
/* init basic things */ /* init basic things */
PWRCON &= ~0x800; PWRCON &= ~0x800;
@ -126,25 +127,26 @@ void lcd_init_device(void)
LCD_INTCON = 0; LCD_INTCON = 0;
LCD_RST_TIME = 0x7ff; LCD_RST_TIME = 0x7ff;
/* detect lcd type */ /* detect lcd type, it's not detected the first time for some reason */
LCD_WCMD = 0x1; for(i=0;i<3;++i) {
lcd_sleep(166670); LCD_WCMD = 0x1;
LCD_WCMD = 0x11; lcd_sleep(166670);
lcd_sleep(2000040); LCD_WCMD = 0x11;
lcd_readdata(); lcd_sleep(2000040);
LCD_WCMD = 0x4; lcd_readdata();
lcd_sleep(100); LCD_WCMD = 0x4;
data[0]=lcd_readdata(); lcd_sleep(100);
data[1]=lcd_readdata(); data[0]=lcd_readdata();
data[2]=lcd_readdata(); data[1]=lcd_readdata();
data[3]=lcd_readdata(); data[2]=lcd_readdata();
data[4]=lcd_readdata(); data[3]=lcd_readdata();
data[4]=lcd_readdata();
lcd_type=0;
if (((data[1]==0x38) && ((data[2] & 0xf0) == 0x80)) ||
((data[2]==0x38) && ((data[3] & 0xf0) == 0x80)))
lcd_type=1;
lcd_type=0;
if (((data[1]==0x38) && ((data[2] & 0xf0) == 0x80)) ||
((data[2]==0x38) && ((data[3] & 0xf0) == 0x80)))
lcd_type=1;
}
/* init lcd */ /* init lcd */
if (lcd_type == 1) { if (lcd_type == 1) {
LCD_WCMD = 0x3a; LCD_WCMD = 0x3a;