From patchwork Wed Feb 3 18:30:40 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Albert Herranz X-Patchwork-Id: 44399 X-Patchwork-Delegate: grant.likely@secretlab.ca Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from bilbo.ozlabs.org (localhost [127.0.0.1]) by ozlabs.org (Postfix) with ESMTP id 4572EB86CB for ; Thu, 4 Feb 2010 05:31:48 +1100 (EST) Received: from smtp133.mail.ukl.yahoo.com (smtp133.mail.ukl.yahoo.com [77.238.184.64]) by ozlabs.org (Postfix) with SMTP id 94ED2B7DBA for ; Thu, 4 Feb 2010 05:31:06 +1100 (EST) Received: (qmail 27999 invoked from network); 3 Feb 2010 18:31:04 -0000 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=s1024; d=yahoo.es; h=Received:X-Yahoo-SMTP:X-YMail-OSG:X-Yahoo-Newman-Property:From:To:Cc:Subject:Date:Message-Id:X-Mailer:In-Reply-To:References; b=pxZ2eK9LJD0oczKB8YCYQYc5MyuY8Y1zdwuuHW4St7Sm1fstC1ElcgLQ1zF8DzOtPBAfVtufziEuhhuLBO7xrIm2hu/PgDJJ9wuCA77JKLDYq02tiSSpab/EjiJIu1nsx4z162M8YDVir8+mjO3tkAQvJqsOdoEQhj/OL3zOdAU= ; Received: from 93.Red-83-46-156.dynamicIP.rima-tde.net (albert_herranz@83.46.156.93 with login) by smtp133.mail.ukl.yahoo.com with SMTP; 03 Feb 2010 18:31:04 +0000 GMT X-Yahoo-SMTP: czee06uswBAtfIYshc.kP27UlfEXaxwWNSjJ X-YMail-OSG: aukvf00VM1nNCGn0etmMnqylXPbM_oJWoX3UtkoGJ3byE_VogxhQ4WbprrCwCgSc6FDLSjbppM888bTQ0TlTHh067kwuEKNH83LXyP3wgrlHd3AyGJImRliVu1wxg7n702GPFvprm3tueQsH8iJOL2ijq9JRInSW6iHNtl8tdL84kTVFyeBfHIA7v9pxNsB3e3qWg3LZuLSd75O4KLc2sPHDJGvyxOfoHcU2DIxjjYJQgt3.Q.1MSTuxP_uELYcVDBqWOQcIB1R7MiamEB0hPzs5xFWjBA-- X-Yahoo-Newman-Property: ymail-3 From: Albert Herranz To: linux-usb@vger.kernel.org Subject: [RFC PATCH 2/2] wii: hollywood ehci controller support Date: Wed, 3 Feb 2010 19:30:40 +0100 Message-Id: <1265221840-25634-3-git-send-email-albert_herranz@yahoo.es> X-Mailer: git-send-email 1.6.3.3 In-Reply-To: <1265221840-25634-1-git-send-email-albert_herranz@yahoo.es> References: <1265221840-25634-1-git-send-email-albert_herranz@yahoo.es> Cc: Albert Herranz , linuxppc-dev@lists.ozlabs.org X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Add support for the USB Enhanced Host Controller Interface included in the "Hollywood" chipset of the Nintendo Wii video game console. Signed-off-by: Albert Herranz --- arch/powerpc/platforms/embedded6xx/Kconfig | 1 + drivers/usb/host/Kconfig | 8 + drivers/usb/host/ehci-hcd.c | 5 + drivers/usb/host/ehci-hlwd.c | 227 ++++++++++++++++++++++++++++ drivers/usb/host/ehci.h | 23 +++ 5 files changed, 264 insertions(+), 0 deletions(-) create mode 100644 drivers/usb/host/ehci-hlwd.c diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index 524d971..34dbb79 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig @@ -119,6 +119,7 @@ config WII bool "Nintendo-Wii" depends on EMBEDDED6xx select GAMECUBE_COMMON + select USB_ARCH_HAS_EHCI help Select WII if configuring for the Nintendo Wii. More information at: diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 2678a16..342954f 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -131,6 +131,14 @@ config USB_EHCI_HCD_PPC_OF Enables support for the USB controller present on the PowerPC OpenFirmware platform bus. +config USB_EHCI_HCD_HLWD + bool "Nintendo Wii (Hollywood) EHCI USB controller support" + depends on USB_EHCI_HCD && WII + default y + ---help--- + Say Y here to support the EHCI USB controller found in the + Hollywood chipset of the Nintendo Wii video game console. + config USB_W90X900_EHCI bool "W90X900(W90P910) EHCI support" depends on USB_EHCI_HCD && ARCH_W90X900 diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 1ec3857..395c6a1 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1133,6 +1133,11 @@ MODULE_LICENSE ("GPL"); #define OF_PLATFORM_DRIVER ehci_hcd_ppc_of_driver #endif +#ifdef CONFIG_USB_EHCI_HCD_HLWD +#include "ehci-hlwd.c" +#define OF_PLATFORM_DRIVER ehci_hcd_hlwd_driver +#endif + #ifdef CONFIG_XPS_USB_HCD_XILINX #include "ehci-xilinx-of.c" #define OF_PLATFORM_DRIVER ehci_hcd_xilinx_of_driver diff --git a/drivers/usb/host/ehci-hlwd.c b/drivers/usb/host/ehci-hlwd.c new file mode 100644 index 0000000..19812db --- /dev/null +++ b/drivers/usb/host/ehci-hlwd.c @@ -0,0 +1,227 @@ +/* + * drivers/usb/host/ehci-hlwd.c + * + * Nintendo Wii (Hollywood) USB Enhanced Host Controller Interface. + * Copyright (C) 2009-2010 The GameCube Linux Team + * Copyright (C) 2009,2010 Albert Herranz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Based on ehci-ppc-of.c + * + * EHCI HCD (Host Controller Driver) for USB. + * + * Bus Glue for PPC On-Chip EHCI driver on the of_platform bus + * Tested on AMCC PPC 440EPx + * + * Valentine Barshak + * + * Based on "ehci-ppc-soc.c" by Stefan Roese + * and "ohci-ppc-of.c" by Sylvain Munaut + * + * This file is licenced under the GPL. + */ + +#include +#include +#include + +#define DRV_MODULE_NAME "ehci-hlwd" +#define DRV_DESCRIPTION "Nintendo Wii EHCI Host Controller" +#define DRV_AUTHOR "Albert Herranz" + +/* + * Non-standard registers. + */ +#define HLWD_EHCI_CTL 0x00cc /* Controller Control */ +#define HLWD_EHCI_CTL_INTE (1<<15) /* Notify EHCI interrupts */ + +/* called during probe() after chip reset completes */ +static int ehci_hlwd_reset(struct usb_hcd *hcd) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + int error; + + dbg_hcs_params(ehci, "reset"); + dbg_hcc_params(ehci, "reset"); + + error = ehci_halt(ehci); + if (error) + goto out; + + error = ehci_init(hcd); + if (error) + goto out; + hcd->self.sg_tablesize = 0; + + /* enable notification of EHCI interrupts */ + setbits32(hcd->regs + HLWD_EHCI_CTL, HLWD_EHCI_CTL_INTE); + + ehci->sbrn = 0x20; + error = ehci_reset(ehci); + ehci_port_power(ehci, 0); +out: + return error; +} + +static const struct hc_driver ehci_hlwd_hc_driver = { + .description = hcd_name, + .product_desc = "Nintendo Wii EHCI Host Controller", + .hcd_priv_size = sizeof(struct ehci_hcd), + + /* + * generic hardware linkage + */ + .irq = ehci_irq, + .flags = HCD_USB2 | HCD_BOUNCE_BUFFERS, + + /* + * basic lifecycle operations + */ + .reset = ehci_hlwd_reset, + .start = ehci_run, + .stop = ehci_stop, + .shutdown = ehci_shutdown, + + /* + * managing i/o requests and associated device resources + */ + .urb_enqueue = ehci_urb_enqueue, + .urb_dequeue = ehci_urb_dequeue, + .endpoint_disable = ehci_endpoint_disable, + .endpoint_reset = ehci_endpoint_reset, + + /* + * scheduling support + */ + .get_frame_number = ehci_get_frame, + + /* + * root hub support + */ + .hub_status_data = ehci_hub_status_data, + .hub_control = ehci_hub_control, +#ifdef CONFIG_PM + .bus_suspend = ehci_bus_suspend, + .bus_resume = ehci_bus_resume, +#endif + .relinquish_port = ehci_relinquish_port, + .port_handed_over = ehci_port_handed_over, + + .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, +}; + + +static int __devinit +ehci_hcd_hlwd_probe(struct of_device *op, const struct of_device_id *match) +{ + struct device_node *dn = op->node; + struct usb_hcd *hcd; + struct ehci_hcd *ehci = NULL; + struct resource res; + int irq; + int error = -ENODEV; + + if (usb_disabled()) + goto out; + + dev_dbg(&op->dev, "initializing " DRV_MODULE_NAME " USB Controller\n"); + + error = of_address_to_resource(dn, 0, &res); + if (error) + goto out; + + hcd = usb_create_hcd(&ehci_hlwd_hc_driver, &op->dev, DRV_MODULE_NAME); + if (!hcd) { + error = -ENOMEM; + goto out; + } + + hcd->rsrc_start = res.start; + hcd->rsrc_len = resource_size(&res); + + irq = irq_of_parse_and_map(dn, 0); + if (irq == NO_IRQ) { + printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n"); + error = -EBUSY; + goto err_irq; + } + + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); + if (!hcd->regs) { + printk(KERN_ERR __FILE__ ": ioremap failed\n"); + error = -EBUSY; + goto err_ioremap; + } + + ehci = hcd_to_ehci(hcd); + ehci->caps = hcd->regs; + ehci->regs = hcd->regs + + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + + /* cache this readonly data; minimize chip reads */ + ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); + + error = usb_add_hcd(hcd, irq, 0); + if (error == 0) + return 0; + + iounmap(hcd->regs); +err_ioremap: + irq_dispose_mapping(irq); +err_irq: + usb_put_hcd(hcd); +out: + return error; +} + + +static int ehci_hcd_hlwd_remove(struct of_device *op) +{ + struct usb_hcd *hcd = dev_get_drvdata(&op->dev); + + dev_set_drvdata(&op->dev, NULL); + + dev_dbg(&op->dev, "stopping " DRV_MODULE_NAME " USB Controller\n"); + + usb_remove_hcd(hcd); + iounmap(hcd->regs); + irq_dispose_mapping(hcd->irq); + usb_put_hcd(hcd); + + return 0; +} + + +static int ehci_hcd_hlwd_shutdown(struct of_device *op) +{ + struct usb_hcd *hcd = dev_get_drvdata(&op->dev); + + if (hcd->driver->shutdown) + hcd->driver->shutdown(hcd); + + return 0; +} + + +static struct of_device_id ehci_hcd_hlwd_match[] = { + { .compatible = "nintendo,hollywood-usb-ehci", }, + {}, +}; +MODULE_DEVICE_TABLE(of, ehci_hcd_hlwd_match); + +static struct of_platform_driver ehci_hcd_hlwd_driver = { + .name = DRV_MODULE_NAME, + .match_table = ehci_hcd_hlwd_match, + .probe = ehci_hcd_hlwd_probe, + .remove = ehci_hcd_hlwd_remove, + .shutdown = ehci_hcd_hlwd_shutdown, + .driver = { + .name = DRV_MODULE_NAME, + .owner = THIS_MODULE, + }, +}; + diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 2d85e21..8fb519b 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -599,6 +599,27 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) #define ehci_big_endian_mmio(e) 0 #endif +#ifdef CONFIG_USB_EHCI_HCD_HLWD + +/* + * The Nintendo Wii video game console has no PCI hardware. + * The USB controllers are part of the "Hollywood" chipset and are + * accessed via the platform internal I/O accessors. + */ +static inline unsigned int ehci_readl(const struct ehci_hcd *ehci, + __u32 __iomem *regs) +{ + return in_be32(regs); +} + +static inline void ehci_writel(const struct ehci_hcd *ehci, + const unsigned int val, __u32 __iomem *regs) +{ + out_be32(regs, val); +} + +#else + /* * Big-endian read/write functions are arch-specific. * Other arches can be added if/when they're needed. @@ -632,6 +653,8 @@ static inline void ehci_writel(const struct ehci_hcd *ehci, #endif } +#endif /* CONFIG_USB_EHCI_HCD_HLWD */ + /* * On certain ppc-44x SoC there is a HW issue, that could only worked around with * explicit suspend/operate of OHCI. This function hereby makes sense only on that arch.