Patchwork [v3,6/8] usb/ehci: Add Sysbus variant and Xilinx Zynq USB

login
register
mail settings
Submitter Peter Crosthwaite
Date Oct. 29, 2012, 1:34 a.m.
Message ID <2db4e6717385b7d957b9c10653587e8c5cb630e0.1351473902.git.peter.crosthwaite@xilinx.com>
Download mbox | patch
Permalink /patch/194781/
State New
Headers show

Comments

Peter Crosthwaite - Oct. 29, 2012, 1:34 a.m.
Add QOM class definition helpers for sysbus attached EHCI implementations and
added Xilinx Zynq USB implementation.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
changed from v2:
Squashed Xilinx zynq Defintion into this patch. Otherwise complie fails due
to werror and unsued ehci_sysbus_class_init fn.
Duplicated state struct (as EHCISysBusState) - no more union.
changed from v1:
Dont create a QOM definition for Sysbus EHCI, rather just add all the bits
and pieces. (Multiple) sysbus EHCI defs can be created by adding to the
type_info[] table.
Use dma_context_memory for sysbus DMA (PMM review)

 hw/usb/hcd-ehci.c |   65 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 65 insertions(+), 0 deletions(-)

Patch

diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index df224b2..7948146 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -35,6 +35,8 @@ 
 #include "trace.h"
 #include "dma.h"
 #include "sysemu.h"
+#include "hw/sysbus.h"
+#include "exec-memory.h"
 
 #define EHCI_DEBUG   0
 
@@ -450,6 +452,11 @@  typedef struct EHCIPCIState {
     EHCIState ehci;
 } EHCIPCIState;
 
+typedef struct EHCISysBusState {
+    SysBusDevice busdev;
+    EHCIState ehci;
+} EHCISysBusState;
+
 #define SET_LAST_RUN_CLOCK(s) \
     (s)->last_run_ns = qemu_get_clock_ns(vm_clock);
 
@@ -2544,6 +2551,7 @@  static const MemoryRegionOps ehci_mmio_port_ops = {
 };
 
 static int usb_ehci_pci_initfn(PCIDevice *dev);
+static int usb_ehci_sysbus_initfn(SysBusDevice *dev);
 
 static USBPortOps ehci_port_ops = {
     .attach = ehci_attach,
@@ -2650,11 +2658,26 @@  static const VMStateDescription vmstate_ehci_pci = {
     }
 };
 
+static const VMStateDescription vmstate_ehci_sysbus = {
+    .name        = "ehci-sysbus",
+    .version_id  = 2,
+    .minimum_version_id  = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_STRUCT(ehci, EHCISysBusState, 2, vmstate_ehci, EHCIState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static Property ehci_pci_properties[] = {
     DEFINE_PROP_UINT32("maxframes", EHCIPCIState, ehci.maxframes, 128),
     DEFINE_PROP_END_OF_LIST(),
 };
 
+static Property ehci_sysbus_properties[] = {
+    DEFINE_PROP_UINT32("maxframes", EHCISysBusState, ehci.maxframes, 128),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 typedef struct EHCIInfo {
     uint16_t capabase;
     uint16_t opregbase;
@@ -2665,6 +2688,11 @@  typedef struct EHCIPCIClass {
     EHCIInfo ehci;
 } EHCIPCIClass;
 
+typedef struct EHCISysBusClass {
+    SysBusDeviceClass sdc;
+    EHCIInfo ehci;
+} EHCISysBusClass;
+
 static void ehci_pci_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -2681,6 +2709,18 @@  static void ehci_pci_class_init(ObjectClass *klass, void *data)
     dc->props = ehci_pci_properties;
 }
 
+static void ehci_sysbus_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    EHCISysBusClass *k = (EHCISysBusClass *)klass;
+    EHCISysBusClass *template = data;
+
+    k->sdc.init = usb_ehci_sysbus_initfn;
+    k->ehci = template->ehci;
+    dc->vmsd = &vmstate_ehci_sysbus;
+    dc->props = ehci_sysbus_properties;
+}
+
 static TypeInfo ehci_info[] = {
     {
         .name          = "usb-ehci",
@@ -2708,6 +2748,16 @@  static TypeInfo ehci_info[] = {
             .ehci.capabase  = 0x0,
             .ehci.opregbase = 0x20,
         } }
+    }, {
+        .name          = "xlnx,ps7-usb",
+        .parent        = TYPE_SYS_BUS_DEVICE,
+        .instance_size = sizeof(EHCISysBusState),
+        .class_init    = ehci_sysbus_class_init,
+        .class_size    = sizeof(EHCISysBusClass),
+        .class_data    = (EHCISysBusClass[]) {{
+            .ehci.capabase = 0x100,
+            .ehci.opregbase = 0x140,
+        } }
     },
 };
 
@@ -2761,6 +2811,21 @@  static void usb_ehci_initfn(EHCIState *s, DeviceState *dev, EHCIInfo *ei)
                                 &s->mem_ports);
 }
 
+static int usb_ehci_sysbus_initfn(SysBusDevice *dev)
+{
+    EHCISysBusState *i = FROM_SYSBUS(EHCISysBusState, dev);
+    EHCISysBusClass *c = (EHCISysBusClass *)object_get_class(OBJECT(dev));
+    EHCIState *s = &i->ehci;
+
+    s->dma = &dma_context_memory;
+
+    usb_ehci_initfn(s, DEVICE(dev), &c->ehci);
+    sysbus_init_irq(dev, &s->irq);
+    sysbus_init_mmio(dev, &s->mem);
+
+    return 0;
+}
+
 static int usb_ehci_pci_initfn(PCIDevice *dev)
 {
     EHCIPCIState *i = DO_UPCAST(EHCIPCIState, pcidev, dev);