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 Rework USB2 attachment using a dedicate...



details:   https://anonhg.NetBSD.org/src/rev/466d2b3c1a20
branches:  trunk
changeset: 329367:466d2b3c1a20
user:      reinoud <reinoud%NetBSD.org@localhost>
date:      Wed May 21 13:02:46 2014 +0000

description:
Rework USB2 attachment using a dedicated usb devices locator. This allows for
the more tightly coupled Exynos{4,5} usb2/usb2otg/usb3 controllers to share
memory spaces and IRQs

Note, currently only USB2 host is implemented.

diffstat:

 sys/arch/arm/samsung/exynos4_loc.c |  16 ++++++-
 sys/arch/arm/samsung/exynos5_loc.c |  14 ++++++
 sys/arch/arm/samsung/exynos5_reg.h |  36 +++++++--------
 sys/arch/arm/samsung/exynos_io.h   |   2 +
 sys/arch/arm/samsung/exynos_usb.c  |  82 +++++++++++++++++++++++--------------
 sys/arch/arm/samsung/exynos_var.h  |  23 ++++++----
 6 files changed, 111 insertions(+), 62 deletions(-)

diffs (truncated from 345 to 300 lines):

diff -r d8e88facf500 -r 466d2b3c1a20 sys/arch/arm/samsung/exynos4_loc.c
--- a/sys/arch/arm/samsung/exynos4_loc.c        Wed May 21 12:24:52 2014 +0000
+++ b/sys/arch/arm/samsung/exynos4_loc.c        Wed May 21 13:02:46 2014 +0000
@@ -272,7 +272,7 @@
        { "sscom", OFFANDSIZE(,UART1), 1, IRQ_UART1, 0 },
        { "sscom", OFFANDSIZE(,UART2), 2, IRQ_UART2, 0 },
        { "sscom", OFFANDSIZE(,UART3), 3, IRQ_UART3, 0 },
-       { "exyousb", OFFANDSIZE(,USBHOST0), 0, IRQ_UHOST, 0},   /* ehci+ohci */
+       { "exyousb", 0, 0, NOPORT, NOINTR, 0},          /* uses usb locators */
 };
 
 const struct exyo_locinfo exynos4_locinfo = {
@@ -301,3 +301,17 @@
        .nlocators = __arraycount(exynos4_i2c_locators)
 };
 
+
+/* usb locators */
+const struct exyo_usb_locinfo exynos4_usb_locinfo = {
+       .uloc_ehci_offset       = EXYNOS4_USBHOST0_OFFSET,
+       .uloc_ohci_offset       = EXYNOS4_USBHOST1_OFFSET,
+       .uloc_usbhost_irq       = IRQ_UHOST,
+       .uloc_usbotg_offset     = EXYNOS4_USBOTG1_OFFSET,
+       .uloc_usbotg_irq        = IRQ_HSOTG,
+       .uloc_usb3_ctrl         = 0,            /* no usbctl */
+       .uloc_usb3_linkoffset   = 0,            /* no usb3   */
+       .uloc_usb3_slots        = 0,            /* no usb3   */
+       .uloc_usb3_irq          = 0,            /* no usb3   */
+};
+
diff -r d8e88facf500 -r 466d2b3c1a20 sys/arch/arm/samsung/exynos5_loc.c
--- a/sys/arch/arm/samsung/exynos5_loc.c        Wed May 21 12:24:52 2014 +0000
+++ b/sys/arch/arm/samsung/exynos5_loc.c        Wed May 21 13:02:46 2014 +0000
@@ -236,3 +236,17 @@
        .nlocators = __arraycount(exynos5_i2c_locators)
 };
 
