From 590501cfe404b5463adecc70628e5bc7c8f142a2 Mon Sep 17 00:00:00 2001 From: Will Robertson Date: Fri, 21 Sep 2007 15:51:53 +0000 Subject: Merge the Gigabeat S branch back into trunk. Fingers crossed nothing breaks. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14805 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/arm/imx31/gigabeat-s/avic-imx31.c | 223 ++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 firmware/target/arm/imx31/gigabeat-s/avic-imx31.c (limited to 'firmware/target/arm/imx31/gigabeat-s/avic-imx31.c') diff --git a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c new file mode 100644 index 0000000000..8236a38014 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c @@ -0,0 +1,223 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 by James Espinoza + * + * 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 +#include "system.h" +#include "imx31l.h" +#include "avic-imx31.h" +#include "debug.h" + +void avic_init(void) +{ + /*following the steps in the AVIC setup in imx31 man*/ + + /*Initialize interrupt structures*/ + int i,avicstart; + /*get start of avic_init section for address calculation*/ + __asm__ ("ldr %0,=_avicstart\n\t" + :"=r"(avicstart):); + + 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); + + /*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"); +} + +void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, + void (*pInt_Handler) (void)) +{ + int i; + + if(ints == ALL) + { + 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; +} + +void avic_disable_int(enum IMX31_INT_LIST ints) +{ + int i; + + if(ints == ALL) + { + for(i=0;i<64;i++) + INTDISNUM=(long)i; + imx31_int[ints].pInt_Handler=Unhandled_Int; + return; + } + + INTDISNUM=(long)ints; +} + +void avic_set_int_type(enum IMX31_INT_LIST ints, 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; +} + +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); +} + +void vector_init(void) +{ + + /*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)); + +} -- cgit v1.2.3