From patchwork Fri Jan 25 08:19:38 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuo-Jung Su X-Patchwork-Id: 215574 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id E89A62C0089 for ; Fri, 25 Jan 2013 19:20:54 +1100 (EST) Received: from localhost ([::1]:45954 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TyeWq-0004K6-UE for incoming@patchwork.ozlabs.org; Fri, 25 Jan 2013 03:20:52 -0500 Received: from eggs.gnu.org ([208.118.235.92]:44458) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TyeWM-0003eC-R2 for qemu-devel@nongnu.org; Fri, 25 Jan 2013 03:20:34 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TyeWG-0007u6-75 for qemu-devel@nongnu.org; Fri, 25 Jan 2013 03:20:22 -0500 Received: from mail-pa0-f47.google.com ([209.85.220.47]:59797) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TyeWF-0007tZ-Uk for qemu-devel@nongnu.org; Fri, 25 Jan 2013 03:20:16 -0500 Received: by mail-pa0-f47.google.com with SMTP id fa10so124414pad.20 for ; Fri, 25 Jan 2013 00:20:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:in-reply-to:references; bh=vynWRKWzXmaGk6a+PSRkrOQ9qNFUQqwd38/KOVgUPzE=; b=lMCyEirF6ncKNWxGiy+rV/XVbHWrQAItfxTWXErDvP753QiECw7Lfc77JvtKrGF2RC mvYQMfN0U2W7p/lFchPjHyu5nXQks02qFJ2+m69EclrPNy+MgJed+9h6e+Fn9CNyKNhv me2kAIysVKguO+9MrT4mxJAywA6O1px0us4CDu6jeTf/g+PmLNr8GiC/nd86RmJGMIW/ 7D+ySJrIC9UMtNdws3QE60YIyxgchtQVOw9vPJ6jTyXTkNImg5MtqenZCyhSyWBYZiuJ sXpKcXgb/XSVu1kmxF09Bd0WiIoJSQp8b8pCtpG3z3CZL2Vf98G4bLD+BVrvcDnaDMgQ fdxA== X-Received: by 10.68.254.195 with SMTP id ak3mr12335711pbd.37.1359102014967; Fri, 25 Jan 2013 00:20:14 -0800 (PST) Received: from localhost.localdomain ([220.132.37.35]) by mx.google.com with ESMTPS id uh9sm246180pbc.65.2013.01.25.00.20.11 (version=TLSv1 cipher=DES-CBC3-SHA bits=168/168); Fri, 25 Jan 2013 00:20:14 -0800 (PST) From: Kuo-Jung Su To: qemu-devel@nongnu.org Date: Fri, 25 Jan 2013 16:19:38 +0800 Message-Id: <1359101996-11667-3-git-send-email-dantesu@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1359101996-11667-1-git-send-email-dantesu@gmail.com> References: <1359101996-11667-1-git-send-email-dantesu@gmail.com> In-Reply-To: <1358490506-18281-1-git-send-email-dantesu@faraday-tech.com> References: <1358490506-18281-1-git-send-email-dantesu@faraday-tech.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 209.85.220.47 Cc: peter.maydell@linaro.org, blauwirbel@gmail.com, paul@codesourcery.com, Kuo-Jung Su , afaerber@suse.de, fred.konrad@greensocs.com Subject: [Qemu-devel] [PATCH v2 02/20] arm: add Faraday FUSBH200 EHCI controller X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Kuo-Jung Su 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 --- .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 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; 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); 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" #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