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