diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/omap_gpmc.c | 76 | ||||
-rw-r--r-- | drivers/power/twl4030.c | 2 | ||||
-rw-r--r-- | drivers/usb/musb/musb_udc.c | 30 |
4 files changed, 95 insertions, 15 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 1092a797321..f37d45bdc4c 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2024,7 +2024,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, uint8_t *wbuf = buf; /* Partial page write ? */ - if (unlikely(column || writelen < (mtd->writesize - 1))) { + if (unlikely(column || writelen < mtd->writesize)) { cached = 0; bytes = min_t(int, bytes - column, (int) writelen); chip->pagebuf = -1; diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c index 1a636cad236..865065e03b3 100644 --- a/drivers/mtd/nand/omap_gpmc.c +++ b/drivers/mtd/nand/omap_gpmc.c @@ -390,6 +390,35 @@ static void micron_set_chip_ecc(struct mtd_info *mtd, int enable) #endif } +void nand_disable_in_chip_ecc(void) +{ + struct nand_chip *nand; + struct mtd_info *mtd; + + if (nand_curr_device < 0 || + nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE || + !nand_info[nand_curr_device].name) + return; + + mtd = &nand_info[nand_curr_device]; + nand = mtd->priv; + + /* If the NAND has in-chip ECC, disable it! */ + if (nand->has_chip_ecc) + micron_set_chip_ecc(mtd, 0); +} + +#ifdef CONFIG_CMD_NAND_CHIP_ECC +static int micron_get_chip_ecc(struct mtd_info *mtd) +{ + uint8_t params[4]; + + nand_get_features(mtd, 0x90, params); + + return ((params[0] & 0x08) != 0); +} +#endif + /** * nand_read_oob_chipecc - read; get status to seeif chip ECC error * @mtd: mtd info structure @@ -610,6 +639,7 @@ void omap_nand_switch_ecc(enum omap_nand_ecc_mode mode) { struct nand_chip *nand; struct mtd_info *mtd; + int in_chip_ecc = 0; if (nand_curr_device < 0 || nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE || @@ -619,6 +649,12 @@ void omap_nand_switch_ecc(enum omap_nand_ecc_mode mode) mtd = &nand_info[nand_curr_device]; nand = mtd->priv; + if (mode == OMAP_ECC_CHIP && !nand->has_chip_ecc) + { + printf("NAND: Chip does not have internal ECC!\n"); + return; + } + nand->options |= NAND_OWN_BUFFERS; /* Reset ecc interface */ @@ -683,20 +719,12 @@ void omap_nand_switch_ecc(enum omap_nand_ecc_mode mode) nand->ecc.calculate = omap_calculate_ecc; omap_hwecc_init(nand); printf("NAND: HW ECC selected\n"); - if (nand->has_chip_ecc) - micron_set_chip_ecc(mtd, 0); } else if (mode == OMAP_ECC_SOFT) { nand->ecc.mode = NAND_ECC_SOFT; /* Use mtd default settings */ nand->ecc.layout = NULL; printf("NAND: SW ECC selected\n"); - if (nand->has_chip_ecc) - micron_set_chip_ecc(mtd, 0); } else if (mode == OMAP_ECC_CHIP) { - if (!nand->has_chip_ecc) { - printf("NAND: Chip does not have internal ECC!\n"); - return; - } nand->ecc.bytes = 0; nand->ecc.size = 2048; nand->ecc.calculate = omap_calculate_chip_hwecc; @@ -716,13 +744,17 @@ void omap_nand_switch_ecc(enum omap_nand_ecc_mode mode) nand->cmdfunc = omap_nand_command_lp; else printf("%s: Huh? not 16-bit wide\n", __FUNCTION__); - micron_set_chip_ecc(mtd, 1); printf("NAND: Internal to NAND ECC selected\n"); + in_chip_ecc = 1; } else { printf("NAND: unknown ECC mode %d\n", mode); return; } + /* Enable/disable the in-chip ECC engine appropriately */ + if (nand->has_chip_ecc) + micron_set_chip_ecc(mtd, in_chip_ecc); + current_ecc_method = mode; /* Update NAND handling after ECC mode switch */ @@ -731,6 +763,32 @@ void omap_nand_switch_ecc(enum omap_nand_ecc_mode mode) nand->options &= ~NAND_OWN_BUFFERS; } +#ifdef CONFIG_CMD_NAND_CHIP_ECC +int omap_nand_switch_chip_ecc(int get, int enable) +{ + struct nand_chip *nand; + struct mtd_info *mtd; + + if (nand_curr_device < 0 || + nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE || + !nand_info[nand_curr_device].name) + return -1; + + mtd = &nand_info[nand_curr_device]; + nand = mtd->priv; + + /* If no in-chip ECC, punt! */ + if (!nand->has_chip_ecc) + return -1; + + if (get) + return micron_get_chip_ecc(mtd); + + micron_set_chip_ecc(mtd, enable); + return 0; +} +#endif + /* * Board-specific NAND initialization. The following members of the * argument are board-specific: diff --git a/drivers/power/twl4030.c b/drivers/power/twl4030.c index b62ed176d25..92c8fd75b59 100644 --- a/drivers/power/twl4030.c +++ b/drivers/power/twl4030.c @@ -136,7 +136,7 @@ U_BOOT_CMD(poweroff, 1, 1, do_poweroff, /* Enable the battery backup charger */ int twl4030_enable_bb_charging(unsigned int millivolts, unsigned int microamps) { - u8 val; + u8 val = 0; if (millivolts >= 3200) val = 0x0c; diff --git a/drivers/usb/musb/musb_udc.c b/drivers/usb/musb/musb_udc.c index 6f6ed61d08b..3ebdcf1daf4 100644 --- a/drivers/usb/musb/musb_udc.c +++ b/drivers/usb/musb/musb_udc.c @@ -180,11 +180,15 @@ static void musb_peri_softconnect(void) /* Power on MUSB */ power = readb(&musbr->power); power |= MUSB_POWER_SOFTCONN; +#if USB_BCD_VERSION == 0x0200 + power |= MUSB_POWER_HSENAB; +#else /* * The usb device interface is usb 1.1 * Disable 2.0 high speed by clearring the hsenable bit. */ power &= ~MUSB_POWER_HSENAB; +#endif writeb(power, &musbr->power); /* Check if device is in b-peripheral mode */ @@ -786,6 +790,9 @@ void udc_irq(void) if (intrtx) musb_peri_tx(intrtx); } else { + udc_device->speed = + (readb(&musbr->power) & MUSB_POWER_HSMODE) ? + USB_SPEED_HIGH : USB_SPEED_FULL; if (MUSB_INTR_SOF & intrusb) { u8 faddr; faddr = readb(&musbr->faddr); @@ -881,10 +888,10 @@ void udc_setup_ep(struct usb_device_instance *device, unsigned int id, ep_addr = endpoint->endpoint_address; if (USB_DIR_IN == (ep_addr & USB_ENDPOINT_DIR_MASK)) { /* IN */ - epinfo[(id * 2) + 1].epsize = endpoint->tx_packetSize; + epinfo[((id - 1) * 2) + 1].epsize = endpoint->tx_packetSize; } else { /* OUT */ - epinfo[id * 2].epsize = endpoint->rcv_packetSize; + epinfo[(id - 1) * 2].epsize = endpoint->rcv_packetSize; } musb_configure_ep(&epinfo[0], @@ -899,12 +906,27 @@ void udc_setup_ep(struct usb_device_instance *device, unsigned int id, void udc_connect(void) { - /* noop */ + musb_peri_softconnect(); } void udc_disconnect(void) { - /* noop */ + u8 power, intrusb; + u16 intrrx, intrtx; + + /* If musbr Null, never initialized MUSB! */ + if (!musbr) + return; + + /* Power off MUSB */ + power = readb(&musbr->power); + power &= ~MUSB_POWER_SOFTCONN; + writeb(power, &musbr->power); + + /* Read intr to clear */ + intrusb = readb(&musbr->intrusb); + intrrx = readw(&musbr->intrrx); + intrtx = readw(&musbr->intrtx); } void udc_enable(struct usb_device_instance *device) |