+
+/* usb locators */
+const struct exyo_usb_locinfo exynos5_usb_locinfo = {
+       .uloc_ehci_offset       = EXYNOS5_USB2_HOST_EHCI_OFFSET,
+       .uloc_ohci_offset       = EXYNOS5_USB2_HOST_OHCI_OFFSET,
+       .uloc_usbhost_irq       = IRQ_USB_HOST20,
+       .uloc_usbotg_offset     = EXYNOS5_USB2_DEVICE_LINK_OFFSET,
+       .uloc_usbotg_irq        = IRQ_USBOTG,
+       .uloc_usb3_ctrl         = EXYNOS5_USB3_DEVICE_CTRL_OFFSET,
+       .uloc_usb3_linkoffset   = EXYNOS5_USB3_DEVICE_LINK_OFFSET00,
+       .uloc_usb3_slots        = 16,
+       .uloc_usb3_irq          = IRQ_USB_DRD30,
+};
+
diff -r d8e88facf500 -r 466d2b3c1a20 sys/arch/arm/samsung/exynos5_reg.h
--- a/sys/arch/arm/samsung/exynos5_reg.h        Wed May 21 12:24:52 2014 +0000
+++ b/sys/arch/arm/samsung/exynos5_reg.h        Wed May 21 13:02:46 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: exynos5_reg.h,v 1.3 2014/05/14 09:03:09 reinoud Exp $  */
+/*     $NetBSD: exynos5_reg.h,v 1.4 2014/05/21 13:02:46 reinoud Exp $  */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -121,24 +121,22 @@
 #define EXYNOS5_AS_A_JPEG_OFFSET               0x01DC0000
 #define EXYNOS5_JPEG_OFFSET                    0x01E00000
 #define EXYNOS5_SYSMMU_JPEG_OFFSET             0x01F20000
-#if 0
-#define EXYNOS5_USB3_DEVICE_LINK_OFFSET                0x02000000
-#define EXYNOS5_USB3_DEVICE_LINK_OFFSET                0x02010000
-#define EXYNOS5_USB3_DEVICE_LINK_OFFSET                0x02020000
-#define EXYNOS5_USB3_DEVICE_LINK_OFFSET                0x02030000
-#define EXYNOS5_USB3_DEVICE_LINK_OFFSET                0x02040000
-#define EXYNOS5_USB3_DEVICE_LINK_OFFSET                0x02050000
-#define EXYNOS5_USB3_DEVICE_LINK_OFFSET                0x02060000
-#define EXYNOS5_USB3_DEVICE_LINK_OFFSET                0x02070000
-#define EXYNOS5_USB3_DEVICE_LINK_OFFSET                0x02080000
-#define EXYNOS5_USB3_DEVICE_LINK_OFFSET                0x02090000
-#define EXYNOS5_USB3_DEVICE_LINK_OFFSET                0x020A0000
-#define EXYNOS5_USB3_DEVICE_LINK_OFFSET                0x020B0000
-#define EXYNOS5_USB3_DEVICE_LINK_OFFSET                0x020C0000
-#define EXYNOS5_USB3_DEVICE_LINK_OFFSET                0x020D0000
-#define EXYNOS5_USB3_DEVICE_LINK_OFFSET                0x020E0000
-#define EXYNOS5_USB3_DEVICE_LINK_OFFSET                0x020F0000
-#endif
+#define EXYNOS5_USB3_DEVICE_LINK_OFFSET00      0x02000000
+#define EXYNOS5_USB3_DEVICE_LINK_OFFSET01      0x02010000
+#define EXYNOS5_USB3_DEVICE_LINK_OFFSET02      0x02020000
+#define EXYNOS5_USB3_DEVICE_LINK_OFFSET03      0x02030000
+#define EXYNOS5_USB3_DEVICE_LINK_OFFSET04      0x02040000
+#define EXYNOS5_USB3_DEVICE_LINK_OFFSET05      0x02050000
+#define EXYNOS5_USB3_DEVICE_LINK_OFFSET06      0x02060000
+#define EXYNOS5_USB3_DEVICE_LINK_OFFSET07      0x02070000
+#define EXYNOS5_USB3_DEVICE_LINK_OFFSET08      0x02080000
+#define EXYNOS5_USB3_DEVICE_LINK_OFFSET09      0x02090000
+#define EXYNOS5_USB3_DEVICE_LINK_OFFSET10      0x020A0000
+#define EXYNOS5_USB3_DEVICE_LINK_OFFSET11      0x020B0000
+#define EXYNOS5_USB3_DEVICE_LINK_OFFSET12      0x020C0000
+#define EXYNOS5_USB3_DEVICE_LINK_OFFSET13      0x020D0000
+#define EXYNOS5_USB3_DEVICE_LINK_OFFSET14      0x020E0000
+#define EXYNOS5_USB3_DEVICE_LINK_OFFSET15      0x020F0000
 #define EXYNOS5_USB3_DEVICE_CTRL_OFFSET                0x02100000
 #define EXYNOS5_USB2_HOST_EHCI_OFFSET          0x02110000
 #define EXYNOS5_USB2_HOST_OHCI_OFFSET          0x02120000
