Path: blob/main/sys/arm64/nvidia/tegra210/tegra210_xusbpadctl.c
48266 views
/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright 2020 Michal Meloun <[email protected]>4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8* 1. Redistributions of source code must retain the above copyright9* notice, this list of conditions and the following disclaimer.10* 2. Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13*14* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND15* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE16* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE17* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE18* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL19* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS20* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)21* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT22* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY23* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF24* SUCH DAMAGE.25*/2627#include <sys/param.h>28#include <sys/systm.h>29#include <sys/bus.h>30#include <sys/kernel.h>31#include <sys/module.h>32#include <sys/malloc.h>33#include <sys/rman.h>3435#include <machine/bus.h>3637#include <dev/clk/clk.h>38#include <dev/hwreset/hwreset.h>39#include <dev/phy/phy.h>40#include <dev/regulator/regulator.h>41#include <dev/fdt/fdt_common.h>42#include <dev/fdt/fdt_pinctrl.h>43#include <dev/ofw/openfirm.h>44#include <dev/ofw/ofw_bus.h>45#include <dev/ofw/ofw_bus_subr.h>4647#include <arm/nvidia/tegra_efuse.h>4849#include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>5051#include "phynode_if.h"5253/* FUSE calibration data. */54#define FUSE_SKU_CALIB_0 0x0F055#define FUSE_SKU_CALIB_0_HS_CURR_LEVEL_123(x, i) (((x) >> (11 + ((i) - 1) * 6)) & 0x3F);56#define FUSE_SKU_CALIB_0_HS_TERM_RANGE_ADJ(x) (((x) >> 7) & 0x0F);57#define FUSE_SKU_CALIB_0_HS_CURR_LEVEL_0(x) (((x) >> 0) & 0x3F);5859#define FUSE_USB_CALIB_EXT_0 0x25060#define FUSE_USB_CALIB_EXT_0_RPD_CTRL(x) (((x) >> 0) & 0x1F);616263/* Registers. */64#define XUSB_PADCTL_USB2_PAD_MUX 0x0046566#define XUSB_PADCTL_USB2_PORT_CAP 0x00867#define USB2_PORT_CAP_PORT_REVERSE_ID(p) (1 << (3 + (p) * 4))68#define USB2_PORT_CAP_PORT_INTERNAL(p) (1 << (2 + (p) * 4))69#define USB2_PORT_CAP_PORT_CAP(p, x) (((x) & 3) << ((p) * 4))70#define USB2_PORT_CAP_PORT_CAP_OTG 0x371#define USB2_PORT_CAP_PORT_CAP_DEVICE 0x272#define USB2_PORT_CAP_PORT_CAP_HOST 0x173#define USB2_PORT_CAP_PORT_CAP_DISABLED 0x07475#define XUSB_PADCTL_SS_PORT_MAP 0x01476#define SS_PORT_MAP_PORT_INTERNAL(p) (1 << (3 + (p) * 4))77#define SS_PORT_MAP_PORT_MAP(p, x) (((x) & 7) << ((p) * 4))7879#define XUSB_PADCTL_ELPG_PROGRAM1 0x02480#define ELPG_PROGRAM1_AUX_MUX_LP0_VCORE_DOWN (1 << 31)81#define ELPG_PROGRAM1_AUX_MUX_LP0_CLAMP_EN_EARLY (1 << 30)82#define ELPG_PROGRAM1_AUX_MUX_LP0_CLAMP_EN (1 << 29)83#define ELPG_PROGRAM1_SSP_ELPG_VCORE_DOWN(x) (1 << (2 + (x) * 3))84#define ELPG_PROGRAM1_SSP_ELPG_CLAMP_EN_EARLY(x) (1 << (1 + (x) * 3))85#define ELPG_PROGRAM1_SSP_ELPG_CLAMP_EN(x) (1 << (0 + (x) * 3))8687#define XUSB_PADCTL_USB3_PAD_MUX 0x02888#define USB3_PAD_MUX_SATA_IDDQ_DISABLE(x) (1 << (8 + (x)))89#define USB3_PAD_MUX_PCIE_IDDQ_DISABLE(x) (1 << (1 + (x)))9091#define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1(x) (0x084 + (x) * 0x40)92#define USB2_BATTERY_CHRG_OTGPAD_CTL1_USBON_RPU_OVRD_VAL (1 << 23)93#define USB2_BATTERY_CHRG_OTGPAD_CTL1_USBON_RPU_OVRD ( 1 << 22)94#define USB2_BATTERY_CHRG_OTGPAD_CTL1_USBON_RPD_OVRD_VAL (1 << 21)95#define USB2_BATTERY_CHRG_OTGPAD_CTL1_USBON_RPD_OVRD (1 << 20)96#define USB2_BATTERY_CHRG_OTGPAD_CTL1_USBOP_RPU_OVRD_VAL (1 << 19)97#define USB2_BATTERY_CHRG_OTGPAD_CTL1_USBOP_RPU_OVRD (1 << 18)98#define USB2_BATTERY_CHRG_OTGPAD_CTL1_USBOP_RPD_OVRD_VAL (1 << 17)99#define USB2_BATTERY_CHRG_OTGPAD_CTL1_USBOP_RPD_OVRD (1 << 16)100#define USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_DYN_DLY(x) (((x) & 0x3) << 9)101#define USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_LEV(x) (((x) & 0x3) << 7)102#define USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_FIX18 (1 << 6)103#define USB2_BATTERY_CHRG_OTGPAD_CTL1_DIV_DET_EN (1 << 4)104#define USB2_BATTERY_CHRG_OTGPAD_CTL1_VOP_DIV2P7_DET (1 << 3)105#define USB2_BATTERY_CHRG_OTGPAD_CTL1_VOP_DIV2P0_DET (1 << 2)106#define USB2_BATTERY_CHRG_OTGPAD_CTL1_VON_DIV2P7_DET (1 << 1)107#define USB2_BATTERY_CHRG_OTGPAD_CTL1_VON_DIV2P0_DET (1 << 0)108109#define XUSB_PADCTL_USB2_OTG_PAD_CTL0(x) (0x088 + (x) * 0x40)110#define USB2_OTG_PAD_CTL0_PD_ZI (1 << 29)111#define USB2_OTG_PAD_CTL0_PD2_OVRD_EN (1 << 28)112#define USB2_OTG_PAD_CTL0_PD2 (1 << 27)113#define USB2_OTG_PAD_CTL0_PD (1 << 26)114#define USB2_OTG_PAD_CTL0_TERM_EN (1 << 25)115#define USB2_OTG_PAD_CTL0_LS_FSLEW(x) (((x) & 0x0F) << 21)116#define USB2_OTG_PAD_CTL0_LS_RSLEW(x) (((x) & 0x0F) << 17)117#define USB2_OTG_PAD_CTL0_FS_FSLEW(x) (((x) & 0x0F) << 13)118#define USB2_OTG_PAD_CTL0_FS_RSLEW(x) (((x) & 0x0F) << 9)119#define USB2_OTG_PAD_CTL0_HS_SLEW(x) (((x) & 0x3F) << 6)120#define USB2_OTG_PAD_CTL0_HS_CURR_LEVEL(x) (((x) & 0x3F) << 0)121122#define XUSB_PADCTL_USB2_OTG_PAD_CTL1(x) (0x08C + (x) * 0x40)123#define USB2_OTG_PAD_CTL1_RPD_CTRL(x) (((x) & 0x1F) << 26)124#define USB2_OTG_PAD_CTL1_RPU_STATUS_HIGH (1 << 25)125#define USB2_OTG_PAD_CTL1_RPU_SWITCH_LOW (1 << 24)126#define USB2_OTG_PAD_CTL1_RPU_SWITCH_OVRD (1 << 23)127#define USB2_OTG_PAD_CTL1_HS_LOOPBACK_OVRD_VAL (1 << 22)128#define USB2_OTG_PAD_CTL1_HS_LOOPBACK_OVRD_EN (1 << 21)129#define USB2_OTG_PAD_CTL1_PTERM_RANGE_ADJ(x) (((x) & 0x0F) << 17)130#define USB2_OTG_PAD_CTL1_PD_DISC_OVRD_VAL (1 << 16)131#define USB2_OTG_PAD_CTL1_PD_CHRP_OVRD_VAL (1 << 15)132#define USB2_OTG_PAD_CTL1_RPU_RANGE_ADJ(x) (((x) & 0x03) << 13)133#define USB2_OTG_PAD_CTL1_HS_COUP_EN(x) (((x) & 0x03) << 11)134#define USB2_OTG_PAD_CTL1_SPARE(x) (((x) & 0x0F) << 7)135#define USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ(x) (((x) & 0x0F) << 3)136#define USB2_OTG_PAD_CTL1_PD_DR (1 << 2)137#define USB2_OTG_PAD_CTL1_PD_DISC_OVRD (1 << 1)138#define USB2_OTG_PAD_CTL1_PD_CHRP_OVRD (1 << 0)139140#define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL0(x) (0x0C0 + (x) * 0x40)141#define XUSB_PADCTL_USB2_BIAS_PAD_CTL0 0x0284142#define USB2_BIAS_PAD_CTL0_TRK_PWR_ENA (1 << 29)143#define USB2_BIAS_PAD_CTL0_SPARE(x) (((x) & 0xF) << 25)144#define USB2_BIAS_PAD_CTL0_CHG_DIV(x) (((x) & 0xF) << 21)145#define USB2_BIAS_PAD_CTL0_TEMP_COEF(x) (((x) & 0x7) << 18)146#define USB2_BIAS_PAD_CTL0_VREF_CTRL(x) (((x) & 0x7) << 15)147#define USB2_BIAS_PAD_CTL0_ADJRPU(x) (((x) & 0x7) << 12)148#define USB2_BIAS_PAD_CTL0_PD (1 << 11)149#define USB2_BIAS_PAD_CTL0_TERM_OFFSETL(x) (((x) & 0x7) << 8)150#define USB2_BIAS_PAD_CTL0_HS_CHIRP_LEVEL(x) (((x) & 0x3) << 6)151#define USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL(x) (((x) & 0x7) << 3)152#define USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL(x) (((x) & 0x7) << 0)153154#define XUSB_PADCTL_USB2_BIAS_PAD_CTL1 0x0288155#define USB2_BIAS_PAD_CTL1_FORCE_TRK_CLK_EN (1 << 30)156#define USB2_BIAS_PAD_CTL1_TRK_SW_OVRD (1 << 29)157#define USB2_BIAS_PAD_CTL1_TRK_DONE (1 << 28)158#define USB2_BIAS_PAD_CTL1_TRK_START (1 << 27)159#define USB2_BIAS_PAD_CTL1_PD_TRK (1 << 26)160#define USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER(x) (((x) & 0x7F) << 19)161#define USB2_BIAS_PAD_CTL1_TRK_START_TIMER(x) (((x) & 0x7F) << 12)162#define USB2_BIAS_PAD_CTL1_PCTRL(x) (((x) & 0x3F) << 6)163#define USB2_BIAS_PAD_CTL1_TCTRL(x) (((x) & 0x3F) << 0)164165#define XUSB_PADCTL_HSIC_PAD_CTL0(x) (0x300 + (x) * 0x20)166#define HSIC_PAD_CTL0_RPU_STROBE (1 << 18)167#define HSIC_PAD_CTL0_RPU_DATA1 (1 << 17)168#define HSIC_PAD_CTL0_RPU_DATA0 (1 << 16)169#define HSIC_PAD_CTL0_RPD_STROBE (1 << 15)170#define HSIC_PAD_CTL0_RPD_DATA1 (1 << 14)171#define HSIC_PAD_CTL0_RPD_DATA0 (1 << 13)172#define HSIC_PAD_CTL0_LPBK_STROBE (1 << 12)173#define HSIC_PAD_CTL0_LPBK_DATA1 (1 << 11)174#define HSIC_PAD_CTL0_LPBK_DATA0 (1 << 10)175#define HSIC_PAD_CTL0_PD_ZI_STROBE (1 << 9)176#define HSIC_PAD_CTL0_PD_ZI_DATA1 (1 << 8)177#define HSIC_PAD_CTL0_PD_ZI_DATA0 (1 << 7)178#define HSIC_PAD_CTL0_PD_RX_STROBE (1 << 6)179#define HSIC_PAD_CTL0_PD_RX_DATA1 (1 << 5)180#define HSIC_PAD_CTL0_PD_RX_DATA0 (1 << 4)181#define HSIC_PAD_CTL0_PD_TX_STROBE (1 << 3)182#define HSIC_PAD_CTL0_PD_TX_DATA1 (1 << 2)183#define HSIC_PAD_CTL0_PD_TX_DATA0 (1 << 1)184#define HSIC_PAD_CTL0_IDDQ (1 << 0)185186#define XUSB_PADCTL_HSIC_PAD_CTL1(x) (0x304 + (x) * 0x20)187#define HSIC_PAD_CTL1_RTERM(x) (((x) & 0xF) << 12)188#define HSIC_PAD_CTL1_HSIC_OPT(x) (((x) & 0xF) << 8)189#define HSIC_PAD_CTL1_TX_SLEW(x) (((x) & 0xF) << 4)190#define HSIC_PAD_CTL1_TX_RTUNEP(x) (((x) & 0xF) << 0)191192#define XUSB_PADCTL_HSIC_PAD_CTL2(x) (0x308 + (x) * 0x20)193#define HSIC_PAD_CTL2_RX_STROBE_TRIM(x) (((x) & 0xF) << 8)194#define HSIC_PAD_CTL2_RX_DATA1_TRIM(x) (((x) & 0xF) << 4)195#define HSIC_PAD_CTL2_RX_DATA0_TRIM(x) (((x) & 0xF) << 0)196197#define XUSB_PADCTL_HSIC_PAD_TRK_CTL 0x340198#define HSIC_PAD_TRK_CTL_AUTO_RTERM_EN (1 << 24)199#define HSIC_PAD_TRK_CTL_FORCE_TRK_CLK_EN (1 << 23)200#define HSIC_PAD_TRK_CTL_TRK_SW_OVRD (1 << 22)201#define HSIC_PAD_TRK_CTL_TRK_DONE (1 << 21)202#define HSIC_PAD_TRK_CTL_TRK_START (1 << 20)203#define HSIC_PAD_TRK_CTL_PD_TRK (1 << 19)204#define HSIC_PAD_TRK_CTL_TRK_DONE_RESET_TIMER(x) (((x) & 0x3F) << 12)205#define HSIC_PAD_TRK_CTL_TRK_START_TIMER(x) (((x) & 0x7F) << 5)206#define HSIC_PAD_TRK_CTL_RTERM_OUT(x) (((x) & 0x1F) << 0)207208#define XUSB_PADCTL_HSIC_STRB_TRIM_CONTROL 0x344209210#define XUSB_PADCTL_UPHY_PLL_P0_CTL1 0x360211#define UPHY_PLL_P0_CTL1_PLL0_FREQ_PSDIV(x) (((x) & 0x03) << 28)212#define UPHY_PLL_P0_CTL1_PLL0_FREQ_NDIV(x) (((x) & 0xFF) << 20)213#define UPHY_PLL_P0_CTL1_PLL0_FREQ_MDIV(x) (((x) & 0x03) << 16)214#define UPHY_PLL_P0_CTL1_PLL0_LOCKDET_STATUS (1 << 15)215#define UPHY_PLL_P0_CTL1_PLL0_MODE_GET(x) (((x) >> 8) & 0x03)216#define UPHY_PLL_P0_CTL1_PLL0_BYPASS_EN (1 << 7)217#define UPHY_PLL_P0_CTL1_PLL0_FREERUN_EN (1 << 6)218#define UPHY_PLL_P0_CTL1_PLL0_PWR_OVRD (1 << 4)219#define UPHY_PLL_P0_CTL1_PLL0_ENABLE (1 << 3)220#define UPHY_PLL_P0_CTL1_PLL0_SLEEP(x) (((x) & 0x03) << 1)221#define UPHY_PLL_P0_CTL1_PLL0_IDDQ (1 << 0)222223#define XUSB_PADCTL_UPHY_PLL_P0_CTL2 0x364224#define UPHY_PLL_P0_CTL2_PLL0_CAL_CTRL(x) (((x) & 0xFFFFFF) << 4)225#define UPHY_PLL_P0_CTL2_PLL0_CAL_RESET (1 << 3)226#define UPHY_PLL_P0_CTL2_PLL0_CAL_OVRD (1 << 2)227#define UPHY_PLL_P0_CTL2_PLL0_CAL_DONE (1 << 1)228#define UPHY_PLL_P0_CTL2_PLL0_CAL_EN (1 << 0)229230#define XUSB_PADCTL_UPHY_PLL_P0_CTL4 0x36c231#define UPHY_PLL_P0_CTL4_PLL0_TCLKOUT_EN (1 << 28)232#define UPHY_PLL_P0_CTL4_PLL0_CLKDIST_CTRL(x) (((x) & 0xF) << 20)233#define UPHY_PLL_P0_CTL4_PLL0_XDIGCLK_EN (1 << 19)234#define UPHY_PLL_P0_CTL4_PLL0_XDIGCLK_SEL(x) (((x) & 0x7) << 16)235#define UPHY_PLL_P0_CTL4_PLL0_TXCLKREF_EN (1 << 15)236#define UPHY_PLL_P0_CTL4_PLL0_TXCLKREF_SEL(x) (((x) & 0x3) << 12)237#define UPHY_PLL_P0_CTL4_PLL0_FBCLKBUF_EN (1 << 9)238#define UPHY_PLL_P0_CTL4_PLL0_REFCLKBUF_EN (1 << 8)239#define UPHY_PLL_P0_CTL4_PLL0_REFCLK_SEL(x) (((x) & 0xF) << 4)240#define UPHY_PLL_P0_CTL4_PLL0_REFCLK_TERM100 (1 << 0)241242#define XUSB_PADCTL_UPHY_PLL_P0_CTL5 0x370243#define UPHY_PLL_P0_CTL5_PLL0_DCO_CTRL(x) (((x) & 0xFF) << 16)244#define UPHY_PLL_P0_CTL5_PLL0_LPF_CTRL(x) (((x) & 0xFF) << 8)245#define UPHY_PLL_P0_CTL5_PLL0_CP_CTRL(x) (((x) & 0x0F) << 4)246#define UPHY_PLL_P0_CTL5_PLL0_PFD_CTRL(x) (((x) & 0x03) << 0)247248#define XUSB_PADCTL_UPHY_PLL_P0_CTL8 0x37c249#define UPHY_PLL_P0_CTL8_PLL0_RCAL_DONE (1U << 31)250#define UPHY_PLL_P0_CTL8_PLL0_RCAL_VAL(x) (((x) & 0x1F) << 24)251#define UPHY_PLL_P0_CTL8_PLL0_RCAL_BYP_EN (1 << 23)252#define UPHY_PLL_P0_CTL8_PLL0_RCAL_BYP_CODE(x) (((x) & 0x1F) << 16)253#define UPHY_PLL_P0_CTL8_PLL0_RCAL_OVRD (1 << 15)254#define UPHY_PLL_P0_CTL8_PLL0_RCAL_CLK_EN (1 << 13)255#define UPHY_PLL_P0_CTL8_PLL0_RCAL_EN (1 << 12)256#define UPHY_PLL_P0_CTL8_PLL0_BGAP_CTRL(x) (((x) & 0xFFF) << 0)257258#define XUSB_PADCTL_UPHY_MISC_PAD_P_CTL1(x) (0x460 + (x) * 0x40)259#define XUSB_PADCTL_UPHY_PLL_S0_CTL1 0x860260#define UPHY_PLL_S0_CTL1_PLL0_FREQ_PSDIV(x) (((x) & 0x03) << 28)261#define UPHY_PLL_S0_CTL1_PLL0_FREQ_NDIV(x) (((x) & 0xFF) << 20)262#define UPHY_PLL_S0_CTL1_PLL0_FREQ_MDIV(x) (((x) & 0x03) << 16)263#define UPHY_PLL_S0_CTL1_PLL0_LOCKDET_STATUS (1 << 15)264#define UPHY_PLL_S0_CTL1_PLL0_MODE_GET(x) (((x) >> 8) & 0x03)265#define UPHY_PLL_S0_CTL1_PLL0_BYPASS_EN (1 << 7)266#define UPHY_PLL_S0_CTL1_PLL0_FREERUN_EN (1 << 6)267#define UPHY_PLL_S0_CTL1_PLL0_PWR_OVRD (1 << 4)268#define UPHY_PLL_S0_CTL1_PLL0_ENABLE (1 << 3)269#define UPHY_PLL_S0_CTL1_PLL0_SLEEP(x) (((x) & 0x03) << 1)270#define UPHY_PLL_S0_CTL1_PLL0_IDDQ (1 << 0)271272#define XUSB_PADCTL_UPHY_PLL_S0_CTL2 0x864273#define UPHY_PLL_S0_CTL2_PLL0_CAL_CTRL(x) (((x) & 0xFFFFFF) << 4)274#define UPHY_PLL_S0_CTL2_PLL0_CAL_RESET (1 << 3)275#define UPHY_PLL_S0_CTL2_PLL0_CAL_OVRD (1 << 2)276#define UPHY_PLL_S0_CTL2_PLL0_CAL_DONE (1 << 1)277#define UPHY_PLL_S0_CTL2_PLL0_CAL_EN (1 << 0)278279#define XUSB_PADCTL_UPHY_PLL_S0_CTL4 0x86c280#define UPHY_PLL_S0_CTL4_PLL0_TCLKOUT_EN (1 << 28)281#define UPHY_PLL_S0_CTL4_PLL0_CLKDIST_CTRL(x) (((x) & 0xF) << 20)282#define UPHY_PLL_S0_CTL4_PLL0_XDIGCLK_EN (1 << 19)283#define UPHY_PLL_S0_CTL4_PLL0_XDIGCLK_SEL(x) (((x) & 0x7) << 16)284#define UPHY_PLL_S0_CTL4_PLL0_TXCLKREF_EN (1 << 15)285#define UPHY_PLL_S0_CTL4_PLL0_TXCLKREF_SEL(x) (((x) & 0x3) << 12)286#define UPHY_PLL_S0_CTL4_PLL0_FBCLKBUF_EN (1 << 9)287#define UPHY_PLL_S0_CTL4_PLL0_REFCLKBUF_EN (1 << 8)288#define UPHY_PLL_S0_CTL4_PLL0_REFCLK_SEL(x) (((x) & 0xF) << 4)289#define UPHY_PLL_S0_CTL4_PLL0_REFCLK_TERM100 (1 << 0)290291#define XUSB_PADCTL_UPHY_PLL_S0_CTL5 0x870292#define UPHY_PLL_S0_CTL5_PLL0_DCO_CTRL(x) (((x) & 0xFF) << 16)293#define UPHY_PLL_S0_CTL5_PLL0_LPF_CTRL(x) (((x) & 0xFF) << 8)294#define UPHY_PLL_S0_CTL5_PLL0_CP_CTRL(x) (((x) & 0x0F) << 4)295#define UPHY_PLL_S0_CTL5_PLL0_PFD_CTRL(x) (((x) & 0x03) << 0)296297#define XUSB_PADCTL_UPHY_PLL_S0_CTL8 0x87c298#define UPHY_PLL_S0_CTL8_PLL0_RCAL_DONE (1U << 31)299#define UPHY_PLL_S0_CTL8_PLL0_RCAL_VAL(x) (((x) & 0x1F) << 24)300#define UPHY_PLL_S0_CTL8_PLL0_RCAL_BYP_EN (1 << 23)301#define UPHY_PLL_S0_CTL8_PLL0_RCAL_BYP_CODE(x) (((x) & 0x1F) << 16)302#define UPHY_PLL_S0_CTL8_PLL0_RCAL_OVRD (1 << 15)303#define UPHY_PLL_S0_CTL8_PLL0_RCAL_CLK_EN (1 << 13)304#define UPHY_PLL_S0_CTL8_PLL0_RCAL_EN (1 << 12)305#define UPHY_PLL_S0_CTL8_PLL0_BGAP_CTRL(x) (((x) & 0xFFF) << 0)306307#define XUSB_PADCTL_UPHY_MISC_PAD_S0_CTL1 0x960308#define XUSB_PADCTL_UPHY_USB3_PAD_ECTL1(x) (0xa60 + (x) * 0x40)309#define UPHY_USB3_PAD_ECTL1_TX_TERM_CTRL(x) (((x) & 0x3) << 16)310311#define XUSB_PADCTL_UPHY_USB3_PAD_ECTL2(x) (0xa64 + (x) * 0x40)312#define UPHY_USB3_PAD_ECTL2_RX_IQ_CTRL(x) (((x) & 0x000F) << 16)313#define UPHY_USB3_PAD_ECTL2_RX_CTLE(x) (((x) & 0xFFFF) << 0)314315#define XUSB_PADCTL_UPHY_USB3_PAD_ECTL3(x) (0xa68 + (x) * 0x40)316#define XUSB_PADCTL_UPHY_USB3_PAD_ECTL4(x) (0xa6c + (x) * 0x40)317#define UPHY_USB3_PAD_ECTL4_RX_CDR_CTRL(x) (((x) & 0xFFFF) << 16)318#define UPHY_USB3_PAD_ECTL4_RX_PI_CTRL(x) (((x) & 0x00FF) << 0)319320#define XUSB_PADCTL_UPHY_USB3_PAD_ECTL6(x) (0xa74 + (x) * 0x40)321322323#define WR4(_sc, _r, _v) bus_write_4((_sc)->mem_res, (_r), (_v))324#define RD4(_sc, _r) bus_read_4((_sc)->mem_res, (_r))325326327struct padctl_softc {328device_t dev;329struct resource *mem_res;330hwreset_t rst;331int phy_ena_cnt;332int pcie_ena_cnt;333int sata_ena_cnt;334335/* Fuses calibration data */336/* USB2 */337uint32_t hs_curr_level[4];338uint32_t hs_curr_level_offs; /* Not inited yet, always 0 */339uint32_t hs_term_range_adj;340uint32_t rpd_ctrl;341342/* HSIC */343uint32_t rx_strobe_trim; /* Not inited yet, always 0 */344uint32_t rx_data0_trim; /* Not inited yet, always 0 */345uint32_t rx_data1_trim; /* Not inited yet, always 0 */346uint32_t tx_rtune_p; /* Not inited yet, always 0 */347uint32_t strobe_trim; /* Not inited yet, always 0 */348};349350static struct ofw_compat_data compat_data[] = {351{"nvidia,tegra210-xusb-padctl", 1},352{NULL, 0},353};354355/* Ports. */356enum padctl_port_type {357PADCTL_PORT_USB2,358PADCTL_PORT_HSIC,359PADCTL_PORT_USB3,360};361362struct padctl_lane;363struct padctl_port {364enum padctl_port_type type;365const char *name;366const char *base_name;367int idx;368int (*init)(struct padctl_softc *sc,369struct padctl_port *port);370371/* Runtime data. */372phandle_t xref;373bool enabled;374bool internal;375uint32_t companion;376regulator_t supply_vbus;377struct padctl_lane *lane;378};379380static int usb3_port_init(struct padctl_softc *sc, struct padctl_port *port);381382#define PORT(t, n, p, i) { \383.type = t, \384.name = n "-" #p, \385.base_name = n, \386.idx = p, \387.init = i, \388}389static struct padctl_port ports_tbl[] = {390PORT(PADCTL_PORT_USB2, "usb2", 0, NULL),391PORT(PADCTL_PORT_USB2, "usb2", 1, NULL),392PORT(PADCTL_PORT_USB2, "usb2", 2, NULL),393PORT(PADCTL_PORT_USB2, "usb2", 3, NULL),394PORT(PADCTL_PORT_HSIC, "hsic", 0, NULL),395PORT(PADCTL_PORT_HSIC, "hsic", 1, NULL),396PORT(PADCTL_PORT_USB3, "usb3", 0, usb3_port_init),397PORT(PADCTL_PORT_USB3, "usb3", 1, usb3_port_init),398};399400/* Pads - a group of lannes. */401enum padctl_pad_type {402PADCTL_PAD_USB2,403PADCTL_PAD_HSIC,404PADCTL_PAD_PCIE,405PADCTL_PAD_SATA,406};407408struct padctl_lane;409struct padctl_pad {410const char *name;411enum padctl_pad_type type;412const char *clock_name;413char *reset_name; /* XXX constify !!!!!! */414int (*enable)(struct padctl_softc *sc,415struct padctl_lane *lane);416int (*disable)(struct padctl_softc *sc,417struct padctl_lane *lane);418/* Runtime data. */419bool enabled;420clk_t clk;421hwreset_t reset;422int nlanes;423struct padctl_lane *lanes[8]; /* Safe maximum value. */424};425426static int usb2_enable(struct padctl_softc *sc, struct padctl_lane *lane);427static int usb2_disable(struct padctl_softc *sc, struct padctl_lane *lane);428static int hsic_enable(struct padctl_softc *sc, struct padctl_lane *lane);429static int hsic_disable(struct padctl_softc *sc, struct padctl_lane *lane);430static int pcie_enable(struct padctl_softc *sc, struct padctl_lane *lane);431static int pcie_disable(struct padctl_softc *sc, struct padctl_lane *lane);432static int sata_enable(struct padctl_softc *sc, struct padctl_lane *lane);433static int sata_disable(struct padctl_softc *sc, struct padctl_lane *lane);434435#define PAD(n, t, cn, rn, e, d) { \436.name = n, \437.type = t, \438.clock_name = cn, \439.reset_name = rn, \440.enable = e, \441.disable = d, \442}443static struct padctl_pad pads_tbl[] = {444PAD("usb2", PADCTL_PAD_USB2, "trk", NULL, usb2_enable, usb2_disable),445PAD("hsic", PADCTL_PAD_HSIC, "trk", NULL, hsic_enable, hsic_disable),446PAD("pcie", PADCTL_PAD_PCIE, "pll", "phy", pcie_enable, pcie_disable),447PAD("sata", PADCTL_PAD_SATA, "pll", "phy", sata_enable, sata_disable),448};449450/* Lanes. */451static char *usb_mux[] = {"snps", "xusb", "uart", "rsvd"};452static char *hsic_mux[] = {"snps", "xusb"};453static char *pci_mux[] = {"pcie-x1", "usb3-ss", "sata", "pcie-x4"};454455struct padctl_lane {456const char *name;457int idx;458bus_size_t reg;459uint32_t shift;460uint32_t mask;461char **mux;462int nmux;463/* Runtime data. */464bool enabled;465phandle_t xref;466struct padctl_pad *pad;467struct padctl_port *port;468int mux_idx;469470};471472#define LANE(n, p, r, s, m, mx) { \473.name = n "-" #p, \474.idx = p, \475.reg = r, \476.shift = s, \477.mask = m, \478.mux = mx, \479.nmux = nitems(mx), \480}481static struct padctl_lane lanes_tbl[] = {482LANE("usb2", 0, XUSB_PADCTL_USB2_PAD_MUX, 0, 0x3, usb_mux),483LANE("usb2", 1, XUSB_PADCTL_USB2_PAD_MUX, 2, 0x3, usb_mux),484LANE("usb2", 2, XUSB_PADCTL_USB2_PAD_MUX, 4, 0x3, usb_mux),485LANE("usb2", 3, XUSB_PADCTL_USB2_PAD_MUX, 6, 0x3, usb_mux),486LANE("hsic", 0, XUSB_PADCTL_USB2_PAD_MUX, 14, 0x1, hsic_mux),487LANE("hsic", 1, XUSB_PADCTL_USB2_PAD_MUX, 15, 0x1, hsic_mux),488LANE("pcie", 0, XUSB_PADCTL_USB3_PAD_MUX, 12, 0x3, pci_mux),489LANE("pcie", 1, XUSB_PADCTL_USB3_PAD_MUX, 14, 0x3, pci_mux),490LANE("pcie", 2, XUSB_PADCTL_USB3_PAD_MUX, 16, 0x3, pci_mux),491LANE("pcie", 3, XUSB_PADCTL_USB3_PAD_MUX, 18, 0x3, pci_mux),492LANE("pcie", 4, XUSB_PADCTL_USB3_PAD_MUX, 20, 0x3, pci_mux),493LANE("pcie", 5, XUSB_PADCTL_USB3_PAD_MUX, 22, 0x3, pci_mux),494LANE("pcie", 6, XUSB_PADCTL_USB3_PAD_MUX, 24, 0x3, pci_mux),495LANE("sata", 0, XUSB_PADCTL_USB3_PAD_MUX, 30, 0x3, pci_mux),496};497498/* Define all possible mappings for USB3 port lanes */499struct padctl_lane_map {500int port_idx;501enum padctl_pad_type pad_type;502int lane_idx;503};504505#define LANE_MAP(pi, pt, li) { \506.port_idx = pi, \507.pad_type = pt, \508.lane_idx = li, \509}510static struct padctl_lane_map lane_map_tbl[] = {511LANE_MAP(0, PADCTL_PAD_PCIE, 6), /* port USB3-0 -> lane PCIE-0 */512LANE_MAP(1, PADCTL_PAD_PCIE, 5), /* port USB3-1 -> lane PCIE-1 */513LANE_MAP(2, PADCTL_PAD_PCIE, 0), /* port USB3-2 -> lane PCIE-0 */514LANE_MAP(2, PADCTL_PAD_PCIE, 2), /* port USB3-2 -> lane PCIE-2 */515LANE_MAP(3, PADCTL_PAD_PCIE, 4), /* port USB3-3 -> lane PCIE-4 */516};517518/* Phy class and methods. */519static int xusbpadctl_phy_enable(struct phynode *phy, bool enable);520static phynode_method_t xusbpadctl_phynode_methods[] = {521PHYNODEMETHOD(phynode_enable, xusbpadctl_phy_enable),522PHYNODEMETHOD_END523524};525DEFINE_CLASS_1(xusbpadctl_phynode, xusbpadctl_phynode_class,526xusbpadctl_phynode_methods, 0, phynode_class);527528static struct padctl_port *search_lane_port(struct padctl_softc *sc,529struct padctl_lane *lane);530531532static void tegra210_xusb_pll_hw_control_enable(void) {}533static void tegra210_xusb_pll_hw_sequence_start(void) {}534static void tegra210_sata_pll_hw_control_enable(void) {}535static void tegra210_sata_pll_hw_sequence_start(void) {}536537/* -------------------------------------------------------------------------538*539* PEX functions540*/541static int542uphy_pex_enable(struct padctl_softc *sc, struct padctl_pad *pad)543{544uint32_t reg;545int rv, i;546547if (sc->pcie_ena_cnt > 0) {548sc->pcie_ena_cnt++;549return (0);550}551552/* 22.8.4 UPHY PLLs, Step 4, page 1346 */553/* 1. Deassert PLL/Lane resets. */554rv = clk_enable(pad->clk);555if (rv < 0) {556device_printf(sc->dev, "Cannot enable clock for pad '%s': %d\n",557pad->name, rv);558return (rv);559}560561rv = hwreset_deassert(pad->reset);562if (rv < 0) {563device_printf(sc->dev, "Cannot unreset pad '%s': %d\n",564pad->name, rv);565clk_disable(pad->clk);566return (rv);567}568569reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL2);570reg &= ~UPHY_PLL_P0_CTL2_PLL0_CAL_CTRL(~0);571reg |= UPHY_PLL_P0_CTL2_PLL0_CAL_CTRL(0x136);572WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL2, reg);573574reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL5);575reg &= ~UPHY_PLL_P0_CTL5_PLL0_DCO_CTRL(~0);576reg |= UPHY_PLL_P0_CTL5_PLL0_DCO_CTRL(0x2a);577WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL5, reg);578579reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL1);580reg |= UPHY_PLL_P0_CTL1_PLL0_PWR_OVRD;581WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL1, reg);582583reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL2);584reg |= UPHY_PLL_P0_CTL2_PLL0_CAL_OVRD;585WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL2, reg);586587reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL8);588reg |= UPHY_PLL_P0_CTL8_PLL0_RCAL_OVRD;589WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL8, reg);590591/*592* 2. For the following registers, default values593* take care of the desired frequency.594*/595reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL4);596reg &= ~UPHY_PLL_P0_CTL4_PLL0_TXCLKREF_SEL(~0);597reg &= ~UPHY_PLL_P0_CTL4_PLL0_REFCLK_SEL(~0);598reg |= UPHY_PLL_P0_CTL4_PLL0_TXCLKREF_SEL(0x2);599reg |= UPHY_PLL_P0_CTL4_PLL0_TXCLKREF_EN;600WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL4, reg);601602reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL1);603reg &= ~UPHY_PLL_P0_CTL1_PLL0_FREQ_MDIV(~0);604reg &= ~UPHY_PLL_P0_CTL1_PLL0_FREQ_NDIV(~0);605reg |= UPHY_PLL_P0_CTL1_PLL0_FREQ_NDIV(0x19);606WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL1, reg);607608reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL1);609reg &= ~UPHY_PLL_P0_CTL1_PLL0_IDDQ;610WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL1, reg);611612reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL1);613reg &= ~UPHY_PLL_P0_CTL1_PLL0_SLEEP(~0);614WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL1, reg);615616/* 3. Wait 100 ns. */617DELAY(10);618619/* XXX This in not in TRM */620reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL4);621reg |= UPHY_PLL_P0_CTL4_PLL0_REFCLKBUF_EN;622WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL4, reg);623624/* 4. Calibration. */625reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL2);626reg |= UPHY_PLL_P0_CTL2_PLL0_CAL_EN;627WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL2, reg);628for (i = 30; i > 0; i--) {629reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL2);630if (reg & UPHY_PLL_P0_CTL2_PLL0_CAL_DONE)631break;632DELAY(10);633}634if (i <= 0) {635device_printf(sc->dev, "Timedout in calibration step 1 "636"for pad '%s' (0x%08X).\n", pad->name, reg);637rv = ETIMEDOUT;638goto err;639}640641reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL2);642reg &= ~UPHY_PLL_P0_CTL2_PLL0_CAL_EN;643WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL2, reg);644for (i = 10; i > 0; i--) {645reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL2);646if ((reg & UPHY_PLL_P0_CTL2_PLL0_CAL_DONE) == 0)647break;648DELAY(10);649}650if (i <= 0) {651device_printf(sc->dev, "Timedout in calibration step 2 "652"for pad '%s'.\n", pad->name);653rv = ETIMEDOUT;654goto err;655}656657/* 5. Enable the PLL (20 μs Lock time) */658reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL1);659reg |= UPHY_PLL_P0_CTL1_PLL0_ENABLE;660WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL1, reg);661for (i = 10; i > 0; i--) {662reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL1);663if (reg & UPHY_PLL_P0_CTL1_PLL0_LOCKDET_STATUS)664break;665DELAY(10);666}667if (i <= 0) {668device_printf(sc->dev, "Timedout while enabling PLL "669"for pad '%s'.\n", pad->name);670rv = ETIMEDOUT;671goto err;672}673674/* 6. RCAL. */675reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL8);676reg |= UPHY_PLL_P0_CTL8_PLL0_RCAL_EN;677reg |= UPHY_PLL_P0_CTL8_PLL0_RCAL_CLK_EN;678WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL8, reg);679680for (i = 10; i > 0; i--) {681reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL8);682if (reg & UPHY_PLL_P0_CTL8_PLL0_RCAL_DONE)683break;684DELAY(10);685}686if (i <= 0) {687device_printf(sc->dev, "Timedout in RX calibration step 1 "688"for pad '%s'.\n", pad->name);689rv = ETIMEDOUT;690goto err;691}692693reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL8);694reg &= ~UPHY_PLL_P0_CTL8_PLL0_RCAL_EN;695WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL8, reg);696697for (i = 10; i > 0; i--) {698reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL8);699if (!(reg & UPHY_PLL_P0_CTL8_PLL0_RCAL_DONE))700break;701702DELAY(10);703}704if (i <= 0) {705device_printf(sc->dev, "Timedout in RX calibration step 2 "706"for pad '%s'.\n", pad->name);707rv = ETIMEDOUT;708goto err;709}710711reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL8);712reg &= ~UPHY_PLL_P0_CTL8_PLL0_RCAL_CLK_EN;713WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL8, reg);714715/* Enable Hardware Power Sequencer. */716tegra210_xusb_pll_hw_control_enable();717718reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL1);719reg &= ~UPHY_PLL_P0_CTL1_PLL0_PWR_OVRD;720WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL1, reg);721722reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL2);723reg &= ~UPHY_PLL_P0_CTL2_PLL0_CAL_OVRD;724WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL2, reg);725726reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL8);727reg &= ~UPHY_PLL_P0_CTL8_PLL0_RCAL_OVRD;728WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL8, reg);729730DELAY(50);731732tegra210_xusb_pll_hw_sequence_start();733734sc->pcie_ena_cnt++;735736return (0);737738err:739hwreset_deassert(pad->reset);740clk_disable(pad->clk);741return (rv);742}743744static void745uphy_pex_disable(struct padctl_softc *sc, struct padctl_pad *pad)746{747int rv;748749sc->pcie_ena_cnt--;750if (sc->pcie_ena_cnt <= 0) {751rv = hwreset_assert(pad->reset);752if (rv != 0) {753device_printf(sc->dev, "Cannot reset pad '%s': %d\n",754pad->name, rv);755}756rv = clk_disable(pad->clk);757if (rv != 0) {758device_printf(sc->dev,759"Cannot dicable clock for pad '%s': %d\n",760pad->name, rv);761}762}763}764765static int766uphy_sata_enable(struct padctl_softc *sc, struct padctl_pad *pad, bool usb)767{768uint32_t reg;769int rv, i;770771/* 22.8.4 UPHY PLLs, Step 4, page 1346 */772/* 1. Deassert PLL/Lane resets. */773if (sc->sata_ena_cnt > 0) {774sc->sata_ena_cnt++;775return (0);776}777778rv = clk_enable(pad->clk);779if (rv < 0) {780device_printf(sc->dev, "Cannot enable clock for pad '%s': %d\n",781pad->name, rv);782return (rv);783}784785rv = hwreset_deassert(pad->reset);786if (rv < 0) {787device_printf(sc->dev, "Cannot unreset pad '%s': %d\n",788pad->name, rv);789clk_disable(pad->clk);790return (rv);791}792reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL2);793reg &= ~UPHY_PLL_P0_CTL2_PLL0_CAL_CTRL(~0);794reg |= UPHY_PLL_P0_CTL2_PLL0_CAL_CTRL(0x136);795WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL2, reg);796797reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL5);798reg &= ~UPHY_PLL_P0_CTL5_PLL0_DCO_CTRL(~0);799reg |= UPHY_PLL_P0_CTL5_PLL0_DCO_CTRL(0x2a);800WR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL5, reg);801802reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL1);803reg |= UPHY_PLL_S0_CTL1_PLL0_PWR_OVRD;804WR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL1, reg);805806reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL2);807reg |= UPHY_PLL_S0_CTL2_PLL0_CAL_OVRD;808WR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL2, reg);809810reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL8);811reg |= UPHY_PLL_S0_CTL8_PLL0_RCAL_OVRD;812WR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL8, reg);813814/*815* 2. For the following registers, default values816* take care of the desired frequency.817*/818reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL4);819reg &= ~UPHY_PLL_S0_CTL4_PLL0_TXCLKREF_SEL(~0);820reg &= ~UPHY_PLL_S0_CTL4_PLL0_REFCLK_SEL(~0);821reg |= UPHY_PLL_S0_CTL4_PLL0_TXCLKREF_EN;822823if (usb)824reg |= UPHY_PLL_S0_CTL4_PLL0_TXCLKREF_SEL(0x2);825else826reg |= UPHY_PLL_S0_CTL4_PLL0_TXCLKREF_SEL(0x0);827828/* XXX PLL0_XDIGCLK_EN */829/*830value &= ~(1 << 19);831WR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL4, reg);832*/833834reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL1);835reg &= ~UPHY_PLL_S0_CTL1_PLL0_FREQ_MDIV(~0);836reg &= ~UPHY_PLL_S0_CTL1_PLL0_FREQ_NDIV(~0);837if (usb)838reg |= UPHY_PLL_S0_CTL1_PLL0_FREQ_NDIV(0x19);839else840reg |= UPHY_PLL_S0_CTL1_PLL0_FREQ_NDIV(0x1e);841WR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL1, reg);842843reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL1);844reg &= ~UPHY_PLL_S0_CTL1_PLL0_IDDQ;845WR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL1, reg);846847reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL1);848reg &= ~UPHY_PLL_S0_CTL1_PLL0_SLEEP(~0);849WR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL1, reg);850851/* 3. Wait 100 ns. */852DELAY(1);853854/* XXX This in not in TRM */855reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL4);856reg |= UPHY_PLL_S0_CTL4_PLL0_REFCLKBUF_EN;857WR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL4, reg);858859/* 4. Calibration. */860reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL2);861reg |= UPHY_PLL_S0_CTL2_PLL0_CAL_EN;862WR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL2, reg);863for (i = 30; i > 0; i--) {864reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL2);865if (reg & UPHY_PLL_S0_CTL2_PLL0_CAL_DONE)866break;867DELAY(10);868}869if (i <= 0) {870device_printf(sc->dev, "Timedout in calibration step 1 "871"for pad '%s'.\n", pad->name);872rv = ETIMEDOUT;873goto err;874}875876reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL2);877reg &= ~UPHY_PLL_S0_CTL2_PLL0_CAL_EN;878WR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL2, reg);879for (i = 10; i > 0; i--) {880reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL2);881if ((reg & UPHY_PLL_S0_CTL2_PLL0_CAL_DONE) == 0)882break;883DELAY(10);884}885if (i <= 0) {886device_printf(sc->dev, "Timedout in calibration step 2 "887"for pad '%s'.\n", pad->name);888rv = ETIMEDOUT;889goto err;890}891892/* 5. Enable the PLL (20 μs Lock time) */893reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL1);894reg |= UPHY_PLL_S0_CTL1_PLL0_ENABLE;895WR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL1, reg);896for (i = 10; i > 0; i--) {897reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL1);898if (reg & UPHY_PLL_S0_CTL1_PLL0_LOCKDET_STATUS)899break;900DELAY(10);901}902if (i <= 0) {903device_printf(sc->dev, "Timedout while enabling PLL "904"for pad '%s'.\n", pad->name);905rv = ETIMEDOUT;906goto err;907}908909/* 6. RCAL. */910reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL8);911reg |= UPHY_PLL_S0_CTL8_PLL0_RCAL_EN;912reg |= UPHY_PLL_S0_CTL8_PLL0_RCAL_CLK_EN;913WR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL8, reg);914for (i = 10; i > 0; i--) {915reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL8);916if (reg & UPHY_PLL_S0_CTL8_PLL0_RCAL_DONE)917break;918DELAY(10);919}920if (i <= 0) {921device_printf(sc->dev, "Timedout in RX calibration step 1 "922"for pad '%s'.\n", pad->name);923rv = ETIMEDOUT;924goto err;925}926927reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL8);928reg &= ~UPHY_PLL_S0_CTL8_PLL0_RCAL_EN;929WR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL8, reg);930for (i = 10; i > 0; i--) {931reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL8);932if (!(reg & UPHY_PLL_S0_CTL8_PLL0_RCAL_DONE))933break;934DELAY(10);935}936if (i <= 0) {937device_printf(sc->dev, "Timedout in RX calibration step 2 "938"for pad '%s'.\n", pad->name);939rv = ETIMEDOUT;940goto err;941}942943reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL8);944reg &= ~UPHY_PLL_S0_CTL8_PLL0_RCAL_CLK_EN;945WR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL8, reg);946947/* Enable Hardware Power Sequencer. */948tegra210_sata_pll_hw_control_enable();949950reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL1);951reg &= ~UPHY_PLL_S0_CTL1_PLL0_PWR_OVRD;952WR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL1, reg);953954reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL2);955reg &= ~UPHY_PLL_S0_CTL2_PLL0_CAL_OVRD;956WR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL2, reg);957958reg = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL8);959reg &= ~UPHY_PLL_S0_CTL8_PLL0_RCAL_OVRD;960WR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL8, reg);961962DELAY(50);963964tegra210_sata_pll_hw_sequence_start();965966sc->sata_ena_cnt++;967968return (0);969970err:971hwreset_deassert(pad->reset);972clk_disable(pad->clk);973return (rv);974}975976static void977uphy_sata_disable(struct padctl_softc *sc, struct padctl_pad *pad)978{979int rv;980981sc->sata_ena_cnt--;982if (sc->sata_ena_cnt <= 0) {983rv = hwreset_assert(pad->reset);984if (rv != 0) {985device_printf(sc->dev, "Cannot reset pad '%s': %d\n",986pad->name, rv);987}988rv = clk_disable(pad->clk);989if (rv != 0) {990device_printf(sc->dev,991"Cannot dicable clock for pad '%s': %d\n",992pad->name, rv);993}994}995}996997998static int999usb3_port_init(struct padctl_softc *sc, struct padctl_port *port)1000{1001uint32_t reg;1002struct padctl_pad *pad;1003int rv;10041005pad = port->lane->pad;1006reg = RD4(sc, XUSB_PADCTL_SS_PORT_MAP);1007if (port->internal)1008reg &= ~SS_PORT_MAP_PORT_INTERNAL(port->idx);1009else1010reg |= SS_PORT_MAP_PORT_INTERNAL(port->idx);1011reg &= ~SS_PORT_MAP_PORT_MAP(port->idx, ~0);1012reg |= SS_PORT_MAP_PORT_MAP(port->idx, port->companion);1013WR4(sc, XUSB_PADCTL_SS_PORT_MAP, reg);10141015if (port->supply_vbus != NULL) {1016rv = regulator_enable(port->supply_vbus);1017if (rv != 0) {1018device_printf(sc->dev,1019"Cannot enable vbus regulator\n");1020return (rv);1021}1022}10231024reg = RD4(sc, XUSB_PADCTL_UPHY_USB3_PAD_ECTL1(port->idx));1025reg &= ~UPHY_USB3_PAD_ECTL1_TX_TERM_CTRL(~0);1026reg |= UPHY_USB3_PAD_ECTL1_TX_TERM_CTRL(2);1027WR4(sc, XUSB_PADCTL_UPHY_USB3_PAD_ECTL1(port->idx), reg);10281029reg = RD4(sc, XUSB_PADCTL_UPHY_USB3_PAD_ECTL2(port->idx));1030reg &= ~UPHY_USB3_PAD_ECTL2_RX_CTLE(~0);1031reg |= UPHY_USB3_PAD_ECTL2_RX_CTLE(0x00fc);1032WR4(sc, XUSB_PADCTL_UPHY_USB3_PAD_ECTL2(port->idx), reg);10331034WR4(sc, XUSB_PADCTL_UPHY_USB3_PAD_ECTL3(port->idx), 0xc0077f1f);10351036reg = RD4(sc, XUSB_PADCTL_UPHY_USB3_PAD_ECTL4(port->idx));1037reg &= ~UPHY_USB3_PAD_ECTL4_RX_CDR_CTRL(~0);1038reg |= UPHY_USB3_PAD_ECTL4_RX_CDR_CTRL(0x01c7);1039WR4(sc, XUSB_PADCTL_UPHY_USB3_PAD_ECTL4(port->idx), reg);10401041WR4(sc, XUSB_PADCTL_UPHY_USB3_PAD_ECTL6(port->idx), 0xfcf01368);10421043if (pad->type == PADCTL_PAD_SATA)1044rv = uphy_sata_enable(sc, pad, true);1045else1046rv = uphy_pex_enable(sc, pad);1047if (rv != 0)1048return (rv);10491050reg = RD4(sc, XUSB_PADCTL_ELPG_PROGRAM1);1051reg &= ~ELPG_PROGRAM1_SSP_ELPG_VCORE_DOWN(port->idx);1052WR4(sc, XUSB_PADCTL_ELPG_PROGRAM1, reg);1053DELAY(100);10541055reg = RD4(sc, XUSB_PADCTL_ELPG_PROGRAM1);1056reg &= ~ELPG_PROGRAM1_SSP_ELPG_CLAMP_EN_EARLY(port->idx);1057WR4(sc, XUSB_PADCTL_ELPG_PROGRAM1, reg);1058DELAY(100);10591060reg = RD4(sc, XUSB_PADCTL_ELPG_PROGRAM1);1061reg &= ~ELPG_PROGRAM1_SSP_ELPG_CLAMP_EN(port->idx);1062WR4(sc, XUSB_PADCTL_ELPG_PROGRAM1, reg);1063DELAY(100);10641065return (0);1066}10671068static int1069pcie_enable(struct padctl_softc *sc, struct padctl_lane *lane)1070{1071uint32_t reg;1072int rv;10731074rv = uphy_pex_enable(sc, lane->pad);1075if (rv != 0)1076return (rv);10771078reg = RD4(sc, XUSB_PADCTL_USB3_PAD_MUX);1079reg |= USB3_PAD_MUX_PCIE_IDDQ_DISABLE(lane->idx);1080WR4(sc, XUSB_PADCTL_USB3_PAD_MUX, reg);10811082return (0);1083}10841085static int1086pcie_disable(struct padctl_softc *sc, struct padctl_lane *lane)1087{1088uint32_t reg;10891090reg = RD4(sc, XUSB_PADCTL_USB3_PAD_MUX);1091reg &= ~USB3_PAD_MUX_PCIE_IDDQ_DISABLE(lane->idx);1092WR4(sc, XUSB_PADCTL_USB3_PAD_MUX, reg);10931094uphy_pex_disable(sc, lane->pad);10951096return (0);10971098}10991100static int1101sata_enable(struct padctl_softc *sc, struct padctl_lane *lane)1102{1103uint32_t reg;1104int rv;11051106rv = uphy_sata_enable(sc, lane->pad, false);1107if (rv != 0)1108return (rv);11091110reg = RD4(sc, XUSB_PADCTL_USB3_PAD_MUX);1111reg |= USB3_PAD_MUX_SATA_IDDQ_DISABLE(lane->idx);1112WR4(sc, XUSB_PADCTL_USB3_PAD_MUX, reg);11131114return (0);1115}11161117static int1118sata_disable(struct padctl_softc *sc, struct padctl_lane *lane)1119{1120uint32_t reg;11211122reg = RD4(sc, XUSB_PADCTL_USB3_PAD_MUX);1123reg &= ~USB3_PAD_MUX_SATA_IDDQ_DISABLE(lane->idx);1124WR4(sc, XUSB_PADCTL_USB3_PAD_MUX, reg);11251126uphy_sata_disable(sc, lane->pad);11271128return (0);1129}11301131static int1132hsic_enable(struct padctl_softc *sc, struct padctl_lane *lane)1133{1134uint32_t reg;1135struct padctl_pad *pad;1136struct padctl_port *port;1137int rv;11381139port = search_lane_port(sc, lane);1140if (port == NULL) {1141device_printf(sc->dev, "Cannot find port for lane: %s\n",1142lane->name);1143}1144pad = lane->pad;11451146if (port->supply_vbus != NULL) {1147rv = regulator_enable(port->supply_vbus);1148if (rv != 0) {1149device_printf(sc->dev,1150"Cannot enable vbus regulator\n");1151return (rv);1152}1153}11541155WR4(sc, XUSB_PADCTL_HSIC_STRB_TRIM_CONTROL, sc->strobe_trim);11561157reg = RD4(sc, XUSB_PADCTL_HSIC_PAD_CTL1(lane->idx));1158reg &= ~HSIC_PAD_CTL1_TX_RTUNEP(~0);1159reg |= HSIC_PAD_CTL1_TX_RTUNEP(sc->tx_rtune_p);1160WR4(sc, XUSB_PADCTL_HSIC_PAD_CTL1(lane->idx), reg);11611162reg = RD4(sc, XUSB_PADCTL_HSIC_PAD_CTL2(lane->idx));1163reg &= ~HSIC_PAD_CTL2_RX_STROBE_TRIM(~0);1164reg &= ~HSIC_PAD_CTL2_RX_DATA1_TRIM(~0);1165reg &= ~HSIC_PAD_CTL2_RX_DATA0_TRIM(~0);1166reg |= HSIC_PAD_CTL2_RX_STROBE_TRIM(sc->rx_strobe_trim);1167reg |= HSIC_PAD_CTL2_RX_DATA1_TRIM(sc->rx_data1_trim);1168reg |= HSIC_PAD_CTL2_RX_DATA0_TRIM(sc->rx_data0_trim);1169WR4(sc, XUSB_PADCTL_HSIC_PAD_CTL2(lane->idx), reg);11701171reg = RD4(sc, XUSB_PADCTL_HSIC_PAD_CTL0(lane->idx));1172reg &= ~HSIC_PAD_CTL0_RPU_DATA0;1173reg &= ~HSIC_PAD_CTL0_RPU_DATA1;1174reg &= ~HSIC_PAD_CTL0_RPU_STROBE;1175reg &= ~HSIC_PAD_CTL0_PD_RX_DATA0;1176reg &= ~HSIC_PAD_CTL0_PD_RX_DATA1;1177reg &= ~HSIC_PAD_CTL0_PD_RX_STROBE;1178reg &= ~HSIC_PAD_CTL0_PD_ZI_DATA0;1179reg &= ~HSIC_PAD_CTL0_PD_ZI_DATA1;1180reg &= ~HSIC_PAD_CTL0_PD_ZI_STROBE;1181reg &= ~HSIC_PAD_CTL0_PD_TX_DATA0;1182reg &= ~HSIC_PAD_CTL0_PD_TX_DATA1;1183reg &= ~HSIC_PAD_CTL0_PD_TX_STROBE;1184reg |= HSIC_PAD_CTL0_RPD_DATA0;1185reg |= HSIC_PAD_CTL0_RPD_DATA1;1186reg |= HSIC_PAD_CTL0_RPD_STROBE;1187WR4(sc, XUSB_PADCTL_HSIC_PAD_CTL0(lane->idx), reg);11881189rv = clk_enable(pad->clk);1190if (rv < 0) {1191device_printf(sc->dev, "Cannot enable clock for pad '%s': %d\n",1192pad->name, rv);1193if (port->supply_vbus != NULL)1194regulator_disable(port->supply_vbus);1195return (rv);1196}11971198reg = RD4(sc, XUSB_PADCTL_HSIC_PAD_TRK_CTL);1199reg &= ~HSIC_PAD_TRK_CTL_TRK_START_TIMER(~0);1200reg &= ~HSIC_PAD_TRK_CTL_TRK_DONE_RESET_TIMER(~0);1201reg |= HSIC_PAD_TRK_CTL_TRK_START_TIMER(0x1e);1202reg |= HSIC_PAD_TRK_CTL_TRK_DONE_RESET_TIMER(0x0a);1203WR4(sc, XUSB_PADCTL_HSIC_PAD_TRK_CTL, reg);12041205DELAY(10);12061207reg = RD4(sc, XUSB_PADCTL_HSIC_PAD_TRK_CTL);1208reg &= ~HSIC_PAD_TRK_CTL_PD_TRK;1209WR4(sc, XUSB_PADCTL_HSIC_PAD_TRK_CTL, reg);12101211DELAY(50);1212clk_disable(pad->clk);1213return (0);1214}12151216static int1217hsic_disable(struct padctl_softc *sc, struct padctl_lane *lane)1218{1219uint32_t reg;1220struct padctl_port *port;1221int rv;12221223port = search_lane_port(sc, lane);1224if (port == NULL) {1225device_printf(sc->dev, "Cannot find port for lane: %s\n",1226lane->name);1227}12281229reg = RD4(sc, XUSB_PADCTL_HSIC_PAD_CTL0(lane->idx));1230reg |= HSIC_PAD_CTL0_PD_RX_DATA0;1231reg |= HSIC_PAD_CTL0_PD_RX_DATA1;1232reg |= HSIC_PAD_CTL0_PD_RX_STROBE;1233reg |= HSIC_PAD_CTL0_PD_ZI_DATA0;1234reg |= HSIC_PAD_CTL0_PD_ZI_DATA1;1235reg |= HSIC_PAD_CTL0_PD_ZI_STROBE;1236reg |= HSIC_PAD_CTL0_PD_TX_DATA0;1237reg |= HSIC_PAD_CTL0_PD_TX_DATA1;1238reg |= HSIC_PAD_CTL0_PD_TX_STROBE;1239WR4(sc, XUSB_PADCTL_HSIC_PAD_CTL1(lane->idx), reg);12401241if (port->supply_vbus != NULL) {1242rv = regulator_disable(port->supply_vbus);1243if (rv != 0) {1244device_printf(sc->dev,1245"Cannot disable vbus regulator\n");1246return (rv);1247}1248}12491250return (0);1251}12521253static int1254usb2_enable(struct padctl_softc *sc, struct padctl_lane *lane)1255{1256uint32_t reg;1257struct padctl_pad *pad;1258struct padctl_port *port;1259int rv;12601261port = search_lane_port(sc, lane);1262if (port == NULL) {1263device_printf(sc->dev, "Cannot find port for lane: %s\n",1264lane->name);1265}1266pad = lane->pad;12671268reg = RD4(sc, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);1269reg &= ~USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL(~0);1270reg &= ~USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL(~0);1271reg |= USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL(0x7);1272WR4(sc, XUSB_PADCTL_USB2_BIAS_PAD_CTL0, reg);12731274reg = RD4(sc, XUSB_PADCTL_USB2_PORT_CAP);1275reg &= ~USB2_PORT_CAP_PORT_CAP(lane->idx, ~0);1276reg |= USB2_PORT_CAP_PORT_CAP(lane->idx, USB2_PORT_CAP_PORT_CAP_HOST);1277WR4(sc, XUSB_PADCTL_USB2_PORT_CAP, reg);12781279reg = RD4(sc, XUSB_PADCTL_USB2_OTG_PAD_CTL0(lane->idx));1280reg &= ~USB2_OTG_PAD_CTL0_HS_CURR_LEVEL(~0);1281reg &= ~USB2_OTG_PAD_CTL0_HS_SLEW(~0);1282reg &= ~USB2_OTG_PAD_CTL0_PD;1283reg &= ~USB2_OTG_PAD_CTL0_PD2;1284reg &= ~USB2_OTG_PAD_CTL0_PD_ZI;1285reg |= USB2_OTG_PAD_CTL0_HS_SLEW(14);1286reg |= USB2_OTG_PAD_CTL0_HS_CURR_LEVEL(sc->hs_curr_level[lane->idx] +1287sc->hs_curr_level_offs);1288WR4(sc, XUSB_PADCTL_USB2_OTG_PAD_CTL0(lane->idx), reg);12891290reg = RD4(sc, XUSB_PADCTL_USB2_OTG_PAD_CTL1(lane->idx));1291reg &= ~USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ(~0);1292reg &= ~USB2_OTG_PAD_CTL1_RPD_CTRL(~0);1293reg &= ~USB2_OTG_PAD_CTL1_PD_DR;1294reg &= ~USB2_OTG_PAD_CTL1_PD_CHRP_OVRD;1295reg &= ~USB2_OTG_PAD_CTL1_PD_DISC_OVRD;1296reg |= USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ(sc->hs_term_range_adj);1297reg |= USB2_OTG_PAD_CTL1_RPD_CTRL(sc->rpd_ctrl);1298WR4(sc, XUSB_PADCTL_USB2_OTG_PAD_CTL1(lane->idx), reg);12991300reg = RD4(sc, XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1(lane->idx));1301reg &= ~USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_LEV(~0);1302reg |= USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_FIX18;1303WR4(sc, XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1(lane->idx), reg);13041305if (port->supply_vbus != NULL) {1306rv = regulator_enable(port->supply_vbus);1307if (rv != 0) {1308device_printf(sc->dev,1309"Cannot enable vbus regulator\n");1310return (rv);1311}1312}1313rv = clk_enable(pad->clk);1314if (rv < 0) {1315device_printf(sc->dev, "Cannot enable clock for pad '%s': %d\n",1316pad->name, rv);1317if (port->supply_vbus != NULL)1318regulator_disable(port->supply_vbus);1319return (rv);1320}1321reg = RD4(sc, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);1322reg &= ~USB2_BIAS_PAD_CTL1_TRK_START_TIMER(~0);1323reg &= ~USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER(~0);1324reg |= USB2_BIAS_PAD_CTL1_TRK_START_TIMER(0x1e);1325reg |= USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER(0x0a);1326WR4(sc, XUSB_PADCTL_USB2_BIAS_PAD_CTL1, reg);13271328reg = RD4(sc, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);1329reg &= ~USB2_BIAS_PAD_CTL0_PD;1330WR4(sc, XUSB_PADCTL_USB2_BIAS_PAD_CTL0, reg);1331return (0);1332}13331334static int1335usb2_disable(struct padctl_softc *sc, struct padctl_lane *lane)1336{1337uint32_t reg;1338struct padctl_pad *pad;1339struct padctl_port *port;1340int rv;13411342port = search_lane_port(sc, lane);1343if (port == NULL) {1344device_printf(sc->dev, "Cannot find port for lane: %s\n",1345lane->name);1346}1347pad = lane->pad;13481349reg = RD4(sc, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);1350reg |= USB2_BIAS_PAD_CTL0_PD;1351WR4(sc, XUSB_PADCTL_USB2_BIAS_PAD_CTL0, reg);13521353if (port->supply_vbus != NULL) {1354rv = regulator_disable(port->supply_vbus);1355if (rv != 0) {1356device_printf(sc->dev,1357"Cannot disable vbus regulator\n");1358return (rv);1359}1360}13611362rv = clk_disable(pad->clk);1363if (rv < 0) {1364device_printf(sc->dev, "Cannot disable clock for pad '%s': %d\n",1365pad->name, rv);1366return (rv);1367}13681369return (0);1370}137113721373static int1374pad_common_enable(struct padctl_softc *sc)1375{1376uint32_t reg;13771378reg = RD4(sc, XUSB_PADCTL_ELPG_PROGRAM1);1379reg &= ~ELPG_PROGRAM1_AUX_MUX_LP0_CLAMP_EN;1380WR4(sc, XUSB_PADCTL_ELPG_PROGRAM1, reg);1381DELAY(100);13821383reg = RD4(sc, XUSB_PADCTL_ELPG_PROGRAM1);1384reg &= ~ELPG_PROGRAM1_AUX_MUX_LP0_CLAMP_EN_EARLY;1385WR4(sc, XUSB_PADCTL_ELPG_PROGRAM1, reg);1386DELAY(100);13871388reg = RD4(sc, XUSB_PADCTL_ELPG_PROGRAM1);1389reg &= ~ELPG_PROGRAM1_AUX_MUX_LP0_VCORE_DOWN;1390WR4(sc, XUSB_PADCTL_ELPG_PROGRAM1, reg);1391DELAY(100);13921393return (0);1394}13951396static int1397pad_common_disable(struct padctl_softc *sc)1398{1399uint32_t reg;14001401reg = RD4(sc, XUSB_PADCTL_ELPG_PROGRAM1);1402reg |= ELPG_PROGRAM1_AUX_MUX_LP0_VCORE_DOWN;1403WR4(sc, XUSB_PADCTL_ELPG_PROGRAM1, reg);1404DELAY(100);14051406reg = RD4(sc, XUSB_PADCTL_ELPG_PROGRAM1);1407reg |= ELPG_PROGRAM1_AUX_MUX_LP0_CLAMP_EN_EARLY;1408WR4(sc, XUSB_PADCTL_ELPG_PROGRAM1, reg);1409DELAY(100);14101411reg = RD4(sc, XUSB_PADCTL_ELPG_PROGRAM1);1412reg |= ELPG_PROGRAM1_AUX_MUX_LP0_CLAMP_EN;1413WR4(sc, XUSB_PADCTL_ELPG_PROGRAM1, reg);1414DELAY(100);14151416return (0);1417}14181419static int1420xusbpadctl_phy_enable(struct phynode *phy, bool enable)1421{1422device_t dev;1423intptr_t id;1424struct padctl_softc *sc;1425struct padctl_lane *lane;1426struct padctl_pad *pad;1427int rv;14281429dev = phynode_get_device(phy);1430id = phynode_get_id(phy);1431sc = device_get_softc(dev);14321433if (id < 0 || id >= nitems(lanes_tbl)) {1434device_printf(dev, "Unknown phy: %d\n", (int)id);1435return (ENXIO);1436}14371438lane = lanes_tbl + id;1439if (!lane->enabled) {1440device_printf(dev, "Lane is not enabled/configured: %s\n",1441lane->name);1442return (ENXIO);1443}14441445pad = lane->pad;1446if (enable) {1447if (sc->phy_ena_cnt == 0) {1448rv = pad_common_enable(sc);1449if (rv != 0)1450return (rv);1451}1452sc->phy_ena_cnt++;1453}14541455if (enable)1456rv = pad->enable(sc, lane);1457else1458rv = pad->disable(sc, lane);1459if (rv != 0)1460return (rv);14611462if (!enable) {1463if (sc->phy_ena_cnt == 1) {1464rv = pad_common_disable(sc);1465if (rv != 0)1466return (rv);1467}1468sc->phy_ena_cnt--;1469}14701471return (0);1472}14731474/* -------------------------------------------------------------------------1475*1476* FDT processing1477*/1478static struct padctl_port *1479search_port(struct padctl_softc *sc, char *port_name)1480{1481int i;14821483for (i = 0; i < nitems(ports_tbl); i++) {1484if (strcmp(port_name, ports_tbl[i].name) == 0)1485return (&ports_tbl[i]);1486}1487return (NULL);1488}14891490static struct padctl_port *1491search_lane_port(struct padctl_softc *sc, struct padctl_lane *lane)1492{1493int i;14941495for (i = 0; i < nitems(ports_tbl); i++) {1496if (!ports_tbl[i].enabled)1497continue;1498if (ports_tbl[i].lane == lane)1499return (ports_tbl + i);1500}1501return (NULL);1502}15031504static struct padctl_lane *1505search_lane(struct padctl_softc *sc, char *lane_name)1506{1507int i;15081509for (i = 0; i < nitems(lanes_tbl); i++) {1510if (strcmp(lane_name, lanes_tbl[i].name) == 0)1511return (lanes_tbl + i);1512}1513return (NULL);1514}15151516static struct padctl_lane *1517search_pad_lane(struct padctl_softc *sc, enum padctl_pad_type type, int idx)1518{1519int i;15201521for (i = 0; i < nitems(lanes_tbl); i++) {1522if (!lanes_tbl[i].enabled)1523continue;1524if (type == lanes_tbl[i].pad->type && idx == lanes_tbl[i].idx)1525return (lanes_tbl + i);1526}1527return (NULL);1528}15291530static struct padctl_lane *1531search_usb3_pad_lane(struct padctl_softc *sc, int idx)1532{1533int i;1534struct padctl_lane *lane, *tmp;15351536lane = NULL;1537for (i = 0; i < nitems(lane_map_tbl); i++) {1538if (idx != lane_map_tbl[i].port_idx)1539continue;1540tmp = search_pad_lane(sc, lane_map_tbl[i].pad_type,1541lane_map_tbl[i].lane_idx);1542if (tmp == NULL)1543continue;1544if (strcmp(tmp->mux[tmp->mux_idx], "usb3-ss") != 0)1545continue;1546if (lane != NULL) {1547device_printf(sc->dev, "Duplicated mappings found for"1548" lanes: %s and %s\n", lane->name, tmp->name);1549return (NULL);1550}1551lane = tmp;1552}1553return (lane);1554}15551556static struct padctl_pad *1557search_pad(struct padctl_softc *sc, char *pad_name)1558{1559int i;15601561for (i = 0; i < nitems(pads_tbl); i++) {1562if (strcmp(pad_name, pads_tbl[i].name) == 0)1563return (pads_tbl + i);1564}1565return (NULL);1566}15671568static int1569search_mux(struct padctl_softc *sc, struct padctl_lane *lane, char *fnc_name)1570{1571int i;15721573for (i = 0; i < lane->nmux; i++) {1574if (strcmp(fnc_name, lane->mux[i]) == 0)1575return (i);1576}1577return (-1);1578}15791580static int1581config_lane(struct padctl_softc *sc, struct padctl_lane *lane)1582{1583uint32_t reg;15841585reg = RD4(sc, lane->reg);1586reg &= ~(lane->mask << lane->shift);1587reg |= (lane->mux_idx & lane->mask) << lane->shift;1588WR4(sc, lane->reg, reg);1589return (0);1590}15911592static int1593process_lane(struct padctl_softc *sc, phandle_t node, struct padctl_pad *pad)1594{1595struct padctl_lane *lane;1596struct phynode *phynode;1597struct phynode_init_def phy_init;1598char *name;1599char *function;1600int rv;16011602name = NULL;1603function = NULL;1604rv = OF_getprop_alloc(node, "name", (void **)&name);1605if (rv <= 0) {1606device_printf(sc->dev, "Cannot read lane name.\n");1607return (ENXIO);1608}16091610lane = search_lane(sc, name);1611if (lane == NULL) {1612device_printf(sc->dev, "Unknown lane: %s\n", name);1613rv = ENXIO;1614goto end;1615}16161617/* Read function (mux) settings. */1618rv = OF_getprop_alloc(node, "nvidia,function", (void **)&function);1619if (rv <= 0) {1620device_printf(sc->dev, "Cannot read lane function.\n");1621rv = ENXIO;1622goto end;1623}16241625lane->mux_idx = search_mux(sc, lane, function);1626if (lane->mux_idx == ~0) {1627device_printf(sc->dev, "Unknown function %s for lane %s\n",1628function, name);1629rv = ENXIO;1630goto end;1631}16321633rv = config_lane(sc, lane);1634if (rv != 0) {1635device_printf(sc->dev, "Cannot configure lane: %s: %d\n",1636name, rv);1637rv = ENXIO;1638goto end;1639}1640lane->xref = OF_xref_from_node(node);1641lane->pad = pad;1642lane->enabled = true;1643pad->lanes[pad->nlanes++] = lane;16441645/* Create and register phy. */1646bzero(&phy_init, sizeof(phy_init));1647phy_init.id = lane - lanes_tbl;1648phy_init.ofw_node = node;1649phynode = phynode_create(sc->dev, &xusbpadctl_phynode_class, &phy_init);1650if (phynode == NULL) {1651device_printf(sc->dev, "Cannot create phy\n");1652rv = ENXIO;1653goto end;1654}1655if (phynode_register(phynode) == NULL) {1656device_printf(sc->dev, "Cannot create phy\n");1657return (ENXIO);1658}16591660rv = 0;16611662end:1663if (name != NULL)1664OF_prop_free(name);1665if (function != NULL)1666OF_prop_free(function);1667return (rv);1668}16691670static int1671process_pad(struct padctl_softc *sc, phandle_t node)1672{1673phandle_t xref;1674struct padctl_pad *pad;1675char *name;1676int rv;16771678name = NULL;1679rv = OF_getprop_alloc(node, "name", (void **)&name);1680if (rv <= 0) {1681device_printf(sc->dev, "Cannot read pad name.\n");1682return (ENXIO);1683}16841685pad = search_pad(sc, name);1686if (pad == NULL) {1687device_printf(sc->dev, "Unknown pad: %s\n", name);1688rv = ENXIO;1689goto end;1690}16911692if (pad->clock_name != NULL) {1693rv = clk_get_by_ofw_name(sc->dev, node, pad->clock_name,1694&pad->clk);1695if (rv != 0) {1696device_printf(sc->dev, "Cannot get '%s' clock\n",1697pad->clock_name);1698return (ENXIO);1699}1700}17011702if (pad->reset_name != NULL) {1703rv = hwreset_get_by_ofw_name(sc->dev, node, pad->reset_name,1704&pad->reset);1705if (rv != 0) {1706device_printf(sc->dev, "Cannot get '%s' reset\n",1707pad->reset_name);1708return (ENXIO);1709}1710}17111712/* Read and process associated lanes. */1713node = ofw_bus_find_child(node, "lanes");1714if (node <= 0) {1715device_printf(sc->dev, "Cannot find 'lanes' subnode\n");1716rv = ENXIO;1717goto end;1718}17191720for (node = OF_child(node); node != 0; node = OF_peer(node)) {1721if (!ofw_bus_node_status_okay(node))1722continue;17231724rv = process_lane(sc, node, pad);1725if (rv != 0)1726goto end;17271728xref = OF_xref_from_node(node);1729OF_device_register_xref(xref, sc->dev);1730}1731pad->enabled = true;1732rv = 0;1733end:1734if (name != NULL)1735OF_prop_free(name);1736return (rv);1737}17381739static int1740process_port(struct padctl_softc *sc, phandle_t node)1741{17421743struct padctl_port *port;1744char *name;1745int rv;17461747name = NULL;1748rv = OF_getprop_alloc(node, "name", (void **)&name);1749if (rv <= 0) {1750device_printf(sc->dev, "Cannot read port name.\n");1751return (ENXIO);1752}17531754port = search_port(sc, name);1755if (port == NULL) {1756device_printf(sc->dev, "Unknown port: %s\n", name);1757rv = ENXIO;1758goto end;1759}17601761regulator_get_by_ofw_property(sc->dev, node,1762"vbus-supply", &port->supply_vbus);17631764if (OF_hasprop(node, "nvidia,internal"))1765port->internal = true;17661767/* Find assigned lane */1768if (port->lane == NULL) {1769switch(port->type) {1770/* Routing is fixed for USB2 AND HSIC. */1771case PADCTL_PORT_USB2:1772port->lane = search_pad_lane(sc, PADCTL_PAD_USB2,1773port->idx);1774break;1775case PADCTL_PORT_HSIC:1776port->lane = search_pad_lane(sc, PADCTL_PAD_HSIC,1777port->idx);1778break;1779case PADCTL_PORT_USB3:1780port->lane = search_usb3_pad_lane(sc, port->idx);1781break;1782}1783}1784if (port->lane == NULL) {1785device_printf(sc->dev, "Cannot find lane for port: %s\n", name);1786rv = ENXIO;1787goto end;1788}17891790if (port->type == PADCTL_PORT_USB3) {1791rv = OF_getencprop(node, "nvidia,usb2-companion",1792&(port->companion), sizeof(port->companion));1793if (rv <= 0) {1794device_printf(sc->dev,1795"Missing 'nvidia,usb2-companion' property "1796"for port: %s\n", name);1797rv = ENXIO;1798goto end;1799}1800}18011802port->enabled = true;1803rv = 0;1804end:1805if (name != NULL)1806OF_prop_free(name);1807return (rv);1808}18091810static int1811parse_fdt(struct padctl_softc *sc, phandle_t base_node)1812{1813phandle_t node;1814int rv;18151816rv = 0;1817node = ofw_bus_find_child(base_node, "pads");18181819if (node <= 0) {1820device_printf(sc->dev, "Cannot find pads subnode.\n");1821return (ENXIO);1822}1823for (node = OF_child(node); node != 0; node = OF_peer(node)) {1824if (!ofw_bus_node_status_okay(node))1825continue;1826rv = process_pad(sc, node);1827if (rv != 0)1828return (rv);1829}18301831node = ofw_bus_find_child(base_node, "ports");1832if (node <= 0) {1833device_printf(sc->dev, "Cannot find ports subnode.\n");1834return (ENXIO);1835}1836for (node = OF_child(node); node != 0; node = OF_peer(node)) {1837if (!ofw_bus_node_status_okay(node))1838continue;1839rv = process_port(sc, node);1840if (rv != 0)1841return (rv);1842}18431844return (0);1845}18461847static void1848load_calibration(struct padctl_softc *sc)1849{1850uint32_t reg;1851int i;18521853reg = tegra_fuse_read_4(FUSE_SKU_CALIB_0);1854sc->hs_curr_level[0] = FUSE_SKU_CALIB_0_HS_CURR_LEVEL_0(reg);1855for (i = 1; i < nitems(sc->hs_curr_level); i++) {1856sc->hs_curr_level[i] =1857FUSE_SKU_CALIB_0_HS_CURR_LEVEL_123(reg, i);1858}1859sc->hs_term_range_adj = FUSE_SKU_CALIB_0_HS_TERM_RANGE_ADJ(reg);18601861tegra_fuse_read_4(FUSE_USB_CALIB_EXT_0);1862sc->rpd_ctrl = FUSE_USB_CALIB_EXT_0_RPD_CTRL(reg);1863}18641865/* -------------------------------------------------------------------------1866*1867* BUS functions1868*/1869static int1870xusbpadctl_probe(device_t dev)1871{18721873if (!ofw_bus_status_okay(dev))1874return (ENXIO);18751876if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)1877return (ENXIO);18781879device_set_desc(dev, "Tegra XUSB phy");1880return (BUS_PROBE_DEFAULT);1881}18821883static int1884xusbpadctl_detach(device_t dev)1885{18861887/* This device is always present. */1888return (EBUSY);1889}18901891static int1892xusbpadctl_attach(device_t dev)1893{1894struct padctl_softc * sc;1895int i, rid, rv;1896struct padctl_port *port;1897phandle_t node;18981899sc = device_get_softc(dev);1900sc->dev = dev;1901node = ofw_bus_get_node(dev);1902rid = 0;1903sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,1904RF_ACTIVE);1905if (sc->mem_res == NULL) {1906device_printf(dev, "Cannot allocate memory resources\n");1907return (ENXIO);1908}19091910rv = hwreset_get_by_ofw_name(dev, 0, "padctl", &sc->rst);1911if (rv != 0) {1912device_printf(dev, "Cannot get 'padctl' reset: %d\n", rv);1913return (rv);1914}1915rv = hwreset_deassert(sc->rst);1916if (rv != 0) {1917device_printf(dev, "Cannot unreset 'padctl' reset: %d\n", rv);1918return (rv);1919}19201921load_calibration(sc);19221923rv = parse_fdt(sc, node);1924if (rv != 0) {1925device_printf(dev, "Cannot parse fdt configuration: %d\n", rv);1926return (rv);1927}1928for (i = 0; i < nitems(ports_tbl); i++) {1929port = ports_tbl + i;1930if (!port->enabled)1931continue;1932if (port->init == NULL)1933continue;1934rv = port->init(sc, port);1935if (rv != 0) {1936device_printf(dev, "Cannot init port '%s'\n",1937port->name);1938return (rv);1939}1940}1941return (0);1942}19431944static device_method_t tegra_xusbpadctl_methods[] = {1945/* Device interface */1946DEVMETHOD(device_probe, xusbpadctl_probe),1947DEVMETHOD(device_attach, xusbpadctl_attach),1948DEVMETHOD(device_detach, xusbpadctl_detach),19491950DEVMETHOD_END1951};19521953static DEFINE_CLASS_0(xusbpadctl, tegra_xusbpadctl_driver,1954tegra_xusbpadctl_methods, sizeof(struct padctl_softc));1955EARLY_DRIVER_MODULE(tegra_xusbpadctl, simplebus, tegra_xusbpadctl_driver,1956NULL, NULL, 73);195719581959