diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/i2c/mxc_i2c.c | 12 | ||||
-rw-r--r-- | drivers/mmc/fsl_esdhc.c | 15 | ||||
-rw-r--r-- | drivers/net/fec_mxc.c | 20 | ||||
-rw-r--r-- | drivers/serial/serial_mxc.c | 9 | ||||
-rw-r--r-- | drivers/usb/host/dwc2.c | 7 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 50 | ||||
-rw-r--r-- | drivers/usb/musb-new/musb_host.c | 10 | ||||
-rw-r--r-- | drivers/usb/musb-new/usb-compat.h | 53 |
8 files changed, 64 insertions, 112 deletions
diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c index fa4c82f1a2..b2d15c9b6a 100644 --- a/drivers/i2c/mxc_i2c.c +++ b/drivers/i2c/mxc_i2c.c @@ -581,8 +581,16 @@ void bus_i2c_init(int index, int speed, int unused, return; } - mxc_i2c_buses[index].idle_bus_fn = idle_bus_fn; - mxc_i2c_buses[index].idle_bus_data = idle_bus_data; + /* + * Warning: Be careful to allow the assignment to a static + * variable here. This function could be called while U-Boot is + * still running in flash memory. So such assignment is equal + * to write data to flash without erasing. + */ + if (idle_bus_fn) + mxc_i2c_buses[index].idle_bus_fn = idle_bus_fn; + if (idle_bus_data) + mxc_i2c_buses[index].idle_bus_data = idle_bus_data; ret = enable_i2c_clk(1, index); if (ret < 0) { diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index c5054d66bd..1ccc576c34 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -502,15 +502,22 @@ static void set_sysctl(struct mmc *mmc, uint clock) clk = (pre_div << 8) | (div << 4); +#ifdef CONFIG_FSL_USDHC + esdhc_setbits32(®s->sysctl, SYSCTL_RSTA); +#else esdhc_clrbits32(®s->sysctl, SYSCTL_CKEN); +#endif esdhc_clrsetbits32(®s->sysctl, SYSCTL_CLOCK_MASK, clk); udelay(10000); - clk = SYSCTL_PEREN | SYSCTL_CKEN; +#ifdef CONFIG_FSL_USDHC + esdhc_clrbits32(®s->sysctl, SYSCTL_RSTA); +#else + esdhc_setbits32(®s->sysctl, SYSCTL_PEREN | SYSCTL_CKEN); +#endif - esdhc_setbits32(®s->sysctl, clk); } #ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK @@ -585,7 +592,9 @@ static int esdhc_init(struct mmc *mmc) esdhc_write32(®s->scr, 0x00000040); #endif +#ifndef CONFIG_FSL_USDHC esdhc_setbits32(®s->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN); +#endif /* Set the initial clock speed */ mmc_set_clock(mmc, 400000); @@ -657,8 +666,10 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) /* First reset the eSDHC controller */ esdhc_reset(regs); +#ifndef CONFIG_FSL_USDHC esdhc_setbits32(®s->sysctl, SYSCTL_PEREN | SYSCTL_HCKEN | SYSCTL_IPGEN | SYSCTL_CKEN); +#endif writel(SDHCI_IRQ_EN_BITS, ®s->irqstaten); memset(&cfg->cfg, 0, sizeof(cfg->cfg)); diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 79f6737e8e..3340dd256f 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -131,13 +131,25 @@ static void fec_mii_setspeed(struct ethernet_regs *eth) /* * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock * and do not drop the Preamble. + * + * The i.MX28 and i.MX6 types have another field in the MSCR (aka + * MII_SPEED) register that defines the MDIO output hold time. Earlier + * versions are RAZ there, so just ignore the difference and write the + * register always. + * The minimal hold time according to IEE802.3 (clause 22) is 10 ns. + * HOLDTIME + 1 is the number of clk cycles the fec is holding the + * output. + * The HOLDTIME bitfield takes values between 0 and 7 (inclusive). + * Given that ceil(clkrate / 5000000) <= 64, the calculation for + * holdtime cannot result in a value greater than 3. */ - register u32 speed = DIV_ROUND_UP(imx_get_fecclk(), 5000000); + u32 pclk = imx_get_fecclk(); + u32 speed = DIV_ROUND_UP(pclk, 5000000); + u32 hold = DIV_ROUND_UP(pclk, 100000000) - 1; #ifdef FEC_QUIRK_ENET_MAC speed--; #endif - speed <<= 1; - writel(speed, ð->mii_speed); + writel(speed << 1 | hold << 8, ð->mii_speed); debug("%s: mii_speed %08x\n", __func__, readl(ð->mii_speed)); } @@ -1097,6 +1109,7 @@ int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr) #ifdef CONFIG_PHYLIB phydev = phy_find_by_mask(bus, 1 << phy_id, PHY_INTERFACE_MODE_RGMII); if (!phydev) { + mdio_unregister(bus); free(bus); return -ENOMEM; } @@ -1108,6 +1121,7 @@ int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr) #ifdef CONFIG_PHYLIB free(phydev); #endif + mdio_unregister(bus); free(bus); } return ret; diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c index d6cf1d874a..51485c0d09 100644 --- a/drivers/serial/serial_mxc.c +++ b/drivers/serial/serial_mxc.c @@ -75,6 +75,7 @@ #define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */ #define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */ #define UFCR_RFDIV (7<<7) /* Reference freq divider mask */ +#define UFCR_RFDIV_SHF 7 /* Reference freq divider shift */ #define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */ #define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */ #define USR1_RTSS (1<<14) /* RTS pin status */ @@ -135,6 +136,10 @@ DECLARE_GLOBAL_DATA_PTR; +#define TXTL 2 /* reset default */ +#define RXTL 1 /* reset default */ +#define RFDIV 4 /* divide input clock by 2 */ + static void mxc_serial_setbrg(void) { u32 clk = imx_get_uartclk(); @@ -142,7 +147,9 @@ static void mxc_serial_setbrg(void) if (!gd->baudrate) gd->baudrate = CONFIG_BAUDRATE; - __REG(UART_PHYS + UFCR) = 4 << 7; /* divide input clock by 2 */ + __REG(UART_PHYS + UFCR) = (RFDIV << UFCR_RFDIV_SHF) + | (TXTL << UFCR_TXTL_SHF) + | (RXTL << UFCR_RXTL_SHF); __REG(UART_PHYS + UBIR) = 0xf; __REG(UART_PHYS + UBMR) = clk / (2 * gd->baudrate); diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c index 541c0f9687..5ef6debd9a 100644 --- a/drivers/usb/host/dwc2.c +++ b/drivers/usb/host/dwc2.c @@ -823,12 +823,13 @@ int chunk_msg(struct dwc2_priv *priv, struct usb_device *dev, (*pid << DWC2_HCTSIZ_PID_OFFSET), &hc_regs->hctsiz); - if (!in) { - memcpy(priv->aligned_buffer, (char *)buffer + done, len); + if (!in && xfer_len) { + memcpy(priv->aligned_buffer, (char *)buffer + done, + xfer_len); flush_dcache_range((unsigned long)priv->aligned_buffer, (unsigned long)((void *)priv->aligned_buffer + - roundup(len, ARCH_DMA_MINALIGN))); + roundup(xfer_len, ARCH_DMA_MINALIGN))); } writel(phys_to_bus((unsigned long)priv->aligned_buffer), diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index c85dbcecfa..c664b1629e 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -279,56 +279,16 @@ static inline u8 ehci_encode_speed(enum usb_device_speed speed) static void ehci_update_endpt2_dev_n_port(struct usb_device *udev, struct QH *qh) { - struct usb_device *ttdev; - int parent_devnum; + uint8_t portnr = 0; + uint8_t hubaddr = 0; if (udev->speed != USB_SPEED_LOW && udev->speed != USB_SPEED_FULL) return; - /* - * For full / low speed devices we need to get the devnum and portnr of - * the tt, so of the first upstream usb-2 hub, there may be usb-1 hubs - * in the tree before that one! - */ -#ifdef CONFIG_DM_USB - /* - * When called from usb-uclass.c: usb_scan_device() udev->dev points - * to the parent udevice, not the actual udevice belonging to the - * udev as the device is not instantiated yet. So when searching - * for the first usb-2 parent start with udev->dev not - * udev->dev->parent . - */ - struct udevice *parent; - struct usb_device *uparent; - - ttdev = udev; - parent = udev->dev; - uparent = dev_get_parent_priv(parent); - - while (uparent->speed != USB_SPEED_HIGH) { - struct udevice *dev = parent; - - if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB) { - printf("ehci: Error cannot find high-speed parent of usb-1 device\n"); - return; - } - - ttdev = dev_get_parent_priv(dev); - parent = dev->parent; - uparent = dev_get_parent_priv(parent); - } - parent_devnum = uparent->devnum; -#else - ttdev = udev; - while (ttdev->parent && ttdev->parent->speed != USB_SPEED_HIGH) - ttdev = ttdev->parent; - if (!ttdev->parent) - return; - parent_devnum = ttdev->parent->devnum; -#endif + usb_find_usb2_hub_address_port(udev, &hubaddr, &portnr); - qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(ttdev->portnr) | - QH_ENDPT2_HUBADDR(parent_devnum)); + qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(portnr) | + QH_ENDPT2_HUBADDR(hubaddr)); } static int diff --git a/drivers/usb/musb-new/musb_host.c b/drivers/usb/musb-new/musb_host.c index 40b9c66af8..2515447308 100644 --- a/drivers/usb/musb-new/musb_host.c +++ b/drivers/usb/musb-new/musb_host.c @@ -2092,9 +2092,13 @@ int musb_urb_enqueue( } #else if (tt_needed(musb, urb->dev)) { - u16 hub_port = find_tt(urb->dev); - qh->h_addr_reg = (u8) (hub_port >> 8); - qh->h_port_reg = (u8) (hub_port & 0xff); + uint8_t portnr = 0; + uint8_t hubaddr = 0; + usb_find_usb2_hub_address_port(urb->dev, + &hubaddr, + &portnr); + qh->h_addr_reg = hubaddr; + qh->h_port_reg = portnr; } #endif } diff --git a/drivers/usb/musb-new/usb-compat.h b/drivers/usb/musb-new/usb-compat.h index 1c41e2aade..760bd787bc 100644 --- a/drivers/usb/musb-new/usb-compat.h +++ b/drivers/usb/musb-new/usb-compat.h @@ -68,38 +68,6 @@ static inline int usb_hcd_unmap_urb_for_dma(struct usb_hcd *hcd, } #ifdef CONFIG_DM_USB -static inline u16 find_tt(struct usb_device *udev) -{ - struct udevice *parent; - struct usb_device *uparent, *ttdev; - - /* - * When called from usb-uclass.c: usb_scan_device() udev->dev points - * to the parent udevice, not the actual udevice belonging to the - * udev as the device is not instantiated yet. So when searching - * for the first usb-2 parent start with udev->dev not - * udev->dev->parent . - */ - ttdev = udev; - parent = udev->dev; - uparent = dev_get_parent_priv(parent); - - while (uparent->speed != USB_SPEED_HIGH) { - struct udevice *dev = parent; - - if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB) { - printf("musb: Error cannot find high speed parent of usb-1 device\n"); - return 0; - } - - ttdev = dev_get_parent_priv(dev); - parent = dev->parent; - uparent = dev_get_parent_priv(parent); - } - - return (uparent->devnum << 8) | (ttdev->portnr - 1); -} - static inline struct usb_device *usb_dev_get_parent(struct usb_device *udev) { struct udevice *parent = udev->dev->parent; @@ -129,27 +97,6 @@ static inline struct usb_device *usb_dev_get_parent(struct usb_device *udev) return NULL; } #else -static inline u16 find_tt(struct usb_device *dev) -{ - u8 chid; - u8 hub; - - /* Find out the nearest parent which is high speed */ - while (dev->parent->parent != NULL) - if (dev->parent->speed != USB_SPEED_HIGH) - dev = dev->parent; - else - break; - - /* determine the port address at that hub */ - hub = dev->parent->devnum; - for (chid = 0; chid < USB_MAXCHILDREN; chid++) - if (dev->parent->children[chid] == dev) - break; - - return (hub << 8) | chid; -} - static inline struct usb_device *usb_dev_get_parent(struct usb_device *dev) { return dev->parent; |