diff -r d8e88facf500 -r 466d2b3c1a20 sys/arch/arm/samsung/exynos_io.h
--- a/sys/arch/arm/samsung/exynos_io.h  Wed May 21 12:24:52 2014 +0000
+++ b/sys/arch/arm/samsung/exynos_io.h  Wed May 21 13:02:46 2014 +0000
@@ -45,6 +45,8 @@
 extern const struct exyo_locinfo exynos4_i2c_locinfo;
 extern const struct exyo_locinfo exynos5_locinfo;
 extern const struct exyo_locinfo exynos5_i2c_locinfo;
+extern const struct exyo_usb_locinfo exynos4_usb_locinfo;
+extern const struct exyo_usb_locinfo exynos5_usb_locinfo;
 
 /* XXXNH needed? */
 #define        NOPORT  EXYOCF_PORT_DEFAULT
diff -r d8e88facf500 -r 466d2b3c1a20 sys/arch/arm/samsung/exynos_usb.c
--- a/sys/arch/arm/samsung/exynos_usb.c Wed May 21 12:24:52 2014 +0000
+++ b/sys/arch/arm/samsung/exynos_usb.c Wed May 21 13:02:46 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: exynos_usb.c,v 1.3 2014/05/10 21:10:27 reinoud Exp $   */
+/*     $NetBSD: exynos_usb.c,v 1.4 2014/05/21 13:02:46 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.3 2014/05/10 21:10:27 reinoud Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exynos_usb.c,v 1.4 2014/05/21 13:02:46 reinoud Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -64,14 +64,12 @@
 
 #include <arm/samsung/exynos_reg.h>
 #include <arm/samsung/exynos_var.h>
-
+#include <arm/samsung/exynos_io.h>
 
-static int exynos_usb_ports = 0;
 
 struct exynos_usb_softc {
        device_t         sc_self;
-       int              sc_port;
-       int              sc_irq;
+       const struct exyo_usb_locinfo *sc_locinfo;
 
        /* keep our tags here */
        bus_dma_tag_t    sc_dmat;
@@ -84,49 +82,57 @@
        device_t         sc_ehci_dev;
 
        void            *sc_intrh;
-};
+} exynos_usb_sc;
 
 struct exynos_usb_attach_args {
        const char *name;
 };
 
 static int exynos_usb_intr(void *arg);
+static void exynos_usb_init(struct exynos_usb_softc *sc);
 
 
 static int     exynos_usb_match(device_t, cfdata_t, void *);
 static void    exynos_usb_attach(device_t, device_t, void *);
 
