[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 2/2] usb-ehci: add Faraday FUSBH200 support
From: |
Kuo-Jung Su |
Subject: |
[Qemu-devel] [PATCH 2/2] usb-ehci: add Faraday FUSBH200 support |
Date: |
Tue, 29 Jan 2013 13:43:54 +0800 |
From: Kuo-Jung Su <address@hidden>
Add Faraday FUSBH200 support, which is slightly different from EHCI spec.
(Or maybe simply a bad/wrong implementation...)
Signed-off-by: Kuo-Jung Su <address@hidden>
Cc: Gerd Hoffmann <address@hidden>
Cc: Andreas <address@hidden>
Cc: Peter Crosthwaite <address@hidden>
---
hw/usb/hcd-ehci-sysbus.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++
hw/usb/hcd-ehci.h | 5 ++++
2 files changed, 71 insertions(+)
diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c
index ae2db1a..404a227 100644
--- a/hw/usb/hcd-ehci-sysbus.c
+++ b/hw/usb/hcd-ehci-sysbus.c
@@ -17,6 +17,49 @@
#include "hw/usb/hcd-ehci.h"
+/*
+ * Faraday FUSBH200 USB 2.0 EHCI
+ */
+
+static uint64_t
+ehci_fusbh200_read(void *ptr, hwaddr addr, unsigned size)
+{
+ hwaddr off = 0x34 + addr;
+
+ switch (off) {
+ case 0x34: /* fusbh200: EOF/Async. Sleep Timer Register */
+ return 0x00000041;
+ case 0x40: /* fusbh200: Bus Monitor Control/Status Register */
+ /* High-Speed, VBUS valid, interrupt level-high active */
+ return (2 << 9) | (1 << 8) | (1 << 3);
+ }
+
+ return 0;
+}
+
+static void
+ehci_fusbh200_write(void *ptr, hwaddr addr, uint64_t val, unsigned size)
+{
+}
+
+static const MemoryRegionOps ehci_mmio_fusbh200_ops = {
+ .read = ehci_fusbh200_read,
+ .write = ehci_fusbh200_write,
+ .valid.min_access_size = 4,
+ .valid.max_access_size = 4,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void
+usb_ehci_fusbh200_initfn(EHCIState *s, DeviceState *dev)
+{
+ memory_region_init_io(&s->mem_vendor, &ehci_mmio_fusbh200_ops, s,
+ "fusbh200", 0x4c);
+ memory_region_add_subregion(&s->mem,
+ s->opregbase + s->portscbase + 4 * s->portnr,
+ &s->mem_vendor);
+}
+
static const VMStateDescription vmstate_ehci_sysbus = {
.name = "ehci-sysbus",
.version_id = 2,
@@ -46,6 +89,9 @@ static void usb_ehci_sysbus_realizefn(DeviceState *dev, Error
**errp)
s->dma = &dma_context_memory;
usb_ehci_initfn(s, dev);
+ if (sec->vendor_init) {
+ sec->vendor_init(s, DEVICE(dev));
+ }
sysbus_init_irq(d, &s->irq);
sysbus_init_mmio(d, &s->mem);
}
@@ -76,6 +122,7 @@ static void ehci_xlnx_class_init(ObjectClass *oc, void *data)
sec->opregbase = 0x140;
sec->portscbase = 0x44;
sec->portnr = NB_PORTS;
+ sec->vendor_init = NULL;
}
static const TypeInfo ehci_xlnx_type_info = {
@@ -92,6 +139,7 @@ static void ehci_exynos4210_class_init(ObjectClass *oc, void
*data)
sec->opregbase = 0x10;
sec->portscbase = 0x44;
sec->portnr = NB_PORTS;
+ sec->vendor_init = NULL;
}
static const TypeInfo ehci_exynos4210_type_info = {
@@ -100,11 +148,29 @@ static const TypeInfo ehci_exynos4210_type_info = {
.class_init = ehci_exynos4210_class_init,
};
+static void ehci_fusbh200_class_init(ObjectClass *oc, void *data)
+{
+ SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc);
+
+ sec->capsbase = 0x0;
+ sec->opregbase = 0x10;
+ sec->portscbase = 0x20;
+ sec->portnr = 1;
+ sec->vendor_init = usb_ehci_fusbh200_initfn;
+}
+
+static const TypeInfo ehci_fusbh200_type_info = {
+ .name = TYPE_FUSBH200_EHCI,
+ .parent = TYPE_SYS_BUS_EHCI,
+ .class_init = ehci_fusbh200_class_init,
+};
+
static void ehci_sysbus_register_types(void)
{
type_register_static(&ehci_type_info);
type_register_static(&ehci_xlnx_type_info);
type_register_static(&ehci_exynos4210_type_info);
+ type_register_static(&ehci_fusbh200_type_info);
}
type_init(ehci_sysbus_register_types)
diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h
index e587b67..3ca9c8f 100644
--- a/hw/usb/hcd-ehci.h
+++ b/hw/usb/hcd-ehci.h
@@ -261,6 +261,7 @@ struct EHCIState {
MemoryRegion mem_caps;
MemoryRegion mem_opreg;
MemoryRegion mem_ports;
+ MemoryRegion mem_vendor;
int companion_count;
uint16_t capsbase;
uint16_t opregbase;
@@ -336,6 +337,7 @@ typedef struct EHCIPCIState {
#define TYPE_SYS_BUS_EHCI "sysbus-ehci-usb"
#define TYPE_EXYNOS4210_EHCI "exynos4210-ehci-usb"
+#define TYPE_FUSBH200_EHCI "fusbh200-ehci-usb"
#define SYS_BUS_EHCI(obj) \
OBJECT_CHECK(EHCISysBusState, (obj), TYPE_SYS_BUS_EHCI)
@@ -361,6 +363,9 @@ typedef struct SysBusEHCIClass {
uint16_t opregbase;
uint16_t portscbase;
uint16_t portnr;
+
+ /* vendor specific init function */
+ void (*vendor_init)(EHCIState *s, DeviceState *dev);
} SysBusEHCIClass;
#endif
--
1.7.9.5