From 4dc2d8ddba2b1a4da44864b10de628bc45b8f653 Mon Sep 17 00:00:00 2001 From: Rob Purchase Date: Sat, 22 Mar 2008 19:41:51 +0000 Subject: Enable tick IRQs on TCC780x. The main menu is now working on the D2. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16749 a1c6a512-1295-4272-9138-f99709370657 --- bootloader/telechips.c | 4 - firmware/export/tcc780x.h | 9 +- firmware/target/arm/tcc780x/crt0.S | 83 ++++++++------- firmware/target/arm/tcc780x/kernel-tcc780x.c | 6 +- firmware/target/arm/tcc780x/system-tcc780x.c | 144 +++++++++++++++++++-------- firmware/target/arm/tcc780x/timer-tcc780x.c | 4 +- 6 files changed, 162 insertions(+), 88 deletions(-) diff --git a/bootloader/telechips.c b/bootloader/telechips.c index 8d2e36914b..305bdf3081 100644 --- a/bootloader/telechips.c +++ b/bootloader/telechips.c @@ -67,10 +67,6 @@ void* main(void) power_init(); system_init(); lcd_init(); - -#if defined(COWON_D2) - kernel_init(); -#endif adc_init(); button_init(); diff --git a/firmware/export/tcc780x.h b/firmware/export/tcc780x.h index 78211acf0a..89c2fdd9c4 100644 --- a/firmware/export/tcc780x.h +++ b/firmware/export/tcc780x.h @@ -107,15 +107,22 @@ #define CREQ (*(volatile unsigned long *)0xF3001004) #define IRQSEL (*(volatile unsigned long *)0xF300100C) #define MREQ (*(volatile unsigned long *)0xF3001014) +#define POL (*(volatile unsigned long *)0xF300101C) #define MIRQ (*(volatile unsigned long *)0xF3001028) #define MFIQ (*(volatile unsigned long *)0xF300102C) +#define MODE (*(volatile unsigned long *)0xF3001030) #define ALLMASK (*(volatile unsigned long *)0xF3001044) #define VAIRQ (*(volatile unsigned long *)0xF3001080) #define VAFIQ (*(volatile unsigned long *)0xF3001084) #define VNIRQ (*(volatile unsigned long *)0xF3001088) #define VNFIQ (*(volatile unsigned long *)0xF300108C) +#define VCTRL (*(volatile unsigned long *)0xF3001090) -#define TIMER_IRQ_MASK (1<<6) +#define IRQ_PRIORITY_TABLE ((volatile unsigned int *)0xF30010A0) + +#define TIMER0_IRQ_MASK (1<<6) +#define DAI_RX_IRQ_MASK (1<<14) +#define DAI_TX_IRQ_MASK (1<<15) /* Timer / Counters */ diff --git a/firmware/target/arm/tcc780x/crt0.S b/firmware/target/arm/tcc780x/crt0.S index af37b40814..05a8868d51 100644 --- a/firmware/target/arm/tcc780x/crt0.S +++ b/firmware/target/arm/tcc780x/crt0.S @@ -121,6 +121,52 @@ copied_start: msr cpsr, r0 ldr sp, =stackend + /* Enable MMU & caches. At present this is just doing what the OF does. + Ensure TCMs are enabled before copying the exception vectors to 0x0. */ + + mov r1, #0xf7000000 /* Virtual MMU Table base */ + + ldr r0, =0x1fe0c /* Region 0: 0x00000000-0xffffffff (4Gb) */ + str r0, [r1] /* AP: 3 EN: 1 DO: 0 CACHE_ALL */ + + ldr r0, =0x2801ae24 /* Region 1: 0x28000000-0x2fffffff (128Mb) */ + str r0, [r1,#4] /* AP: 3 EN: 1 DO: 1 BUFFERED */ + + ldr r0, =0x13e44 /* Region 2: 0x00000000-0x000fffff (1Mb) */ + str r0, [r1,#8] /* AP: 3 EN: 1 DO: 2 BUFFERED */ + + ldr r0, =0x4001ce60 /* Region 3: 0x40000000-0x5fffffff (512Mb) */ + str r0, [r1,#0xc] /* AP: 3 EN: 1 DO: 3 CACHE_NONE */ + + ldr r0, =0x6001be80 /* Region 4: 0x60000000-0x6fffffff (256Mb) */ + str r0, [r1,#0x10] /* AP: 3 EN: 1 DO: 4 CACHE_NONE */ + + ldr r0, =0x3801aea4 /* Region 5: 0x38000000-0x3fffffff (128Mb) */ + str r0, [r1,#0x14] /* AP: 3 EN: 1 DO: 5 BUFFERED */ + + ldr r0, =0x8001eec0 /* Region 6: 0x80000000-0xffffffff (2Gb) */ + str r0, [r1,#0x18] /* AP: 3 EN: 1 DO: 6 CACHE_NONE */ + + ldr r0, =0x1001aee0 /* Region 7: 0x10000000-0x17ffffff (128Mb) */ + str r0, [r1,#0x1c] /* AP: 3 EN: 1 DO: 7 CACHE_NONE */ + + add r1, r1, #0x8000 + mcr p15, 0, r1, c2, c0, 0 /* Set TTBR = TABBASE (Virtual TLB) */ + + ldr r0, =0x55555555 + mcr p15, 0, r0, c3, c0, 0 /* Domain access d0-d15 = 'client' */ + + ldr r0, =0xa0000011 + mcr p15, 0, r0, c9, c1, 0 /* Data TCM: 0xA0000000-0xA00001fff (8Kb) */ + mov r0, #0xd + mcr p15, 0, r0, c9, c1, 1 /* Instr. TCM: 0x00000000-0x00000fff (4Kb) */ + + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 /* Invalidate Icache */ + ldr r2, =0x5507d + mcr p15, 0, r2, c1, c0, 0 /* Enable MMU, I & D caches */ + mcr p15, 0, r0, c7, c6, 0 /* Invalidate Dcache */ + mcr p15, 0, r1, c8, c7, 0 /* Invalidate TLB */ #if !defined(BOOTLOADER) && !defined(STUB) @@ -193,43 +239,6 @@ copied_start: strhi r4, [r2], #4 bhi 1b - /* - Enable cache & TCM regions - TODO: This is just doing what the OF does at present. It needs to be - better understood and moved out to a separate MMU functions package. - */ - ldr r1, =0x1fe0c - mov r0, #0xf7000000 - str r1, [r0] - ldr r1, =0x2801ae24 - str r1, [r0,#4] - ldr r1, =0x13e44 - str r1, [r0,#8] - ldr r1, =0x4001ce60 - str r1, [r0,#0xc] - ldr r1, =0x6001be80 - str r1, [r0,#0x10] - ldr r1, =0x3801aea4 - str r1, [r0,#0x14] - ldr r1, =0x8001eec0 - str r1, [r0,#0x18] - ldr r1, =0x1001aee0 - str r1, [r0,#0x1c] - add r1, r0, #0x8000 /* r1 now = 0xf7008000 */ - ldr r0, =0xa0000011 - ldr r2, =0x5507d - mcr p15, 0, r0,c9,c1 /* data tcm region (enabled; 8kb; 0xa0000000) */ - mov r0, #0xd - mcr p15, 0, r0,c9,c1, 1 /* inst tcm region (enabled, 4kb, 0x00000000) */ - ldr r0, =0x55555555 - mcr p15, 0, r1,c2,c0 /* translation table base register = 0xf7008000 */ - mcr p15, 0, r0,c3,c0 /* domain access d0-d15 = 'client' */ - mov r0, #0 - mcr p15, 0, r0,c7,c5 /* invalidate icache */ - mcr p15, 0, r2,c1,c0 /* enable mmu, i & d caches */ - mcr p15, 0, r0,c7,c6 /* invalidate dcache */ - mcr p15, 0, r1,c8,c7 /* invalidate tlb */ - bl main /* main() should never return */ diff --git a/firmware/target/arm/tcc780x/kernel-tcc780x.c b/firmware/target/arm/tcc780x/kernel-tcc780x.c index e0d9c3342e..333823eef9 100644 --- a/firmware/target/arm/tcc780x/kernel-tcc780x.c +++ b/firmware/target/arm/tcc780x/kernel-tcc780x.c @@ -36,8 +36,8 @@ void tick_start(unsigned int interval_in_ms) TCFG0 = (1<<8) | (0<<4) | (1<<3) | 1; /* Unmask timer IRQ */ - MIRQ &= ~TIMER_IRQ_MASK; + IEN |= TIMER0_IRQ_MASK; } -/* NB: Since the 7801 has a single timer IRQ, the tick tasks are dispatched - as part of the central timer IRQ processing in timer-tcc780x.c */ +/* NB: Since we are using a single timer IRQ, tick tasks are dispatched as + part of the central timer IRQ processing in timer-tcc780x.c */ diff --git a/firmware/target/arm/tcc780x/system-tcc780x.c b/firmware/target/arm/tcc780x/system-tcc780x.c index 30221d180e..cf4256e879 100644 --- a/firmware/target/arm/tcc780x/system-tcc780x.c +++ b/firmware/target/arm/tcc780x/system-tcc780x.c @@ -33,49 +33,86 @@ default_interrupt(EXT0); default_interrupt(EXT1); default_interrupt(EXT2); default_interrupt(EXT3); -default_interrupt(IRQ4); -default_interrupt(IRQ5); -default_interrupt(TIMER); -default_interrupt(IRQ7); -default_interrupt(IRQ8); -default_interrupt(IRQ9); -default_interrupt(IRQ10); -default_interrupt(IRQ11); -default_interrupt(IRQ12); -default_interrupt(IRQ13); +default_interrupt(RTC); +default_interrupt(GPSB0); +default_interrupt(TIMER0); +default_interrupt(TIMER1); +default_interrupt(SCORE); +default_interrupt(SPDTX); +default_interrupt(VIDEO); +default_interrupt(GSIO); +default_interrupt(SCALER); +default_interrupt(I2C); default_interrupt(DAI_RX); default_interrupt(DAI_TX); -default_interrupt(IRQ16); -default_interrupt(IRQ17); -default_interrupt(IRQ18); -default_interrupt(IRQ19); -default_interrupt(IRQ20); -default_interrupt(IRQ21); -default_interrupt(IRQ22); -default_interrupt(IRQ23); -default_interrupt(IRQ24); -default_interrupt(IRQ25); -default_interrupt(IRQ26); -default_interrupt(IRQ27); -default_interrupt(IRQ28); -default_interrupt(IRQ29); -default_interrupt(IRQ30); -default_interrupt(IRQ31); +default_interrupt(CDRX); +default_interrupt(HPI); +default_interrupt(UART0); +default_interrupt(UART1); +default_interrupt(G2D); +default_interrupt(USB_DEVICE); +default_interrupt(USB_HOST); +default_interrupt(DMA); +default_interrupt(HDD); +default_interrupt(MSTICK); +default_interrupt(NFC); +default_interrupt(SDMMC); +default_interrupt(CAM); +default_interrupt(LCD); +default_interrupt(ADC); +default_interrupt(GPSB1); + +/* TODO: Establish IRQ priorities (0 = highest priority) */ +static const char irqpriority[] = +{ + 0, /* EXT0 */ + 1, /* EXT1 */ + 2, /* EXT2 */ + 3, /* EXT3 */ + 4, /* RTC */ + 5, /* GPSB0 */ + 6, /* TIMER0 */ + 7, /* TIMER1 */ + 8, /* SCORE */ + 9, /* SPDTX */ + 10, /* VIDEO */ + 11, /* GSIO */ + 12, /* SCALER */ + 13, /* I2C */ + 14, /* DAI_RX */ + 15, /* DAI_TX */ + 16, /* CDRX */ + 17, /* HPI */ + 18, /* UART0 */ + 19, /* UART1 */ + 20, /* G2D */ + 21, /* USB_DEVICE */ + 22, /* USB_HOST */ + 23, /* DMA */ + 24, /* HDD */ + 25, /* MSTICK */ + 26, /* NFC */ + 27, /* SDMMC */ + 28, /* CAM */ + 29, /* LCD */ + 30, /* ADC */ + 31, /* GPSB */ +}; static void (* const irqvector[])(void) = { - EXT0,EXT1,EXT2,EXT3,IRQ4,IRQ5,TIMER,IRQ7, - IRQ8,IRQ9,IRQ10,IRQ11,IRQ12,IRQ13,DAI_RX,DAI_TX, - IRQ16,IRQ17,IRQ18,IRQ19,IRQ20,IRQ21,IRQ22,IRQ23, - IRQ24,IRQ25,IRQ26,IRQ27,IRQ28,IRQ29,IRQ30,IRQ31 + EXT0,EXT1,EXT2,EXT3,RTC,GPSB0,TIMER0,TIMER1, + SCORE,SPDTX,VIDEO,GSIO,SCALER,I2C,DAI_RX,DAI_TX, + CDRX,HPI,UART0,UART1,G2D,USB_DEVICE,USB_HOST,DMA, + HDD,MSTICK,NFC,SDMMC,CAM,LCD,ADC,GPSB1 }; static const char * const irqname[] = { - "EXT0","EXT1","EXT2","EXT3","IRQ4","IRQ5","TIMER","IRQ7", - "IRQ8","IRQ9","IRQ10","IRQ11","IRQ12","IRQ13","DAI_RX","DAI_TX", - "IRQ16","IRQ17","IRQ18","IRQ19","IRQ20","IRQ21","IRQ22","IRQ23", - "IRQ24","IRQ25","IRQ26","IRQ27","IRQ28","IRQ29","IRQ30","IRQ31" + "EXT0","EXT1","EXT2","EXT3","RTC","GPSB0","TIMER0","TIMER1", + "SCORE","SPDTX","VIDEO","GSIO","SCALER","I2C","DAI_RX","DAI_TX", + "CDRX","HPI","UART0","UART1","G2D","USB_DEVICE","USB_HOST","DMA", + "HDD","MSTICK","NFC","SDMMC","CAM","LCD","ADC","GPSB1" }; static void UIRQ(void) @@ -92,17 +129,23 @@ void irq_handler(void) asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */ "sub sp, sp, #8 \n"); /* Reserve stack */ - irqvector[VNIRQ](); + + int irq_no = VNIRQ; /* Read clears the corresponding IRQ status */ + + if ((irq_no & (1<<31)) == 0) /* Ensure invalid flag is not set */ + { + irqvector[irq_no](); + } + asm volatile( "add sp, sp, #8 \n" /* Cleanup stack */ "ldmfd sp!, {r0-r7, ip, lr} \n" /* Restore context */ - "subs pc, lr, #4 \n"); /* Return from FIQ */ + "subs pc, lr, #4 \n"); /* Return from IRQ */ } void fiq_handler(void) { asm volatile ( - "sub lr, lr, #4 \r\n" - "movs lr,pc \r\n" + "subs pc, lr, #4 \r\n" ); } #endif /* !defined(BOOTLOADER) */ @@ -231,15 +274,36 @@ static void clock_init(void) #ifdef COWON_D2 void system_init(void) { + int i; + MBCFG = 0x19; if (TCC780_VER == 0) ECFG0 = 0x309; else ECFG0 = 0x30d; - + /* mask all interrupts */ - MIRQ = -1; + IEN = 0; + +#if !defined(BOOTLOADER) + + IRQSEL = -1; /* set all interrupts to be IRQs not FIQs */ + + POL = 0x200108; /* IRQs 3,8,21 active low (as OF) */ + MODE = 0x20ce07c0; /* IRQs 6-10,17-19,22-23,29 level-triggered (as OF) */ + + VCTRL |= (1<<31); /* Reading from VNIRQ clears that interrupt */ + + /* Write IRQ priority registers using ints - a freeze occurs otherwise */ + for (i = 0; i < 7; i++) + { + IRQ_PRIORITY_TABLE[i] = ((int*)irqpriority)[i]; + } + + ALLMASK = 3; /* Global FIQ/IRQ unmask */ + +#endif /* !defined(BOOTLOADER) */ gpio_init(); clock_init(); diff --git a/firmware/target/arm/tcc780x/timer-tcc780x.c b/firmware/target/arm/tcc780x/timer-tcc780x.c index c724c4b3a8..44a4cc0395 100644 --- a/firmware/target/arm/tcc780x/timer-tcc780x.c +++ b/firmware/target/arm/tcc780x/timer-tcc780x.c @@ -52,7 +52,7 @@ void __timer_unregister(void) extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); -void TIMER(void) +void TIMER0(void) { if (TIREQ & TF0) /* Timer0 reached ref value */ { @@ -77,6 +77,4 @@ void TIMER(void) { /* dispatch timer */ } - - CREQ |= TIMER_IRQ_MASK; /* clear IRQ */ } -- cgit v1.2.3