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