xref: /linux/drivers/phy/amlogic/phy-meson-g12a-usb2.c (revision 16df8bcb672c45e69a7bf4b37bb6de12c705e195)
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