0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 #include <linux/clk.h>
0040 #include <linux/clk-provider.h>
0041 #include <linux/delay.h>
0042 #include <linux/extcon.h>
0043 #include <linux/io.h>
0044 #include <linux/iopoll.h>
0045 #include <linux/kernel.h>
0046 #include <linux/module.h>
0047 #include <linux/mutex.h>
0048 #include <linux/of.h>
0049 #include <linux/of_address.h>
0050 #include <linux/of_platform.h>
0051 #include <linux/platform_device.h>
0052 #include <linux/regmap.h>
0053 #include <linux/reset.h>
0054
0055 #include <linux/mfd/syscon.h>
0056 #include <linux/phy/phy.h>
0057
0058 #define CMN_SSM_BANDGAP (0x21 << 2)
0059 #define CMN_SSM_BIAS (0x22 << 2)
0060 #define CMN_PLLSM0_PLLEN (0x29 << 2)
0061 #define CMN_PLLSM0_PLLPRE (0x2a << 2)
0062 #define CMN_PLLSM0_PLLVREF (0x2b << 2)
0063 #define CMN_PLLSM0_PLLLOCK (0x2c << 2)
0064 #define CMN_PLLSM1_PLLEN (0x31 << 2)
0065 #define CMN_PLLSM1_PLLPRE (0x32 << 2)
0066 #define CMN_PLLSM1_PLLVREF (0x33 << 2)
0067 #define CMN_PLLSM1_PLLLOCK (0x34 << 2)
0068 #define CMN_PLLSM1_USER_DEF_CTRL (0x37 << 2)
0069 #define CMN_ICAL_OVRD (0xc1 << 2)
0070 #define CMN_PLL0_VCOCAL_OVRD (0x83 << 2)
0071 #define CMN_PLL0_VCOCAL_INIT (0x84 << 2)
0072 #define CMN_PLL0_VCOCAL_ITER (0x85 << 2)
0073 #define CMN_PLL0_LOCK_REFCNT_START (0x90 << 2)
0074 #define CMN_PLL0_LOCK_PLLCNT_START (0x92 << 2)
0075 #define CMN_PLL0_LOCK_PLLCNT_THR (0x93 << 2)
0076 #define CMN_PLL0_INTDIV (0x94 << 2)
0077 #define CMN_PLL0_FRACDIV (0x95 << 2)
0078 #define CMN_PLL0_HIGH_THR (0x96 << 2)
0079 #define CMN_PLL0_DSM_DIAG (0x97 << 2)
0080 #define CMN_PLL0_SS_CTRL1 (0x98 << 2)
0081 #define CMN_PLL0_SS_CTRL2 (0x99 << 2)
0082 #define CMN_PLL1_VCOCAL_START (0xa1 << 2)
0083 #define CMN_PLL1_VCOCAL_OVRD (0xa3 << 2)
0084 #define CMN_PLL1_VCOCAL_INIT (0xa4 << 2)
0085 #define CMN_PLL1_VCOCAL_ITER (0xa5 << 2)
0086 #define CMN_PLL1_LOCK_REFCNT_START (0xb0 << 2)
0087 #define CMN_PLL1_LOCK_PLLCNT_START (0xb2 << 2)
0088 #define CMN_PLL1_LOCK_PLLCNT_THR (0xb3 << 2)
0089 #define CMN_PLL1_INTDIV (0xb4 << 2)
0090 #define CMN_PLL1_FRACDIV (0xb5 << 2)
0091 #define CMN_PLL1_HIGH_THR (0xb6 << 2)
0092 #define CMN_PLL1_DSM_DIAG (0xb7 << 2)
0093 #define CMN_PLL1_SS_CTRL1 (0xb8 << 2)
0094 #define CMN_PLL1_SS_CTRL2 (0xb9 << 2)
0095 #define CMN_RXCAL_OVRD (0xd1 << 2)
0096
0097 #define CMN_TXPUCAL_CTRL (0xe0 << 2)
0098 #define CMN_TXPUCAL_OVRD (0xe1 << 2)
0099 #define CMN_TXPDCAL_CTRL (0xf0 << 2)
0100 #define CMN_TXPDCAL_OVRD (0xf1 << 2)
0101
0102
0103 #define CMN_TXPXCAL_START BIT(15)
0104 #define CMN_TXPXCAL_DONE BIT(14)
0105 #define CMN_TXPXCAL_NO_RESPONSE BIT(13)
0106 #define CMN_TXPXCAL_CURRENT_RESPONSE BIT(12)
0107
0108 #define CMN_TXPU_ADJ_CTRL (0x108 << 2)
0109 #define CMN_TXPD_ADJ_CTRL (0x10c << 2)
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120 #define CMN_CALIB_CODE_WIDTH 7
0121 #define CMN_CALIB_CODE_OFFSET 0
0122 #define CMN_CALIB_CODE_MASK GENMASK(CMN_CALIB_CODE_WIDTH, 0)
0123 #define CMN_CALIB_CODE(x) \
0124 sign_extend32((x) >> CMN_CALIB_CODE_OFFSET, CMN_CALIB_CODE_WIDTH)
0125
0126 #define CMN_CALIB_CODE_POS_MASK GENMASK(CMN_CALIB_CODE_WIDTH - 1, 0)
0127 #define CMN_CALIB_CODE_POS(x) \
0128 (((x) >> CMN_CALIB_CODE_OFFSET) & CMN_CALIB_CODE_POS_MASK)
0129
0130 #define CMN_DIAG_PLL0_FBH_OVRD (0x1c0 << 2)
0131 #define CMN_DIAG_PLL0_FBL_OVRD (0x1c1 << 2)
0132 #define CMN_DIAG_PLL0_OVRD (0x1c2 << 2)
0133 #define CMN_DIAG_PLL0_V2I_TUNE (0x1c5 << 2)
0134 #define CMN_DIAG_PLL0_CP_TUNE (0x1c6 << 2)
0135 #define CMN_DIAG_PLL0_LF_PROG (0x1c7 << 2)
0136 #define CMN_DIAG_PLL1_FBH_OVRD (0x1d0 << 2)
0137 #define CMN_DIAG_PLL1_FBL_OVRD (0x1d1 << 2)
0138 #define CMN_DIAG_PLL1_OVRD (0x1d2 << 2)
0139 #define CMN_DIAG_PLL1_V2I_TUNE (0x1d5 << 2)
0140 #define CMN_DIAG_PLL1_CP_TUNE (0x1d6 << 2)
0141 #define CMN_DIAG_PLL1_LF_PROG (0x1d7 << 2)
0142 #define CMN_DIAG_PLL1_PTATIS_TUNE1 (0x1d8 << 2)
0143 #define CMN_DIAG_PLL1_PTATIS_TUNE2 (0x1d9 << 2)
0144 #define CMN_DIAG_PLL1_INCLK_CTRL (0x1da << 2)
0145 #define CMN_DIAG_HSCLK_SEL (0x1e0 << 2)
0146
0147 #define XCVR_PSM_RCTRL(n) ((0x4001 | ((n) << 9)) << 2)
0148 #define XCVR_PSM_CAL_TMR(n) ((0x4002 | ((n) << 9)) << 2)
0149 #define XCVR_PSM_A0IN_TMR(n) ((0x4003 | ((n) << 9)) << 2)
0150 #define TX_TXCC_CAL_SCLR_MULT(n) ((0x4047 | ((n) << 9)) << 2)
0151 #define TX_TXCC_CPOST_MULT_00(n) ((0x404c | ((n) << 9)) << 2)
0152 #define TX_TXCC_CPOST_MULT_01(n) ((0x404d | ((n) << 9)) << 2)
0153 #define TX_TXCC_CPOST_MULT_10(n) ((0x404e | ((n) << 9)) << 2)
0154 #define TX_TXCC_CPOST_MULT_11(n) ((0x404f | ((n) << 9)) << 2)
0155 #define TX_TXCC_MGNFS_MULT_000(n) ((0x4050 | ((n) << 9)) << 2)
0156 #define TX_TXCC_MGNFS_MULT_001(n) ((0x4051 | ((n) << 9)) << 2)
0157 #define TX_TXCC_MGNFS_MULT_010(n) ((0x4052 | ((n) << 9)) << 2)
0158 #define TX_TXCC_MGNFS_MULT_011(n) ((0x4053 | ((n) << 9)) << 2)
0159 #define TX_TXCC_MGNFS_MULT_100(n) ((0x4054 | ((n) << 9)) << 2)
0160 #define TX_TXCC_MGNFS_MULT_101(n) ((0x4055 | ((n) << 9)) << 2)
0161 #define TX_TXCC_MGNFS_MULT_110(n) ((0x4056 | ((n) << 9)) << 2)
0162 #define TX_TXCC_MGNFS_MULT_111(n) ((0x4057 | ((n) << 9)) << 2)
0163 #define TX_TXCC_MGNLS_MULT_000(n) ((0x4058 | ((n) << 9)) << 2)
0164 #define TX_TXCC_MGNLS_MULT_001(n) ((0x4059 | ((n) << 9)) << 2)
0165 #define TX_TXCC_MGNLS_MULT_010(n) ((0x405a | ((n) << 9)) << 2)
0166 #define TX_TXCC_MGNLS_MULT_011(n) ((0x405b | ((n) << 9)) << 2)
0167 #define TX_TXCC_MGNLS_MULT_100(n) ((0x405c | ((n) << 9)) << 2)
0168 #define TX_TXCC_MGNLS_MULT_101(n) ((0x405d | ((n) << 9)) << 2)
0169 #define TX_TXCC_MGNLS_MULT_110(n) ((0x405e | ((n) << 9)) << 2)
0170 #define TX_TXCC_MGNLS_MULT_111(n) ((0x405f | ((n) << 9)) << 2)
0171
0172 #define XCVR_DIAG_PLLDRC_CTRL(n) ((0x40e0 | ((n) << 9)) << 2)
0173 #define XCVR_DIAG_BIDI_CTRL(n) ((0x40e8 | ((n) << 9)) << 2)
0174 #define XCVR_DIAG_LANE_FCM_EN_MGN(n) ((0x40f2 | ((n) << 9)) << 2)
0175 #define TX_PSC_A0(n) ((0x4100 | ((n) << 9)) << 2)
0176 #define TX_PSC_A1(n) ((0x4101 | ((n) << 9)) << 2)
0177 #define TX_PSC_A2(n) ((0x4102 | ((n) << 9)) << 2)
0178 #define TX_PSC_A3(n) ((0x4103 | ((n) << 9)) << 2)
0179 #define TX_RCVDET_CTRL(n) ((0x4120 | ((n) << 9)) << 2)
0180 #define TX_RCVDET_EN_TMR(n) ((0x4122 | ((n) << 9)) << 2)
0181 #define TX_RCVDET_ST_TMR(n) ((0x4123 | ((n) << 9)) << 2)
0182 #define TX_DIAG_TX_DRV(n) ((0x41e1 | ((n) << 9)) << 2)
0183 #define TX_DIAG_BGREF_PREDRV_DELAY (0x41e7 << 2)
0184
0185
0186 #define AUX_CH_LANE 8
0187
0188 #define TX_ANA_CTRL_REG_1 (0x5020 << 2)
0189
0190 #define TXDA_DP_AUX_EN BIT(15)
0191 #define AUXDA_SE_EN BIT(14)
0192 #define TXDA_CAL_LATCH_EN BIT(13)
0193 #define AUXDA_POLARITY BIT(12)
0194 #define TXDA_DRV_POWER_ISOLATION_EN BIT(11)
0195 #define TXDA_DRV_POWER_EN_PH_2_N BIT(10)
0196 #define TXDA_DRV_POWER_EN_PH_1_N BIT(9)
0197 #define TXDA_BGREF_EN BIT(8)
0198 #define TXDA_DRV_LDO_EN BIT(7)
0199 #define TXDA_DECAP_EN_DEL BIT(6)
0200 #define TXDA_DECAP_EN BIT(5)
0201 #define TXDA_UPHY_SUPPLY_EN_DEL BIT(4)
0202 #define TXDA_UPHY_SUPPLY_EN BIT(3)
0203 #define TXDA_LOW_LEAKAGE_EN BIT(2)
0204 #define TXDA_DRV_IDLE_LOWI_EN BIT(1)
0205 #define TXDA_DRV_CMN_MODE_EN BIT(0)
0206
0207 #define TX_ANA_CTRL_REG_2 (0x5021 << 2)
0208
0209 #define AUXDA_DEBOUNCING_CLK BIT(15)
0210 #define TXDA_LPBK_RECOVERED_CLK_EN BIT(14)
0211 #define TXDA_LPBK_ISI_GEN_EN BIT(13)
0212 #define TXDA_LPBK_SERIAL_EN BIT(12)
0213 #define TXDA_LPBK_LINE_EN BIT(11)
0214 #define TXDA_DRV_LDO_REDC_SINKIQ BIT(10)
0215 #define XCVR_DECAP_EN_DEL BIT(9)
0216 #define XCVR_DECAP_EN BIT(8)
0217 #define TXDA_MPHY_ENABLE_HS_NT BIT(7)
0218 #define TXDA_MPHY_SA_MODE BIT(6)
0219 #define TXDA_DRV_LDO_RBYR_FB_EN BIT(5)
0220 #define TXDA_DRV_RST_PULL_DOWN BIT(4)
0221 #define TXDA_DRV_LDO_BG_FB_EN BIT(3)
0222 #define TXDA_DRV_LDO_BG_REF_EN BIT(2)
0223 #define TXDA_DRV_PREDRV_EN_DEL BIT(1)
0224 #define TXDA_DRV_PREDRV_EN BIT(0)
0225
0226 #define TXDA_COEFF_CALC_CTRL (0x5022 << 2)
0227
0228 #define TX_HIGH_Z BIT(6)
0229 #define TX_VMARGIN_OFFSET 3
0230 #define TX_VMARGIN_MASK 0x7
0231 #define LOW_POWER_SWING_EN BIT(2)
0232 #define TX_FCM_DRV_MAIN_EN BIT(1)
0233 #define TX_FCM_FULL_MARGIN BIT(0)
0234
0235 #define TX_DIG_CTRL_REG_2 (0x5024 << 2)
0236
0237 #define TX_HIGH_Z_TM_EN BIT(15)
0238 #define TX_RESCAL_CODE_OFFSET 0
0239 #define TX_RESCAL_CODE_MASK 0x3f
0240
0241 #define TXDA_CYA_AUXDA_CYA (0x5025 << 2)
0242 #define TX_ANA_CTRL_REG_3 (0x5026 << 2)
0243 #define TX_ANA_CTRL_REG_4 (0x5027 << 2)
0244 #define TX_ANA_CTRL_REG_5 (0x5029 << 2)
0245
0246 #define RX_PSC_A0(n) ((0x8000 | ((n) << 9)) << 2)
0247 #define RX_PSC_A1(n) ((0x8001 | ((n) << 9)) << 2)
0248 #define RX_PSC_A2(n) ((0x8002 | ((n) << 9)) << 2)
0249 #define RX_PSC_A3(n) ((0x8003 | ((n) << 9)) << 2)
0250 #define RX_PSC_CAL(n) ((0x8006 | ((n) << 9)) << 2)
0251 #define RX_PSC_RDY(n) ((0x8007 | ((n) << 9)) << 2)
0252 #define RX_IQPI_ILL_CAL_OVRD (0x8023 << 2)
0253 #define RX_EPI_ILL_CAL_OVRD (0x8033 << 2)
0254 #define RX_SDCAL0_OVRD (0x8041 << 2)
0255 #define RX_SDCAL1_OVRD (0x8049 << 2)
0256 #define RX_SLC_INIT (0x806d << 2)
0257 #define RX_SLC_RUN (0x806e << 2)
0258 #define RX_CDRLF_CNFG2 (0x8081 << 2)
0259 #define RX_SIGDET_HL_FILT_TMR(n) ((0x8090 | ((n) << 9)) << 2)
0260 #define RX_SLC_IOP0_OVRD (0x8101 << 2)
0261 #define RX_SLC_IOP1_OVRD (0x8105 << 2)
0262 #define RX_SLC_QOP0_OVRD (0x8109 << 2)
0263 #define RX_SLC_QOP1_OVRD (0x810d << 2)
0264 #define RX_SLC_EOP0_OVRD (0x8111 << 2)
0265 #define RX_SLC_EOP1_OVRD (0x8115 << 2)
0266 #define RX_SLC_ION0_OVRD (0x8119 << 2)
0267 #define RX_SLC_ION1_OVRD (0x811d << 2)
0268 #define RX_SLC_QON0_OVRD (0x8121 << 2)
0269 #define RX_SLC_QON1_OVRD (0x8125 << 2)
0270 #define RX_SLC_EON0_OVRD (0x8129 << 2)
0271 #define RX_SLC_EON1_OVRD (0x812d << 2)
0272 #define RX_SLC_IEP0_OVRD (0x8131 << 2)
0273 #define RX_SLC_IEP1_OVRD (0x8135 << 2)
0274 #define RX_SLC_QEP0_OVRD (0x8139 << 2)
0275 #define RX_SLC_QEP1_OVRD (0x813d << 2)
0276 #define RX_SLC_EEP0_OVRD (0x8141 << 2)
0277 #define RX_SLC_EEP1_OVRD (0x8145 << 2)
0278 #define RX_SLC_IEN0_OVRD (0x8149 << 2)
0279 #define RX_SLC_IEN1_OVRD (0x814d << 2)
0280 #define RX_SLC_QEN0_OVRD (0x8151 << 2)
0281 #define RX_SLC_QEN1_OVRD (0x8155 << 2)
0282 #define RX_SLC_EEN0_OVRD (0x8159 << 2)
0283 #define RX_SLC_EEN1_OVRD (0x815d << 2)
0284 #define RX_REE_CTRL_DATA_MASK(n) ((0x81bb | ((n) << 9)) << 2)
0285 #define RX_DIAG_SIGDET_TUNE(n) ((0x81dc | ((n) << 9)) << 2)
0286 #define RX_DIAG_SC2C_DELAY (0x81e1 << 2)
0287
0288 #define PMA_LANE_CFG (0xc000 << 2)
0289 #define PIPE_CMN_CTRL1 (0xc001 << 2)
0290 #define PIPE_CMN_CTRL2 (0xc002 << 2)
0291 #define PIPE_COM_LOCK_CFG1 (0xc003 << 2)
0292 #define PIPE_COM_LOCK_CFG2 (0xc004 << 2)
0293 #define PIPE_RCV_DET_INH (0xc005 << 2)
0294 #define DP_MODE_CTL (0xc008 << 2)
0295 #define DP_CLK_CTL (0xc009 << 2)
0296 #define STS (0xc00F << 2)
0297 #define PHY_ISO_CMN_CTRL (0xc010 << 2)
0298 #define PHY_DP_TX_CTL (0xc408 << 2)
0299 #define PMA_CMN_CTRL1 (0xc800 << 2)
0300 #define PHY_PMA_ISO_CMN_CTRL (0xc810 << 2)
0301 #define PHY_ISOLATION_CTRL (0xc81f << 2)
0302 #define PHY_PMA_ISO_XCVR_CTRL(n) ((0xcc11 | ((n) << 6)) << 2)
0303 #define PHY_PMA_ISO_LINK_MODE(n) ((0xcc12 | ((n) << 6)) << 2)
0304 #define PHY_PMA_ISO_PWRST_CTRL(n) ((0xcc13 | ((n) << 6)) << 2)
0305 #define PHY_PMA_ISO_TX_DATA_LO(n) ((0xcc14 | ((n) << 6)) << 2)
0306 #define PHY_PMA_ISO_TX_DATA_HI(n) ((0xcc15 | ((n) << 6)) << 2)
0307 #define PHY_PMA_ISO_RX_DATA_LO(n) ((0xcc16 | ((n) << 6)) << 2)
0308 #define PHY_PMA_ISO_RX_DATA_HI(n) ((0xcc17 | ((n) << 6)) << 2)
0309 #define TX_BIST_CTRL(n) ((0x4140 | ((n) << 9)) << 2)
0310 #define TX_BIST_UDDWR(n) ((0x4141 | ((n) << 9)) << 2)
0311
0312
0313
0314
0315
0316
0317 #define CLK_PLL_CONFIG 0X30
0318 #define CLK_PLL_MASK 0x33
0319
0320 #define CMN_READY BIT(0)
0321
0322 #define DP_PLL_CLOCK_ENABLE BIT(2)
0323 #define DP_PLL_ENABLE BIT(0)
0324 #define DP_PLL_DATA_RATE_RBR ((2 << 12) | (4 << 8))
0325 #define DP_PLL_DATA_RATE_HBR ((2 << 12) | (4 << 8))
0326 #define DP_PLL_DATA_RATE_HBR2 ((1 << 12) | (2 << 8))
0327
0328 #define DP_MODE_A0 BIT(4)
0329 #define DP_MODE_A2 BIT(6)
0330 #define DP_MODE_ENTER_A0 0xc101
0331 #define DP_MODE_ENTER_A2 0xc104
0332
0333 #define PHY_MODE_SET_TIMEOUT 100000
0334
0335 #define PIN_ASSIGN_C_E 0x51d9
0336 #define PIN_ASSIGN_D_F 0x5100
0337
0338 #define MODE_DISCONNECT 0
0339 #define MODE_UFP_USB BIT(0)
0340 #define MODE_DFP_USB BIT(1)
0341 #define MODE_DFP_DP BIT(2)
0342
0343 struct usb3phy_reg {
0344 u32 offset;
0345 u32 enable_bit;
0346 u32 write_enable;
0347 };
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360 struct rockchip_usb3phy_port_cfg {
0361 unsigned int reg;
0362 struct usb3phy_reg typec_conn_dir;
0363 struct usb3phy_reg usb3tousb2_en;
0364 struct usb3phy_reg external_psm;
0365 struct usb3phy_reg pipe_status;
0366 struct usb3phy_reg usb3_host_disable;
0367 struct usb3phy_reg usb3_host_port;
0368 struct usb3phy_reg uphy_dp_sel;
0369 };
0370
0371 struct rockchip_typec_phy {
0372 struct device *dev;
0373 void __iomem *base;
0374 struct extcon_dev *extcon;
0375 struct regmap *grf_regs;
0376 struct clk *clk_core;
0377 struct clk *clk_ref;
0378 struct reset_control *uphy_rst;
0379 struct reset_control *pipe_rst;
0380 struct reset_control *tcphy_rst;
0381 const struct rockchip_usb3phy_port_cfg *port_cfgs;
0382
0383 struct mutex lock;
0384
0385 bool flip;
0386 u8 mode;
0387 };
0388
0389 struct phy_reg {
0390 u16 value;
0391 u32 addr;
0392 };
0393
0394 static struct phy_reg usb3_pll_cfg[] = {
0395 { 0xf0, CMN_PLL0_VCOCAL_INIT },
0396 { 0x18, CMN_PLL0_VCOCAL_ITER },
0397 { 0xd0, CMN_PLL0_INTDIV },
0398 { 0x4a4a, CMN_PLL0_FRACDIV },
0399 { 0x34, CMN_PLL0_HIGH_THR },
0400 { 0x1ee, CMN_PLL0_SS_CTRL1 },
0401 { 0x7f03, CMN_PLL0_SS_CTRL2 },
0402 { 0x20, CMN_PLL0_DSM_DIAG },
0403 { 0, CMN_DIAG_PLL0_OVRD },
0404 { 0, CMN_DIAG_PLL0_FBH_OVRD },
0405 { 0, CMN_DIAG_PLL0_FBL_OVRD },
0406 { 0x7, CMN_DIAG_PLL0_V2I_TUNE },
0407 { 0x45, CMN_DIAG_PLL0_CP_TUNE },
0408 { 0x8, CMN_DIAG_PLL0_LF_PROG },
0409 };
0410
0411 static struct phy_reg dp_pll_cfg[] = {
0412 { 0xf0, CMN_PLL1_VCOCAL_INIT },
0413 { 0x18, CMN_PLL1_VCOCAL_ITER },
0414 { 0x30b9, CMN_PLL1_VCOCAL_START },
0415 { 0x21c, CMN_PLL1_INTDIV },
0416 { 0, CMN_PLL1_FRACDIV },
0417 { 0x5, CMN_PLL1_HIGH_THR },
0418 { 0x35, CMN_PLL1_SS_CTRL1 },
0419 { 0x7f1e, CMN_PLL1_SS_CTRL2 },
0420 { 0x20, CMN_PLL1_DSM_DIAG },
0421 { 0, CMN_PLLSM1_USER_DEF_CTRL },
0422 { 0, CMN_DIAG_PLL1_OVRD },
0423 { 0, CMN_DIAG_PLL1_FBH_OVRD },
0424 { 0, CMN_DIAG_PLL1_FBL_OVRD },
0425 { 0x6, CMN_DIAG_PLL1_V2I_TUNE },
0426 { 0x45, CMN_DIAG_PLL1_CP_TUNE },
0427 { 0x8, CMN_DIAG_PLL1_LF_PROG },
0428 { 0x100, CMN_DIAG_PLL1_PTATIS_TUNE1 },
0429 { 0x7, CMN_DIAG_PLL1_PTATIS_TUNE2 },
0430 { 0x4, CMN_DIAG_PLL1_INCLK_CTRL },
0431 };
0432
0433 static const struct rockchip_usb3phy_port_cfg rk3399_usb3phy_port_cfgs[] = {
0434 {
0435 .reg = 0xff7c0000,
0436 .typec_conn_dir = { 0xe580, 0, 16 },
0437 .usb3tousb2_en = { 0xe580, 3, 19 },
0438 .external_psm = { 0xe588, 14, 30 },
0439 .pipe_status = { 0xe5c0, 0, 0 },
0440 .usb3_host_disable = { 0x2434, 0, 16 },
0441 .usb3_host_port = { 0x2434, 12, 28 },
0442 .uphy_dp_sel = { 0x6268, 19, 19 },
0443 },
0444 {
0445 .reg = 0xff800000,
0446 .typec_conn_dir = { 0xe58c, 0, 16 },
0447 .usb3tousb2_en = { 0xe58c, 3, 19 },
0448 .external_psm = { 0xe594, 14, 30 },
0449 .pipe_status = { 0xe5c0, 16, 16 },
0450 .usb3_host_disable = { 0x2444, 0, 16 },
0451 .usb3_host_port = { 0x2444, 12, 28 },
0452 .uphy_dp_sel = { 0x6268, 3, 19 },
0453 },
0454 { }
0455 };
0456
0457 static void tcphy_cfg_24m(struct rockchip_typec_phy *tcphy)
0458 {
0459 u32 i, rdata;
0460
0461
0462
0463
0464
0465 writel(0x830, tcphy->base + PMA_CMN_CTRL1);
0466 for (i = 0; i < 4; i++) {
0467
0468
0469
0470
0471 writel(0x90, tcphy->base + XCVR_DIAG_LANE_FCM_EN_MGN(i));
0472 writel(0x960, tcphy->base + TX_RCVDET_EN_TMR(i));
0473 writel(0x30, tcphy->base + TX_RCVDET_ST_TMR(i));
0474 }
0475
0476 rdata = readl(tcphy->base + CMN_DIAG_HSCLK_SEL);
0477 rdata &= ~CLK_PLL_MASK;
0478 rdata |= CLK_PLL_CONFIG;
0479 writel(rdata, tcphy->base + CMN_DIAG_HSCLK_SEL);
0480 }
0481
0482 static void tcphy_cfg_usb3_pll(struct rockchip_typec_phy *tcphy)
0483 {
0484 u32 i;
0485
0486
0487 for (i = 0; i < ARRAY_SIZE(usb3_pll_cfg); i++)
0488 writel(usb3_pll_cfg[i].value,
0489 tcphy->base + usb3_pll_cfg[i].addr);
0490 }
0491
0492 static void tcphy_cfg_dp_pll(struct rockchip_typec_phy *tcphy)
0493 {
0494 u32 i;
0495
0496
0497 writel(DP_PLL_CLOCK_ENABLE | DP_PLL_ENABLE | DP_PLL_DATA_RATE_RBR,
0498 tcphy->base + DP_CLK_CTL);
0499
0500
0501 for (i = 0; i < ARRAY_SIZE(dp_pll_cfg); i++)
0502 writel(dp_pll_cfg[i].value, tcphy->base + dp_pll_cfg[i].addr);
0503 }
0504
0505 static void tcphy_tx_usb3_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane)
0506 {
0507 writel(0x7799, tcphy->base + TX_PSC_A0(lane));
0508 writel(0x7798, tcphy->base + TX_PSC_A1(lane));
0509 writel(0x5098, tcphy->base + TX_PSC_A2(lane));
0510 writel(0x5098, tcphy->base + TX_PSC_A3(lane));
0511 writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_000(lane));
0512 writel(0xbf, tcphy->base + XCVR_DIAG_BIDI_CTRL(lane));
0513 }
0514
0515 static void tcphy_rx_usb3_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane)
0516 {
0517 writel(0xa6fd, tcphy->base + RX_PSC_A0(lane));
0518 writel(0xa6fd, tcphy->base + RX_PSC_A1(lane));
0519 writel(0xa410, tcphy->base + RX_PSC_A2(lane));
0520 writel(0x2410, tcphy->base + RX_PSC_A3(lane));
0521 writel(0x23ff, tcphy->base + RX_PSC_CAL(lane));
0522 writel(0x13, tcphy->base + RX_SIGDET_HL_FILT_TMR(lane));
0523 writel(0x03e7, tcphy->base + RX_REE_CTRL_DATA_MASK(lane));
0524 writel(0x1004, tcphy->base + RX_DIAG_SIGDET_TUNE(lane));
0525 writel(0x2010, tcphy->base + RX_PSC_RDY(lane));
0526 writel(0xfb, tcphy->base + XCVR_DIAG_BIDI_CTRL(lane));
0527 }
0528
0529 static void tcphy_dp_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane)
0530 {
0531 u16 rdata;
0532
0533 writel(0xbefc, tcphy->base + XCVR_PSM_RCTRL(lane));
0534 writel(0x6799, tcphy->base + TX_PSC_A0(lane));
0535 writel(0x6798, tcphy->base + TX_PSC_A1(lane));
0536 writel(0x98, tcphy->base + TX_PSC_A2(lane));
0537 writel(0x98, tcphy->base + TX_PSC_A3(lane));
0538
0539 writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_000(lane));
0540 writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_001(lane));
0541 writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_010(lane));
0542 writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_011(lane));
0543 writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_100(lane));
0544 writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_101(lane));
0545 writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_110(lane));
0546 writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_111(lane));
0547 writel(0, tcphy->base + TX_TXCC_CPOST_MULT_10(lane));
0548 writel(0, tcphy->base + TX_TXCC_CPOST_MULT_01(lane));
0549 writel(0, tcphy->base + TX_TXCC_CPOST_MULT_00(lane));
0550 writel(0, tcphy->base + TX_TXCC_CPOST_MULT_11(lane));
0551
0552 writel(0x128, tcphy->base + TX_TXCC_CAL_SCLR_MULT(lane));
0553 writel(0x400, tcphy->base + TX_DIAG_TX_DRV(lane));
0554
0555 rdata = readl(tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane));
0556 rdata = (rdata & 0x8fff) | 0x6000;
0557 writel(rdata, tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane));
0558 }
0559
0560 static inline int property_enable(struct rockchip_typec_phy *tcphy,
0561 const struct usb3phy_reg *reg, bool en)
0562 {
0563 u32 mask = 1 << reg->write_enable;
0564 u32 val = en << reg->enable_bit;
0565
0566 return regmap_write(tcphy->grf_regs, reg->offset, val | mask);
0567 }
0568
0569 static void tcphy_dp_aux_set_flip(struct rockchip_typec_phy *tcphy)
0570 {
0571 u16 tx_ana_ctrl_reg_1;
0572
0573
0574
0575
0576
0577
0578
0579
0580 tx_ana_ctrl_reg_1 = readl(tcphy->base + TX_ANA_CTRL_REG_1);
0581 if (!tcphy->flip)
0582 tx_ana_ctrl_reg_1 |= AUXDA_POLARITY;
0583 else
0584 tx_ana_ctrl_reg_1 &= ~AUXDA_POLARITY;
0585 writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
0586 }
0587
0588 static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy)
0589 {
0590 u16 val;
0591 u16 tx_ana_ctrl_reg_1;
0592 u16 tx_ana_ctrl_reg_2;
0593 s32 pu_calib_code, pd_calib_code;
0594 s32 pu_adj, pd_adj;
0595 u16 calib;
0596
0597
0598
0599
0600
0601 val = readl(tcphy->base + CMN_TXPUCAL_CTRL);
0602 pu_calib_code = CMN_CALIB_CODE_POS(val);
0603 val = readl(tcphy->base + CMN_TXPDCAL_CTRL);
0604 pd_calib_code = CMN_CALIB_CODE_POS(val);
0605 val = readl(tcphy->base + CMN_TXPU_ADJ_CTRL);
0606 pu_adj = CMN_CALIB_CODE(val);
0607 val = readl(tcphy->base + CMN_TXPD_ADJ_CTRL);
0608 pd_adj = CMN_CALIB_CODE(val);
0609 calib = (pu_calib_code + pd_calib_code) / 2 + pu_adj + pd_adj;
0610
0611
0612 tx_ana_ctrl_reg_1 = readl(tcphy->base + TX_ANA_CTRL_REG_1);
0613 tx_ana_ctrl_reg_1 &= ~TXDA_CAL_LATCH_EN;
0614 writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
0615
0616
0617 val = readl(tcphy->base + TX_DIG_CTRL_REG_2);
0618 val &= ~(TX_RESCAL_CODE_MASK << TX_RESCAL_CODE_OFFSET);
0619 val |= calib << TX_RESCAL_CODE_OFFSET;
0620 writel(val, tcphy->base + TX_DIG_CTRL_REG_2);
0621 usleep_range(10000, 10050);
0622
0623
0624
0625
0626
0627
0628 tx_ana_ctrl_reg_1 |= TXDA_CAL_LATCH_EN;
0629 writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
0630 usleep_range(150, 200);
0631
0632
0633 writel(0, tcphy->base + PHY_DP_TX_CTL);
0634
0635
0636 tx_ana_ctrl_reg_2 = XCVR_DECAP_EN;
0637 writel(tx_ana_ctrl_reg_2, tcphy->base + TX_ANA_CTRL_REG_2);
0638 udelay(1);
0639 tx_ana_ctrl_reg_2 |= XCVR_DECAP_EN_DEL;
0640 writel(tx_ana_ctrl_reg_2, tcphy->base + TX_ANA_CTRL_REG_2);
0641
0642 writel(0, tcphy->base + TX_ANA_CTRL_REG_3);
0643
0644 tx_ana_ctrl_reg_1 |= TXDA_UPHY_SUPPLY_EN;
0645 writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
0646 udelay(1);
0647 tx_ana_ctrl_reg_1 |= TXDA_UPHY_SUPPLY_EN_DEL;
0648 writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
0649
0650 writel(0, tcphy->base + TX_ANA_CTRL_REG_5);
0651
0652
0653
0654
0655
0656 writel(0x1001, tcphy->base + TX_ANA_CTRL_REG_4);
0657
0658
0659 tx_ana_ctrl_reg_1 |= TXDA_DRV_LDO_EN;
0660 writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
0661 udelay(5);
0662 tx_ana_ctrl_reg_1 |= TXDA_BGREF_EN;
0663 writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
0664
0665
0666
0667
0668
0669 tx_ana_ctrl_reg_2 |= TXDA_DRV_PREDRV_EN;
0670 writel(tx_ana_ctrl_reg_2, tcphy->base + TX_ANA_CTRL_REG_2);
0671 udelay(1);
0672 tx_ana_ctrl_reg_2 |= TXDA_DRV_PREDRV_EN_DEL;
0673 writel(tx_ana_ctrl_reg_2, tcphy->base + TX_ANA_CTRL_REG_2);
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686 tx_ana_ctrl_reg_1 |= TXDA_DP_AUX_EN;
0687 tx_ana_ctrl_reg_1 |= TXDA_DECAP_EN;
0688 tx_ana_ctrl_reg_1 &= ~TXDA_DRV_LDO_EN;
0689 tx_ana_ctrl_reg_1 &= ~TXDA_BGREF_EN;
0690 writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
0691 udelay(1);
0692 tx_ana_ctrl_reg_1 |= TXDA_DECAP_EN_DEL;
0693 writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
0694
0695
0696
0697
0698
0699
0700 writel(0, tcphy->base + TX_ANA_CTRL_REG_4);
0701
0702
0703 writel(0, tcphy->base + TXDA_COEFF_CALC_CTRL);
0704
0705
0706 writel(0, tcphy->base + TXDA_CYA_AUXDA_CYA);
0707
0708
0709
0710
0711
0712
0713
0714
0715
0716
0717 val = readl(tcphy->base + TX_DIG_CTRL_REG_2);
0718 val |= TX_HIGH_Z_TM_EN;
0719 writel(val, tcphy->base + TX_DIG_CTRL_REG_2);
0720 }
0721
0722 static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode)
0723 {
0724 const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs;
0725 int ret, i;
0726 u32 val;
0727
0728 ret = clk_prepare_enable(tcphy->clk_core);
0729 if (ret) {
0730 dev_err(tcphy->dev, "Failed to prepare_enable core clock\n");
0731 return ret;
0732 }
0733
0734 ret = clk_prepare_enable(tcphy->clk_ref);
0735 if (ret) {
0736 dev_err(tcphy->dev, "Failed to prepare_enable ref clock\n");
0737 goto err_clk_core;
0738 }
0739
0740 reset_control_deassert(tcphy->tcphy_rst);
0741
0742 property_enable(tcphy, &cfg->typec_conn_dir, tcphy->flip);
0743 tcphy_dp_aux_set_flip(tcphy);
0744
0745 tcphy_cfg_24m(tcphy);
0746
0747 if (mode == MODE_DFP_DP) {
0748 tcphy_cfg_dp_pll(tcphy);
0749 for (i = 0; i < 4; i++)
0750 tcphy_dp_cfg_lane(tcphy, i);
0751
0752 writel(PIN_ASSIGN_C_E, tcphy->base + PMA_LANE_CFG);
0753 } else {
0754 tcphy_cfg_usb3_pll(tcphy);
0755 tcphy_cfg_dp_pll(tcphy);
0756 if (tcphy->flip) {
0757 tcphy_tx_usb3_cfg_lane(tcphy, 3);
0758 tcphy_rx_usb3_cfg_lane(tcphy, 2);
0759 tcphy_dp_cfg_lane(tcphy, 0);
0760 tcphy_dp_cfg_lane(tcphy, 1);
0761 } else {
0762 tcphy_tx_usb3_cfg_lane(tcphy, 0);
0763 tcphy_rx_usb3_cfg_lane(tcphy, 1);
0764 tcphy_dp_cfg_lane(tcphy, 2);
0765 tcphy_dp_cfg_lane(tcphy, 3);
0766 }
0767
0768 writel(PIN_ASSIGN_D_F, tcphy->base + PMA_LANE_CFG);
0769 }
0770
0771 writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
0772
0773 reset_control_deassert(tcphy->uphy_rst);
0774
0775 ret = readx_poll_timeout(readl, tcphy->base + PMA_CMN_CTRL1,
0776 val, val & CMN_READY, 10,
0777 PHY_MODE_SET_TIMEOUT);
0778 if (ret < 0) {
0779 dev_err(tcphy->dev, "wait pma ready timeout\n");
0780 ret = -ETIMEDOUT;
0781 goto err_wait_pma;
0782 }
0783
0784 reset_control_deassert(tcphy->pipe_rst);
0785
0786 return 0;
0787
0788 err_wait_pma:
0789 reset_control_assert(tcphy->uphy_rst);
0790 reset_control_assert(tcphy->tcphy_rst);
0791 clk_disable_unprepare(tcphy->clk_ref);
0792 err_clk_core:
0793 clk_disable_unprepare(tcphy->clk_core);
0794 return ret;
0795 }
0796
0797 static void tcphy_phy_deinit(struct rockchip_typec_phy *tcphy)
0798 {
0799 reset_control_assert(tcphy->tcphy_rst);
0800 reset_control_assert(tcphy->uphy_rst);
0801 reset_control_assert(tcphy->pipe_rst);
0802 clk_disable_unprepare(tcphy->clk_core);
0803 clk_disable_unprepare(tcphy->clk_ref);
0804 }
0805
0806 static int tcphy_get_mode(struct rockchip_typec_phy *tcphy)
0807 {
0808 struct extcon_dev *edev = tcphy->extcon;
0809 union extcon_property_value property;
0810 unsigned int id;
0811 bool ufp, dp;
0812 u8 mode;
0813 int ret;
0814
0815 if (!edev)
0816 return MODE_DFP_USB;
0817
0818 ufp = extcon_get_state(edev, EXTCON_USB);
0819 dp = extcon_get_state(edev, EXTCON_DISP_DP);
0820
0821 mode = MODE_DFP_USB;
0822 id = EXTCON_USB_HOST;
0823
0824 if (ufp) {
0825 mode = MODE_UFP_USB;
0826 id = EXTCON_USB;
0827 } else if (dp) {
0828 mode = MODE_DFP_DP;
0829 id = EXTCON_DISP_DP;
0830
0831 ret = extcon_get_property(edev, id, EXTCON_PROP_USB_SS,
0832 &property);
0833 if (ret) {
0834 dev_err(tcphy->dev, "get superspeed property failed\n");
0835 return ret;
0836 }
0837
0838 if (property.intval)
0839 mode |= MODE_DFP_USB;
0840 }
0841
0842 ret = extcon_get_property(edev, id, EXTCON_PROP_USB_TYPEC_POLARITY,
0843 &property);
0844 if (ret) {
0845 dev_err(tcphy->dev, "get polarity property failed\n");
0846 return ret;
0847 }
0848
0849 tcphy->flip = property.intval ? 1 : 0;
0850
0851 return mode;
0852 }
0853
0854 static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_typec_phy *tcphy,
0855 bool value)
0856 {
0857 const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs;
0858
0859 property_enable(tcphy, &cfg->usb3tousb2_en, value);
0860 property_enable(tcphy, &cfg->usb3_host_disable, value);
0861 property_enable(tcphy, &cfg->usb3_host_port, !value);
0862
0863 return 0;
0864 }
0865
0866 static int rockchip_usb3_phy_power_on(struct phy *phy)
0867 {
0868 struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);
0869 const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs;
0870 const struct usb3phy_reg *reg = &cfg->pipe_status;
0871 int timeout, new_mode, ret = 0;
0872 u32 val;
0873
0874 mutex_lock(&tcphy->lock);
0875
0876 new_mode = tcphy_get_mode(tcphy);
0877 if (new_mode < 0) {
0878 ret = new_mode;
0879 goto unlock_ret;
0880 }
0881
0882
0883 if (!(new_mode & (MODE_DFP_USB | MODE_UFP_USB))) {
0884 tcphy_cfg_usb3_to_usb2_only(tcphy, true);
0885 goto unlock_ret;
0886 }
0887
0888 if (tcphy->mode == new_mode)
0889 goto unlock_ret;
0890
0891 if (tcphy->mode == MODE_DISCONNECT) {
0892 ret = tcphy_phy_init(tcphy, new_mode);
0893 if (ret)
0894 goto unlock_ret;
0895 }
0896
0897
0898 for (timeout = 0; timeout < 100; timeout++) {
0899 regmap_read(tcphy->grf_regs, reg->offset, &val);
0900 if (!(val & BIT(reg->enable_bit))) {
0901 tcphy->mode |= new_mode & (MODE_DFP_USB | MODE_UFP_USB);
0902
0903
0904 tcphy_cfg_usb3_to_usb2_only(tcphy, false);
0905 goto unlock_ret;
0906 }
0907 usleep_range(10, 20);
0908 }
0909
0910 if (tcphy->mode == MODE_DISCONNECT)
0911 tcphy_phy_deinit(tcphy);
0912
0913 ret = -ETIMEDOUT;
0914
0915 unlock_ret:
0916 mutex_unlock(&tcphy->lock);
0917 return ret;
0918 }
0919
0920 static int rockchip_usb3_phy_power_off(struct phy *phy)
0921 {
0922 struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);
0923
0924 mutex_lock(&tcphy->lock);
0925 tcphy_cfg_usb3_to_usb2_only(tcphy, false);
0926
0927 if (tcphy->mode == MODE_DISCONNECT)
0928 goto unlock;
0929
0930 tcphy->mode &= ~(MODE_UFP_USB | MODE_DFP_USB);
0931 if (tcphy->mode == MODE_DISCONNECT)
0932 tcphy_phy_deinit(tcphy);
0933
0934 unlock:
0935 mutex_unlock(&tcphy->lock);
0936 return 0;
0937 }
0938
0939 static const struct phy_ops rockchip_usb3_phy_ops = {
0940 .power_on = rockchip_usb3_phy_power_on,
0941 .power_off = rockchip_usb3_phy_power_off,
0942 .owner = THIS_MODULE,
0943 };
0944
0945 static int rockchip_dp_phy_power_on(struct phy *phy)
0946 {
0947 struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);
0948 const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs;
0949 int new_mode, ret = 0;
0950 u32 val;
0951
0952 mutex_lock(&tcphy->lock);
0953
0954 new_mode = tcphy_get_mode(tcphy);
0955 if (new_mode < 0) {
0956 ret = new_mode;
0957 goto unlock_ret;
0958 }
0959
0960 if (!(new_mode & MODE_DFP_DP)) {
0961 ret = -ENODEV;
0962 goto unlock_ret;
0963 }
0964
0965 if (tcphy->mode == new_mode)
0966 goto unlock_ret;
0967
0968
0969
0970
0971
0972 if (new_mode == MODE_DFP_DP && tcphy->mode != MODE_DISCONNECT) {
0973 tcphy_phy_deinit(tcphy);
0974 ret = tcphy_phy_init(tcphy, new_mode);
0975 } else if (tcphy->mode == MODE_DISCONNECT) {
0976 ret = tcphy_phy_init(tcphy, new_mode);
0977 }
0978 if (ret)
0979 goto unlock_ret;
0980
0981 property_enable(tcphy, &cfg->uphy_dp_sel, 1);
0982
0983 ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL,
0984 val, val & DP_MODE_A2, 1000,
0985 PHY_MODE_SET_TIMEOUT);
0986 if (ret < 0) {
0987 dev_err(tcphy->dev, "failed to wait TCPHY enter A2\n");
0988 goto power_on_finish;
0989 }
0990
0991 tcphy_dp_aux_calibration(tcphy);
0992
0993 writel(DP_MODE_ENTER_A0, tcphy->base + DP_MODE_CTL);
0994
0995 ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL,
0996 val, val & DP_MODE_A0, 1000,
0997 PHY_MODE_SET_TIMEOUT);
0998 if (ret < 0) {
0999 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
1006 power_on_finish:
1007 if (tcphy->mode == MODE_DISCONNECT)
1008 tcphy_phy_deinit(tcphy);
1009 unlock_ret:
1010 mutex_unlock(&tcphy->lock);
1011 return ret;
1012 }
1013
1014 static 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
1030 unlock:
1031 mutex_unlock(&tcphy->lock);
1032 return 0;
1033 }
1034
1035 static 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
1041 static 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
1084 static 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
1093 property_enable(tcphy, &cfg->external_psm, 1);
1094 property_enable(tcphy, &cfg->usb3tousb2_en, 0);
1095
1096 tcphy->mode = MODE_DISCONNECT;
1097 }
1098
1099 static 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
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
1198 static int rockchip_typec_phy_remove(struct platform_device *pdev)
1199 {
1200 pm_runtime_disable(&pdev->dev);
1201
1202 return 0;
1203 }
1204
1205 static 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 { }
1211 };
1212
1213 MODULE_DEVICE_TABLE(of, rockchip_typec_phy_dt_ids);
1214
1215 static 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
1224 module_platform_driver(rockchip_typec_phy_driver);
1225
1226 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
1227 MODULE_AUTHOR("Kever Yang <kever.yang@rock-chips.com>");
1228 MODULE_DESCRIPTION("Rockchip USB TYPE-C PHY driver");
1229 MODULE_LICENSE("GPL v2");