Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/samsung Fix Exynos5 SoC OHCI hang
details: https://anonhg.NetBSD.org/src/rev/88335563d361
branches: trunk
changeset: 332437:88335563d361
user: reinoud <reinoud%NetBSD.org@localhost>
date: Sun Sep 21 15:22:40 2014 +0000
description:
Fix Exynos5 SoC OHCI hang
Redo the Exynos 5410 USB phy initialisation following uboot
diffstat:
sys/arch/arm/samsung/exynos_usb.c | 77 +++++++++++++++++++++++++++-----------
1 files changed, 54 insertions(+), 23 deletions(-)
diffs (147 lines):
diff -r 706236fc149e -r 88335563d361 sys/arch/arm/samsung/exynos_usb.c
--- a/sys/arch/arm/samsung/exynos_usb.c Sun Sep 21 15:07:19 2014 +0000
+++ b/sys/arch/arm/samsung/exynos_usb.c Sun Sep 21 15:22:40 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: exynos_usb.c,v 1.9 2014/09/09 21:26:47 reinoud Exp $ */
+/* $NetBSD: exynos_usb.c,v 1.10 2014/09/21 15:22:40 reinoud Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: exynos_usb.c,v 1.9 2014/09/09 21:26:47 reinoud Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exynos_usb.c,v 1.10 2014/09/21 15:22:40 reinoud Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -223,11 +223,20 @@
/*
* Disable interrupts
+ *
+ * To prevent OHCI lockups on Exynos5 SoCs, we first have to read the
+ * address before we set it; this is most likely a bug in the SoC
*/
#if NOHCI > 0
+ int regval;
+
+ regval = bus_space_read_1(sc->sc_bst, sc->sc_ohci_bsh,
+ OHCI_INTERRUPT_DISABLE);
+ regval = OHCI_ALL_INTRS;
bus_space_write_4(sc->sc_bst, sc->sc_ohci_bsh,
- OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
+ OHCI_INTERRUPT_DISABLE, regval);
#endif
+
#if NEHCI > 0
bus_size_t caplength = bus_space_read_1(sc->sc_bst,
sc->sc_ehci_bsh, EHCI_CAPLENGTH);
@@ -504,7 +513,9 @@
static void
exynos5410_usb2phy_enable(struct exynos_usb_softc *sc)
{
- uint32_t phyhost, phyotg, phyhsic, ehcictrl, ohcictrl;
+ uint32_t phyhost; //, phyotg;
+ uint32_t phyhsic1, phyhsic2, hsic_ctrl;
+ uint32_t ehcictrl; //, ohcictrl;
/* host configuration: */
phyhost = bus_space_read_4(sc->sc_bst, sc->sc_usb2phy_bsh,
@@ -518,11 +529,11 @@
phyhost &= ~(HOST_CTRL0_FORCESUSPEND | HOST_CTRL0_FORCESLEEP);
/* host phy reset */
- phyhost &= ~(HOST_CTRL0_PHY_SWRST | HOST_CTRL0_SIDDQ);
+ phyhost &= ~(HOST_CTRL0_PHY_SWRST | HOST_CTRL0_PHY_SWRST_ALL |
+ HOST_CTRL0_SIDDQ | HOST_CTRL0_COMMONON_N);
/* host link reset */
- phyhost |= HOST_CTRL0_LINK_SWRST | HOST_CTRL0_UTMI_SWRST |
- HOST_CTRL0_COMMONON_N;
+ phyhost |= HOST_CTRL0_LINK_SWRST | HOST_CTRL0_UTMI_SWRST;
/* do the reset */
bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
@@ -532,6 +543,7 @@
bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
USB_PHY_HOST_CTRL0, phyhost);
+#if 0
/* otg configuration: */
phyotg = bus_space_read_4(sc->sc_bst, sc->sc_usb2phy_bsh,
USB_PHY_OTG_SYS);
@@ -557,23 +569,49 @@
OTG_SYS_PHYLINK_SWRST);
bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
USB_PHY_OTG_SYS, phyotg);
+#endif
/* HSIC phy configuration: */
- phyhsic = REFCLKDIV_12 | REFCLKSEL_HSIC_DEFAULT |
- HSIC_CTRL_PHY_SWRST;
+ hsic_ctrl = HSIC_CTRL_FORCESUSPEND | HSIC_CTRL_FORCESLEEP |
+ HSIC_CTRL_SIDDQ;
+
+ phyhsic1 = bus_space_read_4(sc->sc_bst, sc->sc_usb2phy_bsh,
+ USB_PHY_HSIC_CTRL1);
+ phyhsic2 = bus_space_read_4(sc->sc_bst, sc->sc_usb2phy_bsh,
+ USB_PHY_HSIC_CTRL1);
+
+ phyhsic1 &= ~hsic_ctrl;
+ phyhsic2 &= ~hsic_ctrl;
bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
- USB_PHY_HSIC_CTRL1, phyhsic);
+ USB_PHY_HSIC_CTRL1, phyhsic1);
bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
- USB_PHY_HSIC_CTRL2, phyhsic);
+ USB_PHY_HSIC_CTRL2, phyhsic2);
DELAY(10000);
- phyhsic &= ~HSIC_CTRL_PHY_SWRST;
+
+ hsic_ctrl = REFCLKDIV_12 | REFCLKSEL_HSIC_DEFAULT |
+ HSIC_CTRL_UTMI_SWRST;
+
+ phyhsic1 |= hsic_ctrl;
+ phyhsic2 |= hsic_ctrl;
+
+ bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
+ USB_PHY_HSIC_CTRL1, phyhsic1);
bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
- USB_PHY_HSIC_CTRL1, phyhsic);
+ USB_PHY_HSIC_CTRL2, phyhsic2);
+
+ DELAY(10000);
+
+ hsic_ctrl = HSIC_CTRL_PHY_SWRST | HSIC_CTRL_UTMI_SWRST;
+
+ phyhsic1 &= ~hsic_ctrl;
+ phyhsic2 &= ~hsic_ctrl;
+
bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
- USB_PHY_HSIC_CTRL2, phyhsic);
-
- DELAY(80000);
+ USB_PHY_HSIC_CTRL1, phyhsic1);
+ bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
+ USB_PHY_HSIC_CTRL2, phyhsic2);
+ DELAY(20000);
/* enable EHCI DMA burst: */
ehcictrl = bus_space_read_4(sc->sc_bst, sc->sc_usb2phy_bsh,
@@ -583,13 +621,6 @@
HOST_EHCICTRL_ENA_INCR16;
bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
USB_PHY_HOST_EHCICTRL, ehcictrl);
-
- /* suspend OHCI legacy (?) */
- ohcictrl = bus_space_read_4(sc->sc_bst, sc->sc_usb2phy_bsh,
- USB_PHY_HOST_OHCICTRL);
- ohcictrl |= HOST_OHCICTRL_SUSPLGCY;
- bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
- USB_PHY_HOST_OHCICTRL, ohcictrl);
DELAY(10000);
}
Home |
Main Index |
Thread Index |
Old Index