From patchwork Tue Jun 19 08:47:03 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Lin X-Patchwork-Id: 165696 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 7DDEDB700D for ; Tue, 19 Jun 2012 18:47:26 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id C898328107; Tue, 19 Jun 2012 10:47:23 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 7E2+waQfMcIb; Tue, 19 Jun 2012 10:47:23 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id A6E53280EB; Tue, 19 Jun 2012 10:47:19 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 146B4280EB for ; Tue, 19 Jun 2012 10:47:16 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id BEaeTOzqBTcg for ; Tue, 19 Jun 2012 10:47:13 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from hqemgate03.nvidia.com (hqemgate03.nvidia.com [216.228.121.140]) by theia.denx.de (Postfix) with ESMTPS id A30E1280E6 for ; Tue, 19 Jun 2012 10:47:10 +0200 (CEST) Received: from hqnvupgp07.nvidia.com (Not Verified[216.228.121.13]) by hqemgate03.nvidia.com id ; Tue, 19 Jun 2012 01:47:06 -0700 Received: from hqemhub03.nvidia.com ([172.17.108.22]) by hqnvupgp07.nvidia.com (PGP Universal service); Tue, 19 Jun 2012 01:44:24 -0700 X-PGP-Universal: processed; by hqnvupgp07.nvidia.com on Tue, 19 Jun 2012 01:44:24 -0700 Received: from hkemhub01.nvidia.com (10.18.67.12) by hqemhub03.nvidia.com (172.20.150.15) with Microsoft SMTP Server (TLS) id 8.3.264.0; Tue, 19 Jun 2012 01:47:06 -0700 Received: from HKMAIL02.nvidia.com ([10.18.67.17]) by hkemhub01.nvidia.com ([10.18.67.12]) with mapi; Tue, 19 Jun 2012 16:47:04 +0800 From: Jim Lin To: 'Stephen Warren' Date: Tue, 19 Jun 2012 16:47:03 +0800 Thread-Topic: [U-Boot] [PATCH v2 1/1] tegra: usb: Fix device enumeration problem of USB1 Thread-Index: Ac1N9fImo9a4Vg8fRvGpaT108NKSJg== Message-ID: <4B9C9637D5087840A465BDCB251780E9E2D629AF74@HKMAIL02.nvidia.com> Accept-Language: zh-TW, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: zh-TW, en-US MIME-Version: 1.0 Cc: "'u-boot@lists.denx.de'" , Tom Warren Subject: [U-Boot] [PATCH v2 1/1] tegra: usb: Fix device enumeration problem of USB1 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de A known hardware issue of USB1 port where bit 1 (connect status change) of PORTSC register will be set after issuing Port Reset (like "usb reset" in u-boot command line). This will be treated as an error and stops later device enumeration. Therefore we add a definition in header file and a callback function to clear that bit after Port Reset in order to proceed later device enumeration. CONFIG_USB_EHCI_SUBMIT_ROOT_POST_CALLBACK Signed-off-by: Jim Lin --- To reproduce this issue, you can modify board .dts file to set as the following to build u-boot binary. " usb0 = "/usb@c5000000"; usb1 = "/usb@c5008000"; " Install device on USB1 port (address at 0xc5000000). And run "usb reset" in u-boot console to enumerate device. Changes in v2: - Change config name - Add a callback function at the end of ehci_submit_root() function drivers/usb/host/ehci-hcd.c | 4 ++++ drivers/usb/host/ehci-tegra.c | 34 ++++++++++++++++++++++++++++++++++ drivers/usb/host/ehci.h | 4 ++++ include/configs/tegra2-common.h | 8 ++++++++ 4 files changed, 50 insertions(+), 0 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 38d6ae0..0b6b656 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -792,7 +792,11 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, dev->act_len = len; dev->status = 0; +#ifdef CONFIG_USB_EHCI_SUBMIT_ROOT_POST_CALLBACK + return ehci_submit_root_post_callback(dev, pipe, buffer, length, req); +#else return 0; +#endif unknown: debug("requesttype=%x, request=%x, value=%x, index=%x, length=%x\n", diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index a7e105b..3dd18d3 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -29,6 +29,40 @@ #include #include +#ifdef CONFIG_USB_EHCI_SUBMIT_ROOT_POST_CALLBACK +int +ehci_submit_root_post_callback(struct usb_device *dev, unsigned long pipe, + void *buffer, int length, struct devrequest *req) +{ + u16 typeReq; + uint32_t reg; + uint32_t *status_reg; + + status_reg = (uint32_t *)&hcor->or_portsc[ + le16_to_cpu(req->index) - 1]; + if (((u32) status_reg & 0xFFFFC000) != TEGRA_USB1_BASE) + return 0; + typeReq = req->request | req->requesttype << 8; + switch (typeReq) { + case USB_REQ_SET_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8): + switch (le16_to_cpu(req->value)) { + /* + * A known HW issue on USB1 port where bit 1 (Connect Status + * Change) of PORTSC register will be set after issuing Port + * Reset. Clear that bit for later device enumeration. + */ + case USB_PORT_FEAT_RESET: + reg = ehci_readl(status_reg); + reg &= ~EHCI_PS_CLEAR; + reg |= EHCI_PS_CSC; + ehci_writel(status_reg, reg); + break; + } + break; + } + return 0; +} +#endif /* * Create the appropriate control structures to manage diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index cc00ce4..6c5d8f3 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -204,4 +204,8 @@ struct QH { int ehci_hcd_init(void); int ehci_hcd_stop(void); +#ifdef CONFIG_USB_EHCI_SUBMIT_ROOT_POST_CALLBACK +int ehci_submit_root_post_callback(struct usb_device *dev, unsigned long pipe, + void *buffer, int length, struct devrequest *req); +#endif #endif /* USB_EHCI_H */ diff --git a/include/configs/tegra2-common.h b/include/configs/tegra2-common.h index 1931179..b4822d4 100644 --- a/include/configs/tegra2-common.h +++ b/include/configs/tegra2-common.h @@ -111,6 +111,14 @@ #define CONFIG_EHCI_IS_TDI #define CONFIG_EHCI_DCACHE +/* + * A known HW issue on USB1 port where bit 1 (Connect Status Change) of PORTSC + * register will be set after issuing Port Reset. + * This setting is to add a callback function to clear that bit for later + * device enumeration. + */ +#define CONFIG_USB_EHCI_SUBMIT_ROOT_POST_CALLBACK + /* Total I2C ports on Tegra2 */ #define TEGRA_I2C_NUM_CONTROLLERS 4