Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch A80 EHCI and OHCI support



details:   https://anonhg.NetBSD.org/src/rev/74d55f9025e3
branches:  trunk
changeset: 804901:74d55f9025e3
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Fri Dec 05 17:32:08 2014 +0000

description:
A80 EHCI and OHCI support

diffstat:

 sys/arch/arm/allwinner/awin_io.c    |    9 +-
 sys/arch/arm/allwinner/awin_reg.h   |   44 +++++++++-
 sys/arch/arm/allwinner/awin_usb.c   |  155 ++++++++++++++++++++++++++++-------
 sys/arch/arm/allwinner/awin_var.h   |    3 +-
 sys/arch/evbarm/awin/awin_machdep.c |   45 +++++++--
 sys/arch/evbarm/awin/platform.h     |    8 +-
 sys/arch/evbarm/conf/ALLWINNER_A80  |   25 +++--
 7 files changed, 231 insertions(+), 58 deletions(-)

diffs (truncated from 604 to 300 lines):

diff -r 3a9f9f4d69eb -r 74d55f9025e3 sys/arch/arm/allwinner/awin_io.c
--- a/sys/arch/arm/allwinner/awin_io.c  Fri Dec 05 17:26:21 2014 +0000
+++ b/sys/arch/arm/allwinner/awin_io.c  Fri Dec 05 17:32:08 2014 +0000
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: awin_io.c,v 1.33 2014/12/05 15:25:27 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: awin_io.c,v 1.34 2014/12/05 17:32:08 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -55,6 +55,7 @@
        bus_space_tag_t sc_a4x_bst;
        bus_space_handle_t sc_bsh;
        bus_space_handle_t sc_ccm_bsh;
+       bus_space_handle_t sc_a80_usb_bsh;
        bus_dma_tag_t sc_dmat;
        bus_dma_tag_t sc_coherent_dmat;
 } awinio_sc;
@@ -126,6 +127,9 @@
        { "awinusb", OFFANDSIZE(USB2), 1, NOINTR, A10|A20 },
        { "awinusb", OFFANDSIZE(A31_USB1), 0, NOINTR, A31 },
        { "awinusb", OFFANDSIZE(A31_USB2), 1, NOINTR, A31 },
+       { "awinusb", OFFANDSIZE(A80_USB0), 0, NOINTR, A80 },
+       { "awinusb", OFFANDSIZE(A80_USB1), 1, NOINTR, A80 },
+       { "awinusb", OFFANDSIZE(A80_USB2), 2, NOINTR, A80 },
        { "motg", OFFANDSIZE(USB0), NOPORT, AWIN_IRQ_USB0, A10|A20 },
        { "motg", OFFANDSIZE(A31_USB0), NOPORT, AWIN_A31_IRQ_USB0, A31 },
        { "awinmmc", OFFANDSIZE(SDMMC0), 0, AWIN_IRQ_SDMMC0, A10|A20 },
@@ -213,6 +217,8 @@
        case AWIN_CHIP_ID_A80:
                bus_space_subregion(sc->sc_bst, sc->sc_bsh,
                    AWIN_A80_CCU_SCLK_OFFSET, 0x1000, &sc->sc_ccm_bsh);
+               bus_space_map(sc->sc_bst, AWIN_A80_USB_PBASE,
+                   AWIN_A80_USB_SIZE, 0, &sc->sc_a80_usb_bsh);
                break;
        default:
                bus_space_subregion(sc->sc_bst, sc->sc_bsh, AWIN_CCM_OFFSET,
@@ -259,6 +265,7 @@
                        .aio_core_a4x_bst = sc->sc_a4x_bst,
                        .aio_core_bsh = sc->sc_bsh,
                        .aio_ccm_bsh = sc->sc_ccm_bsh,
+                       .aio_a80_usb_bsh = sc->sc_a80_usb_bsh,
                        .aio_dmat = sc->sc_dmat,
                        .aio_coherent_dmat = sc->sc_coherent_dmat,
                };
diff -r 3a9f9f4d69eb -r 74d55f9025e3 sys/arch/arm/allwinner/awin_reg.h
--- a/sys/arch/arm/allwinner/awin_reg.h Fri Dec 05 17:26:21 2014 +0000
+++ b/sys/arch/arm/allwinner/awin_reg.h Fri Dec 05 17:32:08 2014 +0000
@@ -54,6 +54,10 @@
 #define AWIN_CORE_PBASE                        0x01C00000
 #if defined(ALLWINNER_A80)
 #define AWIN_CORE_SIZE                 0x06400000      /* XXX */
+#define AWIN_A80_CORE2_PBASE           0x00800000
+#define AWIN_A80_CORE2_SIZE            0x00005000
+#define AWIN_A80_USB_PBASE             0x00a00000
+#define AWIN_A80_USB_SIZE              0x00010000
 #else
 #define AWIN_CORE_SIZE                 0x00400000
 #endif
