From patchwork Thu Jun 7 06:13:09 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paul Walmsley X-Patchwork-Id: 163485 Return-Path: X-Original-To: incoming-imx@patchwork.ozlabs.org Delivered-To: patchwork-incoming-imx@bilbo.ozlabs.org Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:4978:20e::2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 98979B6FC2 for ; Thu, 7 Jun 2012 16:26:27 +1000 (EST) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1ScW7T-0001pW-VV; Thu, 07 Jun 2012 06:22:56 +0000 Received: from utopia.booyaka.com ([72.9.107.138]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1ScW6D-0001MW-4f for linux-arm-kernel@lists.infradead.org; Thu, 07 Jun 2012 06:21:42 +0000 Received: (qmail 23463 invoked by uid 1019); 7 Jun 2012 06:21:36 -0000 MBOX-Line: From nobody Thu Jun 7 00:13:09 2012 Subject: [PATCH 04/11] ARM: OMAP2+: usb_host_fs: add custom reset for usb_host_fs (fsusb) To: linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org From: Paul Walmsley Date: Thu, 07 Jun 2012 00:13:09 -0600 Message-ID: <20120607061308.25532.19767.stgit@dusk> In-Reply-To: <20120607060901.25532.68354.stgit@dusk> References: <20120607060901.25532.68354.stgit@dusk> User-Agent: StGit/0.16-37-g27ac3 MIME-Version: 1.0 X-Spam-Note: CRM114 invocation failed X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Tero Kristo , =?utf-8?q?Beno=C3=AEt?= Cousson , Felipe Balbi X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org List-Id: linux-imx-kernel.lists.patchwork.ozlabs.org From: Tero Kristo Add a custom reset function for the usb_host_fs/fsusb IP block, and connect it to the OMAP4 FSUSB block. This is the first of two fixes required to get rid of the boot warning: omap_hwmod: usb_host_fs: _wait_target_disable failed and to allow the module to idle. It may be necessary to use this reset method for OMAP2xxx SoCs as well; this is left for a future patch. Signed-off-by: Tero Kristo [paul@pwsan.com: rewrote the custom reset function, documented it and updated the commit message, and moved the code to mach-omap2/fs-usb.c] Signed-off-by: Paul Walmsley Cc: BenoƮt Cousson Cc: Felipe Balbi --- arch/arm/mach-omap2/Makefile | 4 -- arch/arm/mach-omap2/cm.h | 8 +++- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 1 arch/arm/mach-omap2/usb-fs.c | 62 ++++++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/usb.h | 3 + 5 files changed, 73 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index bc2ac4f..fc2ff91 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -245,9 +245,7 @@ omap-hsmmc-$(CONFIG_MMC_OMAP_HS) := hsmmc.o obj-y += $(omap-hsmmc-m) $(omap-hsmmc-y) -usbfs-$(CONFIG_ARCH_OMAP_OTG) := usb-fs.o -obj-y += $(usbfs-m) $(usbfs-y) -obj-y += usb-musb.o +obj-y += usb-fs.o usb-musb.o obj-y += omap_phy_internal.o obj-$(CONFIG_MACH_OMAP2_TUSB6010) += usb-tusb6010.o diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h index a7bc096..99978c7 100644 --- a/arch/arm/mach-omap2/cm.h +++ b/arch/arm/mach-omap2/cm.h @@ -1,7 +1,7 @@ /* * OMAP2+ Clock Management prototypes * - * Copyright (C) 2007-2009 Texas Instruments, Inc. + * Copyright (C) 2007-2012 Texas Instruments, Inc. * Copyright (C) 2007-2009 Nokia Corporation * * Written by Paul Walmsley @@ -14,6 +14,12 @@ #define __ARCH_ASM_MACH_OMAP2_CM_H /* + * MAX_MODULE_SOFTRESET_TIME: maximum time in microseconds to wait for + * an IP block to finish an OCP SOFTRESET. + */ +#define MAX_MODULE_SOFTRESET_WAIT 10000 + +/* * MAX_MODULE_READY_TIME: max duration in microseconds to wait for the * PRCM to request that a module exit the inactive state in the case of * OMAP2 & 3. diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index a93ce48..02daacc 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -3314,6 +3314,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_usb_host_fs_sysc = { static struct omap_hwmod_class omap44xx_usb_host_fs_hwmod_class = { .name = "usb_host_fs", .sysc = &omap44xx_usb_host_fs_sysc, + .reset = omap_usb_host_fs_reset, }; /* usb_host_fs */ diff --git a/arch/arm/mach-omap2/usb-fs.c b/arch/arm/mach-omap2/usb-fs.c index 1481078..4faf0f7 100644 --- a/arch/arm/mach-omap2/usb-fs.c +++ b/arch/arm/mach-omap2/usb-fs.c @@ -1,7 +1,7 @@ /* * Platform level USB initialization for FS USB OTG controller on omap1 and 24xx * - * Copyright (C) 2004 Texas Instruments, Inc. + * Copyright (C) 2004, 2012 Texas Instruments, Inc. * * 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 @@ -32,6 +32,8 @@ #include #include +#include "cm.h" +#include "common.h" #include "control.h" #include "mux.h" @@ -41,6 +43,64 @@ #define INT_USB_IRQ_HGEN INT_24XX_USB_IRQ_HGEN #define INT_USB_IRQ_OTG INT_24XX_USB_IRQ_OTG +/* HCCOMMANDSTATUS: the register offset of the HCCOMMANDSTATUS register */ +#define HCCOMMANDSTATUS 0x0008 + +/* HCCOMMANDSTATUS_HCR: the bitmask of the host controller reset flag */ +#define HCCOMMANDSTATUS_HCR_MASK (1 << 0) + +/** + * omap_usb_host_fs_reset - custom reset function for the FSUSB IP block + * @oh: struct omap_hwmod * of the usb_host_fs IP block + * + * Reset the FSUSB IP block. This IP block requires a custom + * two-stage reset; otherwise the IP block won't idle-ack to the PRCM. + * First the OCP SOFTRESET method must be used. Next, the IP block's + * internal reset bit must be toggled. This will place the OHCI + * controller state into UsbSuspend, which allows the IP block to + * idle-ack to the PRCM. Note that the FSUSB still takes almost 4 + * milliseconds to idle-ack after this function returns. Returns 0 + * upon success, -EINVAL if the IP block softreset data wasn't + * supplied, or -EBUSY if the IP block reset times out. + */ +int omap_usb_host_fs_reset(struct omap_hwmod *oh) +{ + int c; + + if (omap_hwmod_softreset(oh)) + return -EINVAL; + + omap_test_timeout(!(omap_hwmod_read(oh, oh->class->sysc->sysc_offs) + & SYSC_TYPE2_SOFTRESET_MASK), + MAX_MODULE_SOFTRESET_WAIT, c); + + if (c == MAX_MODULE_SOFTRESET_WAIT) { + pr_warn("%s: %s: softreset failed (waited %d usec)\n", + __func__, oh->name, MAX_MODULE_SOFTRESET_WAIT); + return -EBUSY; + } else { + pr_debug("%s: %s: softreset in %d usec\n", __func__, + oh->name, c); + } + + omap_hwmod_write(HCCOMMANDSTATUS_HCR_MASK, oh, HCCOMMANDSTATUS); + + omap_test_timeout(!(omap_hwmod_read(oh, HCCOMMANDSTATUS) + & HCCOMMANDSTATUS_HCR_MASK), + MAX_MODULE_SOFTRESET_WAIT, c); + + if (c == MAX_MODULE_SOFTRESET_WAIT) { + pr_warn("%s: %s: host controller reset failed (waited %d usec)\n", + __func__, oh->name, MAX_MODULE_SOFTRESET_WAIT); + return -EBUSY; + } else { + pr_debug("%s: %s: host controller reset in %d usec\n", __func__, + oh->name, c); + } + + return 0; +} + #if defined(CONFIG_ARCH_OMAP2) #ifdef CONFIG_USB_GADGET_OMAP diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h index 762eeb0..ac7db50 100644 --- a/arch/arm/plat-omap/include/plat/usb.h +++ b/arch/arm/plat-omap/include/plat/usb.h @@ -6,6 +6,7 @@ #include #include #include +#include #define OMAP3_HS_USB_PORTS 3 @@ -181,6 +182,8 @@ static inline void omap2_usbfs_init(struct omap_usb_config *pdata) } #endif +extern int omap_usb_host_fs_reset(struct omap_hwmod *oh); + /*-------------------------------------------------------------------------*/ /*