From 985ee23eb4613f8ccc5637606214ede42165cf9a Mon Sep 17 00:00:00 2001 From: Shreshtha SAHU Date: Tue, 29 Mar 2016 17:19:30 +0530 Subject: [PATCH] arm64: remove t186 related files Delete following files: ./drivers/pinctrl/pinctrl-tegra186-padctl-uphy.c ./arch/arm64/boot/dts/tegra186-fpga-cl34563539.dts ./arch/arm64/boot/dts/tegra186-sim-cl34563539.dts ./arch/arm64/boot/dts/tegra186-fpga-cl34324618.dts ./arch/arm64/boot/dts/tegra186-sim-cl34324618.dts ./include/dt-bindings/memory/tegra186-swgroup.h Bug 1748166 Change-Id: Ide593c7188c35e597e9c8efc94a8eab44a9bad57 Signed-off-by: Shreshtha SAHU Reviewed-on: http://git-master/r/1116938 (cherry picked from commit 1d77354b43cbe89d069995c15326abd1b9c5ff45) Reviewed-on: http://git-master/r/1119900 --- arch/arm64/boot/dts/Makefile | 4 - .../boot/dts/tegra186-fpga-cl34324618.dts | 35 - .../boot/dts/tegra186-fpga-cl34563539.dts | 35 - .../boot/dts/tegra186-sim-cl34324618.dts | 31 - .../boot/dts/tegra186-sim-cl34563539.dts | 31 - drivers/pinctrl/Makefile | 1 - .../pinctrl/pinctrl-tegra186-padctl-uphy.c | 3438 ----------------- include/dt-bindings/memory/tegra186-swgroup.h | 1 - 8 files changed, 3576 deletions(-) delete mode 100644 arch/arm64/boot/dts/tegra186-fpga-cl34324618.dts delete mode 100644 arch/arm64/boot/dts/tegra186-fpga-cl34563539.dts delete mode 100644 arch/arm64/boot/dts/tegra186-sim-cl34324618.dts delete mode 100644 arch/arm64/boot/dts/tegra186-sim-cl34563539.dts delete mode 100644 drivers/pinctrl/pinctrl-tegra186-padctl-uphy.c delete mode 120000 include/dt-bindings/memory/tegra186-swgroup.h diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile index 6e3fb7125d1..a26e53a0b17 100644 --- a/arch/arm64/boot/dts/Makefile +++ b/arch/arm64/boot/dts/Makefile @@ -117,10 +117,6 @@ dtb-$(CONFIG_ARCH_TEGRA_21x_SOC) += tegra210-hawkeye-p2290-2306-a05-00-wifi.dtb dtb-$(CONFIG_ARCH_TEGRA_21x_SOC) += tegra210-hawkeye-p2290-2307-a05-00-wifi.dtb dtb-$(CONFIG_ARCH_TEGRA_21x_SOC) += tegra210-p4573-2180.dtb dtb-$(CONFIG_ARCH_TEGRA_21x_SOC) += tegra210-jetson-cv-p2597-2180-a00-imx274.dtb -dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-sim-cl34324618.dtb -dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-fpga-cl34324618.dtb -dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-fpga-cl34563539.dtb -dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-sim-cl34563539.dtb targets += $(dtb-y) DTC_FLAGS := -i $(srctree)/arch/arm/boot/dts diff --git a/arch/arm64/boot/dts/tegra186-fpga-cl34324618.dts b/arch/arm64/boot/dts/tegra186-fpga-cl34324618.dts deleted file mode 100644 index 69b27244ddd..00000000000 --- a/arch/arm64/boot/dts/tegra186-fpga-cl34324618.dts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * arch/arm64/boot/dts/tegra186-fpga-cl34324618.dts - * - * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. - * - * 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 - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* - * DISCLAIMER: THIS FILE IS AUTO GENERATED. DO NOT MANUALLY EDIT THIS FILE!!! - */ - - -#include "tegra186-sim-private.dts" -#include "tegra186-sim-cl34324618-private.dtsi" -#include "tegra186-pinmux-fpga.dtsi" -#include "tegra186-fpga-fixed.dtsi" -#include "tegra186-fpga-cl34324618-private.dtsi" - -/ { - /* chosen */ -}; - diff --git a/arch/arm64/boot/dts/tegra186-fpga-cl34563539.dts b/arch/arm64/boot/dts/tegra186-fpga-cl34563539.dts deleted file mode 100644 index 0d1e1d4d948..00000000000 --- a/arch/arm64/boot/dts/tegra186-fpga-cl34563539.dts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * arch/arm64/boot/dts/tegra186-fpga-cl34563539.dts - * - * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. - * - * 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 - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* - * DISCLAIMER: THIS FILE IS AUTO GENERATED. DO NOT MANUALLY EDIT THIS FILE!!! - */ - - -#include "tegra186-sim-private.dts" -#include "tegra186-sim-cl34563539-private.dtsi" -#include "tegra186-pinmux-fpga.dtsi" -#include "tegra186-fpga-fixed.dtsi" -#include "tegra186-fpga-cl34563539-private.dtsi" - -/ { - /* chosen */ -}; - diff --git a/arch/arm64/boot/dts/tegra186-sim-cl34324618.dts b/arch/arm64/boot/dts/tegra186-sim-cl34324618.dts deleted file mode 100644 index b070f6f3362..00000000000 --- a/arch/arm64/boot/dts/tegra186-sim-cl34324618.dts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * arch/arm64/boot/dts/tegra186-sim-cl34324618.dts - * - * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. - * - * 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 - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* - * DISCLAIMER: THIS FILE IS AUTO GENERATED. DO NOT MANUALLY EDIT THIS FILE!!! - */ - - -#include "tegra186-sim-private.dts" -#include "tegra186-sim-cl34324618-private.dtsi" - -/ { - /* chosen */ -}; diff --git a/arch/arm64/boot/dts/tegra186-sim-cl34563539.dts b/arch/arm64/boot/dts/tegra186-sim-cl34563539.dts deleted file mode 100644 index 2e02b57eb9f..00000000000 --- a/arch/arm64/boot/dts/tegra186-sim-cl34563539.dts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * arch/arm64/boot/dts/tegra186-sim-cl34563539.dts - * - * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. - * - * 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 - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* - * DISCLAIMER: THIS FILE IS AUTO GENERATED. DO NOT MANUALLY EDIT THIS FILE!!! - */ - - -#include "tegra186-sim-private.dts" -#include "tegra186-sim-cl34563539-private.dtsi" - -/ { - /* chosen */ -}; diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 7bb47c334d0..864ef2d410e 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -55,7 +55,6 @@ obj-$(CONFIG_PINCTRL_MAX77660) += pinctrl-max77660.o obj-$(CONFIG_PINCTRL_MAX77620) += pinctrl-max77620.o obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o -obj-y += pinctrl-tegra186-padctl-uphy.o obj-$(CONFIG_PLAT_ORION) += mvebu/ obj-$(CONFIG_ARCH_SHMOBILE) += sh-pfc/ diff --git a/drivers/pinctrl/pinctrl-tegra186-padctl-uphy.c b/drivers/pinctrl/pinctrl-tegra186-padctl-uphy.c deleted file mode 100644 index b444cc93706..00000000000 --- a/drivers/pinctrl/pinctrl-tegra186-padctl-uphy.c +++ /dev/null @@ -1,3438 +0,0 @@ -/* - * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TEGRA_XUSB_PCIE_PHYS 1 -#define TEGRA_XUSB_SATA_PHYS 1 -#define TEGRA_XUSB_UFS_PHYS 1 -#define TEGRA_XUSB_USB3_PHYS 3 -#define TEGRA_XUSB_UTMI_PHYS 3 -#define TEGRA_XUSB_HSIC_PHYS 1 -#define TEGRA_XUSB_NUM_USB_PHYS (TEGRA_XUSB_USB3_PHYS + TEGRA_XUSB_UTMI_PHYS + \ - TEGRA_XUSB_HSIC_PHYS) -#define TEGRA_XUSB_NUM_PHYS (TEGRA_XUSB_NUM_USB_PHYS + TEGRA_XUSB_PCIE_PHYS + \ - TEGRA_XUSB_SATA_PHYS + TEGRA_XUSB_UFS_PHYS) - -#include -#include "../../../arch/arm/mach-tegra/iomap.h" /* FIXME */ - -#ifdef TRACE -#undef TRACE -#endif -#define TRACE(fmt, args...) pr_info("%s %d " fmt "\n", __func__, __LINE__, ## args) - -#ifdef TRACE_DEV -#undef TRACE_DEV -#endif -#define TRACE_DEV(dev, fmt, args...) dev_info(dev, "%s %d " fmt "\n", __func__, __LINE__, ## args) - -#include "core.h" -#include "pinctrl-utils.h" - -#define T186_UPHY_LANES (6) - -/* UPHY PLL registers */ -#define UPHY_PLL_CTL_1 (0x0) -#define PLL_IDDQ (1 << 0) -#define PLL_SLEEP(x) (((x) & 0x3) << 1) -#define PLL_ENABLE (1 << 3) -#define PWR_OVRD (1 << 4) -#define RATE_ID(x) (((x) & 0x3) << 8) -#define RATE_ID_OVRD (1 << 11) -#define LOCKDET_STATUS (1 << 15) - -#define UPHY_PLL_CTL_2 (0x4) -#define CAL_EN (1 << 0) -#define CAL_DONE (1 << 1) -#define CAL_OVRD (1 << 2) -#define CAL_RESET (1 << 3) -#define RCAL_EN (1 << 12) -#define RCAL_CLK_EN (1 << 13) -#define RCAL_OVRD (1 << 15) -#define RCAL_DONE (1 << 31) - -#define UPHY_PLL_CTL_4 (0xc) - -/* UPHY Lane registers */ -#define UPHY_LANE_AUX_CTL_1 (0x0) -#define AUX_RX_IDLE_TH(x) (((x) & 0x3) << 24) - -#define UPHY_LANE_DIRECT_CTL_1 (0x10) -#define MISC_CTRL(x) (((x) & 0xff) << 0) -#define MISC_OUT(x) (((x) & 0xff) << 16) - -#define UPHY_LANE_DIRECT_CTL_2 (0x14) -#define CFG_WDATA(x) (((x) & 0xffff) << 0) -#define CFG_ADDR(x) (((x) & 0xff) << 16) -#define CFG_WDS(x) (((x) & 0x1) << 24) -#define CFG_RDS(x) (((x) & 0x1) << 25) -#define CFG_RESET(x) (((x) & 0x1) << 27) - -#define UPHY_LANE_MUX (0x284) -#define SEL(x) (((x) & 0x7) << 0) -#define SEL_XUSB SEL(0) -#define SEL_PCIE SEL(1) -#define SEL_SATA SEL(2) -#define SEL_MPHY SEL(3) -#define CLAMP_EN_EARLY (1 << 8) -#define FORCE_IDDQ_DISABLE (1 << 9) - -/* UPHY APB Dynamic DYN_CTL registers */ -#define UPHY_LANE_DYN_CTL_1 (0x80) -#define TX_DRV_AMP_SEL0(x) (((x) & 0x3f) << 0) -#define TX_DRV_AMP_SEL1(x) (((x) & 0x3f) << 8) -#define TX_DRV_AMP_SEL2(x) (((x) & 0x3f) << 16) -#define TX_DRV_AMP_SEL3(x) (((x) & 0x3f) << 24) - -#define UPHY_LANE_DYN_CTL_2 (0x84) -#define TX_DRV_AMP_SEL4(x) (((x) & 0x3f) << 0) -#define TX_DRV_AMP_SEL5(x) (((x) & 0x3f) << 8) -#define TX_DRV_AMP_SEL6(x) (((x) & 0x3f) << 16) -#define TX_DRV_AMP_SEL7(x) (((x) & 0x3f) << 24) - -#define UPHY_LANE_DYN_CTL_3 (0x88) -#define TX_DRV_AMP_SEL8(x) (((x) & 0x3f) << 0) -#define TX_DRV_AMP_SEL9(x) (((x) & 0x3f) << 8) - -#define UPHY_LANE_DYN_CTL_4 (0x8c) -#define TX_DRV_POST_SEL0(x) (((x) & 0x3f) << 0) -#define TX_DRV_PRE_SEL0(x) (((x) & 0x3f) << 8) -#define TX_DRV_POST_SEL1(x) (((x) & 0x3f) << 16) -#define TX_DRV_PRE_SEL1(x) (((x) & 0x3f) << 24) - -#define UPHY_LANE_DYN_CTL_5 (0x90) -#define TX_DRV_POST_SEL2(x) (((x) & 0x3f) << 0) -#define TX_DRV_PRE_SEL2(x) (((x) & 0x3f) << 8) -#define TX_DRV_POST_SEL3(x) (((x) & 0x3f) << 16) -#define TX_DRV_PRE_SEL3(x) (((x) & 0x3f) << 24) - -/* FUSE USB_CALIB registers */ /* TODO: check spec */ -#define USB_CALIB_HS_CURR_LEVEL_PADX_SHIFT(x) ((x) ? (11 + (x - 1) * 6) : 0) -#define USB_CALIB_HS_CURR_LEVEL_PAD_MASK (0x3f) -#define USB_CALIB_HS_TERM_RANGE_ADJ_SHIFT (7) -#define USB_CALIB_HS_TERM_RANGE_ADJ_MASK (0xf) - -#define USB_CALIB_EXT_RPD_CTRL_SHIFT (7) -#define USB_CALIB_EXT_RPD_CTRL_MASK (0xf) - -/* FUSE SATA MPHY registers */ -#define FUSE_SATA_MPHY_ODM_CALIB_0 (0x224) -#define SATA_MPHY_ODM_CALIB_0_1(x) (((x) & 0x3) << 0) - -#define FUSE_SATA_NV_CALIB_0 (0x49c) -#define SATA_NV_CALIB_0_1(x) (((x) & (0x3 << 0)) >> 0) -#define SATA_NV_CALIB_2_3(x) (((x) & (0x3 << 2)) >> 2) - -#define FUSE_MPHY_NV_CALIB_0 (0x4a0) -#define MPHY_NV_CALIB_0_1(x) (((x) & (0x3 << 0)) >> 0) -#define MPHY_NV_CALIB_2_3(x) (((x) & (0x3 << 2)) >> 2) -#define MPHY_NV_CALIB_4_5(x) (((x) & (0x3 << 4)) >> 4) - -/* XUSB PADCTL registers */ -#define XUSB_PADCTL_USB2_PAD_MUX (0x4) - -#define XUSB_PADCTL_USB2_PORT_CAP (0x8) -#define XUSB_PADCTL_SS_PORT_CAP (0xc) -#define PORTX_CAP_SHIFT(x) ((x) * 4) -#define PORT_CAP_MASK (0x3) -#define PORT_CAP_DISABLED (0x0) -#define PORT_CAP_HOST (0x1) -#define PORT_CAP_DEVICE (0x2) -#define PORT_CAP_OTG (0x3) - -#define XUSB_PADCTL_ELPG_PROGRAM (0x20) - -#define XUSB_PADCTL_ELPG_PROGRAM_1 (0x24) -#define SSPX_ELPG_CLAMP_EN(x) (1 << (0 + (x) * 3)) -#define SSPX_ELPG_CLAMP_EN_EARLY(x) (1 << (1 + (x) * 3)) -#define SSPX_ELPG_VCORE_DOWN(x) (1 << (2 + (x) * 3)) - -#define USB2_BATTERY_CHRG_OTGPADX_CTL1(x) (0x84 + (x) * 0x40) -#define VREG_LEV(x) (((x) & 0x3) << 7) -#define VREG_FIX18 (1 << 6) - -#define XUSB_PADCTL_USB2_OTG_PADX_CTL0(x) (0x88 + (x) * 0x40) -#define HS_CURR_LEVEL(x) ((x) & 0x3f) -#define USB2_OTG_PD (1 << 26) -#define USB2_OTG_PD2 (1 << 27) -#define USB2_OTG_PD_ZI (1 << 29) - -#define XUSB_PADCTL_USB2_OTG_PADX_CTL1(x) (0x8c + (x) * 0x40) -#define USB2_OTG_PD_DR (1 << 2) -#define TERM_RANGE_ADJ(x) (((x) & 0xf) << 3) -#define RPD_CTRL(x) (((x) & 0x1f) << 26) - -#define XUSB_PADCTL_USB2_BIAS_PAD_CTL0 (0x284) -#define BIAS_PAD_PD (1 << 11) - -#define USB2_VBUS_ID (0x360) -#define VBUS_OVERRIDE (1 << 14) - -/* XUSB AO registers */ -#define XUSB_AO_UTMIP_TRIGGERS(x) (0x40 + (x) * 4) -#define CLR_WALK_PTR (1 << 0) -#define CAP_CFG (1 << 1) -#define CLR_WAKE_ALARM (1 << 3) - -#define XUSB_AO_UTMIP_SLEEPWALK_CFG(x) (0xd0 + (x) * 4) -#define XUSB_AO_UHSIC_SLEEPWALK_CFG(x) (0xf0 + (x) * 4) -#define MASTER_ENABLE (1 << 15) -#define MASTER_CFG_SEL (1 << 22) - -#define XUSB_AO_UTMIP_SLEEPWALK(x) (0x120 + (x) * 4) -#if 0 /* TODO: implement */ -#define padctl_ao_readl padctl_readl /* FIXME */ -#define padctl_ao_writel padctl_writel /* FIXME */ -static int utmip_setup_sleepwalk(struct tegra_padctl_uphy *ctx, int pad) -{ - u32 reg; - - /* ensure sleepwalk logic is disabled */ - reg = padctl_ao_readl(ctx, XUSB_AO_UTMIP_SLEEPWALK_CFG(pad)); - reg &= ~MASTER_ENABLE; - padctl_ao_writel(ctx, reg, XUSB_AO_UTMIP_SLEEPWALK_CFG(pad)); - - - return 0; -} -#endif -/* UPHY PLL config space registers */ -#define MGMT_FREQ_CTRL_ID0 (0) -#define MGMT_FREQ_CTRL_ID1 (1) -#define CFG_FREQ_NDIV(x) (((x) & 0xff) << 0) -#define CFG_FREQ_MDIV(x) (((x) & 0x3) << 8) -#define CFG_FREQ_PSDIV(x) (((x) & 0x3) << 10) -#define CFG_MODE(x) (((x) & 0x3) << 12) - -#define MGMT_REFCLK_CTRL (2) - -#define MGMT_CORECLK_CTRL_ID0 (3) -#define MGMT_CORECLK_CTRL_ID1 (4) -#define CFG_TXCLKREF_EN(x) (((x) & 0x1) << 0) -#define CFG_TXCLKREF_SEL(x) (((x) & 0x3) << 4) -#define DIVIDE_TX_BY_10 (0) -#define DIVIDE_TX_BY_8 (1) -#define DIVIDE_TX_BY_5 (2) -#define DIVIDE_TX_BY_4 (3) -#define CFG_XDIGCLK_EN(x) (((x) & 0x1) << 8) -#define CFG_XDIGCLK_SEL(x) (((x) & 0x3) << 12) - -#define PLLC_CRSWRD_OVRD_ID0 (5) - -#define PLLC_CRSWRD_OVRD_ID1 (6) - -#define MGMT_CYA_CTRL (29) -#define CFG_MGMT_CLK_SEL(x) (((x) & 0x1) << 4) - -/* UPHY Lane config space registers */ -#define MGMT_TX_RATE_CTRL_ID0 (0) -#define MGMT_TX_RATE_CTRL_ID1 (1) -#define MGMT_TX_RATE_CTRL_ID2 (2) -#define MGMT_TX_RATE_CTRL_ID3 (3) -#define TX_RATE_SDIV(x) (((x) & 0x3) << 0) -#define SDIV4 (0) -#define SDIV2 (1) -#define SDIV1 (2) -#define SDIVX (3) - -#define MGMT_RX_RATE_CTRL_ID0 (4) -#define MGMT_RX_RATE_CTRL_ID1 (5) -#define MGMT_RX_RATE_CTRL_ID2 (6) -#define MGMT_RX_RATE_CTRL_ID3 (7) -#define RX_RATE_SDIV(x) (((x) & 0x3) << 0) -#define RX_RATE_CDIV(x) (((x) & 0x3) << 4) -#define CDIV1 (0) -#define CDIV2 (1) -#define CDIV4 (2) -#define CDIV8 (3) - -#define MGMT_TX_CTRL (8) -#define TX_TERM_MODE(x) (((x) & 0x1) << 0) -#define SYNC_DLY(x) (((x) & 0xf) << 4) - -#define AE_CTLE_CTRL_ID0 (10) -#define AE_CTLE_CTRL_ID1 (11) -#define AE_CTLE_CTRL_ID2 (12) -#define AE_CTLE_CTRL_ID3 (13) -#define LF_UGRAY(x) (((x) & 0xf) << 0) -#define HF_UBIN(x) (((x) & 0xf) << 4) - -#define AE_DFE0_CTRL_ID0 (14) -#define AE_DFE0_CTRL_ID1 (15) -#define AE_DFE0_CTRL_ID2 (16) -#define AE_DFE1_CTRL_ID2 (20) -#define H1_SBIN(x) (((x) & 0x1f) << 0) -#define H2_SBIN(x) (((x) & 0xf) << 8) -#define H3_SBIN(x) (((x) & 0x7) << 12) - -#define AE_DFE1_CTRL_ID0 (18) -#define H4_SBIN(x) (((x) & 0x7) << 0) -#define H0_SBIN(x) (((x) & 0x3f) << 8) - -#define AE_CDR_CTRL_ID0 (22) -#define AE_CDR_CTRL_ID1 (23) -#define AE_CDR_CTRL_ID2 (24) -#define AE_CDR_CTRL_ID3 (25) -#define PHGAIN(x) (((x) & 0xf) << 0) -#define FRGAIN(x) (((x) & 0xf) << 4) -#define FRLOOP_EN(x) (((x) & 0x1) << 8) - -#define AE_EQ0_CTRL_ID0 (26) -#define AE_EQ0_CTRL_ID1 (27) -#define AE_EQ0_CTRL_ID2 (28) -#define EQ0_SEQ_MODE(x) (((x) & 0x3) << 0) -#define SEQ_MODE_HF_Z_H0_HN_Z (0) -#define SEQ_MODE_H0_HN_Z_HF_Z (1) -#define SEQ_MODE_HF_H0_HN_Z (2) -#define SEQ_MODE_HF_H0_HN_Z_HF (3) -#define H0INIT_ITERS(x) (((x) & 0xf) << 4) -#define H4_GRAD_INV(x) (((x) & 0x1) << 8) -#define H3_GRAD_INV(x) (((x) & 0x1) << 9) -#define H2_GRAD_INV(x) (((x) & 0x1) << 10) -#define H1_GRAD_INV(x) (((x) & 0x1) << 11) -#define H0_GRAD_INV(x) (((x) & 0x1) << 12) -#define CTLE_HF_GRAD_INV(x) (((x) & 0x1) << 13) -#define SAMP_VOS_GRAD_INV(x) (((x) & 0x1) << 14) -#define CTLE_VOS_GRAD_INV(x) (((x) & 0x1) << 15) - -#define AE_EQ1_CTRL_ID0 (30) -#define AE_EQ1_CTRL_ID1 (31) -#define AE_EQ1_CTRL_ID2 (32) -#define AE_EQ1_CTRL_ID3 (33) -#define CTLE_HF_MODE(x) (((x) & 0x3) << 0) -#define VAR_MODE_AUTO (0) -#define VAR_MODE_OFF (1) -#define VAR_MODE_HOLD (2) -#define VAR_MODE_LOAD (3) -#define CTLE_HF_GRAD(x) (((x) & 0x3) << 2) -#define CTLE_HF_GRAD_1P5 (0) -#define CTLE_HF_GRAD_2P5 (1) -#define CTLE_HF_GRAD_3P5 (2) -#define CTLE_HF_GRAD_1TP (3) -#define H1_MODE(x) (((x) & 0x3) << 8) -#define H2_MODE(x) (((x) & 0x3) << 10) -#define H3_MODE(x) (((x) & 0x3) << 12) -#define H4_MODE(x) (((x) & 0x3) << 14) - -#define AE_EQ2_CTRL_ID0 (34) -#define AE_EQ2_CTRL_ID1 (35) -#define AE_EQ2_CTRL_ID2 (36) -#define AE_EQ2_CTRL_ID3 (37) -#define H0_MODE(x) (((x) & 0x3) << 0) -#define H0_DAC_TIME(x) (((x) & 0x3) << 2) -#define H0_TIME(x) (((x) & 0xf) << 4) -#define H0_ITERS(x) (((x) & 0xf) << 8) -#define HN_ITERS(x) (((x) & 0xf) << 12) - -#define AE_EQ3_CTRL_ID0 (38) -#define AE_EQ3_CTRL_ID2 (40) -#define H0_GAIN(x) (((x) & 0xf) << 0) -#define HN_GAIN(x) (((x) & 0xf) << 4) -#define CTLE_HF_TIME(x) (((x) & 0xf) << 8) -#define CTLE_HF_GAIN(x) (((x) & 0xf) << 12) - -#define MGMT_RX_PI_CTRL_ID2 (48) -#define TX_SLEW(x) (((x) & 0x3) << 0) -#define RX_SLEW(x) (((x) & 0x3) << 2) - -#define CLK_RST_CONTROLLER_RST_DEV_UPHY_0 (0x4000c) -#define SWR_UPHY_RST (1 << 0) - -#define CLK_RST_CONTROLLER_RST_DEV_PEX_USB_UPHY_0 (0x40000) -#define SWR_PEX_USB_UPHY_RST (1 << 0) -#define SWR_PEX_USB_UPHY_PLL0_RST (1 << 7) -#define SWR_PEX_USB_UPHY_PLL1_RST (1 << 15) -#define SWR_PEX_USB_UPHY_LANE_RST(lane) (1 << (16+lane)) - -enum tegra186_function { - TEGRA186_FUNC_HSIC, - TEGRA186_FUNC_HSIC_PLUS, - TEGRA186_FUNC_XUSB, - TEGRA186_FUNC_UART, - TEGRA186_FUNC_PCIE, - TEGRA186_FUNC_USB3, - TEGRA186_FUNC_SATA, - TEGRA186_FUNC_MPHY, - TEGRA186_FUNC_RSVD_0, - TEGRA186_FUNC_RSVD_3, -}; - -struct tegra_padctl_uphy_function { - const char *name; - const char * const *groups; - unsigned int num_groups; -}; - -struct tegra_padctl_uphy_group { - const unsigned int *funcs; - unsigned int num_funcs; -}; - -struct tegra_padctl_uphy_soc { - const struct pinctrl_pin_desc *pins; - unsigned int num_pins; - - const struct tegra_padctl_uphy_function *functions; - unsigned int num_functions; - - const struct tegra_padctl_uphy_lane *lanes; - unsigned int num_lanes; - - unsigned int hsic_port_offset; -}; - -struct tegra_padctl_uphy_lane { - const char *name; - - unsigned int offset; - unsigned int shift; - unsigned int mask; - unsigned int iddq; - - const unsigned int *funcs; - unsigned int num_funcs; -}; - -struct tegra_xusb_fuse_calibration { - u32 hs_curr_level[TEGRA_XUSB_UTMI_PHYS]; - u32 hs_term_range_adj; - u32 rpd_ctrl; -}; - -struct tegra_fuse_calibration { - u32 sata_mphy_odm; - u32 sata_nv; - u32 mphy_nv; -}; - -struct tegra_xusb_usb3_port { - unsigned int lane; -}; - -struct tegra_padctl_uphy { - struct device *dev; - void __iomem *padctl_regs; - void __iomem *uphy_regs; - void __iomem *uphy_pll_regs[2]; - void __iomem *uphy_lane_regs[6]; - - struct clk *clk; /* uphy pad macro clock */ - - struct mutex lock; - - const struct tegra_padctl_uphy_soc *soc; - struct tegra_xusb_fuse_calibration calib; - struct tegra_fuse_calibration fuse_calib; - struct tegra_prod_list *prod_list; - struct pinctrl_dev *pinctrl; - struct pinctrl_desc desc; - - struct phy_provider *provider; -// struct phy *phys[TEGRA_XUSB_NUM_PHYS]; - struct phy *usb3_phys[TEGRA_XUSB_USB3_PHYS]; - struct phy *utmi_phys[TEGRA_XUSB_UTMI_PHYS]; - struct phy *hsic_phys[TEGRA_XUSB_HSIC_PHYS]; - struct phy *pcie_phys[TEGRA_XUSB_PCIE_PHYS]; - struct phy *sata_phys[TEGRA_XUSB_SATA_PHYS]; - struct phy *ufs_phys[TEGRA_XUSB_UFS_PHYS]; - unsigned long usb3_lanes; - unsigned long pcie_lanes; - unsigned long sata_lanes; - unsigned long ufs_lanes; - - unsigned int padctl_clients; - bool sata_bypass_fuse; - - struct tegra_xusb_usb3_port usb3_ports[TEGRA_XUSB_USB3_PHYS]; - unsigned int utmi_enable; - unsigned int hs_curr_level_offset[TEGRA_XUSB_UTMI_PHYS]; - struct regulator *vbus[TEGRA_XUSB_UTMI_PHYS]; - struct regulator *vddio_hsic; - - int uphy_pll_clients[2]; - struct clk *uphy_pll_clk[2]; - struct clk *uphy_lane_clk[6]; - -}; - -#ifdef SIM -#undef writel -#define writel(v,c) {*(u32 *)(c) = v;} -#undef readl -#define readl(c) ({ *(u32 *)(c);}) -#endif - -#if 0 -static inline void padctl_writel(struct tegra_padctl_uphy *padctl, u32 value, - unsigned long offset) -{ - writel(value, padctl->padctl_regs + offset); -} - -static inline u32 padctl_readl(struct tegra_padctl_uphy *padctl, - unsigned long offset) -{ - return readl(padctl->padctl_regs + offset); -} -#else -#define padctl_writel(_padctl, _value, _offset) \ -{ \ - unsigned long v = _value, o = _offset; \ - pr_info("%s padctl_write %s(@0x%lx) with 0x%lx\n", __func__, \ - #_offset, o, v); \ - writel(v, _padctl->padctl_regs + o); \ -} - -#define padctl_readl(_padctl, _offset) \ -({ \ - unsigned long v, o = _offset; \ - v = readl(_padctl->padctl_regs + o); \ - pr_info("%s padctl_read %s(@0x%lx) = 0x%lx\n", __func__, \ - #_offset, o, v); \ - v; \ -}) -#endif - -#if 0 -static inline void uphy_pll_writel(struct tegra_padctl_uphy *ctx, int pll, - u32 value, unsigned long offset) -{ - writel(value, ctx->uphy_pll_regs[pll] + offset); -} - -static inline u32 uphy_pll_readl(struct tegra_padctl_uphy *ctx, int pll, - unsigned long offset) -{ - return readl(ctx->uphy_pll_regs[pll] + offset); -} -#else -#define uphy_pll_writel(_ctx, _pll, _value, _offset) \ -{ \ - unsigned long v = _value, o = _offset; \ - pr_info("%s uphy_pll_writel pll %d %s(@0x%lx) with 0x%lx\n", __func__, \ - _pll, #_offset, o, v); \ - writel(v, _ctx->uphy_pll_regs[_pll] + o); \ -} - -#define uphy_pll_readl(_ctx, _pll, _offset) \ -({ \ - unsigned long v, o = _offset; \ - v = readl(_ctx->uphy_pll_regs[_pll] + o); \ - pr_info("%s uphy_pll_readl pll %d %s(@0x%lx) = 0x%lx\n", __func__, \ - _pll, #_offset, o, v); \ - v; \ -}) -#endif - -#if 0 -static inline void uphy_lane_writel(struct tegra_padctl_uphy *ctx, int lane, - u32 value, unsigned long offset) -{ - writel(value, ctx->uphy_lane_regs[lane] + offset); -} - -static inline u32 uphy_pll_readl(struct tegra_padctl_uphy *ctx, int lane, - unsigned long offset) -{ - return readl(ctx->uphy_lane_regs[lane] + offset); -} -#else -#define uphy_lane_writel(_ctx, _lane, _value, _offset) \ -{ \ - unsigned long v = _value, o = _offset; \ - pr_info("%s uphy_lane_writel lane %d %s(@0x%lx) with 0x%lx\n", __func__, \ - _lane, #_offset, o, v); \ - writel(v, _ctx->uphy_lane_regs[_lane] + o); \ -} - -#define uphy_lane_readl(_ctx, _lane, _offset) \ -({ \ - unsigned long v, o = _offset; \ - v = readl(_ctx->uphy_lane_regs[_lane] + o); \ - pr_info("%s uphy_lane_readl lane %d %s(@0x%lx) = 0x%lx\n", __func__, \ - _lane, #_offset, o, v); \ - v; \ -}) -#endif - -struct tegra_mphy_sata_calib { - u8 aux_rx_idle_th; - u8 tx_drv_amp_sel0; - u8 tx_drv_amp_sel1; - u8 tx_drv_amp_sel2; - u8 tx_drv_amp_sel3; - u8 tx_drv_amp_sel4; - u8 tx_drv_amp_sel5; - u8 tx_drv_amp_sel6; - u8 tx_drv_amp_sel7; - u8 tx_drv_amp_sel8; - u8 tx_drv_amp_sel9; - u8 tx_drv_post_sel0; - u8 tx_drv_post_sel1; - u8 tx_drv_post_sel2; - u8 tx_drv_post_sel3; - u8 tx_drv_pre_sel3; - u8 ae_ctle_ctrl_id0; - u8 ae_ctle_ctrl_id1; -}; - -static struct tegra_mphy_sata_calib mphy_data[] = { - { - .aux_rx_idle_th = 0x0, - .tx_drv_amp_sel0 = 0x8, - .tx_drv_amp_sel1 = 0x11, - .tx_drv_amp_sel2 = 0x8, - .tx_drv_amp_sel3 = 0x11, - .tx_drv_amp_sel4 = 0x8, - .tx_drv_amp_sel5 = 0x11, - .tx_drv_amp_sel6 = 0x8, - .tx_drv_amp_sel7 = 0x11, - .tx_drv_amp_sel8 = 0x8, - .tx_drv_amp_sel9 = 0x11, - .tx_drv_post_sel0 = 0x0, - .tx_drv_post_sel1 = 0xa, - .tx_drv_post_sel2 = 0xf, - .tx_drv_post_sel3 = 0x8, - .tx_drv_pre_sel3 = 0x8, - }, - { - .aux_rx_idle_th = 0x1, - .tx_drv_amp_sel0 = 0x8, - .tx_drv_amp_sel1 = 0x11, - .tx_drv_amp_sel2 = 0x8, - .tx_drv_amp_sel3 = 0x11, - .tx_drv_amp_sel4 = 0x8, - .tx_drv_amp_sel5 = 0x11, - .tx_drv_amp_sel6 = 0x8, - .tx_drv_amp_sel7 = 0x11, - .tx_drv_amp_sel8 = 0x8, - .tx_drv_amp_sel9 = 0x11, - .tx_drv_post_sel0 = 0x0, - .tx_drv_post_sel1 = 0xa, - .tx_drv_post_sel2 = 0xf, - .tx_drv_post_sel3 = 0x8, - .tx_drv_pre_sel3 = 0x8, - }, - { - .aux_rx_idle_th = 0x2, - .tx_drv_amp_sel0 = 0x8, - .tx_drv_amp_sel1 = 0x11, - .tx_drv_amp_sel2 = 0x8, - .tx_drv_amp_sel3 = 0x11, - .tx_drv_amp_sel4 = 0x8, - .tx_drv_amp_sel5 = 0x11, - .tx_drv_amp_sel6 = 0x8, - .tx_drv_amp_sel7 = 0x11, - .tx_drv_amp_sel8 = 0x8, - .tx_drv_amp_sel9 = 0x11, - .tx_drv_post_sel0 = 0x0, - .tx_drv_post_sel1 = 0xa, - .tx_drv_post_sel2 = 0xf, - .tx_drv_post_sel3 = 0x8, - .tx_drv_pre_sel3 = 0x8, - }, - { - .aux_rx_idle_th = 0x3, - .tx_drv_amp_sel0 = 0x8, - .tx_drv_amp_sel1 = 0x11, - .tx_drv_amp_sel2 = 0x8, - .tx_drv_amp_sel3 = 0x11, - .tx_drv_amp_sel4 = 0x8, - .tx_drv_amp_sel5 = 0x11, - .tx_drv_amp_sel6 = 0x8, - .tx_drv_amp_sel7 = 0x11, - .tx_drv_amp_sel8 = 0x8, - .tx_drv_amp_sel9 = 0x11, - .tx_drv_post_sel0 = 0x0, - .tx_drv_post_sel1 = 0xa, - .tx_drv_post_sel2 = 0xf, - .tx_drv_post_sel3 = 0x8, - .tx_drv_pre_sel3 = 0x8, - }, -}; - -static struct tegra_mphy_sata_calib sata_data[] = { - { - .aux_rx_idle_th = 0x0, - .tx_drv_amp_sel0 = 0x1b, - .tx_drv_amp_sel1 = 0x1f, - .tx_drv_post_sel0 = 0x7, - .tx_drv_post_sel1 = 0xa, - .ae_ctle_ctrl_id0 = 0xf, - .ae_ctle_ctrl_id1 = 0x8f, - }, - { - .aux_rx_idle_th = 0x1, - .tx_drv_amp_sel0 = 0x17, - .tx_drv_amp_sel1 = 0x1b, - .tx_drv_post_sel0 = 0x5, - .tx_drv_post_sel1 = 0xa, - .ae_ctle_ctrl_id0 = 0xf, - .ae_ctle_ctrl_id1 = 0x4f, - }, - { - .aux_rx_idle_th = 0x2, - .tx_drv_amp_sel0 = 0x13, - .tx_drv_amp_sel1 = 0x17, - .tx_drv_post_sel0 = 0x4, - .tx_drv_post_sel1 = 0xa, - .ae_ctle_ctrl_id0 = 0xf, - .ae_ctle_ctrl_id1 = 0xf, - }, - { - .aux_rx_idle_th = 0x3, - .tx_drv_amp_sel0 = 0x1f, - .tx_drv_amp_sel1 = 0x23, - .tx_drv_post_sel0 = 0xa, - .tx_drv_post_sel1 = 0xe, - .ae_ctle_ctrl_id0 = 0xf, - .ae_ctle_ctrl_id1 = 0xcd, - }, -}; - -struct init_data { - u8 cfg_addr; - u16 cfg_wdata; - bool cfg_wds; - bool cfg_rds; - bool cfg_rst; -}; - -static struct init_data usb3_pll_g1_init_data[] = { - { - .cfg_addr = MGMT_CORECLK_CTRL_ID0, - .cfg_wdata = CFG_TXCLKREF_EN(1) | - CFG_TXCLKREF_SEL(DIVIDE_TX_BY_5), - }, -}; - -static void pcie_usb3_pll_defaults(struct tegra_padctl_uphy *ctx) -{ - u32 reg; - int i; - - for (i = 0; i < ARRAY_SIZE(usb3_pll_g1_init_data); i++) { - reg = CFG_ADDR(usb3_pll_g1_init_data[i].cfg_addr); - reg |= CFG_WDATA(usb3_pll_g1_init_data[i].cfg_wdata); - uphy_pll_writel(ctx, 0, reg, UPHY_PLL_CTL_4); - } -} - -#define pcie_pll_init pcie_usb3_pll_defaults - -static struct init_data sata_pll_g1_g2_g3_init_data[] = { - { - .cfg_addr = MGMT_FREQ_CTRL_ID0, - .cfg_wdata = CFG_FREQ_NDIV(30), - }, - { - .cfg_addr = MGMT_CORECLK_CTRL_ID0, - .cfg_wdata = CFG_TXCLKREF_EN(1) | - CFG_TXCLKREF_SEL(DIVIDE_TX_BY_10), - }, -}; - -static void sata_pll_init(struct tegra_padctl_uphy *ctx) -{ - u32 reg; - int i; - - for (i = 0; i < ARRAY_SIZE(sata_pll_g1_g2_g3_init_data); i++) { - reg = CFG_ADDR(sata_pll_g1_g2_g3_init_data[i].cfg_addr); - reg |= CFG_WDATA(sata_pll_g1_g2_g3_init_data[i].cfg_wdata); - uphy_pll_writel(ctx, 1, reg, UPHY_PLL_CTL_4); - } -} - -static struct init_data ufs_pll_g1_g2_g3_A_B_init_data[] = { - { - .cfg_addr = MGMT_FREQ_CTRL_ID0, - .cfg_wdata = CFG_FREQ_NDIV(24) | CFG_FREQ_MDIV(1), - }, - { - .cfg_addr = MGMT_FREQ_CTRL_ID1, - .cfg_wdata = CFG_FREQ_NDIV(28) | CFG_FREQ_MDIV(1), - }, - { - .cfg_addr = MGMT_CORECLK_CTRL_ID0, - .cfg_wdata = CFG_TXCLKREF_EN(1) | - CFG_TXCLKREF_SEL(DIVIDE_TX_BY_10), - }, - { - .cfg_addr = MGMT_CORECLK_CTRL_ID1, - .cfg_wdata = CFG_TXCLKREF_EN(1) | - CFG_TXCLKREF_SEL(DIVIDE_TX_BY_10), - }, - { - .cfg_addr = PLLC_CRSWRD_OVRD_ID1, - .cfg_wdata = 0, - }, - { - .cfg_addr = MGMT_CYA_CTRL, - .cfg_wdata = CFG_MGMT_CLK_SEL(1), - }, -}; -static void ufs_pll_init(struct tegra_padctl_uphy *ctx) -{ - u32 reg; - int i; - - for (i = 0; i < ARRAY_SIZE(ufs_pll_g1_g2_g3_A_B_init_data); i++) { - reg = CFG_ADDR(ufs_pll_g1_g2_g3_A_B_init_data[i].cfg_addr); - reg |= CFG_WDATA(ufs_pll_g1_g2_g3_A_B_init_data[i].cfg_wdata); - uphy_pll_writel(ctx, 1, reg, UPHY_PLL_CTL_4); - } -} - -static struct init_data ufs_pll_rateid_init_data[] = { - { - .cfg_addr = MGMT_FREQ_CTRL_ID0, - .cfg_wdata = CFG_FREQ_NDIV(0x18) | CFG_FREQ_MDIV(0x1), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = MGMT_FREQ_CTRL_ID1, - .cfg_wdata = CFG_FREQ_NDIV(0x1c) | CFG_FREQ_MDIV(0x1), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = MGMT_REFCLK_CTRL, - .cfg_wdata = 0x0, - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = MGMT_CORECLK_CTRL_ID0, - .cfg_wdata = CFG_XDIGCLK_SEL(0x7) | CFG_XDIGCLK_EN(0x1) - | CFG_TXCLKREF_SEL(0x2) | CFG_TXCLKREF_EN(1), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = MGMT_TX_RATE_CTRL_ID1, - .cfg_wdata = CFG_XDIGCLK_SEL(0x7) | CFG_XDIGCLK_EN(0x1) - | CFG_TXCLKREF_SEL(0x2) | CFG_TXCLKREF_EN(1), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = PLLC_CRSWRD_OVRD_ID0, - .cfg_wdata = 0x3e, - .cfg_wds = true, - .cfg_rst = true, - } -}; - -static void ufs_pll_rateid_init(struct tegra_padctl_uphy *ctx) -{ - u32 reg; - int i; - - for (i = 0; i < ARRAY_SIZE(ufs_pll_rateid_init_data); i++) { - reg = CFG_ADDR(ufs_pll_rateid_init_data[i].cfg_addr); - reg |= CFG_WDATA(ufs_pll_rateid_init_data[i].cfg_wdata); - reg |= CFG_WDS(ufs_pll_rateid_init_data[i].cfg_wds); - reg |= CFG_RDS(ufs_pll_rateid_init_data[i].cfg_rds); - reg |= CFG_RESET(ufs_pll_rateid_init_data[i].cfg_rst); - uphy_pll_writel(ctx, 1, reg, UPHY_PLL_CTL_4); - } -} - -static struct init_data ufs_lane_rateid_init_data[] = { - { - .cfg_addr = MGMT_TX_RATE_CTRL_ID0, - .cfg_wdata = TX_RATE_SDIV(SDIV4), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = MGMT_TX_RATE_CTRL_ID1, - .cfg_wdata = TX_RATE_SDIV(SDIV2), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = MGMT_TX_RATE_CTRL_ID2, - .cfg_wdata = TX_RATE_SDIV(SDIV1), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = MGMT_TX_RATE_CTRL_ID3, - .cfg_wdata = TX_RATE_SDIV(SDIV1), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = MGMT_RX_RATE_CTRL_ID0, - .cfg_wdata = RX_RATE_SDIV(CDIV1), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = MGMT_RX_RATE_CTRL_ID1, - .cfg_wdata = RX_RATE_SDIV(CDIV2), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = MGMT_RX_RATE_CTRL_ID2, - .cfg_wdata = RX_RATE_SDIV(CDIV4), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = MGMT_RX_RATE_CTRL_ID0, - .cfg_wdata = RX_RATE_SDIV(CDIV4), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = MGMT_TX_CTRL, - .cfg_wdata = TX_TERM_MODE(0x1), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = AE_CDR_CTRL_ID0, - .cfg_wdata = FRLOOP_EN(0x1) | FRGAIN(0x3) | PHGAIN(0x7), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = AE_CDR_CTRL_ID1, - .cfg_wdata = FRLOOP_EN(0x1) | FRGAIN(0x6) | PHGAIN(0x7), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = AE_CDR_CTRL_ID2, - .cfg_wdata = FRLOOP_EN(0x1) | FRGAIN(0xc) | PHGAIN(0x7), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = AE_CDR_CTRL_ID3, - .cfg_wdata = FRLOOP_EN(0x1) | FRGAIN(0xc) | PHGAIN(0x7), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = AE_CTLE_CTRL_ID0, - .cfg_wdata = HF_UBIN(0x0) | LF_UGRAY(0xf), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = AE_CTLE_CTRL_ID1, - .cfg_wdata = HF_UBIN(0x0) | LF_UGRAY(0xf), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = AE_CTLE_CTRL_ID2, - .cfg_wdata = HF_UBIN(0x8) | LF_UGRAY(0xf), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = AE_CTLE_CTRL_ID3, - .cfg_wdata = HF_UBIN(0xf) | LF_UGRAY(0xd), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = AE_EQ1_CTRL_ID0, - .cfg_wdata = CTLE_HF_MODE(0x1), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = AE_EQ1_CTRL_ID1, - .cfg_wdata = CTLE_HF_MODE(0x1), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = AE_EQ1_CTRL_ID2, - .cfg_wdata = CTLE_HF_MODE(0x1), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = AE_EQ1_CTRL_ID3, - .cfg_wdata = CTLE_HF_MODE(0x0), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = AE_EQ2_CTRL_ID0, - .cfg_wdata = H0_MODE(0x1), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = AE_EQ2_CTRL_ID0, - .cfg_wdata = H0_MODE(0x1), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = AE_EQ2_CTRL_ID0, - .cfg_wdata = H0_MODE(0x1), - .cfg_wds = true, - .cfg_rst = true, - }, - { - .cfg_addr = AE_EQ2_CTRL_ID0, - .cfg_wdata = H0_MODE(0x0), - .cfg_wds = true, - .cfg_rst = true, - }, -}; - -static void ufs_lane_rateid_init(struct tegra_padctl_uphy *ctx, int lane) -{ - u32 reg; - int i; - - for (i = 0; i < ARRAY_SIZE(ufs_lane_rateid_init_data); i++) { - reg = CFG_ADDR(ufs_lane_rateid_init_data[i].cfg_addr); - reg |= CFG_WDATA(ufs_lane_rateid_init_data[i].cfg_wdata); - reg |= CFG_WDS(ufs_lane_rateid_init_data[i].cfg_wds); - reg |= CFG_RDS(ufs_lane_rateid_init_data[i].cfg_rds); - reg |= CFG_RESET(ufs_lane_rateid_init_data[i].cfg_rst); - uphy_lane_writel(ctx, lane, reg, UPHY_LANE_DIRECT_CTL_2); - } -} - - -static struct init_data pcie_lane_g1_g2_init_data[] = { -}; - -static void pcie_lane_defaults(struct tegra_padctl_uphy *ctx, int lane) -{ - u32 reg; - int i; - - for (i = 0; i < ARRAY_SIZE(pcie_lane_g1_g2_init_data); i++) { - reg = CFG_ADDR(pcie_lane_g1_g2_init_data[i].cfg_addr); - reg |= CFG_WDATA(pcie_lane_g1_g2_init_data[i].cfg_wdata); - uphy_lane_writel(ctx, lane, reg, UPHY_LANE_DIRECT_CTL_2); - } -} - -static struct init_data usb3_lane_g1_init_data[] = { - { - .cfg_addr = MGMT_TX_RATE_CTRL_ID0, - .cfg_wdata = TX_RATE_SDIV(SDIV1), - }, - { - .cfg_addr = MGMT_RX_RATE_CTRL_ID0, - .cfg_wdata = RX_RATE_SDIV(SDIV1) | RX_RATE_CDIV(CDIV4), - }, - { - .cfg_addr = MGMT_TX_CTRL, - .cfg_wdata = TX_TERM_MODE(0), - }, - { - .cfg_addr = AE_CTLE_CTRL_ID0, - .cfg_wdata = LF_UGRAY(0xd) | HF_UBIN(0xf), - }, - { - .cfg_addr = AE_DFE0_CTRL_ID0, - .cfg_wdata = LF_UGRAY(0xd) | HF_UBIN(0xf), - }, - { - .cfg_addr = AE_DFE1_CTRL_ID0, - .cfg_wdata = H0_SBIN(48) | H4_SBIN(-1), - }, - { - .cfg_addr = AE_CDR_CTRL_ID0, - .cfg_wdata = PHGAIN(0x7) | FRGAIN(0xc) | FRLOOP_EN(1), - }, - { - .cfg_addr = AE_EQ0_CTRL_ID0, - .cfg_wdata = EQ0_SEQ_MODE(SEQ_MODE_HF_Z_H0_HN_Z) | - H0INIT_ITERS(0x3), - }, - { - .cfg_addr = AE_EQ1_CTRL_ID0, - .cfg_wdata = CTLE_HF_MODE(VAR_MODE_AUTO) | - CTLE_HF_GRAD(CTLE_HF_GRAD_1P5) | - H1_MODE(VAR_MODE_AUTO) | - H2_MODE(VAR_MODE_AUTO) | - H3_MODE(VAR_MODE_AUTO) | - H4_MODE(VAR_MODE_AUTO), - }, - { - .cfg_addr = AE_EQ2_CTRL_ID0, - .cfg_wdata = H1_MODE(VAR_MODE_AUTO) | H0_DAC_TIME(0x2) | - H0_TIME(0x6) | H0_ITERS(0x3) | HN_ITERS(0x1), - }, - { - .cfg_addr = AE_EQ3_CTRL_ID0, - .cfg_wdata = HN_GAIN(0Xf) | CTLE_HF_TIME(0xc) | - CTLE_HF_GAIN(0xf), - }, -}; - -static void usb3_lane_defaults(struct tegra_padctl_uphy *ctx, int lane) -{ - u32 reg; - int i; - - for (i = 0; i < ARRAY_SIZE(usb3_lane_g1_init_data); i++) { - reg = CFG_ADDR(usb3_lane_g1_init_data[i].cfg_addr); - reg |= CFG_WDATA(usb3_lane_g1_init_data[i].cfg_wdata); - uphy_lane_writel(ctx, lane, reg, UPHY_LANE_DIRECT_CTL_2); - } - -} - -static struct init_data sata_lane_g1_g2_init_data[] = { - { - .cfg_addr = MGMT_TX_RATE_CTRL_ID0, - .cfg_wdata = TX_RATE_SDIV(SDIV4), - }, - { - .cfg_addr = MGMT_TX_RATE_CTRL_ID1, - .cfg_wdata = TX_RATE_SDIV(SDIV2), - }, - { - .cfg_addr = MGMT_RX_RATE_CTRL_ID0, - .cfg_wdata = RX_RATE_SDIV(SDIV4) | RX_RATE_CDIV(CDIV1), - }, - { - .cfg_addr = MGMT_RX_RATE_CTRL_ID1, - .cfg_wdata = RX_RATE_SDIV(SDIV2) | RX_RATE_CDIV(CDIV2), - }, - { - .cfg_addr = MGMT_TX_CTRL, - .cfg_wdata = TX_TERM_MODE(0), - }, - { - .cfg_addr = AE_CTLE_CTRL_ID0, - .cfg_wdata = LF_UGRAY(0x8), - }, - { - .cfg_addr = AE_CDR_CTRL_ID0, - .cfg_wdata = PHGAIN(0x7) | FRGAIN(0x3) | FRLOOP_EN(1), - }, - { - .cfg_addr = AE_CDR_CTRL_ID1, - .cfg_wdata = PHGAIN(0x7) | FRGAIN(0x6) | FRLOOP_EN(1), - }, -}; - -static void sata_lane_init(struct tegra_padctl_uphy *ctx, int lane) -{ - u32 reg; - int i; - - for (i = 0; i < ARRAY_SIZE(sata_lane_g1_g2_init_data); i++) { - reg = CFG_ADDR(sata_lane_g1_g2_init_data[i].cfg_addr); - reg |= CFG_WDATA(sata_lane_g1_g2_init_data[i].cfg_wdata); - uphy_lane_writel(ctx, lane, reg, UPHY_LANE_DIRECT_CTL_2); - } - -} - -static struct init_data ufs_lane_g1_g2_g3_init_data[] = { - { - .cfg_addr = MGMT_TX_RATE_CTRL_ID0, - .cfg_wdata = TX_RATE_SDIV(SDIV4), - }, - { - .cfg_addr = MGMT_TX_RATE_CTRL_ID1, - .cfg_wdata = TX_RATE_SDIV(SDIV2), - }, - { - .cfg_addr = MGMT_RX_RATE_CTRL_ID0, - .cfg_wdata = RX_RATE_SDIV(SDIV4) | RX_RATE_CDIV(CDIV1), - }, - { - .cfg_addr = MGMT_RX_RATE_CTRL_ID1, - .cfg_wdata = RX_RATE_SDIV(SDIV2) | RX_RATE_CDIV(CDIV2), - }, - { - .cfg_addr = MGMT_TX_CTRL, - .cfg_wdata = TX_TERM_MODE(1), - }, - { - .cfg_addr = AE_CTLE_CTRL_ID0, - .cfg_wdata = LF_UGRAY(0xf), - }, - { - .cfg_addr = AE_CTLE_CTRL_ID1, - .cfg_wdata = LF_UGRAY(0xf), - }, - { - .cfg_addr = AE_CTLE_CTRL_ID2, - .cfg_wdata = LF_UGRAY(0xf) | HF_UBIN(8), - }, - - { - .cfg_addr = AE_DFE0_CTRL_ID2, - .cfg_wdata = 0, - }, - { - .cfg_addr = AE_DFE1_CTRL_ID2, - .cfg_wdata = 0, - }, - { - .cfg_addr = AE_CDR_CTRL_ID0, - .cfg_wdata = PHGAIN(0x7) | FRGAIN(0x3) | FRLOOP_EN(1), - }, - { - .cfg_addr = AE_CDR_CTRL_ID1, - .cfg_wdata = PHGAIN(0x7) | FRGAIN(0x6) | FRLOOP_EN(1), - }, - { - .cfg_addr = AE_CDR_CTRL_ID2, - .cfg_wdata = PHGAIN(0x7) | FRGAIN(0xc) | FRLOOP_EN(1), - }, - { - .cfg_addr = AE_EQ0_CTRL_ID2, - .cfg_wdata = EQ0_SEQ_MODE(SEQ_MODE_HF_Z_H0_HN_Z), - }, - { - .cfg_addr = AE_EQ1_CTRL_ID2, - .cfg_wdata = CTLE_HF_MODE(VAR_MODE_OFF) | - CTLE_HF_GRAD(CTLE_HF_GRAD_1P5) | - H1_MODE(VAR_MODE_OFF) | - H2_MODE(VAR_MODE_OFF) | - H3_MODE(VAR_MODE_OFF) | - H4_MODE(VAR_MODE_OFF), - }, - { - .cfg_addr = AE_EQ2_CTRL_ID2, - .cfg_wdata = H1_MODE(VAR_MODE_OFF), - }, - { - .cfg_addr = AE_EQ3_CTRL_ID2, - .cfg_wdata = 0, - }, - { - .cfg_addr = MGMT_RX_PI_CTRL_ID2, - .cfg_wdata = 0, - }, -}; - -static void ufs_lane_init(struct tegra_padctl_uphy *ctx, int lane) -{ - u32 reg; - int i; - - for (i = 0; i < ARRAY_SIZE(ufs_lane_g1_g2_g3_init_data); i++) { - reg = CFG_ADDR(ufs_lane_g1_g2_g3_init_data[i].cfg_addr); - reg |= CFG_WDATA(ufs_lane_g1_g2_g3_init_data[i].cfg_wdata); - uphy_lane_writel(ctx, lane, reg, UPHY_LANE_DIRECT_CTL_2); - } - -} - -static int __uphy_pll_init(struct tegra_padctl_uphy *ctx, int pll) -{ - struct device *dev = ctx->dev; - u32 reg; - int i; - - /* FIXME: Need to see needed ??? */ - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_1); - reg |= PWR_OVRD; - uphy_pll_writel(ctx, pll, reg, UPHY_PLL_CTL_1); - - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_2); - reg |= (CAL_OVRD | RCAL_OVRD | CAL_RESET); - uphy_pll_writel(ctx, pll, reg, UPHY_PLL_CTL_2); - - /* power up PLL */ - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_1); - reg &= ~PLL_IDDQ; - uphy_pll_writel(ctx, pll, reg, UPHY_PLL_CTL_1); - - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_1); - reg &= ~PLL_SLEEP(~0); - uphy_pll_writel(ctx, pll, reg, UPHY_PLL_CTL_1); - - ndelay(100); - - /* perform PLL calibration */ - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_2); - reg |= CAL_EN; - uphy_pll_writel(ctx, pll, reg, UPHY_PLL_CTL_2); - for (i = 0; i < 20; i++) { - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_2); - if (reg & CAL_DONE) - break; - usleep_range(10, 15); - } - if (!(reg & CAL_DONE)) { - dev_err(dev, "start PLL %d calibration timeout\n", pll); - return -ETIMEDOUT; - } - - /* stop PLL calibration */ - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_2); - reg &= ~CAL_EN; - uphy_pll_writel(ctx, pll, reg, UPHY_PLL_CTL_2); - for (i = 0; i < 20; i++) { - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_2); - if (!(reg & CAL_DONE)) - break; - usleep_range(10, 15); - } - if (reg & CAL_DONE) { - dev_err(dev, "stop PLL %d calibration timeout\n", pll); - return -ETIMEDOUT; - } - - if (pll == 1) { - /* perform PLL rate change for UPHY_PLL_1, used by UFS */ - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_1); - reg &= ~RATE_ID(~0); - reg |= (RATE_ID(1) | RATE_ID_OVRD); - uphy_pll_writel(ctx, pll, reg, UPHY_PLL_CTL_1); - - ndelay(100); - - /* perform PLL calibration for rate B */ - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_2); - reg |= CAL_EN; - uphy_pll_writel(ctx, pll, reg, UPHY_PLL_CTL_2); - for (i = 0; i < 20; i++) { - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_2); - if (reg & CAL_DONE) - break; - usleep_range(10, 15); - } - if (!(reg & CAL_DONE)) { - dev_err(dev, "start PLL %d calibration timeout\n", pll); - return -ETIMEDOUT; - } - - /* stop PLL calibration */ - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_2); - reg &= ~CAL_EN; - uphy_pll_writel(ctx, pll, reg, UPHY_PLL_CTL_2); - for (i = 0; i < 20; i++) { - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_2); - if (!(reg & CAL_DONE)) - break; - usleep_range(10, 15); - } - if (reg & CAL_DONE) { - dev_err(dev, "stop PLL %d calibration timeout\n", pll); - return -ETIMEDOUT; - } - - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_1); - reg &= ~RATE_ID(~0); - reg |= RATE_ID_OVRD; - uphy_pll_writel(ctx, pll, reg, UPHY_PLL_CTL_1); - ndelay(100); - } - - /* enable PLL and wait for lock */ - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_1); - reg |= PLL_ENABLE; - uphy_pll_writel(ctx, pll, reg, UPHY_PLL_CTL_1); - usleep_range(20, 25); - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_1); - if (!(reg & LOCKDET_STATUS)) { - dev_err(dev, "enable PLL %d timeout\n", pll); - return -ETIMEDOUT; - } - - /* perform resistor calibration */ - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_2); - reg |= RCAL_EN; - uphy_pll_writel(ctx, pll, reg, UPHY_PLL_CTL_2); - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_2); - reg |= RCAL_CLK_EN; - uphy_pll_writel(ctx, pll, reg, UPHY_PLL_CTL_2); - usleep_range(5, 10); - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_2); - if (!(reg & RCAL_DONE)) { - dev_err(dev, "start resistor %d calibration timeout\n", pll); - return -ETIMEDOUT; - } - - /* stop resistor calibration */ - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_2); - reg &= ~RCAL_EN; - uphy_pll_writel(ctx, pll, reg, UPHY_PLL_CTL_2); - usleep_range(5, 10); - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_2); - if (reg & RCAL_DONE) { - dev_err(dev, "stop resistor %d calibration timeout\n", pll); - return -ETIMEDOUT; - } - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_2); - reg &= ~RCAL_CLK_EN; - uphy_pll_writel(ctx, pll, reg, UPHY_PLL_CTL_2); - - /* remove SW overrides to allow HW sequencer to run */ - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_1); - reg &= ~PWR_OVRD; - if (pll == 1) - reg &= ~RATE_ID_OVRD; - uphy_pll_writel(ctx, pll, reg, UPHY_PLL_CTL_1); - reg = uphy_pll_readl(ctx, pll, UPHY_PLL_CTL_2); - reg &= ~(CAL_OVRD | RCAL_OVRD); - uphy_pll_writel(ctx, pll, reg, UPHY_PLL_CTL_2); - - return 0; -} - -static int uphy_pll_init(struct tegra_padctl_uphy *ctx, int pll) -{ - struct device *dev = ctx->dev; - char clk_name[] = "uphy_pllX"; - int rc = 0; - - if (pll < 0 || pll > 1) - return -EINVAL; - - if (!ctx->uphy_pll_clk[pll]) { - snprintf(clk_name, sizeof(clk_name), "uphy_pll%d", pll); - ctx->uphy_pll_clk[pll] = clk_get_sys(NULL, clk_name); - - if (IS_ERR(ctx->uphy_pll_clk[pll])) { - rc = PTR_ERR(ctx->uphy_pll_clk[pll]); - dev_err(dev, "fail get uphy_pll%d clk %d\n", pll, rc); - ctx->uphy_pll_clk[pll] = NULL; - return rc; - } - } - - /* FIXME: lock */ - TRACE_DEV(dev, "clients %d", ctx->uphy_pll_clients[pll]); - if (ctx->uphy_pll_clients[pll]++ > 0) - goto done; - - tegra_periph_reset_deassert(ctx->uphy_pll_clk[pll]); - rc = __uphy_pll_init(ctx, pll); - -done: - return rc; -} - -static int uphy_pll_deinit(struct tegra_padctl_uphy *ctx, int pll) -{ - struct device *dev = ctx->dev; - - TRACE_DEV(dev, "clients %d", ctx->uphy_pll_clients[pll]); - ctx->uphy_pll_clients[pll]--; - - TRACE("FIXME: implement!\n"); /* TODO */ - return 0; -} - -static int uphy_lane_init(struct tegra_padctl_uphy *ctx, int lane) -{ - struct device *dev = ctx->dev; - char clk_name[] = "uphy_laneX"; - int rc; - - if (lane < 0 || lane > 5) - return -EINVAL; - - if (!ctx->uphy_lane_clk[lane]) { - snprintf(clk_name, sizeof(clk_name), "uphy_lane%d", lane); - ctx->uphy_lane_clk[lane] = clk_get_sys(NULL, clk_name); - - if (IS_ERR(ctx->uphy_lane_clk[lane])) { - rc = PTR_ERR(ctx->uphy_lane_clk[lane]); - dev_err(dev, "fail get uphy_lane%d clk %d\n", lane, rc); - ctx->uphy_lane_clk[lane] = NULL; - return rc; - } - } - - tegra_periph_reset_deassert(ctx->uphy_lane_clk[lane]); - - return 0; -} - -static int uphy_lane_deinit(struct tegra_padctl_uphy *ctx, int lane) -{ - if (lane < 0 || lane > 5) - return -EINVAL; - - if (ctx->uphy_lane_clk[lane]) - tegra_periph_reset_assert(ctx->uphy_lane_clk[lane]); - - return 0; -} - - -#define PIN_OTG_0 0 -#define PIN_OTG_1 1 -#define PIN_OTG_2 2 -#define PIN_OTG_3 3 -#define PIN_HSIC_0 4 -#define PIN_HSIC_1 5 -#define PIN_UPHY_0 6 -#define PIN_UPHY_1 7 -#define PIN_UPHY_2 8 -#define PIN_UPHY_3 9 -#define PIN_UPHY_4 10 -#define PIN_UPHY_5 11 -#define PIN_UPHY_6 12 -#define PIN_SATA_0 13 - -static inline bool lane_is_otg(unsigned int lane) -{ - return lane >= PIN_OTG_0 && lane <= PIN_OTG_3; -} - -static inline bool lane_is_hsic(unsigned int lane) -{ - return lane >= PIN_HSIC_0 && lane <= PIN_HSIC_1; -} - -static inline bool lane_is_uphy(unsigned int lane) -{ - return lane >= PIN_UPHY_0 && lane <= PIN_UPHY_6; -} - -static inline bool lane_is_pcie_or_sata(unsigned int lane) -{ - return lane >= PIN_UPHY_0 && lane <= PIN_SATA_0; -} - -static int lane_to_usb3_port(struct tegra_padctl_uphy *padctl, - unsigned int lane) -{ - unsigned int i; - - for (i = 0; i < TEGRA_XUSB_USB3_PHYS; i++) { - if (padctl->usb3_ports[i].lane == lane) - return i; - } - - return -EINVAL; -} - -static int tegra_xusb_padctl_get_groups_count(struct pinctrl_dev *pinctrl) -{ - struct tegra_padctl_uphy *padctl = pinctrl_dev_get_drvdata(pinctrl); - - TRACE("num_pins %u", padctl->soc->num_pins); - return padctl->soc->num_pins; -} - -static const char *tegra_xusb_padctl_get_group_name(struct pinctrl_dev *pinctrl, - unsigned int group) -{ - struct tegra_padctl_uphy *padctl = pinctrl_dev_get_drvdata(pinctrl); - - TRACE("group %u name %s", group, padctl->soc->pins[group].name); - return padctl->soc->pins[group].name; -} - -static int tegra_xusb_padctl_get_group_pins(struct pinctrl_dev *pinctrl, - unsigned group, - const unsigned **pins, - unsigned *num_pins) -{ - struct tegra_padctl_uphy *padctl = pinctrl_dev_get_drvdata(pinctrl); - - *pins = &padctl->soc->pins[group].number; - *num_pins = 1; /* one pin per group */ - - TRACE("group %u num_pins %u pins[0] %u", group, *num_pins, *pins[0]); - - return 0; -} - -enum tegra_xusb_padctl_param { - TEGRA_XUSB_PADCTL_USB3_PORT, - TEGRA_XUSB_PADCTL_USB2_PORT, -}; - -static const struct tegra_xusb_padctl_property { - const char *name; - enum tegra_xusb_padctl_param param; -} properties[] = { - {"nvidia,usb3-port", TEGRA_XUSB_PADCTL_USB3_PORT}, - {"nvidia,usb2-port", TEGRA_XUSB_PADCTL_USB2_PORT}, -}; - -#define TEGRA_XUSB_PADCTL_PACK(param, value) ((param) << 16 | (value)) -#define TEGRA_XUSB_PADCTL_UNPACK_PARAM(config) ((config) >> 16) -#define TEGRA_XUSB_PADCTL_UNPACK_VALUE(config) ((config) & 0xffff) - -static int tegra186_padctl_uphy_parse_subnode(struct tegra_padctl_uphy *padctl, - struct device_node *np, - struct pinctrl_map **maps, - unsigned int *reserved_maps, - unsigned int *num_maps) -{ - unsigned int i, reserve = 0, num_configs = 0; - unsigned long config, *configs = NULL; - const char *function, *group; - struct property *prop; - int err = 0; - u32 value; - - TRACE(); - err = of_property_read_string(np, "nvidia,function", &function); - TRACE("err %d function %s", err, function ? function : "(null)"); - if (err < 0) { - if (err != -EINVAL) - return err; - - function = NULL; - } - - for (i = 0; i < ARRAY_SIZE(properties); i++) { - err = of_property_read_u32(np, properties[i].name, &value); - TRACE("err %d property %s (%d) value %d", - err, properties[i].name, i, value); - if (err < 0) { - if (err == -EINVAL) - continue; - - return err; - } - - config = TEGRA_XUSB_PADCTL_PACK(properties[i].param, value); - - err = pinctrl_utils_add_config(padctl->pinctrl, &configs, - &num_configs, config); - TRACE("err %d num_configs %d", err, num_configs); - if (err < 0) - return err; - } - - if (function) - reserve++; - - if (num_configs) - reserve++; - - err = of_property_count_strings(np, "nvidia,lanes"); - TRACE("of_property_count_strings(\"nvidia,lanes\") %d", err); - if (err < 0) - return err; - - reserve *= err; - - err = pinctrl_utils_reserve_map(padctl->pinctrl, maps, reserved_maps, - num_maps, reserve); - TRACE("pinctrl_utils_reserve_map reserve %d num_maps %d err %d", - reserve, *num_maps, err); - if (err < 0) - return err; - - of_property_for_each_string(np, "nvidia,lanes", prop, group) { - if (function) { - err = pinctrl_utils_add_map_mux(padctl->pinctrl, maps, - reserved_maps, num_maps, group, - function); - TRACE("pinctrl_utils_add_map_mux() err %d num_maps %u group %s function %s", - err, *num_maps, group, function); - if (err < 0) - return err; - } - - if (num_configs) { - err = pinctrl_utils_add_map_configs(padctl->pinctrl, - maps, reserved_maps, num_maps, group, - configs, num_configs, - PIN_MAP_TYPE_CONFIGS_GROUP); - TRACE("pinctrl_utils_add_map_configs() err %d", err); - if (err < 0) - return err; - } - } - - return 0; -} - -static int tegra_xusb_padctl_dt_node_to_map(struct pinctrl_dev *pinctrl, - struct device_node *parent, - struct pinctrl_map **maps, - unsigned int *num_maps) -{ - struct tegra_padctl_uphy *padctl = pinctrl_dev_get_drvdata(pinctrl); - unsigned int reserved_maps = 0; - struct device_node *np; - int err; - - *num_maps = 0; - *maps = NULL; - - pr_info("%s %d\n", __func__, __LINE__); - for_each_child_of_node(parent, np) { - err = tegra186_padctl_uphy_parse_subnode(padctl, np, maps, - &reserved_maps, - num_maps); - if (err < 0) { - pr_info("%s %d err %d\n", __func__, __LINE__, err); - return err; - } - } - - return 0; -} - -static const struct pinctrl_ops tegra_xusb_padctl_pinctrl_ops = { - .get_groups_count = tegra_xusb_padctl_get_groups_count, - .get_group_name = tegra_xusb_padctl_get_group_name, - .get_group_pins = tegra_xusb_padctl_get_group_pins, - .dt_node_to_map = tegra_xusb_padctl_dt_node_to_map, - .dt_free_map = pinctrl_utils_dt_free_map, -}; - -static int tegra186_padctl_uphy_get_functions_count(struct pinctrl_dev *pinctrl) -{ - struct tegra_padctl_uphy *padctl = pinctrl_dev_get_drvdata(pinctrl); - - TRACE("num_functions %u", padctl->soc->num_functions); - return padctl->soc->num_functions; -} - -static const char * -tegra186_padctl_uphy_get_function_name(struct pinctrl_dev *pinctrl, - unsigned int function) -{ - struct tegra_padctl_uphy *padctl = pinctrl_dev_get_drvdata(pinctrl); - - TRACE("function %u name %s", function, padctl->soc->functions[function].name); - return padctl->soc->functions[function].name; -} - -static int tegra186_padctl_uphy_get_function_groups(struct pinctrl_dev *pinctrl, - unsigned int function, - const char * const **groups, - unsigned * const num_groups) -{ - struct tegra_padctl_uphy *padctl = pinctrl_dev_get_drvdata(pinctrl); - - *num_groups = padctl->soc->functions[function].num_groups; - *groups = padctl->soc->functions[function].groups; - - TRACE("function %u *num_groups %u groups %s", - function, *num_groups, *groups[0]); - return 0; -} - -static int tegra186_padctl_uphy_pinmux_enable(struct pinctrl_dev *pinctrl, - unsigned int function, - unsigned int group) -{ - struct tegra_padctl_uphy *ctx = pinctrl_dev_get_drvdata(pinctrl); - const struct tegra_padctl_uphy_lane *lane; - unsigned int i; - u32 value; - - lane = &ctx->soc->lanes[group]; - - TRACE_DEV(pinctrl->dev, "group %u (%s) function %u num_funcs %d", - group, lane->name, function, lane->num_funcs); - - for (i = 0; i < lane->num_funcs; i++) { - TRACE_DEV(pinctrl->dev, "funcs[%d] %d", i, lane->funcs[i]); - if (lane->funcs[i] == function) - break; - } - - if (i >= lane->num_funcs) - return -EINVAL; - - TRACE_DEV(pinctrl->dev, "group %s set to function %d", lane->name, i); - - if (lane_is_otg(group) || lane_is_hsic(group)) { - value = padctl_readl(ctx, lane->offset); - value &= ~(lane->mask << lane->shift); - value |= i << lane->shift; - padctl_writel(ctx, value, lane->offset); - } else if (lane_is_uphy(group)) { - int uphy_lane = group - PIN_UPHY_0; - if (function == TEGRA186_FUNC_USB3) - set_bit(uphy_lane, &ctx->usb3_lanes); - else if (function == TEGRA186_FUNC_PCIE) - set_bit(uphy_lane, &ctx->pcie_lanes); - else if (function == TEGRA186_FUNC_SATA) - set_bit(uphy_lane, &ctx->sata_lanes); - else if (function == TEGRA186_FUNC_MPHY) - set_bit(uphy_lane, &ctx->ufs_lanes); -#if 0 - value = uphy_lane_readl(ctx, uphy_lane, lane->offset); - value &= ~(lane->mask << lane->shift); - value |= i << lane->shift; - uphy_lane_writel(ctx, uphy_lane, value, lane->offset); -#endif - } else - return -EINVAL; - - return 0; -} - -static const struct pinmux_ops tegra186_padctl_uphy_pinmux_ops = { - .get_functions_count = tegra186_padctl_uphy_get_functions_count, - .get_function_name = tegra186_padctl_uphy_get_function_name, - .get_function_groups = tegra186_padctl_uphy_get_function_groups, - .enable = tegra186_padctl_uphy_pinmux_enable, -}; - -static int tegra_xusb_padctl_pinconf_group_get(struct pinctrl_dev *pinctrl, - unsigned int group, - unsigned long *config) -{ - struct tegra_padctl_uphy *padctl = pinctrl_dev_get_drvdata(pinctrl); - const struct tegra_padctl_uphy_lane *lane; - enum tegra_xusb_padctl_param param; - int value = 0; - int port; - - param = TEGRA_XUSB_PADCTL_UNPACK_PARAM(*config); - lane = &padctl->soc->lanes[group]; - - TRACE("group %u param 0x%x\n", group, param); - - switch (param) { - case TEGRA_XUSB_PADCTL_USB3_PORT: - value = lane_to_usb3_port(padctl, group); - if (value < 0) { - dev_err(padctl->dev, - "Pin %d not mapped to USB3 port\n", group); - return -EINVAL; - } - break; - - case TEGRA_XUSB_PADCTL_USB2_PORT: - port = lane_to_usb3_port(padctl, group); - if (port < 0) { - dev_err(padctl->dev, - "Pin %d not mapped to USB3 port\n", group); - return -EINVAL; - } - - break; - - default: - dev_err(padctl->dev, "invalid configuration parameter: %04x\n", - param); - return -ENOTSUPP; - } - - *config = TEGRA_XUSB_PADCTL_PACK(param, value); - return 0; -} - -#if 0 -static int tegra_xusb_padctl_pinconf_group_set(struct pinctrl_dev *pinctrl, - unsigned int group, - unsigned long *configs, - unsigned int num_configs) -{ - struct tegra_padctl_uphy *padctl = pinctrl_dev_get_drvdata(pinctrl); - const struct tegra_padctl_uphy_lane *lane; - enum tegra_xusb_padctl_param param; - unsigned long value; - unsigned int i; - int port; - - lane = &padctl->soc->lanes[group]; - - for (i = 0; i < num_configs; i++) { - param = TEGRA_XUSB_PADCTL_UNPACK_PARAM(configs[i]); - value = TEGRA_XUSB_PADCTL_UNPACK_VALUE(configs[i]); - - TRACE("group %u config %d param 0x%x value 0x%lx", - group, i, param, value); - - switch (param) { - case TEGRA_XUSB_PADCTL_USB3_PORT: - if (value >= TEGRA_XUSB_USB3_PHYS) { - dev_err(padctl->dev, "Invalid USB3 port: %lu\n", - value); - return -EINVAL; - } - if (!lane_is_uphy(group)) { - dev_err(padctl->dev, - "USB3 port not applicable for pin %d\n", - group); - return -EINVAL; - } - - padctl->usb3_ports[value].lane = group; - break; - - case TEGRA_XUSB_PADCTL_USB2_PORT: - if (value >= TEGRA_XUSB_UTMI_PHYS) { - dev_err(padctl->dev, "Invalid USB2 port: %lu\n", - value); - return -EINVAL; - } - if (!lane_is_pcie_or_sata(group)) { - dev_err(padctl->dev, - "USB2 port not applicable for pin %d\n", - group); - return -EINVAL; - } - port = lane_to_usb3_port(padctl, group); - if (port < 0) { - dev_err(padctl->dev, - "Pin %d not mapped to USB3 port\n", - group); - return -EINVAL; - } - - break; - - default: - dev_err(padctl->dev, - "invalid configuration parameter: %04x\n", - param); - return -ENOTSUPP; - } - } - - return 0; -} -#else -static int tegra_xusb_padctl_pinconf_group_set(struct pinctrl_dev *pinctrl, - unsigned int group, - unsigned long config) -{ - struct tegra_padctl_uphy *padctl = pinctrl_dev_get_drvdata(pinctrl); - const struct tegra_padctl_uphy_lane *lane; - enum tegra_xusb_padctl_param param; - unsigned long value; - int port; - - lane = &padctl->soc->lanes[group]; - - param = TEGRA_XUSB_PADCTL_UNPACK_PARAM(config); - value = TEGRA_XUSB_PADCTL_UNPACK_VALUE(config); - - TRACE("group %u config 0x%lx param 0x%x value 0x%lx", - group, config, param, value); - - switch (param) { - case TEGRA_XUSB_PADCTL_USB3_PORT: - if (value >= TEGRA_XUSB_USB3_PHYS) { - dev_err(padctl->dev, "Invalid USB3 port: %lu\n", - value); - return -EINVAL; - } - if (!lane_is_uphy(group)) { - dev_err(padctl->dev, - "USB3 port not applicable for pin %d\n", - group); - return -EINVAL; - } - - padctl->usb3_ports[value].lane = group; - break; - - case TEGRA_XUSB_PADCTL_USB2_PORT: - if (value >= TEGRA_XUSB_UTMI_PHYS) { - dev_err(padctl->dev, "Invalid USB2 port: %lu\n", - value); - return -EINVAL; - } - if (!lane_is_pcie_or_sata(group)) { - dev_err(padctl->dev, - "USB2 port not applicable for pin %d\n", - group); - return -EINVAL; - } - port = lane_to_usb3_port(padctl, group); - if (port < 0) { - dev_err(padctl->dev, - "Pin %d not mapped to USB3 port\n", - group); - return -EINVAL; - } - - break; - - default: - dev_err(padctl->dev, - "invalid configuration parameter: %04x\n", - param); - return -ENOTSUPP; - } - - return 0; -} -#endif - -#ifdef CONFIG_DEBUG_FS -static const char *strip_prefix(const char *s) -{ - const char *comma = strchr(s, ','); - if (!comma) - return s; - - return comma + 1; -} - -static void -tegra_xusb_padctl_pinconf_group_dbg_show(struct pinctrl_dev *pinctrl, - struct seq_file *s, - unsigned int group) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(properties); i++) { - unsigned long config, value; - int err; - - config = TEGRA_XUSB_PADCTL_PACK(properties[i].param, 0); - - err = tegra_xusb_padctl_pinconf_group_get(pinctrl, group, - &config); - if (err < 0) - continue; - - value = TEGRA_XUSB_PADCTL_UNPACK_VALUE(config); - - seq_printf(s, "\n\t%s=%lu\n", strip_prefix(properties[i].name), - value); - } -} - -static void -tegra_xusb_padctl_pinconf_config_dbg_show(struct pinctrl_dev *pinctrl, - struct seq_file *s, - unsigned long config) -{ - enum tegra_xusb_padctl_param param; - const char *name = "unknown"; - unsigned long value; - unsigned int i; - - param = TEGRA_XUSB_PADCTL_UNPACK_PARAM(config); - value = TEGRA_XUSB_PADCTL_UNPACK_VALUE(config); - - for (i = 0; i < ARRAY_SIZE(properties); i++) { - if (properties[i].param == param) { - name = properties[i].name; - break; - } - } - - seq_printf(s, "%s=%lu", strip_prefix(name), value); -} -#endif - -static const struct pinconf_ops tegra_xusb_padctl_pinconf_ops = { - .pin_config_group_get = tegra_xusb_padctl_pinconf_group_get, - .pin_config_group_set = tegra_xusb_padctl_pinconf_group_set, -#ifdef CONFIG_DEBUG_FS - .pin_config_group_dbg_show = tegra_xusb_padctl_pinconf_group_dbg_show, - .pin_config_config_dbg_show = tegra_xusb_padctl_pinconf_config_dbg_show, -#endif -}; - -static int tegra_xusb_padctl_enable(struct tegra_padctl_uphy *ctx) -{ - - mutex_lock(&ctx->lock); - TRACE_DEV(ctx->dev, "padctl_clients %d", ctx->padctl_clients); - - if (ctx->padctl_clients++ > 0) - goto out; - -out: - mutex_unlock(&ctx->lock); - return 0; -} - -static int tegra_xusb_padctl_disable(struct tegra_padctl_uphy *ctx) -{ - - mutex_lock(&ctx->lock); - - TRACE_DEV(ctx->dev, "padctl_clients %d", ctx->padctl_clients); - - if (WARN_ON(ctx->padctl_clients == 0)) - goto out; - - if (--ctx->padctl_clients > 0) - goto out; - -out: - mutex_unlock(&ctx->lock); - return 0; -} - -static int tegra_xusb_phy_init(struct phy *phy) -{ - struct tegra_padctl_uphy *padctl = phy_get_drvdata(phy); - - return tegra_xusb_padctl_enable(padctl); -} - -static int tegra_xusb_phy_exit(struct phy *phy) -{ - struct tegra_padctl_uphy *padctl = phy_get_drvdata(phy); - - return tegra_xusb_padctl_disable(padctl); -} - -static int tegra186_pcie_phy_power_on(struct phy *phy) -{ - struct tegra_padctl_uphy *ctx = phy_get_drvdata(phy); - unsigned int uphy_lane; - u32 reg; - - for_each_set_bit(uphy_lane, &ctx->pcie_lanes, T186_UPHY_LANES) { - TRACE_DEV(&phy->dev, "lane %d", uphy_lane); - - reg = uphy_lane_readl(ctx, uphy_lane, UPHY_LANE_MUX); - reg &= SEL(~0); - reg |= SEL_PCIE; - reg |= FORCE_IDDQ_DISABLE; - reg &= ~CLAMP_EN_EARLY; - uphy_lane_writel(ctx, uphy_lane, reg, UPHY_LANE_MUX); - } - - TRACE_DEV(&phy->dev, "FIXME: implement!"); /* TODO: more? */ - return 0; -} - -static int tegra186_pcie_phy_power_off(struct phy *phy) -{ - struct tegra_padctl_uphy *ctx = phy_get_drvdata(phy); - unsigned int uphy_lane; - u32 reg; - - for_each_set_bit(uphy_lane, &ctx->pcie_lanes, T186_UPHY_LANES) { - TRACE_DEV(&phy->dev, "lane %d", uphy_lane); - - reg = uphy_lane_readl(ctx, uphy_lane, UPHY_LANE_MUX); - reg &= ~FORCE_IDDQ_DISABLE; - reg |= CLAMP_EN_EARLY; - uphy_lane_writel(ctx, uphy_lane, reg, UPHY_LANE_MUX); - } - - TRACE_DEV(&phy->dev, "FIXME: implement!"); /* TODO */ - return 0; -} - -static int tegra186_pcie_phy_init(struct phy *phy) -{ - struct tegra_padctl_uphy *ctx = phy_get_drvdata(phy); - unsigned uphy_lane; - - for_each_set_bit(uphy_lane, &ctx->pcie_lanes, T186_UPHY_LANES) { - TRACE_DEV(&phy->dev, "lane %d", uphy_lane); - - uphy_pll_init(ctx, 0); - uphy_lane_init(ctx, uphy_lane); - pcie_lane_defaults(ctx, uphy_lane); - pcie_usb3_pll_defaults(ctx); - } - - return tegra_xusb_phy_init(phy); -} - -static int tegra186_pcie_phy_exit(struct phy *phy) -{ - struct tegra_padctl_uphy *ctx = phy_get_drvdata(phy); - unsigned uphy_lane; - - for_each_set_bit(uphy_lane, &ctx->pcie_lanes, T186_UPHY_LANES) { - TRACE_DEV(&phy->dev, "lane %d", uphy_lane); - - uphy_lane_deinit(ctx, uphy_lane); - uphy_pll_deinit(ctx, 0); - } - - return tegra_xusb_phy_exit(phy); -} - -static const struct phy_ops pcie_phy_ops = { - .init = tegra186_pcie_phy_init, - .exit = tegra186_pcie_phy_exit, - .power_on = tegra186_pcie_phy_power_on, - .power_off = tegra186_pcie_phy_power_off, - .owner = THIS_MODULE, -}; - -static int tegra186_sata_phy_power_on(struct phy *phy) -{ - struct tegra_padctl_uphy *ctx = phy_get_drvdata(phy); - unsigned int uphy_lane; - u32 reg; - - for_each_set_bit(uphy_lane, &ctx->sata_lanes, T186_UPHY_LANES) { - TRACE_DEV(&phy->dev, "lane %d", uphy_lane); - - reg = uphy_lane_readl(ctx, uphy_lane, UPHY_LANE_MUX); - reg &= SEL(~0); - reg |= SEL_SATA; - reg |= FORCE_IDDQ_DISABLE; - reg &= ~CLAMP_EN_EARLY; - uphy_lane_writel(ctx, uphy_lane, reg, UPHY_LANE_MUX); - } - - TRACE_DEV(&phy->dev, "FIXME: implement!"); /* TODO: more? */ - return 0; -} - -static int tegra186_sata_phy_power_off(struct phy *phy) -{ - struct tegra_padctl_uphy *ctx = phy_get_drvdata(phy); - unsigned int uphy_lane; - u32 reg; - - for_each_set_bit(uphy_lane, &ctx->sata_lanes, T186_UPHY_LANES) { - TRACE_DEV(&phy->dev, "lane %d", uphy_lane); - - reg = uphy_lane_readl(ctx, uphy_lane, UPHY_LANE_MUX); - reg &= ~FORCE_IDDQ_DISABLE; - reg |= CLAMP_EN_EARLY; - uphy_lane_writel(ctx, uphy_lane, reg, UPHY_LANE_MUX); - } - - TRACE_DEV(&phy->dev, "FIXME: implement!"); /* TODO */ - return 0; -} - -static int tegra186_sata_fuse_calibration(struct tegra_padctl_uphy *ctx, - int lane) -{ - void __iomem *base; - u32 reg; - int idx, err; - - if (ctx->sata_bypass_fuse && ctx->prod_list) { - base = ctx->uphy_lane_regs[lane]; - err = tegra_prod_set_by_name(&base, - "prod_c_sata", ctx->prod_list); - if (!err) - return 0; - - /* In case of err update setting based on fuse */ - dev_warn(ctx->dev, - "Failed to set sata prod settings, err %d", err); - } - - /* Update based on fuse_sata_nv_calib[1:0] value */ - idx = SATA_NV_CALIB_0_1(ctx->fuse_calib.sata_nv); - - reg = uphy_lane_readl(ctx, lane, UPHY_LANE_AUX_CTL_1); - reg |= AUX_RX_IDLE_TH(sata_data[idx].aux_rx_idle_th); - uphy_lane_writel(ctx, lane, reg, UPHY_LANE_AUX_CTL_1); - - /* Update based on fuse_sata_nv_calib[3:2] value TBD */ - idx = SATA_NV_CALIB_2_3(ctx->fuse_calib.sata_nv); - - /* Update based on fuse_sata_mphy_odm_calib[1:0] value */ - idx = SATA_MPHY_ODM_CALIB_0_1(ctx->fuse_calib.sata_mphy_odm); - - reg = uphy_lane_readl(ctx, lane, UPHY_LANE_DYN_CTL_1); - reg |= TX_DRV_AMP_SEL0(sata_data[idx].tx_drv_amp_sel0); - reg |= TX_DRV_AMP_SEL1(sata_data[idx].tx_drv_amp_sel1); - uphy_lane_writel(ctx, lane, reg, UPHY_LANE_DYN_CTL_1); - - reg = uphy_lane_readl(ctx, lane, UPHY_LANE_DYN_CTL_4); - reg |= TX_DRV_POST_SEL0(sata_data[idx].tx_drv_post_sel0); - reg |= TX_DRV_POST_SEL1(sata_data[idx].tx_drv_post_sel1); - uphy_lane_writel(ctx, lane, reg, UPHY_LANE_DYN_CTL_4); - - reg = CFG_ADDR(AE_CTLE_CTRL_ID0); - reg |= CFG_WDATA(sata_data[idx].ae_ctle_ctrl_id0); - uphy_lane_writel(ctx, lane, reg, UPHY_LANE_DIRECT_CTL_2); - - reg = CFG_ADDR(AE_CTLE_CTRL_ID1); - reg |= CFG_WDATA(sata_data[idx].ae_ctle_ctrl_id1); - uphy_lane_writel(ctx, lane, reg, UPHY_LANE_DIRECT_CTL_2); - - return 0; -} - -static int tegra186_sata_phy_init(struct phy *phy) -{ - struct tegra_padctl_uphy *ctx = phy_get_drvdata(phy); - unsigned uphy_lane; - - sata_pll_init(ctx); - - for_each_set_bit(uphy_lane, &ctx->sata_lanes, T186_UPHY_LANES) { - TRACE_DEV(&phy->dev, "uphy_lane %u\n", uphy_lane); - sata_lane_init(ctx, uphy_lane); - } - - tegra186_sata_fuse_calibration(ctx, ctx->sata_lanes); - - return tegra_xusb_phy_init(phy); -} - -static int tegra186_sata_phy_exit(struct phy *phy) -{ - TRACE_DEV(&phy->dev, ""); - return tegra_xusb_phy_exit(phy); -} - -static const struct phy_ops sata_phy_ops = { - .init = tegra186_sata_phy_init, - .exit = tegra186_sata_phy_exit, - .power_on = tegra186_sata_phy_power_on, - .power_off = tegra186_sata_phy_power_off, - .owner = THIS_MODULE, -}; - - -static int tegra186_ufs_phy_power_on(struct phy *phy) -{ - - return 0; -} - -static int tegra186_ufs_phy_power_off(struct phy *phy) -{ - struct tegra_padctl_uphy *ctx = phy_get_drvdata(phy); - unsigned int uphy_lane; - u32 reg; - - TRACE(); - for_each_set_bit(uphy_lane, &ctx->ufs_lanes, T186_UPHY_LANES) { - TRACE_DEV(&phy->dev, "lane %d", uphy_lane); - reg = uphy_lane_readl(ctx, uphy_lane, UPHY_LANE_MUX); - reg &= ~FORCE_IDDQ_DISABLE; - reg |= CLAMP_EN_EARLY; - uphy_lane_writel(ctx, uphy_lane, reg, UPHY_LANE_MUX); - } - - return 0; -} - -static void tegra186_uphy_lane_pad_macro(bool on) -{ - void __iomem *car_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE); - u32 reg; - - reg = ioread32(car_base + CLK_RST_CONTROLLER_RST_DEV_UPHY_0); - if (on) - reg |= SWR_UPHY_RST; - else - reg &= ~SWR_UPHY_RST; - iowrite32(reg, car_base + CLK_RST_CONTROLLER_RST_DEV_UPHY_0); -} - -static void tegra186_uphy_lane_and_pll_reset(int function, unsigned long lanes) -{ - void __iomem *car_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE); - unsigned uphy_lane; - u32 reg; - - reg = ioread32(car_base + CLK_RST_CONTROLLER_RST_DEV_PEX_USB_UPHY_0); - - /* De-assert global reset */ - reg |= SWR_PEX_USB_UPHY_RST; - - /* De-assert corresponding pll reset */ - if (function == TEGRA186_FUNC_MPHY) - reg &= ~SWR_PEX_USB_UPHY_PLL1_RST; - else - reg &= ~SWR_PEX_USB_UPHY_PLL0_RST; - - /* De-assert corresponding lane reset */ - for_each_set_bit(uphy_lane, &lanes, T186_UPHY_LANES) { - reg &= ~SWR_PEX_USB_UPHY_LANE_RST(uphy_lane); - } - - iowrite32(reg, car_base + CLK_RST_CONTROLLER_RST_DEV_PEX_USB_UPHY_0); -} - -static int tegra186_ufs_fuse_calibration(struct tegra_padctl_uphy *ctx, - int lane) -{ - u32 reg; - int idx; - - /* Update based on fuse_mphy_nv_calib[1:0] value */ - idx = MPHY_NV_CALIB_0_1(ctx->fuse_calib.mphy_nv); - - reg = uphy_lane_readl(ctx, lane, UPHY_LANE_AUX_CTL_1); - reg |= AUX_RX_IDLE_TH(mphy_data[idx].aux_rx_idle_th); - uphy_lane_writel(ctx, lane, reg, UPHY_LANE_AUX_CTL_1); - - /* Update based on fuse_mphy_nv_calib[3:2] value TBD */ - idx = MPHY_NV_CALIB_2_3(ctx->fuse_calib.mphy_nv); - - - /* Update based on fuse_mphy_nv_calib[5:4] value TBD */ - idx = MPHY_NV_CALIB_4_5(ctx->fuse_calib.mphy_nv); - - - /* Update based on fuse_sata_mphy_odm_calib[1:0] value */ - idx = SATA_MPHY_ODM_CALIB_0_1(ctx->fuse_calib.sata_mphy_odm); - - reg = uphy_lane_readl(ctx, lane, UPHY_LANE_DYN_CTL_1); - reg |= TX_DRV_AMP_SEL0(mphy_data[idx].tx_drv_amp_sel0); - reg |= TX_DRV_AMP_SEL1(mphy_data[idx].tx_drv_amp_sel1); - reg |= TX_DRV_AMP_SEL2(mphy_data[idx].tx_drv_amp_sel2); - reg |= TX_DRV_AMP_SEL3(mphy_data[idx].tx_drv_amp_sel3); - uphy_lane_writel(ctx, lane, reg, UPHY_LANE_DYN_CTL_1); - - reg = uphy_lane_readl(ctx, lane, UPHY_LANE_DYN_CTL_2); - reg |= TX_DRV_AMP_SEL4(mphy_data[idx].tx_drv_amp_sel4); - reg |= TX_DRV_AMP_SEL5(mphy_data[idx].tx_drv_amp_sel5); - reg |= TX_DRV_AMP_SEL6(mphy_data[idx].tx_drv_amp_sel6); - reg |= TX_DRV_AMP_SEL7(mphy_data[idx].tx_drv_amp_sel7); - uphy_lane_writel(ctx, lane, reg, UPHY_LANE_DYN_CTL_2); - - reg = uphy_lane_readl(ctx, lane, UPHY_LANE_DYN_CTL_3); - reg |= TX_DRV_AMP_SEL8(mphy_data[idx].tx_drv_amp_sel8); - reg |= TX_DRV_AMP_SEL9(mphy_data[idx].tx_drv_amp_sel9); - uphy_lane_writel(ctx, lane, reg, UPHY_LANE_DYN_CTL_3); - - reg = uphy_lane_readl(ctx, lane, UPHY_LANE_DYN_CTL_4); - reg |= TX_DRV_POST_SEL0(mphy_data[idx].tx_drv_post_sel0); - reg |= TX_DRV_POST_SEL1(mphy_data[idx].tx_drv_post_sel1); - uphy_lane_writel(ctx, lane, reg, UPHY_LANE_DYN_CTL_4); - - reg = uphy_lane_readl(ctx, lane, UPHY_LANE_DYN_CTL_5); - reg |= TX_DRV_POST_SEL2(mphy_data[idx].tx_drv_post_sel2); - reg |= TX_DRV_POST_SEL3(mphy_data[idx].tx_drv_post_sel3); - reg |= TX_DRV_PRE_SEL3(mphy_data[idx].tx_drv_pre_sel3); - uphy_lane_writel(ctx, lane, reg, UPHY_LANE_DYN_CTL_5); - - return 0; -} - -static int tegra186_ufs_phy_init(struct phy *phy) -{ - struct tegra_padctl_uphy *ctx = phy_get_drvdata(phy); - unsigned uphy_lane; - u32 reg; - - TRACE(); - /* FIXME: step 1: Enable refplle to 208M and pllp 102M */ - - /* step 2: De-assert UPHY LANE PAD Macro */ - /* FIXME: Should be part of probe ? */ - tegra186_uphy_lane_pad_macro(false); - - /* Bring the lanes out of IDDQ, remove clamps, select MPHY for mux */ - for_each_set_bit(uphy_lane, &ctx->ufs_lanes, T186_UPHY_LANES) { - reg = uphy_lane_readl(ctx, uphy_lane, UPHY_LANE_MUX); - reg &= SEL(~0); - reg |= SEL_MPHY; - reg |= FORCE_IDDQ_DISABLE; - reg &= ~CLAMP_EN_EARLY; - uphy_lane_writel(ctx, uphy_lane, reg, UPHY_LANE_MUX); - } - - /* FIXME: bring refPLLE to under HW control. Needed ? */ - - - /* step 3: Enable PLL1 and lane by releasing resets */ - tegra186_uphy_lane_and_pll_reset(TEGRA186_FUNC_MPHY, ctx->ufs_lanes); - - /* pll parameters init */ - ufs_pll_init(ctx); - - /* lane parameters init */ - for_each_set_bit(uphy_lane, &ctx->ufs_lanes, T186_UPHY_LANES) { - TRACE_DEV(&phy->dev, "uphy_lane %u\n", uphy_lane); - ufs_lane_init(ctx, uphy_lane); - } - - /* step 4: electrical parameters programming based on fuses */ - for_each_set_bit(uphy_lane, &ctx->ufs_lanes, T186_UPHY_LANES) - tegra186_ufs_fuse_calibration(ctx, uphy_lane); - - /* step 5: rate id programming */ - ufs_pll_rateid_init(ctx); - ufs_lane_rateid_init(ctx, ctx->ufs_lanes); - - /* step 6: uphy pll1 calibration */ - uphy_pll_init(ctx, 0); - - /* FIXME: Need to add MPHY programming in above step ? */ - - return tegra_xusb_phy_init(phy); -} - -static int tegra186_ufs_phy_exit(struct phy *phy) -{ - TRACE_DEV(&phy->dev, ""); - return tegra_xusb_phy_exit(phy); -} - -static const struct phy_ops ufs_phy_ops = { - .init = tegra186_ufs_phy_init, - .exit = tegra186_ufs_phy_exit, - .power_on = tegra186_ufs_phy_power_on, - .power_off = tegra186_ufs_phy_power_off, - .owner = THIS_MODULE, -}; - -static int usb3_phy_to_port(struct phy *phy) -{ - struct tegra_padctl_uphy *ctx = phy_get_drvdata(phy); - unsigned int i; - - for (i = 0; i < TEGRA_XUSB_USB3_PHYS; i++) { - if (phy == ctx->usb3_phys[i]) - return i; - } - WARN_ON(1); - - return -EINVAL; -} - -static int tegra186_usb3_phy_power_on(struct phy *phy) -{ - struct tegra_padctl_uphy *ctx = phy_get_drvdata(phy); - int port = usb3_phy_to_port(phy); - unsigned int uphy_lane; - unsigned int lane; - u32 reg; - - TRACE_DEV(&phy->dev, "port %d", port); - if (port < 0) - return port; - - lane = ctx->usb3_ports[port].lane; - if (!lane_is_uphy(lane)) { - dev_err(ctx->dev, "USB3 PHY %d mapped to invalid lane: %d\n", - port, lane); - return -EINVAL; - } - - reg = padctl_readl(ctx, XUSB_PADCTL_SS_PORT_CAP); - reg &= ~(PORT_CAP_MASK << PORTX_CAP_SHIFT(port)); - reg |= (PORT_CAP_HOST << PORTX_CAP_SHIFT(port)); - padctl_writel(ctx, reg, XUSB_PADCTL_SS_PORT_CAP); - - uphy_lane = lane - PIN_UPHY_0; - reg = uphy_lane_readl(ctx, uphy_lane, UPHY_LANE_MUX); - reg &= SEL(~0); - reg |= SEL_XUSB; - reg |= FORCE_IDDQ_DISABLE; - reg &= ~CLAMP_EN_EARLY; - uphy_lane_writel(ctx, uphy_lane, reg, UPHY_LANE_MUX); - - reg = padctl_readl(ctx, XUSB_PADCTL_ELPG_PROGRAM_1); - reg &= ~SSPX_ELPG_CLAMP_EN_EARLY(port); - padctl_writel(ctx, reg, XUSB_PADCTL_ELPG_PROGRAM_1); - - usleep_range(100, 200); - - reg = padctl_readl(ctx, XUSB_PADCTL_ELPG_PROGRAM_1); - reg &= ~SSPX_ELPG_CLAMP_EN_EARLY(port); - padctl_writel(ctx, reg, XUSB_PADCTL_ELPG_PROGRAM_1); - - reg = padctl_readl(ctx, XUSB_PADCTL_ELPG_PROGRAM_1); - reg &= ~SSPX_ELPG_VCORE_DOWN(port); - padctl_writel(ctx, reg, XUSB_PADCTL_ELPG_PROGRAM_1); - - return 0; -} - -static int tegra186_usb3_phy_power_off(struct phy *phy) -{ - struct tegra_padctl_uphy *ctx = phy_get_drvdata(phy); - int port = usb3_phy_to_port(phy); - unsigned int uphy_lane; - unsigned int lane; - u32 reg; - - TRACE_DEV(&phy->dev, "port %d", port); - if (port < 0) - return port; - - lane = ctx->usb3_ports[port].lane; - if (!lane_is_uphy(lane)) { - dev_err(ctx->dev, "USB3 PHY %d mapped to invalid lane: %d\n", - port, lane); - return -EINVAL; - } - - uphy_lane = lane - PIN_UPHY_0; - reg = uphy_lane_readl(ctx, uphy_lane, UPHY_LANE_MUX); - reg &= ~FORCE_IDDQ_DISABLE; - reg |= CLAMP_EN_EARLY; - uphy_lane_writel(ctx, uphy_lane, reg, UPHY_LANE_MUX); - - reg = padctl_readl(ctx, XUSB_PADCTL_ELPG_PROGRAM_1); - reg |= SSPX_ELPG_CLAMP_EN_EARLY(port); - padctl_writel(ctx, reg, XUSB_PADCTL_ELPG_PROGRAM_1); - - usleep_range(100, 200); - - reg = padctl_readl(ctx, XUSB_PADCTL_ELPG_PROGRAM_1); - reg |= SSPX_ELPG_CLAMP_EN_EARLY(port); - padctl_writel(ctx, reg, XUSB_PADCTL_ELPG_PROGRAM_1); - - usleep_range(250, 350); - - reg = padctl_readl(ctx, XUSB_PADCTL_ELPG_PROGRAM_1); - reg |= SSPX_ELPG_VCORE_DOWN(port); - padctl_writel(ctx, reg, XUSB_PADCTL_ELPG_PROGRAM_1); - - return 0; -} - -static int tegra186_usb3_phy_init(struct phy *phy) -{ - struct tegra_padctl_uphy *ctx = phy_get_drvdata(phy); - int port = usb3_phy_to_port(phy); - unsigned uphy_lane; - unsigned int lane; - - TRACE_DEV(&phy->dev, "port %d", port); - if (port < 0) - return port; - - lane = ctx->usb3_ports[port].lane; - if (!lane_is_uphy(lane)) { - dev_err(ctx->dev, "USB3 PHY %d mapped to invalid lane: %d\n", - port, lane); - return -EINVAL; - } - - uphy_pll_init(ctx, 0); - - uphy_lane = lane - PIN_UPHY_0; - uphy_lane_init(ctx, uphy_lane); - usb3_lane_defaults(ctx, uphy_lane); - pcie_usb3_pll_defaults(ctx); - - return tegra_xusb_phy_init(phy); -} - -static int tegra186_usb3_phy_exit(struct phy *phy) -{ - struct tegra_padctl_uphy *ctx = phy_get_drvdata(phy); - int port = usb3_phy_to_port(phy); - unsigned uphy_lane; - unsigned int lane; - - TRACE_DEV(&phy->dev, "port %d", port); - if (port < 0) - return port; - - lane = ctx->usb3_ports[port].lane; - if (!lane_is_uphy(lane)) { - dev_err(ctx->dev, "USB3 PHY %d mapped to invalid lane: %d\n", - port, lane); - return -EINVAL; - } - - uphy_lane = lane - PIN_UPHY_0; - uphy_lane_deinit(ctx, lane); - uphy_pll_deinit(ctx, 0); - - return tegra_xusb_phy_exit(phy); -} - -static const struct phy_ops usb3_phy_ops = { - .init = tegra186_usb3_phy_init, - .exit = tegra186_usb3_phy_exit, - .power_on = tegra186_usb3_phy_power_on, - .power_off = tegra186_usb3_phy_power_off, - .owner = THIS_MODULE, -}; - -static int utmi_phy_to_port(struct phy *phy) -{ - struct tegra_padctl_uphy *padctl = phy_get_drvdata(phy); - unsigned int i; - - for (i = 0; i < TEGRA_XUSB_UTMI_PHYS; i++) { - if (phy == padctl->utmi_phys[i]) - return i; - } - WARN_ON(1); - - return -EINVAL; -} - -static int tegra186_utmi_phy_power_on(struct phy *phy) -{ - struct tegra_padctl_uphy *padctl = phy_get_drvdata(phy); - int port = utmi_phy_to_port(phy); - int err; - u32 value; - - TRACE_DEV(&phy->dev, "port %d", port); - if (port < 0) - return port; - -#if 0 - value = padctl_readl(padctl, XUSB_PADCTL_USB2_PORT_CAP); - value &= ~(PORT_CAP_MASK << PORTX_CAP_SHIFT(port)); -#if 1 - if (port == 0) /* TODO: support OTG */ - value |= (PORT_CAP_DEVICE << PORTX_CAP_SHIFT(port)); - else -#endif - value |= (PORT_CAP_HOST << PORTX_CAP_SHIFT(port)); - padctl_writel(padctl, value, XUSB_PADCTL_USB2_PORT_CAP); -#endif - - value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(port)); - value &= ~(USB2_OTG_PD | USB2_OTG_PD2 | USB2_OTG_PD_ZI); - value &= ~HS_CURR_LEVEL(~0); - value |= HS_CURR_LEVEL(padctl->calib.hs_curr_level[port]); - padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL0(port)); - - value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL1(port)); - value &= ~USB2_OTG_PD_DR; - value &= ~TERM_RANGE_ADJ(~0); - value |= TERM_RANGE_ADJ(padctl->calib.hs_term_range_adj); - padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL1(port)); - - err = regulator_enable(padctl->vbus[port]); - if (err) - return err; - - mutex_lock(&padctl->lock); - - if (padctl->utmi_enable++ > 0) - goto out; - - value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); - value &= ~BIAS_PAD_PD; - padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); - -out: - mutex_unlock(&padctl->lock); - return 0; -} - -static int tegra186_utmi_phy_power_off(struct phy *phy) -{ - struct tegra_padctl_uphy *padctl = phy_get_drvdata(phy); - int port = utmi_phy_to_port(phy); - u32 value; - - TRACE_DEV(&phy->dev, "port %d", port); - if (port < 0) - return port; - - regulator_disable(padctl->vbus[port]); - - mutex_lock(&padctl->lock); - - if (WARN_ON(padctl->utmi_enable == 0)) - goto out; - - if (--padctl->utmi_enable > 0) - goto out; - - value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); - value |= BIAS_PAD_PD; - padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); - -out: - mutex_unlock(&padctl->lock); - return 0; -} - -static int tegra186_utmi_phy_init(struct phy *phy) -{ - TRACE_DEV(&phy->dev, ""); - return tegra_xusb_phy_init(phy); -} - -static int tegra186_utmi_phy_exit(struct phy *phy) -{ - TRACE_DEV(&phy->dev, ""); - return tegra_xusb_phy_exit(phy); -} - -static const struct phy_ops utmi_phy_ops = { - .init = tegra186_utmi_phy_init, - .exit = tegra186_utmi_phy_exit, - .power_on = tegra186_utmi_phy_power_on, - .power_off = tegra186_utmi_phy_power_off, - .owner = THIS_MODULE, -}; - -#if 0 -static int utmi_phy_set_role(struct phy *phy, bool host) -{ - struct tegra_padctl_uphy *padctl = phy_get_drvdata(phy); - int pad = utmi_phy_to_port(phy); - u32 reg; - - dev_info(&phy->dev, "%s %d port %d\n", __func__, __LINE__, pad); - if (pad < 0) - return pad; - - reg = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL1(pad)); - reg &= ~(VREG_FIX18 | VREG_LEV(~0)); - if (host) - reg |= VREG_FIX18; - else - reg |= VREG_LEV(3); - padctl_writel(padctl, reg, USB2_BATTERY_CHRG_OTGPADX_CTL1(pad)); - - reg = padctl_readl(padctl, USB2_VBUS_ID); - if (host) - reg &= ~VBUS_OVERRIDE; - else - reg |= VBUS_OVERRIDE; - padctl_writel(padctl, reg, USB2_VBUS_ID); - - return 0; -} - -static int tegra_phy_otg_set_host(struct phy *phy) -{ - return utmi_phy_set_role(phy, true); -} - -static int tegra_phy_otg_set_device(struct phy *phy) -{ - return utmi_phy_set_role(phy, false); -} -#endif -static int hsic_phy_to_port(struct phy *phy) -{ - struct tegra_padctl_uphy *padctl = phy_get_drvdata(phy); - unsigned int i; - - for (i = 0; i < TEGRA_XUSB_HSIC_PHYS; i++) { - if (phy == padctl->hsic_phys[i]) - return i; - } - WARN_ON(1); - - return -EINVAL; -} - -static int tegra186_hsic_phy_power_on(struct phy *phy) -{ - struct tegra_padctl_uphy *padctl = phy_get_drvdata(phy); - int port = hsic_phy_to_port(phy); - int err; - u32 value; - - TRACE_DEV(&phy->dev, "port %d", port); - if (port < 0) - return port; - - err = regulator_enable(padctl->vddio_hsic); - if (err) - return err; -#if 0 - value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PADX_CTL1(port)); - value &= ~(XUSB_PADCTL_HSIC_PAD_CTL1_RPD_STROBE | - XUSB_PADCTL_HSIC_PAD_CTL1_RPU_DATA | - XUSB_PADCTL_HSIC_PAD_CTL1_PD_RX | - XUSB_PADCTL_HSIC_PAD_CTL1_PD_ZI | - XUSB_PADCTL_HSIC_PAD_CTL1_PD_TRX | - XUSB_PADCTL_HSIC_PAD_CTL1_PD_TX); - value |= XUSB_PADCTL_HSIC_PAD_CTL1_RPD_DATA | - XUSB_PADCTL_HSIC_PAD_CTL1_RPU_STROBE; - padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PADX_CTL1(port)); -#else - value = 0; - TRACE_DEV(&phy->dev, "FIXME: implement!"); /* TODO */ -#endif - return 0; -} - -static int tegra186_hsic_phy_power_off(struct phy *phy) -{ - struct tegra_padctl_uphy *padctl = phy_get_drvdata(phy); - int port = hsic_phy_to_port(phy); - u32 value; - - TRACE_DEV(&phy->dev, "port %d\n", port); - if (port < 0) - return port; -#if 0 - value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PADX_CTL1(port)); - value |= XUSB_PADCTL_HSIC_PAD_CTL1_PD_RX | - XUSB_PADCTL_HSIC_PAD_CTL1_PD_ZI | - XUSB_PADCTL_HSIC_PAD_CTL1_PD_TRX | - XUSB_PADCTL_HSIC_PAD_CTL1_PD_TX; - padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PADX_CTL1(port)); -#else - value = 0; - TRACE_DEV(&phy->dev, "FIXME: implement!"); /* TODO */ -#endif - regulator_disable(padctl->vddio_hsic); - - return 0; -} - -static int tegra186_hsic_phy_init(struct phy *phy) -{ - TRACE_DEV(&phy->dev, ""); - return tegra_xusb_phy_init(phy); -} - -static int tegra186_hsic_phy_exit(struct phy *phy) -{ - TRACE_DEV(&phy->dev, ""); - return tegra_xusb_phy_exit(phy); -} - -static const struct phy_ops hsic_phy_ops = { - .init = tegra186_hsic_phy_init, - .exit = tegra186_hsic_phy_exit, - .power_on = tegra186_hsic_phy_power_on, - .power_off = tegra186_hsic_phy_power_off, - .owner = THIS_MODULE, -}; - -static struct phy *tegra186_padctl_uphy_xlate(struct device *dev, - struct of_phandle_args *args) -{ - struct tegra_padctl_uphy *padctl = dev_get_drvdata(dev); - unsigned int index = args->args[0]; - unsigned int phy_index; - struct phy *phy = NULL; - - if (args->args_count <= 0) - return ERR_PTR(-EINVAL); - - TRACE_DEV(dev, "index %d", index); - - if ((index >= TEGRA_USB3_PADCTL_USB3_BASE) && - (index < TEGRA_USB3_PADCTL_USB3_BASE + 16)) { - - phy_index = index - TEGRA_USB3_PADCTL_USB3_BASE; - if (phy_index < TEGRA_XUSB_USB3_PHYS) - phy = padctl->usb3_phys[phy_index]; - - } else if ((index >= TEGRA_USB3_PADCTL_UTMI_BASE) && - (index < TEGRA_USB3_PADCTL_UTMI_BASE + 16)) { - - phy_index = index - TEGRA_USB3_PADCTL_UTMI_BASE; - if (phy_index < TEGRA_XUSB_UTMI_PHYS) - phy = padctl->utmi_phys[phy_index]; - - } else if ((index >= TEGRA_USB3_PADCTL_HSIC_BASE) && - (index < TEGRA_USB3_PADCTL_HSIC_BASE + 16)) { - - phy_index = index - TEGRA_USB3_PADCTL_HSIC_BASE; - if (phy_index < TEGRA_XUSB_HSIC_PHYS) - phy = padctl->hsic_phys[phy_index]; - - } else if ((index >= TEGRA_USB3_PADCTL_PCIE_BASE) && - (index < TEGRA_USB3_PADCTL_PCIE_BASE + 16)) { - - phy_index = index - TEGRA_USB3_PADCTL_PCIE_BASE; - if (phy_index < TEGRA_XUSB_PCIE_PHYS) - phy = padctl->pcie_phys[phy_index]; - - } else if ((index >= TEGRA_USB3_PADCTL_SATA_BASE) && - (index < TEGRA_USB3_PADCTL_SATA_BASE + 16)) { - - phy_index = index - TEGRA_USB3_PADCTL_SATA_BASE; - if (phy_index < TEGRA_XUSB_SATA_PHYS) - phy = padctl->sata_phys[phy_index]; - - } else if ((index >= TEGRA_USB3_PADCTL_UFS_BASE) && - (index < TEGRA_USB3_PADCTL_UFS_BASE + 16)) { - - phy_index = index - TEGRA_USB3_PADCTL_UFS_BASE; - if (phy_index < TEGRA_XUSB_UFS_PHYS) - phy = padctl->ufs_phys[phy_index]; - - } - - return (phy) ? phy : ERR_PTR(-EINVAL); -} - -static const struct pinctrl_pin_desc tegra186_pins[] = { - PINCTRL_PIN(PIN_OTG_0, "otg-0"), - PINCTRL_PIN(PIN_OTG_1, "otg-1"), - PINCTRL_PIN(PIN_OTG_2, "otg-2"), - PINCTRL_PIN(PIN_OTG_3, "otg-3"), - PINCTRL_PIN(PIN_HSIC_0, "hsic-0"), - PINCTRL_PIN(PIN_HSIC_1, "hsic-1"), - PINCTRL_PIN(PIN_UPHY_0, "uphy-lane-0"), - PINCTRL_PIN(PIN_UPHY_1, "uphy-lane-1"), - PINCTRL_PIN(PIN_UPHY_2, "uphy-lane-2"), - PINCTRL_PIN(PIN_UPHY_3, "uphy-lane-3"), - PINCTRL_PIN(PIN_UPHY_4, "uphy-lane-4"), - PINCTRL_PIN(PIN_UPHY_5, "uphy-lane-5"), -}; - - -static const char * const tegra186_hsic_groups[] = { - "hsic-0", - "hsic-1", -}; - -static const char * const tegra186_hsic_plus_groups[] = { - "hsic-0", - "hsic-1", -}; - -static const char * const tegra186_xusb_groups[] = { - "otg-0", - "otg-1", - "otg-2", - "otg-3", -}; - -static const char * const tegra186_uart_groups[] = { - "otg-0", - "otg-1", - "otg-2", - "otg-3" -}; - -static const char * const tegra186_pcie_groups[] = { - "uphy-lane-0", - "uphy-lane-1", - "uphy-lane-2", - "uphy-lane-3", - "uphy-lane-4", - "uphy-lane-5", -}; - -static const char * const tegra186_usb3_groups[] = { - "uphy-lane-0", - "uphy-lane-1", - "uphy-lane-2", - "uphy-lane-3", - "uphy-lane-4", - "uphy-lane-5", -}; - -static const char * const tegra186_sata_groups[] = { - "uphy-lane-0", - "uphy-lane-1", - "uphy-lane-2", - "uphy-lane-3", - "uphy-lane-4", - "uphy-lane-5", -}; - -static const char * const tegra186_mphy_groups[] = { - "uphy-lane-0", - "uphy-lane-1", - "uphy-lane-2", - "uphy-lane-3", - "uphy-lane-4", - "uphy-lane-5", -}; - -#define TEGRA186_FUNCTION(_name) \ - { \ - .name = #_name, \ - .num_groups = ARRAY_SIZE(tegra186_##_name##_groups), \ - .groups = tegra186_##_name##_groups, \ - } - -static struct tegra_padctl_uphy_function tegra186_functions[] = { - TEGRA186_FUNCTION(hsic), - TEGRA186_FUNCTION(hsic_plus), - TEGRA186_FUNCTION(xusb), - TEGRA186_FUNCTION(uart), - TEGRA186_FUNCTION(pcie), - TEGRA186_FUNCTION(usb3), - TEGRA186_FUNCTION(sata), - TEGRA186_FUNCTION(mphy), -}; - -static const unsigned int tegra186_otg_functions[] = { - TEGRA186_FUNC_RSVD_0, - TEGRA186_FUNC_XUSB, - TEGRA186_FUNC_UART, - TEGRA186_FUNC_RSVD_3 -}; - -static const unsigned int tegra186_hsic_functions[] = { - TEGRA186_FUNC_HSIC, - TEGRA186_FUNC_HSIC_PLUS, -}; - -static const unsigned int tegra186_uphy_functions[] = { - TEGRA186_FUNC_USB3, - TEGRA186_FUNC_PCIE, - TEGRA186_FUNC_SATA, - TEGRA186_FUNC_MPHY, -}; - -#define TEGRA186_LANE(_name, _offset, _shift, _mask, _iddq, _funcs) \ - { \ - .name = _name, \ - .offset = _offset, \ - .shift = _shift, \ - .mask = _mask, \ - .iddq = _iddq, \ - .num_funcs = ARRAY_SIZE(tegra186_##_funcs##_functions), \ - .funcs = tegra186_##_funcs##_functions, \ - } - -static const struct tegra_padctl_uphy_lane tegra186_lanes[] = { - TEGRA186_LANE("otg-0", 0x004, 0, 0x3, 0, otg), - TEGRA186_LANE("otg-1", 0x004, 2, 0x3, 0, otg), - TEGRA186_LANE("otg-2", 0x004, 4, 0x3, 0, otg), - TEGRA186_LANE("otg-3", 0x004, 6, 0x3, 0, otg), - TEGRA186_LANE("hsic-0", 0x004, 20, 0x1, 0, hsic), - TEGRA186_LANE("hsic-1", 0x004, 21, 0x1, 0, hsic), - TEGRA186_LANE("uphy-lane-0", 0x284, 0, 0x3, 9, uphy), - TEGRA186_LANE("uphy-lane-1", 0x284, 0, 0x3, 9, uphy), - TEGRA186_LANE("uphy-lane-2", 0x284, 0, 0x3, 9, uphy), - TEGRA186_LANE("uphy-lane-3", 0x284, 0, 0x3, 9, uphy), - TEGRA186_LANE("uphy-lane-4", 0x284, 0, 0x3, 9, uphy), - TEGRA186_LANE("uphy-lane-5", 0x284, 0, 0x3, 9, uphy), -}; - -static const struct tegra_padctl_uphy_soc tegra186_soc = { - .num_pins = ARRAY_SIZE(tegra186_pins), - .pins = tegra186_pins, - .num_functions = ARRAY_SIZE(tegra186_functions), - .functions = tegra186_functions, - .num_lanes = ARRAY_SIZE(tegra186_lanes), - .lanes = tegra186_lanes, - .hsic_port_offset = 6, -}; - -static const struct of_device_id tegra_padctl_uphy_of_match[] = { - { .compatible = "nvidia,tegra186-padctl-uphy", .data = &tegra186_soc }, - { } -}; -MODULE_DEVICE_TABLE(of, tegra_padctl_uphy_of_match); - -static int tegra_xusb_read_fuse_calibration(struct tegra_padctl_uphy *padctl) -{ - unsigned int i; - u32 value; - - value = tegra_fuse_readl(FUSE_SKU_USB_CALIB_0); - dev_info(padctl->dev, "FUSE_SKU_USB_CALIB_0 0x%x\n", value); - for (i = 0; i < TEGRA_XUSB_UTMI_PHYS; i++) { - padctl->calib.hs_curr_level[i] = - (value >> USB_CALIB_HS_CURR_LEVEL_PADX_SHIFT(i)) & - USB_CALIB_HS_CURR_LEVEL_PAD_MASK; - } - padctl->calib.hs_term_range_adj = - (value >> USB_CALIB_HS_TERM_RANGE_ADJ_SHIFT) & - USB_CALIB_HS_TERM_RANGE_ADJ_MASK; - - value = tegra_fuse_readl(FUSE_USB_CALIB_EXT_0); - dev_info(padctl->dev, "FUSE_USB_CALIB_EXT_0 0x%x\n", value); - padctl->calib.rpd_ctrl = - (value >> USB_CALIB_EXT_RPD_CTRL_SHIFT) & - USB_CALIB_EXT_RPD_CTRL_MASK; - - return 0; -} - -static int tegra_mphy_stata_fuse_calibration(struct tegra_padctl_uphy *padctl) -{ - u32 value; - - value = tegra_fuse_readl(FUSE_SATA_MPHY_ODM_CALIB_0); - padctl->fuse_calib.sata_mphy_odm = value; - - value = tegra_fuse_readl(FUSE_SATA_NV_CALIB_0); - padctl->fuse_calib.sata_nv = value; - - value = tegra_fuse_readl(FUSE_MPHY_NV_CALIB_0); - padctl->fuse_calib.mphy_nv = value; - - return 0; -} - -static int tegra_xusb_setup_usb(struct tegra_padctl_uphy *ctx) -{ - struct phy *phy; - unsigned int i; - - for (i = 0; i < TEGRA_XUSB_USB3_PHYS; i++) { - phy = devm_phy_create(ctx->dev, &usb3_phy_ops, NULL); - TRACE("SS P%d phy %p\n", i, phy); - if (IS_ERR(phy)) - return PTR_ERR(phy); - - ctx->usb3_phys[i] = phy; - phy_set_drvdata(phy, ctx); - } - - for (i = 0; i < TEGRA_XUSB_UTMI_PHYS; i++) { - char reg_name[sizeof("vbus-N")]; - - sprintf(reg_name, "vbus-%d", i); - ctx->vbus[i] = devm_regulator_get(ctx->dev, reg_name); - TRACE("UTMI P%d vbus %p IS_ERR %ld PTR_ERR %ld\n", i, ctx->vbus[i], IS_ERR(ctx->vbus[i]), PTR_ERR(ctx->vbus[i])); - if (IS_ERR(ctx->vbus[i])) - return PTR_ERR(ctx->vbus[i]); - - phy = devm_phy_create(ctx->dev, &utmi_phy_ops, NULL); - TRACE("UTMI P%d phy %p IS_ERR %ld PTR_ERR %ld\n", i, phy, IS_ERR(phy), PTR_ERR(phy)); - if (IS_ERR(phy)) - return PTR_ERR(phy); - - ctx->utmi_phys[i] = phy; - phy_set_drvdata(phy, ctx); - } - - ctx->vddio_hsic = devm_regulator_get(ctx->dev, "vddio_hsic"); - if (IS_ERR(ctx->vddio_hsic)) - return PTR_ERR(ctx->vddio_hsic); - - for (i = 0; i < TEGRA_XUSB_HSIC_PHYS; i++) { - phy = devm_phy_create(ctx->dev, &hsic_phy_ops, NULL); - TRACE("HSIC P%d phy %p\n", i, phy); - if (IS_ERR(phy)) - return PTR_ERR(phy); - - ctx->hsic_phys[i] = phy; - phy_set_drvdata(phy, ctx); - } - - return 0; -} - -#define DEBUG -#ifdef DEBUG -#define reg_dump(_dev, _base, _reg) \ - dev_info(_dev, "%s @%x = 0x%x\n", #_reg, _reg, ioread32(_base + _reg)); -#else -#define reg_dump(_dev, _base, _reg) do {} while (0) -#endif - -static void __iomem *car_base; -static void tegra186_fpga_hacks_init(struct platform_device *pdev) -{ -#if defined(CONFIG_ARCH_TEGRA_18x_SOC) - car_base = devm_ioremap(&pdev->dev, 0x05000000, 0x1000000); -#endif - if (!car_base) - dev_err(&pdev->dev, "failed to map CAR mmio\n"); -} - -static -void tegra186_fpga_hacks_uphy_reset(struct platform_device *pdev, bool on) -{ - int reg; - if (!car_base) { - dev_err(&pdev->dev, "CAR mmio is not mapped\n"); - return; - } - - reg_dump(&pdev->dev, car_base, CLK_RST_CONTROLLER_RST_DEV_UPHY_0); - reg = ioread32(car_base + CLK_RST_CONTROLLER_RST_DEV_UPHY_0); - if (on) - reg |= SWR_UPHY_RST; - else - reg &= ~SWR_UPHY_RST; - iowrite32(reg, car_base + CLK_RST_CONTROLLER_RST_DEV_UPHY_0); - reg_dump(&pdev->dev, car_base, CLK_RST_CONTROLLER_RST_DEV_UPHY_0); -} - -static int tegra186_padctl_uphy_probe(struct platform_device *pdev) -{ - struct tegra_padctl_uphy *ctx; - const struct of_device_id *match; - struct device_node *np = pdev->dev.of_node; - struct resource *res; - struct phy *phy; - int err; - - TRACE(); - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - TRACE(); - platform_set_drvdata(pdev, ctx); - mutex_init(&ctx->lock); - ctx->dev = &pdev->dev; - - TRACE(); - match = of_match_node(tegra_padctl_uphy_of_match, pdev->dev.of_node); - ctx->soc = match->data; - - TRACE(); - - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - ctx->padctl_regs = devm_ioremap_resource(&pdev->dev, res); - TRACE_DEV(&pdev->dev, "padctl mmio start %pa end %pa\n", &res->start, &res->end); - if (IS_ERR(ctx->padctl_regs)) - return PTR_ERR(ctx->padctl_regs); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - ctx->uphy_regs = devm_ioremap_resource(&pdev->dev, res); - TRACE_DEV(&pdev->dev, "uphy mmio start %pa end %pa\n", &res->start, &res->end); - if (IS_ERR(ctx->uphy_regs)) - return PTR_ERR(ctx->uphy_regs); - - ctx->uphy_pll_regs[0] = ctx->uphy_regs; - ctx->uphy_lane_regs[0] = ctx->uphy_regs + 0x20000; - ctx->uphy_lane_regs[1] = ctx->uphy_regs + 0x30000; - ctx->uphy_lane_regs[2] = ctx->uphy_regs + 0x40000; - ctx->uphy_lane_regs[3] = ctx->uphy_regs + 0x50000; - ctx->uphy_lane_regs[4] = ctx->uphy_regs + 0x60000; - ctx->uphy_lane_regs[5] = ctx->uphy_regs + 0x70000; - ctx->uphy_pll_regs[1] = ctx->uphy_regs + 0x80000; - - TRACE(); - if (tegra_platform_is_silicon()) { - err = tegra_xusb_read_fuse_calibration(ctx); - if (err < 0) - return err; - - err = tegra_mphy_stata_fuse_calibration(ctx); - if (err < 0) - return err; - } - - TRACE(); - if (tegra_platform_is_silicon()) { - /* TODO: check clock framework */ - ctx->clk = devm_clk_get(ctx->dev, "uphy"); - if (IS_ERR(ctx->clk)) { - dev_err(ctx->dev, "failed to get uphy pad clock\n"); - return PTR_ERR(ctx->clk); - } - tegra_periph_reset_deassert(ctx->clk); - } - - if (tegra_platform_is_fpga()) { - tegra186_fpga_hacks_init(pdev); - tegra186_fpga_hacks_uphy_reset(pdev, false); - } - - TRACE(); - memset(&ctx->desc, 0, sizeof(ctx->desc)); - ctx->desc.name = dev_name(ctx->dev); - ctx->desc.pins = ctx->soc->pins; - ctx->desc.npins = ctx->soc->num_pins; - ctx->desc.pctlops = &tegra_xusb_padctl_pinctrl_ops; - ctx->desc.pmxops = &tegra186_padctl_uphy_pinmux_ops; - ctx->desc.confops = &tegra_xusb_padctl_pinconf_ops; - ctx->desc.owner = THIS_MODULE; - - ctx->pinctrl = pinctrl_register(&ctx->desc, &pdev->dev, ctx); - if (!ctx->pinctrl) { - dev_err(&pdev->dev, "failed to register pincontrol\n"); - err = -ENODEV; - goto assert_clk_reset; - } - - TRACE(); - phy = devm_phy_create(&pdev->dev, &pcie_phy_ops, NULL); - if (IS_ERR(phy)) { - err = PTR_ERR(phy); - goto unregister; - } - - ctx->pcie_phys[0] = phy; - phy_set_drvdata(phy, ctx); - - TRACE(); - phy = devm_phy_create(&pdev->dev, &sata_phy_ops, NULL); - if (IS_ERR(phy)) { - err = PTR_ERR(phy); - goto unregister; - } - - ctx->sata_phys[0] = phy; - phy_set_drvdata(phy, ctx); - - TRACE(); - phy = devm_phy_create(&pdev->dev, &ufs_phy_ops, NULL); - if (IS_ERR(phy)) { - err = PTR_ERR(phy); - goto unregister; - } - - ctx->ufs_phys[0] = phy; - phy_set_drvdata(phy, ctx); - - TRACE(); - err = tegra_xusb_setup_usb(ctx); - TRACE("err %d\n", err); - if (err) - goto unregister; - - TRACE(); - ctx->provider = devm_of_phy_provider_register(&pdev->dev, - tegra186_padctl_uphy_xlate); - if (IS_ERR(ctx->provider)) { - dev_err(&pdev->dev, "failed to register PHYs: %d\n", err); - goto unregister; - } - - TRACE(); - - ctx->prod_list = tegra_prod_get(&pdev->dev, NULL); - if (IS_ERR_OR_NULL(ctx->prod_list)) { - dev_warn(&pdev->dev, "uphy: prod list not found %ld\n", - PTR_ERR(ctx->prod_list)); - ctx->prod_list = NULL; - } - - ctx->sata_bypass_fuse = - of_property_read_bool(np, "nvidia,sata-use-prods"); - - return 0; - -unregister: - TRACE(); - pinctrl_unregister(ctx->pinctrl); -assert_clk_reset: - if (tegra_platform_is_silicon()) - tegra_periph_reset_assert(ctx->clk); - return err; -} - -static int tegra186_padctl_uphy_remove(struct platform_device *pdev) -{ - struct tegra_padctl_uphy *ctx = platform_get_drvdata(pdev); - if (ctx->prod_list) - tegra_prod_release(&ctx->prod_list); - - pinctrl_unregister(ctx->pinctrl); - tegra_periph_reset_assert(ctx->clk); - return 0; -} - -static struct platform_driver tegra186_padctl_uphy_driver = { - .driver = { - .name = "tegra186-padctl-uphy", - .of_match_table = tegra_padctl_uphy_of_match, - }, - .probe = tegra186_padctl_uphy_probe, - .remove = tegra186_padctl_uphy_remove, -}; -module_platform_driver(tegra186_padctl_uphy_driver); - -MODULE_AUTHOR("JC Kuo "); -MODULE_DESCRIPTION("Tegra 186 XUSB Pad Control and UPHY driver"); -MODULE_LICENSE("GPL v2"); diff --git a/include/dt-bindings/memory/tegra186-swgroup.h b/include/dt-bindings/memory/tegra186-swgroup.h deleted file mode 120000 index be41c6ca53b..00000000000 --- a/include/dt-bindings/memory/tegra186-swgroup.h +++ /dev/null @@ -1 +0,0 @@ -../../../../kernel-t18x/include/dt-bindings/memory/tegra186-swgroup.h \ No newline at end of file -- 2.39.2