diff options
-rw-r--r-- | arch/arm/include/asm/arch-at91/at91_pmc.h | 14 | ||||
-rw-r--r-- | board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c | 13 | ||||
-rw-r--r-- | board/ti/evm/evm.c | 43 | ||||
-rw-r--r-- | board/ti/evm/evm.h | 14 | ||||
-rw-r--r-- | common/env_sf.c | 232 | ||||
-rw-r--r-- | drivers/mtd/spi/atmel.c | 7 | ||||
-rw-r--r-- | drivers/mtd/spi/macronix.c | 5 | ||||
-rw-r--r-- | drivers/mtd/spi/spansion.c | 5 | ||||
-rw-r--r-- | drivers/mtd/spi/spi_flash.c | 5 | ||||
-rw-r--r-- | drivers/mtd/spi/sst.c | 5 | ||||
-rw-r--r-- | drivers/mtd/spi/stmicro.c | 26 | ||||
-rw-r--r-- | drivers/mtd/spi/winbond.c | 7 | ||||
-rw-r--r-- | drivers/usb/host/ohci-at91.c | 14 | ||||
-rw-r--r-- | drivers/usb/host/ohci-hcd.c | 150 | ||||
-rw-r--r-- | drivers/usb/host/ohci.h | 15 | ||||
-rw-r--r-- | drivers/usb/musb/da8xx.c | 6 | ||||
-rw-r--r-- | drivers/usb/musb/davinci.c | 6 | ||||
-rw-r--r-- | drivers/usb/musb/musb_core.c | 7 | ||||
-rw-r--r-- | drivers/usb/musb/musb_core.h | 30 | ||||
-rw-r--r-- | drivers/usb/musb/omap3.c | 9 | ||||
-rw-r--r-- | drivers/usb/musb/omap3.h | 4 |
21 files changed, 509 insertions, 108 deletions
diff --git a/arch/arm/include/asm/arch-at91/at91_pmc.h b/arch/arm/include/asm/arch-at91/at91_pmc.h index 5b1a85d..2f9ad96 100644 --- a/arch/arm/include/asm/arch-at91/at91_pmc.h +++ b/arch/arm/include/asm/arch-at91/at91_pmc.h @@ -35,13 +35,15 @@ typedef struct at91_pmc { u32 pcer; /* 0x10 Peripheral Clock Enable Register */ u32 pcdr; /* 0x14 Peripheral Clock Disable Register */ u32 pcsr; /* 0x18 Peripheral Clock Status Register */ - u32 reserved1; + u32 uckr; /* 0x1C UTMI Clock Register */ u32 mor; /* 0x20 Main Oscilator Register */ u32 mcfr; /* 0x24 Main Clock Frequency Register */ u32 pllar; /* 0x28 PLL A Register */ u32 pllbr; /* 0x2C PLL B Register */ u32 mckr; /* 0x30 Master Clock Register */ - u32 reserved2[3]; + u32 reserved1; + u32 usb; /* 0x38 USB Clock Register */ + u32 reserved2; u32 pck[4]; /* 0x40 Programmable Clock Register 0 - 3 */ u32 reserved3[4]; u32 ier; /* 0x60 Interrupt Enable Register */ @@ -199,6 +201,14 @@ typedef struct at91_pmc { #define AT91_PMC_PDIV_2 (1 << 12) #ifdef CONFIG_AT91_LEGACY +#define AT91_PMC_USB (AT91_PMC + 0x38) /* USB Clock Register */ +#endif +#define AT91_PMC_USBS_USB_PLLA (0x0) /* USB Clock Input is PLLA */ +#define AT91_PMC_USBS_USB_UPLL (0x1) /* USB Clock Input is UPLL */ +#define AT91_PMC_USBDIV_8 (0x7 << 8) /* USB Clock divided by 8 */ +#define AT91_PMC_USBDIV_10 (0x9 << 8) /* USB Clock divided by 10 */ + +#ifdef CONFIG_AT91_LEGACY #define AT91_PMC_PCKR(n) (AT91_PMC + 0x40 + ((n) * 4)) /* Programmable Clock 0-3 Registers */ #define AT91_PMC_IER (AT91_PMC + 0x60) /* Interrupt Enable Register */ diff --git a/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c b/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c index edfb627..8fa0449 100644 --- a/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c +++ b/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c @@ -87,6 +87,16 @@ static void at91sam9m10g45ek_nand_hw_init(void) } #endif +#ifdef CONFIG_CMD_USB +static void at91sam9m10g45ek_usb_hw_init(void) +{ + at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9G45_ID_PIODE); + + at91_set_gpio_output(AT91_PIN_PD1, 0); + at91_set_gpio_output(AT91_PIN_PD3, 0); +} +#endif + #ifdef CONFIG_MACB static void at91sam9m10g45ek_macb_hw_init(void) { @@ -251,6 +261,9 @@ int board_init(void) #ifdef CONFIG_CMD_NAND at91sam9m10g45ek_nand_hw_init(); #endif +#ifdef CONFIG_CMD_USB + at91sam9m10g45ek_usb_hw_init(); +#endif #ifdef CONFIG_HAS_DATAFLASH at91_spi0_hw_init(1 << 0); #endif diff --git a/board/ti/evm/evm.c b/board/ti/evm/evm.c index 0718a08..9948b9c 100644 --- a/board/ti/evm/evm.c +++ b/board/ti/evm/evm.c @@ -37,6 +37,46 @@ #include <asm/mach-types.h> #include "evm.h" +static u8 omap3_evm_version; + +u8 get_omap3_evm_rev(void) +{ + return omap3_evm_version; +} + +static void omap3_evm_get_revision(void) +{ + unsigned int smsc_id; + + /* Ethernet PHY ID is stored at ID_REV register */ + smsc_id = readl(CONFIG_SMC911X_BASE + 0x50) & 0xFFFF0000; + printf("Read back SMSC id 0x%x\n", smsc_id); + + switch (smsc_id) { + /* SMSC9115 chipset */ + case 0x01150000: + omap3_evm_version = OMAP3EVM_BOARD_GEN_1; + break; + /* SMSC 9220 chipset */ + case 0x92200000: + default: + omap3_evm_version = OMAP3EVM_BOARD_GEN_2; + } +} + +/* + * MUSB port on OMAP3EVM Rev >= E requires extvbus programming. + */ +u8 omap3_evm_need_extvbus(void) +{ + u8 retval = 0; + + if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) + retval = 1; + + return retval; +} + /* * Routine: board_init * Description: Early hardware init. @@ -121,6 +161,9 @@ static void setup_net_chip(void) writel(GPIO0, &gpio3_base->cleardataout); udelay(1); writel(GPIO0, &gpio3_base->setdataout); + + /* determine omap3evm revision */ + omap3_evm_get_revision(); } int board_eth_init(bd_t *bis) diff --git a/board/ti/evm/evm.h b/board/ti/evm/evm.h index 37da29d..e2581f6 100644 --- a/board/ti/evm/evm.h +++ b/board/ti/evm/evm.h @@ -33,6 +33,20 @@ const omap3_sysinfo sysinfo = { #endif }; +/* + * OMAP35x EVM revision + * Run time detection of EVM revision is done by reading Ethernet + * PHY ID - + * GEN_1 = 0x01150000 + * GEN_2 = 0x92200000 + */ +enum { + OMAP3EVM_BOARD_GEN_1 = 0, /* EVM Rev between A - D */ + OMAP3EVM_BOARD_GEN_2, /* EVM Rev >= Rev E */ +}; + +u8 get_omap3_evm_rev(void); + static void setup_net_chip(void); /* diff --git a/common/env_sf.c b/common/env_sf.c index 6575b6d..4391d61 100644 --- a/common/env_sf.c +++ b/common/env_sf.c @@ -43,6 +43,14 @@ # define CONFIG_ENV_SPI_MODE SPI_MODE_3 #endif +#ifdef CONFIG_ENV_OFFSET_REDUND +static ulong env_offset = CONFIG_ENV_OFFSET; +static ulong env_new_offset = CONFIG_ENV_OFFSET_REDUND; + +#define ACTIVE_FLAG 1 +#define OBSOLETE_FLAG 0 +#endif /* CONFIG_ENV_ADDR_REDUND */ + DECLARE_GLOBAL_DATA_PTR; /* references to names in env_common.c */ @@ -58,6 +66,229 @@ uchar env_get_char_spec(int index) return *((uchar *)(gd->env_addr + index)); } +#if defined(CONFIG_ENV_OFFSET_REDUND) +void swap_env(void) +{ + ulong tmp_offset = env_offset; + + env_offset = env_new_offset; + env_new_offset = tmp_offset; +} + +int saveenv(void) +{ + u32 saved_size, saved_offset; + char *saved_buffer = NULL; + u32 sector = 1; + int ret; + char flag = OBSOLETE_FLAG, new_flag = ACTIVE_FLAG; + + if (!env_flash) { + puts("Environment SPI flash not initialized\n"); + return 1; + } + + /* Is the sector larger than the env (i.e. embedded) */ + if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { + saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE; + saved_offset = env_new_offset + CONFIG_ENV_SIZE; + saved_buffer = malloc(saved_size); + if (!saved_buffer) { + ret = 1; + goto done; + } + ret = spi_flash_read(env_flash, saved_offset, + saved_size, saved_buffer); + if (ret) + goto done; + } + + if (CONFIG_ENV_SIZE > CONFIG_ENV_SECT_SIZE) { + sector = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE; + if (CONFIG_ENV_SIZE % CONFIG_ENV_SECT_SIZE) + sector++; + } + + puts("Erasing SPI flash..."); + ret = spi_flash_erase(env_flash, env_new_offset, + sector * CONFIG_ENV_SECT_SIZE); + if (ret) + goto done; + + puts("Writing to SPI flash..."); + ret = spi_flash_write(env_flash, + env_new_offset + offsetof(env_t, data), + sizeof(env_ptr->data), env_ptr->data); + if (ret) + goto done; + + ret = spi_flash_write(env_flash, + env_new_offset + offsetof(env_t, crc), + sizeof(env_ptr->crc), &env_ptr->crc); + if (ret) + goto done; + + ret = spi_flash_write(env_flash, + env_offset + offsetof(env_t, flags), + sizeof(env_ptr->flags), &flag); + if (ret) + goto done; + + ret = spi_flash_write(env_flash, + env_new_offset + offsetof(env_t, flags), + sizeof(env_ptr->flags), &new_flag); + if (ret) + goto done; + + if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { + ret = spi_flash_write(env_flash, saved_offset, + saved_size, saved_buffer); + if (ret) + goto done; + } + + swap_env(); + + ret = 0; + puts("done\n"); + + done: + if (saved_buffer) + free(saved_buffer); + return ret; +} + +void env_relocate_spec(void) +{ + int ret; + int crc1_ok = 0, crc2_ok = 0; + env_t *tmp_env1 = NULL; + env_t *tmp_env2 = NULL; + uchar flag1, flag2; + /* current_env is set only in case both areas are valid! */ + int current_env = 0; + + tmp_env1 = (env_t *)malloc(CONFIG_ENV_SIZE); + if (!tmp_env1) { + puts("*** Warning: could not init environment," + " using defaults\n\n"); + goto out; + } + + tmp_env2 = (env_t *)malloc(CONFIG_ENV_SIZE); + if (!tmp_env2) { + puts("*** Warning: could not init environment," + " using defaults\n\n"); + goto out; + } + + env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, + CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE); + if (!env_flash) + goto err_probe; + + ret = spi_flash_read(env_flash, CONFIG_ENV_OFFSET, + CONFIG_ENV_SIZE, tmp_env1); + if (ret) + goto err_read; + + if (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc) + crc1_ok = 1; + flag1 = tmp_env1->flags; + + ret = spi_flash_read(env_flash, CONFIG_ENV_OFFSET_REDUND, + CONFIG_ENV_SIZE, tmp_env2); + if (!ret) { + if (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc) + crc2_ok = 1; + flag2 = tmp_env2->flags; + } + + if (!crc1_ok && !crc2_ok) + goto err_crc; + else if (crc1_ok && !crc2_ok) { + gd->env_valid = 1; + memcpy(env_ptr, tmp_env1, CONFIG_ENV_SIZE); + } else if (!crc1_ok && crc2_ok) { + gd->env_valid = 1; + memcpy(env_ptr, tmp_env2, CONFIG_ENV_SIZE); + swap_env(); + } else if (flag1 == ACTIVE_FLAG && flag2 == OBSOLETE_FLAG) { + gd->env_valid = 1; + memcpy(env_ptr, tmp_env1, CONFIG_ENV_SIZE); + } else if (flag1 == OBSOLETE_FLAG && flag2 == ACTIVE_FLAG) { + gd->env_valid = 1; + memcpy(env_ptr, tmp_env2, CONFIG_ENV_SIZE); + swap_env(); + } else if (flag1 == flag2) { + gd->env_valid = 2; + memcpy(env_ptr, tmp_env1, CONFIG_ENV_SIZE); + current_env = 1; + } else if (flag1 == 0xFF) { + gd->env_valid = 2; + memcpy(env_ptr, tmp_env1, CONFIG_ENV_SIZE); + current_env = 1; + } else { + /* + * this differs from code in env_flash.c, but I think a sane + * default path is desirable. + */ + gd->env_valid = 2; + memcpy(env_ptr, tmp_env2, CONFIG_ENV_SIZE); + swap_env(); + current_env = 2; + } + if (current_env == 1) { + if (flag2 != OBSOLETE_FLAG) { + flag2 = OBSOLETE_FLAG; + spi_flash_write(env_flash, + env_new_offset + offsetof(env_t, flags), + sizeof(env_ptr->flags), &flag2); + } + if (flag1 != ACTIVE_FLAG) { + flag1 = ACTIVE_FLAG; + spi_flash_write(env_flash, + env_offset + offsetof(env_t, flags), + sizeof(env_ptr->flags), &flag1); + } + } else if (current_env == 2) { + if (flag1 != OBSOLETE_FLAG) { + flag1 = OBSOLETE_FLAG; + spi_flash_write(env_flash, + env_new_offset + offsetof(env_t, flags), + sizeof(env_ptr->flags), &flag1); + } + if (flag2 != ACTIVE_FLAG) { + flag2 = ACTIVE_FLAG; + spi_flash_write(env_flash, + env_offset + offsetof(env_t, flags), + sizeof(env_ptr->flags), &flag2); + } + } + if (gd->env_valid == 2) { + puts("*** Warning - some problems detected " + "reading environment; recovered successfully\n\n"); + } + if (tmp_env1) + free(tmp_env1); + if (tmp_env2) + free(tmp_env2); + return; + +err_read: + spi_flash_free(env_flash); + env_flash = NULL; +err_probe: +err_crc: + puts("*** Warning - bad CRC, using default environment\n\n"); +out: + if (tmp_env1) + free(tmp_env1); + if (tmp_env2) + free(tmp_env2); + set_default_env(); +} +#else int saveenv(void) { u32 saved_size, saved_offset; @@ -144,6 +375,7 @@ err_crc: set_default_env(); } +#endif int env_init(void) { diff --git a/drivers/mtd/spi/atmel.c b/drivers/mtd/spi/atmel.c index 8306c00..8d02169 100644 --- a/drivers/mtd/spi/atmel.c +++ b/drivers/mtd/spi/atmel.c @@ -467,7 +467,7 @@ out: struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode) { const struct atmel_spi_flash_params *params; - unsigned long page_size; + unsigned page_size; unsigned int family; struct atmel_spi_flash *asf; unsigned int i; @@ -540,8 +540,9 @@ struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode) * params->blocks_per_sector * params->nr_sectors; - debug("SF: Detected %s with page size %lu, total %u bytes\n", - params->name, page_size, asf->flash.size); + printf("SF: Detected %s with page size %u, total ", + params->name, page_size); + print_size(asf->flash.size, "\n"); return &asf->flash; diff --git a/drivers/mtd/spi/macronix.c b/drivers/mtd/spi/macronix.c index fe1310b..76d5284 100644 --- a/drivers/mtd/spi/macronix.c +++ b/drivers/mtd/spi/macronix.c @@ -330,8 +330,9 @@ struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode) mcx->flash.size = params->page_size * params->pages_per_sector * params->sectors_per_block * params->nr_blocks; - printf("SF: Detected %s with page size %u, total %u bytes\n", - params->name, params->page_size, mcx->flash.size); + printf("SF: Detected %s with page size %u, total ", + params->name, params->page_size); + print_size(mcx->flash.size, "\n"); return &mcx->flash; } diff --git a/drivers/mtd/spi/spansion.c b/drivers/mtd/spi/spansion.c index fdb7917..d6c1a5f 100644 --- a/drivers/mtd/spi/spansion.c +++ b/drivers/mtd/spi/spansion.c @@ -343,8 +343,9 @@ struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode) spsn->flash.size = params->page_size * params->pages_per_sector * params->nr_sectors; - debug("SF: Detected %s with page size %u, total %u bytes\n", - params->name, params->page_size, spsn->flash.size); + printf("SF: Detected %s with page size %u, total ", + params->name, params->page_size); + print_size(spsn->flash.size, "\n"); return &spsn->flash; } diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index 612f819..ea875dc 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -106,7 +106,7 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, spi = spi_setup_slave(bus, cs, max_hz, spi_mode); if (!spi) { - debug("SF: Failed to set up slave\n"); + printf("SF: Failed to set up slave\n"); return NULL; } @@ -147,6 +147,7 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, #endif #ifdef CONFIG_SPI_FLASH_STMICRO case 0x20: + case 0xff: /* Let the stmicro func handle non-JEDEC ids */ flash = spi_flash_probe_stmicro(spi, idcode); break; #endif @@ -156,7 +157,7 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, break; #endif default: - debug("SF: Unsupported manufacturer %02X\n", idcode[0]); + printf("SF: Unsupported manufacturer %02X\n", idcode[0]); flash = NULL; break; } diff --git a/drivers/mtd/spi/sst.c b/drivers/mtd/spi/sst.c index 50e9299..2557891 100644 --- a/drivers/mtd/spi/sst.c +++ b/drivers/mtd/spi/sst.c @@ -364,8 +364,9 @@ spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode) stm->flash.read = sst_read_fast; stm->flash.size = SST_SECTOR_SIZE * params->nr_sectors; - debug("SF: Detected %s with page size %u, total %u bytes\n", - params->name, SST_SECTOR_SIZE, stm->flash.size); + printf("SF: Detected %s with page size %u, total ", + params->name, SST_SECTOR_SIZE); + print_size(stm->flash.size, "\n"); /* Flash powers up read-only, so clear BP# bits */ sst_unlock(&stm->flash); diff --git a/drivers/mtd/spi/stmicro.c b/drivers/mtd/spi/stmicro.c index ae0d047..3134027 100644 --- a/drivers/mtd/spi/stmicro.c +++ b/drivers/mtd/spi/stmicro.c @@ -46,6 +46,7 @@ #define CMD_M25PXX_DP 0xb9 /* Deep Power-down */ #define CMD_M25PXX_RES 0xab /* Release from DP, and Read Signature */ +#define STM_ID_M25P10 0x11 #define STM_ID_M25P16 0x15 #define STM_ID_M25P20 0x12 #define STM_ID_M25P32 0x16 @@ -78,6 +79,13 @@ static inline struct stmicro_spi_flash *to_stmicro_spi_flash(struct spi_flash static const struct stmicro_spi_flash_params stmicro_spi_flash_table[] = { { + .idcode1 = STM_ID_M25P10, + .page_size = 256, + .pages_per_sector = 128, + .nr_sectors = 4, + .name = "M25P10", + }, + { .idcode1 = STM_ID_M25P16, .page_size = 256, .pages_per_sector = 256, @@ -316,6 +324,19 @@ struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode) struct stmicro_spi_flash *stm; unsigned int i; + if (idcode[0] == 0xff) { + i = spi_flash_cmd(spi, CMD_M25PXX_RES, + idcode, 4); + if (i) + return NULL; + if ((idcode[3] & 0xf0) == 0x10) { + idcode[0] = 0x20; + idcode[1] = 0x20; + idcode[2] = idcode[3] + 1; + } else + return NULL; + } + for (i = 0; i < ARRAY_SIZE(stmicro_spi_flash_table); i++) { params = &stmicro_spi_flash_table[i]; if (params->idcode1 == idcode[2]) { @@ -344,8 +365,9 @@ struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode) stm->flash.size = params->page_size * params->pages_per_sector * params->nr_sectors; - debug("SF: Detected %s with page size %u, total %u bytes\n", - params->name, params->page_size, stm->flash.size); + printf("SF: Detected %s with page size %u, total ", + params->name, params->page_size); + print_size(stm->flash.size, "\n"); return &stm->flash; } diff --git a/drivers/mtd/spi/winbond.c b/drivers/mtd/spi/winbond.c index b8da923..ff1df25 100644 --- a/drivers/mtd/spi/winbond.c +++ b/drivers/mtd/spi/winbond.c @@ -289,7 +289,7 @@ out: struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode) { const struct winbond_spi_flash_params *params; - unsigned long page_size; + unsigned page_size; struct winbond_spi_flash *stm; unsigned int i; @@ -325,8 +325,9 @@ struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode) * params->sectors_per_block * params->nr_blocks; - debug("SF: Detected %s with page size %u, total %u bytes\n", - params->name, page_size, stm->flash.size); + printf("SF: Detected %s with page size %u, total ", + params->name, page_size); + print_size(stm->flash.size, "\n"); return &stm->flash; } diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index b2e03bc..64fde68 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -41,6 +41,15 @@ int usb_cpu_init(void) writel(get_pllb_init(), &pmc->pllbr); while ((readl(&pmc->sr) & AT91_PMC_LOCKB) != AT91_PMC_LOCKB) ; +#elif defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) + /* Enable UPLL */ + writel(readl(&pmc->uckr) | AT91_PMC_UPLLEN | AT91_PMC_BIASEN, + &pmc->uckr); + while ((readl(&pmc->sr) & AT91_PMC_LOCKU) != AT91_PMC_LOCKU) + ; + + /* Select PLLA as input clock of OHCI */ + writel(AT91_PMC_USBS_USB_UPLL | AT91_PMC_USBDIV_10, &pmc->usb); #endif /* Enable USB host clock. */ @@ -72,6 +81,11 @@ int usb_cpu_stop(void) writel(0, &pmc->pllbr); while ((readl(&pmc->sr) & AT91_PMC_LOCKB) != 0) ; +#elif defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) + /* Disable UPLL */ + writel(readl(&pmc->uckr) & (~AT91_PMC_UPLLEN), &pmc->uckr); + while ((readl(&pmc->sr) & AT91_PMC_LOCKU) == AT91_PMC_LOCKU) + ; #endif return 0; diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index b03a600..3f76c4e 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -83,17 +83,6 @@ #define OHCI_CONTROL_INIT \ (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE -/* - * e.g. PCI controllers need this - */ -#ifdef CONFIG_SYS_OHCI_SWAP_REG_ACCESS -# define readl(a) __swap_32(*((volatile u32 *)(a))) -# define writel(a, b) (*((volatile u32 *)(b)) = __swap_32((volatile u32)a)) -#else -# define readl(a) (*((volatile u32 *)(a))) -# define writel(a, b) (*((volatile u32 *)(b)) = ((volatile u32)a)) -#endif /* CONFIG_SYS_OHCI_SWAP_REG_ACCESS */ - #define min_t(type, x, y) \ ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) @@ -147,13 +136,13 @@ struct ohci_device ohci_dev; struct usb_device *devgone; static inline u32 roothub_a(struct ohci *hc) - { return readl(&hc->regs->roothub.a); } + { return ohci_readl(&hc->regs->roothub.a); } static inline u32 roothub_b(struct ohci *hc) - { return readl(&hc->regs->roothub.b); } + { return ohci_readl(&hc->regs->roothub.b); } static inline u32 roothub_status(struct ohci *hc) - { return readl(&hc->regs->roothub.status); } + { return ohci_readl(&hc->regs->roothub.status); } static inline u32 roothub_portstatus(struct ohci *hc, int i) - { return readl(&hc->regs->roothub.portstatus[i]); } + { return ohci_readl(&hc->regs->roothub.portstatus[i]); } /* forward declaration */ static int hc_interrupt(void); @@ -302,11 +291,11 @@ static void ohci_dump_status(ohci_t *controller) struct ohci_regs *regs = controller->regs; __u32 temp; - temp = readl(®s->revision) & 0xff; + temp = ohci_readl(®s->revision) & 0xff; if (temp != 0x10) dbg("spec %d.%d", (temp >> 4), (temp & 0x0f)); - temp = readl(®s->control); + temp = ohci_readl(®s->control); dbg("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp, (temp & OHCI_CTRL_RWE) ? " RWE" : "", (temp & OHCI_CTRL_RWC) ? " RWC" : "", @@ -319,7 +308,7 @@ static void ohci_dump_status(ohci_t *controller) temp & OHCI_CTRL_CBSR ); - temp = readl(®s->cmdstatus); + temp = ohci_readl(®s->cmdstatus); dbg("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp, (temp & OHCI_SOC) >> 16, (temp & OHCI_OCR) ? " OCR" : "", @@ -328,18 +317,20 @@ static void ohci_dump_status(ohci_t *controller) (temp & OHCI_HCR) ? " HCR" : "" ); - ohci_dump_intr_mask("intrstatus", readl(®s->intrstatus)); - ohci_dump_intr_mask("intrenable", readl(®s->intrenable)); + ohci_dump_intr_mask("intrstatus", ohci_readl(®s->intrstatus)); + ohci_dump_intr_mask("intrenable", ohci_readl(®s->intrenable)); - maybe_print_eds("ed_periodcurrent", readl(®s->ed_periodcurrent)); + maybe_print_eds("ed_periodcurrent", + ohci_readl(®s->ed_periodcurrent)); - maybe_print_eds("ed_controlhead", readl(®s->ed_controlhead)); - maybe_print_eds("ed_controlcurrent", readl(®s->ed_controlcurrent)); + maybe_print_eds("ed_controlhead", ohci_readl(®s->ed_controlhead)); + maybe_print_eds("ed_controlcurrent", + ohci_readl(®s->ed_controlcurrent)); - maybe_print_eds("ed_bulkhead", readl(®s->ed_bulkhead)); - maybe_print_eds("ed_bulkcurrent", readl(®s->ed_bulkcurrent)); + maybe_print_eds("ed_bulkhead", ohci_readl(®s->ed_bulkhead)); + maybe_print_eds("ed_bulkcurrent", ohci_readl(®s->ed_bulkcurrent)); - maybe_print_eds("donehead", readl(®s->donehead)); + maybe_print_eds("donehead", ohci_readl(®s->donehead)); } static void ohci_dump_roothub(ohci_t *controller, int verbose) @@ -518,11 +509,11 @@ static inline int sohci_return_job(struct ohci *hc, urb_priv_t *urb) /* implicitly requeued */ if (urb->dev->irq_handle && (urb->dev->irq_act_len = urb->actual_length)) { - writel(OHCI_INTR_WDH, ®s->intrenable); - readl(®s->intrenable); /* PCI posting flush */ + ohci_writel(OHCI_INTR_WDH, ®s->intrenable); + ohci_readl(®s->intrenable); /* PCI posting flush */ urb->dev->irq_handle(urb->dev); - writel(OHCI_INTR_WDH, ®s->intrdisable); - readl(®s->intrdisable); /* PCI posting flush */ + ohci_writel(OHCI_INTR_WDH, ®s->intrdisable); + ohci_readl(®s->intrdisable); /* PCI posting flush */ } urb->actual_length = 0; td_submit_job( @@ -631,7 +622,7 @@ static int ep_link(ohci_t *ohci, ed_t *edi) case PIPE_CONTROL: ed->hwNextED = 0; if (ohci->ed_controltail == NULL) - writel(ed, &ohci->regs->ed_controlhead); + ohci_writel(ed, &ohci->regs->ed_controlhead); else ohci->ed_controltail->hwNextED = m32_swap((unsigned long)ed); @@ -640,7 +631,7 @@ static int ep_link(ohci_t *ohci, ed_t *edi) if (!ohci->ed_controltail && !ohci->ed_rm_list[0] && !ohci->ed_rm_list[1] && !ohci->sleeping) { ohci->hc_control |= OHCI_CTRL_CLE; - writel(ohci->hc_control, &ohci->regs->control); + ohci_writel(ohci->hc_control, &ohci->regs->control); } ohci->ed_controltail = edi; break; @@ -648,7 +639,7 @@ static int ep_link(ohci_t *ohci, ed_t *edi) case PIPE_BULK: ed->hwNextED = 0; if (ohci->ed_bulktail == NULL) - writel(ed, &ohci->regs->ed_bulkhead); + ohci_writel(ed, &ohci->regs->ed_bulkhead); else ohci->ed_bulktail->hwNextED = m32_swap((unsigned long)ed); @@ -657,7 +648,7 @@ static int ep_link(ohci_t *ohci, ed_t *edi) if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] && !ohci->ed_rm_list[1] && !ohci->sleeping) { ohci->hc_control |= OHCI_CTRL_BLE; - writel(ohci->hc_control, &ohci->regs->control); + ohci_writel(ohci->hc_control, &ohci->regs->control); } ohci->ed_bulktail = edi; break; @@ -725,9 +716,10 @@ static int ep_unlink(ohci_t *ohci, ed_t *edi) if (ed->ed_prev == NULL) { if (!ed->hwNextED) { ohci->hc_control &= ~OHCI_CTRL_CLE; - writel(ohci->hc_control, &ohci->regs->control); + ohci_writel(ohci->hc_control, + &ohci->regs->control); } - writel(m32_swap(*((__u32 *)&ed->hwNextED)), + ohci_writel(m32_swap(*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_controlhead); } else { ed->ed_prev->hwNextED = ed->hwNextED; @@ -744,9 +736,10 @@ static int ep_unlink(ohci_t *ohci, ed_t *edi) if (ed->ed_prev == NULL) { if (!ed->hwNextED) { ohci->hc_control &= ~OHCI_CTRL_BLE; - writel(ohci->hc_control, &ohci->regs->control); + ohci_writel(ohci->hc_control, + &ohci->regs->control); } - writel(m32_swap(*((__u32 *)&ed->hwNextED)), + ohci_writel(m32_swap(*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_bulkhead); } else { ed->ed_prev->hwNextED = ed->hwNextED; @@ -923,7 +916,7 @@ static void td_submit_job(struct usb_device *dev, unsigned long pipe, if (!ohci->sleeping) { /* start bulk list */ - writel(OHCI_BLF, &ohci->regs->cmdstatus); + ohci_writel(OHCI_BLF, &ohci->regs->cmdstatus); } break; @@ -949,7 +942,7 @@ static void td_submit_job(struct usb_device *dev, unsigned long pipe, if (!ohci->sleeping) { /* start Control list */ - writel(OHCI_CLF, &ohci->regs->cmdstatus); + ohci_writel(OHCI_CLF, &ohci->regs->cmdstatus); } break; @@ -1224,13 +1217,13 @@ static unsigned char root_hub_str_index1[] = #define OK(x) len = (x); break #ifdef DEBUG -#define WR_RH_STAT(x) {info("WR:status %#8x", (x)); writel((x), \ +#define WR_RH_STAT(x) {info("WR:status %#8x", (x)); ohci_writel((x), \ &gohci.regs->roothub.status); } #define WR_RH_PORTSTAT(x) {info("WR:portstatus[%d] %#8x", wIndex-1, \ - (x)); writel((x), &gohci.regs->roothub.portstatus[wIndex-1]); } + (x)); ohci_writel((x), &gohci.regs->roothub.portstatus[wIndex-1]); } #else -#define WR_RH_STAT(x) writel((x), &gohci.regs->roothub.status) -#define WR_RH_PORTSTAT(x) writel((x), \ +#define WR_RH_STAT(x) ohci_writel((x), &gohci.regs->roothub.status) +#define WR_RH_PORTSTAT(x) ohci_writel((x), \ &gohci.regs->roothub.portstatus[wIndex-1]) #endif #define RD_RH_STAT roothub_status(&gohci) @@ -1661,10 +1654,10 @@ static int hc_reset(ohci_t *ohci) int timeout = 1000; pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &base); - writel(readl(base + EHCI_USBCMD_OFF) | EHCI_USBCMD_HCRESET, - base + EHCI_USBCMD_OFF); + base += EHCI_USBCMD_OFF; + ohci_writel(ohci_readl(base) | EHCI_USBCMD_HCRESET, base); - while (readl(base + EHCI_USBCMD_OFF) & EHCI_USBCMD_HCRESET) { + while (ohci_readl(base) & EHCI_USBCMD_HCRESET) { if (timeout-- <= 0) { printf("USB RootHub reset timed out!"); break; @@ -1674,11 +1667,11 @@ static int hc_reset(ohci_t *ohci) } else printf("No EHCI func at %d index!\n", CONFIG_PCI_EHCI_DEVNO); #endif - if (readl(&ohci->regs->control) & OHCI_CTRL_IR) { - /* SMM owns the HC */ - writel(OHCI_OCR, &ohci->regs->cmdstatus);/* request ownership */ + if (ohci_readl(&ohci->regs->control) & OHCI_CTRL_IR) { + /* SMM owns the HC, request ownership */ + ohci_writel(OHCI_OCR, &ohci->regs->cmdstatus); info("USB HC TakeOver from SMM"); - while (readl(&ohci->regs->control) & OHCI_CTRL_IR) { + while (ohci_readl(&ohci->regs->control) & OHCI_CTRL_IR) { wait_ms(10); if (--smm_timeout == 0) { err("USB HC TakeOver failed!"); @@ -1688,19 +1681,19 @@ static int hc_reset(ohci_t *ohci) } /* Disable HC interrupts */ - writel(OHCI_INTR_MIE, &ohci->regs->intrdisable); + ohci_writel(OHCI_INTR_MIE, &ohci->regs->intrdisable); dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;\n", ohci->slot_name, - readl(&ohci->regs->control)); + ohci_readl(&ohci->regs->control)); /* Reset USB (needed by some controllers) */ ohci->hc_control = 0; - writel(ohci->hc_control, &ohci->regs->control); + ohci_writel(ohci->hc_control, &ohci->regs->control); /* HC Reset requires max 10 us delay */ - writel(OHCI_HCR, &ohci->regs->cmdstatus); - while ((readl(&ohci->regs->cmdstatus) & OHCI_HCR) != 0) { + ohci_writel(OHCI_HCR, &ohci->regs->cmdstatus); + while ((ohci_readl(&ohci->regs->cmdstatus) & OHCI_HCR) != 0) { if (--timeout == 0) { err("USB HC reset timed out!"); return -1; @@ -1726,39 +1719,40 @@ static int hc_start(ohci_t *ohci) /* Tell the controller where the control and bulk lists are * The lists are empty now. */ - writel(0, &ohci->regs->ed_controlhead); - writel(0, &ohci->regs->ed_bulkhead); + ohci_writel(0, &ohci->regs->ed_controlhead); + ohci_writel(0, &ohci->regs->ed_bulkhead); - writel((__u32)ohci->hcca, &ohci->regs->hcca); /* a reset clears this */ + ohci_writel((__u32)ohci->hcca, + &ohci->regs->hcca); /* reset clears this */ fminterval = 0x2edf; - writel((fminterval * 9) / 10, &ohci->regs->periodicstart); + ohci_writel((fminterval * 9) / 10, &ohci->regs->periodicstart); fminterval |= ((((fminterval - 210) * 6) / 7) << 16); - writel(fminterval, &ohci->regs->fminterval); - writel(0x628, &ohci->regs->lsthresh); + ohci_writel(fminterval, &ohci->regs->fminterval); + ohci_writel(0x628, &ohci->regs->lsthresh); /* start controller operations */ ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER; ohci->disabled = 0; - writel(ohci->hc_control, &ohci->regs->control); + ohci_writel(ohci->hc_control, &ohci->regs->control); /* disable all interrupts */ mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD | OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC | OHCI_INTR_OC | OHCI_INTR_MIE); - writel(mask, &ohci->regs->intrdisable); + ohci_writel(mask, &ohci->regs->intrdisable); /* clear all interrupts */ mask &= ~OHCI_INTR_MIE; - writel(mask, &ohci->regs->intrstatus); + ohci_writel(mask, &ohci->regs->intrstatus); /* Choose the interrupts we care about now - but w/o MIE */ mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO; - writel(mask, &ohci->regs->intrenable); + ohci_writel(mask, &ohci->regs->intrenable); #ifdef OHCI_USE_NPS /* required for AMD-756 and some Mac platforms */ - writel((roothub_a(ohci) | RH_A_NPS) & ~RH_A_PSM, + ohci_writel((roothub_a(ohci) | RH_A_NPS) & ~RH_A_PSM, &ohci->regs->roothub.a); - writel(RH_HS_LPSC, &ohci->regs->roothub.status); + ohci_writel(RH_HS_LPSC, &ohci->regs->roothub.status); #endif /* OHCI_USE_NPS */ #define mdelay(n) ({unsigned long msec = (n); while (msec--) udelay(1000); }) @@ -1792,13 +1786,13 @@ static int hc_interrupt(void) !(m32_swap(ohci->hcca->done_head) & 0x01)) { ints = OHCI_INTR_WDH; } else { - ints = readl(®s->intrstatus); + ints = ohci_readl(®s->intrstatus); if (ints == ~(u32)0) { ohci->disabled++; err("%s device removed!", ohci->slot_name); return -1; } else { - ints &= readl(®s->intrenable); + ints &= ohci_readl(®s->intrenable); if (ints == 0) { dbg("hc_interrupt: returning..\n"); return 0xff; @@ -1833,16 +1827,16 @@ static int hc_interrupt(void) if (ints & OHCI_INTR_WDH) { wait_ms(1); - writel(OHCI_INTR_WDH, ®s->intrdisable); - (void)readl(®s->intrdisable); /* flush */ + ohci_writel(OHCI_INTR_WDH, ®s->intrdisable); + (void)ohci_readl(®s->intrdisable); /* flush */ stat = dl_done_list(&gohci); - writel(OHCI_INTR_WDH, ®s->intrenable); - (void)readl(®s->intrdisable); /* flush */ + ohci_writel(OHCI_INTR_WDH, ®s->intrenable); + (void)ohci_readl(®s->intrdisable); /* flush */ } if (ints & OHCI_INTR_SO) { dbg("USB Schedule overrun\n"); - writel(OHCI_INTR_SO, ®s->intrenable); + ohci_writel(OHCI_INTR_SO, ®s->intrenable); stat = -1; } @@ -1850,13 +1844,13 @@ static int hc_interrupt(void) if (ints & OHCI_INTR_SF) { unsigned int frame = m16_swap(ohci->hcca->frame_no) & 1; wait_ms(1); - writel(OHCI_INTR_SF, ®s->intrdisable); + ohci_writel(OHCI_INTR_SF, ®s->intrdisable); if (ohci->ed_rm_list[frame] != NULL) - writel(OHCI_INTR_SF, ®s->intrenable); + ohci_writel(OHCI_INTR_SF, ®s->intrenable); stat = 0xff; } - writel(ints, ®s->intrstatus); + ohci_writel(ints, ®s->intrstatus); return stat; } diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 79aa79d..d977e8f 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -7,6 +7,17 @@ * usb-ohci.h */ +/* + * e.g. PCI controllers need this + */ +#ifdef CONFIG_SYS_OHCI_SWAP_REG_ACCESS +# define ohci_readl(a) __swap_32(*((volatile u32 *)(a))) +# define ohci_writel(a, b) (*((volatile u32 *)(b)) = __swap_32((volatile u32)a)) +#else +# define ohci_readl(a) (*((volatile u32 *)(a))) +# define ohci_writel(a, b) (*((volatile u32 *)(b)) = ((volatile u32)a)) +#endif /* CONFIG_SYS_OHCI_SWAP_REG_ACCESS */ + /* functions for doing board or CPU specific setup/cleanup */ extern int usb_board_init(void); extern int usb_board_stop(void); @@ -196,8 +207,8 @@ struct ohci_hcca { /* * This is the structure of the OHCI controller's memory mapped I/O - * region. This is Memory Mapped I/O. You must use the readl() and - * writel() macros defined in asm/io.h to access these!! + * region. This is Memory Mapped I/O. You must use the ohci_readl() and + * ohci_writel() macros defined in this file to access these!! */ struct ohci_regs { /* control and status registers */ diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 40bfe44..617d88e 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -27,9 +27,9 @@ /* MUSB platform configuration */ struct musb_config musb_cfg = { - (struct musb_regs *)DA8XX_USB_OTG_CORE_BASE, - DA8XX_USB_OTG_TIMEOUT, - 0 + .regs = (struct musb_regs *)DA8XX_USB_OTG_CORE_BASE, + .timeout = DA8XX_USB_OTG_TIMEOUT, + .musb_speed = 0, }; /* diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 8fbadc9..f56f2df 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -28,9 +28,9 @@ /* MUSB platform configuration */ struct musb_config musb_cfg = { - (struct musb_regs *)MENTOR_USB0_BASE, - DAVINCI_USB_TIMEOUT, - 0 + .regs = (struct musb_regs *)MENTOR_USB0_BASE, + .timeout = DAVINCI_USB_TIMEOUT, + .musb_speed = 0, }; /* MUSB module register overlay */ diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 7766069..dc740cf 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -34,6 +34,7 @@ void musb_start(void) { #if defined(CONFIG_MUSB_HCD) u8 devctl; + u8 busctl; #endif /* disable all interrupts */ @@ -45,6 +46,12 @@ void musb_start(void) /* put into basic highspeed mode and start session */ writeb(MUSB_POWER_HSENAB, &musbr->power); #if defined(CONFIG_MUSB_HCD) + /* Program PHY to use EXT VBUS if required */ + if (musb_cfg.extvbus == 1) { + busctl = musb_read_ulpi_buscontrol(musbr); + musb_write_ulpi_buscontrol(musbr, busctl | ULPI_USE_EXTVBUS); + } + devctl = readb(&musbr->devctl); writeb(devctl | MUSB_DEVCTL_SESSION, &musbr->devctl); #endif diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 9a1fb4f..4771876 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -112,7 +112,10 @@ struct musb_regs { u16 rxfifoadd; u32 vcontrol; u16 hwvers; - u16 reserved2[5]; + u16 reserved2a[1]; + u8 ulpi_busctl; + u8 reserved2b[1]; + u16 reserved2[3]; u8 epinfo; u8 raminfo; u8 linkinfo; @@ -181,6 +184,10 @@ struct musb_regs { #define MUSB_DEVCTL_HR 0x02 #define MUSB_DEVCTL_SESSION 0x01 +/* ULPI VBUSCONTROL */ +#define ULPI_USE_EXTVBUS 0x01 +#define ULPI_USE_EXTVBUSIND 0x02 + /* TESTMODE */ #define MUSB_TEST_FORCE_HOST 0x80 #define MUSB_TEST_FIFO_ACCESS 0x40 @@ -341,6 +348,7 @@ struct musb_config { struct musb_regs *regs; u32 timeout; u8 musb_speed; + u8 extvbus; }; /* externally defined data */ @@ -361,6 +369,26 @@ extern void read_fifo(u8 ep, u32 length, void *fifo_data); # define readb(addr) (u8)bfin_read16(addr) # undef writeb # define writeb(b, addr) bfin_write16(addr, b) +/* + * The USB PHY on current Blackfin processors is a UTMI+ level 2 PHY. + * However, it has no ULPI support - so there are no registers at all. + * That means accesses to ULPI_BUSCONTROL have to be abstracted away. + */ +static inline u8 musb_read_ulpi_buscontrol(struct musb_regs *musbr) +{ + return 0; +} +static inline void musb_write_ulpi_buscontrol(struct musb_regs *musbr, u8 val) +{} +#else +static inline u8 musb_read_ulpi_buscontrol(struct musb_regs *musbr) +{ + return readb(&musbr->ulpi_busctl); +} +static inline void musb_write_ulpi_buscontrol(struct musb_regs *musbr, u8 val) +{ + writeb(val, &musbr->ulpi_busctl); +} #endif #endif /* __MUSB_HDRC_DEFS_H__ */ diff --git a/drivers/usb/musb/omap3.c b/drivers/usb/musb/omap3.c index 3bfd0a0..a983552 100644 --- a/drivers/usb/musb/omap3.c +++ b/drivers/usb/musb/omap3.c @@ -36,9 +36,9 @@ static int platform_needs_initialization = 1; struct musb_config musb_cfg = { - (struct musb_regs *)MENTOR_USB0_BASE, - OMAP3_USB_TIMEOUT, - 0 + .regs = (struct musb_regs *)MENTOR_USB0_BASE, + .timeout = OMAP3_USB_TIMEOUT, + .musb_speed = 0, }; /* @@ -119,6 +119,9 @@ int musb_platform_init(void) stdby &= ~OMAP3_OTG_FORCESTDBY_STANDBY; writel(stdby, &otg->forcestdby); +#ifdef CONFIG_OMAP3_EVM + musb_cfg.extvbus = omap3_evm_need_extvbus(); +#endif platform_needs_initialization = 0; } diff --git a/drivers/usb/musb/omap3.h b/drivers/usb/musb/omap3.h index b591862..c934e0c 100644 --- a/drivers/usb/musb/omap3.h +++ b/drivers/usb/musb/omap3.h @@ -44,4 +44,8 @@ int musb_platform_init(void); +#ifdef CONFIG_OMAP3_EVM +extern u8 omap3_evm_use_extvbus(void); +#endif + #endif /* _MUSB_OMAP3_H */ |