add omap3 hsusb ohci support
authorJuha Riihimäki <juhriihi@LX9900438.local>
Mon, 30 Mar 2009 07:50:34 +0000 (10:50 +0300)
committerJuha Riihimäki <juhriihi@LX9900438.local>
Mon, 30 Mar 2009 07:50:34 +0000 (10:50 +0300)
hw/omap.h
hw/omap2.c
hw/omap3.c
hw/omap3_usb.c
hw/usb-ohci.c

index 6e820e2..28d9406 100644 (file)
--- a/hw/omap.h
+++ b/hw/omap.h
@@ -79,6 +79,8 @@ struct omap_target_agent_s;
 struct omap_target_agent_s *omap_l4ta_get(struct omap_l4_s *bus, int cs);
 target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, int region,
                 int iotype);
+target_phys_addr_t omap_l4_base(struct omap_target_agent_s *ta, int region);
+uint32_t omap_l4_size(struct omap_target_agent_s *ta, int region);
 # define l4_register_io_memory cpu_register_io_memory
 
 struct omap_intr_handler_s;
@@ -1028,6 +1030,11 @@ struct omap3_hsusb_s *omap3_hsusb_init(struct omap_target_agent_s *otg_ta,
                                        qemu_irq ehci_irq,
                                        qemu_irq tll_irq);
 
+/* usb-ohci.c */
+int usb_ohci_init_omap(target_phys_addr_t base, uint32_t region_size,
+                       int num_ports, qemu_irq irq);
+
+
 # define cpu_is_omap310(cpu)           (cpu->mpu_model == omap310)
 # define cpu_is_omap1510(cpu)          (cpu->mpu_model == omap1510)
 # define cpu_is_omap1610(cpu)          (cpu->mpu_model == omap1610)
index 798f164..b4895d3 100644 (file)
@@ -2539,6 +2539,16 @@ target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, int region,
     return base;
 }
 
