Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp147076pxk; Wed, 9 Sep 2020 01:14:45 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxgBAWvuAuMi2ph9mmdCwq5qxU6WlhLPWpjx/GCJjtnmKtD/ieAjaI8uKHu8UrbVUMRYBac X-Received: by 2002:aa7:db02:: with SMTP id t2mr2859346eds.95.1599639284906; Wed, 09 Sep 2020 01:14:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1599639284; cv=none; d=google.com; s=arc-20160816; b=KDt+re6ztSIqIfoZDxIy2wlD814jN6+ZUCE8PUSRsyQgi/eIpRmV5SEVMSAeu1Hscu 7ozBsXM7Hy6N0ADlu9EvZPr6eXxf3n/iELp3+hY30U2w5ckTSinPiKZtoHn03kVMGweS +GzK049IDEOoQ4vqe0T3NG2bUWZZzNan7Jmjugn/wl2kj+mkY5KQOmE/XFe0CKhgYuQw oFPZPy990iqmuamF7S1ISPfevdthuAx6A6XMtDmJnxqX/finr4VCH+IuKJ6FfbrI7HqT kgW3n/5kUOKEWDM1L74SE0Qma7QvRW1iKV7uTz/vndPtdYoKbF9aZwmBQb2iw6U4ZvWX 5RPw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:dkim-signature:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from; bh=Le6GPCD6TsgFhwY1LsvLU20GkvLiIMjdvSiShSWj/Rk=; b=LlfWKLD+ZMYw1uzfgfrKrFUHn4RG8hAFksyOMSoeGTyjQ/2XYNBBuUJ7f5aT2N5alV jBCpJ6WHMxlvmA8sUNJXRKCQQJ9ut7s5e3zxr785mA3rz/uO208roLS/wk62kBnHYrbD LSZryQlpc4TgrSDEvgQsJWnQ9aRvFlHM2miQB/R9Oh1AydYY+DHmhZOVyVGKytw4FEDG HYt/A+nMEGkx4p6xWUGq3Wn0zPMLw2saROz76nJsFvnjpqWQNICb/eTXKQ4tqzL7QNH7 P5PUhEefM8NlUaU4rs5IYTT2Bd8w3TjrCV3LYEccsUEgced0/kQflO641XHoIIGKrgqk Uf0Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@nvidia.com header.s=n1 header.b="MP0l/Rx/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=nvidia.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id qx7si1000425ejb.438.2020.09.09.01.14.21; Wed, 09 Sep 2020 01:14:44 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@nvidia.com header.s=n1 header.b="MP0l/Rx/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=nvidia.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730310AbgIIINi (ORCPT + 99 others); Wed, 9 Sep 2020 04:13:38 -0400 Received: from hqnvemgate26.nvidia.com ([216.228.121.65]:12024 "EHLO hqnvemgate26.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726005AbgIIILD (ORCPT ); Wed, 9 Sep 2020 04:11:03 -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, 09 Sep 2020 01:10:50 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Wed, 09 Sep 2020 01:11:03 -0700 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Wed, 09 Sep 2020 01:11:03 -0700 Received: from HQMAIL105.nvidia.com (172.20.187.12) by HQMAIL101.nvidia.com (172.20.187.10) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Wed, 9 Sep 2020 08:10:59 +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, 9 Sep 2020 08:10:59 +0000 Received: from jckuo-lt.nvidia.com (Not Verified[10.19.100.126]) by rnnvemgw01.nvidia.com with Trustwave SEG (v7,5,8,10121) id ; Wed, 09 Sep 2020 01:10:58 -0700 From: JC Kuo To: , , , , CC: , , , , , JC Kuo Subject: [PATCH v3 06/15] phy: tegra: xusb: Add Tegra210 lane_iddq operation Date: Wed, 9 Sep 2020 16:10:32 +0800 Message-ID: <20200909081041.3190157-7-jckuo@nvidia.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200909081041.3190157-1-jckuo@nvidia.com> References: <20200909081041.3190157-1-jckuo@nvidia.com> MIME-Version: 1.0 X-NVConfidentiality: public Content-Transfer-Encoding: quoted-printable Content-Type: text/plain DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1599639050; bh=Le6GPCD6TsgFhwY1LsvLU20GkvLiIMjdvSiShSWj/Rk=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:MIME-Version:X-NVConfidentiality: Content-Transfer-Encoding:Content-Type; b=MP0l/Rx/TVWZ6+uNgEn0ZOrXp6CGRnR08qEVUmW+AikxMX9nkC1TDq6kyMC4Ni3RJ XZCDM9DLWEwGI9aGHjgp1VsEI8JbbeNmguWe9D+MHYPWD3fiL2rkj0/4shoFByfpBr KQL2VjK0norR48ZP3UjPyva5MxQ6NF9jMqnKYBz+EJ+riK3VocH6apW3LgNSVHvVTq vyQ90Qww/3yDdOBVjMHo6wN8eyQr4M53UMU40v/+SlqY8db9UJHXPNy0MUYWvisHlW C3n2eygVQE0wKr+jjDTjcUCiaKDxstmkW13jD2womHn1540nTR7v+qXi1m9H8gZCZ+ POunFmcoxw65w== Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org As per Tegra210 TRM, before changing lane assignments, driver should keep lanes in IDDQ and sleep state; after changing lane assignments, driver should bring lanes out of IDDQ. This commit implements the required operations. Signed-off-by: JC Kuo --- v3: add 'misc_ctl2' data member to UPHY lane for carrying MISC_PAD_PX_CTL2 o= ffset tegra210_uphy_lane_iddq_[enable/disable]() to access 'misc_ctl2' data me= mber =20 drivers/phy/tegra/xusb-tegra210.c | 82 ++++++++++++++++++++++++++++--- drivers/phy/tegra/xusb.c | 6 +++ drivers/phy/tegra/xusb.h | 6 +++ 3 files changed, 86 insertions(+), 8 deletions(-) diff --git a/drivers/phy/tegra/xusb-tegra210.c b/drivers/phy/tegra/xusb-teg= ra210.c index b3f065ef92e6..ff5dbc4818b0 100644 --- a/drivers/phy/tegra/xusb-tegra210.c +++ b/drivers/phy/tegra/xusb-tegra210.c @@ -198,6 +198,18 @@ #define XUSB_PADCTL_UPHY_MISC_PAD_CTL1_AUX_RX_TERM_EN BIT(18) #define XUSB_PADCTL_UPHY_MISC_PAD_CTL1_AUX_RX_MODE_OVRD BIT(13) =20 +#define XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(x) (0x464 + (x) * 0x40) +#define XUSB_PADCTL_UPHY_MISC_PAD_CTL2_TX_IDDQ BIT(0) +#define XUSB_PADCTL_UPHY_MISC_PAD_CTL2_TX_IDDQ_OVRD BIT(1) +#define XUSB_PADCTL_UPHY_MISC_PAD_CTL2_TX_SLEEP_MASK (0x3 << 4) +#define XUSB_PADCTL_UPHY_MISC_PAD_CTL2_TX_SLEEP_VAL (0x3 << 4) +#define XUSB_PADCTL_UPHY_MISC_PAD_CTL2_TX_PWR_OVRD BIT(24) +#define XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_IDDQ BIT(8) +#define XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_IDDQ_OVRD BIT(9) +#define XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_SLEEP_MASK (0x3 << 12) +#define XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_SLEEP_VAL (0x3 << 12) +#define XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_PWR_OVRD BIT(25) + #define XUSB_PADCTL_UPHY_PLL_S0_CTL1 0x860 =20 #define XUSB_PADCTL_UPHY_PLL_S0_CTL2 0x864 @@ -209,6 +221,7 @@ #define XUSB_PADCTL_UPHY_PLL_S0_CTL8 0x87c =20 #define XUSB_PADCTL_UPHY_MISC_PAD_S0_CTL1 0x960 +#define XUSB_PADCTL_UPHY_MISC_PAD_S0_CTL2 0x964 =20 #define XUSB_PADCTL_UPHY_USB3_PADX_ECTL1(x) (0xa60 + (x) * 0x40) #define XUSB_PADCTL_UPHY_USB3_PAD_ECTL1_TX_TERM_CTRL_SHIFT 16 @@ -1640,6 +1653,55 @@ static const struct tegra_xusb_pad_soc tegra210_hsic= _pad =3D { .ops =3D &tegra210_hsic_ops, }; =20 +static void tegra210_uphy_lane_iddq_enable(struct tegra_xusb_lane *lane) +{ + struct tegra_xusb_padctl *padctl =3D lane->pad->padctl; + u32 value; + + value =3D padctl_readl(padctl, lane->soc->regs.misc_ctl2); + value |=3D XUSB_PADCTL_UPHY_MISC_PAD_CTL2_TX_IDDQ_OVRD; + value |=3D XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_IDDQ_OVRD; + value |=3D XUSB_PADCTL_UPHY_MISC_PAD_CTL2_TX_PWR_OVRD; + value |=3D XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_PWR_OVRD; + value |=3D XUSB_PADCTL_UPHY_MISC_PAD_CTL2_TX_IDDQ; + value &=3D ~XUSB_PADCTL_UPHY_MISC_PAD_CTL2_TX_SLEEP_MASK; + value |=3D XUSB_PADCTL_UPHY_MISC_PAD_CTL2_TX_SLEEP_VAL; + value |=3D XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_IDDQ; + value &=3D ~XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_SLEEP_MASK; + value |=3D XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_SLEEP_VAL; + padctl_writel(padctl, value, lane->soc->regs.misc_ctl2); +} + +static void tegra210_uphy_lane_iddq_disable(struct tegra_xusb_lane *lane) +{ + struct tegra_xusb_padctl *padctl =3D lane->pad->padctl; + u32 value; + + value =3D padctl_readl(padctl, lane->soc->regs.misc_ctl2); + value &=3D ~XUSB_PADCTL_UPHY_MISC_PAD_CTL2_TX_IDDQ_OVRD; + value &=3D ~XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_IDDQ_OVRD; + value &=3D ~XUSB_PADCTL_UPHY_MISC_PAD_CTL2_TX_PWR_OVRD; + value &=3D ~XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_PWR_OVRD; + value |=3D XUSB_PADCTL_UPHY_MISC_PAD_CTL2_TX_IDDQ; + value &=3D ~XUSB_PADCTL_UPHY_MISC_PAD_CTL2_TX_SLEEP_MASK; + value |=3D XUSB_PADCTL_UPHY_MISC_PAD_CTL2_TX_SLEEP_VAL; + value |=3D XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_IDDQ; + value &=3D ~XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_SLEEP_MASK; + value |=3D XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_SLEEP_VAL; + padctl_writel(padctl, value, lane->soc->regs.misc_ctl2); +} + +#define TEGRA210_UPHY_LANE(_name, _offset, _shift, _mask, _type, _misc) \ + { \ + .name =3D _name, \ + .offset =3D _offset, \ + .shift =3D _shift, \ + .mask =3D _mask, \ + .num_funcs =3D ARRAY_SIZE(tegra210_##_type##_functions), \ + .funcs =3D tegra210_##_type##_functions, \ + .regs.misc_ctl2 =3D _misc, \ + } + static const char *tegra210_pcie_functions[] =3D { "pcie-x1", "usb3-ss", @@ -1648,13 +1710,13 @@ static const char *tegra210_pcie_functions[] =3D { }; =20 static const struct tegra_xusb_lane_soc tegra210_pcie_lanes[] =3D { - TEGRA210_LANE("pcie-0", 0x028, 12, 0x3, pcie), - TEGRA210_LANE("pcie-1", 0x028, 14, 0x3, pcie), - TEGRA210_LANE("pcie-2", 0x028, 16, 0x3, pcie), - TEGRA210_LANE("pcie-3", 0x028, 18, 0x3, pcie), - TEGRA210_LANE("pcie-4", 0x028, 20, 0x3, pcie), - TEGRA210_LANE("pcie-5", 0x028, 22, 0x3, pcie), - TEGRA210_LANE("pcie-6", 0x028, 24, 0x3, pcie), + TEGRA210_UPHY_LANE("pcie-0", 0x028, 12, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_= PAD_PX_CTL2(0)), + TEGRA210_UPHY_LANE("pcie-1", 0x028, 14, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_= PAD_PX_CTL2(1)), + TEGRA210_UPHY_LANE("pcie-2", 0x028, 16, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_= PAD_PX_CTL2(2)), + TEGRA210_UPHY_LANE("pcie-3", 0x028, 18, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_= PAD_PX_CTL2(3)), + TEGRA210_UPHY_LANE("pcie-4", 0x028, 20, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_= PAD_PX_CTL2(4)), + TEGRA210_UPHY_LANE("pcie-5", 0x028, 22, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_= PAD_PX_CTL2(5)), + TEGRA210_UPHY_LANE("pcie-6", 0x028, 24, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_= PAD_PX_CTL2(6)), }; =20 static struct tegra_xusb_usb3_port * @@ -1815,6 +1877,8 @@ static void tegra210_pcie_lane_remove(struct tegra_xu= sb_lane *lane) static const struct tegra_xusb_lane_ops tegra210_pcie_lane_ops =3D { .probe =3D tegra210_pcie_lane_probe, .remove =3D tegra210_pcie_lane_remove, + .iddq_enable =3D tegra210_uphy_lane_iddq_enable, + .iddq_disable =3D tegra210_uphy_lane_iddq_disable, }; =20 static int tegra210_pcie_phy_init(struct phy *phy) @@ -1939,7 +2003,7 @@ static const struct tegra_xusb_pad_soc tegra210_pcie_= pad =3D { }; =20 static const struct tegra_xusb_lane_soc tegra210_sata_lanes[] =3D { - TEGRA210_LANE("sata-0", 0x028, 30, 0x3, pcie), + TEGRA210_UPHY_LANE("sata-0", 0x028, 30, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_= PAD_S0_CTL2), }; =20 static struct tegra_xusb_lane * @@ -1978,6 +2042,8 @@ static void tegra210_sata_lane_remove(struct tegra_xu= sb_lane *lane) static const struct tegra_xusb_lane_ops tegra210_sata_lane_ops =3D { .probe =3D tegra210_sata_lane_probe, .remove =3D tegra210_sata_lane_remove, + .iddq_enable =3D tegra210_uphy_lane_iddq_enable, + .iddq_disable =3D tegra210_uphy_lane_iddq_disable, }; =20 static int tegra210_sata_phy_init(struct phy *phy) diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c index b48b590aa0c1..b92478a350df 100644 --- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c @@ -321,11 +321,17 @@ static void tegra_xusb_lane_program(struct tegra_xusb= _lane *lane) if (soc->num_funcs < 2) return; =20 + if (lane->pad->ops->iddq_enable) + lane->pad->ops->iddq_enable(lane); + /* choose function */ value =3D padctl_readl(padctl, soc->offset); value &=3D ~(soc->mask << soc->shift); value |=3D lane->function << soc->shift; padctl_writel(padctl, value, soc->offset); + + if (lane->pad->ops->iddq_disable) + lane->pad->ops->iddq_disable(lane); } =20 static void tegra_xusb_pad_program(struct tegra_xusb_pad *pad) diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h index 0c828694cf2d..9463bc74729e 100644 --- a/drivers/phy/tegra/xusb.h +++ b/drivers/phy/tegra/xusb.h @@ -35,6 +35,10 @@ struct tegra_xusb_lane_soc { =20 const char * const *funcs; unsigned int num_funcs; + + struct { + unsigned int misc_ctl2; + } regs; }; =20 struct tegra_xusb_lane { @@ -126,6 +130,8 @@ struct tegra_xusb_lane_ops { struct device_node *np, unsigned int index); void (*remove)(struct tegra_xusb_lane *lane); + void (*iddq_enable)(struct tegra_xusb_lane *lane); + void (*iddq_disable)(struct tegra_xusb_lane *lane); }; =20 bool tegra_xusb_lane_check(struct tegra_xusb_lane *lane, const char *funct= ion); --=20 2.25.1