From 1f021af60cd0351a309666c2e32b3d1b8b2cbd6f Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Tue, 5 Feb 2008 04:43:19 +0000 Subject: Gigabeat S mixer: Make some progress. Get the tick and core sleep working using the AVIC. Redo the startup code to remap from IRAM and not include the lcd driver frambuffer in the remapping (until it can be moved). Clean up LCD driver. For other misc. changes, see the diffs. Now it progresses to ATA init and fails with -11 but without crashing or hanging. Replace all bootloaders. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16216 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/arm/imx31/gigabeat-s/avic-imx31.c | 305 +++++++++------------ firmware/target/arm/imx31/gigabeat-s/avic-imx31.h | 124 ++------- .../target/arm/imx31/gigabeat-s/kernel-imx31.c | 55 +++- .../target/arm/imx31/gigabeat-s/lcd-as-imx31.S | 222 --------------- firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c | 224 ++++++++------- firmware/target/arm/imx31/gigabeat-s/mmu-imx31.c | 4 + firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c | 8 - .../target/arm/imx31/gigabeat-s/system-imx31.c | 18 +- .../target/arm/imx31/gigabeat-s/system-target.h | 20 +- 9 files changed, 352 insertions(+), 628 deletions(-) delete mode 100644 firmware/target/arm/imx31/gigabeat-s/lcd-as-imx31.S (limited to 'firmware/target/arm/imx31/gigabeat-s') diff --git a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c index 8236a38014..99a52e56d5 100644 --- a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c @@ -20,204 +20,161 @@ #include "system.h" #include "imx31l.h" #include "avic-imx31.h" +#include "panic.h" #include "debug.h" +static const char * avic_int_names[64] = +{ + "RESERVED0", "RESERVED1", "RESERVED2", "I2C3", + "I2C2", "MPEG4_ENCODER", "RTIC", "FIR", + "MMC/SDHC2", "MMC/SDHC1", "I2C1", "SSI2", + "SSI1", "CSPI2", "CSPI1", "ATA", + "MBX", "CSPI3", "UART3", "IIM", + "SIM1", "SIM2", "RNGA", "EVTMON", + "KPP", "RTC", "PWN", "EPIT2", + "EPIT1", "GPT", "PWR_FAIL", "CCM_DVFS", + "UART2", "NANDFC", "SDMA", "USB_HOST1", + "USB_HOST2", "USB_OTG", "RESERVED3", "MSHC1", + "MSHC2", "IPU_ERR", "IPU", "RESERVED4", + "RESERVED5", "UART1", "UART4", "UART5", + "ETC_IRQ", "SCC_SCM", "SCC_SMN", "GPIO2", + "GPIO1", "CCM_CLK", "PCMCIA", "WDOG", + "GPIO3", "RESERVED6", "EXT_PWMG", "EXT_TEMP", + "EXT_SENS1", "EXT_SENS2", "EXT_WDOG", "EXT_TV" +}; + +static void UIE_VECTOR(void) +{ + set_interrupt_status(IRQ_FIQ_DISABLED, IRQ_FIQ_STATUS); + long offset = FIVECSR; + long offsetn = (long)NIVECSR >> 16; + + if (offsetn == -1) + offset = offsetn; /* Could be FIQ */ + + panicf("Unhandled %s %ld: %s", + offsetn >= 0 ? "IRQ" : "FIQ", offset, + offset >= 0 ? avic_int_names[offset] : ""); +} + +/* We use the AVIC */ +void __attribute__((naked)) irq_handler(void) +{ + panicf("Unhandled IRQ"); +} + +/* Accoring to section 9.3.5 of the UM, the AVIC doesn't accelerate + * fast interrupts and they must be dispatched */ +void __attribute__((naked)) fiq_handler(void) +{ + asm volatile ( + "mov r10, #0x6c000000 \n" /* load AVIC base address */ + "ldr r9, [r10, #0x44] \n" /* read FIVECSR of AVIC */ + "add r10, r10, #100 \n" /* move pointer to base of VECTOR table */ + "ldr r8, [r10, r9, lsl #2] \n" /* read FIQ vector from VECTOR table */ + "bx r8 \n" /* jump to FIQ service routine */ + ); +} + void avic_init(void) { - /*following the steps in the AVIC setup in imx31 man*/ + /* Disable all interrupts and set to unhandled */ + avic_disable_int(ALL); - /*Initialize interrupt structures*/ - int i,avicstart; - /*get start of avic_init section for address calculation*/ - __asm__ ("ldr %0,=_avicstart\n\t" - :"=r"(avicstart):); + /* Init all interrupts to type IRQ */ + avic_set_int_type(ALL, IRQ); - for(i=0; i < 64;i++) - { - imx31_int[i].name = (char *)&imx31_int_names[i]; - imx31_int[i].int_type=IRQ; - /*integer i MUST be multiplied by 8 b/c gnu as - generates 2 instructions for each vector instruction - in vector_init(). Hence the value of 8 byte intervals - between each vector start address*/ - imx31_int[i].addr=(avicstart+(i*8)); - imx31_int[i].priority=0; - imx31_int[i].pInt_Handler=Unhandled_Int; - } - - /*enable all Interrupts*/ - avic_enable_int(ALL,IRQ,0); - - /*Setup all interrupt type IRQ*/ - avic_set_int_type(ALL,IRQ); - - /*Set NM bit to enable VIC*/ - INTCNTL |= (1 << 18); + /* Set NM bit to enable VIC */ + INTCNTL |= INTCNTL_NM; - /*Setup Registers Vector0-Vector63 for interrupt handler functions*/ - for(i=0; i < 64;i++) - writel(imx31_int[i].addr,(VECTOR_BASE_ADDR+(i*8))); - - /*disable FIQ for now until the interrupt handlers are more mature...*/ - disable_fiq(); - /*enable_fiq();*/ - - /*enable IRQ in imx31 INTCNTL reg*/ - INTCNTL &= ~(NIDIS); - /*disable FIQ in imx31 INTCNTL reg*/ - INTCNTL |= FIDIS; - - /*enable IRQ in ARM11 core, enable VE bit in CP15 Control reg to enable VIC*/ - __asm__ ("mrs r0,cpsr\t\n" - "bic r0,r0,#0x80\t\n" - "msr cpsr,r0\t\n" - "mrc p15,0,r0,c1,c0,0\n\t" - "orr r0,r0,#0x1000000\n\t" - "mcr p15,0,r0,c1,c0,0\n\t"::: - "r0"); + /* Enable IRQ/FIQ in imx31 INTCNTL reg */ + INTCNTL &= ~(INTCNTL_ABFEN | INTCNTL_NIDIS | INTCNTL_FIDIS); + + /* Enable VE bit in CP15 Control reg to enable VIC */ + asm volatile ( + "mrc p15, 0, r0, c1, c0, 0 \n" + "orr r0, r0, #(1 << 24) \n" + "mcr p15, 0, r0, c1, c0, 0 \n" + : : : "r0"); + + /* Enable normal interrupts at all priorities */ + NIMASK = 16; } void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, - void (*pInt_Handler) (void)) -{ - int i; + void (*handler)(void)) +{ + int oldstatus = set_interrupt_status(IRQ_FIQ_DISABLED, + IRQ_FIQ_STATUS); - if(ints == ALL) + if (ints != ALL) /* No mass-enable allowed */ { - avic_set_int_type(ALL,intstype); - for(i=0;i<64;i++) - INTENNUM= (long)i; - if(!(*pInt_Handler)) - pInt_Handler=Unhandled_Int; - return; - } - - imx31_int[ints].int_type=intstype; - imx31_int[ints].pInt_Handler=pInt_Handler; - avic_set_int_type(ints,intstype); - INTENNUM=(long)ints; + avic_set_int_type(ints, intstype); + VECTOR(ints) = (long)handler; + INTENNUM = ints; + } + + set_interrupt_status(oldstatus, IRQ_FIQ_STATUS); } void avic_disable_int(enum IMX31_INT_LIST ints) { - int i; + long i; - if(ints == ALL) + if (ints == ALL) { - for(i=0;i<64;i++) - INTDISNUM=(long)i; - imx31_int[ints].pInt_Handler=Unhandled_Int; - return; + for (i = 0; i < 64; i++) + { + INTDISNUM = i; + VECTOR(i) = (long)UIE_VECTOR; + } } - - INTDISNUM=(long)ints; + else + { + INTDISNUM = ints; + VECTOR(ints) = (long)UIE_VECTOR; + } } -void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype) +static void set_int_type(int i, enum INT_TYPE intstype) { - int i; - if(ints == ALL) - { - imx31_int[ints].int_type=intstype; - for(i=0;i<64;i++) - { - if(intstype > CCM_DVFS) - INTTYPEH=(long)(intstype-32); - else INTTYPEL=(long)intstype; - } - return; - } - - imx31_int[ints].int_type=intstype; - if(intstype > CCM_DVFS) - INTTYPEH=(long)(intstype-32); - else INTTYPEL=(long)intstype; -} + volatile unsigned long *reg; + long val; -void Unhandled_Int(void) -{ - enum IMX31_INT_LIST ints = 0; - DEBUGF("Unhandled Interrupt:\n"); - DEBUGF("Name : %s\n",imx31_int[ints].name); - DEBUGF("Interrupt Type : "); - if(imx31_int[ints].int_type==IRQ) - DEBUGF("IRQ\n"); - else DEBUGF("FIQ\n"); - DEBUGF("Handler Address : 0x%x\n",imx31_int[ints].addr); - DEBUGF("Priority : %d",imx31_int[ints].priority); + if (i >= 32) + { + reg = &INTTYPEH; + val = 1L << (i - 32); + } + else + { + reg = &INTTYPEL; + val = 1L << i; + } + + if (intstype == IRQ) + val = *reg & ~val; + else + val = *reg | val; + + *reg = val; } -void vector_init(void) +void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype) { - - /*64 branch instructions, one for every vector in avic - A better idea would to calculate the shellcode for each of these - instructions...*/ - - - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED0].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED1].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED2].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[I2C3].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[I2C2].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MPEG4_ENCODER].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RTIC].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[FIR].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MMC_SDHC2].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MMC_SDHC1].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[I2C1].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SSI2].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SSI1].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[CSPI2].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[CSPI1].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[ATA].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MBX].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[CSPI3].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[UART3].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[IIM].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SIM1].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SIM2].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RNGA].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EVTMON].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[KPP].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RTC].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[PWN].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EPIT2].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EPIT1].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[GPT].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[PWR_FAIL].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[CCM_DVFS].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[UART2].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[NANDFC].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SDMA].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[USB_HOST1].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[USB_HOST2].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[USB_OTG].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED3].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MSHC1].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MSHC2].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[IPU_ERR].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[IPU].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED4].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED5].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[UART1].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[UART4].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[UART5].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[ETC_IRQ].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SCC_SCM].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SCC_SMN].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[GPIO2].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[GPIO1].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[CCM_CLK].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[PCMCIA].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[WDOG].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[GPIO3].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED6].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_PWMG].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_TEMP].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_SENS1].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_SENS2].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_WDOG].pInt_Handler)); - __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_TV].pInt_Handler)); - + int oldstatus = set_interrupt_status(IRQ_FIQ_DISABLED, + IRQ_FIQ_STATUS); + + if (ints == ALL) + { + int i; + for (i = 0; i < 64; i++) + set_int_type(i, intstype); + } + else + { + set_int_type(ints, intstype); + } + + set_interrupt_status(oldstatus, IRQ_FIQ_STATUS); } diff --git a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h index 53a37b353b..29a3ec8dd0 100644 --- a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h +++ b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h @@ -19,107 +19,37 @@ #ifndef AVIC_IMX31_H #define AVIC_IMX31_H - -enum INT_TYPE {IRQ=0,FIQ}; - -struct int_names { - char name[16]; +enum INT_TYPE +{ + IRQ = 0, + FIQ }; -static const struct int_names imx31_int_names[64] = -{ {"RESERVED0"}, - {"RESERVED1"}, - {"RESERVED2"}, - {"I2C3"}, - {"I2C2"}, - {"MPEG4_ENCODER"}, - {"RTIC"}, - {"FIR"}, - {"MMC/SDHC2"}, - {"MMC/SDHC1"}, - {"I2C1"}, - {"SSI2"}, - {"SSI1"}, - {"CSPI2"}, - {"CSPI1"}, - {"ATA"}, - {"MBX"}, - {"CSPI3"}, - {"UART3"}, - {"IIM"}, - {"SIM1"}, - {"SIM2"}, - {"RNGA"}, - {"EVTMON"}, - {"KPP"}, - {"RTC"}, - {"PWN"}, - {"EPIT2"}, - {"EPIT1"}, - {"GPT"}, - {"PWR_FAIL"}, - {"CCM_DVFS"}, - {"UART2"}, - {"NANDFC"}, - {"SDMA"}, - {"USB_HOST1"}, - {"USB_HOST2"}, - {"USB_OTG"}, - {"RESERVED3"}, - {"MSHC1"}, - {"MSHC2"}, - {"IPU_ERR"}, - {"IPU"}, - {"RESERVED4"}, - {"RESERVED5"}, - {"UART1"}, - {"UART4"}, - {"UART5"}, - {"ETC_IRQ"}, - {"SCC_SCM"}, - {"SCC_SMN"}, - {"GPIO2"}, - {"GPIO1"}, - {"CCM_CLK"}, - {"PCMCIA"}, - {"WDOG"}, - {"GPIO3"}, - {"RESERVED6"}, - {"EXT_PWMG"}, - {"EXT_TEMP"}, - {"EXT_SENS1"}, - {"EXT_SENS2"}, - {"EXT_WDOG"}, - {"EXT_TV"} }; - -enum IMX31_INT_LIST { - RESERVED0 = 0,RESERVED1,RESERVED2,I2C3, - I2C2,MPEG4_ENCODER,RTIC,FIR,MMC_SDHC2, - MMC_SDHC1,I2C1,SSI2,SSI1,CSPI2,CSPI1, - ATA,MBX,CSPI3,UART3,IIM,SIM1,SIM2, - RNGA,EVTMON,KPP,RTC,PWN,EPIT2,EPIT1, - GPT,PWR_FAIL,CCM_DVFS,UART2,NANDFC, - SDMA,USB_HOST1,USB_HOST2,USB_OTG, - RESERVED3,MSHC1,MSHC2,IPU_ERR,IPU, - RESERVED4,RESERVED5,UART1,UART4,UART5, - ETC_IRQ,SCC_SCM,SCC_SMN,GPIO2,GPIO1, - CCM_CLK,PCMCIA,WDOG,GPIO3,RESERVED6, - EXT_PWMG,EXT_TEMP,EXT_SENS1,EXT_SENS2, - EXT_WDOG,EXT_TV,ALL }; - -static struct avic_int { - char * name; - enum INT_TYPE int_type; - unsigned int addr; - unsigned int priority; - void (*pInt_Handler) (void); -} imx31_int[64]; +enum IMX31_INT_LIST +{ + __IMX31_INT_FIRST = -1, + RESERVED0, RESERVED1, RESERVED2, I2C3, + I2C2, MPEG4_ENCODER, RTIC, FIR, + MMC_SDHC2, MMC_SDHC1, I2C1, SSI2, + SSI1, CSPI2, CSPI1, ATA, + MBX, CSPI3, UART3, IIM, + SIM1, SIM2, RNGA, EVTMON, + KPP, RTC, PWN, EPIT2, + EPIT1, GPT, PWR_FAIL, CCM_DVFS, + UART2, NANDFC, SDMA, USB_HOST1, + USB_HOST2, USB_OTG, RESERVED3, MSHC1, + MSHC2, IPU_ERR, IPU, RESERVED4, + RESERVED5, UART1, UART4, UART5, + ETC_IRQ, SCC_SCM, SCC_SMN, GPIO2, + GPIO1, CCM_CLK, PCMCIA, WDOG, + GPIO3, RESERVED6, EXT_PWMG, EXT_TEMP, + EXT_SENS1, EXT_SENS2, EXT_WDOG, EXT_TV, + ALL +}; void avic_init(void); void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, - void (*pInt_Handler) (void)); -void avic_disable_int(enum IMX31_INT_LIST ints) ; + void (*handler)(void)); +void avic_disable_int(enum IMX31_INT_LIST ints); void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype); -void Unhandled_Int(void); -void vector_init(void) __attribute__ ((section(".avic_int"),naked)); #endif diff --git a/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c b/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c index 9df90a2344..7f882405a5 100644 --- a/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c @@ -1,25 +1,60 @@ +#include "config.h" +#include "system.h" +#include "avic-imx31.h" #include "kernel.h" #include "thread.h" - #include -#include "lcd.h" extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); -void timer4(void) { - int i; +#ifndef BOOTLOADER +static __attribute__((interrupt("IRQ"))) void EPIT1_HANDLER(void) +{ + int i; + + EPITSR1 = 1; /* Clear the pending status */ + /* Run through the list of tick tasks */ - for(i = 0; i < MAX_NUM_TICK_TASKS; i++) + for(i = 0;i < MAX_NUM_TICK_TASKS;i++) { if(tick_funcs[i]) - { tick_funcs[i](); - } } current_tick++; - - /* following needs to be fixed. */ - /*wake_up_thread();*/ } +#endif + +void tick_start(unsigned int interval_in_ms) +{ + EPITCR1 &= ~(1 << 0); /* Disable the counter */ + EPITCR1 |= (1 << 16); /* Reset */ + CLKCTL_CGR0 |= (0x3 << 6); /* Clock ON */ + CLKCTL_WIMR0 &= ~(1 << 23); /* Clear wakeup mask */ + + /* NOTE: This isn't really accurate yet but it's close enough to work + * with for the moment */ + + /* CLKSRC=32KHz, EPIT Output Disconnected, Enabled + * prescale 1/32, Reload from modulus register, Compare interrupt enabled, + * Count from load value */ + EPITCR1 = (0x3 << 24) | (1 << 19) | (32 << 4) | + (1 << 3) | (1 << 2) | (1 << 1); + EPITSR1 = 1; /* Clear any pending interrupt */ +#ifndef BOOTLOADER + EPITLR1 = interval_in_ms; + EPITCMPR1 = 0; /* Event when counter reaches 0 */ + avic_enable_int(EPIT1, IRQ, EPIT1_HANDLER); +#else + (void)interval_in_ms; +#endif + + EPITCR1 |= (1 << 0); /* Enable the counter */ + + /* Why does only this trigger the counter? Remove when we find out. */ + asm volatile ( + "mcr p15, 0, %0, c7, c0, 4 \n" + : : "r" (0) + ); +} diff --git a/firmware/target/arm/imx31/gigabeat-s/lcd-as-imx31.S b/firmware/target/arm/imx31/gigabeat-s/lcd-as-imx31.S deleted file mode 100644 index d431c95f29..0000000000 --- a/firmware/target/arm/imx31/gigabeat-s/lcd-as-imx31.S +++ /dev/null @@ -1,222 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2007 by Michael Sevakis - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "config.h" -#include "cpu.h" - -/**************************************************************************** - * void lcd_write_yuv_420_lines(fb_data *dst, - * unsigned char chroma_buf[LCD_HEIGHT/2*3], - unsigned char const * const src[3], - * int width, - * int stride); - * - * |R| |1.000000 -0.000001 1.402000| |Y'| - * |G| = |1.000000 -0.334136 -0.714136| |Pb| - * |B| |1.000000 1.772000 0.000000| |Pr| - * Scaled, normalized, rounded and tweaked to yield RGB 565: - * |R| |74 0 101| |Y' - 16| >> 9 - * |G| = |74 -24 -51| |Cb - 128| >> 8 - * |B| |74 128 0| |Cr - 128| >> 9 - */ - .section .icode, "ax", %progbits - .align 2 - .global lcd_write_yuv420_lines - .type lcd_write_yuv420_lines, %function -lcd_write_yuv420_lines: - @ r0 = dst - @ r1 = chroma_buf - @ r2 = yuv_src - @ r3 = width - @ [sp] = stride - stmdb sp!, { r4-r12, lr } @ save non-scratch - stmdb sp!, { r0, r3 } @ save dst and width - mov r14, #74 @ r14 = Y factor - ldmia r2, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p - @ r5 = yuv_src[1] = Cb_p - @ r6 = yuv_src[2] = Cr_p -10: @ loop line 1 @ - ldrb r2, [r4], #1 @ r2 = *Y'_p++; - ldrb r8, [r5], #1 @ r8 = *Cb_p++; - ldrb r11, [r6], #1 @ r11 = *Cr_p++; - @ - @ compute Y - sub r2, r2, #16 @ r7 = Y = (Y' - 16)*74 - mul r7, r2, r14 @ - @ - sub r8, r8, #128 @ Cb -= 128 - sub r11, r11, #128 @ Cr -= 128 - @ - mvn r2, #24 @ compute guv - mul r10, r2, r8 @ r10 = Cb*-24 - mvn r2, #51 @ - mla r10, r2, r11, r10 @ r10 = r10 + Cr*-51 - @ - mov r2, #101 @ compute rv - mul r9, r11, r2 @ r9 = rv = Cr*101 - @ - @ store chromas in line buffer - add r8, r8, #2 @ bu = (Cb + 2) >> 2 - mov r8, r8, asr #2 @ - strb r8, [r1], #1 @ - add r9, r9, #256 @ rv = (Cr + 256) >> 9 - mov r9, r9, asr #9 @ - strb r9, [r1], #1 @ - mov r10, r10, asr #8 @ guv >>= 8 - strb r10, [r1], #1 @ - @ compute R, G, and B - add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu - add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv - add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv - @ - orr r12, r2, r11 @ check if clamping is needed... - orr r12, r12, r7, asr #1 @ ...at all - cmp r12, #31 @ - bls 15f @ no clamp @ - mov r12, #31 @ - cmp r12, r2 @ clamp b - andlo r2, r12, r2, asr #31 @ - eorlo r2, r2, r12 @ - cmp r12, r11 @ clamp r - andlo r11, r12, r11, asr #31 @ - eorlo r11, r11, r12 @ - cmp r12, r7, asr #1 @ clamp g - andlo r7, r12, r7, asr #31 @ - eorlo r7, r7, r12 @ - orrlo r7, r7, r7, asl #1 @ -15: @ no clamp @ - @ - orr r12, r2, r7, lsl #5 @ r4 |= (g << 5) - ldrb r2, [r4], #1 @ r2 = Y' = *Y'_p++ - orr r12, r12, r11, lsl #11 @ r4 = b | (r << 11) - strh r12, [r0], #240 @ store pixel - @ - sub r2, r2, #16 @ r7 = Y = (Y' - 16)*74 - mul r7, r2, r14 @ next Y - @ compute R, G, and B - add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu - add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv - add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv - @ - orr r12, r2, r11 @ check if clamping is needed... - orr r12, r12, r7, asr #1 @ ...at all - cmp r12, #31 @ - bls 15f @ no clamp @ - mov r12, #31 @ - cmp r12, r2 @ clamp b - andlo r2, r12, r2, asr #31 @ - eorlo r2, r2, r12 @ - cmp r12, r11 @ clamp r - andlo r11, r12, r11, asr #31 @ - eorlo r11, r11, r12 @ - cmp r12, r7, asr #1 @ clamp g - andlo r7, r12, r7, asr #31 @ - eorlo r7, r7, r12 @ - orrlo r7, r7, r7, asl #1 @ -15: @ no clamp @ - @ - orr r12, r2, r11, lsl #11 @ r4 = b | (r << 11) - orr r12, r12, r7, lsl #5 @ r4 |= (g << 5) - strh r12, [r0, #240]! @ store pixel - add r0, r0, #2*240 @ - @ - subs r3, r3, #2 @ - bgt 10b @ loop line 1 @ - @ do second line - @ - ldmia sp!, { r0, r3 } @ pop dst and width - sub r0, r0, #2 @ set dst to start of next line - sub r1, r1, r3, asl #1 @ rewind chroma pointer... - ldr r2, [sp, #40] @ r2 = stride - add r1, r1, r3, asr #1 @ ... (r1 -= width/2*3) - @ move sources to start of next line - sub r2, r2, r3 @ r2 = skip = stride - width - add r4, r4, r2 @ r4 = Y'_p + skip - @ -20: @ loop line 2 @ - ldrb r2, [r4], #1 @ r7 = Y' = *Y'_p++ - ldrsb r8, [r1], #1 @ reload saved chromas - ldrsb r9, [r1], #1 @ - ldrsb r10, [r1], #1 @ - @ - sub r2, r2, #16 @ r2 = Y = (Y' - 16)*74 - mul r7, r2, r14 @ - @ compute R, G, and B - add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu - add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv - add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv - @ - orr r12, r2, r11 @ check if clamping is needed... - orr r12, r12, r7, asr #1 @ ...at all - cmp r12, #31 @ - bls 25f @ no clamp @ - mov r12, #31 @ - cmp r12, r2 @ clamp b - andlo r2, r12, r2, asr #31 @ - eorlo r2, r2, r12 @ - cmp r12, r11 @ clamp r - andlo r11, r12, r11, asr #31 @ - eorlo r11, r11, r12 @ - cmp r12, r7, asr #1 @ clamp g - andlo r7, r12, r7, asr #31 @ - eorlo r7, r7, r12 @ - orrlo r7, r7, r7, asl #1 @ -25: @ no clamp @ - @ - orr r12, r2, r11, lsl #11 @ r4 = b | (r << 11) - ldrb r2, [r4], #1 @ r2 = Y' = *Y'_p++ - orr r12, r12, r7, lsl #5 @ r4 |= (g << 5) - strh r12, [r0], #240 @ store pixel - @ - @ do second pixel - @ - sub r2, r2, #16 @ r2 = Y = (Y' - 16)*74 - mul r7, r2, r14 @ - @ compute R, G, and B - add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu - add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv - add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv - @ - orr r12, r2, r11 @ check if clamping is needed... - orr r12, r12, r7, asr #1 @ ...at all - cmp r12, #31 @ - bls 25f @ no clamp @ - mov r12, #31 @ - cmp r12, r2 @ clamp b - andlo r2, r12, r2, asr #31 @ - eorlo r2, r2, r12 @ - cmp r12, r11 @ clamp r - andlo r11, r12, r11, asr #31 @ - eorlo r11, r11, r12 @ - cmp r12, r7, asr #1 @ clamp g - andlo r7, r12, r7, asr #31 @ - eorlo r7, r7, r12 @ - orrlo r7, r7, r7, asl #1 @ -25: @ no clamp @ - @ - orr r12, r2, r11, lsl #11 @ r4 = b | (r << 11) - orr r12, r12, r7, lsl #5 @ r4 |= (g << 5) - strh r12, [r0, #240]! @ store pixel - add r0, r0, #2*240 @ - @ - subs r3, r3, #2 @ - bgt 20b @ loop line 2 @ - @ - ldmia sp!, { r4-r12, pc } @ restore registers and return - .size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines diff --git a/firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c b/firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c index c9cce6d653..b39ddbe77d 100644 --- a/firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c @@ -9,12 +9,15 @@ static volatile bool lcd_on = true; volatile bool lcd_poweroff = false; +static unsigned lcd_yuv_options = 0; /* ** These are imported from lcd-16bit.c */ extern unsigned fg_pattern; extern unsigned bg_pattern; +extern struct viewport* current_vp; + #if 0 bool lcd_enabled() { @@ -22,68 +25,60 @@ bool lcd_enabled() } #endif -void printscreen(unsigned int colour) { +void printscreen(unsigned int colour) +{ int i; - int base = 0x84100000; - for(i=0;i<(320*240*2);i++) { - writel(colour,base); + char * base = (char *)FRAME; + for(i = 0; i < (320*240*2); i++) + { + writel(colour, base); base++; } } -unsigned int LCDBANK(unsigned int address) -{ - return ((address >> 22) & 0xff); -} - -unsigned int LCDBASEU(unsigned int address) -{ - return (address & ((1 << 22)-1)) >> 1; -} - -unsigned int LCDBASEL(unsigned int address) -{ - address += 320*240*2; - return (address & ((1 << 22)-1)) >> 1; -} - - /* LCD init */ void lcd_init_device(void) { - int i; -#ifdef BOOTLOADER - /* When the Rockbox bootloader starts, we are changing framebuffer address, - but we don't want what's shown on the LCD to change until we do an - lcd_update(), so copy the data from the old framebuffer to the new one */ - unsigned short *buf = (unsigned short*)FRAME1; - - memcpy(FRAME1, (short *)((LCDSADDR1)<<1), 320*240*2); - - /* The Rockbox bootloader is transitioning from RGB555I to RGB565 mode - so convert the frambuffer data accordingly */ - for(i=0; i< 320*240; i++){ - *buf = ((*buf>>1) & 0x1F) | (*buf & 0xffc0); - buf++; - } - return; -#endif } /* Update a fraction of the display. */ void lcd_update_rect(int x, int y, int width, int height) { - (void)x; - (void)width; - (void)y; - (void)height; + fb_data *dst, *src; - if(!lcd_on) - { - sleep(200); + if (!lcd_on) return; + + if (x + width > LCD_WIDTH) + width = LCD_WIDTH - x; /* Clip right */ + if (x < 0) + width += x, x = 0; /* Clip left */ + if (width <= 0) + return; /* nothing left to do */ + + if (y + height > LCD_HEIGHT) + height = LCD_HEIGHT - y; /* Clip bottom */ + if (y < 0) + height += y, y = 0; /* Clip top */ + if (height <= 0) + return; /* nothing left to do */ + + /* TODO: It may be faster to swap the addresses of lcd_driver_framebuffer + * and lcd_framebuffer */ + dst = (fb_data *)FRAME + LCD_WIDTH*y + x; + src = &lcd_framebuffer[y][x]; + + /* Copy part of the Rockbox framebuffer to the second framebuffer */ + if (width < LCD_WIDTH) + { + /* Not full width - do line-by-line */ + lcd_copy_buffer_rect(dst, src, width, height); + } + else + { + /* Full width - copy as one line */ + lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1); } - memcpy(((char*)FRAME2) + (y * sizeof(fb_data) * LCD_WIDTH), ((char *)&lcd_framebuffer) + (y * sizeof(fb_data) * LCD_WIDTH), ((height * sizeof(fb_data) * LCD_WIDTH))); } void lcd_enable(bool state) @@ -100,68 +95,82 @@ bool lcd_enabled(void) This must be called after all other LCD functions that change the display. */ void lcd_update(void) { - lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); + if (!lcd_on) + return; + + lcd_copy_buffer_rect((fb_data *)FRAME, &lcd_framebuffer[0][0], + LCD_WIDTH*LCD_HEIGHT, 1); } void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, int stride, int x, int y, int width, int height) { - fb_data *dst, *dst_end; - unsigned int transcolor; - - /* nothing to draw? */ - if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) - || (x + width <= 0) || (y + height <= 0)) - return; +#if 0 + int w, px; + fb_data *dst; - /* clipping */ - if (x < 0) - { - width += x; - src_x -= x; - x = 0; - } - if (y < 0) - { - height += y; - src_y -= y; - y = 0; - } if (x + width > LCD_WIDTH) - width = LCD_WIDTH - x; + width = LCD_WIDTH - x; /* Clip right */ + if (x < 0) + width += x, x = 0; /* Clip left */ + if (width <= 0) + return; /* nothing left to do */ + if (y + height > LCD_HEIGHT) - height = LCD_HEIGHT - y; + height = LCD_HEIGHT - y; /* Clip bottom */ + if (y < 0) + height += y, y = 0; /* Clip top */ + if (height <= 0) + return; /* nothing left to do */ src += stride * src_y + src_x; /* move starting point */ - dst = &lcd_framebuffer[(y)][(x)]; - dst_end = dst + height * LCD_WIDTH; - width *= 2; - stride *= 2; - transcolor = TRANSPARENT_COLOR; - asm volatile( - "rowstart: \n" - "mov r0, #0 \n" - "nextpixel: \n" - "ldrh r1, [%0, r0] \n" /* Load word src+r0 */ - "cmp r1, %5 \n" /* Compare to transparent color */ - "strneh r1, [%1, r0] \n" /* Store dst+r0 if not transparent */ - "add r0, r0, #2 \n" - "cmp r0, %2 \n" /* r0 == width? */ - "bne nextpixel \n" /* More in this row? */ - "add %0, %0, %4 \n" /* src += stride */ - "add %1, %1, #480 \n" /* dst += LCD_WIDTH (x2) */ - "cmp %1, %3 \n" - "bne rowstart \n" /* if(dst != dst_end), keep going */ - : : "r" (src), "r" (dst), "r" (width), "r" (dst_end), "r" (stride), "r" (transcolor) : "r0", "r1" ); + dst = &lcd_framebuffer[y][x]; + + asm volatile ( + ".rowstart: \r\n" + "mov %[w], %[width] \r\n" /* Load width for inner loop */ + ".nextpixel: \r\n" + "ldrh %[px], [%[s]], #2 \r\n" /* Load src pixel */ + "add %[d], %[d], #2 \r\n" /* Uncoditionally increment dst */ + "cmp %[px], %[fgcolor] \r\n" /* Compare to foreground color */ + "streqh %[fgpat], [%[d], #-2] \r\n" /* Store foregroud if match */ + "cmpne %[px], %[transcolor] \r\n" /* Compare to transparent color */ + "strneh %[px], [%[d], #-2] \r\n" /* Store dst if not transparent */ + "subs %[w], %[w], #1 \r\n" /* Width counter has run down? */ + "bgt .nextpixel \r\n" /* More in this row? */ + "add %[s], %[s], %[sstp], lsl #1 \r\n" /* Skip over to start of next line */ + "add %[d], %[d], %[dstp], lsl #1 \r\n" + "subs %[h], %[h], #1 \r\n" /* Height counter has run down? */ + "bgt .rowstart \r\n" /* More rows? */ + : [w]"=&r"(w), [h]"+&r"(height), [px]"=&r"(px), + [s]"+&r"(src), [d]"+&r"(dst) + : [width]"r"(width), + [sstp]"r"(stride - width), + [dstp]"r"(LCD_WIDTH - width), + [transcolor]"r"(TRANSPARENT_COLOR), + [fgcolor]"r"(REPLACEWITHFG_COLOR), + [fgpat]"r"(current_vp->fg_pattern) + ); +#endif +} + +void lcd_yuv_set_options(unsigned options) +{ + lcd_yuv_options = options; } /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ extern void lcd_write_yuv420_lines(fb_data *dst, - unsigned char chroma_buf[LCD_HEIGHT/2*3], unsigned char const * const src[3], int width, int stride); +extern void lcd_write_yuv420_lines_odither(fb_data *dst, + unsigned char const * const src[3], + int width, + int stride, + int x_screen, /* To align dither pattern */ + int y_screen); /* Performance function to blit a YUV bitmap directly to the LCD */ /* For the Gigabeat - show it rotated */ /* So the LCD_WIDTH is now the height */ @@ -171,7 +180,6 @@ void lcd_yuv_blit(unsigned char * const src[3], { /* Caches for chroma data so it only need be recaculated every other line */ - unsigned char chroma_buf[LCD_HEIGHT/2*3]; /* 480 bytes */ unsigned char const * yuv_src[3]; off_t z; @@ -182,23 +190,39 @@ void lcd_yuv_blit(unsigned char * const src[3], width &= ~1; height >>= 1; - fb_data *dst = (fb_data*)FRAME1 + x * LCD_WIDTH + (LCD_WIDTH - y) - 1; + y = LCD_WIDTH - 1 - y; + fb_data *dst = (fb_data*)FRAME + x * LCD_WIDTH + y; z = stride*src_y; yuv_src[0] = src[0] + z + src_x; yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); yuv_src[2] = src[2] + (yuv_src[1] - src[1]); - do + if (lcd_yuv_options & LCD_YUV_DITHER) + { + do + { + lcd_write_yuv420_lines_odither(dst, yuv_src, width, stride, y, x); + yuv_src[0] += stride << 1; /* Skip down two luma lines */ + yuv_src[1] += stride >> 1; /* Skip down one chroma line */ + yuv_src[2] += stride >> 1; + dst -= 2; + y -= 2; + } + while (--height > 0); + } + else { - lcd_write_yuv420_lines(dst, chroma_buf, yuv_src, width, - stride); - yuv_src[0] += stride << 1; /* Skip down two luma lines */ - yuv_src[1] += stride >> 1; /* Skip down one chroma line */ - yuv_src[2] += stride >> 1; - dst -= 2; + do + { + lcd_write_yuv420_lines(dst, yuv_src, width, stride); + yuv_src[0] += stride << 1; /* Skip down two luma lines */ + yuv_src[1] += stride >> 1; /* Skip down one chroma line */ + yuv_src[2] += stride >> 1; + dst -= 2; + } + while (--height > 0); } - while (--height > 0); } void lcd_set_contrast(int val) { diff --git a/firmware/target/arm/imx31/gigabeat-s/mmu-imx31.c b/firmware/target/arm/imx31/gigabeat-s/mmu-imx31.c index e8ec495449..e116439217 100644 --- a/firmware/target/arm/imx31/gigabeat-s/mmu-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/mmu-imx31.c @@ -21,16 +21,20 @@ #include "mmu-arm.h" void memory_init(void) { +#if 0 ttb_init(); set_page_tables(); enable_mmu(); +#endif } void set_page_tables() { +#if 0 map_section(0, 0, 0x1000, CACHE_NONE); /* map every memory region to itself */ /*This pa *might* change*/ map_section(0x80000000, 0, 64, CACHE_ALL); /* map RAM to 0 and enable caching for it */ map_section((int)FRAME1, (int)FRAME1, 1, BUFFERED); /* enable buffered writing for the framebuffer */ map_section((int)FRAME2, (int)FRAME2, 1, BUFFERED); +#endif } diff --git a/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c b/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c index b62051e41d..8485679aa4 100644 --- a/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c @@ -27,8 +27,6 @@ static int pcm_freq = HW_SAMPR_DEFAULT; /* 44.1 is default */ -void fiq_handler(void) __attribute__((naked)); - void pcm_play_lock(void) { } @@ -77,12 +75,6 @@ void pcm_play_dma_pause(bool pause) { } -/* Get more samples to play out - call pcm_play_dma_stop and - pcm_play_dma_stopped_callback if the data runs out */ -void fiq_handler(void) -{ -} - /* Set the pcm frequency hardware will use when play is next started or when pcm_apply_settings is called. Do not apply the setting to the hardware here but simply cache it. */ diff --git a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c index 544ae3afe6..ed5a26cd6e 100644 --- a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c @@ -13,27 +13,15 @@ int system_memory_guard(int newmode) return 0; } -extern void timer4(void); -extern void dma0(void); /* free */ -extern void dma1(void); -extern void dma3(void); - -void irq_handler(void) -{ -} - -#ifdef BOOTLOADER -void fiq_handler(void) -{ -} -#endif - void system_reboot(void) { } void system_init(void) { +#ifndef BOOTLOADER + avic_init(); +#endif } inline void dumpregs(void) diff --git a/firmware/target/arm/imx31/gigabeat-s/system-target.h b/firmware/target/arm/imx31/gigabeat-s/system-target.h index e87b93b13a..1f7a2475af 100644 --- a/firmware/target/arm/imx31/gigabeat-s/system-target.h +++ b/firmware/target/arm/imx31/gigabeat-s/system-target.h @@ -19,15 +19,15 @@ #ifndef SYSTEM_TARGET_H #define SYSTEM_TARGET_H -#include "mmu-imx31.h" #include "system-arm.h" +#include "mmu-arm.h" #define CPUFREQ_NORMAL 532000000 static inline void udelay(unsigned int usecs) { volatile signed int stop = EPITCNT1 - usecs; - while (EPITCNT1 > stop); + while ((signed int)EPITCNT1 > stop); } #define __dbg_hw_info(...) 0 @@ -36,6 +36,22 @@ static inline void udelay(unsigned int usecs) #define HAVE_INVALIDATE_ICACHE static inline void invalidate_icache(void) { + long rd = 0; + asm volatile( + "mcr p15, 0, %0, c7, c10, 0 \n" + "mcr p15, 0, %0, c7, c5, 0 \n" + : : "r"(rd) + ); +} + +#define HAVE_FLUSH_ICACHE +static inline void flush_icache(void) +{ + long rd = 0; + asm volatile ( + "mcr p15, 0, %0, c7, c10, 0 \n" + : : "r"(rd) + ); } struct ARM_REGS { -- cgit v1.2.3