-CFATTACH_DECL_NEW(exyo_usb, sizeof(struct exynos_usb_softc),
+CFATTACH_DECL_NEW(exyo_usb, 0,
     exynos_usb_match, exynos_usb_attach, NULL, NULL);
 
 
 static int
 exynos_usb_match(device_t parent, cfdata_t cf, void *aux)
 {
-       struct exyo_attach_args *exyoaa = (struct exyo_attach_args *) aux;
-
-       /* no multiple attachments on same port nr */
-       if (exynos_usb_ports & __BIT(exyoaa->exyo_loc.loc_port))
+       /* there can only be one */
+       if (exynos_usb_sc.sc_self)
                return 0;
 
        return 1;
 }
 
 
-#define OHCI_OFFSET 0x10000
 static void
 exynos_usb_attach(device_t parent, device_t self, void *aux)
 {
-       struct exynos_usb_softc * const sc = device_private(self);
+       struct exynos_usb_softc * const sc = &exynos_usb_sc;
        struct exyo_attach_args *exyoaa = (struct exyo_attach_args *) aux;
+       struct exyo_locators *loc = &exyoaa->exyo_loc;
+
+       /* no locators expected */
+       KASSERT(loc->loc_offset == 0);
+       KASSERT(loc->loc_size   == 0);
+       KASSERT(loc->loc_port   == EXYOCF_PORT_DEFAULT);
 
-       /* mark we're here */
-       exynos_usb_ports |= __BIT(exyoaa->exyo_loc.loc_port);
-
-       /* copy our attachment info */
+       /* copy our device handle */
        sc->sc_self = self;
-       sc->sc_port = exyoaa->exyo_loc.loc_port;
-       sc->sc_irq  = exyoaa->exyo_loc.loc_intr;
+#ifdef EXYNOS4
+       if (IS_EXYNOS4_P())
+               sc->sc_locinfo = &exynos4_usb_locinfo;
+#endif
+#ifdef EXYNOS5
+       if (IS_EXYNOS5_P())
+               sc->sc_locinfo = &exynos5_usb_locinfo;
+#endif
+       KASSERT(sc->sc_locinfo);
 
        /* get our bushandles */
        sc->sc_bst  = exyoaa->exyo_core_bst;
@@ -134,11 +140,10 @@
 //     sc->sc_dmat = exyoaa->exyo_coherent_dmat;
 
        bus_space_subregion(sc->sc_bst, exyoaa->exyo_core_bsh,
-               exyoaa->exyo_loc.loc_offset, exyoaa->exyo_loc.loc_size,
+               sc->sc_locinfo->uloc_ehci_offset, EXYNOS_BLOCK_SIZE,
                &sc->sc_ehci_bsh);
        bus_space_subregion(sc->sc_bst, exyoaa->exyo_core_bsh,
-               exyoaa->exyo_loc.loc_offset + OHCI_OFFSET,
-               exyoaa->exyo_loc.loc_size,
+               sc->sc_locinfo->uloc_ohci_offset, EXYNOS_BLOCK_SIZE,
                &sc->sc_ohci_bsh);
 
        aprint_naive("\n");
@@ -158,18 +163,22 @@
            caplength + EHCI_USBINTR, 0);
 #endif
 
-       /* TBD Init USB subsystem */
+       /*
+        * Init USB subsystem
+        */
+       exynos_usb_init(sc);
 
        /* claim shared interrupt for OHCI/EHCI */
-       sc->sc_intrh = intr_establish(sc->sc_irq, IPL_USB, IST_LEVEL,
-               exynos_usb_intr, sc);
+       sc->sc_intrh = intr_establish(sc->sc_locinfo->uloc_usbhost_irq,
+               IPL_USB, IST_LEVEL, exynos_usb_intr, sc);
        if (!sc->sc_intrh) {
                aprint_error(": unable to establish interrupt at irq %d\n",
-                       sc->sc_irq);
+                       sc->sc_locinfo->uloc_usbhost_irq);
                /* disable? TBD */
                return;
        }
-       aprint_normal_dev(sc->sc_self, "interrupting on irq %d\n", sc->sc_irq);
+       aprint_normal_dev(sc->sc_self, "USB2 host interrupting on irq %d\n",
+               sc->sc_locinfo->uloc_usbhost_irq);
 
 #if NOHCI > 0
        /* attach OHCI */
@@ -237,7 +246,7 @@
 static void
 exynos_ohci_attach(device_t parent, device_t self, void *aux)
 {
-       struct exynos_usb_softc *usbsc = device_private(parent);
+       struct exynos_usb_softc *usbsc = &exynos_usb_sc;
        struct ohci_softc *sc = device_private(self);
        int r;
 
@@ -265,7 +274,8 @@
                return;
        }
        sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint);
-       aprint_normal_dev(sc->sc_dev, "interrupting on irq %d\n", usbsc->sc_irq);
+       aprint_normal_dev(sc->sc_dev, "interrupting on irq %d\n",
+               usbsc->sc_locinfo->uloc_usbhost_irq);
 }
 #endif
 
@@ -293,7 +303,7 @@
 static void
 exynos_ehci_attach(device_t parent, device_t self, void *aux)
 {
-       struct exynos_usb_softc *usbsc = device_private(parent);
+       struct exynos_usb_softc *usbsc = &exynos_usb_sc;
        struct ehci_softc *sc = device_private(self);
        int r;
 
@@ -325,7 +335,15 @@
                return;
        }
        sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint);
-       aprint_normal_dev(sc->sc_dev, "interrupting on irq %d\n", usbsc->sc_irq);
+       aprint_normal_dev(sc->sc_dev, "interrupting on irq %d\n",
+               usbsc->sc_locinfo->uloc_usbhost_irq);
 }
 #endif
 



Home | Main Index | Thread Index | Old Index