Am 25.01.2013 09:19, schrieb Kuo-Jung Su: > From: Kuo-Jung Su <dant...@faraday-tech.com> > > Faraday FUSBH200 is a one-port host controller for USB 2.0, > which is fully compliant with the USB 2.0 specification and > the Enhanced Host Controller Interface (EHCI) specification. > This host controller supports the HS/FS/LS transactions, > Isochronous/Interrupt/Control/Bulk transfers, and split/preamble > transaction for the hub. Without intervening by the software, > this host controller can deal with the transaction-based data > structure to offload the CPU and automatically transmit and receive > the data on the USB bus. > > The native system bus of FUSBH200 is a PVCI 32-bit bus interface. > However, by using the wrappers, FUSBH200 can also support the AMBA > AHB 32-bit bus or RISC 8051 bus. The transceiver interface is UTMI+ > level 3, which supports the HS/FS/LS device and HS/FS hub. > > Signed-off-by: Kuo-Jung Su <dant...@faraday-tech.com>
Please CC all relevant maintainers, in this case Gerd Hoffmann for USB. To automate this, you can use git-send-email's --cccmd="scripts/get_maintainer.pl --nogit-fallback" argument (or config option). > --- > .gitignore | 1 + > hw/usb/hcd-ehci-sysbus.c | 23 +++++++++++++++++++++ > hw/usb/hcd-ehci.c | 51 > ++++++++++++++++++++++++++++++++++++++-------- > hw/usb/hcd-ehci.h | 14 +++++++------ > 4 files changed, 75 insertions(+), 14 deletions(-) > > diff --git a/.gitignore b/.gitignore > index 53fe9c3..0fd6a51 100644 > --- a/.gitignore > +++ b/.gitignore > @@ -55,6 +55,7 @@ fsdev/virtfs-proxy-helper.pod > .gdbinit > *.a > *.aux > +*.bak > *.cp > *.dvi > *.exe This hunk seems unrelated, please drop it from this series. > diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c > index b68a66a..b1147f3 100644 > --- a/hw/usb/hcd-ehci-sysbus.c > +++ b/hw/usb/hcd-ehci-sysbus.c > @@ -40,6 +40,8 @@ static int usb_ehci_sysbus_initfn(SysBusDevice *dev) > > s->capsbase = sec->capsbase; > s->opregbase = sec->opregbase; > + s->portscbase = sec->portscbase; > + s->portnr = sec->portnr; Since NB_PORTS in the max. number of ports, maybe you should assert that here? > s->dma = &dma_context_memory; > > usb_ehci_initfn(s, DEVICE(dev)); > @@ -73,6 +75,8 @@ static void ehci_xlnx_class_init(ObjectClass *oc, void > *data) > > sec->capsbase = 0x100; > sec->opregbase = 0x140; > + sec->portscbase = 0x44; > + sec->portnr = NB_PORTS; > } > > static const TypeInfo ehci_xlnx_type_info = { > @@ -87,6 +91,8 @@ static void ehci_exynos4210_class_init(ObjectClass *oc, > void *data) > > sec->capsbase = 0x0; > sec->opregbase = 0x10; > + sec->portscbase = 0x44; > + sec->portnr = NB_PORTS; > } > > static const TypeInfo ehci_exynos4210_type_info = { > @@ -95,11 +101,28 @@ static const TypeInfo ehci_exynos4210_type_info = { > .class_init = ehci_exynos4210_class_init, > }; > > +static void ehci_faraday_class_init(ObjectClass *oc, void *data) > +{ > + SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc); > + > + sec->capsbase = 0x00; > + sec->opregbase = 0x10; > + sec->portscbase = 0x20; > + sec->portnr = 1; > +} > + > +static const TypeInfo ehci_faraday_type_info = { > + .name = TYPE_FARADAY_EHCI, > + .parent = TYPE_SYS_BUS_EHCI, > + .class_init = ehci_faraday_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_faraday_type_info); > } > > type_init(ehci_sysbus_register_types) > diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c > index 7040659..6e42086 100644 > --- a/hw/usb/hcd-ehci.c > +++ b/hw/usb/hcd-ehci.c > @@ -10,7 +10,8 @@ > * > * EHCI project was started by Mark Burkley, with contributions by > * Niels de Vos. David S. Ahern continued working on it. Kevin Wolf, > - * Jan Kiszka and Vincent Palatin contributed bugfixes. > + * Jan Kiszka and Vincent Palatin contributed bugfixes. Kuo-Jung Su > + * contributed Faraday extension. > * > * > * This library is free software; you can redistribute it and/or > @@ -988,7 +989,7 @@ static uint64_t ehci_port_read(void *ptr, hwaddr addr, > uint32_t val; > > val = s->portsc[addr >> 2]; > - trace_usb_ehci_portsc_read(addr + PORTSC_BEGIN, addr >> 2, val); > + trace_usb_ehci_portsc_read(addr + s->portscbase, addr >> 2, val); > return val; > } > > @@ -1029,7 +1030,7 @@ static void ehci_port_write(void *ptr, hwaddr addr, > uint32_t old = *portsc; > USBDevice *dev = s->ports[port].dev; > > - trace_usb_ehci_portsc_write(addr + PORTSC_BEGIN, addr >> 2, val); > + trace_usb_ehci_portsc_write(addr + s->portscbase, addr >> 2, val); > > /* Clear rwc bits */ > *portsc &= ~(val & PORTSC_RWC_MASK); > @@ -1062,7 +1063,7 @@ static void ehci_port_write(void *ptr, hwaddr addr, > > *portsc &= ~PORTSC_RO_MASK; > *portsc |= val; > - trace_usb_ehci_portsc_change(addr + PORTSC_BEGIN, addr >> 2, *portsc, > old); > + trace_usb_ehci_portsc_change(addr + s->portscbase, addr >> 2, *portsc, > old); > } > > static void ehci_opreg_write(void *ptr, hwaddr addr, > @@ -2501,6 +2502,35 @@ const VMStateDescription vmstate_ehci = { > } > }; > > +static uint64_t > +ehci_faraday_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_faraday_write(void *ptr, hwaddr addr, uint64_t val, unsigned size) > +{ > +} > + > +static const MemoryRegionOps ehci_mmio_faraday_ops = { > + .read = ehci_faraday_read, > + .write = ehci_faraday_write, > + .valid.min_access_size = 4, > + .valid.max_access_size = 4, > + .endianness = DEVICE_LITTLE_ENDIAN, > +}; > + > void usb_ehci_initfn(EHCIState *s, DeviceState *dev) > { > int i; > @@ -2510,7 +2540,7 @@ void usb_ehci_initfn(EHCIState *s, DeviceState *dev) > s->caps[0x01] = 0x00; > s->caps[0x02] = 0x00; > s->caps[0x03] = 0x01; /* HC version */ > - s->caps[0x04] = NB_PORTS; /* Number of downstream ports */ > + s->caps[0x04] = s->portnr; /* Number of downstream ports */ > s->caps[0x05] = 0x00; /* No companion ports at present */ > s->caps[0x06] = 0x00; > s->caps[0x07] = 0x00; > @@ -2538,14 +2568,19 @@ void usb_ehci_initfn(EHCIState *s, DeviceState *dev) > memory_region_init_io(&s->mem_caps, &ehci_mmio_caps_ops, s, > "capabilities", CAPA_SIZE); > memory_region_init_io(&s->mem_opreg, &ehci_mmio_opreg_ops, s, > - "operational", PORTSC_BEGIN); > + "operational", s->portscbase); > memory_region_init_io(&s->mem_ports, &ehci_mmio_port_ops, s, > - "ports", PORTSC_END - PORTSC_BEGIN); > + "ports", 4 * s->portnr); > + memory_region_init_io(&s->mem_faraday, &ehci_mmio_faraday_ops, s, > + "faraday", 0x4c); I don't think this is good design... Can't you do the Faraday part from your own instance_init / initfn / realizefn function? > > memory_region_add_subregion(&s->mem, s->capsbase, &s->mem_caps); > memory_region_add_subregion(&s->mem, s->opregbase, &s->mem_opreg); > - memory_region_add_subregion(&s->mem, s->opregbase + PORTSC_BEGIN, > + memory_region_add_subregion(&s->mem, s->opregbase + s->portscbase, > &s->mem_ports); > + memory_region_add_subregion(&s->mem, > + s->opregbase + s->portscbase + 4 * s->portnr, > + &s->mem_faraday); > } > > /* > diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h > index e95bb7e..2849e81 100644 > --- a/hw/usb/hcd-ehci.h > +++ b/hw/usb/hcd-ehci.h > @@ -40,11 +40,7 @@ > #define MMIO_SIZE 0x1000 > #define CAPA_SIZE 0x10 > > -#define PORTSC 0x0044 > -#define PORTSC_BEGIN PORTSC > -#define PORTSC_END (PORTSC + 4 * NB_PORTS) > - > -#define NB_PORTS 6 /* Number of downstream ports */ > +#define NB_PORTS 6 /* Max. number of downstream ports */ > > typedef struct EHCIPacket EHCIPacket; > typedef struct EHCIQueue EHCIQueue; > @@ -265,9 +261,12 @@ struct EHCIState { > MemoryRegion mem_caps; > MemoryRegion mem_opreg; > MemoryRegion mem_ports; > + MemoryRegion mem_faraday; > int companion_count; > uint16_t capsbase; > uint16_t opregbase; > + uint16_t portscbase; > + uint16_t portnr; > > /* properties */ > uint32_t maxframes; > @@ -278,7 +277,7 @@ struct EHCIState { > */ > uint8_t caps[CAPA_SIZE]; > union { > - uint32_t opreg[PORTSC_BEGIN/sizeof(uint32_t)]; > + uint32_t opreg[0x44/sizeof(uint32_t)]; > struct { > uint32_t usbcmd; > uint32_t usbsts; > @@ -338,6 +337,7 @@ typedef struct EHCIPCIState { > > #define TYPE_SYS_BUS_EHCI "sysbus-ehci-usb" > #define TYPE_EXYNOS4210_EHCI "exynos4210-ehci-usb" > +#define TYPE_FARADAY_EHCI "faraday-ehci-usb" I wonder if you might want to use a product rather than company name? E.g., "fusbh200-ehci-usb". Your choice of course. > > #define SYS_BUS_EHCI(obj) \ > OBJECT_CHECK(EHCISysBusState, (obj), TYPE_SYS_BUS_EHCI) > @@ -361,6 +361,8 @@ typedef struct SysBusEHCIClass { > > uint16_t capsbase; > uint16_t opregbase; > + uint16_t portscbase; > + uint16_t portnr; > } SysBusEHCIClass; > > #endif The define -> class/state movements look fine to me as continuation of our previous effort. Optionally this patch could be split into two - preparing the fields and updating all define users, and then introduce your new model. Regards, Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg