summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/i2c/mxc_i2c.c12
-rw-r--r--drivers/mmc/fsl_esdhc.c15
-rw-r--r--drivers/net/fec_mxc.c20
-rw-r--r--drivers/serial/serial_mxc.c9
-rw-r--r--drivers/usb/host/dwc2.c7
-rw-r--r--drivers/usb/host/ehci-hcd.c50
-rw-r--r--drivers/usb/musb-new/musb_host.c10
-rw-r--r--drivers/usb/musb-new/usb-compat.h53
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(&regs->sysctl, SYSCTL_RSTA);
+#else
esdhc_clrbits32(&regs->sysctl, SYSCTL_CKEN);
+#endif
esdhc_clrsetbits32(&regs->sysctl, SYSCTL_CLOCK_MASK, clk);
udelay(10000);
- clk = SYSCTL_PEREN | SYSCTL_CKEN;
+#ifdef CONFIG_FSL_USDHC
+ esdhc_clrbits32(&regs->sysctl, SYSCTL_RSTA);
+#else
+ esdhc_setbits32(&regs->sysctl, SYSCTL_PEREN | SYSCTL_CKEN);
+#endif
- esdhc_setbits32(&regs->sysctl, clk);
}
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
@@ -585,7 +592,9 @@ static int esdhc_init(struct mmc *mmc)
esdhc_write32(&regs->scr, 0x00000040);
#endif
+#ifndef CONFIG_FSL_USDHC
esdhc_setbits32(&regs->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(&regs->sysctl, SYSCTL_PEREN | SYSCTL_HCKEN
| SYSCTL_IPGEN | SYSCTL_CKEN);
+#endif
writel(SDHCI_IRQ_EN_BITS, &regs->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, &eth->mii_speed);
+ writel(speed << 1 | hold << 8, &eth->mii_speed);
debug("%s: mii_speed %08x\n", __func__, readl(&eth->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;