1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Meson G12A USB3+PCIE Combo PHY driver
4  *
5  * Copyright (C) 2018 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
6  * Copyright (C) 2019 BayLibre, SAS
7  * Author: Neil Armstrong <narmstron@baylibre.com>
8  */
9 
10 #include <common.h>
11 #include <clk.h>
12 #include <dm.h>
13 #include <malloc.h>
14 #include <regmap.h>
15 #include <errno.h>
16 #include <asm/io.h>
17 #include <reset.h>
18 #include <bitfield.h>
19 #include <generic-phy.h>
20 #include <linux/delay.h>
21 
22 #include <linux/bitops.h>
23 #include <linux/compat.h>
24 #include <linux/bitfield.h>
25 
26 #define PHY_R0							0x00
27 	#define PHY_R0_PCIE_POWER_STATE				GENMASK(4, 0)
28 	#define PHY_R0_PCIE_USB3_SWITCH				GENMASK(6, 5)
29 
30 #define PHY_R1							0x04
31 	#define PHY_R1_PHY_TX1_TERM_OFFSET			GENMASK(4, 0)
32 	#define PHY_R1_PHY_TX0_TERM_OFFSET			GENMASK(9, 5)
33 	#define PHY_R1_PHY_RX1_EQ				GENMASK(12, 10)
34 	#define PHY_R1_PHY_RX0_EQ				GENMASK(15, 13)
35 	#define PHY_R1_PHY_LOS_LEVEL				GENMASK(20, 16)
36 	#define PHY_R1_PHY_LOS_BIAS				GENMASK(23, 21)
37 	#define PHY_R1_PHY_REF_CLKDIV2				BIT(24)
38 	#define PHY_R1_PHY_MPLL_MULTIPLIER			GENMASK(31, 25)
39 
40 #define PHY_R2							0x08
41 	#define PHY_R2_PCS_TX_DEEMPH_GEN2_6DB			GENMASK(5, 0)
42 	#define PHY_R2_PCS_TX_DEEMPH_GEN2_3P5DB			GENMASK(11, 6)
43 	#define PHY_R2_PCS_TX_DEEMPH_GEN1			GENMASK(17, 12)
44 	#define PHY_R2_PHY_TX_VBOOST_LVL			GENMASK(20, 18)
45 
46 #define PHY_R4							0x10
47 	#define PHY_R4_PHY_CR_WRITE				BIT(0)
48 	#define PHY_R4_PHY_CR_READ				BIT(1)
49 	#define PHY_R4_PHY_CR_DATA_IN				GENMASK(17, 2)
50 	#define PHY_R4_PHY_CR_CAP_DATA				BIT(18)
51 	#define PHY_R4_PHY_CR_CAP_ADDR				BIT(19)
52 
53 #define PHY_R5							0x14
54 	#define PHY_R5_PHY_CR_DATA_OUT				GENMASK(15, 0)
55 	#define PHY_R5_PHY_CR_ACK				BIT(16)
56 	#define PHY_R5_PHY_BS_OUT				BIT(17)
57 
58 struct phy_g12a_usb3_pcie_priv {
59 	struct regmap		*regmap;
60 #if CONFIG_IS_ENABLED(CLK)
61 	struct clk		clk;
62 #endif
63 	struct reset_ctl_bulk	resets;
64 };
65 
phy_g12a_usb3_pcie_cr_bus_addr(struct phy_g12a_usb3_pcie_priv * priv,unsigned int addr)66 static int phy_g12a_usb3_pcie_cr_bus_addr(struct phy_g12a_usb3_pcie_priv *priv,
67 					  unsigned int addr)
68 {
69 	unsigned int val, reg;
70 	int ret;
71 
72 	reg = FIELD_PREP(PHY_R4_PHY_CR_DATA_IN, addr);
73 
74 	regmap_write(priv->regmap, PHY_R4, reg);
75 	regmap_write(priv->regmap, PHY_R4, reg);
76 
77 	regmap_write(priv->regmap, PHY_R4, reg | PHY_R4_PHY_CR_CAP_ADDR);
78 
79 	ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
80 				       (val & PHY_R5_PHY_CR_ACK),
81 				       5, 1000);
82 	if (ret)
83 		return ret;
84 
85 	regmap_write(priv->regmap, PHY_R4, reg);
86 
87 	ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
88 				       !(val & PHY_R5_PHY_CR_ACK),
89 				       5, 1000);
90 	if (ret)
91 		return ret;
92 
93 	return 0;
94 }
95 
96 static int
phy_g12a_usb3_pcie_cr_bus_read(struct phy_g12a_usb3_pcie_priv * priv,unsigned int addr,unsigned int * data)97 phy_g12a_usb3_pcie_cr_bus_read(struct phy_g12a_usb3_pcie_priv *priv,
98 			       unsigned int addr, unsigned int *data)
99 {
100 	unsigned int val;
101 	int ret;
102 
103 	ret = phy_g12a_usb3_pcie_cr_bus_addr(priv, addr);
104 	if (ret)
105 		return ret;
106 
107 	regmap_write(priv->regmap, PHY_R4, 0);
108 	regmap_write(priv->regmap, PHY_R4, PHY_R4_PHY_CR_READ);
109 
110 	ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
111 				       (val & PHY_R5_PHY_CR_ACK),
112 				       5, 1000);
113 	if (ret)
114 		return ret;
115 
116 	*data = FIELD_GET(PHY_R5_PHY_CR_DATA_OUT, val);
117 
118 	regmap_write(priv->regmap, PHY_R4, 0);
119 
120 	ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
121 				       !(val & PHY_R5_PHY_CR_ACK),
122 				       5, 1000);
123 	if (ret)
124 		return ret;
125 
126 	return 0;
127 }
128 
129 static int
phy_g12a_usb3_pcie_cr_bus_write(struct phy_g12a_usb3_pcie_priv * priv,unsigned int addr,unsigned int data)130 phy_g12a_usb3_pcie_cr_bus_write(struct phy_g12a_usb3_pcie_priv *priv,
131 			        unsigned int addr, unsigned int data)
132 {
133 	unsigned int val, reg;
134 	int ret;
135 
136 	ret = phy_g12a_usb3_pcie_cr_bus_addr(priv, addr);
137 	if (ret)
138 		return ret;
139 
140 	reg = FIELD_PREP(PHY_R4_PHY_CR_DATA_IN, data);
141 
142 	regmap_write(priv->regmap, PHY_R4, reg);
143 	regmap_write(priv->regmap, PHY_R4, reg);
144 
145 	regmap_write(priv->regmap, PHY_R4, reg | PHY_R4_PHY_CR_CAP_DATA);
146 
147 	ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
148 				       (val & PHY_R5_PHY_CR_ACK),
149 				       5, 1000);
150 	if (ret)
151 		return ret;
152 
153 	regmap_write(priv->regmap, PHY_R4, reg);
154 
155 	ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
156 				       (val & PHY_R5_PHY_CR_ACK) == 0,
157 				       5, 1000);
158 	if (ret)
159 		return ret;
160 
161 	regmap_write(priv->regmap, PHY_R4, reg);
162 
163 	regmap_write(priv->regmap, PHY_R4, reg | PHY_R4_PHY_CR_WRITE);
164 
165 	ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
166 				       (val & PHY_R5_PHY_CR_ACK),
167 				       5, 1000);
168 	if (ret)
169 		return ret;
170 
171 	regmap_write(priv->regmap, PHY_R4, reg);
172 
173 	ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
174 				       (val & PHY_R5_PHY_CR_ACK) == 0,
175 				       5, 1000);
176 	if (ret)
177 		return ret;
178 
179 	return 0;
180 }
181 
182 static int
phy_g12a_usb3_pcie_cr_bus_update_bits(struct phy_g12a_usb3_pcie_priv * priv,uint offset,uint mask,uint val)183 phy_g12a_usb3_pcie_cr_bus_update_bits(struct phy_g12a_usb3_pcie_priv *priv,
184 				      uint offset, uint mask, uint val)
185 {
186 	uint reg;
187 	int ret;
188 
189 	ret = phy_g12a_usb3_pcie_cr_bus_read(priv, offset, &reg);
190 	if (ret)
191 		return ret;
192 
193 	reg &= ~mask;
194 
195 	return phy_g12a_usb3_pcie_cr_bus_write(priv, offset, reg | val);
196 }
197 
phy_meson_g12a_usb3_init(struct phy * phy)198 static int phy_meson_g12a_usb3_init(struct phy *phy)
199 {
200 	struct udevice *dev = phy->dev;
201 	struct phy_g12a_usb3_pcie_priv *priv = dev_get_priv(dev);
202 	unsigned int data;
203 	int ret;
204 
205 	/* TOFIX Handle PCIE mode */
206 
207 	ret = reset_assert_bulk(&priv->resets);
208 	udelay(1);
209 	ret |= reset_deassert_bulk(&priv->resets);
210 	if (ret)
211 		return ret;
212 
213 	/* Switch PHY to USB3 */
214 	regmap_update_bits(priv->regmap, PHY_R0,
215 			   PHY_R0_PCIE_USB3_SWITCH,
216 			   PHY_R0_PCIE_USB3_SWITCH);
217 
218 	/*
219 	 * WORKAROUND: There is SSPHY suspend bug due to
220 	 * which USB enumerates
221 	 * in HS mode instead of SS mode. Workaround it by asserting
222 	 * LANE0.TX_ALT_BLOCK.EN_ALT_BUS to enable TX to use alt bus
223 	 * mode
224 	 */
225 	ret = phy_g12a_usb3_pcie_cr_bus_update_bits(priv, 0x102d,
226 						    BIT(7), BIT(7));
227 	if (ret)
228 		return ret;
229 
230 	ret = phy_g12a_usb3_pcie_cr_bus_update_bits(priv, 0x1010, 0xff0, 20);
231 	if (ret)
232 		return ret;
233 
234 	/*
235 	 * Fix RX Equalization setting as follows
236 	 * LANE0.RX_OVRD_IN_HI. RX_EQ_EN set to 0
237 	 * LANE0.RX_OVRD_IN_HI.RX_EQ_EN_OVRD set to 1
238 	 * LANE0.RX_OVRD_IN_HI.RX_EQ set to 3
239 	 * LANE0.RX_OVRD_IN_HI.RX_EQ_OVRD set to 1
240 	 */
241 	ret = phy_g12a_usb3_pcie_cr_bus_read(priv, 0x1006, &data);
242 	if (ret)
243 		return ret;
244 
245 	data &= ~BIT(6);
246 	data |= BIT(7);
247 	data &= ~(0x7 << 8);
248 	data |= (0x3 << 8);
249 	data |= (1 << 11);
250 	ret = phy_g12a_usb3_pcie_cr_bus_write(priv, 0x1006, data);
251 	if (ret)
252 		return ret;
253 
254 	/*
255 	 * Set EQ and TX launch amplitudes as follows
256 	 * LANE0.TX_OVRD_DRV_LO.PREEMPH set to 22
257 	 * LANE0.TX_OVRD_DRV_LO.AMPLITUDE set to 127
258 	 * LANE0.TX_OVRD_DRV_LO.EN set to 1.
259 	 */
260 	ret = phy_g12a_usb3_pcie_cr_bus_read(priv, 0x1002, &data);
261 	if (ret)
262 		return ret;
263 
264 	data &= ~0x3f80;
265 	data |= (0x16 << 7);
266 	data &= ~0x7f;
267 	data |= (0x7f | BIT(14));
268 	ret = phy_g12a_usb3_pcie_cr_bus_write(priv, 0x1002, data);
269 	if (ret)
270 		return ret;
271 
272 	/*
273 	 * MPLL_LOOP_CTL.PROP_CNTRL = 8
274 	 */
275 	ret = phy_g12a_usb3_pcie_cr_bus_update_bits(priv, 0x30,
276 						    0xf << 4, 8 << 4);
277 	if (ret)
278 		return ret;
279 
280 	regmap_update_bits(priv->regmap, PHY_R2,
281 			PHY_R2_PHY_TX_VBOOST_LVL,
282 			FIELD_PREP(PHY_R2_PHY_TX_VBOOST_LVL, 0x4));
283 
284 	regmap_update_bits(priv->regmap, PHY_R1,
285 			PHY_R1_PHY_LOS_BIAS | PHY_R1_PHY_LOS_LEVEL,
286 			FIELD_PREP(PHY_R1_PHY_LOS_BIAS, 4) |
287 			FIELD_PREP(PHY_R1_PHY_LOS_LEVEL, 9));
288 
289 	return ret;
290 }
291 
phy_meson_g12a_usb3_exit(struct phy * phy)292 static int phy_meson_g12a_usb3_exit(struct phy *phy)
293 {
294 	struct phy_g12a_usb3_pcie_priv *priv = dev_get_priv(phy->dev);
295 
296 	return reset_assert_bulk(&priv->resets);
297 }
298 
299 struct phy_ops meson_g12a_usb3_pcie_phy_ops = {
300 	.init = phy_meson_g12a_usb3_init,
301 	.exit = phy_meson_g12a_usb3_exit,
302 };
303 
meson_g12a_usb3_pcie_phy_probe(struct udevice * dev)304 int meson_g12a_usb3_pcie_phy_probe(struct udevice *dev)
305 {
306 	struct phy_g12a_usb3_pcie_priv *priv = dev_get_priv(dev);
307 	int ret;
308 
309 	ret = regmap_init_mem(dev_ofnode(dev), &priv->regmap);
310 	if (ret)
311 		return ret;
312 
313 	ret = reset_get_bulk(dev, &priv->resets);
314 	if (ret == -ENOTSUPP)
315 		return 0;
316 	else if (ret)
317 		return ret;
318 
319 #if CONFIG_IS_ENABLED(CLK)
320 	ret = clk_get_by_index(dev, 0, &priv->clk);
321 	if (ret < 0)
322 		return ret;
323 
324 	ret = clk_enable(&priv->clk);
325 	if (ret && ret != -ENOENT && ret != -ENOTSUPP) {
326 		pr_err("failed to enable PHY clock\n");
327 		clk_free(&priv->clk);
328 		return ret;
329 	}
330 #endif
331 
332 	return 0;
333 }
334 
335 static const struct udevice_id meson_g12a_usb3_pcie_phy_ids[] = {
336 	{ .compatible = "amlogic,g12a-usb3-pcie-phy" },
337 	{ }
338 };
339 
340 U_BOOT_DRIVER(meson_g12a_usb3_pcie_phy) = {
341 	.name = "meson_g12a_usb3_pcie_phy",
342 	.id = UCLASS_PHY,
343 	.of_match = meson_g12a_usb3_pcie_phy_ids,
344 	.probe = meson_g12a_usb3_pcie_phy_probe,
345 	.ops = &meson_g12a_usb3_pcie_phy_ops,
346 	.priv_auto	= sizeof(struct phy_g12a_usb3_pcie_priv),
347 };
348