@@ -1207,9 +1211,12 @@
 #define AWIN_USB0_PHY_CTL_CLK1         __BIT(1)
 #define AWIN_USB0_PHY_CTL_CLK0         __BIT(0)
 
+#define AWIN_USB_PMU_IRQ_EHCI_HS_FORCE __BIT(20)       /* A80 */
+#define AWIN_USB_PMU_IRQ_HSIC_CONNECT_DET __BIT(17)    /* A80 */
 #define AWIN_USB_PMU_IRQ_AHB_INCR8     __BIT(10)
 #define AWIN_USB_PMU_IRQ_AHB_INCR4     __BIT(9)
 #define AWIN_USB_PMU_IRQ_AHB_INCRX     __BIT(8)
+#define AWIN_USB_PMU_IRQ_HSIC          __BIT(1)        /* A80 */
 #define AWIN_USB_PMU_IRQ_ULPI_BYPASS   __BIT(0)
 
 /* PATA Definitions */
@@ -2656,6 +2663,9 @@
  */
 #define AWIN_A80_GIC_BASE              0x01c40000
 
+/*
+ * These offsets are relative to AWIN_CORE_PBASE
+ */
 #define AWIN_A80_SDMMC_COMM_OFFSET     0x00013000
 #define AWIN_A80_CCU_OFFSET            0x04400000
 #define AWIN_A80_CCU_SCLK_OFFSET       0x04400400
@@ -2665,7 +2675,6 @@
 #define AWIN_A80_KEYADC_OFFSET         0x04401800
 #define AWIN_A80_SMTA_OFFSET           0x04403400
 #define AWIN_A80_GPADC_OFFSET          0x04404c00
-
 #define AWIN_A80_UART0_OFFSET          0x05400000
 #define AWIN_A80_UART1_OFFSET          0x05400400
 #define AWIN_A80_UART2_OFFSET          0x05400800
@@ -2678,6 +2687,14 @@
 #define AWIN_A80_TWI3_OFFSET           0x05403400
 #define AWIN_A80_TWI4_OFFSET           0x05403800
 
+/*
+ * These offsets are relative to AWIN_A80_USB_PBASE
+ */
+#define AWIN_A80_USB0_OFFSET           0x00000000
+#define AWIN_A80_USB1_OFFSET           0x00001000
+#define AWIN_A80_USB2_OFFSET           0x00002000
+#define AWIN_A80_USBPHY_OFFSET         0x00008000
+
 #define AWIN_A80_SDMMC_COMM_SDC_RESET_SW       __BIT(18)
 #define AWIN_A80_SDMMC_COMM_SDC_CLOCK_SW       __BIT(16)
 
@@ -2725,6 +2742,8 @@
 
 #define AWIN_A80_CCU_SCLK_BUS_CLK_GATING0_SD   __BIT(8)
 
+#define AWIN_A80_CCU_SCLK_BUS_CLK_GATING1_USB_HOST __BIT(1)
+
 #define AWIN_A80_CCU_SCLK_BUS_CLK_GATING4_TWI4 __BIT(4)
 #define AWIN_A80_CCU_SCLK_BUS_CLK_GATING4_TWI2 __BIT(3)
 #define AWIN_A80_CCU_SCLK_BUS_CLK_GATING4_TWI3 __BIT(2)
@@ -2733,6 +2752,8 @@
 
 #define AWIN_A80_CCU_SCLK_BUS_SOFT_RST0_SD     __BIT(8)
 
+#define AWIN_A80_CCU_SCLK_BUS_SOFT_RST1_USB_HOST __BIT(1)
+
 #define AWIN_A80_CCU_SCLK_BUS_SOFT_RST4_TWI4   __BIT(4)
 #define AWIN_A80_CCU_SCLK_BUS_SOFT_RST4_TWI3   __BIT(3)
 #define AWIN_A80_CCU_SCLK_BUS_SOFT_RST4_TWI2   __BIT(2)
@@ -2748,6 +2769,27 @@
 #define AWIN_A80_CCU_SCLK_SDMMC_OUTPUT_CLK_PHASE_CTR __BITS(10,8)
 #define AWIN_A80_CCU_SCLK_SDMMC_CLK_DIV_RATIO_M        __BITS(3,0)
 
