From patchwork Wed Apr 15 08:25:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nagarjuna Kristam X-Patchwork-Id: 11490407 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BBD0192C for ; Wed, 15 Apr 2020 08:29:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A4AF320784 for ; Wed, 15 Apr 2020 08:29:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=nvidia.com header.i=@nvidia.com header.b="W9Ip2w4s" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2894552AbgDOI2t (ORCPT ); Wed, 15 Apr 2020 04:28:49 -0400 Received: from hqnvemgate25.nvidia.com ([216.228.121.64]:16774 "EHLO hqnvemgate25.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2894466AbgDOI1K (ORCPT ); Wed, 15 Apr 2020 04:27:10 -0400 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate25.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Wed, 15 Apr 2020 01:24:25 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Wed, 15 Apr 2020 01:25:23 -0700 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Wed, 15 Apr 2020 01:25:23 -0700 Received: from HQMAIL111.nvidia.com (172.20.187.18) by HQMAIL101.nvidia.com (172.20.187.10) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Wed, 15 Apr 2020 08:25:22 +0000 Received: from rnnvemgw01.nvidia.com (10.128.109.123) by HQMAIL111.nvidia.com (172.20.187.18) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Wed, 15 Apr 2020 08:25:22 +0000 Received: from nkristam-ubuntu.nvidia.com (Not Verified[10.19.67.128]) by rnnvemgw01.nvidia.com with Trustwave SEG (v7,5,8,10121) id ; Wed, 15 Apr 2020 01:25:21 -0700 From: Nagarjuna Kristam To: , , , , , , CC: , , , , Nagarjuna Kristam Subject: [PATCH V2 1/8] dt-bindings: phy: tegra-xusb: Add charger-detect property Date: Wed, 15 Apr 2020 13:55:01 +0530 Message-ID: <1586939108-10075-2-git-send-email-nkristam@nvidia.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1586939108-10075-1-git-send-email-nkristam@nvidia.com> References: <1586939108-10075-1-git-send-email-nkristam@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1586939065; bh=SV8SYGELTW8vG0isvMFMvi6jGyjhj/U0TJjzJY0h4YA=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:X-NVConfidentiality:MIME-Version: Content-Type; b=W9Ip2w4sJ4GcC+j42qRE8/LGsCSIOrqZ+8+7GADC/vJBlGvVVjGbltupTQjoBKVpU zlD7HSFxoFF35N/OubsbW05ui8FG2h/MrjE2bioybjIUET9Zx0RoMZPNePqpoEhW4m j4ZW8CuEZ4S8/s0u37ct4Sr+tmQSPyt05gWtQbU1WcqBOI5S1Ul+CN8g9Mm5AwhSSJ ZhGe0t3LlWfFuVKpABfv2gYQnP0d4+Kq3C7kn0k86jLo78v9JtzBL49CfqEPeOCOXR iFLnoFa41s9bRTGRBszW6CcWOkV1wTS2v9rifQz2yuHXiWcdkV+QrYRJckYpd3Jtsm +R1Gztu25QExg== Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Add nvidia,charger-detect boolean property for Tegra210 and Tegra186 platforms. This property is used to inform driver to perform charger detection on corresponding USB 2 port. Signed-off-by: Nagarjuna Kristam Acked-by: Rob Herring Acked-by: Thierry Reding --- V2: - Added Acked-by updates to commit message. --- Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt b/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt index 38c5fa2..9b2d2dd 100644 --- a/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt +++ b/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt @@ -190,6 +190,10 @@ Required properties for OTG/Peripheral capable USB2 ports: and peripheral roles. Connector should be added as subnode. See usb/usb-conn-gpio.txt. +Optional properties for OTG/Peripheral capable USB2 ports: +- nvidia,charger-detect: A boolean property whose presence inform driver to + perform charger-detect activity. + Optional properties: - nvidia,internal: A boolean property whose presence determines that a port is internal. In the absence of this property the port is considered to be From patchwork Wed Apr 15 08:25:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nagarjuna Kristam X-Patchwork-Id: 11490399 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8209514B4 for ; Wed, 15 Apr 2020 08:27:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6A37A20775 for ; Wed, 15 Apr 2020 08:27:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=nvidia.com header.i=@nvidia.com header.b="c6nU3yHL" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2894498AbgDOI1V (ORCPT ); Wed, 15 Apr 2020 04:27:21 -0400 Received: from hqnvemgate25.nvidia.com ([216.228.121.64]:16788 "EHLO hqnvemgate25.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2894471AbgDOI1K (ORCPT ); Wed, 15 Apr 2020 04:27:10 -0400 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate25.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Wed, 15 Apr 2020 01:24:28 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Wed, 15 Apr 2020 01:25:27 -0700 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Wed, 15 Apr 2020 01:25:27 -0700 Received: from HQMAIL109.nvidia.com (172.20.187.15) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Wed, 15 Apr 2020 08:25:26 +0000 Received: from rnnvemgw01.nvidia.com (10.128.109.123) by HQMAIL109.nvidia.com (172.20.187.15) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Wed, 15 Apr 2020 08:25:26 +0000 Received: from nkristam-ubuntu.nvidia.com (Not Verified[10.19.67.128]) by rnnvemgw01.nvidia.com with Trustwave SEG (v7,5,8,10121) id ; Wed, 15 Apr 2020 01:25:25 -0700 From: Nagarjuna Kristam To: , , , , , , CC: , , , , Nagarjuna Kristam Subject: [PATCH V2 2/8] usb: gadget: tegra-xudc: Add vbus_draw support Date: Wed, 15 Apr 2020 13:55:02 +0530 Message-ID: <1586939108-10075-3-git-send-email-nkristam@nvidia.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1586939108-10075-1-git-send-email-nkristam@nvidia.com> References: <1586939108-10075-1-git-send-email-nkristam@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1586939068; bh=dGYpAOijxW3GRCvoqmiBOVWTNifRfJYwZqamEi3UNkM=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:X-NVConfidentiality:MIME-Version: Content-Type; b=c6nU3yHL1CVuyXkrkf++DlgV8JwwzyamZnXysUsHa8WP67YMG6dd+3I8wabebFwbm bGoiqgTcmddjuD9gxGWm1bYxxejUe5l5aw6oxBqluSmCdib/uABPlvj4xiU7g2aivb Fi4v4iArRi48CWskEC1G2EkCr5zVnZchjDVZLzxZB6Sb0+sPF96dqa1Kb7xZzljrTy iNSn24KFqkXeR5IwyQZAXGMb0lfvldv4PMNmtNYx5OUFGcfzLiWNPkwiFE982XtUDW gyr9YA9U1eteSIqwh0k1b/IhapBxIr9fRo0xwILKx2vA9gmrgoQ5u83I8ygSLW44qh FkxdypfGpqdpQ== Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Register vbus_draw to gadget ops and update corresponding vbus draw current to usb_phy. Signed-off-by: Nagarjuna Kristam --- V2: - Patch re-based. --- drivers/usb/gadget/udc/tegra-xudc.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c index 52a6add..9d3c109 100644 --- a/drivers/usb/gadget/udc/tegra-xudc.c +++ b/drivers/usb/gadget/udc/tegra-xudc.c @@ -492,6 +492,7 @@ struct tegra_xudc { bool powergated; struct usb_phy **usbphy; + struct usb_phy *curr_usbphy; struct notifier_block vbus_nb; struct completion disconnect_complete; @@ -719,6 +720,7 @@ static int tegra_xudc_vbus_notify(struct notifier_block *nb, if (!xudc->suspended && phy_index != -1) { xudc->curr_utmi_phy = xudc->utmi_phy[phy_index]; xudc->curr_usb3_phy = xudc->usb3_phy[phy_index]; + xudc->curr_usbphy = usbphy; schedule_work(&xudc->usb_role_sw_work); } @@ -2042,6 +2044,19 @@ static int tegra_xudc_gadget_stop(struct usb_gadget *gadget) return 0; } +static int tegra_xudc_gadget_vbus_draw(struct usb_gadget *gadget, + unsigned int m_a) +{ + struct tegra_xudc *xudc = to_xudc(gadget); + + dev_dbg(xudc->dev, "%s: %u mA\n", __func__, m_a); + + if (xudc->curr_usbphy->chg_type == SDP_TYPE) + usb_phy_set_power(xudc->curr_usbphy, m_a); + + return 0; +} + static int tegra_xudc_set_selfpowered(struct usb_gadget *gadget, int is_on) { struct tegra_xudc *xudc = to_xudc(gadget); @@ -2058,6 +2073,7 @@ static struct usb_gadget_ops tegra_xudc_gadget_ops = { .pullup = tegra_xudc_gadget_pullup, .udc_start = tegra_xudc_gadget_start, .udc_stop = tegra_xudc_gadget_stop, + .vbus_draw = tegra_xudc_gadget_vbus_draw, .set_selfpowered = tegra_xudc_set_selfpowered, }; From patchwork Wed Apr 15 08:25:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nagarjuna Kristam X-Patchwork-Id: 11490401 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6CBE314B4 for ; Wed, 15 Apr 2020 08:28:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5018F20784 for ; Wed, 15 Apr 2020 08:28:17 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=nvidia.com header.i=@nvidia.com header.b="XtV98Fz/" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2894487AbgDOI1T (ORCPT ); Wed, 15 Apr 2020 04:27:19 -0400 Received: from hqnvemgate24.nvidia.com ([216.228.121.143]:4442 "EHLO hqnvemgate24.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2894474AbgDOI1K (ORCPT ); Wed, 15 Apr 2020 04:27:10 -0400 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate24.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Wed, 15 Apr 2020 01:23:41 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Wed, 15 Apr 2020 01:25:30 -0700 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Wed, 15 Apr 2020 01:25:30 -0700 Received: from HQMAIL101.nvidia.com (172.20.187.10) by HQMAIL105.nvidia.com (172.20.187.12) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Wed, 15 Apr 2020 08:25:30 +0000 Received: from rnnvemgw01.nvidia.com (10.128.109.123) by HQMAIL101.nvidia.com (172.20.187.10) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Wed, 15 Apr 2020 08:25:30 +0000 Received: from nkristam-ubuntu.nvidia.com (Not Verified[10.19.67.128]) by rnnvemgw01.nvidia.com with Trustwave SEG (v7,5,8,10121) id ; Wed, 15 Apr 2020 01:25:29 -0700 From: Nagarjuna Kristam To: , , , , , , CC: , , , , Nagarjuna Kristam Subject: [PATCH V2 3/8] phy: tegra: xusb: Add support for UTMI pad power control Date: Wed, 15 Apr 2020 13:55:03 +0530 Message-ID: <1586939108-10075-4-git-send-email-nkristam@nvidia.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1586939108-10075-1-git-send-email-nkristam@nvidia.com> References: <1586939108-10075-1-git-send-email-nkristam@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1586939021; bh=54AsFYf8Iqj2Ar3hTENRodkHPBl+dIfWETSGg1O9VZE=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:X-NVConfidentiality:MIME-Version: Content-Type; b=XtV98Fz/PwRSt1chfLXRMVVUO0d3YWIiPdwncIdLrG40iZWb1bYtGLFkssynGBGrY TOqOn1Ff3AXT0hUHJ8GCSsuTTHIFsptp55Rr9CnufBtwrjXx/SLeM6qKd5vNBRyUAE /k8/zYsf0J9Tr/vyvVewch3lQ6AvQtMUMxzE5Hxd+bh4PB09kMqIPLMWL8APfDtaHl LXp3Ry2ajxmDPKPtAdTwAmNIrj/N+jGm2xQ7rlPXyBQXqFRw/n2Oj/0iD+DQ+chSi6 Nj1NJGgNOfdQkrN63frhcLtqpezJfizBlLLFzuijQRZi3BorkMZHDZ1OT+HwO19XAv 6wM+qvEwJV3Cw== Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Add support for UTMI pad power on and off API's via soc ops. These API can be used by operations like charger detect to power on and off UTMI pad if needed. Update powered_on flag in the pad power control API's. Signed-off-by: Nagarjuna Kristam Acked-by: Thierry Reding --- V2: - Patch re-based. --- drivers/phy/tegra/xusb-tegra186.c | 51 ++++++++++++++++++--------------------- drivers/phy/tegra/xusb.h | 2 ++ 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/drivers/phy/tegra/xusb-tegra186.c b/drivers/phy/tegra/xusb-tegra186.c index 5d64f69..f862254 100644 --- a/drivers/phy/tegra/xusb-tegra186.c +++ b/drivers/phy/tegra/xusb-tegra186.c @@ -192,12 +192,8 @@ static void tegra186_utmi_bias_pad_power_on(struct tegra_xusb_padctl *padctl) u32 value; int err; - mutex_lock(&padctl->lock); - - if (priv->bias_pad_enable++ > 0) { - mutex_unlock(&padctl->lock); + if (priv->bias_pad_enable++ > 0) return; - } err = clk_prepare_enable(priv->usb2_trk_clk); if (err < 0) @@ -221,8 +217,6 @@ static void tegra186_utmi_bias_pad_power_on(struct tegra_xusb_padctl *padctl) value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); value &= ~USB2_PD_TRK; padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); - - mutex_unlock(&padctl->lock); } static void tegra186_utmi_bias_pad_power_off(struct tegra_xusb_padctl *padctl) @@ -230,44 +224,29 @@ static void tegra186_utmi_bias_pad_power_off(struct tegra_xusb_padctl *padctl) struct tegra186_xusb_padctl *priv = to_tegra186_xusb_padctl(padctl); u32 value; - mutex_lock(&padctl->lock); - - if (WARN_ON(priv->bias_pad_enable == 0)) { - mutex_unlock(&padctl->lock); + if (WARN_ON(priv->bias_pad_enable == 0)) return; - } - if (--priv->bias_pad_enable > 0) { - mutex_unlock(&padctl->lock); + if (--priv->bias_pad_enable > 0) return; - } value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); value |= USB2_PD_TRK; padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); clk_disable_unprepare(priv->usb2_trk_clk); - - mutex_unlock(&padctl->lock); } static void tegra_phy_xusb_utmi_pad_power_on(struct phy *phy) { struct tegra_xusb_lane *lane = phy_get_drvdata(phy); struct tegra_xusb_padctl *padctl = lane->pad->padctl; - struct tegra_xusb_usb2_port *port; - struct device *dev = padctl->dev; + struct tegra_xusb_usb2_lane *usb2 = to_usb2_lane(lane); unsigned int index = lane->index; u32 value; - if (!phy) - return; - - port = tegra_xusb_find_usb2_port(padctl, index); - if (!port) { - dev_err(dev, "no port found for USB2 lane %u\n", index); + if (!phy || usb2->powered_on) return; - } tegra186_utmi_bias_pad_power_on(padctl); @@ -280,16 +259,19 @@ static void tegra_phy_xusb_utmi_pad_power_on(struct phy *phy) value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index)); value &= ~USB2_OTG_PD_DR; padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index)); + + usb2->powered_on = true; } static void tegra_phy_xusb_utmi_pad_power_down(struct phy *phy) { struct tegra_xusb_lane *lane = phy_get_drvdata(phy); struct tegra_xusb_padctl *padctl = lane->pad->padctl; + struct tegra_xusb_usb2_lane *usb2 = to_usb2_lane(lane); unsigned int index = lane->index; u32 value; - if (!phy) + if (!phy || !usb2->powered_on) return; value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index)); @@ -303,6 +285,8 @@ static void tegra_phy_xusb_utmi_pad_power_down(struct phy *phy) udelay(2); tegra186_utmi_bias_pad_power_off(padctl); + + usb2->powered_on = false; } static int tegra186_xusb_padctl_vbus_override(struct tegra_xusb_padctl *padctl, @@ -413,6 +397,8 @@ static int tegra186_utmi_phy_power_on(struct phy *phy) return -ENODEV; } + mutex_lock(&padctl->lock); + value = padctl_readl(padctl, XUSB_PADCTL_USB2_PAD_MUX); value &= ~(USB2_PORT_MASK << USB2_PORT_SHIFT(index)); value |= (PORT_XUSB << USB2_PORT_SHIFT(index)); @@ -464,14 +450,23 @@ static int tegra186_utmi_phy_power_on(struct phy *phy) /* TODO: pad power saving */ tegra_phy_xusb_utmi_pad_power_on(phy); + + mutex_unlock(&padctl->lock); return 0; } static int tegra186_utmi_phy_power_off(struct phy *phy) { + struct tegra_xusb_lane *lane = phy_get_drvdata(phy); + struct tegra_xusb_padctl *padctl = lane->pad->padctl; + + mutex_lock(&padctl->lock); + /* TODO: pad power saving */ tegra_phy_xusb_utmi_pad_power_down(phy); + mutex_unlock(&padctl->lock); + return 0; } @@ -938,6 +933,8 @@ static const struct tegra_xusb_padctl_ops tegra186_xusb_padctl_ops = { .probe = tegra186_xusb_padctl_probe, .remove = tegra186_xusb_padctl_remove, .vbus_override = tegra186_xusb_padctl_vbus_override, + .utmi_pad_power_on = tegra_phy_xusb_utmi_pad_power_on, + .utmi_pad_power_down = tegra_phy_xusb_utmi_pad_power_down, }; #if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC) diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h index ea35af7..6995fc4 100644 --- a/drivers/phy/tegra/xusb.h +++ b/drivers/phy/tegra/xusb.h @@ -396,6 +396,8 @@ struct tegra_xusb_padctl_ops { unsigned int index, bool enable); int (*vbus_override)(struct tegra_xusb_padctl *padctl, bool set); int (*utmi_port_reset)(struct phy *phy); + void (*utmi_pad_power_on)(struct phy *phy); + void (*utmi_pad_power_down)(struct phy *phy); }; struct tegra_xusb_padctl_soc { From patchwork Wed Apr 15 08:25:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nagarjuna Kristam X-Patchwork-Id: 11490397 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D2CB292C for ; Wed, 15 Apr 2020 08:27:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AE54C20775 for ; Wed, 15 Apr 2020 08:27:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=nvidia.com header.i=@nvidia.com header.b="hUWi4CE0" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2894511AbgDOI11 (ORCPT ); Wed, 15 Apr 2020 04:27:27 -0400 Received: from hqnvemgate26.nvidia.com ([216.228.121.65]:11476 "EHLO hqnvemgate26.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2894475AbgDOI1K (ORCPT ); Wed, 15 Apr 2020 04:27:10 -0400 Received: from hqpgpgate102.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate26.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Wed, 15 Apr 2020 01:25:21 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate102.nvidia.com (PGP Universal service); Wed, 15 Apr 2020 01:25:34 -0700 X-PGP-Universal: processed; by hqpgpgate102.nvidia.com on Wed, 15 Apr 2020 01:25:34 -0700 Received: from HQMAIL105.nvidia.com (172.20.187.12) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Wed, 15 Apr 2020 08:25:34 +0000 Received: from rnnvemgw01.nvidia.com (10.128.109.123) by HQMAIL105.nvidia.com (172.20.187.12) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Wed, 15 Apr 2020 08:25:33 +0000 Received: from nkristam-ubuntu.nvidia.com (Not Verified[10.19.67.128]) by rnnvemgw01.nvidia.com with Trustwave SEG (v7,5,8,10121) id ; Wed, 15 Apr 2020 01:25:33 -0700 From: Nagarjuna Kristam To: , , , , , , CC: , , , , Nagarjuna Kristam Subject: [PATCH V2 4/8] phy: tegra: xusb: Add USB2 pad power control support for Tegra210 Date: Wed, 15 Apr 2020 13:55:04 +0530 Message-ID: <1586939108-10075-5-git-send-email-nkristam@nvidia.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1586939108-10075-1-git-send-email-nkristam@nvidia.com> References: <1586939108-10075-1-git-send-email-nkristam@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1586939121; bh=0IfgHkW4p2Q1oj9Dq+jfSsUtMb2IgCv5lL6w9zFSnVs=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:X-NVConfidentiality:MIME-Version: Content-Type; b=hUWi4CE0IEiUqjplcs6ff7bxR6INnn5n1YYJjD7YqEcyASo7pzgdbkvsevH2Exy0V M87crAshH+EBl8KJEOcLmzPIuckQfjMlD7gWzeK1v34CwX4eT+9T6fK/qLqQ3aKWhv vP7RWhwQV6UQo8UtEjkgiEcjVz52GeFbMShVhLB0w6Pao/YjoFPPVcgkx6dCcueFau BoLt4PQtlRFK5Qogy8b/Kk4PzlwPIDFoaqGiQyYAtWFoeWaDb0mqZnu9S2xalkxwIk I0b4ig8EDYhJJv0OzwfGFPOnUFC6Fxo/fH3XGlffRpjYoqQyb5P0RgVvC6/HopHyEl SSYGT8LSZZbtg== Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Add USB2 pad power on and off API's for TEgra210 and provide its control via soc ops. It can be used by operations like charger detect to power on and off USB2 pad if needed. Signed-off-by: Nagarjuna Kristam Acked-by: Thierry Reding --- V2: - Patch re-based. --- drivers/phy/tegra/xusb-tegra210.c | 190 ++++++++++++++++++++++++++------------ 1 file changed, 133 insertions(+), 57 deletions(-) diff --git a/drivers/phy/tegra/xusb-tegra210.c b/drivers/phy/tegra/xusb-tegra210.c index 66bd461..caf0890 100644 --- a/drivers/phy/tegra/xusb-tegra210.c +++ b/drivers/phy/tegra/xusb-tegra210.c @@ -994,6 +994,128 @@ static int tegra210_xusb_padctl_id_override(struct tegra_xusb_padctl *padctl, return 0; } +static void tegra210_usb2_bias_pad_power_on(struct tegra_xusb_usb2_pad *pad) +{ + struct tegra_xusb_padctl *padctl = pad->base.padctl; + u32 value; + + if (pad->enable++ > 0) + return; + + dev_dbg(padctl->dev, "power on BIAS PAD & USB2 tracking\n"); + + if (clk_prepare_enable(pad->clk)) + dev_warn(padctl->dev, "failed to enable BIAS PAD & USB2 tracking\n"); + + value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); + value &= ~((XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_MASK << + XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_SHIFT) | + (XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_MASK << + XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_SHIFT)); + value |= (XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_VAL << + XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_SHIFT) | + (XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_VAL << + XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_SHIFT); + padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); + + value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); + value &= ~XUSB_PADCTL_USB2_BIAS_PAD_CTL0_PD; + padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); + + udelay(1); + + value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); + value &= ~XUSB_PADCTL_USB2_BIAS_PAD_CTL1_PD_TRK; + padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); + + udelay(50); +} + +static void tegra210_usb2_bias_pad_power_off(struct tegra_xusb_usb2_pad *pad) +{ + struct tegra_xusb_padctl *padctl = pad->base.padctl; + u32 value; + + if (WARN_ON(pad->enable == 0)) + return; + + if (--pad->enable > 0) + return; + + dev_dbg(padctl->dev, "power off USB2 tracking\n"); + + value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); + value |= XUSB_PADCTL_USB2_BIAS_PAD_CTL0_PD; + padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); + + clk_disable_unprepare(pad->clk); +} + +/* must be called under padctl->lock */ +void tegra210_usb2_pad_power_on(struct phy *phy) +{ + struct tegra_xusb_lane *lane = phy_get_drvdata(phy); + struct tegra_xusb_usb2_lane *usb2 = to_usb2_lane(lane); + struct tegra_xusb_usb2_pad *pad = to_usb2_pad(lane->pad); + struct tegra_xusb_padctl *padctl = lane->pad->padctl; + unsigned int index = lane->index; + u32 value; + + if (!phy) + return; + + if (usb2->powered_on) + return; + + dev_info(padctl->dev, "power on UTMI pads %d\n", index); + + tegra210_usb2_bias_pad_power_on(pad); + + udelay(2); + + value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index)); + value &= ~XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD; + padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index)); + + value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index)); + value &= ~XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_DR; + padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index)); + + usb2->powered_on = true; +} + +/* must be called under padctl->lock */ +void tegra210_usb2_pad_power_down(struct phy *phy) +{ + struct tegra_xusb_lane *lane = phy_get_drvdata(phy); + struct tegra_xusb_usb2_lane *usb2 = to_usb2_lane(lane); + struct tegra_xusb_usb2_pad *pad = to_usb2_pad(lane->pad); + struct tegra_xusb_padctl *padctl = lane->pad->padctl; + unsigned int index = lane->index; + u32 value; + + if (!phy) + return; + + if (!usb2->powered_on) + return; + + dev_info(padctl->dev, "power down UTMI pad %d\n", index); + + value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index)); + value |= XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD; + padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index)); + + value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index)); + value |= XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_DR; + padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index)); + + udelay(2); + + tegra210_usb2_bias_pad_power_off(pad); + usb2->powered_on = false; +} + static int tegra210_usb2_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) { @@ -1037,7 +1159,6 @@ static int tegra210_usb2_phy_power_on(struct phy *phy) { struct tegra_xusb_lane *lane = phy_get_drvdata(phy); struct tegra_xusb_usb2_lane *usb2 = to_usb2_lane(lane); - struct tegra_xusb_usb2_pad *pad = to_usb2_pad(lane->pad); struct tegra_xusb_padctl *padctl = lane->pad->padctl; struct tegra210_xusb_padctl *priv; struct tegra_xusb_usb2_port *port; @@ -1053,6 +1174,8 @@ static int tegra210_usb2_phy_power_on(struct phy *phy) priv = to_tegra210_xusb_padctl(padctl); + mutex_lock(&padctl->lock); + if (port->usb3_port_fake != -1) { value = padctl_readl(padctl, XUSB_PADCTL_SS_PORT_MAP); value &= ~XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP_MASK( @@ -1148,62 +1271,21 @@ static int tegra210_usb2_phy_power_on(struct phy *phy) if (port->supply && port->mode == USB_DR_MODE_HOST) { err = regulator_enable(port->supply); - if (err) + if (err) { + mutex_unlock(&padctl->lock); return err; + } } - mutex_lock(&padctl->lock); - - if (pad->enable > 0) { - pad->enable++; - mutex_unlock(&padctl->lock); - return 0; - } - - err = clk_prepare_enable(pad->clk); - if (err) - goto disable_regulator; + tegra210_usb2_pad_power_on(phy); - value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); - value &= ~((XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_MASK << - XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_SHIFT) | - (XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_MASK << - XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_SHIFT)); - value |= (XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_VAL << - XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_SHIFT) | - (XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_VAL << - XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_SHIFT); - padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); - - value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); - value &= ~XUSB_PADCTL_USB2_BIAS_PAD_CTL0_PD; - padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); - - udelay(1); - - value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); - value &= ~XUSB_PADCTL_USB2_BIAS_PAD_CTL1_PD_TRK; - padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); - - udelay(50); - - clk_disable_unprepare(pad->clk); - - pad->enable++; mutex_unlock(&padctl->lock); - return 0; - -disable_regulator: - regulator_disable(port->supply); - mutex_unlock(&padctl->lock); - return err; } static int tegra210_usb2_phy_power_off(struct phy *phy) { struct tegra_xusb_lane *lane = phy_get_drvdata(phy); - struct tegra_xusb_usb2_pad *pad = to_usb2_pad(lane->pad); struct tegra_xusb_padctl *padctl = lane->pad->padctl; struct tegra_xusb_usb2_port *port; u32 value; @@ -1217,6 +1299,8 @@ static int tegra210_usb2_phy_power_off(struct phy *phy) mutex_lock(&padctl->lock); + tegra210_usb2_pad_power_down(phy); + if (port->usb3_port_fake != -1) { value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1); value |= XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_CLAMP_EN_EARLY( @@ -1243,18 +1327,8 @@ static int tegra210_usb2_phy_power_off(struct phy *phy) padctl_writel(padctl, value, XUSB_PADCTL_SS_PORT_MAP); } - if (WARN_ON(pad->enable == 0)) - goto out; - - if (--pad->enable > 0) - goto out; - - value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); - value |= XUSB_PADCTL_USB2_BIAS_PAD_CTL0_PD; - padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); - -out: regulator_disable(port->supply); + mutex_unlock(&padctl->lock); return 0; } @@ -2215,6 +2289,8 @@ static const struct tegra_xusb_padctl_ops tegra210_xusb_padctl_ops = { .hsic_set_idle = tegra210_hsic_set_idle, .vbus_override = tegra210_xusb_padctl_vbus_override, .utmi_port_reset = tegra210_utmi_port_reset, + .utmi_pad_power_on = tegra210_usb2_pad_power_on, + .utmi_pad_power_down = tegra210_usb2_pad_power_down, }; static const char * const tegra210_xusb_padctl_supply_names[] = { From patchwork Wed Apr 15 08:25:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nagarjuna Kristam X-Patchwork-Id: 11490411 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 48BA492C for ; Wed, 15 Apr 2020 08:29:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 275E220768 for ; Wed, 15 Apr 2020 08:29:26 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=nvidia.com header.i=@nvidia.com header.b="F08F4ONV" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2894583AbgDOI3X (ORCPT ); Wed, 15 Apr 2020 04:29:23 -0400 Received: from hqnvemgate26.nvidia.com ([216.228.121.65]:11492 "EHLO hqnvemgate26.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2894445AbgDOI1K (ORCPT ); Wed, 15 Apr 2020 04:27:10 -0400 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate26.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Wed, 15 Apr 2020 01:25:25 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Wed, 15 Apr 2020 01:25:37 -0700 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Wed, 15 Apr 2020 01:25:37 -0700 Received: from HQMAIL109.nvidia.com (172.20.187.15) by HQMAIL111.nvidia.com (172.20.187.18) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Wed, 15 Apr 2020 08:25:37 +0000 Received: from rnnvemgw01.nvidia.com (10.128.109.123) by HQMAIL109.nvidia.com (172.20.187.15) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Wed, 15 Apr 2020 08:25:37 +0000 Received: from nkristam-ubuntu.nvidia.com (Not Verified[10.19.67.128]) by rnnvemgw01.nvidia.com with Trustwave SEG (v7,5,8,10121) id ; Wed, 15 Apr 2020 01:25:36 -0700 From: Nagarjuna Kristam To: , , , , , , CC: , , , , Nagarjuna Kristam Subject: [PATCH V2 5/8] phy: tegra: xusb: Add soc ops API to enable UTMI PAD protection Date: Wed, 15 Apr 2020 13:55:05 +0530 Message-ID: <1586939108-10075-6-git-send-email-nkristam@nvidia.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1586939108-10075-1-git-send-email-nkristam@nvidia.com> References: <1586939108-10075-1-git-send-email-nkristam@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1586939125; bh=3LNQ0SN38gsYKuB1+QCeNLaIcQ/aDK75/NBFEtXfl6c=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:X-NVConfidentiality:MIME-Version: Content-Type; b=F08F4ONVTSzuzGJ5URMWePIEZ4XfIr0iRQAi+srQ5ZyO1x/dbacH43yjqebx6MMzQ 4dTEShih+e7mj8YTnt54ZnGhFwWgzzj/0PvjAPX8M7nF9nN0U8I9HToJ5oUQN0LCm2 gx/RdWUQCEDqHltW8ltNeIdtJgubDACoMtHiW2Y8LLMm8Nu/OtBcc0P06O1Z1930O1 Y0PIrbagh4z1RBxMzxdM3LrxHCtp1GjjyO3lvBPh7W5qqxcOiGvlx2aHSQ3oCvv5b1 DP5Ax/OC1lbPG+Hcvx8A9gnd85iSB2ThBkQ2lJRCTAPxWM+oPnUuXqdJE2Iif8N78Z HgZFnZVeCkclw== Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org When USB charger is enabled, UTMI PAD needs to be protected according to the direction and current level. Add support for the same on Tegra210 and Tegra186. Signed-off-by: Nagarjuna Kristam --- V2: - Commit message coorected. - Patch re-based. --- drivers/phy/tegra/xusb-tegra186.c | 40 +++++++++++++++++++++++++++++++++++++++ drivers/phy/tegra/xusb-tegra210.c | 31 ++++++++++++++++++++++++++++++ drivers/phy/tegra/xusb.h | 13 +++++++++++++ 3 files changed, 84 insertions(+) diff --git a/drivers/phy/tegra/xusb-tegra186.c b/drivers/phy/tegra/xusb-tegra186.c index f862254..03bdb5b 100644 --- a/drivers/phy/tegra/xusb-tegra186.c +++ b/drivers/phy/tegra/xusb-tegra186.c @@ -68,6 +68,13 @@ #define PORTX_SPEED_SUPPORT_MASK (0x3) #define PORT_SPEED_SUPPORT_GEN1 (0x0) +#define USB2_BATTERY_CHRG_OTGPADX_CTL1(x) (0x84 + (x) * 0x40) +#define PD_VREG (1 << 6) +#define VREG_LEV(x) (((x) & 0x3) << 7) +#define VREG_DIR(x) (((x) & 0x3) << 11) +#define VREG_DIR_IN VREG_DIR(1) +#define VREG_DIR_OUT VREG_DIR(2) + #define XUSB_PADCTL_USB2_OTG_PADX_CTL0(x) (0x88 + (x) * 0x40) #define HS_CURR_LEVEL(x) ((x) & 0x3f) #define TERM_SEL BIT(25) @@ -289,6 +296,37 @@ static void tegra_phy_xusb_utmi_pad_power_down(struct phy *phy) usb2->powered_on = false; } +static void tegra186_xusb_padctl_utmi_pad_set_protection_level( + struct tegra_xusb_port *port, int level, + enum tegra_vbus_dir dir) +{ + u32 value; + struct tegra_xusb_padctl *padctl = port->padctl; + unsigned int index = port->index; + + value = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL1(index)); + + if (level < 0) { + /* disable pad protection */ + value |= PD_VREG; + value &= ~VREG_LEV(~0); + value &= ~VREG_DIR(~0); + } else { + if (dir == TEGRA_VBUS_SOURCE) + value |= VREG_DIR_OUT; + else if (dir == TEGRA_VBUS_SINK) + value |= VREG_DIR_IN; + + value &= ~PD_VREG; + value &= ~VREG_DIR(~0); + value &= ~VREG_LEV(~0); + value |= VREG_LEV(level); + } + + padctl_writel(padctl, value, USB2_BATTERY_CHRG_OTGPADX_CTL1(index)); +} + + static int tegra186_xusb_padctl_vbus_override(struct tegra_xusb_padctl *padctl, bool status) { @@ -935,6 +973,8 @@ static const struct tegra_xusb_padctl_ops tegra186_xusb_padctl_ops = { .vbus_override = tegra186_xusb_padctl_vbus_override, .utmi_pad_power_on = tegra_phy_xusb_utmi_pad_power_on, .utmi_pad_power_down = tegra_phy_xusb_utmi_pad_power_down, + .utmi_pad_set_protection_level = + tegra186_xusb_padctl_utmi_pad_set_protection_level, }; #if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC) diff --git a/drivers/phy/tegra/xusb-tegra210.c b/drivers/phy/tegra/xusb-tegra210.c index caf0890..7d84f1a 100644 --- a/drivers/phy/tegra/xusb-tegra210.c +++ b/drivers/phy/tegra/xusb-tegra210.c @@ -74,6 +74,8 @@ #define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_LEV_MASK 0x3 #define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_LEV_VAL 0x1 #define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_FIX18 (1 << 6) +#define USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_LEV(x) (((x) & 0x3) << 7) +#define USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_DIR(x) (((x) & 0x3) << 11) #define XUSB_PADCTL_USB2_OTG_PADX_CTL0(x) (0x088 + (x) * 0x40) #define XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD_ZI (1 << 29) @@ -1116,6 +1118,33 @@ void tegra210_usb2_pad_power_down(struct phy *phy) usb2->powered_on = false; } +static void tegra210_xusb_padctl_utmi_pad_set_protection_level( + struct tegra_xusb_port *port, int level, + enum tegra_vbus_dir dir) +{ + u32 value; + struct tegra_xusb_padctl *padctl = port->padctl; + unsigned int index = port->index; + + value = padctl_readl(padctl, + XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADX_CTL1(index)); + + if (level < 0) { + /* disable pad protection */ + value |= XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_FIX18; + value &= USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_LEV(~0); + value &= ~USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_DIR(~0); + } else { + value &= ~XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_FIX18; + value &= ~USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_DIR(~0); + value &= USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_LEV(~0); + value |= USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_LEV(level); + } + + padctl_writel(padctl, value, + XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADX_CTL1(index)); +} + static int tegra210_usb2_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) { @@ -2291,6 +2320,8 @@ static const struct tegra_xusb_padctl_ops tegra210_xusb_padctl_ops = { .utmi_port_reset = tegra210_utmi_port_reset, .utmi_pad_power_on = tegra210_usb2_pad_power_on, .utmi_pad_power_down = tegra210_usb2_pad_power_down, + .utmi_pad_set_protection_level = + tegra210_xusb_padctl_utmi_pad_set_protection_level, }; static const char * const tegra210_xusb_padctl_supply_names[] = { diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h index 6995fc4..79e96b0 100644 --- a/drivers/phy/tegra/xusb.h +++ b/drivers/phy/tegra/xusb.h @@ -259,6 +259,17 @@ to_sata_pad(struct tegra_xusb_pad *pad) */ struct tegra_xusb_port_ops; +/* + * Tegra OTG port VBUS direction: + * default (based on port capability) or + * as source or sink + */ +enum tegra_vbus_dir { + TEGRA_VBUS_DEFAULT, + TEGRA_VBUS_SOURCE, + TEGRA_VBUS_SINK +}; + struct tegra_xusb_port { struct tegra_xusb_padctl *padctl; struct tegra_xusb_lane *lane; @@ -398,6 +409,8 @@ struct tegra_xusb_padctl_ops { int (*utmi_port_reset)(struct phy *phy); void (*utmi_pad_power_on)(struct phy *phy); void (*utmi_pad_power_down)(struct phy *phy); + void (*utmi_pad_set_protection_level)(struct tegra_xusb_port *port, + int max_ua, enum tegra_vbus_dir dir); }; struct tegra_xusb_padctl_soc { From patchwork Wed Apr 15 08:25:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nagarjuna Kristam X-Patchwork-Id: 11490405 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ABE1F14B4 for ; Wed, 15 Apr 2020 08:29:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8882A206E9 for ; Wed, 15 Apr 2020 08:29:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=nvidia.com header.i=@nvidia.com header.b="o2cG1vCA" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2894558AbgDOI2u (ORCPT ); Wed, 15 Apr 2020 04:28:50 -0400 Received: from hqnvemgate24.nvidia.com ([216.228.121.143]:4454 "EHLO hqnvemgate24.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2894481AbgDOI1K (ORCPT ); Wed, 15 Apr 2020 04:27:10 -0400 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate24.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Wed, 15 Apr 2020 01:23:52 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Wed, 15 Apr 2020 01:25:42 -0700 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Wed, 15 Apr 2020 01:25:42 -0700 Received: from HQMAIL109.nvidia.com (172.20.187.15) by HQMAIL105.nvidia.com (172.20.187.12) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Wed, 15 Apr 2020 08:25:41 +0000 Received: from rnnvemgw01.nvidia.com (10.128.109.123) by HQMAIL109.nvidia.com (172.20.187.15) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Wed, 15 Apr 2020 08:25:41 +0000 Received: from nkristam-ubuntu.nvidia.com (Not Verified[10.19.67.128]) by rnnvemgw01.nvidia.com with Trustwave SEG (v7,5,8,10121) id ; Wed, 15 Apr 2020 01:25:40 -0700 From: Nagarjuna Kristam To: , , , , , , CC: , , , , Nagarjuna Kristam Subject: [PATCH V2 6/8] phy: tegra: xusb: Add support for charger detect Date: Wed, 15 Apr 2020 13:55:06 +0530 Message-ID: <1586939108-10075-7-git-send-email-nkristam@nvidia.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1586939108-10075-1-git-send-email-nkristam@nvidia.com> References: <1586939108-10075-1-git-send-email-nkristam@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1586939032; bh=fzRzTvCVK3zQgga98rvTRBlhCxtbdz/QlhV06FzfVXs=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:X-NVConfidentiality:MIME-Version: Content-Type; b=o2cG1vCACzzkDVZM3rCnujnc/HFiavjyn6qsjNZZHttwwYvng32OZQxuqZdXiTiOZ M/K8KAV2QauqbcB1ymTpCh52Ai4KcG+5c44/aiMpac1YH7F85+UlRapPGPGpEPBu6U xkVllueU/PhNjyi7RKrKoogPYZ7vFsuRHSGCcHhavXgBLmd1Yky+y0vF9PwC9ziLgA iQxfnaWOOQ/wEcRCFqloHVVPGJUqM2i3M5qmIdoHaxu8kNUu/yPRIpxHs6tKeJ+55t i5uZh8I6ertkIziXSLUeA2Wk71bzAo4/lW3C4MpRh+iIBXyInqhCb8N2VGweJOoEjV lUyrgob3Vfxlg== Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Perform charger-detect operation if corresponding dt property is enabled. Update usb-phy with the detected charger state and max current values. Register charger-detect API's of usb-phy to provide needed functionalities. Signed-off-by: Nagarjuna Kristam --- V2: - Patch re-based. --- drivers/phy/tegra/Makefile | 2 +- drivers/phy/tegra/xusb-tegra-cd.c | 300 ++++++++++++++++++++++++++++++++++++++ drivers/phy/tegra/xusb.c | 80 ++++++++++ drivers/phy/tegra/xusb.h | 7 + 4 files changed, 388 insertions(+), 1 deletion(-) create mode 100644 drivers/phy/tegra/xusb-tegra-cd.c diff --git a/drivers/phy/tegra/Makefile b/drivers/phy/tegra/Makefile index 89b8406..25ea9a9 100644 --- a/drivers/phy/tegra/Makefile +++ b/drivers/phy/tegra/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_PHY_TEGRA_XUSB) += phy-tegra-xusb.o -phy-tegra-xusb-y += xusb.o +phy-tegra-xusb-y += xusb.o xusb-tegra-cd.o phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_124_SOC) += xusb-tegra124.o phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_132_SOC) += xusb-tegra124.o phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_210_SOC) += xusb-tegra210.o diff --git a/drivers/phy/tegra/xusb-tegra-cd.c b/drivers/phy/tegra/xusb-tegra-cd.c new file mode 100644 index 0000000..0fafc68 --- /dev/null +++ b/drivers/phy/tegra/xusb-tegra-cd.c @@ -0,0 +1,300 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + */ + +#include +#include +#include +#include + +#include "xusb.h" + +/* Data contact detection timeout */ +#define TDCD_TIMEOUT_MS 400 + +#define USB2_BATTERY_CHRG_OTGPADX_CTL0(x) (0x80 + (x) * 0x40) +#define PD_CHG (1 << 0) +#define VDCD_DET_FILTER_EN (1 << 4) +#define VDAT_DET (1 << 5) +#define VDAT_DET_FILTER_EN (1 << 8) +#define OP_SINK_EN (1 << 9) +#define OP_SRC_EN (1 << 10) +#define ON_SINK_EN (1 << 11) +#define ON_SRC_EN (1 << 12) +#define OP_I_SRC_EN (1 << 13) +#define ZIP_FILTER_EN (1 << 21) +#define ZIN_FILTER_EN (1 << 25) +#define DCD_DETECTED (1 << 26) + +#define USB2_BATTERY_CHRG_OTGPADX_CTL1(x) (0x84 + (x) * 0x40) +#define PD_VREG (1 << 6) +#define VREG_LEV(x) (((x) & 0x3) << 7) +#define VREG_DIR(x) (((x) & 0x3) << 11) +#define VREG_DIR_IN VREG_DIR(1) +#define VREG_DIR_OUT VREG_DIR(2) +#define USBOP_RPD_OVRD (1 << 16) +#define USBOP_RPD_OVRD_VAL (1 << 17) +#define USBOP_RPU_OVRD (1 << 18) +#define USBOP_RPU_OVRD_VAL (1 << 19) +#define USBON_RPD_OVRD (1 << 20) +#define USBON_RPD_OVRD_VAL (1 << 21) +#define USBON_RPU_OVRD (1 << 22) +#define USBON_RPU_OVRD_VAL (1 << 23) + +#define XUSB_PADCTL_USB2_OTG_PADX_CTL0(x) (0x88 + (x) * 0x40) +#define USB2_OTG_PD2 (1 << 27) +#define USB2_OTG_PD2_OVRD_EN (1 << 28) +#define USB2_OTG_PD_ZI (1 << 29) + +#define XUSB_PADCTL_USB2_BATTERY_CHRG_TDCD_DBNC_TIMER_0 (0x280) +#define TDCD_DBNC(x) (((x) & 0x7ff) << 0) + +static void tegra_xusb_padctl_set_debounce_time( + struct tegra_xusb_padctl *padctl, u32 val) +{ + u32 value; + + value = padctl_readl(padctl, + XUSB_PADCTL_USB2_BATTERY_CHRG_TDCD_DBNC_TIMER_0); + value &= ~(TDCD_DBNC(0)); + value |= TDCD_DBNC(val); + padctl_writel(padctl, value, + XUSB_PADCTL_USB2_BATTERY_CHRG_TDCD_DBNC_TIMER_0); +} + +static void tegra_xusb_padctl_utmi_pad_charger_detect_on( + struct tegra_xusb_padctl *padctl, u32 index) +{ + u32 value; + + value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index)); + value &= ~USB2_OTG_PD_ZI; + padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index)); + + value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index)); + value |= (USB2_OTG_PD2 | USB2_OTG_PD2_OVRD_EN); + padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index)); + + value = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + value &= ~PD_CHG; + padctl_writel(padctl, value, USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + + /* Set DP/DN Pull up/down to zero by default */ + value = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL1(index)); + value &= ~(USBOP_RPD_OVRD_VAL | USBOP_RPU_OVRD_VAL | + USBON_RPD_OVRD_VAL | USBON_RPU_OVRD_VAL); + value |= (USBOP_RPD_OVRD | USBOP_RPU_OVRD | + USBON_RPD_OVRD | USBON_RPU_OVRD); + padctl_writel(padctl, value, USB2_BATTERY_CHRG_OTGPADX_CTL1(index)); + + /* Disable DP/DN as src/sink */ + value = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + value &= ~(OP_SRC_EN | ON_SINK_EN | + ON_SRC_EN | OP_SINK_EN); + padctl_writel(padctl, value, USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); +} + +static void tegra_xusb_padctl_utmi_pad_charger_detect_off( + struct tegra_xusb_padctl *padctl, u32 index) +{ + u32 value; + + value = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL1(index)); + value &= ~(USBOP_RPD_OVRD | USBOP_RPU_OVRD | + USBON_RPD_OVRD | USBON_RPU_OVRD); + padctl_writel(padctl, value, USB2_BATTERY_CHRG_OTGPADX_CTL1(index)); + + /* power down necessary stuff */ + value = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + value |= PD_CHG; + padctl_writel(padctl, value, USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + + value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index)); + value &= ~(USB2_OTG_PD2 | USB2_OTG_PD2_OVRD_EN); + padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index)); +} + + +static void tegra_xusb_padctl_detect_filters( + struct tegra_xusb_padctl *padctl, u32 index, + bool on) +{ + u32 value; + + if (on) { + value = padctl_readl(padctl, + USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + value |= (VDCD_DET_FILTER_EN | VDAT_DET_FILTER_EN | + ZIP_FILTER_EN | ZIN_FILTER_EN); + padctl_writel(padctl, value, + USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + } else { + value = padctl_readl(padctl, + USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + value &= ~(VDCD_DET_FILTER_EN | VDAT_DET_FILTER_EN | + ZIP_FILTER_EN | ZIN_FILTER_EN); + padctl_writel(padctl, value, + USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + } +} + +static void tegra_xusb_padctl_utmi_pad_dcd(struct tegra_xusb_padctl *padctl, + u32 index) +{ + u32 value; + int dcd_timeout_ms = 0; + bool ret = false; + + /* Turn on IDP_SRC */ + value = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + value |= OP_I_SRC_EN; + padctl_writel(padctl, value, USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + + /* Turn on D- pull-down resistor */ + value = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL1(index)); + value |= USBON_RPD_OVRD_VAL; + padctl_writel(padctl, value, USB2_BATTERY_CHRG_OTGPADX_CTL1(index)); + + /* Wait for TDCD_DBNC */ + usleep_range(10000, 120000); + + while (dcd_timeout_ms < TDCD_TIMEOUT_MS) { + value = padctl_readl(padctl, + USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + if (value & DCD_DETECTED) { + dev_dbg(padctl->dev, "USB2 port %d DCD successful\n", + index); + ret = true; + break; + } + + usleep_range(20000, 22000); + dcd_timeout_ms += 22; + } + + if (!ret) + dev_info(padctl->dev, "%s: DCD timeout %d ms\n", __func__, + dcd_timeout_ms); + + /* Turn off IP_SRC, clear DCD DETECTED*/ + value = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + value &= ~OP_I_SRC_EN; + value |= DCD_DETECTED; + padctl_writel(padctl, value, USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + + /* Turn off D- pull-down resistor */ + value = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL1(index)); + value &= ~USBON_RPD_OVRD_VAL; + padctl_writel(padctl, value, USB2_BATTERY_CHRG_OTGPADX_CTL1(index)); + + dev_dbg(padctl->dev, "DCD: %d\n", ret); +} + +static bool tegra_xusb_padctl_utmi_pad_primary_charger_detect( + struct tegra_xusb_padctl *padctl, u32 index) +{ + u32 value; + int ret = false; + + /* data contact detection */ + tegra_xusb_padctl_utmi_pad_dcd(padctl, index); + + /* Source D+ to D- */ + value = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + value |= OP_SRC_EN | ON_SINK_EN; + padctl_writel(padctl, value, USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + + /* Wait for TVDPSRC_ON */ + msleep(40); + + value = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + ret = !!(value & VDAT_DET); + + /* Turn off OP_SRC, ON_SINK, clear VDAT, ZIN status change */ + value = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + value &= ~(OP_SRC_EN | ON_SINK_EN); + padctl_writel(padctl, value, USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + + return ret; +} + +static bool tegra_xusb_padctl_utmi_pad_secondary_charger_detect( + struct tegra_xusb_padctl *padctl, u32 index) +{ + u32 value; + bool ret = false; + + /* Source D- to D+ */ + value = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + value |= ON_SRC_EN | OP_SINK_EN; + padctl_writel(padctl, value, USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + + /* Wait for TVDPSRC_ON */ + msleep(40); + + value = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + ret = !(value & VDAT_DET); + + /* Turn off ON_SRC, OP_SINK, clear VDAT, ZIP status change */ + value = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + value &= ~(ON_SRC_EN | OP_SINK_EN); + padctl_writel(padctl, value, USB2_BATTERY_CHRG_OTGPADX_CTL0(index)); + + return ret; +} + +enum usb_charger_type tegra_xusb_padctl_charger_detect( + struct tegra_xusb_port *port) +{ + struct tegra_xusb_padctl *padctl = port->padctl; + struct phy *phy = port->lane->pad->lanes[port->index]; + struct tegra_xusb_usb2_lane *usb2 = to_usb2_lane(port->lane); + u32 index = port->index; + enum usb_charger_type chrg_type; + bool pad_power_off = false; + + mutex_lock(&padctl->lock); + + if (!usb2->powered_on) { + padctl->soc->ops->utmi_pad_power_on(phy); + pad_power_off = true; + } + + tegra_xusb_padctl_utmi_pad_charger_detect_on(padctl, index); + tegra_xusb_padctl_set_debounce_time(padctl, 0xa); + tegra_xusb_padctl_detect_filters(padctl, index, true); + + if (tegra_xusb_padctl_utmi_pad_primary_charger_detect(padctl, + index)) { + /* + * wait 20ms (max of TVDMSRC_DIS) for D- to be disabled + * from host side, before we perform secondary detection. + * Some hosts may not respond well if we do secondary + * detection right after primary detection. + */ + msleep(20); + if (tegra_xusb_padctl_utmi_pad_secondary_charger_detect(padctl, + index)) + chrg_type = CDP_TYPE; + else + chrg_type = DCP_TYPE; + } else { + chrg_type = SDP_TYPE; + } + + dev_dbg(&port->dev, "charger detected of type %d", chrg_type); + + tegra_xusb_padctl_detect_filters(padctl, index, false); + tegra_xusb_padctl_utmi_pad_charger_detect_off(padctl, index); + + if (pad_power_off) + padctl->soc->ops->utmi_pad_power_down(phy); + + mutex_unlock(&padctl->lock); + return chrg_type; +} + +MODULE_AUTHOR("Nagarjuna Kristam "); +MODULE_DESCRIPTION("NVIDIA Tegra186 XUSB charger detect driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c index de4a46f..e505ac4 100644 --- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c @@ -591,6 +591,50 @@ static enum usb_phy_events to_usb_phy_event(enum usb_role role) } } +#define VON_DIV2P0_DET BIT(0) +#define VON_DIV2P7_DET BIT(1) +#define VOP_DIV2P0_DET BIT(2) +#define VOP_DIV2P7_DET BIT(3) + +#define VREG_CUR_LEVEL_0 500 +#define VREG_CUR_LEVEL_1 900 +#define VREG_CUR_LEVEL_2 1500 +#define VREG_CUR_LEVEL_3 2000 + +#define IS_CUR_IN_RANGE(ma, low, high) \ + ((ma >= VREG_CUR_LEVEL_##low) && (ma <= (VREG_CUR_LEVEL_##high - 1))) +#define VREG_LVL(ma, level) IS_CUR_IN_RANGE(ma, level, level + 1) + +static void tegra_xusb_padctl_vbus_pad_portection(struct tegra_xusb_port *port) +{ + struct tegra_xusb_padctl *padctl = port->padctl; + int level = 0; + enum tegra_vbus_dir dir = TEGRA_VBUS_SINK; + int max_ua, min_ua; + + if (!padctl->soc->ops->utmi_pad_set_protection_level) + return; + + usb_phy_get_charger_current(&port->usb_phy, &min_ua, &max_ua); + + if (max_ua == 0) { + level = -1; + dir = TEGRA_VBUS_DEFAULT; + } else if (VREG_LVL(max_ua, 0)) { + level = 0; + } else if (VREG_LVL(max_ua, 1)) { + level = 1; + } else if (VREG_LVL(max_ua, 2)) { + level = 2; + } else if (max_ua >= VREG_CUR_LEVEL_3) { + level = 3; + } else { + return; + } + + padctl->soc->ops->utmi_pad_set_protection_level(port, max_ua, dir); +} + static void tegra_xusb_usb_phy_work(struct work_struct *work) { struct tegra_xusb_port *port = container_of(work, @@ -598,6 +642,10 @@ static void tegra_xusb_usb_phy_work(struct work_struct *work) usb_phy_work); enum usb_role role = usb_role_switch_get_role(port->usb_role_sw); + /* Set role to none, if charger is DCP type */ + if (port->chrg_type == DCP_TYPE) + role = USB_ROLE_NONE; + usb_phy_set_event(&port->usb_phy, to_usb_phy_event(role)); dev_dbg(&port->dev, "%s(): calling notifier for role %s\n", __func__, @@ -610,9 +658,26 @@ static int tegra_xusb_role_sw_set(struct usb_role_switch *sw, enum usb_role role) { struct tegra_xusb_port *port = usb_role_switch_get_drvdata(sw); + enum usb_charger_state charger_state; dev_dbg(&port->dev, "%s(): role %s\n", __func__, usb_roles[role]); + /* Do charger detect if role is Device and charger detect is enabled */ + if (port->charger_detect) { + if (role == USB_ROLE_DEVICE) + port->chrg_type = + tegra_xusb_padctl_charger_detect(port); + else + port->chrg_type = UNKNOWN_TYPE; + + charger_state = (port->chrg_type == UNKNOWN_TYPE) ? + USB_CHARGER_ABSENT : USB_CHARGER_PRESENT; + + usb_phy_set_charger_state(&port->usb_phy, charger_state); + + tegra_xusb_padctl_vbus_pad_portection(port); + } + schedule_work(&port->usb_phy_work); return 0; @@ -643,6 +708,14 @@ static int tegra_xusb_set_host(struct usb_otg *otg, struct usb_bus *host) return 0; } +static enum usb_charger_type tegra_xusb_charger_detect(struct usb_phy *usb_phy) +{ + struct tegra_xusb_port *port = container_of(usb_phy, + struct tegra_xusb_port, + usb_phy); + + return port->chrg_type; +} static int tegra_xusb_setup_usb_role_switch(struct tegra_xusb_port *port) { @@ -693,6 +766,9 @@ static int tegra_xusb_setup_usb_role_switch(struct tegra_xusb_port *port) port->usb_phy.otg->set_peripheral = tegra_xusb_set_peripheral; port->usb_phy.otg->set_host = tegra_xusb_set_host; + if (port->charger_detect) + port->usb_phy.charger_detect = tegra_xusb_charger_detect; + err = usb_add_phy_dev(&port->usb_phy); if (err < 0) { dev_err(&port->dev, "Failed to add USB PHY: %d\n", err); @@ -727,6 +803,10 @@ static int tegra_xusb_usb2_port_parse_dt(struct tegra_xusb_usb2_port *usb2) usb2->mode = USB_DR_MODE_HOST; } + if (port->padctl->soc->charger_detect && + of_property_read_bool(np, "nvidia,charger-detect")) + port->charger_detect = true; + /* usb-role-switch property is mandatory for OTG/Peripheral modes */ if (usb2->mode == USB_DR_MODE_PERIPHERAL || usb2->mode == USB_DR_MODE_OTG) { diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h index 79e96b0..714bca2 100644 --- a/drivers/phy/tegra/xusb.h +++ b/drivers/phy/tegra/xusb.h @@ -282,6 +282,9 @@ struct tegra_xusb_port { struct work_struct usb_phy_work; struct usb_phy usb_phy; + bool charger_detect; + enum usb_charger_type chrg_type; + const struct tegra_xusb_port_ops *ops; }; @@ -306,6 +309,9 @@ struct tegra_xusb_port * tegra_xusb_find_port(struct tegra_xusb_padctl *padctl, const char *type, unsigned int index); +enum usb_charger_type tegra_xusb_padctl_charger_detect( + struct tegra_xusb_port *port); + struct tegra_xusb_usb2_port { struct tegra_xusb_port base; @@ -430,6 +436,7 @@ struct tegra_xusb_padctl_soc { unsigned int num_supplies; bool supports_gen2; bool need_fake_usb3_port; + bool charger_detect; }; struct tegra_xusb_padctl { From patchwork Wed Apr 15 08:25:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nagarjuna Kristam X-Patchwork-Id: 11490403 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0A3E792C for ; Wed, 15 Apr 2020 08:28:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E5D4820775 for ; Wed, 15 Apr 2020 08:28:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=nvidia.com header.i=@nvidia.com header.b="mk01WjuZ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2894480AbgDOI2d (ORCPT ); Wed, 15 Apr 2020 04:28:33 -0400 Received: from hqnvemgate24.nvidia.com ([216.228.121.143]:4463 "EHLO hqnvemgate24.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2894488AbgDOI1K (ORCPT ); Wed, 15 Apr 2020 04:27:10 -0400 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate24.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Wed, 15 Apr 2020 01:23:56 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Wed, 15 Apr 2020 01:25:45 -0700 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Wed, 15 Apr 2020 01:25:45 -0700 Received: from HQMAIL111.nvidia.com (172.20.187.18) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Wed, 15 Apr 2020 08:25:45 +0000 Received: from rnnvemgw01.nvidia.com (10.128.109.123) by HQMAIL111.nvidia.com (172.20.187.18) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Wed, 15 Apr 2020 08:25:45 +0000 Received: from nkristam-ubuntu.nvidia.com (Not Verified[10.19.67.128]) by rnnvemgw01.nvidia.com with Trustwave SEG (v7,5,8,10121) id ; Wed, 15 Apr 2020 01:25:44 -0700 From: Nagarjuna Kristam To: , , , , , , CC: , , , , Nagarjuna Kristam Subject: [PATCH V2 7/8] phy: tegra: xusb: Enable charger detect for Tegra186 Date: Wed, 15 Apr 2020 13:55:07 +0530 Message-ID: <1586939108-10075-8-git-send-email-nkristam@nvidia.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1586939108-10075-1-git-send-email-nkristam@nvidia.com> References: <1586939108-10075-1-git-send-email-nkristam@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1586939036; bh=NFF4rNyK1bxZi46MjrBDC+rV9hWDW87mBhP0TbbGgTA=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:X-NVConfidentiality:MIME-Version: Content-Type; b=mk01WjuZWgabl8Wy/fkvjv+ayfW5bgYmcF+pYBmsNhgjaa+VOyrFXHUbz6BQHacU5 tzif5yOp2K6WtRLenXrgyZIm4vftNJsgZ6fU2BFH3iHt40t+f8AiBa/6EATEQRD+/T OKn8qpNxCv1J1rDD2x5G5TnE5XUa/mnMPiDG46THt1bGSGYpSmjHrNZO5WgGwl3P/e 0e6lKj7TXyM9+x/x4FDNZ3AIpY3rBEbN2GfHdA0dizbsqYmBvgr6yLpdt/T0ugcwyX vF4SP36dyi8GBbdFLVdklbN2+2qAvirR693fijsaJ0f/jQJlxeOOkb1WQvpaktXZD6 13zQ5COLtk36Q== Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Tegra186 SoC supports charger detect, set corresponding soc flag. Signed-off-by: Nagarjuna Kristam Acked-by: Thierry Reding --- V2: - Patch re-based. --- drivers/phy/tegra/xusb-tegra186.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/phy/tegra/xusb-tegra186.c b/drivers/phy/tegra/xusb-tegra186.c index 03bdb5b..12ff492 100644 --- a/drivers/phy/tegra/xusb-tegra186.c +++ b/drivers/phy/tegra/xusb-tegra186.c @@ -1041,6 +1041,7 @@ const struct tegra_xusb_padctl_soc tegra186_xusb_padctl_soc = { .ops = &tegra186_xusb_padctl_ops, .supply_names = tegra186_xusb_padctl_supply_names, .num_supplies = ARRAY_SIZE(tegra186_xusb_padctl_supply_names), + .charger_detect = true, }; EXPORT_SYMBOL_GPL(tegra186_xusb_padctl_soc); #endif From patchwork Wed Apr 15 08:25:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nagarjuna Kristam X-Patchwork-Id: 11490395 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C6D8014B4 for ; Wed, 15 Apr 2020 08:27:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A277D2078A for ; Wed, 15 Apr 2020 08:27:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=nvidia.com header.i=@nvidia.com header.b="k8fQPFJ1" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2894508AbgDOI1Y (ORCPT ); Wed, 15 Apr 2020 04:27:24 -0400 Received: from hqnvemgate24.nvidia.com ([216.228.121.143]:4522 "EHLO hqnvemgate24.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2894455AbgDOI1R (ORCPT ); Wed, 15 Apr 2020 04:27:17 -0400 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate24.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Wed, 15 Apr 2020 01:24:00 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Wed, 15 Apr 2020 01:25:49 -0700 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Wed, 15 Apr 2020 01:25:49 -0700 Received: from HQMAIL109.nvidia.com (172.20.187.15) by HQMAIL105.nvidia.com (172.20.187.12) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Wed, 15 Apr 2020 08:25:49 +0000 Received: from rnnvemgw01.nvidia.com (10.128.109.123) by HQMAIL109.nvidia.com (172.20.187.15) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Wed, 15 Apr 2020 08:25:48 +0000 Received: from nkristam-ubuntu.nvidia.com (Not Verified[10.19.67.128]) by rnnvemgw01.nvidia.com with Trustwave SEG (v7,5,8,10121) id ; Wed, 15 Apr 2020 01:25:48 -0700 From: Nagarjuna Kristam To: , , , , , , CC: , , , , Nagarjuna Kristam Subject: [PATCH V2 8/8] phy: tegra: xusb: Enable charger detect for Tegra210 Date: Wed, 15 Apr 2020 13:55:08 +0530 Message-ID: <1586939108-10075-9-git-send-email-nkristam@nvidia.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1586939108-10075-1-git-send-email-nkristam@nvidia.com> References: <1586939108-10075-1-git-send-email-nkristam@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1586939040; bh=055RAzmaGHUjBmQF8JPysR26eaww2SCbnUqbBC+ZFk4=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:X-NVConfidentiality:MIME-Version: Content-Type; b=k8fQPFJ192XnwKkG4g9GVom7Z04W0MGP1M9gcjdJGRYEEIMkcAhs5WcelJNpK2QWQ dMYVctTvIAq2wvH3ck9xdxgX2S7ekzH1iaq2NNH2gr0RKbUNFvsawkzThv69Mh3Rcq VuGlhccCLB7dHhz4JxNLQDi73iwBsDPLnE04aojmyD2MqB27BnZtzj/vv7SiqDJx19 lEU8a3la3weiHi3xDEevptnouoODmOn/Ufd1DUjKNktJmHK10QUAKMBMf3Pi7DhrXk 6CkkPtNLZLNt6P0c4k2maXC2P2AIrq09Wplv0wUUDXN888E2s7SD6XT20REbNI80rd jJM3YP8Y/PUaQ== Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Tegra210 SoC supports charger detect, set corresponding soc flag. Signed-off-by: Nagarjuna Kristam Acked-by: Thierry Reding --- V2: - Patch re-based. --- drivers/phy/tegra/xusb-tegra210.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/phy/tegra/xusb-tegra210.c b/drivers/phy/tegra/xusb-tegra210.c index 7d84f1a..2be5201 100644 --- a/drivers/phy/tegra/xusb-tegra210.c +++ b/drivers/phy/tegra/xusb-tegra210.c @@ -2352,6 +2352,7 @@ const struct tegra_xusb_padctl_soc tegra210_xusb_padctl_soc = { .supply_names = tegra210_xusb_padctl_supply_names, .num_supplies = ARRAY_SIZE(tegra210_xusb_padctl_supply_names), .need_fake_usb3_port = true, + .charger_detect = true, }; EXPORT_SYMBOL_GPL(tegra210_xusb_padctl_soc);