1*16df8bcbSNeil Armstrong // SPDX-License-Identifier: GPL-2.0 2*16df8bcbSNeil Armstrong /* 3*16df8bcbSNeil Armstrong * Meson G12A USB2 PHY driver 4*16df8bcbSNeil Armstrong * 5*16df8bcbSNeil Armstrong * Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com> 6*16df8bcbSNeil Armstrong * Copyright (C) 2017 Amlogic, Inc. All rights reserved 7*16df8bcbSNeil Armstrong * Copyright (C) 2019 BayLibre, SAS 8*16df8bcbSNeil Armstrong * Author: Neil Armstrong <narmstrong@baylibre.com> 9*16df8bcbSNeil Armstrong */ 10*16df8bcbSNeil Armstrong 11*16df8bcbSNeil Armstrong #include <linux/bitfield.h> 12*16df8bcbSNeil Armstrong #include <linux/bitops.h> 13*16df8bcbSNeil Armstrong #include <linux/clk.h> 14*16df8bcbSNeil Armstrong #include <linux/delay.h> 15*16df8bcbSNeil Armstrong #include <linux/io.h> 16*16df8bcbSNeil Armstrong #include <linux/module.h> 17*16df8bcbSNeil Armstrong #include <linux/of_device.h> 18*16df8bcbSNeil Armstrong #include <linux/regmap.h> 19*16df8bcbSNeil Armstrong #include <linux/reset.h> 20*16df8bcbSNeil Armstrong #include <linux/phy/phy.h> 21*16df8bcbSNeil Armstrong #include <linux/platform_device.h> 22*16df8bcbSNeil Armstrong 23*16df8bcbSNeil Armstrong #define PHY_CTRL_R0 0x0 24*16df8bcbSNeil Armstrong #define PHY_CTRL_R1 0x4 25*16df8bcbSNeil Armstrong #define PHY_CTRL_R2 0x8 26*16df8bcbSNeil Armstrong #define PHY_CTRL_R3 0xc 27*16df8bcbSNeil Armstrong #define PHY_CTRL_R3_SQUELCH_REF GENMASK(1, 0) 28*16df8bcbSNeil Armstrong #define PHY_CTRL_R3_HSDIC_REF GENMASK(3, 2) 29*16df8bcbSNeil Armstrong #define PHY_CTRL_R3_DISC_THRESH GENMASK(7, 4) 30*16df8bcbSNeil Armstrong 31*16df8bcbSNeil Armstrong #define PHY_CTRL_R4 0x10 32*16df8bcbSNeil Armstrong #define PHY_CTRL_R4_CALIB_CODE_7_0 GENMASK(7, 0) 33*16df8bcbSNeil Armstrong #define PHY_CTRL_R4_CALIB_CODE_15_8 GENMASK(15, 8) 34*16df8bcbSNeil Armstrong #define PHY_CTRL_R4_CALIB_CODE_23_16 GENMASK(23, 16) 35*16df8bcbSNeil Armstrong #define PHY_CTRL_R4_I_C2L_CAL_EN BIT(24) 36*16df8bcbSNeil Armstrong #define PHY_CTRL_R4_I_C2L_CAL_RESET_N BIT(25) 37*16df8bcbSNeil Armstrong #define PHY_CTRL_R4_I_C2L_CAL_DONE BIT(26) 38*16df8bcbSNeil Armstrong #define PHY_CTRL_R4_TEST_BYPASS_MODE_EN BIT(27) 39*16df8bcbSNeil Armstrong #define PHY_CTRL_R4_I_C2L_BIAS_TRIM_1_0 GENMASK(29, 28) 40*16df8bcbSNeil Armstrong #define PHY_CTRL_R4_I_C2L_BIAS_TRIM_3_2 GENMASK(31, 30) 41*16df8bcbSNeil Armstrong 42*16df8bcbSNeil Armstrong #define PHY_CTRL_R5 0x14 43*16df8bcbSNeil Armstrong #define PHY_CTRL_R6 0x18 44*16df8bcbSNeil Armstrong #define PHY_CTRL_R7 0x1c 45*16df8bcbSNeil Armstrong #define PHY_CTRL_R8 0x20 46*16df8bcbSNeil Armstrong #define PHY_CTRL_R9 0x24 47*16df8bcbSNeil Armstrong #define PHY_CTRL_R10 0x28 48*16df8bcbSNeil Armstrong #define PHY_CTRL_R11 0x2c 49*16df8bcbSNeil Armstrong #define PHY_CTRL_R12 0x30 50*16df8bcbSNeil Armstrong #define PHY_CTRL_R13 0x34 51*16df8bcbSNeil Armstrong #define PHY_CTRL_R13_CUSTOM_PATTERN_19 GENMASK(7, 0) 52*16df8bcbSNeil Armstrong #define PHY_CTRL_R13_LOAD_STAT BIT(14) 53*16df8bcbSNeil Armstrong #define PHY_CTRL_R13_UPDATE_PMA_SIGNALS BIT(15) 54*16df8bcbSNeil Armstrong #define PHY_CTRL_R13_MIN_COUNT_FOR_SYNC_DET GENMASK(20, 16) 55*16df8bcbSNeil Armstrong #define PHY_CTRL_R13_CLEAR_HOLD_HS_DISCONNECT BIT(21) 56*16df8bcbSNeil Armstrong #define PHY_CTRL_R13_BYPASS_HOST_DISCONNECT_VAL BIT(22) 57*16df8bcbSNeil Armstrong #define PHY_CTRL_R13_BYPASS_HOST_DISCONNECT_EN BIT(23) 58*16df8bcbSNeil Armstrong #define PHY_CTRL_R13_I_C2L_HS_EN BIT(24) 59*16df8bcbSNeil Armstrong #define PHY_CTRL_R13_I_C2L_FS_EN BIT(25) 60*16df8bcbSNeil Armstrong #define PHY_CTRL_R13_I_C2L_LS_EN BIT(26) 61*16df8bcbSNeil Armstrong #define PHY_CTRL_R13_I_C2L_HS_OE BIT(27) 62*16df8bcbSNeil Armstrong #define PHY_CTRL_R13_I_C2L_FS_OE BIT(28) 63*16df8bcbSNeil Armstrong #define PHY_CTRL_R13_I_C2L_HS_RX_EN BIT(29) 64*16df8bcbSNeil Armstrong #define PHY_CTRL_R13_I_C2L_FSLS_RX_EN BIT(30) 65*16df8bcbSNeil Armstrong 66*16df8bcbSNeil Armstrong #define PHY_CTRL_R14 0x38 67*16df8bcbSNeil Armstrong #define PHY_CTRL_R14_I_RDP_EN BIT(0) 68*16df8bcbSNeil Armstrong #define PHY_CTRL_R14_I_RPU_SW1_EN BIT(1) 69*16df8bcbSNeil Armstrong #define PHY_CTRL_R14_I_RPU_SW2_EN GENMASK(2, 3) 70*16df8bcbSNeil Armstrong #define PHY_CTRL_R14_PG_RSTN BIT(4) 71*16df8bcbSNeil Armstrong #define PHY_CTRL_R14_I_C2L_DATA_16_8 BIT(5) 72*16df8bcbSNeil Armstrong #define PHY_CTRL_R14_I_C2L_ASSERT_SINGLE_EN_ZERO BIT(6) 73*16df8bcbSNeil Armstrong #define PHY_CTRL_R14_BYPASS_CTRL_7_0 GENMASK(15, 8) 74*16df8bcbSNeil Armstrong #define PHY_CTRL_R14_BYPASS_CTRL_15_8 GENMASK(23, 16) 75*16df8bcbSNeil Armstrong 76*16df8bcbSNeil Armstrong #define PHY_CTRL_R15 0x3c 77*16df8bcbSNeil Armstrong #define PHY_CTRL_R16 0x40 78*16df8bcbSNeil Armstrong #define PHY_CTRL_R16_MPLL_M GENMASK(8, 0) 79*16df8bcbSNeil Armstrong #define PHY_CTRL_R16_MPLL_N GENMASK(14, 10) 80*16df8bcbSNeil Armstrong #define PHY_CTRL_R16_MPLL_TDC_MODE BIT(20) 81*16df8bcbSNeil Armstrong #define PHY_CTRL_R16_MPLL_SDM_EN BIT(21) 82*16df8bcbSNeil Armstrong #define PHY_CTRL_R16_MPLL_LOAD BIT(22) 83*16df8bcbSNeil Armstrong #define PHY_CTRL_R16_MPLL_DCO_SDM_EN BIT(23) 84*16df8bcbSNeil Armstrong #define PHY_CTRL_R16_MPLL_LOCK_LONG GENMASK(25, 24) 85*16df8bcbSNeil Armstrong #define PHY_CTRL_R16_MPLL_LOCK_F BIT(26) 86*16df8bcbSNeil Armstrong #define PHY_CTRL_R16_MPLL_FAST_LOCK BIT(27) 87*16df8bcbSNeil Armstrong #define PHY_CTRL_R16_MPLL_EN BIT(28) 88*16df8bcbSNeil Armstrong #define PHY_CTRL_R16_MPLL_RESET BIT(29) 89*16df8bcbSNeil Armstrong #define PHY_CTRL_R16_MPLL_LOCK BIT(30) 90*16df8bcbSNeil Armstrong #define PHY_CTRL_R16_MPLL_LOCK_DIG BIT(31) 91*16df8bcbSNeil Armstrong 92*16df8bcbSNeil Armstrong #define PHY_CTRL_R17 0x44 93*16df8bcbSNeil Armstrong #define PHY_CTRL_R17_MPLL_FRAC_IN GENMASK(13, 0) 94*16df8bcbSNeil Armstrong #define PHY_CTRL_R17_MPLL_FIX_EN BIT(16) 95*16df8bcbSNeil Armstrong #define PHY_CTRL_R17_MPLL_LAMBDA1 GENMASK(19, 17) 96*16df8bcbSNeil Armstrong #define PHY_CTRL_R17_MPLL_LAMBDA0 GENMASK(22, 20) 97*16df8bcbSNeil Armstrong #define PHY_CTRL_R17_MPLL_FILTER_MODE BIT(23) 98*16df8bcbSNeil Armstrong #define PHY_CTRL_R17_MPLL_FILTER_PVT2 GENMASK(27, 24) 99*16df8bcbSNeil Armstrong #define PHY_CTRL_R17_MPLL_FILTER_PVT1 GENMASK(31, 28) 100*16df8bcbSNeil Armstrong 101*16df8bcbSNeil Armstrong #define PHY_CTRL_R18 0x48 102*16df8bcbSNeil Armstrong #define PHY_CTRL_R18_MPLL_LKW_SEL GENMASK(1, 0) 103*16df8bcbSNeil Armstrong #define PHY_CTRL_R18_MPLL_LK_W GENMASK(5, 2) 104*16df8bcbSNeil Armstrong #define PHY_CTRL_R18_MPLL_LK_S GENMASK(11, 6) 105*16df8bcbSNeil Armstrong #define PHY_CTRL_R18_MPLL_DCO_M_EN BIT(12) 106*16df8bcbSNeil Armstrong #define PHY_CTRL_R18_MPLL_DCO_CLK_SEL BIT(13) 107*16df8bcbSNeil Armstrong #define PHY_CTRL_R18_MPLL_PFD_GAIN GENMASK(15, 14) 108*16df8bcbSNeil Armstrong #define PHY_CTRL_R18_MPLL_ROU GENMASK(18, 16) 109*16df8bcbSNeil Armstrong #define PHY_CTRL_R18_MPLL_DATA_SEL GENMASK(21, 19) 110*16df8bcbSNeil Armstrong #define PHY_CTRL_R18_MPLL_BIAS_ADJ GENMASK(23, 22) 111*16df8bcbSNeil Armstrong #define PHY_CTRL_R18_MPLL_BB_MODE GENMASK(25, 24) 112*16df8bcbSNeil Armstrong #define PHY_CTRL_R18_MPLL_ALPHA GENMASK(28, 26) 113*16df8bcbSNeil Armstrong #define PHY_CTRL_R18_MPLL_ADJ_LDO GENMASK(30, 29) 114*16df8bcbSNeil Armstrong #define PHY_CTRL_R18_MPLL_ACG_RANGE BIT(31) 115*16df8bcbSNeil Armstrong 116*16df8bcbSNeil Armstrong #define PHY_CTRL_R19 0x4c 117*16df8bcbSNeil Armstrong #define PHY_CTRL_R20 0x50 118*16df8bcbSNeil Armstrong #define PHY_CTRL_R20_USB2_IDDET_EN BIT(0) 119*16df8bcbSNeil Armstrong #define PHY_CTRL_R20_USB2_OTG_VBUS_TRIM_2_0 GENMASK(3, 1) 120*16df8bcbSNeil Armstrong #define PHY_CTRL_R20_USB2_OTG_VBUSDET_EN BIT(4) 121*16df8bcbSNeil Armstrong #define PHY_CTRL_R20_USB2_AMON_EN BIT(5) 122*16df8bcbSNeil Armstrong #define PHY_CTRL_R20_USB2_CAL_CODE_R5 BIT(6) 123*16df8bcbSNeil Armstrong #define PHY_CTRL_R20_BYPASS_OTG_DET BIT(7) 124*16df8bcbSNeil Armstrong #define PHY_CTRL_R20_USB2_DMON_EN BIT(8) 125*16df8bcbSNeil Armstrong #define PHY_CTRL_R20_USB2_DMON_SEL_3_0 GENMASK(12, 9) 126*16df8bcbSNeil Armstrong #define PHY_CTRL_R20_USB2_EDGE_DRV_EN BIT(13) 127*16df8bcbSNeil Armstrong #define PHY_CTRL_R20_USB2_EDGE_DRV_TRIM_1_0 GENMASK(15, 14) 128*16df8bcbSNeil Armstrong #define PHY_CTRL_R20_USB2_BGR_ADJ_4_0 GENMASK(20, 16) 129*16df8bcbSNeil Armstrong #define PHY_CTRL_R20_USB2_BGR_START BIT(21) 130*16df8bcbSNeil Armstrong #define PHY_CTRL_R20_USB2_BGR_VREF_4_0 GENMASK(28, 24) 131*16df8bcbSNeil Armstrong #define PHY_CTRL_R20_USB2_BGR_DBG_1_0 GENMASK(30, 29) 132*16df8bcbSNeil Armstrong #define PHY_CTRL_R20_BYPASS_CAL_DONE_R5 BIT(31) 133*16df8bcbSNeil Armstrong 134*16df8bcbSNeil Armstrong #define PHY_CTRL_R21 0x54 135*16df8bcbSNeil Armstrong #define PHY_CTRL_R21_USB2_BGR_FORCE BIT(0) 136*16df8bcbSNeil Armstrong #define PHY_CTRL_R21_USB2_CAL_ACK_EN BIT(1) 137*16df8bcbSNeil Armstrong #define PHY_CTRL_R21_USB2_OTG_ACA_EN BIT(2) 138*16df8bcbSNeil Armstrong #define PHY_CTRL_R21_USB2_TX_STRG_PD BIT(3) 139*16df8bcbSNeil Armstrong #define PHY_CTRL_R21_USB2_OTG_ACA_TRIM_1_0 GENMASK(5, 4) 140*16df8bcbSNeil Armstrong #define PHY_CTRL_R21_BYPASS_UTMI_CNTR GENMASK(15, 6) 141*16df8bcbSNeil Armstrong #define PHY_CTRL_R21_BYPASS_UTMI_REG GENMASK(25, 20) 142*16df8bcbSNeil Armstrong 143*16df8bcbSNeil Armstrong #define PHY_CTRL_R22 0x58 144*16df8bcbSNeil Armstrong #define PHY_CTRL_R23 0x5c 145*16df8bcbSNeil Armstrong 146*16df8bcbSNeil Armstrong #define RESET_COMPLETE_TIME 1000 147*16df8bcbSNeil Armstrong #define PLL_RESET_COMPLETE_TIME 100 148*16df8bcbSNeil Armstrong 149*16df8bcbSNeil Armstrong struct phy_meson_g12a_usb2_priv { 150*16df8bcbSNeil Armstrong struct device *dev; 151*16df8bcbSNeil Armstrong struct regmap *regmap; 152*16df8bcbSNeil Armstrong struct clk *clk; 153*16df8bcbSNeil Armstrong struct reset_control *reset; 154*16df8bcbSNeil Armstrong }; 155*16df8bcbSNeil Armstrong 156*16df8bcbSNeil Armstrong static const struct regmap_config phy_meson_g12a_usb2_regmap_conf = { 157*16df8bcbSNeil Armstrong .reg_bits = 8, 158*16df8bcbSNeil Armstrong .val_bits = 32, 159*16df8bcbSNeil Armstrong .reg_stride = 4, 160*16df8bcbSNeil Armstrong .max_register = PHY_CTRL_R23, 161*16df8bcbSNeil Armstrong }; 162*16df8bcbSNeil Armstrong 163*16df8bcbSNeil Armstrong static int phy_meson_g12a_usb2_init(struct phy *phy) 164*16df8bcbSNeil Armstrong { 165*16df8bcbSNeil Armstrong struct phy_meson_g12a_usb2_priv *priv = phy_get_drvdata(phy); 166*16df8bcbSNeil Armstrong int ret; 167*16df8bcbSNeil Armstrong 168*16df8bcbSNeil Armstrong ret = reset_control_reset(priv->reset); 169*16df8bcbSNeil Armstrong if (ret) 170*16df8bcbSNeil Armstrong return ret; 171*16df8bcbSNeil Armstrong 172*16df8bcbSNeil Armstrong udelay(RESET_COMPLETE_TIME); 173*16df8bcbSNeil Armstrong 174*16df8bcbSNeil Armstrong /* usb2_otg_aca_en == 0 */ 175*16df8bcbSNeil Armstrong regmap_update_bits(priv->regmap, PHY_CTRL_R21, 176*16df8bcbSNeil Armstrong PHY_CTRL_R21_USB2_OTG_ACA_EN, 0); 177*16df8bcbSNeil Armstrong 178*16df8bcbSNeil Armstrong /* PLL Setup : 24MHz * 20 / 1 = 480MHz */ 179*16df8bcbSNeil Armstrong regmap_write(priv->regmap, PHY_CTRL_R16, 180*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R16_MPLL_M, 20) | 181*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R16_MPLL_N, 1) | 182*16df8bcbSNeil Armstrong PHY_CTRL_R16_MPLL_LOAD | 183*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R16_MPLL_LOCK_LONG, 1) | 184*16df8bcbSNeil Armstrong PHY_CTRL_R16_MPLL_FAST_LOCK | 185*16df8bcbSNeil Armstrong PHY_CTRL_R16_MPLL_EN | 186*16df8bcbSNeil Armstrong PHY_CTRL_R16_MPLL_RESET); 187*16df8bcbSNeil Armstrong 188*16df8bcbSNeil Armstrong regmap_write(priv->regmap, PHY_CTRL_R17, 189*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R17_MPLL_FRAC_IN, 0) | 190*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R17_MPLL_LAMBDA1, 7) | 191*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R17_MPLL_LAMBDA0, 7) | 192*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R17_MPLL_FILTER_PVT2, 2) | 193*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R17_MPLL_FILTER_PVT1, 9)); 194*16df8bcbSNeil Armstrong 195*16df8bcbSNeil Armstrong regmap_write(priv->regmap, PHY_CTRL_R18, 196*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R18_MPLL_LKW_SEL, 1) | 197*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R18_MPLL_LK_W, 9) | 198*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R18_MPLL_LK_S, 0x27) | 199*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R18_MPLL_PFD_GAIN, 1) | 200*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R18_MPLL_ROU, 7) | 201*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R18_MPLL_DATA_SEL, 3) | 202*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R18_MPLL_BIAS_ADJ, 1) | 203*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R18_MPLL_BB_MODE, 0) | 204*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R18_MPLL_ALPHA, 3) | 205*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R18_MPLL_ADJ_LDO, 1) | 206*16df8bcbSNeil Armstrong PHY_CTRL_R18_MPLL_ACG_RANGE); 207*16df8bcbSNeil Armstrong 208*16df8bcbSNeil Armstrong udelay(PLL_RESET_COMPLETE_TIME); 209*16df8bcbSNeil Armstrong 210*16df8bcbSNeil Armstrong /* UnReset PLL */ 211*16df8bcbSNeil Armstrong regmap_write(priv->regmap, PHY_CTRL_R16, 212*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R16_MPLL_M, 20) | 213*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R16_MPLL_N, 1) | 214*16df8bcbSNeil Armstrong PHY_CTRL_R16_MPLL_LOAD | 215*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R16_MPLL_LOCK_LONG, 1) | 216*16df8bcbSNeil Armstrong PHY_CTRL_R16_MPLL_FAST_LOCK | 217*16df8bcbSNeil Armstrong PHY_CTRL_R16_MPLL_EN); 218*16df8bcbSNeil Armstrong 219*16df8bcbSNeil Armstrong /* PHY Tuning */ 220*16df8bcbSNeil Armstrong regmap_write(priv->regmap, PHY_CTRL_R20, 221*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R20_USB2_OTG_VBUS_TRIM_2_0, 4) | 222*16df8bcbSNeil Armstrong PHY_CTRL_R20_USB2_OTG_VBUSDET_EN | 223*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R20_USB2_DMON_SEL_3_0, 15) | 224*16df8bcbSNeil Armstrong PHY_CTRL_R20_USB2_EDGE_DRV_EN | 225*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R20_USB2_EDGE_DRV_TRIM_1_0, 3) | 226*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R20_USB2_BGR_ADJ_4_0, 0) | 227*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R20_USB2_BGR_VREF_4_0, 0) | 228*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R20_USB2_BGR_DBG_1_0, 0)); 229*16df8bcbSNeil Armstrong 230*16df8bcbSNeil Armstrong regmap_write(priv->regmap, PHY_CTRL_R4, 231*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R4_CALIB_CODE_7_0, 0xf) | 232*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R4_CALIB_CODE_15_8, 0xf) | 233*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R4_CALIB_CODE_23_16, 0xf) | 234*16df8bcbSNeil Armstrong PHY_CTRL_R4_TEST_BYPASS_MODE_EN | 235*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R4_I_C2L_BIAS_TRIM_1_0, 0) | 236*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R4_I_C2L_BIAS_TRIM_3_2, 0)); 237*16df8bcbSNeil Armstrong 238*16df8bcbSNeil Armstrong /* Tuning Disconnect Threshold */ 239*16df8bcbSNeil Armstrong regmap_write(priv->regmap, PHY_CTRL_R3, 240*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R3_SQUELCH_REF, 0) | 241*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R3_HSDIC_REF, 1) | 242*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R3_DISC_THRESH, 3)); 243*16df8bcbSNeil Armstrong 244*16df8bcbSNeil Armstrong /* Analog Settings */ 245*16df8bcbSNeil Armstrong regmap_write(priv->regmap, PHY_CTRL_R14, 0); 246*16df8bcbSNeil Armstrong regmap_write(priv->regmap, PHY_CTRL_R13, 247*16df8bcbSNeil Armstrong PHY_CTRL_R13_UPDATE_PMA_SIGNALS | 248*16df8bcbSNeil Armstrong FIELD_PREP(PHY_CTRL_R13_MIN_COUNT_FOR_SYNC_DET, 7)); 249*16df8bcbSNeil Armstrong 250*16df8bcbSNeil Armstrong return 0; 251*16df8bcbSNeil Armstrong } 252*16df8bcbSNeil Armstrong 253*16df8bcbSNeil Armstrong static int phy_meson_g12a_usb2_exit(struct phy *phy) 254*16df8bcbSNeil Armstrong { 255*16df8bcbSNeil Armstrong struct phy_meson_g12a_usb2_priv *priv = phy_get_drvdata(phy); 256*16df8bcbSNeil Armstrong 257*16df8bcbSNeil Armstrong return reset_control_reset(priv->reset); 258*16df8bcbSNeil Armstrong } 259*16df8bcbSNeil Armstrong 260*16df8bcbSNeil Armstrong /* set_mode is not needed, mode setting is handled via the UTMI bus */ 261*16df8bcbSNeil Armstrong static const struct phy_ops phy_meson_g12a_usb2_ops = { 262*16df8bcbSNeil Armstrong .init = phy_meson_g12a_usb2_init, 263*16df8bcbSNeil Armstrong .exit = phy_meson_g12a_usb2_exit, 264*16df8bcbSNeil Armstrong .owner = THIS_MODULE, 265*16df8bcbSNeil Armstrong }; 266*16df8bcbSNeil Armstrong 267*16df8bcbSNeil Armstrong static int phy_meson_g12a_usb2_probe(struct platform_device *pdev) 268*16df8bcbSNeil Armstrong { 269*16df8bcbSNeil Armstrong struct device *dev = &pdev->dev; 270*16df8bcbSNeil Armstrong struct phy_provider *phy_provider; 271*16df8bcbSNeil Armstrong struct resource *res; 272*16df8bcbSNeil Armstrong struct phy_meson_g12a_usb2_priv *priv; 273*16df8bcbSNeil Armstrong struct phy *phy; 274*16df8bcbSNeil Armstrong void __iomem *base; 275*16df8bcbSNeil Armstrong int ret; 276*16df8bcbSNeil Armstrong 277*16df8bcbSNeil Armstrong priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 278*16df8bcbSNeil Armstrong if (!priv) 279*16df8bcbSNeil Armstrong return -ENOMEM; 280*16df8bcbSNeil Armstrong 281*16df8bcbSNeil Armstrong priv->dev = dev; 282*16df8bcbSNeil Armstrong platform_set_drvdata(pdev, priv); 283*16df8bcbSNeil Armstrong 284*16df8bcbSNeil Armstrong res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 285*16df8bcbSNeil Armstrong base = devm_ioremap_resource(dev, res); 286*16df8bcbSNeil Armstrong if (IS_ERR(base)) 287*16df8bcbSNeil Armstrong return PTR_ERR(base); 288*16df8bcbSNeil Armstrong 289*16df8bcbSNeil Armstrong priv->regmap = devm_regmap_init_mmio(dev, base, 290*16df8bcbSNeil Armstrong &phy_meson_g12a_usb2_regmap_conf); 291*16df8bcbSNeil Armstrong if (IS_ERR(priv->regmap)) 292*16df8bcbSNeil Armstrong return PTR_ERR(priv->regmap); 293*16df8bcbSNeil Armstrong 294*16df8bcbSNeil Armstrong priv->clk = devm_clk_get(dev, "xtal"); 295*16df8bcbSNeil Armstrong if (IS_ERR(priv->clk)) 296*16df8bcbSNeil Armstrong return PTR_ERR(priv->clk); 297*16df8bcbSNeil Armstrong 298*16df8bcbSNeil Armstrong priv->reset = devm_reset_control_get(dev, "phy"); 299*16df8bcbSNeil Armstrong if (IS_ERR(priv->reset)) 300*16df8bcbSNeil Armstrong return PTR_ERR(priv->reset); 301*16df8bcbSNeil Armstrong 302*16df8bcbSNeil Armstrong ret = reset_control_deassert(priv->reset); 303*16df8bcbSNeil Armstrong if (ret) 304*16df8bcbSNeil Armstrong return ret; 305*16df8bcbSNeil Armstrong 306*16df8bcbSNeil Armstrong phy = devm_phy_create(dev, NULL, &phy_meson_g12a_usb2_ops); 307*16df8bcbSNeil Armstrong if (IS_ERR(phy)) { 308*16df8bcbSNeil Armstrong ret = PTR_ERR(phy); 309*16df8bcbSNeil Armstrong if (ret != -EPROBE_DEFER) 310*16df8bcbSNeil Armstrong dev_err(dev, "failed to create PHY\n"); 311*16df8bcbSNeil Armstrong 312*16df8bcbSNeil Armstrong return ret; 313*16df8bcbSNeil Armstrong } 314*16df8bcbSNeil Armstrong 315*16df8bcbSNeil Armstrong phy_set_bus_width(phy, 8); 316*16df8bcbSNeil Armstrong phy_set_drvdata(phy, priv); 317*16df8bcbSNeil Armstrong 318*16df8bcbSNeil Armstrong phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 319*16df8bcbSNeil Armstrong 320*16df8bcbSNeil Armstrong return PTR_ERR_OR_ZERO(phy_provider); 321*16df8bcbSNeil Armstrong } 322*16df8bcbSNeil Armstrong 323*16df8bcbSNeil Armstrong static const struct of_device_id phy_meson_g12a_usb2_of_match[] = { 324*16df8bcbSNeil Armstrong { .compatible = "amlogic,g12a-usb2-phy", }, 325*16df8bcbSNeil Armstrong { }, 326*16df8bcbSNeil Armstrong }; 327*16df8bcbSNeil Armstrong MODULE_DEVICE_TABLE(of, phy_meson_g12a_usb2_of_match); 328*16df8bcbSNeil Armstrong 329*16df8bcbSNeil Armstrong static struct platform_driver phy_meson_g12a_usb2_driver = { 330*16df8bcbSNeil Armstrong .probe = phy_meson_g12a_usb2_probe, 331*16df8bcbSNeil Armstrong .driver = { 332*16df8bcbSNeil Armstrong .name = "phy-meson-g12a-usb2", 333*16df8bcbSNeil Armstrong .of_match_table = phy_meson_g12a_usb2_of_match, 334*16df8bcbSNeil Armstrong }, 335*16df8bcbSNeil Armstrong }; 336*16df8bcbSNeil Armstrong module_platform_driver(phy_meson_g12a_usb2_driver); 337*16df8bcbSNeil Armstrong 338*16df8bcbSNeil Armstrong MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>"); 339*16df8bcbSNeil Armstrong MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>"); 340*16df8bcbSNeil Armstrong MODULE_DESCRIPTION("Meson G12A USB2 PHY driver"); 341*16df8bcbSNeil Armstrong MODULE_LICENSE("GPL v2"); 342