+#define AWIN_A80_USBPHY_HCI_SCR_REG            0x0000
+#define AWIN_A80_USBPHY_HCI_PCR_REG            0x0004
+
+#define AWIN_A80_USBPHY_HCI_SCR_HCI2_RST       __BIT(19)
+#define AWIN_A80_USBPHY_HCI_SCR_HCI1_RST       __BIT(18)
+#define AWIN_A80_USBPHY_HCI_SCR_HCI0_RST       __BIT(17)
+#define AWIN_A80_USBPHY_HCI_SCR_OHCI2_SCLK_GATING __BIT(6)
+#define AWIN_A80_USBPHY_HCI_SCR_HCI2_AHB_GATING        __BIT(5)
+#define AWIN_A80_USBPHY_HCI_SCR_HCI1_AHB_GATING __BIT(3)
+#define AWIN_A80_USBPHY_HCI_SCR_OHCI0_SCLK_GATING __BIT(2)
+#define AWIN_A80_USBPHY_HCI_SCR_HCI0_AHB_GATING        __BIT(1)
+
+#define AWIN_A80_USBPHY_HCI_PCR_HCI2_UTMIPHY_RST __BIT(21)
+#define AWIN_A80_USBPHY_HCI_PCR_HCI1_HSIC_RST  __BIT(18)
+#define AWIN_A80_USBPHY_HCI_PCR_HCI0_PHY_RST   __BIT(17)
+#define AWIN_A80_USBPHY_HCI_PCR_12M_GATING_HCI1_HSIC __BIT(10)
+#define AWIN_A80_USBPHY_HCI_PCR_SCLK_GATING_HCI2_UTMIPHY __BIT(5)
+#define AWIN_A80_USBPHY_HCI_PCR_480M_GATING_HCI2_HSIC __BIT(4)
+#define AWIN_A80_USBPHY_HCI_PCR_480M_GATING_HCI1_HSIC __BIT(2)
+#define AWIN_A80_USBPHY_HCI_PCR_SCLK_GATING_HCI0_PHY __BIT(1)
+
 #define AWIN_A80_PIO_PA_PINS           18
 
 #define AWIN_A80_PIO_PB_PINS           20
diff -r 3a9f9f4d69eb -r 74d55f9025e3 sys/arch/arm/allwinner/awin_usb.c
--- a/sys/arch/arm/allwinner/awin_usb.c Fri Dec 05 17:26:21 2014 +0000
+++ b/sys/arch/arm/allwinner/awin_usb.c Fri Dec 05 17:32:08 2014 +0000
@@ -34,7 +34,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: awin_usb.c,v 1.17 2014/11/14 08:20:22 skrll Exp $");
+__KERNEL_RCSID(1, "$NetBSD: awin_usb.c,v 1.18 2014/12/05 17:32:08 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -93,6 +93,9 @@
 static const int awinusb_ohci_irqs[2] = { AWIN_IRQ_USB3, AWIN_IRQ_USB4 };
 static const int awinusb_ohci_irqs_a31[2] = { AWIN_A31_IRQ_USB3,
                                              AWIN_A31_IRQ_USB4 };
+static const int awinusb_ohci_irqs_a80[3] = { AWIN_A80_IRQ_USB_OHCI0,
+                                             -1,
+                                             AWIN_A80_IRQ_USB_OHCI2 };
 
 #ifdef OHCI_DEBUG
 #define OHCI_DPRINTF(x)        if (ohcidebug) printf x
@@ -124,6 +127,7 @@
        struct awinusb_softc * const usbsc = device_private(parent);
        struct ohci_softc * const sc = device_private(self);
        struct awinusb_attach_args * const usbaa = aux;
+       int irq;
 
        sc->sc_dev = self;
 
@@ -148,9 +152,18 @@
        /* Attach usb device. */
        sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint);
 
-       const int irq = awin_chip_id() == AWIN_CHIP_ID_A31 ?
-                       awinusb_ohci_irqs_a31[usbaa->usbaa_port] :
-                       awinusb_ohci_irqs[usbaa->usbaa_port];
+       switch (awin_chip_id()) {
+       case AWIN_CHIP_ID_A80:
+               irq = awinusb_ohci_irqs_a80[usbaa->usbaa_port];
+               break;
+       case AWIN_CHIP_ID_A31:
+               irq = awinusb_ohci_irqs_a31[usbaa->usbaa_port];
+               break;
+       default:
+               irq = awinusb_ohci_irqs[usbaa->usbaa_port];
+               break;
+       }
+
        usbsc->usbsc_ohci_ih = intr_establish(irq, IPL_VM,
            IST_LEVEL, ohci_intr, sc);
        if (usbsc->usbsc_ohci_ih == NULL) {
@@ -176,6 +189,9 @@
 static const int awinusb_ehci_irqs[2] = { AWIN_IRQ_USB1, AWIN_IRQ_USB2 };
 static const int awinusb_ehci_irqs_a31[2] = { AWIN_A31_IRQ_USB1,
                                              AWIN_A31_IRQ_USB2 };
+static const int awinusb_ehci_irqs_a80[3] = { AWIN_A80_IRQ_USB_EHCI0,
+                                             AWIN_A80_IRQ_USB_EHCI1,
+                                             AWIN_A80_IRQ_USB_EHCI2 };
 
 CFATTACH_DECL_NEW(ehci_awinusb, sizeof(struct ehci_softc),
        ehci_awinusb_match, ehci_awinusb_attach, NULL, NULL);
@@ -197,6 +213,7 @@
        struct awinusb_softc * const usbsc = device_private(parent);
        struct ehci_softc * const sc = device_private(self);
        struct awinusb_attach_args * const usbaa = aux;
+       int irq;
 
        sc->sc_dev = self;
 
@@ -225,9 +242,18 @@
        /* Attach usb device. */
        sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint);
 
