From patchwork Tue Jul 22 10:56:29 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kishon Vijay Abraham I X-Patchwork-Id: 34039 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-oi0-f69.google.com (mail-oi0-f69.google.com [209.85.218.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id D497B20540 for ; Tue, 22 Jul 2014 10:57:36 +0000 (UTC) Received: by mail-oi0-f69.google.com with SMTP id h136sf19463089oig.4 for ; Tue, 22 Jul 2014 03:57:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe:content-type; bh=mxpzNtjHC/2t7eqVQmnhJ0OIK5CZCyZV59/kbBm/iFI=; b=Tp17VDysJtvk7DSU9QBNYyjyGTEOTA6x1zODnuaN1FbzE84a9OIxIIUBGUlYJx695m RMAdKHhJBWxiuiMqBVJJzTmIyp/A9NvV8SCinGAOEswjSd+CLoLskmO7B1vsE1Yq8Uwt Ii9bV/D6TZRxCOnhNFkvVVpOsdGjZsajkgY+4sbe8zO2mcAsp2sOzZYqrcA7Q4VZqEKK TdmZGE+EtAgqfYNsVMMTTatlpKFi51BPjLy87uzb1gkPP/Xk/d9TwcR4tjwJZYhi1+JJ yf8HVHlKZAzG3gNulEz/kZrRPfQ4RF5lm1wCgNceJbppDhAFnAzmfOsrW4ptdsjeUJ6a 7oww== X-Gm-Message-State: ALoCoQmiseyaB41rQeOH8WzRHvWkuZfp7dG4cgPWfIFVKeZotTy4pNXRmQr9iX0Kixq6M7ra560m X-Received: by 10.42.85.142 with SMTP id q14mr7048709icl.16.1406026656394; Tue, 22 Jul 2014 03:57:36 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.90.41 with SMTP id w38ls1291837qgd.56.gmail; Tue, 22 Jul 2014 03:57:36 -0700 (PDT) X-Received: by 10.221.39.132 with SMTP id tm4mr11246927vcb.74.1406026656264; Tue, 22 Jul 2014 03:57:36 -0700 (PDT) Received: from mail-vc0-f181.google.com (mail-vc0-f181.google.com [209.85.220.181]) by mx.google.com with ESMTPS id sn16si45015vdb.23.2014.07.22.03.57.36 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 22 Jul 2014 03:57:36 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.181 as permitted sender) client-ip=209.85.220.181; Received: by mail-vc0-f181.google.com with SMTP id lf12so14354195vcb.12 for ; Tue, 22 Jul 2014 03:57:36 -0700 (PDT) X-Received: by 10.52.129.200 with SMTP id ny8mr2404626vdb.27.1406026656108; Tue, 22 Jul 2014 03:57:36 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.221.37.5 with SMTP id tc5csp185649vcb; Tue, 22 Jul 2014 03:57:35 -0700 (PDT) X-Received: by 10.70.118.5 with SMTP id ki5mr193422pdb.104.1406026654530; Tue, 22 Jul 2014 03:57:34 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id dn2si8668784pdb.500.2014.07.22.03.57.30 for ; Tue, 22 Jul 2014 03:57:30 -0700 (PDT) Received-SPF: none (google.com: linux-kernel-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754431AbaGVK5X (ORCPT + 12 others); Tue, 22 Jul 2014 06:57:23 -0400 Received: from comal.ext.ti.com ([198.47.26.152]:34871 "EHLO comal.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754283AbaGVK5U (ORCPT ); Tue, 22 Jul 2014 06:57:20 -0400 Received: from dflxv15.itg.ti.com ([128.247.5.124]) by comal.ext.ti.com (8.13.7/8.13.7) with ESMTP id s6MAvI25012178; Tue, 22 Jul 2014 05:57:18 -0500 Received: from DFLE72.ent.ti.com (dfle72.ent.ti.com [128.247.5.109]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id s6MAvI7Y018070; Tue, 22 Jul 2014 05:57:18 -0500 Received: from dlep32.itg.ti.com (157.170.170.100) by DFLE72.ent.ti.com (128.247.5.109) with Microsoft SMTP Server id 14.3.174.1; Tue, 22 Jul 2014 05:57:18 -0500 Received: from localhost.localdomain (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep32.itg.ti.com (8.14.3/8.13.8) with ESMTP id s6MAv7qj027221; Tue, 22 Jul 2014 05:57:17 -0500 From: Kishon Vijay Abraham I To: CC: , Subject: [PATCH 06/28] phy: phy-samsung-usb2: Change phy power on/power off sequence Date: Tue, 22 Jul 2014 16:26:29 +0530 Message-ID: <1406026611-30493-7-git-send-email-kishon@ti.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1406026611-30493-1-git-send-email-kishon@ti.com> References: <1406026611-30493-1-git-send-email-kishon@ti.com> MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: kishon@ti.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.181 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , From: Kamil Debski The Exynos4412 USB 2.0 PHY hardware differs from the description provided in the documentation. Some register bits have different function. This patch fixes the defines of register bits and changes the way how phys are powered on and off. Signed-off-by: Kamil Debski Tested-by: Daniel Drake Tested-by: Marek Szyprowski Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-exynos4x12-usb2.c | 112 +++++++++++++++++++++++++------------ drivers/phy/phy-exynos5250-usb2.c | 2 - drivers/phy/phy-samsung-usb2.h | 3 +- 3 files changed, 77 insertions(+), 40 deletions(-) diff --git a/drivers/phy/phy-exynos4x12-usb2.c b/drivers/phy/phy-exynos4x12-usb2.c index d92a7cc..63134d8 100644 --- a/drivers/phy/phy-exynos4x12-usb2.c +++ b/drivers/phy/phy-exynos4x12-usb2.c @@ -86,13 +86,23 @@ #define EXYNOS_4x12_URSTCON_OTG_HLINK BIT(1) #define EXYNOS_4x12_URSTCON_OTG_PHYLINK BIT(2) #define EXYNOS_4x12_URSTCON_HOST_PHY BIT(3) +/* The following bit defines are presented in the + * order taken from the Exynos4412 reference manual. + * + * During experiments with the hardware and debugging + * it was determined that the hardware behaves contrary + * to the manual. + * + * The following bit values were chaned accordingly to the + * results of real hardware experiments. + */ #define EXYNOS_4x12_URSTCON_PHY1 BIT(4) -#define EXYNOS_4x12_URSTCON_HSIC0 BIT(5) -#define EXYNOS_4x12_URSTCON_HSIC1 BIT(6) +#define EXYNOS_4x12_URSTCON_HSIC0 BIT(6) +#define EXYNOS_4x12_URSTCON_HSIC1 BIT(5) #define EXYNOS_4x12_URSTCON_HOST_LINK_ALL BIT(7) -#define EXYNOS_4x12_URSTCON_HOST_LINK_P0 BIT(8) +#define EXYNOS_4x12_URSTCON_HOST_LINK_P0 BIT(10) #define EXYNOS_4x12_URSTCON_HOST_LINK_P1 BIT(9) -#define EXYNOS_4x12_URSTCON_HOST_LINK_P2 BIT(10) +#define EXYNOS_4x12_URSTCON_HOST_LINK_P2 BIT(8) /* Isolation, configured in the power management unit */ #define EXYNOS_4x12_USB_ISOL_OFFSET 0x704 @@ -188,6 +198,7 @@ static void exynos4x12_setup_clk(struct samsung_usb2_phy_instance *inst) clk = readl(drv->reg_phy + EXYNOS_4x12_UPHYCLK); clk &= ~EXYNOS_4x12_UPHYCLK_PHYFSEL_MASK; clk |= drv->ref_reg_val << EXYNOS_4x12_UPHYCLK_PHYFSEL_OFFSET; + clk |= EXYNOS_4x12_UPHYCLK_PHY1_COMMON_ON; writel(clk, drv->reg_phy + EXYNOS_4x12_UPHYCLK); } @@ -198,27 +209,22 @@ static void exynos4x12_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on) u32 phypwr = 0; u32 rst; u32 pwr; - u32 mode = 0; - u32 switch_mode = 0; switch (inst->cfg->id) { case EXYNOS4x12_DEVICE: phypwr = EXYNOS_4x12_UPHYPWR_PHY0; rstbits = EXYNOS_4x12_URSTCON_PHY0; - mode = EXYNOS_4x12_MODE_SWITCH_DEVICE; - switch_mode = 1; break; case EXYNOS4x12_HOST: phypwr = EXYNOS_4x12_UPHYPWR_PHY1; - rstbits = EXYNOS_4x12_URSTCON_HOST_PHY; - mode = EXYNOS_4x12_MODE_SWITCH_HOST; - switch_mode = 1; + rstbits = EXYNOS_4x12_URSTCON_HOST_PHY | + EXYNOS_4x12_URSTCON_PHY1 | + EXYNOS_4x12_URSTCON_HOST_LINK_P0; break; case EXYNOS4x12_HSIC0: phypwr = EXYNOS_4x12_UPHYPWR_HSIC0; - rstbits = EXYNOS_4x12_URSTCON_HSIC1 | - EXYNOS_4x12_URSTCON_HOST_LINK_P0 | - EXYNOS_4x12_URSTCON_HOST_PHY; + rstbits = EXYNOS_4x12_URSTCON_HSIC0 | + EXYNOS_4x12_URSTCON_HOST_LINK_P1; break; case EXYNOS4x12_HSIC1: phypwr = EXYNOS_4x12_UPHYPWR_HSIC1; @@ -228,11 +234,6 @@ static void exynos4x12_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on) }; if (on) { - if (switch_mode) - regmap_update_bits(drv->reg_sys, - EXYNOS_4x12_MODE_SWITCH_OFFSET, - EXYNOS_4x12_MODE_SWITCH_MASK, mode); - pwr = readl(drv->reg_phy + EXYNOS_4x12_UPHYPWR); pwr &= ~phypwr; writel(pwr, drv->reg_phy + EXYNOS_4x12_UPHYPWR); @@ -253,41 +254,78 @@ static void exynos4x12_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on) } } -static int exynos4x12_power_on(struct samsung_usb2_phy_instance *inst) +static void exynos4x12_power_on_int(struct samsung_usb2_phy_instance *inst) { - struct samsung_usb2_phy_driver *drv = inst->drv; + if (inst->int_cnt++ > 0) + return; - inst->enabled = 1; exynos4x12_setup_clk(inst); - exynos4x12_phy_pwr(inst, 1); exynos4x12_isol(inst, 0); + exynos4x12_phy_pwr(inst, 1); +} + +static int exynos4x12_power_on(struct samsung_usb2_phy_instance *inst) +{ + struct samsung_usb2_phy_driver *drv = inst->drv; + + if (inst->ext_cnt++ > 0) + return 0; - /* Power on the device, as it is necessary for HSIC to work */ - if (inst->cfg->id == EXYNOS4x12_HSIC0) { - struct samsung_usb2_phy_instance *device = - &drv->instances[EXYNOS4x12_DEVICE]; - exynos4x12_phy_pwr(device, 1); - exynos4x12_isol(device, 0); + if (inst->cfg->id == EXYNOS4x12_HOST) { + regmap_update_bits(drv->reg_sys, EXYNOS_4x12_MODE_SWITCH_OFFSET, + EXYNOS_4x12_MODE_SWITCH_MASK, + EXYNOS_4x12_MODE_SWITCH_HOST); + exynos4x12_power_on_int(&drv->instances[EXYNOS4x12_DEVICE]); } + if (inst->cfg->id == EXYNOS4x12_DEVICE) + regmap_update_bits(drv->reg_sys, EXYNOS_4x12_MODE_SWITCH_OFFSET, + EXYNOS_4x12_MODE_SWITCH_MASK, + EXYNOS_4x12_MODE_SWITCH_DEVICE); + + if (inst->cfg->id == EXYNOS4x12_HSIC0 || + inst->cfg->id == EXYNOS4x12_HSIC1) { + exynos4x12_power_on_int(&drv->instances[EXYNOS4x12_DEVICE]); + exynos4x12_power_on_int(&drv->instances[EXYNOS4x12_HOST]); + } + + exynos4x12_power_on_int(inst); + return 0; } -static int exynos4x12_power_off(struct samsung_usb2_phy_instance *inst) +static void exynos4x12_power_off_int(struct samsung_usb2_phy_instance *inst) { - struct samsung_usb2_phy_driver *drv = inst->drv; - struct samsung_usb2_phy_instance *device = - &drv->instances[EXYNOS4x12_DEVICE]; + if (inst->int_cnt-- > 1) + return; - inst->enabled = 0; exynos4x12_isol(inst, 1); exynos4x12_phy_pwr(inst, 0); +} - if (inst->cfg->id == EXYNOS4x12_HSIC0 && !device->enabled) { - exynos4x12_isol(device, 1); - exynos4x12_phy_pwr(device, 0); +static int exynos4x12_power_off(struct samsung_usb2_phy_instance *inst) +{ + struct samsung_usb2_phy_driver *drv = inst->drv; + + if (inst->ext_cnt-- > 1) + return 0; + + if (inst->cfg->id == EXYNOS4x12_DEVICE) + regmap_update_bits(drv->reg_sys, EXYNOS_4x12_MODE_SWITCH_OFFSET, + EXYNOS_4x12_MODE_SWITCH_MASK, + EXYNOS_4x12_MODE_SWITCH_HOST); + + if (inst->cfg->id == EXYNOS4x12_HOST) + exynos4x12_power_off_int(&drv->instances[EXYNOS4x12_DEVICE]); + + if (inst->cfg->id == EXYNOS4x12_HSIC0 || + inst->cfg->id == EXYNOS4x12_HSIC1) { + exynos4x12_power_off_int(&drv->instances[EXYNOS4x12_DEVICE]); + exynos4x12_power_off_int(&drv->instances[EXYNOS4x12_HOST]); } + exynos4x12_power_off_int(inst); + return 0; } diff --git a/drivers/phy/phy-exynos5250-usb2.c b/drivers/phy/phy-exynos5250-usb2.c index 94179af..1c139aa 100644 --- a/drivers/phy/phy-exynos5250-usb2.c +++ b/drivers/phy/phy-exynos5250-usb2.c @@ -318,7 +318,6 @@ static int exynos5250_power_on(struct samsung_usb2_phy_instance *inst) break; } - inst->enabled = 1; exynos5250_isol(inst, 0); return 0; @@ -331,7 +330,6 @@ static int exynos5250_power_off(struct samsung_usb2_phy_instance *inst) u32 otg; u32 hsic; - inst->enabled = 0; exynos5250_isol(inst, 1); switch (inst->cfg->id) { diff --git a/drivers/phy/phy-samsung-usb2.h b/drivers/phy/phy-samsung-usb2.h index 45b3170..9188478 100644 --- a/drivers/phy/phy-samsung-usb2.h +++ b/drivers/phy/phy-samsung-usb2.h @@ -29,7 +29,8 @@ struct samsung_usb2_phy_instance { const struct samsung_usb2_common_phy *cfg; struct phy *phy; struct samsung_usb2_phy_driver *drv; - bool enabled; + int int_cnt; + int ext_cnt; }; struct samsung_usb2_phy_driver {