1758 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.4 */5 6#include <linux/delay.h>7#include <linux/io.h>8#include <linux/mailbox_client.h>9#include <linux/module.h>10#include <linux/of.h>11#include <linux/phy/phy.h>12#include <linux/platform_device.h>13#include <linux/regulator/consumer.h>14#include <linux/reset.h>15#include <linux/slab.h>16 17#include <soc/tegra/fuse.h>18 19#include "xusb.h"20 21#define FUSE_SKU_CALIB_HS_CURR_LEVEL_PADX_SHIFT(x) ((x) ? 15 : 0)22#define FUSE_SKU_CALIB_HS_CURR_LEVEL_PAD_MASK 0x3f23#define FUSE_SKU_CALIB_HS_IREF_CAP_SHIFT 1324#define FUSE_SKU_CALIB_HS_IREF_CAP_MASK 0x325#define FUSE_SKU_CALIB_HS_SQUELCH_LEVEL_SHIFT 1126#define FUSE_SKU_CALIB_HS_SQUELCH_LEVEL_MASK 0x327#define FUSE_SKU_CALIB_HS_TERM_RANGE_ADJ_SHIFT 728#define FUSE_SKU_CALIB_HS_TERM_RANGE_ADJ_MASK 0xf29 30#define XUSB_PADCTL_USB2_PORT_CAP 0x00831#define XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_SHIFT(x) ((x) * 4)32#define XUSB_PADCTL_USB2_PORT_CAP_PORT_CAP_MASK 0x333#define XUSB_PADCTL_USB2_PORT_CAP_DISABLED 0x034#define XUSB_PADCTL_USB2_PORT_CAP_HOST 0x135#define XUSB_PADCTL_USB2_PORT_CAP_DEVICE 0x236#define XUSB_PADCTL_USB2_PORT_CAP_OTG 0x337 38#define XUSB_PADCTL_SS_PORT_MAP 0x01439#define XUSB_PADCTL_SS_PORT_MAP_PORTX_INTERNAL(x) (1 << (((x) * 4) + 3))40#define XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP_SHIFT(x) ((x) * 4)41#define XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP_MASK(x) (0x7 << ((x) * 4))42#define XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP(x, v) (((v) & 0x7) << ((x) * 4))43#define XUSB_PADCTL_SS_PORT_MAP_PORT_MAP_MASK 0x744 45#define XUSB_PADCTL_ELPG_PROGRAM 0x01c46#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN (1 << 26)47#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY (1 << 25)48#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN (1 << 24)49#define XUSB_PADCTL_ELPG_PROGRAM_SSPX_ELPG_VCORE_DOWN(x) (1 << (18 + (x) * 4))50#define XUSB_PADCTL_ELPG_PROGRAM_SSPX_ELPG_CLAMP_EN_EARLY(x) \51 (1 << (17 + (x) * 4))52#define XUSB_PADCTL_ELPG_PROGRAM_SSPX_ELPG_CLAMP_EN(x) (1 << (16 + (x) * 4))53 54#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1 0x04055#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET (1 << 19)56#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK (0xf << 12)57#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST (1 << 1)58 59#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2 0x04460#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN (1 << 6)61#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN (1 << 5)62#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL (1 << 4)63 64#define XUSB_PADCTL_IOPHY_USB3_PADX_CTL2(x) (0x058 + (x) * 4)65#define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_CDR_CNTL_SHIFT 2466#define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_CDR_CNTL_MASK 0xff67#define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_CDR_CNTL_VAL 0x2468#define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_Z_SHIFT 1669#define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_Z_MASK 0x3f70#define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_G_SHIFT 871#define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_G_MASK 0x3f72#define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_SHIFT 873#define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_MASK 0xffff74#define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_VAL 0xf07075#define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_WANDER_SHIFT 476#define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_WANDER_MASK 0xf77#define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_WANDER_VAL 0xf78 79#define XUSB_PADCTL_IOPHY_USB3_PADX_CTL4(x) (0x068 + (x) * 4)80#define XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_TAP_SHIFT 2481#define XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_TAP_MASK 0x1f82#define XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_AMP_SHIFT 1683#define XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_AMP_MASK 0x7f84#define XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_VAL 0x002008ee85 86#define XUSB_PADCTL_IOPHY_MISC_PAD_PX_CTL2(x) ((x) < 2 ? 0x078 + (x) * 4 : \87 0x0f8 + (x) * 4)88#define XUSB_PADCTL_IOPHY_MISC_PAD_CTL2_SPARE_IN_SHIFT 2889#define XUSB_PADCTL_IOPHY_MISC_PAD_CTL2_SPARE_IN_MASK 0x390#define XUSB_PADCTL_IOPHY_MISC_PAD_CTL2_SPARE_IN_VAL 0x191 92#define XUSB_PADCTL_IOPHY_MISC_PAD_PX_CTL5(x) ((x) < 2 ? 0x090 + (x) * 4 : \93 0x11c + (x) * 4)94#define XUSB_PADCTL_IOPHY_MISC_PAD_CTL5_RX_QEYE_EN (1 << 8)95 96#define XUSB_PADCTL_IOPHY_MISC_PAD_PX_CTL6(x) ((x) < 2 ? 0x098 + (x) * 4 : \97 0x128 + (x) * 4)98#define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SHIFT 2499#define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_G_Z_MASK 0x3f100#define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_TAP_MASK 0x1f101#define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_AMP_MASK 0x7f102#define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT 16103#define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_MASK 0xff104#define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_G_Z 0x21105#define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_TAP 0x32106#define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_AMP 0x33107#define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_CTLE_Z 0x48108#define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_LATCH_G_Z 0xa1109 110#define XUSB_PADCTL_USB2_OTG_PADX_CTL0(x) (0x0a0 + (x) * 4)111#define XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD_ZI (1 << 21)112#define XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD2 (1 << 20)113#define XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD (1 << 19)114#define XUSB_PADCTL_USB2_OTG_PAD_CTL0_LS_RSLEW_SHIFT 14115#define XUSB_PADCTL_USB2_OTG_PAD_CTL0_LS_RSLEW_MASK 0x3116#define XUSB_PADCTL_USB2_OTG_PAD_CTL0_LS_RSLEW_VAL(x) ((x) ? 0x0 : 0x3)117#define XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_SLEW_SHIFT 6118#define XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_SLEW_MASK 0x3f119#define XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_SLEW_VAL 0x0e120#define XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_SHIFT 0121#define XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_MASK 0x3f122 123#define XUSB_PADCTL_USB2_OTG_PADX_CTL1(x) (0x0ac + (x) * 4)124#define XUSB_PADCTL_USB2_OTG_PAD_CTL1_HS_IREF_CAP_SHIFT 9125#define XUSB_PADCTL_USB2_OTG_PAD_CTL1_HS_IREF_CAP_MASK 0x3126#define XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_SHIFT 3127#define XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_MASK 0x7128#define XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_DR (1 << 2)129#define XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_DISC_FORCE_POWERUP (1 << 1)130#define XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_CHRP_FORCE_POWERUP (1 << 0)131 132#define XUSB_PADCTL_USB2_BIAS_PAD_CTL0 0x0b8133#define XUSB_PADCTL_USB2_BIAS_PAD_CTL0_PD (1 << 12)134#define XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_SHIFT 2135#define XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_MASK 0x7136#define XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_VAL 0x5137#define XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_SHIFT 0138#define XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_MASK 0x3139 140#define XUSB_PADCTL_HSIC_PADX_CTL0(x) (0x0c0 + (x) * 4)141#define XUSB_PADCTL_HSIC_PAD_CTL0_TX_RSLEWN_SHIFT 12142#define XUSB_PADCTL_HSIC_PAD_CTL0_TX_RSLEWN_MASK 0x7143#define XUSB_PADCTL_HSIC_PAD_CTL0_TX_RSLEWP_SHIFT 8144#define XUSB_PADCTL_HSIC_PAD_CTL0_TX_RSLEWP_MASK 0x7145#define XUSB_PADCTL_HSIC_PAD_CTL0_TX_RTUNEN_SHIFT 4146#define XUSB_PADCTL_HSIC_PAD_CTL0_TX_RTUNEN_MASK 0x7147#define XUSB_PADCTL_HSIC_PAD_CTL0_TX_RTUNEP_SHIFT 0148#define XUSB_PADCTL_HSIC_PAD_CTL0_TX_RTUNEP_MASK 0x7149 150#define XUSB_PADCTL_HSIC_PADX_CTL1(x) (0x0c8 + (x) * 4)151#define XUSB_PADCTL_HSIC_PAD_CTL1_RPU_STROBE (1 << 10)152#define XUSB_PADCTL_HSIC_PAD_CTL1_RPU_DATA (1 << 9)153#define XUSB_PADCTL_HSIC_PAD_CTL1_RPD_STROBE (1 << 8)154#define XUSB_PADCTL_HSIC_PAD_CTL1_RPD_DATA (1 << 7)155#define XUSB_PADCTL_HSIC_PAD_CTL1_PD_ZI (1 << 5)156#define XUSB_PADCTL_HSIC_PAD_CTL1_PD_RX (1 << 4)157#define XUSB_PADCTL_HSIC_PAD_CTL1_PD_TRX (1 << 3)158#define XUSB_PADCTL_HSIC_PAD_CTL1_PD_TX (1 << 2)159#define XUSB_PADCTL_HSIC_PAD_CTL1_AUTO_TERM_EN (1 << 0)160 161#define XUSB_PADCTL_HSIC_PADX_CTL2(x) (0x0d0 + (x) * 4)162#define XUSB_PADCTL_HSIC_PAD_CTL2_RX_STROBE_TRIM_SHIFT 4163#define XUSB_PADCTL_HSIC_PAD_CTL2_RX_STROBE_TRIM_MASK 0x7164#define XUSB_PADCTL_HSIC_PAD_CTL2_RX_DATA_TRIM_SHIFT 0165#define XUSB_PADCTL_HSIC_PAD_CTL2_RX_DATA_TRIM_MASK 0x7166 167#define XUSB_PADCTL_HSIC_STRB_TRIM_CONTROL 0x0e0168#define XUSB_PADCTL_HSIC_STRB_TRIM_CONTROL_STRB_TRIM_MASK 0x1f169 170#define XUSB_PADCTL_USB3_PAD_MUX 0x134171#define XUSB_PADCTL_USB3_PAD_MUX_PCIE_IDDQ_DISABLE(x) (1 << (1 + (x)))172#define XUSB_PADCTL_USB3_PAD_MUX_SATA_IDDQ_DISABLE(x) (1 << (6 + (x)))173 174#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1 0x138175#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET (1 << 27)176#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE (1 << 24)177#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL0_REFCLK_NDIV_SHIFT 20178#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL0_REFCLK_NDIV_MASK 0x3179#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD (1 << 3)180#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST (1 << 1)181#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ (1 << 0)182 183#define XUSB_PADCTL_IOPHY_PLL_S0_CTL2 0x13c184#define XUSB_PADCTL_IOPHY_PLL_S0_CTL2_PLL1_CP_CNTL_SHIFT 20185#define XUSB_PADCTL_IOPHY_PLL_S0_CTL2_PLL1_CP_CNTL_MASK 0xf186#define XUSB_PADCTL_IOPHY_PLL_S0_CTL2_PLL0_CP_CNTL_SHIFT 16187#define XUSB_PADCTL_IOPHY_PLL_S0_CTL2_PLL0_CP_CNTL_MASK 0xf188#define XUSB_PADCTL_IOPHY_PLL_S0_CTL2_TCLKOUT_EN (1 << 12)189#define XUSB_PADCTL_IOPHY_PLL_S0_CTL2_TXCLKREF_SEL (1 << 4)190#define XUSB_PADCTL_IOPHY_PLL_S0_CTL2_XDIGCLK_SEL_SHIFT 0191#define XUSB_PADCTL_IOPHY_PLL_S0_CTL2_XDIGCLK_SEL_MASK 0x7192 193#define XUSB_PADCTL_IOPHY_PLL_S0_CTL3 0x140194#define XUSB_PADCTL_IOPHY_PLL_S0_CTL3_RCAL_BYPASS (1 << 7)195 196#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1 0x148197#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD (1 << 1)198#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ (1 << 0)199 200#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL2 0x14c201 202#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL5 0x158203 204#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL6 0x15c205 206struct tegra124_xusb_fuse_calibration {207 u32 hs_curr_level[3];208 u32 hs_iref_cap;209 u32 hs_term_range_adj;210 u32 hs_squelch_level;211};212 213struct tegra124_xusb_padctl {214 struct tegra_xusb_padctl base;215 216 struct tegra124_xusb_fuse_calibration fuse;217};218 219static inline struct tegra124_xusb_padctl *220to_tegra124_xusb_padctl(struct tegra_xusb_padctl *padctl)221{222 return container_of(padctl, struct tegra124_xusb_padctl, base);223}224 225static int tegra124_xusb_padctl_enable(struct tegra_xusb_padctl *padctl)226{227 u32 value;228 229 mutex_lock(&padctl->lock);230 231 if (padctl->enable++ > 0)232 goto out;233 234 value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);235 value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;236 padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);237 238 usleep_range(100, 200);239 240 value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);241 value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY;242 padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);243 244 usleep_range(100, 200);245 246 value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);247 value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;248 padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);249 250out:251 mutex_unlock(&padctl->lock);252 return 0;253}254 255static int tegra124_xusb_padctl_disable(struct tegra_xusb_padctl *padctl)256{257 u32 value;258 259 mutex_lock(&padctl->lock);260 261 if (WARN_ON(padctl->enable == 0))262 goto out;263 264 if (--padctl->enable > 0)265 goto out;266 267 value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);268 value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;269 padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);270 271 usleep_range(100, 200);272 273 value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);274 value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY;275 padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);276 277 usleep_range(100, 200);278 279 value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);280 value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;281 padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);282 283out:284 mutex_unlock(&padctl->lock);285 return 0;286}287 288static int tegra124_usb3_save_context(struct tegra_xusb_padctl *padctl,289 unsigned int index)290{291 struct tegra_xusb_usb3_port *port;292 struct tegra_xusb_lane *lane;293 u32 value, offset;294 295 port = tegra_xusb_find_usb3_port(padctl, index);296 if (!port)297 return -ENODEV;298 299 port->context_saved = true;300 lane = port->base.lane;301 302 if (lane->pad == padctl->pcie)303 offset = XUSB_PADCTL_IOPHY_MISC_PAD_PX_CTL6(lane->index);304 else305 offset = XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL6;306 307 value = padctl_readl(padctl, offset);308 value &= ~(XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_MASK <<309 XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT);310 value |= XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_TAP <<311 XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT;312 padctl_writel(padctl, value, offset);313 314 value = padctl_readl(padctl, offset) >>315 XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SHIFT;316 port->tap1 = value & XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_TAP_MASK;317 318 value = padctl_readl(padctl, offset);319 value &= ~(XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_MASK <<320 XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT);321 value |= XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_AMP <<322 XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT;323 padctl_writel(padctl, value, offset);324 325 value = padctl_readl(padctl, offset) >>326 XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SHIFT;327 port->amp = value & XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_AMP_MASK;328 329 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_USB3_PADX_CTL4(index));330 value &= ~((XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_TAP_MASK <<331 XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_TAP_SHIFT) |332 (XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_AMP_MASK <<333 XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_AMP_SHIFT));334 value |= (port->tap1 <<335 XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_TAP_SHIFT) |336 (port->amp <<337 XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_AMP_SHIFT);338 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_USB3_PADX_CTL4(index));339 340 value = padctl_readl(padctl, offset);341 value &= ~(XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_MASK <<342 XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT);343 value |= XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_LATCH_G_Z <<344 XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT;345 padctl_writel(padctl, value, offset);346 347 value = padctl_readl(padctl, offset);348 value &= ~(XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_MASK <<349 XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT);350 value |= XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_G_Z <<351 XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT;352 padctl_writel(padctl, value, offset);353 354 value = padctl_readl(padctl, offset) >>355 XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SHIFT;356 port->ctle_g = value &357 XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_G_Z_MASK;358 359 value = padctl_readl(padctl, offset);360 value &= ~(XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_MASK <<361 XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT);362 value |= XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_CTLE_Z <<363 XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT;364 padctl_writel(padctl, value, offset);365 366 value = padctl_readl(padctl, offset) >>367 XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SHIFT;368 port->ctle_z = value &369 XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_G_Z_MASK;370 371 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_USB3_PADX_CTL2(index));372 value &= ~((XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_G_MASK <<373 XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_G_SHIFT) |374 (XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_Z_MASK <<375 XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_Z_SHIFT));376 value |= (port->ctle_g <<377 XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_G_SHIFT) |378 (port->ctle_z <<379 XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_Z_SHIFT);380 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_USB3_PADX_CTL2(index));381 382 return 0;383}384 385static int tegra124_hsic_set_idle(struct tegra_xusb_padctl *padctl,386 unsigned int index, bool idle)387{388 u32 value;389 390 value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PADX_CTL1(index));391 392 if (idle)393 value |= XUSB_PADCTL_HSIC_PAD_CTL1_RPD_DATA |394 XUSB_PADCTL_HSIC_PAD_CTL1_RPU_STROBE;395 else396 value &= ~(XUSB_PADCTL_HSIC_PAD_CTL1_RPD_DATA |397 XUSB_PADCTL_HSIC_PAD_CTL1_RPU_STROBE);398 399 padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PADX_CTL1(index));400 401 return 0;402}403 404#define TEGRA124_LANE(_name, _offset, _shift, _mask, _type) \405 { \406 .name = _name, \407 .offset = _offset, \408 .shift = _shift, \409 .mask = _mask, \410 .num_funcs = ARRAY_SIZE(tegra124_##_type##_functions), \411 .funcs = tegra124_##_type##_functions, \412 }413 414static const char * const tegra124_usb2_functions[] = {415 "snps",416 "xusb",417 "uart",418};419 420static const struct tegra_xusb_lane_soc tegra124_usb2_lanes[] = {421 TEGRA124_LANE("usb2-0", 0x004, 0, 0x3, usb2),422 TEGRA124_LANE("usb2-1", 0x004, 2, 0x3, usb2),423 TEGRA124_LANE("usb2-2", 0x004, 4, 0x3, usb2),424};425 426static struct tegra_xusb_lane *427tegra124_usb2_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np,428 unsigned int index)429{430 struct tegra_xusb_usb2_lane *usb2;431 int err;432 433 usb2 = kzalloc(sizeof(*usb2), GFP_KERNEL);434 if (!usb2)435 return ERR_PTR(-ENOMEM);436 437 INIT_LIST_HEAD(&usb2->base.list);438 usb2->base.soc = &pad->soc->lanes[index];439 usb2->base.index = index;440 usb2->base.pad = pad;441 usb2->base.np = np;442 443 err = tegra_xusb_lane_parse_dt(&usb2->base, np);444 if (err < 0) {445 kfree(usb2);446 return ERR_PTR(err);447 }448 449 return &usb2->base;450}451 452static void tegra124_usb2_lane_remove(struct tegra_xusb_lane *lane)453{454 struct tegra_xusb_usb2_lane *usb2 = to_usb2_lane(lane);455 456 kfree(usb2);457}458 459static const struct tegra_xusb_lane_ops tegra124_usb2_lane_ops = {460 .probe = tegra124_usb2_lane_probe,461 .remove = tegra124_usb2_lane_remove,462};463 464static int tegra124_usb2_phy_init(struct phy *phy)465{466 struct tegra_xusb_lane *lane = phy_get_drvdata(phy);467 468 return tegra124_xusb_padctl_enable(lane->pad->padctl);469}470 471static int tegra124_usb2_phy_exit(struct phy *phy)472{473 struct tegra_xusb_lane *lane = phy_get_drvdata(phy);474 475 return tegra124_xusb_padctl_disable(lane->pad->padctl);476}477 478static int tegra124_usb2_phy_power_on(struct phy *phy)479{480 struct tegra_xusb_lane *lane = phy_get_drvdata(phy);481 struct tegra_xusb_usb2_lane *usb2 = to_usb2_lane(lane);482 struct tegra_xusb_usb2_pad *pad = to_usb2_pad(lane->pad);483 struct tegra_xusb_padctl *padctl = lane->pad->padctl;484 struct tegra124_xusb_padctl *priv;485 struct tegra_xusb_usb2_port *port;486 unsigned int index = lane->index;487 u32 value;488 int err;489 490 port = tegra_xusb_find_usb2_port(padctl, index);491 if (!port) {492 dev_err(&phy->dev, "no port found for USB2 lane %u\n", index);493 return -ENODEV;494 }495 496 priv = to_tegra124_xusb_padctl(padctl);497 498 value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);499 value &= ~((XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_MASK <<500 XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_SHIFT) |501 (XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_MASK <<502 XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_SHIFT));503 value |= (priv->fuse.hs_squelch_level <<504 XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_SHIFT) |505 (XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_VAL <<506 XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_SHIFT);507 padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);508 509 value = padctl_readl(padctl, XUSB_PADCTL_USB2_PORT_CAP);510 value &= ~(XUSB_PADCTL_USB2_PORT_CAP_PORT_CAP_MASK <<511 XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_SHIFT(index));512 value |= XUSB_PADCTL_USB2_PORT_CAP_HOST <<513 XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_SHIFT(index);514 padctl_writel(padctl, value, XUSB_PADCTL_USB2_PORT_CAP);515 516 value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index));517 value &= ~((XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_MASK <<518 XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_SHIFT) |519 (XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_SLEW_MASK <<520 XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_SLEW_SHIFT) |521 (XUSB_PADCTL_USB2_OTG_PAD_CTL0_LS_RSLEW_MASK <<522 XUSB_PADCTL_USB2_OTG_PAD_CTL0_LS_RSLEW_SHIFT) |523 XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD |524 XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD2 |525 XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD_ZI);526 value |= (priv->fuse.hs_curr_level[index] +527 usb2->hs_curr_level_offset) <<528 XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_SHIFT;529 value |= XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_SLEW_VAL <<530 XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_SLEW_SHIFT;531 value |= XUSB_PADCTL_USB2_OTG_PAD_CTL0_LS_RSLEW_VAL(index) <<532 XUSB_PADCTL_USB2_OTG_PAD_CTL0_LS_RSLEW_SHIFT;533 padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index));534 535 value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));536 value &= ~((XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_MASK <<537 XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_SHIFT) |538 (XUSB_PADCTL_USB2_OTG_PAD_CTL1_HS_IREF_CAP_MASK <<539 XUSB_PADCTL_USB2_OTG_PAD_CTL1_HS_IREF_CAP_SHIFT) |540 XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_DR |541 XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_CHRP_FORCE_POWERUP |542 XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_DISC_FORCE_POWERUP);543 value |= (priv->fuse.hs_term_range_adj <<544 XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_SHIFT) |545 (priv->fuse.hs_iref_cap <<546 XUSB_PADCTL_USB2_OTG_PAD_CTL1_HS_IREF_CAP_SHIFT);547 padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));548 549 err = regulator_enable(port->supply);550 if (err)551 return err;552 553 mutex_lock(&pad->lock);554 555 if (pad->enable++ > 0)556 goto out;557 558 value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);559 value &= ~XUSB_PADCTL_USB2_BIAS_PAD_CTL0_PD;560 padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);561 562out:563 mutex_unlock(&pad->lock);564 return 0;565}566 567static int tegra124_usb2_phy_power_off(struct phy *phy)568{569 struct tegra_xusb_lane *lane = phy_get_drvdata(phy);570 struct tegra_xusb_usb2_pad *pad = to_usb2_pad(lane->pad);571 struct tegra_xusb_padctl *padctl = lane->pad->padctl;572 struct tegra_xusb_usb2_port *port;573 u32 value;574 575 port = tegra_xusb_find_usb2_port(padctl, lane->index);576 if (!port) {577 dev_err(&phy->dev, "no port found for USB2 lane %u\n",578 lane->index);579 return -ENODEV;580 }581 582 mutex_lock(&pad->lock);583 584 if (WARN_ON(pad->enable == 0))585 goto out;586 587 if (--pad->enable > 0)588 goto out;589 590 value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);591 value |= XUSB_PADCTL_USB2_BIAS_PAD_CTL0_PD;592 padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);593 594out:595 regulator_disable(port->supply);596 mutex_unlock(&pad->lock);597 return 0;598}599 600static const struct phy_ops tegra124_usb2_phy_ops = {601 .init = tegra124_usb2_phy_init,602 .exit = tegra124_usb2_phy_exit,603 .power_on = tegra124_usb2_phy_power_on,604 .power_off = tegra124_usb2_phy_power_off,605 .owner = THIS_MODULE,606};607 608static struct tegra_xusb_pad *609tegra124_usb2_pad_probe(struct tegra_xusb_padctl *padctl,610 const struct tegra_xusb_pad_soc *soc,611 struct device_node *np)612{613 struct tegra_xusb_usb2_pad *usb2;614 struct tegra_xusb_pad *pad;615 int err;616 617 usb2 = kzalloc(sizeof(*usb2), GFP_KERNEL);618 if (!usb2)619 return ERR_PTR(-ENOMEM);620 621 mutex_init(&usb2->lock);622 623 pad = &usb2->base;624 pad->ops = &tegra124_usb2_lane_ops;625 pad->soc = soc;626 627 err = tegra_xusb_pad_init(pad, padctl, np);628 if (err < 0) {629 kfree(usb2);630 goto out;631 }632 633 err = tegra_xusb_pad_register(pad, &tegra124_usb2_phy_ops);634 if (err < 0)635 goto unregister;636 637 dev_set_drvdata(&pad->dev, pad);638 639 return pad;640 641unregister:642 device_unregister(&pad->dev);643out:644 return ERR_PTR(err);645}646 647static void tegra124_usb2_pad_remove(struct tegra_xusb_pad *pad)648{649 struct tegra_xusb_usb2_pad *usb2 = to_usb2_pad(pad);650 651 kfree(usb2);652}653 654static const struct tegra_xusb_pad_ops tegra124_usb2_ops = {655 .probe = tegra124_usb2_pad_probe,656 .remove = tegra124_usb2_pad_remove,657};658 659static const struct tegra_xusb_pad_soc tegra124_usb2_pad = {660 .name = "usb2",661 .num_lanes = ARRAY_SIZE(tegra124_usb2_lanes),662 .lanes = tegra124_usb2_lanes,663 .ops = &tegra124_usb2_ops,664};665 666static const char * const tegra124_ulpi_functions[] = {667 "snps",668 "xusb",669};670 671static const struct tegra_xusb_lane_soc tegra124_ulpi_lanes[] = {672 TEGRA124_LANE("ulpi-0", 0x004, 12, 0x1, ulpi),673};674 675static struct tegra_xusb_lane *676tegra124_ulpi_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np,677 unsigned int index)678{679 struct tegra_xusb_ulpi_lane *ulpi;680 int err;681 682 ulpi = kzalloc(sizeof(*ulpi), GFP_KERNEL);683 if (!ulpi)684 return ERR_PTR(-ENOMEM);685 686 INIT_LIST_HEAD(&ulpi->base.list);687 ulpi->base.soc = &pad->soc->lanes[index];688 ulpi->base.index = index;689 ulpi->base.pad = pad;690 ulpi->base.np = np;691 692 err = tegra_xusb_lane_parse_dt(&ulpi->base, np);693 if (err < 0) {694 kfree(ulpi);695 return ERR_PTR(err);696 }697 698 return &ulpi->base;699}700 701static void tegra124_ulpi_lane_remove(struct tegra_xusb_lane *lane)702{703 struct tegra_xusb_ulpi_lane *ulpi = to_ulpi_lane(lane);704 705 kfree(ulpi);706}707 708static const struct tegra_xusb_lane_ops tegra124_ulpi_lane_ops = {709 .probe = tegra124_ulpi_lane_probe,710 .remove = tegra124_ulpi_lane_remove,711};712 713static int tegra124_ulpi_phy_init(struct phy *phy)714{715 struct tegra_xusb_lane *lane = phy_get_drvdata(phy);716 717 return tegra124_xusb_padctl_enable(lane->pad->padctl);718}719 720static int tegra124_ulpi_phy_exit(struct phy *phy)721{722 struct tegra_xusb_lane *lane = phy_get_drvdata(phy);723 724 return tegra124_xusb_padctl_disable(lane->pad->padctl);725}726 727static int tegra124_ulpi_phy_power_on(struct phy *phy)728{729 return 0;730}731 732static int tegra124_ulpi_phy_power_off(struct phy *phy)733{734 return 0;735}736 737static const struct phy_ops tegra124_ulpi_phy_ops = {738 .init = tegra124_ulpi_phy_init,739 .exit = tegra124_ulpi_phy_exit,740 .power_on = tegra124_ulpi_phy_power_on,741 .power_off = tegra124_ulpi_phy_power_off,742 .owner = THIS_MODULE,743};744 745static struct tegra_xusb_pad *746tegra124_ulpi_pad_probe(struct tegra_xusb_padctl *padctl,747 const struct tegra_xusb_pad_soc *soc,748 struct device_node *np)749{750 struct tegra_xusb_ulpi_pad *ulpi;751 struct tegra_xusb_pad *pad;752 int err;753 754 ulpi = kzalloc(sizeof(*ulpi), GFP_KERNEL);755 if (!ulpi)756 return ERR_PTR(-ENOMEM);757 758 pad = &ulpi->base;759 pad->ops = &tegra124_ulpi_lane_ops;760 pad->soc = soc;761 762 err = tegra_xusb_pad_init(pad, padctl, np);763 if (err < 0) {764 kfree(ulpi);765 goto out;766 }767 768 err = tegra_xusb_pad_register(pad, &tegra124_ulpi_phy_ops);769 if (err < 0)770 goto unregister;771 772 dev_set_drvdata(&pad->dev, pad);773 774 return pad;775 776unregister:777 device_unregister(&pad->dev);778out:779 return ERR_PTR(err);780}781 782static void tegra124_ulpi_pad_remove(struct tegra_xusb_pad *pad)783{784 struct tegra_xusb_ulpi_pad *ulpi = to_ulpi_pad(pad);785 786 kfree(ulpi);787}788 789static const struct tegra_xusb_pad_ops tegra124_ulpi_ops = {790 .probe = tegra124_ulpi_pad_probe,791 .remove = tegra124_ulpi_pad_remove,792};793 794static const struct tegra_xusb_pad_soc tegra124_ulpi_pad = {795 .name = "ulpi",796 .num_lanes = ARRAY_SIZE(tegra124_ulpi_lanes),797 .lanes = tegra124_ulpi_lanes,798 .ops = &tegra124_ulpi_ops,799};800 801static const char * const tegra124_hsic_functions[] = {802 "snps",803 "xusb",804};805 806static const struct tegra_xusb_lane_soc tegra124_hsic_lanes[] = {807 TEGRA124_LANE("hsic-0", 0x004, 14, 0x1, hsic),808 TEGRA124_LANE("hsic-1", 0x004, 15, 0x1, hsic),809};810 811static struct tegra_xusb_lane *812tegra124_hsic_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np,813 unsigned int index)814{815 struct tegra_xusb_hsic_lane *hsic;816 int err;817 818 hsic = kzalloc(sizeof(*hsic), GFP_KERNEL);819 if (!hsic)820 return ERR_PTR(-ENOMEM);821 822 INIT_LIST_HEAD(&hsic->base.list);823 hsic->base.soc = &pad->soc->lanes[index];824 hsic->base.index = index;825 hsic->base.pad = pad;826 hsic->base.np = np;827 828 err = tegra_xusb_lane_parse_dt(&hsic->base, np);829 if (err < 0) {830 kfree(hsic);831 return ERR_PTR(err);832 }833 834 return &hsic->base;835}836 837static void tegra124_hsic_lane_remove(struct tegra_xusb_lane *lane)838{839 struct tegra_xusb_hsic_lane *hsic = to_hsic_lane(lane);840 841 kfree(hsic);842}843 844static const struct tegra_xusb_lane_ops tegra124_hsic_lane_ops = {845 .probe = tegra124_hsic_lane_probe,846 .remove = tegra124_hsic_lane_remove,847};848 849static int tegra124_hsic_phy_init(struct phy *phy)850{851 struct tegra_xusb_lane *lane = phy_get_drvdata(phy);852 853 return tegra124_xusb_padctl_enable(lane->pad->padctl);854}855 856static int tegra124_hsic_phy_exit(struct phy *phy)857{858 struct tegra_xusb_lane *lane = phy_get_drvdata(phy);859 860 return tegra124_xusb_padctl_disable(lane->pad->padctl);861}862 863static int tegra124_hsic_phy_power_on(struct phy *phy)864{865 struct tegra_xusb_lane *lane = phy_get_drvdata(phy);866 struct tegra_xusb_hsic_lane *hsic = to_hsic_lane(lane);867 struct tegra_xusb_hsic_pad *pad = to_hsic_pad(lane->pad);868 struct tegra_xusb_padctl *padctl = lane->pad->padctl;869 unsigned int index = lane->index;870 u32 value;871 int err;872 873 err = regulator_enable(pad->supply);874 if (err)875 return err;876 877 padctl_writel(padctl, hsic->strobe_trim,878 XUSB_PADCTL_HSIC_STRB_TRIM_CONTROL);879 880 value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PADX_CTL1(index));881 882 if (hsic->auto_term)883 value |= XUSB_PADCTL_HSIC_PAD_CTL1_AUTO_TERM_EN;884 else885 value &= ~XUSB_PADCTL_HSIC_PAD_CTL1_AUTO_TERM_EN;886 887 padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PADX_CTL1(index));888 889 value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PADX_CTL0(index));890 value &= ~((XUSB_PADCTL_HSIC_PAD_CTL0_TX_RTUNEN_MASK <<891 XUSB_PADCTL_HSIC_PAD_CTL0_TX_RTUNEN_SHIFT) |892 (XUSB_PADCTL_HSIC_PAD_CTL0_TX_RTUNEP_MASK <<893 XUSB_PADCTL_HSIC_PAD_CTL0_TX_RTUNEP_SHIFT) |894 (XUSB_PADCTL_HSIC_PAD_CTL0_TX_RSLEWN_MASK <<895 XUSB_PADCTL_HSIC_PAD_CTL0_TX_RSLEWN_SHIFT) |896 (XUSB_PADCTL_HSIC_PAD_CTL0_TX_RSLEWP_MASK <<897 XUSB_PADCTL_HSIC_PAD_CTL0_TX_RSLEWP_SHIFT));898 value |= (hsic->tx_rtune_n <<899 XUSB_PADCTL_HSIC_PAD_CTL0_TX_RTUNEN_SHIFT) |900 (hsic->tx_rtune_p <<901 XUSB_PADCTL_HSIC_PAD_CTL0_TX_RTUNEP_SHIFT) |902 (hsic->tx_rslew_n <<903 XUSB_PADCTL_HSIC_PAD_CTL0_TX_RSLEWN_SHIFT) |904 (hsic->tx_rslew_p <<905 XUSB_PADCTL_HSIC_PAD_CTL0_TX_RSLEWP_SHIFT);906 padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PADX_CTL0(index));907 908 value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PADX_CTL2(index));909 value &= ~((XUSB_PADCTL_HSIC_PAD_CTL2_RX_STROBE_TRIM_MASK <<910 XUSB_PADCTL_HSIC_PAD_CTL2_RX_STROBE_TRIM_SHIFT) |911 (XUSB_PADCTL_HSIC_PAD_CTL2_RX_DATA_TRIM_MASK <<912 XUSB_PADCTL_HSIC_PAD_CTL2_RX_DATA_TRIM_SHIFT));913 value |= (hsic->rx_strobe_trim <<914 XUSB_PADCTL_HSIC_PAD_CTL2_RX_STROBE_TRIM_SHIFT) |915 (hsic->rx_data_trim <<916 XUSB_PADCTL_HSIC_PAD_CTL2_RX_DATA_TRIM_SHIFT);917 padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PADX_CTL2(index));918 919 value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PADX_CTL1(index));920 value &= ~(XUSB_PADCTL_HSIC_PAD_CTL1_RPD_STROBE |921 XUSB_PADCTL_HSIC_PAD_CTL1_RPU_DATA |922 XUSB_PADCTL_HSIC_PAD_CTL1_PD_RX |923 XUSB_PADCTL_HSIC_PAD_CTL1_PD_ZI |924 XUSB_PADCTL_HSIC_PAD_CTL1_PD_TRX |925 XUSB_PADCTL_HSIC_PAD_CTL1_PD_TX);926 value |= XUSB_PADCTL_HSIC_PAD_CTL1_RPD_DATA |927 XUSB_PADCTL_HSIC_PAD_CTL1_RPU_STROBE;928 padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PADX_CTL1(index));929 930 return 0;931}932 933static int tegra124_hsic_phy_power_off(struct phy *phy)934{935 struct tegra_xusb_lane *lane = phy_get_drvdata(phy);936 struct tegra_xusb_hsic_pad *pad = to_hsic_pad(lane->pad);937 struct tegra_xusb_padctl *padctl = lane->pad->padctl;938 unsigned int index = lane->index;939 u32 value;940 941 value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PADX_CTL1(index));942 value |= XUSB_PADCTL_HSIC_PAD_CTL1_PD_RX |943 XUSB_PADCTL_HSIC_PAD_CTL1_PD_ZI |944 XUSB_PADCTL_HSIC_PAD_CTL1_PD_TRX |945 XUSB_PADCTL_HSIC_PAD_CTL1_PD_TX;946 padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PADX_CTL1(index));947 948 regulator_disable(pad->supply);949 950 return 0;951}952 953static const struct phy_ops tegra124_hsic_phy_ops = {954 .init = tegra124_hsic_phy_init,955 .exit = tegra124_hsic_phy_exit,956 .power_on = tegra124_hsic_phy_power_on,957 .power_off = tegra124_hsic_phy_power_off,958 .owner = THIS_MODULE,959};960 961static struct tegra_xusb_pad *962tegra124_hsic_pad_probe(struct tegra_xusb_padctl *padctl,963 const struct tegra_xusb_pad_soc *soc,964 struct device_node *np)965{966 struct tegra_xusb_hsic_pad *hsic;967 struct tegra_xusb_pad *pad;968 int err;969 970 hsic = kzalloc(sizeof(*hsic), GFP_KERNEL);971 if (!hsic)972 return ERR_PTR(-ENOMEM);973 974 pad = &hsic->base;975 pad->ops = &tegra124_hsic_lane_ops;976 pad->soc = soc;977 978 err = tegra_xusb_pad_init(pad, padctl, np);979 if (err < 0) {980 kfree(hsic);981 goto out;982 }983 984 err = tegra_xusb_pad_register(pad, &tegra124_hsic_phy_ops);985 if (err < 0)986 goto unregister;987 988 dev_set_drvdata(&pad->dev, pad);989 990 return pad;991 992unregister:993 device_unregister(&pad->dev);994out:995 return ERR_PTR(err);996}997 998static void tegra124_hsic_pad_remove(struct tegra_xusb_pad *pad)999{1000 struct tegra_xusb_hsic_pad *hsic = to_hsic_pad(pad);1001 1002 kfree(hsic);1003}1004 1005static const struct tegra_xusb_pad_ops tegra124_hsic_ops = {1006 .probe = tegra124_hsic_pad_probe,1007 .remove = tegra124_hsic_pad_remove,1008};1009 1010static const struct tegra_xusb_pad_soc tegra124_hsic_pad = {1011 .name = "hsic",1012 .num_lanes = ARRAY_SIZE(tegra124_hsic_lanes),1013 .lanes = tegra124_hsic_lanes,1014 .ops = &tegra124_hsic_ops,1015};1016 1017static const char * const tegra124_pcie_functions[] = {1018 "pcie",1019 "usb3-ss",1020 "sata",1021};1022 1023static const struct tegra_xusb_lane_soc tegra124_pcie_lanes[] = {1024 TEGRA124_LANE("pcie-0", 0x134, 16, 0x3, pcie),1025 TEGRA124_LANE("pcie-1", 0x134, 18, 0x3, pcie),1026 TEGRA124_LANE("pcie-2", 0x134, 20, 0x3, pcie),1027 TEGRA124_LANE("pcie-3", 0x134, 22, 0x3, pcie),1028 TEGRA124_LANE("pcie-4", 0x134, 24, 0x3, pcie),1029};1030 1031static struct tegra_xusb_lane *1032tegra124_pcie_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np,1033 unsigned int index)1034{1035 struct tegra_xusb_pcie_lane *pcie;1036 int err;1037 1038 pcie = kzalloc(sizeof(*pcie), GFP_KERNEL);1039 if (!pcie)1040 return ERR_PTR(-ENOMEM);1041 1042 INIT_LIST_HEAD(&pcie->base.list);1043 pcie->base.soc = &pad->soc->lanes[index];1044 pcie->base.index = index;1045 pcie->base.pad = pad;1046 pcie->base.np = np;1047 1048 err = tegra_xusb_lane_parse_dt(&pcie->base, np);1049 if (err < 0) {1050 kfree(pcie);1051 return ERR_PTR(err);1052 }1053 1054 return &pcie->base;1055}1056 1057static void tegra124_pcie_lane_remove(struct tegra_xusb_lane *lane)1058{1059 struct tegra_xusb_pcie_lane *pcie = to_pcie_lane(lane);1060 1061 kfree(pcie);1062}1063 1064static const struct tegra_xusb_lane_ops tegra124_pcie_lane_ops = {1065 .probe = tegra124_pcie_lane_probe,1066 .remove = tegra124_pcie_lane_remove,1067};1068 1069static int tegra124_pcie_phy_init(struct phy *phy)1070{1071 struct tegra_xusb_lane *lane = phy_get_drvdata(phy);1072 1073 return tegra124_xusb_padctl_enable(lane->pad->padctl);1074}1075 1076static int tegra124_pcie_phy_exit(struct phy *phy)1077{1078 struct tegra_xusb_lane *lane = phy_get_drvdata(phy);1079 1080 return tegra124_xusb_padctl_disable(lane->pad->padctl);1081}1082 1083static int tegra124_pcie_phy_power_on(struct phy *phy)1084{1085 struct tegra_xusb_lane *lane = phy_get_drvdata(phy);1086 struct tegra_xusb_padctl *padctl = lane->pad->padctl;1087 unsigned long timeout;1088 int err = -ETIMEDOUT;1089 u32 value;1090 1091 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);1092 value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK;1093 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);1094 1095 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL2);1096 value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN |1097 XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN |1098 XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL;1099 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL2);1100 1101 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);1102 value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST;1103 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);1104 1105 timeout = jiffies + msecs_to_jiffies(50);1106 1107 while (time_before(jiffies, timeout)) {1108 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);1109 if (value & XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET) {1110 err = 0;1111 break;1112 }1113 1114 usleep_range(100, 200);1115 }1116 1117 value = padctl_readl(padctl, XUSB_PADCTL_USB3_PAD_MUX);1118 value |= XUSB_PADCTL_USB3_PAD_MUX_PCIE_IDDQ_DISABLE(lane->index);1119 padctl_writel(padctl, value, XUSB_PADCTL_USB3_PAD_MUX);1120 1121 return err;1122}1123 1124static int tegra124_pcie_phy_power_off(struct phy *phy)1125{1126 struct tegra_xusb_lane *lane = phy_get_drvdata(phy);1127 struct tegra_xusb_padctl *padctl = lane->pad->padctl;1128 u32 value;1129 1130 value = padctl_readl(padctl, XUSB_PADCTL_USB3_PAD_MUX);1131 value &= ~XUSB_PADCTL_USB3_PAD_MUX_PCIE_IDDQ_DISABLE(lane->index);1132 padctl_writel(padctl, value, XUSB_PADCTL_USB3_PAD_MUX);1133 1134 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);1135 value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST;1136 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);1137 1138 return 0;1139}1140 1141static const struct phy_ops tegra124_pcie_phy_ops = {1142 .init = tegra124_pcie_phy_init,1143 .exit = tegra124_pcie_phy_exit,1144 .power_on = tegra124_pcie_phy_power_on,1145 .power_off = tegra124_pcie_phy_power_off,1146 .owner = THIS_MODULE,1147};1148 1149static struct tegra_xusb_pad *1150tegra124_pcie_pad_probe(struct tegra_xusb_padctl *padctl,1151 const struct tegra_xusb_pad_soc *soc,1152 struct device_node *np)1153{1154 struct tegra_xusb_pcie_pad *pcie;1155 struct tegra_xusb_pad *pad;1156 int err;1157 1158 pcie = kzalloc(sizeof(*pcie), GFP_KERNEL);1159 if (!pcie)1160 return ERR_PTR(-ENOMEM);1161 1162 pad = &pcie->base;1163 pad->ops = &tegra124_pcie_lane_ops;1164 pad->soc = soc;1165 1166 err = tegra_xusb_pad_init(pad, padctl, np);1167 if (err < 0) {1168 kfree(pcie);1169 goto out;1170 }1171 1172 err = tegra_xusb_pad_register(pad, &tegra124_pcie_phy_ops);1173 if (err < 0)1174 goto unregister;1175 1176 dev_set_drvdata(&pad->dev, pad);1177 1178 return pad;1179 1180unregister:1181 device_unregister(&pad->dev);1182out:1183 return ERR_PTR(err);1184}1185 1186static void tegra124_pcie_pad_remove(struct tegra_xusb_pad *pad)1187{1188 struct tegra_xusb_pcie_pad *pcie = to_pcie_pad(pad);1189 1190 kfree(pcie);1191}1192 1193static const struct tegra_xusb_pad_ops tegra124_pcie_ops = {1194 .probe = tegra124_pcie_pad_probe,1195 .remove = tegra124_pcie_pad_remove,1196};1197 1198static const struct tegra_xusb_pad_soc tegra124_pcie_pad = {1199 .name = "pcie",1200 .num_lanes = ARRAY_SIZE(tegra124_pcie_lanes),1201 .lanes = tegra124_pcie_lanes,1202 .ops = &tegra124_pcie_ops,1203};1204 1205static const struct tegra_xusb_lane_soc tegra124_sata_lanes[] = {1206 TEGRA124_LANE("sata-0", 0x134, 26, 0x3, pcie),1207};1208 1209static struct tegra_xusb_lane *1210tegra124_sata_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np,1211 unsigned int index)1212{1213 struct tegra_xusb_sata_lane *sata;1214 int err;1215 1216 sata = kzalloc(sizeof(*sata), GFP_KERNEL);1217 if (!sata)1218 return ERR_PTR(-ENOMEM);1219 1220 INIT_LIST_HEAD(&sata->base.list);1221 sata->base.soc = &pad->soc->lanes[index];1222 sata->base.index = index;1223 sata->base.pad = pad;1224 sata->base.np = np;1225 1226 err = tegra_xusb_lane_parse_dt(&sata->base, np);1227 if (err < 0) {1228 kfree(sata);1229 return ERR_PTR(err);1230 }1231 1232 return &sata->base;1233}1234 1235static void tegra124_sata_lane_remove(struct tegra_xusb_lane *lane)1236{1237 struct tegra_xusb_sata_lane *sata = to_sata_lane(lane);1238 1239 kfree(sata);1240}1241 1242static const struct tegra_xusb_lane_ops tegra124_sata_lane_ops = {1243 .probe = tegra124_sata_lane_probe,1244 .remove = tegra124_sata_lane_remove,1245};1246 1247static int tegra124_sata_phy_init(struct phy *phy)1248{1249 struct tegra_xusb_lane *lane = phy_get_drvdata(phy);1250 1251 return tegra124_xusb_padctl_enable(lane->pad->padctl);1252}1253 1254static int tegra124_sata_phy_exit(struct phy *phy)1255{1256 struct tegra_xusb_lane *lane = phy_get_drvdata(phy);1257 1258 return tegra124_xusb_padctl_disable(lane->pad->padctl);1259}1260 1261static int tegra124_sata_phy_power_on(struct phy *phy)1262{1263 struct tegra_xusb_lane *lane = phy_get_drvdata(phy);1264 struct tegra_xusb_padctl *padctl = lane->pad->padctl;1265 unsigned long timeout;1266 int err = -ETIMEDOUT;1267 u32 value;1268 1269 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);1270 value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD;1271 value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ;1272 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);1273 1274 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);1275 value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD;1276 value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ;1277 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);1278 1279 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);1280 value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE;1281 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);1282 1283 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);1284 value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST;1285 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);1286 1287 timeout = jiffies + msecs_to_jiffies(50);1288 1289 while (time_before(jiffies, timeout)) {1290 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);1291 if (value & XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET) {1292 err = 0;1293 break;1294 }1295 1296 usleep_range(100, 200);1297 }1298 1299 value = padctl_readl(padctl, XUSB_PADCTL_USB3_PAD_MUX);1300 value |= XUSB_PADCTL_USB3_PAD_MUX_SATA_IDDQ_DISABLE(lane->index);1301 padctl_writel(padctl, value, XUSB_PADCTL_USB3_PAD_MUX);1302 1303 return err;1304}1305 1306static int tegra124_sata_phy_power_off(struct phy *phy)1307{1308 struct tegra_xusb_lane *lane = phy_get_drvdata(phy);1309 struct tegra_xusb_padctl *padctl = lane->pad->padctl;1310 u32 value;1311 1312 value = padctl_readl(padctl, XUSB_PADCTL_USB3_PAD_MUX);1313 value &= ~XUSB_PADCTL_USB3_PAD_MUX_SATA_IDDQ_DISABLE(lane->index);1314 padctl_writel(padctl, value, XUSB_PADCTL_USB3_PAD_MUX);1315 1316 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);1317 value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST;1318 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);1319 1320 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);1321 value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE;1322 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);1323 1324 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);1325 value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD;1326 value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ;1327 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);1328 1329 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);1330 value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD;1331 value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ;1332 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);1333 1334 return 0;1335}1336 1337static const struct phy_ops tegra124_sata_phy_ops = {1338 .init = tegra124_sata_phy_init,1339 .exit = tegra124_sata_phy_exit,1340 .power_on = tegra124_sata_phy_power_on,1341 .power_off = tegra124_sata_phy_power_off,1342 .owner = THIS_MODULE,1343};1344 1345static struct tegra_xusb_pad *1346tegra124_sata_pad_probe(struct tegra_xusb_padctl *padctl,1347 const struct tegra_xusb_pad_soc *soc,1348 struct device_node *np)1349{1350 struct tegra_xusb_sata_pad *sata;1351 struct tegra_xusb_pad *pad;1352 int err;1353 1354 sata = kzalloc(sizeof(*sata), GFP_KERNEL);1355 if (!sata)1356 return ERR_PTR(-ENOMEM);1357 1358 pad = &sata->base;1359 pad->ops = &tegra124_sata_lane_ops;1360 pad->soc = soc;1361 1362 err = tegra_xusb_pad_init(pad, padctl, np);1363 if (err < 0) {1364 kfree(sata);1365 goto out;1366 }1367 1368 err = tegra_xusb_pad_register(pad, &tegra124_sata_phy_ops);1369 if (err < 0)1370 goto unregister;1371 1372 dev_set_drvdata(&pad->dev, pad);1373 1374 return pad;1375 1376unregister:1377 device_unregister(&pad->dev);1378out:1379 return ERR_PTR(err);1380}1381 1382static void tegra124_sata_pad_remove(struct tegra_xusb_pad *pad)1383{1384 struct tegra_xusb_sata_pad *sata = to_sata_pad(pad);1385 1386 kfree(sata);1387}1388 1389static const struct tegra_xusb_pad_ops tegra124_sata_ops = {1390 .probe = tegra124_sata_pad_probe,1391 .remove = tegra124_sata_pad_remove,1392};1393 1394static const struct tegra_xusb_pad_soc tegra124_sata_pad = {1395 .name = "sata",1396 .num_lanes = ARRAY_SIZE(tegra124_sata_lanes),1397 .lanes = tegra124_sata_lanes,1398 .ops = &tegra124_sata_ops,1399};1400 1401static const struct tegra_xusb_pad_soc *tegra124_pads[] = {1402 &tegra124_usb2_pad,1403 &tegra124_ulpi_pad,1404 &tegra124_hsic_pad,1405 &tegra124_pcie_pad,1406 &tegra124_sata_pad,1407};1408 1409static int tegra124_usb2_port_enable(struct tegra_xusb_port *port)1410{1411 return 0;1412}1413 1414static void tegra124_usb2_port_disable(struct tegra_xusb_port *port)1415{1416}1417 1418static struct tegra_xusb_lane *1419tegra124_usb2_port_map(struct tegra_xusb_port *port)1420{1421 return tegra_xusb_find_lane(port->padctl, "usb2", port->index);1422}1423 1424static const struct tegra_xusb_port_ops tegra124_usb2_port_ops = {1425 .release = tegra_xusb_usb2_port_release,1426 .remove = tegra_xusb_usb2_port_remove,1427 .enable = tegra124_usb2_port_enable,1428 .disable = tegra124_usb2_port_disable,1429 .map = tegra124_usb2_port_map,1430};1431 1432static int tegra124_ulpi_port_enable(struct tegra_xusb_port *port)1433{1434 return 0;1435}1436 1437static void tegra124_ulpi_port_disable(struct tegra_xusb_port *port)1438{1439}1440 1441static struct tegra_xusb_lane *1442tegra124_ulpi_port_map(struct tegra_xusb_port *port)1443{1444 return tegra_xusb_find_lane(port->padctl, "ulpi", port->index);1445}1446 1447static const struct tegra_xusb_port_ops tegra124_ulpi_port_ops = {1448 .release = tegra_xusb_ulpi_port_release,1449 .enable = tegra124_ulpi_port_enable,1450 .disable = tegra124_ulpi_port_disable,1451 .map = tegra124_ulpi_port_map,1452};1453 1454static int tegra124_hsic_port_enable(struct tegra_xusb_port *port)1455{1456 return 0;1457}1458 1459static void tegra124_hsic_port_disable(struct tegra_xusb_port *port)1460{1461}1462 1463static struct tegra_xusb_lane *1464tegra124_hsic_port_map(struct tegra_xusb_port *port)1465{1466 return tegra_xusb_find_lane(port->padctl, "hsic", port->index);1467}1468 1469static const struct tegra_xusb_port_ops tegra124_hsic_port_ops = {1470 .release = tegra_xusb_hsic_port_release,1471 .enable = tegra124_hsic_port_enable,1472 .disable = tegra124_hsic_port_disable,1473 .map = tegra124_hsic_port_map,1474};1475 1476static int tegra124_usb3_port_enable(struct tegra_xusb_port *port)1477{1478 struct tegra_xusb_usb3_port *usb3 = to_usb3_port(port);1479 struct tegra_xusb_padctl *padctl = port->padctl;1480 struct tegra_xusb_lane *lane = usb3->base.lane;1481 unsigned int index = port->index, offset;1482 u32 value;1483 1484 value = padctl_readl(padctl, XUSB_PADCTL_SS_PORT_MAP);1485 1486 if (!usb3->internal)1487 value &= ~XUSB_PADCTL_SS_PORT_MAP_PORTX_INTERNAL(index);1488 else1489 value |= XUSB_PADCTL_SS_PORT_MAP_PORTX_INTERNAL(index);1490 1491 value &= ~XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP_MASK(index);1492 value |= XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP(index, usb3->port);1493 padctl_writel(padctl, value, XUSB_PADCTL_SS_PORT_MAP);1494 1495 /*1496 * TODO: move this code into the PCIe/SATA PHY ->power_on() callbacks1497 * and conditionalize based on mux function? This seems to work, but1498 * might not be the exact proper sequence.1499 */1500 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_USB3_PADX_CTL2(index));1501 value &= ~((XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_WANDER_MASK <<1502 XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_WANDER_SHIFT) |1503 (XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_MASK <<1504 XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_SHIFT) |1505 (XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_CDR_CNTL_MASK <<1506 XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_CDR_CNTL_SHIFT));1507 value |= (XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_WANDER_VAL <<1508 XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_WANDER_SHIFT) |1509 (XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_CDR_CNTL_VAL <<1510 XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_CDR_CNTL_SHIFT) |1511 (XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_VAL <<1512 XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_SHIFT);1513 1514 if (usb3->context_saved) {1515 value &= ~((XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_G_MASK <<1516 XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_G_SHIFT) |1517 (XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_Z_MASK <<1518 XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_Z_SHIFT));1519 value |= (usb3->ctle_g <<1520 XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_G_SHIFT) |1521 (usb3->ctle_z <<1522 XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_Z_SHIFT);1523 }1524 1525 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_USB3_PADX_CTL2(index));1526 1527 value = XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_VAL;1528 1529 if (usb3->context_saved) {1530 value &= ~((XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_TAP_MASK <<1531 XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_TAP_SHIFT) |1532 (XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_AMP_MASK <<1533 XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_AMP_SHIFT));1534 value |= (usb3->tap1 <<1535 XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_TAP_SHIFT) |1536 (usb3->amp <<1537 XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_AMP_SHIFT);1538 }1539 1540 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_USB3_PADX_CTL4(index));1541 1542 if (lane->pad == padctl->pcie)1543 offset = XUSB_PADCTL_IOPHY_MISC_PAD_PX_CTL2(lane->index);1544 else1545 offset = XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL2;1546 1547 value = padctl_readl(padctl, offset);1548 value &= ~(XUSB_PADCTL_IOPHY_MISC_PAD_CTL2_SPARE_IN_MASK <<1549 XUSB_PADCTL_IOPHY_MISC_PAD_CTL2_SPARE_IN_SHIFT);1550 value |= XUSB_PADCTL_IOPHY_MISC_PAD_CTL2_SPARE_IN_VAL <<1551 XUSB_PADCTL_IOPHY_MISC_PAD_CTL2_SPARE_IN_SHIFT;1552 padctl_writel(padctl, value, offset);1553 1554 if (lane->pad == padctl->pcie)1555 offset = XUSB_PADCTL_IOPHY_MISC_PAD_PX_CTL5(lane->index);1556 else1557 offset = XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL5;1558 1559 value = padctl_readl(padctl, offset);1560 value |= XUSB_PADCTL_IOPHY_MISC_PAD_CTL5_RX_QEYE_EN;1561 padctl_writel(padctl, value, offset);1562 1563 /* Enable SATA PHY when SATA lane is used */1564 if (lane->pad == padctl->sata) {1565 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);1566 value &= ~(XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL0_REFCLK_NDIV_MASK <<1567 XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL0_REFCLK_NDIV_SHIFT);1568 value |= 0x2 <<1569 XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL0_REFCLK_NDIV_SHIFT;1570 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);1571 1572 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL2);1573 value &= ~((XUSB_PADCTL_IOPHY_PLL_S0_CTL2_XDIGCLK_SEL_MASK <<1574 XUSB_PADCTL_IOPHY_PLL_S0_CTL2_XDIGCLK_SEL_SHIFT) |1575 (XUSB_PADCTL_IOPHY_PLL_S0_CTL2_PLL1_CP_CNTL_MASK <<1576 XUSB_PADCTL_IOPHY_PLL_S0_CTL2_PLL1_CP_CNTL_SHIFT) |1577 (XUSB_PADCTL_IOPHY_PLL_S0_CTL2_PLL0_CP_CNTL_MASK <<1578 XUSB_PADCTL_IOPHY_PLL_S0_CTL2_PLL0_CP_CNTL_SHIFT) |1579 XUSB_PADCTL_IOPHY_PLL_S0_CTL2_TCLKOUT_EN);1580 value |= (0x7 <<1581 XUSB_PADCTL_IOPHY_PLL_S0_CTL2_XDIGCLK_SEL_SHIFT) |1582 (0x8 <<1583 XUSB_PADCTL_IOPHY_PLL_S0_CTL2_PLL1_CP_CNTL_SHIFT) |1584 (0x8 <<1585 XUSB_PADCTL_IOPHY_PLL_S0_CTL2_PLL0_CP_CNTL_SHIFT) |1586 XUSB_PADCTL_IOPHY_PLL_S0_CTL2_TXCLKREF_SEL;1587 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL2);1588 1589 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL3);1590 value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL3_RCAL_BYPASS;1591 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL3);1592 }1593 1594 value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);1595 value &= ~XUSB_PADCTL_ELPG_PROGRAM_SSPX_ELPG_VCORE_DOWN(index);1596 padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);1597 1598 usleep_range(100, 200);1599 1600 value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);1601 value &= ~XUSB_PADCTL_ELPG_PROGRAM_SSPX_ELPG_CLAMP_EN_EARLY(index);1602 padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);1603 1604 usleep_range(100, 200);1605 1606 value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);1607 value &= ~XUSB_PADCTL_ELPG_PROGRAM_SSPX_ELPG_CLAMP_EN(index);1608 padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);1609 1610 return 0;1611}1612 1613static void tegra124_usb3_port_disable(struct tegra_xusb_port *port)1614{1615 struct tegra_xusb_padctl *padctl = port->padctl;1616 u32 value;1617 1618 value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);1619 value |= XUSB_PADCTL_ELPG_PROGRAM_SSPX_ELPG_CLAMP_EN_EARLY(port->index);1620 padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);1621 1622 usleep_range(100, 200);1623 1624 value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);1625 value |= XUSB_PADCTL_ELPG_PROGRAM_SSPX_ELPG_CLAMP_EN(port->index);1626 padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);1627 1628 usleep_range(250, 350);1629 1630 value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);1631 value |= XUSB_PADCTL_ELPG_PROGRAM_SSPX_ELPG_VCORE_DOWN(port->index);1632 padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);1633 1634 value = padctl_readl(padctl, XUSB_PADCTL_SS_PORT_MAP);1635 value &= ~XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP_MASK(port->index);1636 value |= XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP(port->index, 0x7);1637 padctl_writel(padctl, value, XUSB_PADCTL_SS_PORT_MAP);1638}1639 1640static const struct tegra_xusb_lane_map tegra124_usb3_map[] = {1641 { 0, "pcie", 0 },1642 { 1, "pcie", 1 },1643 { 1, "sata", 0 },1644 { 0, NULL, 0 },1645};1646 1647static struct tegra_xusb_lane *1648tegra124_usb3_port_map(struct tegra_xusb_port *port)1649{1650 return tegra_xusb_port_find_lane(port, tegra124_usb3_map, "usb3-ss");1651}1652 1653static const struct tegra_xusb_port_ops tegra124_usb3_port_ops = {1654 .release = tegra_xusb_usb3_port_release,1655 .enable = tegra124_usb3_port_enable,1656 .disable = tegra124_usb3_port_disable,1657 .map = tegra124_usb3_port_map,1658};1659 1660static int1661tegra124_xusb_read_fuse_calibration(struct tegra124_xusb_fuse_calibration *fuse)1662{1663 unsigned int i;1664 int err;1665 u32 value;1666 1667 err = tegra_fuse_readl(TEGRA_FUSE_SKU_CALIB_0, &value);1668 if (err < 0)1669 return err;1670 1671 for (i = 0; i < ARRAY_SIZE(fuse->hs_curr_level); i++) {1672 fuse->hs_curr_level[i] =1673 (value >> FUSE_SKU_CALIB_HS_CURR_LEVEL_PADX_SHIFT(i)) &1674 FUSE_SKU_CALIB_HS_CURR_LEVEL_PAD_MASK;1675 }1676 fuse->hs_iref_cap =1677 (value >> FUSE_SKU_CALIB_HS_IREF_CAP_SHIFT) &1678 FUSE_SKU_CALIB_HS_IREF_CAP_MASK;1679 fuse->hs_term_range_adj =1680 (value >> FUSE_SKU_CALIB_HS_TERM_RANGE_ADJ_SHIFT) &1681 FUSE_SKU_CALIB_HS_TERM_RANGE_ADJ_MASK;1682 fuse->hs_squelch_level =1683 (value >> FUSE_SKU_CALIB_HS_SQUELCH_LEVEL_SHIFT) &1684 FUSE_SKU_CALIB_HS_SQUELCH_LEVEL_MASK;1685 1686 return 0;1687}1688 1689static struct tegra_xusb_padctl *1690tegra124_xusb_padctl_probe(struct device *dev,1691 const struct tegra_xusb_padctl_soc *soc)1692{1693 struct tegra124_xusb_padctl *padctl;1694 int err;1695 1696 padctl = devm_kzalloc(dev, sizeof(*padctl), GFP_KERNEL);1697 if (!padctl)1698 return ERR_PTR(-ENOMEM);1699 1700 padctl->base.dev = dev;1701 padctl->base.soc = soc;1702 1703 err = tegra124_xusb_read_fuse_calibration(&padctl->fuse);1704 if (err < 0)1705 return ERR_PTR(err);1706 1707 return &padctl->base;1708}1709 1710static void tegra124_xusb_padctl_remove(struct tegra_xusb_padctl *padctl)1711{1712}1713 1714static const struct tegra_xusb_padctl_ops tegra124_xusb_padctl_ops = {1715 .probe = tegra124_xusb_padctl_probe,1716 .remove = tegra124_xusb_padctl_remove,1717 .usb3_save_context = tegra124_usb3_save_context,1718 .hsic_set_idle = tegra124_hsic_set_idle,1719};1720 1721static const char * const tegra124_xusb_padctl_supply_names[] = {1722 "avdd-pll-utmip",1723 "avdd-pll-erefe",1724 "avdd-pex-pll",1725 "hvdd-pex-pll-e",1726};1727 1728const struct tegra_xusb_padctl_soc tegra124_xusb_padctl_soc = {1729 .num_pads = ARRAY_SIZE(tegra124_pads),1730 .pads = tegra124_pads,1731 .ports = {1732 .usb2 = {1733 .ops = &tegra124_usb2_port_ops,1734 .count = 3,1735 },1736 .ulpi = {1737 .ops = &tegra124_ulpi_port_ops,1738 .count = 1,1739 },1740 .hsic = {1741 .ops = &tegra124_hsic_port_ops,1742 .count = 2,1743 },1744 .usb3 = {1745 .ops = &tegra124_usb3_port_ops,1746 .count = 2,1747 },1748 },1749 .ops = &tegra124_xusb_padctl_ops,1750 .supply_names = tegra124_xusb_padctl_supply_names,1751 .num_supplies = ARRAY_SIZE(tegra124_xusb_padctl_supply_names),1752};1753EXPORT_SYMBOL_GPL(tegra124_xusb_padctl_soc);1754 1755MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");1756MODULE_DESCRIPTION("NVIDIA Tegra 124 XUSB Pad Controller driver");1757MODULE_LICENSE("GPL v2");1758