+target_phys_addr_t omap_l4_base(struct omap_target_agent_s *ta, int region)
+{
+    return ta->bus->base + ta->start[region].offset;
+}
+
+uint32_t omap_l4_size(struct omap_target_agent_s *ta, int region)
+{
+    return ta->start[region].size;
+}
+
 /* TEST-Chip-level TAP */
 static uint32_t omap_tap_read(void *opaque, target_phys_addr_t addr)
 {
index 0e72c20..2cdd764 100644 (file)
@@ -836,8 +836,10 @@ typedef enum {
     /* 48061000-48061FFF */ L4ID_I2C3_TA,
     /* 48062000-48062FFF */ L4ID_USBTLL,
     /* 48063000-48063FFF */ L4ID_USBTLL_TA,
-    /* 48064000-48064FFF */ L4ID_HSUSBHOST,
-    /* 48065000-48065FFF */ L4ID_HSUSBHOST_TA,
+    /* 48064000-480643FF */ L4ID_USBHOST,
+    /* 48064400-480647FF */ L4ID_USBHOST_OHCI,
+    /* 48064800-4806BFFF */ L4ID_USBHOST_EHCI,
+    /* 48065000-48065FFF */ L4ID_USBHOST_TA,
     /* 48066000-48069FFF */
     /* 4806A000-4806AFFF */ L4ID_UART1,
     /* 4806B000-4806BFFF */ L4ID_UART1_TA,
@@ -1047,8 +1049,10 @@ static struct omap_l4_region_s omap3_l4_region[] = {
     [L4ID_I2C3_TA     ] = {0x00061000, 0x1000, L4TYPE_TA},
     [L4ID_USBTLL      ] = {0x00062000, 0x1000, L4TYPE_GENERIC},
     [L4ID_USBTLL_TA   ] = {0x00063000, 0x1000, L4TYPE_TA},
-    [L4ID_HSUSBHOST   ] = {0x00064000, 0x1000, L4TYPE_GENERIC},
-    [L4ID_HSUSBHOST_TA] = {0x00065000, 0x1000, L4TYPE_TA},
+    [L4ID_USBHOST     ] = {0x00064000, 0x0400, L4TYPE_GENERIC},
+    [L4ID_USBHOST_OHCI] = {0x00064400, 0x0400, L4TYPE_GENERIC},
+    [L4ID_USBHOST_EHCI] = {0x00064800, 0x0400, L4TYPE_GENERIC},
+    [L4ID_USBHOST_TA  ] = {0x00065000, 0x1000, L4TYPE_TA},
     [L4ID_UART1       ] = {0x0006a000, 0x1000, L4TYPE_GENERIC},
     [L4ID_UART1_TA    ] = {0x0006b000, 0x1000, L4TYPE_TA},
     [L4ID_UART2       ] = {0x0006c000, 0x1000, L4TYPE_GENERIC},
@@ -1245,7 +1249,7 @@ static const struct omap3_l4_agent_info_s omap3_l4_agent_info[] = {
     {L4A_DSS,        L4ID_DSI,       6},
     /* TODO: camera */
     {L4A_USBHS_OTG,  L4ID_HSUSBOTG,  2},
-    {L4A_USBHS_HOST, L4ID_HSUSBHOST, 2},
+    {L4A_USBHS_HOST, L4ID_USBHOST,   4},
     {L4A_USBHS_TLL,  L4ID_USBTLL,    2},
     {L4A_UART1,      L4ID_UART1,     2},
     {L4A_UART2,      L4ID_UART2,     2},
@@ -1441,6 +1445,8 @@ static struct omap_target_agent_s *omap3_l4ta_init(struct omap_l4_s *bus, int cs
 
     register_savevm("omap3_l4ta", ta->base >> 8, 0,
                     omap3_l4ta_save_state, omap3_l4ta_load_state, ta);
+#else
+    ta->base = ta->bus->base + ta->start[i].offset;
 #endif
 
     return ta;
index 6af06da..1e3bcb6 100644 (file)
@@ -33,6 +33,7 @@
 #define TRACE(...)
 #endif
 
+/* usb-musb.c */
 extern CPUReadMemoryFunc *musb_read[];
 extern CPUWriteMemoryFunc *musb_write[];
 
@@ -260,25 +261,70 @@ static void omap3_hsusb_otg_init(struct omap_target_agent_s *otg_ta,
 }
 
 struct omap3_hsusb_host_s {
-    struct {
-        qemu_irq ohci_irq;
-        qemu_irq ehci_irq;
-    } hc;
-    struct {
-        qemu_irq irq;
-    } tll;
+    qemu_irq ehci_irq;
+    qemu_irq tll_irq;
+    
+    uint32_t uhh_sysconfig;
+    uint32_t uhh_hostconfig;
+    uint32_t uhh_debug_csr;
 };
 
+static void omap3_hsusb_host_reset(struct omap3_hsusb_host_s *s)
+{
+    s->uhh_sysconfig = 1;
+    s->uhh_hostconfig = 0x700;
+    s->uhh_debug_csr = 0x20;
+    /* TODO: perform OHCI & EHCI reset */
+}
+
 static uint32_t omap3_hsusb_host_read(void *opaque, target_phys_addr_t addr)
 {
-    TRACE(OMAP_FMT_plx, addr);
+    struct omap3_hsusb_host_s *s = (struct omap3_hsusb_host_s *)opaque;
+    
+    switch (addr) {
+        case 0x00: /* UHH_REVISION */
+            return 0x10;
+        case 0x10: /* UHH_SYSCONFIG */
+            return s->uhh_sysconfig;
+        case 0x14: /* UHH_SYSSTATUS */
+            return 0x7; /* EHCI_RESETDONE | OHCI_RESETDONE | RESETDONE */
+        case 0x40: /* UHH_HOSTCONFIG */
+            return s->uhh_hostconfig;
+        case 0x44: /* UHH_DEBUG_CSR */
+            return s->uhh_debug_csr;
+        default:
+            break;
+    }
+    OMAP_BAD_REG(addr);
     return 0;
 }
 
 static void omap3_hsusb_host_write(void *opaque, target_phys_addr_t addr,
                                    uint32_t value)
 {
-    TRACE(OMAP_FMT_plx " = 0x%08x", addr, value);
+    struct omap3_hsusb_host_s *s = (struct omap3_hsusb_host_s *)opaque;
+    
+    switch (addr) {
+        case 0x00: /* UHH_REVISION */
+        case 0x14: /* UHH_SYSSTATUS */
+            OMAP_RO_REGV(addr, value);
+            break;
+        case 0x10: /* UHH_SYSCONFIG */
+            s->uhh_sysconfig = value & 0x311d;
+            if (value & 2) { /* SOFTRESET */
+                omap3_hsusb_host_reset(s);
+            }
+            break;
+        case 0x40: /* UHH_HOSTCONFIG */
+            s->uhh_hostconfig = value & 0x1f3d;
+            break;
+        case 0x44: /* UHH_DEBUG_CSR */
+            s->uhh_debug_csr = value & 0xf00ff;
+            break;
+        default:
+            OMAP_BAD_REGV(addr, value);
+            break;
+    }
 }
 
 static CPUReadMemoryFunc *omap3_hsusb_host_readfn[] = {
@@ -293,6 +339,30 @@ static CPUWriteMemoryFunc *omap3_hsusb_host_writefn[] = {
     omap3_hsusb_host_write,
 };
 
+static uint32_t omap3_hsusb_ehci_read(void *opaque, target_phys_addr_t addr)
+{
+    TRACE(OMAP_FMT_plx, addr);
+    return 0;
+}
+
+static void omap3_hsusb_ehci_write(void *opaque, target_phys_addr_t addr,
+                                   uint32_t value)
+{
+    TRACE(OMAP_FMT_plx " = 0x%08x", addr, value);
+}
+
+static CPUReadMemoryFunc *omap3_hsusb_ehci_readfn[] = {
+    omap_badwidth_read32,
+    omap_badwidth_read32,
+    omap3_hsusb_ehci_read,
+};
+
+static CPUWriteMemoryFunc *omap3_hsusb_ehci_writefn[] = {
+    omap_badwidth_write32,
+    omap_badwidth_write32,
+    omap3_hsusb_ehci_write,
+};
+
 static uint32_t omap3_hsusb_tll_read(void *opaque, target_phys_addr_t addr)
 {
     TRACE(OMAP_FMT_plx, addr);
@@ -324,14 +394,26 @@ static void omap3_hsusb_host_init(struct omap_target_agent_s *host_ta,
                                   qemu_irq tll_irq,
                                   struct omap3_hsusb_host_s *s)
 {
-    s->hc.ohci_irq = ohci_irq;
-    s->hc.ehci_irq = ehci_irq;
-    s->tll.irq     = tll_irq;
+    s->ehci_irq = ehci_irq;
+    s->tll_irq  = tll_irq;
+    
+    omap_l4_attach(tll_ta, 0, l4_register_io_memory(0,
+                                                    omap3_hsusb_tll_readfn,
+                                                    omap3_hsusb_tll_writefn,
+                                                    s));
+    omap_l4_attach(host_ta, 0, l4_register_io_memory(0,
+                                                     omap3_hsusb_host_readfn,
+                                                     omap3_hsusb_host_writefn,
+                                                     s));
+    omap_l4_attach(host_ta, 1, usb_ohci_init_omap(omap_l4_base(host_ta, 1),
+                                                  omap_l4_size(host_ta, 1),
+                                                  3, ohci_irq));
+    omap_l4_attach(host_ta, 2, l4_register_io_memory(0,
+                                                     omap3_hsusb_ehci_readfn,
+                                                     omap3_hsusb_ehci_writefn,
+                                                     s));
     
-    omap_l4_attach(host_ta, 0, l4_register_io_memory(0, omap3_hsusb_host_readfn,
-                                                     omap3_hsusb_host_writefn, s));
-    omap_l4_attach(tll_ta, 0, l4_register_io_memory(0, omap3_hsusb_tll_readfn,
-                                                    omap3_hsusb_tll_writefn, s));
+    omap3_hsusb_host_reset(s);
 }
 
 struct omap3_hsusb_s {
index e59bc8a..f9da20e 100644 (file)
@@ -32,6 +32,7 @@
 #include "usb.h"
 #include "pci.h"
 #include "pxa.h"
+#include "omap.h"
 
 //#define DEBUG_OHCI
 /* Dump packet contents.  */
@@ -60,7 +61,8 @@ typedef struct OHCIPort {
 
 enum ohci_type {
     OHCI_TYPE_PCI,
-    OHCI_TYPE_PXA
+    OHCI_TYPE_PXA,
+    OHCI_TYPE_OMAP
 };
 
 typedef struct {
@@ -1703,3 +1705,12 @@ void usb_ohci_init_pxa(target_phys_addr_t base, int num_ports, int devfn,
 
     cpu_register_physical_memory(base, 0x1000, ohci->mem);
 }
+
+int usb_ohci_init_omap(target_phys_addr_t base, uint32_t region_size,
+                       int num_ports, qemu_irq irq)
+{
+    OHCIState *ohci = (OHCIState *)qemu_mallocz(sizeof(OHCIState));
+    
+    usb_ohci_init(ohci, num_ports, -1, irq, OHCI_TYPE_OMAP, "OHCI USB");
+    return ohci->mem;
+}
\ No newline at end of file