-       const int irq = awin_chip_id() == AWIN_CHIP_ID_A31 ?
-                       awinusb_ehci_irqs_a31[usbaa->usbaa_port] :
-                       awinusb_ehci_irqs[usbaa->usbaa_port];
+       switch (awin_chip_id()) {
+       case AWIN_CHIP_ID_A80:
+               irq = awinusb_ehci_irqs_a80[usbaa->usbaa_port];
+               break;
+       case AWIN_CHIP_ID_A31:
+               irq = awinusb_ehci_irqs_a31[usbaa->usbaa_port];
+               break;
+       default:
+               irq = awinusb_ehci_irqs[usbaa->usbaa_port];
+               break;
+       }
+
        usbsc->usbsc_ehci_ih = intr_establish(irq, IPL_VM,
            IST_LEVEL, ehci_intr, sc);
        if (usbsc->usbsc_ehci_ih == NULL) {
@@ -283,8 +309,8 @@
 
 static int awinusb_ports;
 
-static const char awinusb_drvpin_names[2][8] = { "usb1drv", "usb2drv" };
-static const char awinusb_restrictpin_names[2][13] = { "usb1restrict", "usb2restrict" };
+static const char awinusb_drvpin_names[3][8] = { "usb1drv", "usb2drv", "usb3drv" };
+static const char awinusb_restrictpin_names[3][13] = { "usb1restrict", "usb2restrict", "usb3restrict" };
 
 static const bus_size_t awinusb_dram_hpcr_regs[2] = {
        AWIN_DRAM_HPCR_USB1_REG,
@@ -350,6 +376,29 @@
 #endif
        0,
 };
+static const uint32_t awinusb_usb_scr_a80[3] = {
+       AWIN_A80_USBPHY_HCI_SCR_HCI0_AHB_GATING |
+#if NOHCI > 0
+       AWIN_A80_USBPHY_HCI_SCR_OHCI0_SCLK_GATING |
+#endif
+       AWIN_A80_USBPHY_HCI_SCR_HCI0_RST,
+       AWIN_A80_USBPHY_HCI_SCR_HCI1_AHB_GATING |
+       AWIN_A80_USBPHY_HCI_SCR_HCI1_RST,
+       AWIN_A80_USBPHY_HCI_SCR_HCI2_AHB_GATING |
+#if NOHCI > 0
+       AWIN_A80_USBPHY_HCI_SCR_OHCI2_SCLK_GATING |
+#endif
+       AWIN_A80_USBPHY_HCI_SCR_HCI2_RST,
+};
+static const uint32_t awinusb_usb_pcr_a80[3] = {
+       AWIN_A80_USBPHY_HCI_PCR_SCLK_GATING_HCI0_PHY |
+       AWIN_A80_USBPHY_HCI_PCR_HCI0_PHY_RST,
+       AWIN_A80_USBPHY_HCI_PCR_480M_GATING_HCI1_HSIC |
+       AWIN_A80_USBPHY_HCI_PCR_12M_GATING_HCI1_HSIC |
+       AWIN_A80_USBPHY_HCI_PCR_HCI1_HSIC_RST,
+       AWIN_A80_USBPHY_HCI_PCR_SCLK_GATING_HCI2_UTMIPHY |
+       AWIN_A80_USBPHY_HCI_PCR_HCI2_UTMIPHY_RST,
+};
 
 int
 awinusb_match(device_t parent, cfdata_t cf, void *aux)
@@ -372,6 +421,8 @@
        struct awinusb_softc * const usbsc = device_private(self);
        const struct awinio_attach_args * const aio = aux;
        const struct awin_locators * const loc = &aio->aio_loc;
+       bus_space_handle_t usb_bsh;
+       bool has_ohci = true;
 
        awinusb_ports |= __BIT(loc->loc_port);
 
@@ -379,15 +430,25 @@
        usbsc->usbsc_dmat = aio->aio_dmat;
        usbsc->usbsc_number = loc->loc_port + 1;
 
-       bus_space_subregion(usbsc->usbsc_bst, aio->aio_core_bsh,



Home | Main Index | Thread Index | Old Index