Index: firmware/export/powermgmt.h =================================================================== --- firmware/export/powermgmt.h (revision 16006) +++ firmware/export/powermgmt.h (working copy) @@ -111,7 +111,7 @@ # define CURRENT_RECORD 35 /* FIXME: this needs adjusting */ #endif #elif defined(IPOD_VIDEO) /* iPOD Video */ -# define CURRENT_NORMAL 42 /* 9.5h out of 400mAh battery (30GB) or 14h out of 600mAh (60GB) from IpodRuntime */ +# define CURRENT_NORMAL 36 /* 11h out of 400mAh battery (30GB) or 16h out of 600mAh (60GB) from IpodRuntime */ # define CURRENT_BACKLIGHT 20 /* FIXME: this needs adjusting */ #if defined(HAVE_RECORDING) # define CURRENT_RECORD 35 /* FIXME: this needs adjusting */ Index: firmware/export/pp5020.h =================================================================== --- firmware/export/pp5020.h (revision 16006) +++ firmware/export/pp5020.h (working copy) @@ -132,7 +132,9 @@ #define DEV_EN (*(volatile unsigned long *)(0x6000600c)) #define DEV_EN2 (*(volatile unsigned long *)(0x60006010)) +#define DEV_EXTCLOCKS 0x00000002 #define DEV_SYSTEM 0x00000004 +#define DEV_USB0 0x00000008 #define DEV_SER0 0x00000040 #define DEV_SER1 0x00000080 #define DEV_I2S 0x00000800 @@ -140,7 +142,7 @@ #define DEV_ATA 0x00004000 #define DEV_OPTO 0x00010000 #define DEV_PIEZO 0x00010000 -#define DEV_USB 0x00400000 +#define DEV_USB1 0x00400000 #define DEV_FIREWIRE 0x00800000 #define DEV_IDE0 0x02000000 #define DEV_LCD 0x04000000 @@ -332,6 +334,8 @@ #define XMB_NOR_CFG (*(volatile unsigned long *)(0x70000038)) #define XMB_RAM_CFG (*(volatile unsigned long *)(0x7000003c)) +#define INIT_BUTTONS 0x00040000 +#define INIT_PLL 0x40000000 #define INIT_USB 0x80000000 /* 32 bit GPO port */ Index: firmware/target/arm/usb-fw-pp502x.c =================================================================== --- firmware/target/arm/usb-fw-pp502x.c (revision 16055) +++ firmware/target/arm/usb-fw-pp502x.c (working copy) @@ -33,18 +33,23 @@ void usb_init_device(void) { /* enable usb module */ - GPO32_ENABLE |= 0x200; - outl(inl(0x7000002C) | 0x3000000, 0x7000002C); - DEV_EN |= DEV_USB; + DEV_EN |= DEV_USB0; + DEV_EN |= DEV_USB1; - DEV_RS |= DEV_USB; /* reset usb start */ - DEV_RS &=~DEV_USB;/* reset usb end */ + /* reset both USBs */ + DEV_RS |= DEV_USB0; + DEV_RS &=~DEV_USB0; + DEV_RS |= DEV_USB1; + DEV_RS &=~DEV_USB1; - DEV_INIT2 |= INIT_USB; while ((inl(0x70000028) & 0x80) == 0); outl(inl(0x70000028) | 0x2, 0x70000028); udelay(0x186A0); + + /* disable USB-devices until USB is detected via GPIO */ + DEV_EN &= ~DEV_USB0; + DEV_EN &= ~DEV_USB1; #if defined(IPOD_COLOR) || defined(IPOD_4G) \ || defined(IPOD_MINI) || defined(IPOD_MINI2G) @@ -85,33 +90,43 @@ static bool usb_pin_detect(void) { + bool retval = false; + #if defined(IPOD_4G) || defined(IPOD_COLOR) \ || defined(IPOD_MINI) || defined(IPOD_MINI2G) /* GPIO D bit 3 is usb detect */ if (GPIOD_INPUT_VAL & 0x08) - return true; + retval = true; #elif defined(IPOD_NANO) || defined(IPOD_VIDEO) /* GPIO L bit 4 is usb detect */ if (GPIOL_INPUT_VAL & 0x10) - return true; + retval = true; #elif defined(SANSA_C200) /* GPIO H bit 1 is usb detect */ if (GPIOH_INPUT_VAL & 0x02) - return true; + retval = true; #elif defined(SANSA_E200) /* GPIO B bit 4 is usb detect */ if (GPIOB_INPUT_VAL & 0x10) - return true; + retval = true; #elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB) /* GPIO L bit 2 is usb detect */ if (GPIOL_INPUT_VAL & 0x4) - return true; + retval = true; #endif - return false; + + /* if USB is detected, re-enable the USB-devices */ + if (retval) + { + DEV_EN |= DEV_USB0; + DEV_EN |= DEV_USB1; + } + + return retval; } /* detect host or charger (INSERTED or POWERED) */ Index: firmware/target/arm/system-target.h =================================================================== --- firmware/target/arm/system-target.h (revision 16055) +++ firmware/target/arm/system-target.h (working copy) @@ -29,13 +29,13 @@ #if CONFIG_CPU == PP5002 #define CPUFREQ_SLEEP 32768 #define CPUFREQ_DEFAULT 24000000 -#define CPUFREQ_NORMAL 30000000 +#define CPUFREQ_NORMAL 24000000 #define CPUFREQ_MAX 80000000 #else /* PP5022, PP5024 */ #define CPUFREQ_SLEEP 32768 #define CPUFREQ_DEFAULT 24000000 -#define CPUFREQ_NORMAL 30000000 +#define CPUFREQ_NORMAL 24000000 #define CPUFREQ_MAX 80000000 #endif Index: firmware/target/arm/wmcodec-pp.c =================================================================== --- firmware/target/arm/wmcodec-pp.c (revision 16055) +++ firmware/target/arm/wmcodec-pp.c (working copy) @@ -52,15 +52,15 @@ DEV_INIT1 &=~0x3000000; /*mini2?*/ - /* device reset */ + /* I2S device reset */ DEV_RS |= DEV_I2S; DEV_RS &=~DEV_I2S; - /* device enable */ - DEV_EN |= (DEV_I2S | 0x7); + /* I2S device enable */ + DEV_EN |= DEV_I2S; /* enable external dev clock clocks */ - DEV_EN |= 0x2; + DEV_EN |= DEV_EXTCLOCKS; /* external dev clock to 24MHz */ outl(inl(0x70000018) & ~0xc, 0x70000018); Index: firmware/target/arm/ipod/button-clickwheel.c =================================================================== --- firmware/target/arm/ipod/button-clickwheel.c (revision 16055) +++ firmware/target/arm/ipod/button-clickwheel.c (working copy) @@ -73,64 +73,40 @@ static void opto_i2c_init(void) { - int i, curr_value; - - /* wait for value to settle */ - i = 1000; - curr_value = (inl(0x7000c104) << 16) >> 24; - while (i > 0) - { - int new_value = (inl(0x7000c104) << 16) >> 24; - - if (new_value != curr_value) { - i = 10000; - curr_value = new_value; - } - else { - i--; - } - } - - GPIOB_OUTPUT_VAL |= 0x10; - DEV_EN |= 0x10000; - DEV_RS |= 0x10000; + DEV_EN |= DEV_OPTO; + DEV_RS |= DEV_OPTO; udelay(5); - DEV_RS &= ~0x10000; /* finish reset */ + DEV_RS &= ~DEV_OPTO; /* finish reset */ + DEV_INIT1 |= INIT_BUTTONS; /* enable buttons (needed for "hold"-detection) */ - outl(0xffffffff, 0x7000c120); - outl(0xffffffff, 0x7000c124); outl(0xc00a1f00, 0x7000c100); - outl(0x1000000, 0x7000c104); + outl(0x01000000, 0x7000c104); } static inline int ipod_4g_button_read(void) { int whl = -1; + int btn = BUTTON_NONE; - /* The ipodlinux source had a udelay(250) here, but testing has shown that - it is not needed - tested on Nano, Color/Photo and Video. */ - /* udelay(250);*/ + /* The following delay was 250 in the ipodlinux source, but 50 seems to + work fine - tested on Nano, Color/Photo and Video. */ + udelay(50); - int btn = BUTTON_NONE; - unsigned reg = 0x7000c104; - if ((inl(0x7000c104) & 0x4000000) != 0) + if ((inl(0x7000c104) & 0x04000000) != 0) { unsigned status = inl(0x7000c140); - reg = reg + 0x3C; /* 0x7000c140 */ - outl(0x0, 0x7000c140); /* clear interrupt status? */ - if ((status & 0x800000ff) == 0x8000001a) { - if (status & 0x100) + if (status & 0x00000100) btn |= BUTTON_SELECT; - if (status & 0x200) + if (status & 0x00000200) btn |= BUTTON_RIGHT; - if (status & 0x400) + if (status & 0x00000400) btn |= BUTTON_LEFT; - if (status & 0x800) + if (status & 0x00000800) btn |= BUTTON_PLAY; - if (status & 0x1000) + if (status & 0x00001000) btn |= BUTTON_MENU; if (status & 0x40000000) { @@ -263,19 +239,10 @@ } } - else if (status == 0xffffffff) - { - opto_i2c_init(); - } } - if ((inl(reg) & 0x8000000) != 0) - { - outl(0xffffffff, 0x7000c120); - outl(0xffffffff, 0x7000c124); - } - /* Save the new absolute wheel position */ #ifdef HAVE_WHEEL_POSITION + /* Save the new absolute wheel position */ wheel_position = whl; #endif return btn; @@ -296,16 +263,12 @@ void ipod_4g_button_int(void) { CPU_HI_INT_CLR = I2C_MASK; - /* The following delay was 250 in the ipodlinux source, but 50 seems to - work fine - tested on Nano, Color/Photo and Video. */ - udelay(50); - outl(0x0, 0x7000c140); + int_btn = ipod_4g_button_read(); - outl(inl(0x7000c104) | 0xC000000, 0x7000c104); + + outl(inl(0x7000c104) | 0x0c000000, 0x7000c104); outl(0x400a1f00, 0x7000c100); - GPIOB_OUTPUT_VAL |= 0x10; - CPU_INT_EN = 0x40000000; CPU_HI_INT_EN = I2C_MASK; } @@ -317,15 +280,8 @@ GPIOA_ENABLE |= 0x20; GPIOA_OUTPUT_EN &= ~0x20; - /* hold button - set interrupt levels */ - GPIOA_INT_LEV = ~(GPIOA_INPUT_VAL & 0x20); - GPIOA_INT_CLR = GPIOA_INT_STAT & 0x20; - - /* enable interrupts */ - GPIOA_INT_EN = 0x20; - /* unmask interrupt */ - CPU_INT_EN = 0x40000000; + CPU_INT_EN = HI_MASK; CPU_HI_INT_EN = I2C_MASK; } @@ -342,7 +298,20 @@ hold_button = button_hold(); if (hold_button != hold_button_old) + { backlight_hold_changed(hold_button); + + if (hold_button) + { + /* lock -> disable wheel sensor */ + DEV_EN &= ~DEV_OPTO; + } + else + { + /* unlock -> enable wheel sensor */ + DEV_EN |= DEV_OPTO; + } + } /* The int_btn variable is set in the button interrupt handler */ return int_btn; Index: firmware/target/arm/ipod/power-ipod.c =================================================================== --- firmware/target/arm/ipod/power-ipod.c (revision 16055) +++ firmware/target/arm/ipod/power-ipod.c (working copy) @@ -71,9 +71,15 @@ GPIO_SET_BITWISE(GPIOJ_OUTPUT_VAL, 0x04); #elif defined(IPOD_VIDEO) if (on) + { GPO32_VAL &= ~0x40000000; + DEV_EN |= DEV_IDE0; + } else + { + DEV_EN &= ~DEV_IDE0; GPO32_VAL |= 0x40000000; + } #else /* Nano */ (void)on; /* Do nothing. */ #endif Index: firmware/target/arm/system-pp502x.c =================================================================== --- firmware/target/arm/system-pp502x.c (revision 16055) +++ firmware/target/arm/system-pp502x.c (working copy) @@ -166,92 +166,120 @@ spinlock_lock(&boostctrl_spin); #endif - scale_suspend_core(true); - - cpu_frequency = frequency; - switch (frequency) { - /* Note: The PP5022 PLL must be run at >= 96MHz + /* Note1: The PP5022 PLL must be run at >= 96MHz * Bits 20..21 select the post divider (1/2/4/8). * PP5026 is similar to PP5022 except it doesn't - * have this limitation (and the post divider?) */ + * have this limitation (and the post divider?) + * Note2: CLOCK_SOURCE is set via 0=32kHz, 1=16MHz, + * 2=24MHz, 3=33MHz, 4=48MHz, ..., 7=PLL. */ + case CPUFREQ_SLEEP: + cpu_frequency = CPUFREQ_SLEEP; + PLL_CONTROL |= 0x0c000000; + scale_suspend_core(true); + CLOCK_SOURCE = 0x20000000; /* source #1, #2, #3, #4: 32kHz (#2 active) */ + scale_suspend_core(false); + PLL_CONTROL &= ~0x80000000; /* disable PLL */ + DEV_INIT2 &= ~INIT_PLL; /* disable PLL power */ + break; + case CPUFREQ_MAX: - CLOCK_SOURCE = 0x10007772; /* source #1: 24MHz, #2, #3, #4: PLL */ - DEV_TIMING1 = 0x00000303; -#ifdef IPOD_NANO - IDE0_CFG |= (0x10000000); /* Set CPU > 65MHz bit */ -#endif -#ifdef IPOD_MINI2G + cpu_frequency = CPUFREQ_MAX; + DEV_INIT2 |= INIT_PLL; /* enable PLL power */ + PLL_CONTROL |= 0x88000000; /* enable PLL */ + scale_suspend_core(true); + CLOCK_SOURCE = 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */ + DEV_TIMING1 = 0x00000303; + scale_suspend_core(false); +#if defined(IPOD_MINI2G) MLCD_SCLK_DIV = 0x00000001; /* Mono LCD bridge serial clock divider */ +#elif defined(IPOD_NANO) + IDE0_CFG |= 0x10000000; /* set ">65MHz" bit */ #endif #if CONFIG_CPU == PP5020 - PLL_CONTROL = 0x8a020a03; /* 10/3 * 24MHz */ - PLL_STATUS = 0xd19b; /* unlock frequencies > 66MHz */ - PLL_CONTROL = 0x8a020a03; /* repeat setup */ - scale_suspend_core(false); + PLL_CONTROL = 0x8a020a03; /* 80 MHz = 10/3 * 24MHz */ + PLL_STATUS = 0xd19b; /* unlock frequencies > 66MHz */ + PLL_CONTROL = 0x8a020a03; /* repeat setup */ udelay(500); /* wait for relock */ #elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) - PLL_CONTROL = 0x8a121403; /* (20/3 * 24MHz) / 2 */ - scale_suspend_core(false); - udelay(250); + PLL_CONTROL = 0x8a121403; /* 80 MHz = (20/3 * 24MHz) / 2 */ + //PLL_CONTROL = 0x8a121903; /* 100 MHz = (25/3 * 24MHz) / 2 */ + //udelay(250); while (!(PLL_STATUS & 0x80000000)); /* wait for relock */ #endif scale_suspend_core(true); + DEV_TIMING1 = 0x00000808; + //DEV_TIMING1 = 0x00000a0a; + CLOCK_SOURCE = 0x20007777; /* source #1, #2, #3, #4: PLL (#2 active) */ + scale_suspend_core(false); break; - +#if 0 /* CPUFREQ_NORMAL clocking via PLL */ case CPUFREQ_NORMAL: - CLOCK_SOURCE = 0x10007772; /* source #1: 24MHz, #2, #3, #4: PLL */ - DEV_TIMING1 = 0x00000303; -#ifdef IPOD_NANO - IDE0_CFG &=~(0x10000000); /* clear > 65MHz bit */ + cpu_frequency = CPUFREQ_NORMAL; + DEV_INIT2 |= INIT_PLL; /* enable PLL power */ + PLL_CONTROL |= 0x88000000; /* enable PLL */ + scale_suspend_core(true); + CLOCK_SOURCE = 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */ + DEV_TIMING1 = 0x00000303; + scale_suspend_core(false); +#if defined(IPOD_MINI2G) + MLCD_SCLK_DIV = 0x00000001; /* Mono LCD bridge serial clock divider */ +#elif defined(IPOD_NANO) + IDE0_CFG |= 0x10000000; /* set ">65MHz" bit */ #endif -#ifdef IPOD_MINI2G - MLCD_SCLK_DIV = 0x00000000; /* Mono LCD bridge serial clock divider */ -#endif #if CONFIG_CPU == PP5020 - PLL_CONTROL = 0x8a020504; /* 5/4 * 24MHz */ - scale_suspend_core(false); + //PLL_CONTROL = 0x8a020504; /* 30 MHz = 5/4 * 24MHz */ + PLL_CONTROL = 0x8a020404; /* 24 MHz = 4/4 * 24MHz */ udelay(500); /* wait for relock */ #elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) - PLL_CONTROL = 0x8a220501; /* (5/1 * 24MHz) / 4 */ - scale_suspend_core(false); - udelay(250); + //PLL_CONTROL = 0x8a220501; /* 30 MHz = (5/1 * 24MHz) / 4 */ + PLL_CONTROL = 0x8a220401; /* 24 MHz = (4/1 * 24MHz) / 4 */ + //PLL_CONTROL = 0x8a320701; /* 21 MHz = (7/1 * 24MHz) / 8 */ + //PLL_CONTROL = 0x8a320601; /* 18 MHz = (6/1 * 24MHz) / 8 */ + //PLL_CONTROL = 0x8a320501; /* 15 MHz = (5/1 * 24MHz) / 8 */ + //PLL_CONTROL = 0x8a320401; /* 12 MHz = (4/1 * 24MHz) / 8 */ + //udelay(250); while (!(PLL_STATUS & 0x80000000)); /* wait for relock */ #endif scale_suspend_core(true); + CLOCK_SOURCE = 0x20007777; /* source #1, #2, #3, #4: PLL (#2 active) */ + scale_suspend_core(false); break; - - case CPUFREQ_SLEEP: - CLOCK_SOURCE = 0x10002202; /* source #2: 32kHz, #1, #3, #4: 24MHz */ - PLL_CONTROL &= ~0x80000000; /* disable PLL */ +#else /* CPUFREQ_NORMAL clocking without PLL */ + case CPUFREQ_NORMAL: + cpu_frequency = CPUFREQ_NORMAL; + PLL_CONTROL |= 0x08000000; + scale_suspend_core(true); + CLOCK_SOURCE = 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */ + DEV_TIMING1 = 0x00000303; +#if defined(IPOD_MINI2G) + MLCD_SCLK_DIV = 0x00000000; /* Mono LCD bridge serial clock divider */ +#elif defined(IPOD_NANO) + IDE0_CFG &= ~0x10000000; /* clear ">65MHz" bit */ +#endif scale_suspend_core(false); - udelay(10000); /* let 32kHz source stabilize? */ - scale_suspend_core(true); + PLL_CONTROL &= ~0x80000000; /* disable PLL */ + DEV_INIT2 &= ~INIT_PLL; /* disable PLL power */ break; - +#endif /* CPUFREQ_NORMAL clocking */ default: - CLOCK_SOURCE = 0x10002222; /* source #1, #2, #3, #4: 24MHz */ - DEV_TIMING1 = 0x00000303; -#ifdef IPOD_MINI2G - MLCD_SCLK_DIV = 0x00000000; /* Mono LCD bridge serial clock divider */ + cpu_frequency = CPUFREQ_DEFAULT; + PLL_CONTROL |= 0x08000000; + scale_suspend_core(true); + CLOCK_SOURCE = 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */ + DEV_TIMING1 = 0x00000303; +#if defined(IPOD_MINI2G) + MLCD_SCLK_DIV = 0x00000000; /* Mono LCD bridge serial clock divider */ +#elif defined(IPOD_NANO) + IDE0_CFG &= ~0x10000000; /* clear ">65MHz" bit */ #endif -#ifdef IPOD_NANO - IDE0_CFG &=~(0x10000000); /* clear > 65MHz bit */ -#endif - PLL_CONTROL &= ~0x80000000; /* disable PLL */ - cpu_frequency = CPUFREQ_DEFAULT; - PROC_CTL(CURRENT_CORE) = 0x4800001f; nop; + scale_suspend_core(false); + PLL_CONTROL &= ~0x80000000; /* disable PLL */ + DEV_INIT2 &= ~INIT_PLL; /* disable PLL power */ break; } - - if (frequency == CPUFREQ_MAX) - DEV_TIMING1 = 0x00000808; - - CLOCK_SOURCE = (CLOCK_SOURCE & ~0xf0000000) | 0x20000000; /* select source #2 */ - - scale_suspend_core(false); - + #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1) spinlock_unlock(&boostctrl_spin); #endif @@ -270,12 +298,27 @@ DEV_RS2 = -1; DEV_RS = 0; DEV_RS2 = 0; - #elif defined (IRIVER_H10) +#elif defined (IRIVER_H10) DEV_RS = 0x3ffffef8; DEV_RS2 = -1; outl(inl(0x70000024) | 0xc0, 0x70000024); DEV_RS = 0; DEV_RS2 = 0; +#elif defined (IPOD_VIDEO) + /* set minimum startup configuration */ + DEV_EN = 0xc2000124; /* DEV_EN1 minimum configuration for startup */ + DEV_EN2 = 0x00000000; /* DEV_EN2 minimum configuration for startup */ + CACHE_PRIORITY = 0x0000003f; /* DEV_EN3 minimum configuration for startup */ + GPO32_ENABLE = 0x40004000; /* GPO32_EN minimum configuration for startup */ + GPO32_VAL = 0x00004000; /* GPO32_VAL minimum configuration for startup */ + DEV_INIT1 = 0x00000000; /* INIT1 minimum configuration for startup */ + DEV_INIT2 = 0x40000000; /* INIT2 minimum configuration for startup */ + + /* reset all allowed devices */ + DEV_RS = 0x3ffffef8; + DEV_RS2 = 0xffffffff; + DEV_RS = 0x00000000; + DEV_RS2 = 0x00000000; #endif #if !defined(SANSA_E200) && !defined(SANSA_C200) @@ -314,8 +357,6 @@ outl(inl(0x6000a000) | 0x80000000, 0x6000a000); /* Init DMA controller? */ #endif - DEV_INIT2 |= 1 << 30; /* enable PLL power */ - #ifdef HAVE_ADJUSTABLE_CPU_FREQ #if NUM_CORES > 1 cpu_boost_init(); Index: firmware/drivers/audio/as3514.c =================================================================== --- firmware/drivers/audio/as3514.c (revision 16006) +++ firmware/drivers/audio/as3514.c (working copy) @@ -146,11 +146,15 @@ DEV_RS |= DEV_I2S; DEV_RS &=~DEV_I2S; - /* device enable */ - DEV_EN |= (DEV_I2S | 0x7); + /* I2S device reset */ + DEV_RS |= DEV_I2S; + DEV_RS &=~DEV_I2S; + /* I2S device enable */ + DEV_EN |= DEV_I2S; + /* enable external dev clock clocks */ - DEV_EN |= 0x2; + DEV_EN |= DEV_EXTCLOCKS; /* external dev clock to 24MHz */ outl(inl(0x70000018) & ~0xc, 0x70000018);