From 9003dbe5b257990e8141f95b97520090444ef81a Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Sun, 20 Apr 2008 03:30:57 +0000 Subject: [PATCH] Make the inital connect problem go away on Gigabeat S. Would be nice if a better way were found but it works for me. Update the bootloader to have it work. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17181 a1c6a512-1295-4272-9138-f99709370657 --- bootloader/gigabeat-s.c | 7 +++- firmware/export/usb_drv.h | 1 + .../target/arm/imx31/gigabeat-s/usb-imx31.c | 34 ++++++++++++++--- firmware/target/arm/usb-drv-arc.c | 38 ++++++++++++------- firmware/target/arm/usb-fw-pp502x.c | 5 +++ 5 files changed, 65 insertions(+), 20 deletions(-) diff --git a/bootloader/gigabeat-s.c b/bootloader/gigabeat-s.c index dbacaaa901..87d7d3e56c 100644 --- a/bootloader/gigabeat-s.c +++ b/bootloader/gigabeat-s.c @@ -156,7 +156,7 @@ void main(void) lcd_clear_display(); printf("Hello world!"); - printf("Gigabeat S Rockbox Bootloader v.00000007"); + printf("Gigabeat S Rockbox Bootloader v.00000008"); system_init(); kernel_init(); printf("kernel init done"); @@ -274,6 +274,11 @@ void main(void) reset_screen(); } + else + { + /* Bang on the controller */ + usb_init_device(); + } unsigned char *loadbuffer = (unsigned char *)0x0; int buffer_size = 31*1024*1024; diff --git a/firmware/export/usb_drv.h b/firmware/export/usb_drv.h index 105b934844..da7500f1ab 100644 --- a/firmware/export/usb_drv.h +++ b/firmware/export/usb_drv.h @@ -21,6 +21,7 @@ #include "usb_ch9.h" #include "kernel.h" +void usb_drv_startup(void); void usb_drv_init(void); void usb_drv_exit(void); void usb_drv_int(void); diff --git a/firmware/target/arm/imx31/gigabeat-s/usb-imx31.c b/firmware/target/arm/imx31/gigabeat-s/usb-imx31.c index 2ef0bc6f6e..dae5f46762 100644 --- a/firmware/target/arm/imx31/gigabeat-s/usb-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/usb-imx31.c @@ -28,6 +28,23 @@ static int usb_status = USB_EXTRACTED; +static void enable_transceiver(bool enable) +{ + if (enable) + { + if (GPIO1_DR & (1 << 30)) + { + GPIO3_DR &= ~(1 << 16); /* Reset ISP1504 */ + GPIO3_DR |= (1 << 16); + GPIO1_DR &= ~(1 << 30); /* Select ISP1504 */ + } + } + else + { + GPIO1_DR |= (1 << 30); /* Deselect ISP1504 */ + } +} + void usb_set_status(bool plugged) { usb_status = plugged ? USB_INSERTED : USB_EXTRACTED; @@ -44,8 +61,17 @@ bool usb_plugged(void) return mc13783_read(MC13783_INTERRUPT_SENSE0) & MC13783_USB4V4; } +extern void usb_drv_startup(void); + void usb_init_device(void) { + imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_ON_ALL); + + enable_transceiver(true); + + /* Module will be turned off later after firmware init */ + usb_drv_startup(); + mc13783_clear(MC13783_INTERRUPT_MASK0, MC13783_USB4V4); } @@ -54,18 +80,16 @@ void usb_enable(bool on) if (on) { imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_ON_ALL); - GPIO3_DR &= ~(1 << 16); /* Reset ISP1504 */ - GPIO3_DR |= (1 << 16); - GPIO1_DR &= ~(1 << 30); /* Select ISP1504 */ + enable_transceiver(true); usb_core_init(); } else { /* Module clock should be on since this could be called first */ imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_ON_ALL); - GPIO1_DR &= ~(1 << 30); /* Select ISP1504 */ + enable_transceiver(true); usb_core_exit(); - GPIO1_DR |= (1 << 30); /* Deselect ISP1504 */ + enable_transceiver(false); imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_OFF); } } diff --git a/firmware/target/arm/usb-drv-arc.c b/firmware/target/arm/usb-drv-arc.c index 3bf53fa431..3093120c83 100644 --- a/firmware/target/arm/usb-drv-arc.c +++ b/firmware/target/arm/usb-drv-arc.c @@ -352,8 +352,6 @@ static const unsigned int pipe2mask[] = { 0x10, 0x100000, }; -static bool first_init = true; - /*-------------------------------------------------------------------------*/ static void transfer_completed(void); static void control_received(void); @@ -373,22 +371,34 @@ bool usb_drv_powered(void) return (REG_OTGSC & OTGSC_B_SESSION_VALID) ? true : false; } +/* One-time driver startup init */ +void usb_drv_startup(void) +{ +#if CONFIG_CPU == IMX31L && defined(BOOTLOADER) + /* This is the bootloader - activate the OTG controller or cold + * connect later could/will fail */ + REG_USBCMD &= ~USBCMD_RUN; + + sleep(HZ/20); + REG_USBCMD |= USBCMD_CTRL_RESET; + while (REG_USBCMD & USBCMD_CTRL_RESET); + + /* Set to ULPI */ + REG_PORTSC1 = (REG_PORTSC1 & ~PORTSCX_PHY_TYPE_SEL) | PORTSCX_PTS_ULPI; + sleep(HZ/10); +#endif + + /* Initialize all the signal objects once */ + int i; + for(i=0;i