From 8f80adf4d72042270533facad5e5991c1784849f Mon Sep 17 00:00:00 2001 From: Karl Kurbjun Date: Sun, 6 Feb 2011 20:58:58 +0000 Subject: [PATCH] Remove some initializations that are taken care of in the bootloader or crt0 setup. Agressive timings are #if 0'd since they are unstable, but may later be added to board setup. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29235 a1c6a512-1295-4272-9138-f99709370657 --- .../target/arm/tms320dm320/system-dm320.c | 303 ++++++++---------- 1 file changed, 126 insertions(+), 177 deletions(-) diff --git a/firmware/target/arm/tms320dm320/system-dm320.c b/firmware/target/arm/tms320dm320/system-dm320.c index 2d618a1b8b..03196f3d46 100644 --- a/firmware/target/arm/tms320dm320/system-dm320.c +++ b/firmware/target/arm/tms320dm320/system-dm320.c @@ -32,11 +32,14 @@ #include "usb-mr500.h" #endif +static unsigned short clock_arm_slow = 0xFFFF; +static unsigned short clock_arm_fast = 0xFFFF; + #define default_interrupt(name) \ extern __attribute__((weak,alias("UIRQ"))) void name (void) -void irq_handler(void) __attribute__((interrupt ("IRQ"), naked, section(".icode"))); -void fiq_handler(void) __attribute__((interrupt ("FIQ"), naked, section(".icode"))); +void irq_handler(void) __attribute__((interrupt ("IRQ"), section(".icode"))); +void fiq_handler(void) __attribute__((interrupt ("FIQ"), section(".icode"))); default_interrupt(TIMER0); default_interrupt(TIMER1); @@ -132,21 +135,12 @@ static void UIRQ(void) void irq_handler(void) { - /* - * Based on: linux/arch/arm/kernel/entry-armv.S and system-meg-fx.c - */ - - asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */ - "sub sp, sp, #8 \n"); /* Reserve stack */ unsigned short addr = IO_INTC_IRQENTRY0>>2; if(addr != 0) { addr--; irqvector[addr](); } - 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 IRQ */ } void fiq_handler(void) @@ -154,18 +148,12 @@ void fiq_handler(void) /* * Based on: linux/arch/arm/kernel/entry-armv.S and system-meg-fx.c */ - - asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */ - "sub sp, sp, #8 \n"); /* Reserve stack */ unsigned short addr = IO_INTC_FIQENTRY0>>2; if(addr != 0) { addr--; irqvector[addr](); } - 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 */ } void system_reboot(void) @@ -199,20 +187,13 @@ void system_exception_wait(void) void system_init(void) { + unsigned int vector_addr; /* Pin 33 is connected to a buzzer, for an annoying sound set * PWM0C == 0x3264 * PWM0H == 0x1932 * Function to 1 * Since this is not used in the FW, set it to a normal output at a zero * level. */ - /* 33: output, non-inverted, no-irq, falling edge, no-chat, normal */ - dm320_set_io(33, false, false, false, false, false, 0x00); - IO_GIO_BITCLR2 = 1<<1; - - /* Pin 1 is the power button. Right now it is setup without IRQ, but that - * may be needed for wakeup if a different shutdown method is used. */ - /* 1: input , non-inverted, no-irq, falling edge, no-chat, normal */ - dm320_set_io(1, true, false, false, false, false, 0x00); /* taken from linux/arch/arm/mach-itdm320-20/irq.c */ @@ -234,45 +215,118 @@ void system_init(void) IO_INTC_FISEL0 = 0; IO_INTC_FISEL1 = 0; IO_INTC_FISEL2 = 0; + + /* Only initially needed clocks should be turned on */ + IO_CLK_MOD0 = CLK_MOD0_HPIB | CLK_MOD0_DSP | CLK_MOD0_SDRAMC | + CLK_MOD0_EMIF | CLK_MOD0_INTC | CLK_MOD0_AIM | + CLK_MOD0_AHB | CLK_MOD0_BUSC | CLK_MOD0_ARM; + IO_CLK_MOD1 = CLK_MOD1_CPBUS; + IO_CLK_MOD2 = CLK_MOD2_GIO; + +#if 0 + if (IO_BUSC_REVR == REVR_ES11) + { + /* Agressive clock setup for newer parts (ES11) - this is actually lower + * power also. + */ + + /* Setup the EMIF interface timings */ + + /* ATA interface: + * If this is the newer silicon the timings need to be slowed down some + * for reliable access due to the faster ARM clock. + */ + /* OE width, WE width, CS width, Cycle width */ + IO_EMIF_CS3CTRL1 = (8 << 12) | (8 << 8) | (14 << 4) | 15; + /* 14: Width (16), 12: Idles, 8: OE setup, 4: WE Setup, CS setup */ + IO_EMIF_CS3CTRL2 = (1<<14) | (1 << 12) | (3 << 8) | (3 << 4) | 1; + + /* USB interface: + * The following EMIF timing values are from the OF: + * IO_EMIF_CS4CTRL1 = 0x66AB; + * IO_EMIF_CS4CTRL2 = 0x4220; + * + * More agressive numbers may be possible, but it depends on the clocking + * setup. + */ + IO_EMIF_CS4CTRL1 = 0x66AB; + IO_EMIF_CS4CTRL2 = 0x4220; + + /* 27 MHz input clock: + * PLLA: 27 * 15 / 2 = 202.5 MHz + * PLLB: 27 * 9 / 2 = 121.5 MHz (off: bit 12) + */ + IO_CLK_PLLA = (14 << 4) | 1; + IO_CLK_PLLB = ( 1 << 12) | ( 8 << 4) | 1; + + /* Set the slow and fast clock speeds used for boosting + * Slow Setup: + * ARM div = 4 ( 50.625 MHz ) + * AHB div = 1 ( 50.625 MHz ) + * Fast Setup: + * ARM div = 1 ( 202.5 MHz ) + * AHB div = 2 ( 101.25 MHz ) + */ + clock_arm_slow = (0 << 8) | 3; + clock_arm_fast = (1 << 8) | 0; + + IO_CLK_DIV0 = clock_arm_slow; + + /* SDRAM div= 2 ( 101.25 MHz ) + * AXL div = 1 ( 202.5 MHz ) + */ + IO_CLK_DIV1 = (0 << 8) | 1; + + /* MS div = 15 ( 13.5 MHz ) + * DSP div = 4 ( 50.625 MHz - could be double, but this saves power) + */ + IO_CLK_DIV2 = (3 << 8) | 14; + + /* MMC div = 256 ( slow ) + * VENC div = 32 ( 843.75 KHz ) + */ + IO_CLK_DIV3 = (31 << 8) | 255; + + /* I2C div = 1 ( 48 MHz if M48XI is running ) + * VLNQ div = 32 + */ + IO_CLK_DIV4 = (31 << 8) | 0; + + /* Feed everything from PLLA */ + IO_CLK_SEL0=0x007E; + IO_CLK_SEL1=0x1000; + IO_CLK_SEL2=0x0000; + } + else +#endif + { + /* Set the slow and fast clock speeds used for boosting + * Slow Setup: + * ARM div = 4 ( 87.5 MHz ) + * AHB div = 1 ( 87.5 MHz ) + * Fast Setup: + * ARM div = 2 ( 175 MHz ) + * AHB div = 2 ( 87.5 MHz ) + */ + clock_arm_slow = (0 << 8) | 3; + clock_arm_fast = (1 << 8) | 1; + } - /* setup the clocks */ - IO_CLK_DIV0=0x0003; - - /* SDRAM Divide by 3 */ - IO_CLK_DIV1=0x0102; - IO_CLK_DIV2=0x021F; - IO_CLK_DIV3=0x1FFF; - IO_CLK_DIV4=0x1F00; - - /* 27 MHz input clock: - * PLLA = 27*11/1 - */ - IO_CLK_PLLA=0x80A0; - IO_CLK_PLLB=0x80C0; - - IO_CLK_SEL0=0x017E; - IO_CLK_SEL1=0x1000; - IO_CLK_SEL2=0x1001; - - /* need to wait before bypassing */ - - IO_CLK_BYP=0x0000; - - /* turn off some unneeded modules */ - IO_CLK_MOD0 &= ~0x0018; - IO_CLK_MOD1 = 0x0918; - IO_CLK_MOD2 = ~0x7C58; + /* M48XI disabled, USB buffer powerdown */ + IO_CLK_LPCTL1 = 0x11; /* I2C wodn't work with this disabled */ /* IRQENTRY only reflects enabled interrupts */ IO_INTC_RAW = 0; - IO_INTC_ENTRY_TBA0 = 0; - IO_INTC_ENTRY_TBA1 = 0; + vector_addr = (unsigned int) irqvector; + IO_INTC_ENTRY_TBA0 = 0;//(short) vector_addr & ~0x000F; + IO_INTC_ENTRY_TBA1 = 0;//(short) (vector_addr >> 16); int i; /* Set interrupt priorities to predefined values */ for(i = 0; i < 23; i++) - DM320_REG(0x0540+i*2) = ((irqpriority[i*2+1] & 0x3F) << 8) | (irqpriority[i*2] & 0x3F); /* IO_INTC_PRIORITYx */ + DM320_REG(0x0540+i*2) = ((irqpriority[i*2+1] & 0x3F) << 8) | + (irqpriority[i*2] & 0x3F); /* IO_INTC_PRIORITYx */ /* Turn off all timers */ IO_TIMER0_TMMD = CONFIG_TIMER0_TMMD_STOP; @@ -280,47 +334,12 @@ void system_init(void) IO_TIMER2_TMMD = CONFIG_TIMER2_TMMD_STOP; IO_TIMER3_TMMD = CONFIG_TIMER3_TMMD_STOP; -#ifndef CREATIVE_ZVx - /* set GIO26 (reset pin) to output and low */ - IO_GIO_BITCLR1=(1<<10); - IO_GIO_DIR1&=~(1<<10); -#endif - uart_init(); spi_init(); #ifdef CREATIVE_ZVx dma_init(); #endif - -#if !defined(LCD_NATIVE_WIDTH) && !defined(LCD_NATIVE_HEIGHT) -#define LCD_NATIVE_WIDTH LCD_WIDTH -#define LCD_NATIVE_HEIGHT LCD_HEIGHT -#endif - -#define LCD_FUDGE LCD_NATIVE_WIDTH%32 -#define LCD_BUFFER_SIZE ((LCD_NATIVE_WIDTH+LCD_FUDGE)*LCD_NATIVE_HEIGHT*2) -#define LCD_TTB_AREA ((LCD_BUFFER_SIZE>>19)+1) - - /* MMU initialization (Starts data and instruction cache) */ - ttb_init(); - /* Make sure everything is mapped on itself */ - map_section(0, 0, 0x1000, CACHE_NONE); - - /* Enable caching for RAM */ - map_section(CONFIG_SDRAM_START, CONFIG_SDRAM_START, MEMORYSIZE, CACHE_ALL); - /* enable buffered writing for the framebuffer */ - map_section((int)FRAME, (int)FRAME, LCD_TTB_AREA, BUFFERED); -#ifdef CREATIVE_ZVx - /* mimic OF */ - map_section(0x00100000, 0x00100000, 4, CACHE_NONE); - map_section(0x04700000, 0x04700000, 2, BUFFERED); - map_section(0x40000000, 0x40000000, 16, CACHE_NONE); - map_section(0x50000000, 0x50000000, 16, CACHE_NONE); - map_section(0x60000000, 0x60000000, 16, CACHE_NONE); - map_section(0x80000000, 0x80000000, 1, CACHE_NONE); -#endif - enable_mmu(); } int system_memory_guard(int newmode) @@ -332,10 +351,23 @@ int system_memory_guard(int newmode) #ifdef HAVE_ADJUSTABLE_CPU_FREQ void set_cpu_frequency(long frequency) { - if (frequency == CPUFREQ_MAX) { - IO_CLK_DIV0 = 0x0101; /* 175 MHz ARM */ - } else { - IO_CLK_DIV0 = 0x0003; /* 87.5 MHz ARM - not much savings, about 3 mA */ + /* If these variables have not been changed since startup then boosting + * should not be used. + */ + if(clock_arm_slow == 0xFFFF || clock_arm_fast == 0xFFFF) + { + return; + } + + if (frequency == CPUFREQ_MAX) + { + IO_CLK_DIV0 = clock_arm_fast; + FREQ = CPUFREQ_MAX; + } + else + { + IO_CLK_DIV0 = clock_arm_slow; + FREQ = CPUFREQ_NORMAL; } } #endif @@ -351,87 +383,4 @@ void udelay(int usec) { } } -/* This function sets the specified pin up */ -void dm320_set_io (char pin_num, bool input, bool invert, bool irq, bool irqany, - bool chat, char func_num ) -{ - volatile short *pio; - char reg_offset; /* Holds the offset to the register */ - char shift_val; /* Holds the shift offset to the GPIO bit(s) */ - short io_val; /* Used as an intermediary to prevent glitchy - * assignments. */ - - /* Make sure this is a valid pin number */ - if( (unsigned) pin_num > 40 ) - return; - - /* Clamp the function number */ - func_num &= 0x03; - - /* Note that these are integer calculations */ - reg_offset = (pin_num / 16); - shift_val = (pin_num - (16 * reg_offset)); - - /* Handle the direction */ - /* Calculate the pointer to the direction register */ - pio = &IO_GIO_DIR0 + reg_offset; - - if(input) - *pio |= ( 1 << shift_val ); - else - *pio &= ~( 1 << shift_val ); - - /* Handle the inversion */ - /* Calculate the pointer to the inversion register */ - pio = &IO_GIO_INV0 + reg_offset; - - if(invert) - *pio |= ( 1 << shift_val ); - else - *pio &= ~( 1 << shift_val ); - - /* Handle the chat */ - /* Calculate the pointer to the chat register */ - pio = &IO_GIO_CHAT0 + reg_offset; - - if(chat) - *pio |= ( 1 << shift_val ); - else - *pio &= ~( 1 << shift_val ); - - /* Handle interrupt configuration */ - if(pin_num < 16) - { - /* Sets whether the pin is an irq or not */ - if(irq) - IO_GIO_IRQPORT |= (1 << pin_num ); - else - IO_GIO_IRQPORT &= ~(1 << pin_num ); - - /* Set whether this is a falling or any edge sensitive irq */ - if(irqany) - IO_GIO_IRQEDGE |= (1 << pin_num ); - else - IO_GIO_IRQEDGE &= ~(1 << pin_num ); - } - - /* Handle the function number */ - /* Calculate the pointer to the function register */ - reg_offset = ( (pin_num - 9) / 8 ); - shift_val = ( ((pin_num - 9) - (8 * reg_offset)) * 2 ); - - if( pin_num < 9 ) - { - reg_offset = 0; - shift_val = 0; - } - - /* Calculate the pointer to the function register */ - pio = &IO_GIO_FSEL0 + reg_offset; - - io_val = *pio; - io_val &= ~( 3 << shift_val ); /* zero previous value */ - io_val |= ( func_num << shift_val ); /* Store new value */ - *pio = io_val; -}