phy-rockchip-typec.c (37464B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd 4 * Author: Chris Zhong <zyw@rock-chips.com> 5 * Kever Yang <kever.yang@rock-chips.com> 6 * 7 * The ROCKCHIP Type-C PHY has two PLL clocks. The first PLL clock 8 * is used for USB3, the second PLL clock is used for DP. This Type-C PHY has 9 * 3 working modes: USB3 only mode, DP only mode, and USB3+DP mode. 10 * At USB3 only mode, both PLL clocks need to be initialized, this allows the 11 * PHY to switch mode between USB3 and USB3+DP, without disconnecting the USB 12 * device. 13 * In The DP only mode, only the DP PLL needs to be powered on, and the 4 lanes 14 * are all used for DP. 15 * 16 * This driver gets extcon cable state and property, then decides which mode to 17 * select: 18 * 19 * 1. USB3 only mode: 20 * EXTCON_USB or EXTCON_USB_HOST state is true, and 21 * EXTCON_PROP_USB_SS property is true. 22 * EXTCON_DISP_DP state is false. 23 * 24 * 2. DP only mode: 25 * EXTCON_DISP_DP state is true, and 26 * EXTCON_PROP_USB_SS property is false. 27 * If EXTCON_USB_HOST state is true, it is DP + USB2 mode, since the USB2 phy 28 * is a separate phy, so this case is still DP only mode. 29 * 30 * 3. USB3+DP mode: 31 * EXTCON_USB_HOST and EXTCON_DISP_DP are both true, and 32 * EXTCON_PROP_USB_SS property is true. 33 * 34 * This Type-C PHY driver supports normal and flip orientation. The orientation 35 * is reported by the EXTCON_PROP_USB_TYPEC_POLARITY property: true is flip 36 * orientation, false is normal orientation. 37 */ 38 39#include <linux/clk.h> 40#include <linux/clk-provider.h> 41#include <linux/delay.h> 42#include <linux/extcon.h> 43#include <linux/io.h> 44#include <linux/iopoll.h> 45#include <linux/kernel.h> 46#include <linux/module.h> 47#include <linux/mutex.h> 48#include <linux/of.h> 49#include <linux/of_address.h> 50#include <linux/of_platform.h> 51#include <linux/platform_device.h> 52#include <linux/regmap.h> 53#include <linux/reset.h> 54 55#include <linux/mfd/syscon.h> 56#include <linux/phy/phy.h> 57 58#define CMN_SSM_BANDGAP (0x21 << 2) 59#define CMN_SSM_BIAS (0x22 << 2) 60#define CMN_PLLSM0_PLLEN (0x29 << 2) 61#define CMN_PLLSM0_PLLPRE (0x2a << 2) 62#define CMN_PLLSM0_PLLVREF (0x2b << 2) 63#define CMN_PLLSM0_PLLLOCK (0x2c << 2) 64#define CMN_PLLSM1_PLLEN (0x31 << 2) 65#define CMN_PLLSM1_PLLPRE (0x32 << 2) 66#define CMN_PLLSM1_PLLVREF (0x33 << 2) 67#define CMN_PLLSM1_PLLLOCK (0x34 << 2) 68#define CMN_PLLSM1_USER_DEF_CTRL (0x37 << 2) 69#define CMN_ICAL_OVRD (0xc1 << 2) 70#define CMN_PLL0_VCOCAL_OVRD (0x83 << 2) 71#define CMN_PLL0_VCOCAL_INIT (0x84 << 2) 72#define CMN_PLL0_VCOCAL_ITER (0x85 << 2) 73#define CMN_PLL0_LOCK_REFCNT_START (0x90 << 2) 74#define CMN_PLL0_LOCK_PLLCNT_START (0x92 << 2) 75#define CMN_PLL0_LOCK_PLLCNT_THR (0x93 << 2) 76#define CMN_PLL0_INTDIV (0x94 << 2) 77#define CMN_PLL0_FRACDIV (0x95 << 2) 78#define CMN_PLL0_HIGH_THR (0x96 << 2) 79#define CMN_PLL0_DSM_DIAG (0x97 << 2) 80#define CMN_PLL0_SS_CTRL1 (0x98 << 2) 81#define CMN_PLL0_SS_CTRL2 (0x99 << 2) 82#define CMN_PLL1_VCOCAL_START (0xa1 << 2) 83#define CMN_PLL1_VCOCAL_OVRD (0xa3 << 2) 84#define CMN_PLL1_VCOCAL_INIT (0xa4 << 2) 85#define CMN_PLL1_VCOCAL_ITER (0xa5 << 2) 86#define CMN_PLL1_LOCK_REFCNT_START (0xb0 << 2) 87#define CMN_PLL1_LOCK_PLLCNT_START (0xb2 << 2) 88#define CMN_PLL1_LOCK_PLLCNT_THR (0xb3 << 2) 89#define CMN_PLL1_INTDIV (0xb4 << 2) 90#define CMN_PLL1_FRACDIV (0xb5 << 2) 91#define CMN_PLL1_HIGH_THR (0xb6 << 2) 92#define CMN_PLL1_DSM_DIAG (0xb7 << 2) 93#define CMN_PLL1_SS_CTRL1 (0xb8 << 2) 94#define CMN_PLL1_SS_CTRL2 (0xb9 << 2) 95#define CMN_RXCAL_OVRD (0xd1 << 2) 96 97#define CMN_TXPUCAL_CTRL (0xe0 << 2) 98#define CMN_TXPUCAL_OVRD (0xe1 << 2) 99#define CMN_TXPDCAL_CTRL (0xf0 << 2) 100#define CMN_TXPDCAL_OVRD (0xf1 << 2) 101 102/* For CMN_TXPUCAL_CTRL, CMN_TXPDCAL_CTRL */ 103#define CMN_TXPXCAL_START BIT(15) 104#define CMN_TXPXCAL_DONE BIT(14) 105#define CMN_TXPXCAL_NO_RESPONSE BIT(13) 106#define CMN_TXPXCAL_CURRENT_RESPONSE BIT(12) 107 108#define CMN_TXPU_ADJ_CTRL (0x108 << 2) 109#define CMN_TXPD_ADJ_CTRL (0x10c << 2) 110 111/* 112 * For CMN_TXPUCAL_CTRL, CMN_TXPDCAL_CTRL, 113 * CMN_TXPU_ADJ_CTRL, CMN_TXPDCAL_CTRL 114 * 115 * NOTE: some of these registers are documented to be 2's complement 116 * signed numbers, but then documented to be always positive. Weird. 117 * In such a case, using CMN_CALIB_CODE_POS() avoids the unnecessary 118 * sign extension. 119 */ 120#define CMN_CALIB_CODE_WIDTH 7 121#define CMN_CALIB_CODE_OFFSET 0 122#define CMN_CALIB_CODE_MASK GENMASK(CMN_CALIB_CODE_WIDTH, 0) 123#define CMN_CALIB_CODE(x) \ 124 sign_extend32((x) >> CMN_CALIB_CODE_OFFSET, CMN_CALIB_CODE_WIDTH) 125 126#define CMN_CALIB_CODE_POS_MASK GENMASK(CMN_CALIB_CODE_WIDTH - 1, 0) 127#define CMN_CALIB_CODE_POS(x) \ 128 (((x) >> CMN_CALIB_CODE_OFFSET) & CMN_CALIB_CODE_POS_MASK) 129 130#define CMN_DIAG_PLL0_FBH_OVRD (0x1c0 << 2) 131#define CMN_DIAG_PLL0_FBL_OVRD (0x1c1 << 2) 132#define CMN_DIAG_PLL0_OVRD (0x1c2 << 2) 133#define CMN_DIAG_PLL0_V2I_TUNE (0x1c5 << 2) 134#define CMN_DIAG_PLL0_CP_TUNE (0x1c6 << 2) 135#define CMN_DIAG_PLL0_LF_PROG (0x1c7 << 2) 136#define CMN_DIAG_PLL1_FBH_OVRD (0x1d0 << 2) 137#define CMN_DIAG_PLL1_FBL_OVRD (0x1d1 << 2) 138#define CMN_DIAG_PLL1_OVRD (0x1d2 << 2) 139#define CMN_DIAG_PLL1_V2I_TUNE (0x1d5 << 2) 140#define CMN_DIAG_PLL1_CP_TUNE (0x1d6 << 2) 141#define CMN_DIAG_PLL1_LF_PROG (0x1d7 << 2) 142#define CMN_DIAG_PLL1_PTATIS_TUNE1 (0x1d8 << 2) 143#define CMN_DIAG_PLL1_PTATIS_TUNE2 (0x1d9 << 2) 144#define CMN_DIAG_PLL1_INCLK_CTRL (0x1da << 2) 145#define CMN_DIAG_HSCLK_SEL (0x1e0 << 2) 146 147#define XCVR_PSM_RCTRL(n) ((0x4001 | ((n) << 9)) << 2) 148#define XCVR_PSM_CAL_TMR(n) ((0x4002 | ((n) << 9)) << 2) 149#define XCVR_PSM_A0IN_TMR(n) ((0x4003 | ((n) << 9)) << 2) 150#define TX_TXCC_CAL_SCLR_MULT(n) ((0x4047 | ((n) << 9)) << 2) 151#define TX_TXCC_CPOST_MULT_00(n) ((0x404c | ((n) << 9)) << 2) 152#define TX_TXCC_CPOST_MULT_01(n) ((0x404d | ((n) << 9)) << 2) 153#define TX_TXCC_CPOST_MULT_10(n) ((0x404e | ((n) << 9)) << 2) 154#define TX_TXCC_CPOST_MULT_11(n) ((0x404f | ((n) << 9)) << 2) 155#define TX_TXCC_MGNFS_MULT_000(n) ((0x4050 | ((n) << 9)) << 2) 156#define TX_TXCC_MGNFS_MULT_001(n) ((0x4051 | ((n) << 9)) << 2) 157#define TX_TXCC_MGNFS_MULT_010(n) ((0x4052 | ((n) << 9)) << 2) 158#define TX_TXCC_MGNFS_MULT_011(n) ((0x4053 | ((n) << 9)) << 2) 159#define TX_TXCC_MGNFS_MULT_100(n) ((0x4054 | ((n) << 9)) << 2) 160#define TX_TXCC_MGNFS_MULT_101(n) ((0x4055 | ((n) << 9)) << 2) 161#define TX_TXCC_MGNFS_MULT_110(n) ((0x4056 | ((n) << 9)) << 2) 162#define TX_TXCC_MGNFS_MULT_111(n) ((0x4057 | ((n) << 9)) << 2) 163#define TX_TXCC_MGNLS_MULT_000(n) ((0x4058 | ((n) << 9)) << 2) 164#define TX_TXCC_MGNLS_MULT_001(n) ((0x4059 | ((n) << 9)) << 2) 165#define TX_TXCC_MGNLS_MULT_010(n) ((0x405a | ((n) << 9)) << 2) 166#define TX_TXCC_MGNLS_MULT_011(n) ((0x405b | ((n) << 9)) << 2) 167#define TX_TXCC_MGNLS_MULT_100(n) ((0x405c | ((n) << 9)) << 2) 168#define TX_TXCC_MGNLS_MULT_101(n) ((0x405d | ((n) << 9)) << 2) 169#define TX_TXCC_MGNLS_MULT_110(n) ((0x405e | ((n) << 9)) << 2) 170#define TX_TXCC_MGNLS_MULT_111(n) ((0x405f | ((n) << 9)) << 2) 171 172#define XCVR_DIAG_PLLDRC_CTRL(n) ((0x40e0 | ((n) << 9)) << 2) 173#define XCVR_DIAG_BIDI_CTRL(n) ((0x40e8 | ((n) << 9)) << 2) 174#define XCVR_DIAG_LANE_FCM_EN_MGN(n) ((0x40f2 | ((n) << 9)) << 2) 175#define TX_PSC_A0(n) ((0x4100 | ((n) << 9)) << 2) 176#define TX_PSC_A1(n) ((0x4101 | ((n) << 9)) << 2) 177#define TX_PSC_A2(n) ((0x4102 | ((n) << 9)) << 2) 178#define TX_PSC_A3(n) ((0x4103 | ((n) << 9)) << 2) 179#define TX_RCVDET_CTRL(n) ((0x4120 | ((n) << 9)) << 2) 180#define TX_RCVDET_EN_TMR(n) ((0x4122 | ((n) << 9)) << 2) 181#define TX_RCVDET_ST_TMR(n) ((0x4123 | ((n) << 9)) << 2) 182#define TX_DIAG_TX_DRV(n) ((0x41e1 | ((n) << 9)) << 2) 183#define TX_DIAG_BGREF_PREDRV_DELAY (0x41e7 << 2) 184 185/* Use this for "n" in macros like "_MULT_XXX" to target the aux channel */ 186#define AUX_CH_LANE 8 187 188#define TX_ANA_CTRL_REG_1 (0x5020 << 2) 189 190#define TXDA_DP_AUX_EN BIT(15) 191#define AUXDA_SE_EN BIT(14) 192#define TXDA_CAL_LATCH_EN BIT(13) 193#define AUXDA_POLARITY BIT(12) 194#define TXDA_DRV_POWER_ISOLATION_EN BIT(11) 195#define TXDA_DRV_POWER_EN_PH_2_N BIT(10) 196#define TXDA_DRV_POWER_EN_PH_1_N BIT(9) 197#define TXDA_BGREF_EN BIT(8) 198#define TXDA_DRV_LDO_EN BIT(7) 199#define TXDA_DECAP_EN_DEL BIT(6) 200#define TXDA_DECAP_EN BIT(5) 201#define TXDA_UPHY_SUPPLY_EN_DEL BIT(4) 202#define TXDA_UPHY_SUPPLY_EN BIT(3) 203#define TXDA_LOW_LEAKAGE_EN BIT(2) 204#define TXDA_DRV_IDLE_LOWI_EN BIT(1) 205#define TXDA_DRV_CMN_MODE_EN BIT(0) 206 207#define TX_ANA_CTRL_REG_2 (0x5021 << 2) 208 209#define AUXDA_DEBOUNCING_CLK BIT(15) 210#define TXDA_LPBK_RECOVERED_CLK_EN BIT(14) 211#define TXDA_LPBK_ISI_GEN_EN BIT(13) 212#define TXDA_LPBK_SERIAL_EN BIT(12) 213#define TXDA_LPBK_LINE_EN BIT(11) 214#define TXDA_DRV_LDO_REDC_SINKIQ BIT(10) 215#define XCVR_DECAP_EN_DEL BIT(9) 216#define XCVR_DECAP_EN BIT(8) 217#define TXDA_MPHY_ENABLE_HS_NT BIT(7) 218#define TXDA_MPHY_SA_MODE BIT(6) 219#define TXDA_DRV_LDO_RBYR_FB_EN BIT(5) 220#define TXDA_DRV_RST_PULL_DOWN BIT(4) 221#define TXDA_DRV_LDO_BG_FB_EN BIT(3) 222#define TXDA_DRV_LDO_BG_REF_EN BIT(2) 223#define TXDA_DRV_PREDRV_EN_DEL BIT(1) 224#define TXDA_DRV_PREDRV_EN BIT(0) 225 226#define TXDA_COEFF_CALC_CTRL (0x5022 << 2) 227 228#define TX_HIGH_Z BIT(6) 229#define TX_VMARGIN_OFFSET 3 230#define TX_VMARGIN_MASK 0x7 231#define LOW_POWER_SWING_EN BIT(2) 232#define TX_FCM_DRV_MAIN_EN BIT(1) 233#define TX_FCM_FULL_MARGIN BIT(0) 234 235#define TX_DIG_CTRL_REG_2 (0x5024 << 2) 236 237#define TX_HIGH_Z_TM_EN BIT(15) 238#define TX_RESCAL_CODE_OFFSET 0 239#define TX_RESCAL_CODE_MASK 0x3f 240 241#define TXDA_CYA_AUXDA_CYA (0x5025 << 2) 242#define TX_ANA_CTRL_REG_3 (0x5026 << 2) 243#define TX_ANA_CTRL_REG_4 (0x5027 << 2) 244#define TX_ANA_CTRL_REG_5 (0x5029 << 2) 245 246#define RX_PSC_A0(n) ((0x8000 | ((n) << 9)) << 2) 247#define RX_PSC_A1(n) ((0x8001 | ((n) << 9)) << 2) 248#define RX_PSC_A2(n) ((0x8002 | ((n) << 9)) << 2) 249#define RX_PSC_A3(n) ((0x8003 | ((n) << 9)) << 2) 250#define RX_PSC_CAL(n) ((0x8006 | ((n) << 9)) << 2) 251#define RX_PSC_RDY(n) ((0x8007 | ((n) << 9)) << 2) 252#define RX_IQPI_ILL_CAL_OVRD (0x8023 << 2) 253#define RX_EPI_ILL_CAL_OVRD (0x8033 << 2) 254#define RX_SDCAL0_OVRD (0x8041 << 2) 255#define RX_SDCAL1_OVRD (0x8049 << 2) 256#define RX_SLC_INIT (0x806d << 2) 257#define RX_SLC_RUN (0x806e << 2) 258#define RX_CDRLF_CNFG2 (0x8081 << 2) 259#define RX_SIGDET_HL_FILT_TMR(n) ((0x8090 | ((n) << 9)) << 2) 260#define RX_SLC_IOP0_OVRD (0x8101 << 2) 261#define RX_SLC_IOP1_OVRD (0x8105 << 2) 262#define RX_SLC_QOP0_OVRD (0x8109 << 2) 263#define RX_SLC_QOP1_OVRD (0x810d << 2) 264#define RX_SLC_EOP0_OVRD (0x8111 << 2) 265#define RX_SLC_EOP1_OVRD (0x8115 << 2) 266#define RX_SLC_ION0_OVRD (0x8119 << 2) 267#define RX_SLC_ION1_OVRD (0x811d << 2) 268#define RX_SLC_QON0_OVRD (0x8121 << 2) 269#define RX_SLC_QON1_OVRD (0x8125 << 2) 270#define RX_SLC_EON0_OVRD (0x8129 << 2) 271#define RX_SLC_EON1_OVRD (0x812d << 2) 272#define RX_SLC_IEP0_OVRD (0x8131 << 2) 273#define RX_SLC_IEP1_OVRD (0x8135 << 2) 274#define RX_SLC_QEP0_OVRD (0x8139 << 2) 275#define RX_SLC_QEP1_OVRD (0x813d << 2) 276#define RX_SLC_EEP0_OVRD (0x8141 << 2) 277#define RX_SLC_EEP1_OVRD (0x8145 << 2) 278#define RX_SLC_IEN0_OVRD (0x8149 << 2) 279#define RX_SLC_IEN1_OVRD (0x814d << 2) 280#define RX_SLC_QEN0_OVRD (0x8151 << 2) 281#define RX_SLC_QEN1_OVRD (0x8155 << 2) 282#define RX_SLC_EEN0_OVRD (0x8159 << 2) 283#define RX_SLC_EEN1_OVRD (0x815d << 2) 284#define RX_REE_CTRL_DATA_MASK(n) ((0x81bb | ((n) << 9)) << 2) 285#define RX_DIAG_SIGDET_TUNE(n) ((0x81dc | ((n) << 9)) << 2) 286#define RX_DIAG_SC2C_DELAY (0x81e1 << 2) 287 288#define PMA_LANE_CFG (0xc000 << 2) 289#define PIPE_CMN_CTRL1 (0xc001 << 2) 290#define PIPE_CMN_CTRL2 (0xc002 << 2) 291#define PIPE_COM_LOCK_CFG1 (0xc003 << 2) 292#define PIPE_COM_LOCK_CFG2 (0xc004 << 2) 293#define PIPE_RCV_DET_INH (0xc005 << 2) 294#define DP_MODE_CTL (0xc008 << 2) 295#define DP_CLK_CTL (0xc009 << 2) 296#define STS (0xc00F << 2) 297#define PHY_ISO_CMN_CTRL (0xc010 << 2) 298#define PHY_DP_TX_CTL (0xc408 << 2) 299#define PMA_CMN_CTRL1 (0xc800 << 2) 300#define PHY_PMA_ISO_CMN_CTRL (0xc810 << 2) 301#define PHY_ISOLATION_CTRL (0xc81f << 2) 302#define PHY_PMA_ISO_XCVR_CTRL(n) ((0xcc11 | ((n) << 6)) << 2) 303#define PHY_PMA_ISO_LINK_MODE(n) ((0xcc12 | ((n) << 6)) << 2) 304#define PHY_PMA_ISO_PWRST_CTRL(n) ((0xcc13 | ((n) << 6)) << 2) 305#define PHY_PMA_ISO_TX_DATA_LO(n) ((0xcc14 | ((n) << 6)) << 2) 306#define PHY_PMA_ISO_TX_DATA_HI(n) ((0xcc15 | ((n) << 6)) << 2) 307#define PHY_PMA_ISO_RX_DATA_LO(n) ((0xcc16 | ((n) << 6)) << 2) 308#define PHY_PMA_ISO_RX_DATA_HI(n) ((0xcc17 | ((n) << 6)) << 2) 309#define TX_BIST_CTRL(n) ((0x4140 | ((n) << 9)) << 2) 310#define TX_BIST_UDDWR(n) ((0x4141 | ((n) << 9)) << 2) 311 312/* 313 * Selects which PLL clock will be driven on the analog high speed 314 * clock 0: PLL 0 div 1 315 * clock 1: PLL 1 div 2 316 */ 317#define CLK_PLL_CONFIG 0X30 318#define CLK_PLL_MASK 0x33 319 320#define CMN_READY BIT(0) 321 322#define DP_PLL_CLOCK_ENABLE BIT(2) 323#define DP_PLL_ENABLE BIT(0) 324#define DP_PLL_DATA_RATE_RBR ((2 << 12) | (4 << 8)) 325#define DP_PLL_DATA_RATE_HBR ((2 << 12) | (4 << 8)) 326#define DP_PLL_DATA_RATE_HBR2 ((1 << 12) | (2 << 8)) 327 328#define DP_MODE_A0 BIT(4) 329#define DP_MODE_A2 BIT(6) 330#define DP_MODE_ENTER_A0 0xc101 331#define DP_MODE_ENTER_A2 0xc104 332 333#define PHY_MODE_SET_TIMEOUT 100000 334 335#define PIN_ASSIGN_C_E 0x51d9 336#define PIN_ASSIGN_D_F 0x5100 337 338#define MODE_DISCONNECT 0 339#define MODE_UFP_USB BIT(0) 340#define MODE_DFP_USB BIT(1) 341#define MODE_DFP_DP BIT(2) 342 343struct usb3phy_reg { 344 u32 offset; 345 u32 enable_bit; 346 u32 write_enable; 347}; 348 349/** 350 * struct rockchip_usb3phy_port_cfg - usb3-phy port configuration. 351 * @reg: the base address for usb3-phy config. 352 * @typec_conn_dir: the register of type-c connector direction. 353 * @usb3tousb2_en: the register of type-c force usb2 to usb2 enable. 354 * @external_psm: the register of type-c phy external psm clock. 355 * @pipe_status: the register of type-c phy pipe status. 356 * @usb3_host_disable: the register of type-c usb3 host disable. 357 * @usb3_host_port: the register of type-c usb3 host port. 358 * @uphy_dp_sel: the register of type-c phy DP select control. 359 */ 360struct rockchip_usb3phy_port_cfg { 361 unsigned int reg; 362 struct usb3phy_reg typec_conn_dir; 363 struct usb3phy_reg usb3tousb2_en; 364 struct usb3phy_reg external_psm; 365 struct usb3phy_reg pipe_status; 366 struct usb3phy_reg usb3_host_disable; 367 struct usb3phy_reg usb3_host_port; 368 struct usb3phy_reg uphy_dp_sel; 369}; 370 371struct rockchip_typec_phy { 372 struct device *dev; 373 void __iomem *base; 374 struct extcon_dev *extcon; 375 struct regmap *grf_regs; 376 struct clk *clk_core; 377 struct clk *clk_ref; 378 struct reset_control *uphy_rst; 379 struct reset_control *pipe_rst; 380 struct reset_control *tcphy_rst; 381 const struct rockchip_usb3phy_port_cfg *port_cfgs; 382 /* mutex to protect access to individual PHYs */ 383 struct mutex lock; 384 385 bool flip; 386 u8 mode; 387}; 388 389struct phy_reg { 390 u16 value; 391 u32 addr; 392}; 393 394static struct phy_reg usb3_pll_cfg[] = { 395 { 0xf0, CMN_PLL0_VCOCAL_INIT }, 396 { 0x18, CMN_PLL0_VCOCAL_ITER }, 397 { 0xd0, CMN_PLL0_INTDIV }, 398 { 0x4a4a, CMN_PLL0_FRACDIV }, 399 { 0x34, CMN_PLL0_HIGH_THR }, 400 { 0x1ee, CMN_PLL0_SS_CTRL1 }, 401 { 0x7f03, CMN_PLL0_SS_CTRL2 }, 402 { 0x20, CMN_PLL0_DSM_DIAG }, 403 { 0, CMN_DIAG_PLL0_OVRD }, 404 { 0, CMN_DIAG_PLL0_FBH_OVRD }, 405 { 0, CMN_DIAG_PLL0_FBL_OVRD }, 406 { 0x7, CMN_DIAG_PLL0_V2I_TUNE }, 407 { 0x45, CMN_DIAG_PLL0_CP_TUNE }, 408 { 0x8, CMN_DIAG_PLL0_LF_PROG }, 409}; 410 411static struct phy_reg dp_pll_cfg[] = { 412 { 0xf0, CMN_PLL1_VCOCAL_INIT }, 413 { 0x18, CMN_PLL1_VCOCAL_ITER }, 414 { 0x30b9, CMN_PLL1_VCOCAL_START }, 415 { 0x21c, CMN_PLL1_INTDIV }, 416 { 0, CMN_PLL1_FRACDIV }, 417 { 0x5, CMN_PLL1_HIGH_THR }, 418 { 0x35, CMN_PLL1_SS_CTRL1 }, 419 { 0x7f1e, CMN_PLL1_SS_CTRL2 }, 420 { 0x20, CMN_PLL1_DSM_DIAG }, 421 { 0, CMN_PLLSM1_USER_DEF_CTRL }, 422 { 0, CMN_DIAG_PLL1_OVRD }, 423 { 0, CMN_DIAG_PLL1_FBH_OVRD }, 424 { 0, CMN_DIAG_PLL1_FBL_OVRD }, 425 { 0x6, CMN_DIAG_PLL1_V2I_TUNE }, 426 { 0x45, CMN_DIAG_PLL1_CP_TUNE }, 427 { 0x8, CMN_DIAG_PLL1_LF_PROG }, 428 { 0x100, CMN_DIAG_PLL1_PTATIS_TUNE1 }, 429 { 0x7, CMN_DIAG_PLL1_PTATIS_TUNE2 }, 430 { 0x4, CMN_DIAG_PLL1_INCLK_CTRL }, 431}; 432 433static const struct rockchip_usb3phy_port_cfg rk3399_usb3phy_port_cfgs[] = { 434 { 435 .reg = 0xff7c0000, 436 .typec_conn_dir = { 0xe580, 0, 16 }, 437 .usb3tousb2_en = { 0xe580, 3, 19 }, 438 .external_psm = { 0xe588, 14, 30 }, 439 .pipe_status = { 0xe5c0, 0, 0 }, 440 .usb3_host_disable = { 0x2434, 0, 16 }, 441 .usb3_host_port = { 0x2434, 12, 28 }, 442 .uphy_dp_sel = { 0x6268, 19, 19 }, 443 }, 444 { 445 .reg = 0xff800000, 446 .typec_conn_dir = { 0xe58c, 0, 16 }, 447 .usb3tousb2_en = { 0xe58c, 3, 19 }, 448 .external_psm = { 0xe594, 14, 30 }, 449 .pipe_status = { 0xe5c0, 16, 16 }, 450 .usb3_host_disable = { 0x2444, 0, 16 }, 451 .usb3_host_port = { 0x2444, 12, 28 }, 452 .uphy_dp_sel = { 0x6268, 3, 19 }, 453 }, 454 { /* sentinel */ } 455}; 456 457static void tcphy_cfg_24m(struct rockchip_typec_phy *tcphy) 458{ 459 u32 i, rdata; 460 461 /* 462 * cmn_ref_clk_sel = 3, select the 24Mhz for clk parent 463 * cmn_psm_clk_dig_div = 2, set the clk division to 2 464 */ 465 writel(0x830, tcphy->base + PMA_CMN_CTRL1); 466 for (i = 0; i < 4; i++) { 467 /* 468 * The following PHY configuration assumes a 24 MHz reference 469 * clock. 470 */ 471 writel(0x90, tcphy->base + XCVR_DIAG_LANE_FCM_EN_MGN(i)); 472 writel(0x960, tcphy->base + TX_RCVDET_EN_TMR(i)); 473 writel(0x30, tcphy->base + TX_RCVDET_ST_TMR(i)); 474 } 475 476 rdata = readl(tcphy->base + CMN_DIAG_HSCLK_SEL); 477 rdata &= ~CLK_PLL_MASK; 478 rdata |= CLK_PLL_CONFIG; 479 writel(rdata, tcphy->base + CMN_DIAG_HSCLK_SEL); 480} 481 482static void tcphy_cfg_usb3_pll(struct rockchip_typec_phy *tcphy) 483{ 484 u32 i; 485 486 /* load the configuration of PLL0 */ 487 for (i = 0; i < ARRAY_SIZE(usb3_pll_cfg); i++) 488 writel(usb3_pll_cfg[i].value, 489 tcphy->base + usb3_pll_cfg[i].addr); 490} 491 492static void tcphy_cfg_dp_pll(struct rockchip_typec_phy *tcphy) 493{ 494 u32 i; 495 496 /* set the default mode to RBR */ 497 writel(DP_PLL_CLOCK_ENABLE | DP_PLL_ENABLE | DP_PLL_DATA_RATE_RBR, 498 tcphy->base + DP_CLK_CTL); 499 500 /* load the configuration of PLL1 */ 501 for (i = 0; i < ARRAY_SIZE(dp_pll_cfg); i++) 502 writel(dp_pll_cfg[i].value, tcphy->base + dp_pll_cfg[i].addr); 503} 504 505static void tcphy_tx_usb3_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane) 506{ 507 writel(0x7799, tcphy->base + TX_PSC_A0(lane)); 508 writel(0x7798, tcphy->base + TX_PSC_A1(lane)); 509 writel(0x5098, tcphy->base + TX_PSC_A2(lane)); 510 writel(0x5098, tcphy->base + TX_PSC_A3(lane)); 511 writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_000(lane)); 512 writel(0xbf, tcphy->base + XCVR_DIAG_BIDI_CTRL(lane)); 513} 514 515static void tcphy_rx_usb3_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane) 516{ 517 writel(0xa6fd, tcphy->base + RX_PSC_A0(lane)); 518 writel(0xa6fd, tcphy->base + RX_PSC_A1(lane)); 519 writel(0xa410, tcphy->base + RX_PSC_A2(lane)); 520 writel(0x2410, tcphy->base + RX_PSC_A3(lane)); 521 writel(0x23ff, tcphy->base + RX_PSC_CAL(lane)); 522 writel(0x13, tcphy->base + RX_SIGDET_HL_FILT_TMR(lane)); 523 writel(0x03e7, tcphy->base + RX_REE_CTRL_DATA_MASK(lane)); 524 writel(0x1004, tcphy->base + RX_DIAG_SIGDET_TUNE(lane)); 525 writel(0x2010, tcphy->base + RX_PSC_RDY(lane)); 526 writel(0xfb, tcphy->base + XCVR_DIAG_BIDI_CTRL(lane)); 527} 528 529static void tcphy_dp_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane) 530{ 531 u16 rdata; 532 533 writel(0xbefc, tcphy->base + XCVR_PSM_RCTRL(lane)); 534 writel(0x6799, tcphy->base + TX_PSC_A0(lane)); 535 writel(0x6798, tcphy->base + TX_PSC_A1(lane)); 536 writel(0x98, tcphy->base + TX_PSC_A2(lane)); 537 writel(0x98, tcphy->base + TX_PSC_A3(lane)); 538 539 writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_000(lane)); 540 writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_001(lane)); 541 writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_010(lane)); 542 writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_011(lane)); 543 writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_100(lane)); 544 writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_101(lane)); 545 writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_110(lane)); 546 writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_111(lane)); 547 writel(0, tcphy->base + TX_TXCC_CPOST_MULT_10(lane)); 548 writel(0, tcphy->base + TX_TXCC_CPOST_MULT_01(lane)); 549 writel(0, tcphy->base + TX_TXCC_CPOST_MULT_00(lane)); 550 writel(0, tcphy->base + TX_TXCC_CPOST_MULT_11(lane)); 551 552 writel(0x128, tcphy->base + TX_TXCC_CAL_SCLR_MULT(lane)); 553 writel(0x400, tcphy->base + TX_DIAG_TX_DRV(lane)); 554 555 rdata = readl(tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane)); 556 rdata = (rdata & 0x8fff) | 0x6000; 557 writel(rdata, tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane)); 558} 559 560static inline int property_enable(struct rockchip_typec_phy *tcphy, 561 const struct usb3phy_reg *reg, bool en) 562{ 563 u32 mask = 1 << reg->write_enable; 564 u32 val = en << reg->enable_bit; 565 566 return regmap_write(tcphy->grf_regs, reg->offset, val | mask); 567} 568 569static void tcphy_dp_aux_set_flip(struct rockchip_typec_phy *tcphy) 570{ 571 u16 tx_ana_ctrl_reg_1; 572 573 /* 574 * Select the polarity of the xcvr: 575 * 1, Reverses the polarity (If TYPEC, Pulls ups aux_p and pull 576 * down aux_m) 577 * 0, Normal polarity (if TYPEC, pulls up aux_m and pulls down 578 * aux_p) 579 */ 580 tx_ana_ctrl_reg_1 = readl(tcphy->base + TX_ANA_CTRL_REG_1); 581 if (!tcphy->flip) 582 tx_ana_ctrl_reg_1 |= AUXDA_POLARITY; 583 else 584 tx_ana_ctrl_reg_1 &= ~AUXDA_POLARITY; 585 writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1); 586} 587 588static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy) 589{ 590 u16 val; 591 u16 tx_ana_ctrl_reg_1; 592 u16 tx_ana_ctrl_reg_2; 593 s32 pu_calib_code, pd_calib_code; 594 s32 pu_adj, pd_adj; 595 u16 calib; 596 597 /* 598 * Calculate calibration code as per docs: use an average of the 599 * pull down and pull up. Then add in adjustments. 600 */ 601 val = readl(tcphy->base + CMN_TXPUCAL_CTRL); 602 pu_calib_code = CMN_CALIB_CODE_POS(val); 603 val = readl(tcphy->base + CMN_TXPDCAL_CTRL); 604 pd_calib_code = CMN_CALIB_CODE_POS(val); 605 val = readl(tcphy->base + CMN_TXPU_ADJ_CTRL); 606 pu_adj = CMN_CALIB_CODE(val); 607 val = readl(tcphy->base + CMN_TXPD_ADJ_CTRL); 608 pd_adj = CMN_CALIB_CODE(val); 609 calib = (pu_calib_code + pd_calib_code) / 2 + pu_adj + pd_adj; 610 611 /* disable txda_cal_latch_en for rewrite the calibration values */ 612 tx_ana_ctrl_reg_1 = readl(tcphy->base + TX_ANA_CTRL_REG_1); 613 tx_ana_ctrl_reg_1 &= ~TXDA_CAL_LATCH_EN; 614 writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1); 615 616 /* write the calibration, then delay 10 ms as sample in docs */ 617 val = readl(tcphy->base + TX_DIG_CTRL_REG_2); 618 val &= ~(TX_RESCAL_CODE_MASK << TX_RESCAL_CODE_OFFSET); 619 val |= calib << TX_RESCAL_CODE_OFFSET; 620 writel(val, tcphy->base + TX_DIG_CTRL_REG_2); 621 usleep_range(10000, 10050); 622 623 /* 624 * Enable signal for latch that sample and holds calibration values. 625 * Activate this signal for 1 clock cycle to sample new calibration 626 * values. 627 */ 628 tx_ana_ctrl_reg_1 |= TXDA_CAL_LATCH_EN; 629 writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1); 630 usleep_range(150, 200); 631 632 /* set TX Voltage Level and TX Deemphasis to 0 */ 633 writel(0, tcphy->base + PHY_DP_TX_CTL); 634 635 /* re-enable decap */ 636 tx_ana_ctrl_reg_2 = XCVR_DECAP_EN; 637 writel(tx_ana_ctrl_reg_2, tcphy->base + TX_ANA_CTRL_REG_2); 638 udelay(1); 639 tx_ana_ctrl_reg_2 |= XCVR_DECAP_EN_DEL; 640 writel(tx_ana_ctrl_reg_2, tcphy->base + TX_ANA_CTRL_REG_2); 641 642 writel(0, tcphy->base + TX_ANA_CTRL_REG_3); 643 644 tx_ana_ctrl_reg_1 |= TXDA_UPHY_SUPPLY_EN; 645 writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1); 646 udelay(1); 647 tx_ana_ctrl_reg_1 |= TXDA_UPHY_SUPPLY_EN_DEL; 648 writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1); 649 650 writel(0, tcphy->base + TX_ANA_CTRL_REG_5); 651 652 /* 653 * Programs txda_drv_ldo_prog[15:0], Sets driver LDO 654 * voltage 16'h1001 for DP-AUX-TX and RX 655 */ 656 writel(0x1001, tcphy->base + TX_ANA_CTRL_REG_4); 657 658 /* re-enables Bandgap reference for LDO */ 659 tx_ana_ctrl_reg_1 |= TXDA_DRV_LDO_EN; 660 writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1); 661 udelay(5); 662 tx_ana_ctrl_reg_1 |= TXDA_BGREF_EN; 663 writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1); 664 665 /* 666 * re-enables the transmitter pre-driver, driver data selection MUX, 667 * and receiver detect circuits. 668 */ 669 tx_ana_ctrl_reg_2 |= TXDA_DRV_PREDRV_EN; 670 writel(tx_ana_ctrl_reg_2, tcphy->base + TX_ANA_CTRL_REG_2); 671 udelay(1); 672 tx_ana_ctrl_reg_2 |= TXDA_DRV_PREDRV_EN_DEL; 673 writel(tx_ana_ctrl_reg_2, tcphy->base + TX_ANA_CTRL_REG_2); 674 675 /* 676 * Do all the undocumented magic: 677 * - Turn on TXDA_DP_AUX_EN, whatever that is, even though sample 678 * never shows this going on. 679 * - Turn on TXDA_DECAP_EN (and TXDA_DECAP_EN_DEL) even though 680 * docs say for aux it's always 0. 681 * - Turn off the LDO and BGREF, which we just spent time turning 682 * on above (???). 683 * 684 * Without this magic, things seem worse. 685 */ 686 tx_ana_ctrl_reg_1 |= TXDA_DP_AUX_EN; 687 tx_ana_ctrl_reg_1 |= TXDA_DECAP_EN; 688 tx_ana_ctrl_reg_1 &= ~TXDA_DRV_LDO_EN; 689 tx_ana_ctrl_reg_1 &= ~TXDA_BGREF_EN; 690 writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1); 691 udelay(1); 692 tx_ana_ctrl_reg_1 |= TXDA_DECAP_EN_DEL; 693 writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1); 694 695 /* 696 * Undo the work we did to set the LDO voltage. 697 * This doesn't seem to help nor hurt, but it kinda goes with the 698 * undocumented magic above. 699 */ 700 writel(0, tcphy->base + TX_ANA_CTRL_REG_4); 701 702 /* Don't set voltage swing to 400 mV peak to peak (differential) */ 703 writel(0, tcphy->base + TXDA_COEFF_CALC_CTRL); 704 705 /* Init TXDA_CYA_AUXDA_CYA for unknown magic reasons */ 706 writel(0, tcphy->base + TXDA_CYA_AUXDA_CYA); 707 708 /* 709 * More undocumented magic, presumably the goal of which is to 710 * make the "auxda_source_aux_oen" be ignored and instead to decide 711 * about "high impedance state" based on what software puts in the 712 * register TXDA_COEFF_CALC_CTRL (see TX_HIGH_Z). Since we only 713 * program that register once and we don't set the bit TX_HIGH_Z, 714 * presumably the goal here is that we should never put the analog 715 * driver in high impedance state. 716 */ 717 val = readl(tcphy->base + TX_DIG_CTRL_REG_2); 718 val |= TX_HIGH_Z_TM_EN; 719 writel(val, tcphy->base + TX_DIG_CTRL_REG_2); 720} 721 722static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode) 723{ 724 const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs; 725 int ret, i; 726 u32 val; 727 728 ret = clk_prepare_enable(tcphy->clk_core); 729 if (ret) { 730 dev_err(tcphy->dev, "Failed to prepare_enable core clock\n"); 731 return ret; 732 } 733 734 ret = clk_prepare_enable(tcphy->clk_ref); 735 if (ret) { 736 dev_err(tcphy->dev, "Failed to prepare_enable ref clock\n"); 737 goto err_clk_core; 738 } 739 740 reset_control_deassert(tcphy->tcphy_rst); 741 742 property_enable(tcphy, &cfg->typec_conn_dir, tcphy->flip); 743 tcphy_dp_aux_set_flip(tcphy); 744 745 tcphy_cfg_24m(tcphy); 746 747 if (mode == MODE_DFP_DP) { 748 tcphy_cfg_dp_pll(tcphy); 749 for (i = 0; i < 4; i++) 750 tcphy_dp_cfg_lane(tcphy, i); 751 752 writel(PIN_ASSIGN_C_E, tcphy->base + PMA_LANE_CFG); 753 } else { 754 tcphy_cfg_usb3_pll(tcphy); 755 tcphy_cfg_dp_pll(tcphy); 756 if (tcphy->flip) { 757 tcphy_tx_usb3_cfg_lane(tcphy, 3); 758 tcphy_rx_usb3_cfg_lane(tcphy, 2); 759 tcphy_dp_cfg_lane(tcphy, 0); 760 tcphy_dp_cfg_lane(tcphy, 1); 761 } else { 762 tcphy_tx_usb3_cfg_lane(tcphy, 0); 763 tcphy_rx_usb3_cfg_lane(tcphy, 1); 764 tcphy_dp_cfg_lane(tcphy, 2); 765 tcphy_dp_cfg_lane(tcphy, 3); 766 } 767 768 writel(PIN_ASSIGN_D_F, tcphy->base + PMA_LANE_CFG); 769 } 770 771 writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL); 772 773 reset_control_deassert(tcphy->uphy_rst); 774 775 ret = readx_poll_timeout(readl, tcphy->base + PMA_CMN_CTRL1, 776 val, val & CMN_READY, 10, 777 PHY_MODE_SET_TIMEOUT); 778 if (ret < 0) { 779 dev_err(tcphy->dev, "wait pma ready timeout\n"); 780 ret = -ETIMEDOUT; 781 goto err_wait_pma; 782 } 783 784 reset_control_deassert(tcphy->pipe_rst); 785 786 return 0; 787 788err_wait_pma: 789 reset_control_assert(tcphy->uphy_rst); 790 reset_control_assert(tcphy->tcphy_rst); 791 clk_disable_unprepare(tcphy->clk_ref); 792err_clk_core: 793 clk_disable_unprepare(tcphy->clk_core); 794 return ret; 795} 796 797static void tcphy_phy_deinit(struct rockchip_typec_phy *tcphy) 798{ 799 reset_control_assert(tcphy->tcphy_rst); 800 reset_control_assert(tcphy->uphy_rst); 801 reset_control_assert(tcphy->pipe_rst); 802 clk_disable_unprepare(tcphy->clk_core); 803 clk_disable_unprepare(tcphy->clk_ref); 804} 805 806static int tcphy_get_mode(struct rockchip_typec_phy *tcphy) 807{ 808 struct extcon_dev *edev = tcphy->extcon; 809 union extcon_property_value property; 810 unsigned int id; 811 bool ufp, dp; 812 u8 mode; 813 int ret; 814 815 if (!edev) 816 return MODE_DFP_USB; 817 818 ufp = extcon_get_state(edev, EXTCON_USB); 819 dp = extcon_get_state(edev, EXTCON_DISP_DP); 820 821 mode = MODE_DFP_USB; 822 id = EXTCON_USB_HOST; 823 824 if (ufp) { 825 mode = MODE_UFP_USB; 826 id = EXTCON_USB; 827 } else if (dp) { 828 mode = MODE_DFP_DP; 829 id = EXTCON_DISP_DP; 830 831 ret = extcon_get_property(edev, id, EXTCON_PROP_USB_SS, 832 &property); 833 if (ret) { 834 dev_err(tcphy->dev, "get superspeed property failed\n"); 835 return ret; 836 } 837 838 if (property.intval) 839 mode |= MODE_DFP_USB; 840 } 841 842 ret = extcon_get_property(edev, id, EXTCON_PROP_USB_TYPEC_POLARITY, 843 &property); 844 if (ret) { 845 dev_err(tcphy->dev, "get polarity property failed\n"); 846 return ret; 847 } 848 849 tcphy->flip = property.intval ? 1 : 0; 850 851 return mode; 852} 853 854static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_typec_phy *tcphy, 855 bool value) 856{ 857 const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs; 858 859 property_enable(tcphy, &cfg->usb3tousb2_en, value); 860 property_enable(tcphy, &cfg->usb3_host_disable, value); 861 property_enable(tcphy, &cfg->usb3_host_port, !value); 862 863 return 0; 864} 865 866static int rockchip_usb3_phy_power_on(struct phy *phy) 867{ 868 struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy); 869 const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs; 870 const struct usb3phy_reg *reg = &cfg->pipe_status; 871 int timeout, new_mode, ret = 0; 872 u32 val; 873 874 mutex_lock(&tcphy->lock); 875 876 new_mode = tcphy_get_mode(tcphy); 877 if (new_mode < 0) { 878 ret = new_mode; 879 goto unlock_ret; 880 } 881 882 /* DP-only mode; fall back to USB2 */ 883 if (!(new_mode & (MODE_DFP_USB | MODE_UFP_USB))) { 884 tcphy_cfg_usb3_to_usb2_only(tcphy, true); 885 goto unlock_ret; 886 } 887 888 if (tcphy->mode == new_mode) 889 goto unlock_ret; 890 891 if (tcphy->mode == MODE_DISCONNECT) { 892 ret = tcphy_phy_init(tcphy, new_mode); 893 if (ret) 894 goto unlock_ret; 895 } 896 897 /* wait TCPHY for pipe ready */ 898 for (timeout = 0; timeout < 100; timeout++) { 899 regmap_read(tcphy->grf_regs, reg->offset, &val); 900 if (!(val & BIT(reg->enable_bit))) { 901 tcphy->mode |= new_mode & (MODE_DFP_USB | MODE_UFP_USB); 902 903 /* enable usb3 host */ 904 tcphy_cfg_usb3_to_usb2_only(tcphy, false); 905 goto unlock_ret; 906 } 907 usleep_range(10, 20); 908 } 909 910 if (tcphy->mode == MODE_DISCONNECT) 911 tcphy_phy_deinit(tcphy); 912 913 ret = -ETIMEDOUT; 914 915unlock_ret: 916 mutex_unlock(&tcphy->lock); 917 return ret; 918} 919 920static int rockchip_usb3_phy_power_off(struct phy *phy) 921{ 922 struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy); 923 924 mutex_lock(&tcphy->lock); 925 tcphy_cfg_usb3_to_usb2_only(tcphy, false); 926 927 if (tcphy->mode == MODE_DISCONNECT) 928 goto unlock; 929 930 tcphy->mode &= ~(MODE_UFP_USB | MODE_DFP_USB); 931 if (tcphy->mode == MODE_DISCONNECT) 932 tcphy_phy_deinit(tcphy); 933 934unlock: 935 mutex_unlock(&tcphy->lock); 936 return 0; 937} 938 939static const struct phy_ops rockchip_usb3_phy_ops = { 940 .power_on = rockchip_usb3_phy_power_on, 941 .power_off = rockchip_usb3_phy_power_off, 942 .owner = THIS_MODULE, 943}; 944 945static int rockchip_dp_phy_power_on(struct phy *phy) 946{ 947 struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy); 948 const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs; 949 int new_mode, ret = 0; 950 u32 val; 951 952 mutex_lock(&tcphy->lock); 953 954 new_mode = tcphy_get_mode(tcphy); 955 if (new_mode < 0) { 956 ret = new_mode; 957 goto unlock_ret; 958 } 959 960 if (!(new_mode & MODE_DFP_DP)) { 961 ret = -ENODEV; 962 goto unlock_ret; 963 } 964 965 if (tcphy->mode == new_mode) 966 goto unlock_ret; 967 968 /* 969 * If the PHY has been power on, but the mode is not DP only mode, 970 * re-init the PHY for setting all of 4 lanes to DP. 971 */ 972 if (new_mode == MODE_DFP_DP && tcphy->mode != MODE_DISCONNECT) { 973 tcphy_phy_deinit(tcphy); 974 ret = tcphy_phy_init(tcphy, new_mode); 975 } else if (tcphy->mode == MODE_DISCONNECT) { 976 ret = tcphy_phy_init(tcphy, new_mode); 977 } 978 if (ret) 979 goto unlock_ret; 980 981 property_enable(tcphy, &cfg->uphy_dp_sel, 1); 982 983 ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL, 984 val, val & DP_MODE_A2, 1000, 985 PHY_MODE_SET_TIMEOUT); 986 if (ret < 0) { 987 dev_err(tcphy->dev, "failed to wait TCPHY enter A2\n"); 988 goto power_on_finish; 989 } 990 991 tcphy_dp_aux_calibration(tcphy); 992 993 writel(DP_MODE_ENTER_A0, tcphy->base + DP_MODE_CTL); 994 995 ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL, 996 val, val & DP_MODE_A0, 1000, 997 PHY_MODE_SET_TIMEOUT); 998 if (ret < 0) { 999 writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL); 1000 dev_err(tcphy->dev, "failed to wait TCPHY enter A0\n"); 1001 goto power_on_finish; 1002 } 1003 1004 tcphy->mode |= MODE_DFP_DP; 1005 1006power_on_finish: 1007 if (tcphy->mode == MODE_DISCONNECT) 1008 tcphy_phy_deinit(tcphy); 1009unlock_ret: 1010 mutex_unlock(&tcphy->lock); 1011 return ret; 1012} 1013 1014static int rockchip_dp_phy_power_off(struct phy *phy) 1015{ 1016 struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy); 1017 1018 mutex_lock(&tcphy->lock); 1019 1020 if (tcphy->mode == MODE_DISCONNECT) 1021 goto unlock; 1022 1023 tcphy->mode &= ~MODE_DFP_DP; 1024 1025 writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL); 1026 1027 if (tcphy->mode == MODE_DISCONNECT) 1028 tcphy_phy_deinit(tcphy); 1029 1030unlock: 1031 mutex_unlock(&tcphy->lock); 1032 return 0; 1033} 1034 1035static const struct phy_ops rockchip_dp_phy_ops = { 1036 .power_on = rockchip_dp_phy_power_on, 1037 .power_off = rockchip_dp_phy_power_off, 1038 .owner = THIS_MODULE, 1039}; 1040 1041static int tcphy_parse_dt(struct rockchip_typec_phy *tcphy, 1042 struct device *dev) 1043{ 1044 tcphy->grf_regs = syscon_regmap_lookup_by_phandle(dev->of_node, 1045 "rockchip,grf"); 1046 if (IS_ERR(tcphy->grf_regs)) { 1047 dev_err(dev, "could not find grf dt node\n"); 1048 return PTR_ERR(tcphy->grf_regs); 1049 } 1050 1051 tcphy->clk_core = devm_clk_get(dev, "tcpdcore"); 1052 if (IS_ERR(tcphy->clk_core)) { 1053 dev_err(dev, "could not get uphy core clock\n"); 1054 return PTR_ERR(tcphy->clk_core); 1055 } 1056 1057 tcphy->clk_ref = devm_clk_get(dev, "tcpdphy-ref"); 1058 if (IS_ERR(tcphy->clk_ref)) { 1059 dev_err(dev, "could not get uphy ref clock\n"); 1060 return PTR_ERR(tcphy->clk_ref); 1061 } 1062 1063 tcphy->uphy_rst = devm_reset_control_get(dev, "uphy"); 1064 if (IS_ERR(tcphy->uphy_rst)) { 1065 dev_err(dev, "no uphy_rst reset control found\n"); 1066 return PTR_ERR(tcphy->uphy_rst); 1067 } 1068 1069 tcphy->pipe_rst = devm_reset_control_get(dev, "uphy-pipe"); 1070 if (IS_ERR(tcphy->pipe_rst)) { 1071 dev_err(dev, "no pipe_rst reset control found\n"); 1072 return PTR_ERR(tcphy->pipe_rst); 1073 } 1074 1075 tcphy->tcphy_rst = devm_reset_control_get(dev, "uphy-tcphy"); 1076 if (IS_ERR(tcphy->tcphy_rst)) { 1077 dev_err(dev, "no tcphy_rst reset control found\n"); 1078 return PTR_ERR(tcphy->tcphy_rst); 1079 } 1080 1081 return 0; 1082} 1083 1084static void typec_phy_pre_init(struct rockchip_typec_phy *tcphy) 1085{ 1086 const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs; 1087 1088 reset_control_assert(tcphy->tcphy_rst); 1089 reset_control_assert(tcphy->uphy_rst); 1090 reset_control_assert(tcphy->pipe_rst); 1091 1092 /* select external psm clock */ 1093 property_enable(tcphy, &cfg->external_psm, 1); 1094 property_enable(tcphy, &cfg->usb3tousb2_en, 0); 1095 1096 tcphy->mode = MODE_DISCONNECT; 1097} 1098 1099static int rockchip_typec_phy_probe(struct platform_device *pdev) 1100{ 1101 struct device *dev = &pdev->dev; 1102 struct device_node *np = dev->of_node; 1103 struct device_node *child_np; 1104 struct rockchip_typec_phy *tcphy; 1105 struct phy_provider *phy_provider; 1106 struct resource *res; 1107 const struct rockchip_usb3phy_port_cfg *phy_cfgs; 1108 int index, ret; 1109 1110 tcphy = devm_kzalloc(dev, sizeof(*tcphy), GFP_KERNEL); 1111 if (!tcphy) 1112 return -ENOMEM; 1113 1114 phy_cfgs = of_device_get_match_data(dev); 1115 if (!phy_cfgs) { 1116 dev_err(dev, "phy configs are not assigned!\n"); 1117 return -EINVAL; 1118 } 1119 1120 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1121 tcphy->base = devm_ioremap_resource(dev, res); 1122 if (IS_ERR(tcphy->base)) 1123 return PTR_ERR(tcphy->base); 1124 1125 /* find out a proper config which can be matched with dt. */ 1126 index = 0; 1127 while (phy_cfgs[index].reg) { 1128 if (phy_cfgs[index].reg == res->start) { 1129 tcphy->port_cfgs = &phy_cfgs[index]; 1130 break; 1131 } 1132 1133 ++index; 1134 } 1135 1136 if (!tcphy->port_cfgs) { 1137 dev_err(dev, "no phy-config can be matched with %pOFn node\n", 1138 np); 1139 return -EINVAL; 1140 } 1141 1142 ret = tcphy_parse_dt(tcphy, dev); 1143 if (ret) 1144 return ret; 1145 1146 tcphy->dev = dev; 1147 platform_set_drvdata(pdev, tcphy); 1148 mutex_init(&tcphy->lock); 1149 1150 typec_phy_pre_init(tcphy); 1151 1152 tcphy->extcon = extcon_get_edev_by_phandle(dev, 0); 1153 if (IS_ERR(tcphy->extcon)) { 1154 if (PTR_ERR(tcphy->extcon) == -ENODEV) { 1155 tcphy->extcon = NULL; 1156 } else { 1157 if (PTR_ERR(tcphy->extcon) != -EPROBE_DEFER) 1158 dev_err(dev, "Invalid or missing extcon\n"); 1159 return PTR_ERR(tcphy->extcon); 1160 } 1161 } 1162 1163 pm_runtime_enable(dev); 1164 1165 for_each_available_child_of_node(np, child_np) { 1166 struct phy *phy; 1167 1168 if (of_node_name_eq(child_np, "dp-port")) 1169 phy = devm_phy_create(dev, child_np, 1170 &rockchip_dp_phy_ops); 1171 else if (of_node_name_eq(child_np, "usb3-port")) 1172 phy = devm_phy_create(dev, child_np, 1173 &rockchip_usb3_phy_ops); 1174 else 1175 continue; 1176 1177 if (IS_ERR(phy)) { 1178 dev_err(dev, "failed to create phy: %pOFn\n", 1179 child_np); 1180 pm_runtime_disable(dev); 1181 of_node_put(child_np); 1182 return PTR_ERR(phy); 1183 } 1184 1185 phy_set_drvdata(phy, tcphy); 1186 } 1187 1188 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 1189 if (IS_ERR(phy_provider)) { 1190 dev_err(dev, "Failed to register phy provider\n"); 1191 pm_runtime_disable(dev); 1192 return PTR_ERR(phy_provider); 1193 } 1194 1195 return 0; 1196} 1197 1198static int rockchip_typec_phy_remove(struct platform_device *pdev) 1199{ 1200 pm_runtime_disable(&pdev->dev); 1201 1202 return 0; 1203} 1204 1205static const struct of_device_id rockchip_typec_phy_dt_ids[] = { 1206 { 1207 .compatible = "rockchip,rk3399-typec-phy", 1208 .data = &rk3399_usb3phy_port_cfgs 1209 }, 1210 { /* sentinel */ } 1211}; 1212 1213MODULE_DEVICE_TABLE(of, rockchip_typec_phy_dt_ids); 1214 1215static struct platform_driver rockchip_typec_phy_driver = { 1216 .probe = rockchip_typec_phy_probe, 1217 .remove = rockchip_typec_phy_remove, 1218 .driver = { 1219 .name = "rockchip-typec-phy", 1220 .of_match_table = rockchip_typec_phy_dt_ids, 1221 }, 1222}; 1223 1224module_platform_driver(rockchip_typec_phy_driver); 1225 1226MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>"); 1227MODULE_AUTHOR("Kever Yang <kever.yang@rock-chips.com>"); 1228MODULE_DESCRIPTION("Rockchip USB TYPE-C PHY driver"); 1229MODULE_LICENSE("GPL v2");