Merge tag 'exfat-for-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkin...
[linux-2.6-microblaze.git] / drivers / phy / socionext / phy-uniphier-ahci.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * phy-uniphier-ahci.c - PHY driver for UniPhier AHCI controller
4  * Copyright 2016-2020, Socionext Inc.
5  * Author: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
6  */
7
8 #include <linux/bitfield.h>
9 #include <linux/bitops.h>
10 #include <linux/clk.h>
11 #include <linux/iopoll.h>
12 #include <linux/module.h>
13 #include <linux/of.h>
14 #include <linux/of_platform.h>
15 #include <linux/phy/phy.h>
16 #include <linux/platform_device.h>
17 #include <linux/reset.h>
18
19 struct uniphier_ahciphy_priv {
20         struct device *dev;
21         void __iomem  *base;
22         struct clk *clk, *clk_parent, *clk_parent_gio;
23         struct reset_control *rst, *rst_parent, *rst_parent_gio;
24         struct reset_control *rst_pm, *rst_tx, *rst_rx;
25         const struct uniphier_ahciphy_soc_data *data;
26 };
27
28 struct uniphier_ahciphy_soc_data {
29         int (*init)(struct uniphier_ahciphy_priv *priv);
30         int (*power_on)(struct uniphier_ahciphy_priv *priv);
31         int (*power_off)(struct uniphier_ahciphy_priv *priv);
32         bool is_legacy;
33         bool is_ready_high;
34         bool is_phy_clk;
35 };
36
37 /* for Pro4 */
38 #define CKCTRL0                         0x0
39 #define CKCTRL0_CK_OFF                  BIT(9)
40 #define CKCTRL0_NCY_MASK                GENMASK(8, 4)
41 #define CKCTRL0_NCY5_MASK               GENMASK(3, 2)
42 #define CKCTRL0_PRESCALE_MASK           GENMASK(1, 0)
43 #define CKCTRL1                         0x4
44 #define CKCTRL1_LOS_LVL_MASK            GENMASK(20, 16)
45 #define CKCTRL1_TX_LVL_MASK             GENMASK(12, 8)
46 #define RXTXCTRL                        0x8
47 #define RXTXCTRL_RX_EQ_VALL_MASK        GENMASK(31, 29)
48 #define RXTXCTRL_RX_DPLL_MODE_MASK      GENMASK(28, 26)
49 #define RXTXCTRL_TX_ATTEN_MASK          GENMASK(14, 12)
50 #define RXTXCTRL_TX_BOOST_MASK          GENMASK(11, 8)
51 #define RXTXCTRL_TX_EDGERATE_MASK       GENMASK(3, 2)
52 #define RXTXCTRL_TX_CKO_EN              BIT(0)
53 #define RSTPWR                          0x30
54 #define RSTPWR_RX_EN_VAL                BIT(18)
55
56 /* for PXs2/PXs3 */
57 #define CKCTRL                          0x0
58 #define CKCTRL_P0_READY                 BIT(15)
59 #define CKCTRL_P0_RESET                 BIT(10)
60 #define CKCTRL_REF_SSP_EN               BIT(9)
61 #define TXCTRL0                         0x4
62 #define TXCTRL0_AMP_G3_MASK             GENMASK(22, 16)
63 #define TXCTRL0_AMP_G2_MASK             GENMASK(14, 8)
64 #define TXCTRL0_AMP_G1_MASK             GENMASK(6, 0)
65 #define TXCTRL1                         0x8
66 #define TXCTRL1_DEEMPH_G3_MASK          GENMASK(21, 16)
67 #define TXCTRL1_DEEMPH_G2_MASK          GENMASK(13, 8)
68 #define TXCTRL1_DEEMPH_G1_MASK          GENMASK(5, 0)
69 #define RXCTRL                          0xc
70 #define RXCTRL_LOS_LVL_MASK             GENMASK(20, 16)
71 #define RXCTRL_LOS_BIAS_MASK            GENMASK(10, 8)
72 #define RXCTRL_RX_EQ_MASK               GENMASK(2, 0)
73
74 static int uniphier_ahciphy_pro4_init(struct uniphier_ahciphy_priv *priv)
75 {
76         u32 val;
77
78         /* set phy MPLL parameters */
79         val = readl(priv->base + CKCTRL0);
80         val &= ~CKCTRL0_NCY_MASK;
81         val |= FIELD_PREP(CKCTRL0_NCY_MASK, 0x6);
82         val &= ~CKCTRL0_NCY5_MASK;
83         val |= FIELD_PREP(CKCTRL0_NCY5_MASK, 0x2);
84         val &= ~CKCTRL0_PRESCALE_MASK;
85         val |= FIELD_PREP(CKCTRL0_PRESCALE_MASK, 0x1);
86         writel(val, priv->base + CKCTRL0);
87
88         /* setup phy control parameters */
89         val = readl(priv->base + CKCTRL1);
90         val &= ~CKCTRL1_LOS_LVL_MASK;
91         val |= FIELD_PREP(CKCTRL1_LOS_LVL_MASK, 0x10);
92         val &= ~CKCTRL1_TX_LVL_MASK;
93         val |= FIELD_PREP(CKCTRL1_TX_LVL_MASK, 0x06);
94         writel(val, priv->base + CKCTRL1);
95
96         val = readl(priv->base + RXTXCTRL);
97         val &= ~RXTXCTRL_RX_EQ_VALL_MASK;
98         val |= FIELD_PREP(RXTXCTRL_RX_EQ_VALL_MASK, 0x6);
99         val &= ~RXTXCTRL_RX_DPLL_MODE_MASK;
100         val |= FIELD_PREP(RXTXCTRL_RX_DPLL_MODE_MASK, 0x3);
101         val &= ~RXTXCTRL_TX_ATTEN_MASK;
102         val |= FIELD_PREP(RXTXCTRL_TX_ATTEN_MASK, 0x3);
103         val &= ~RXTXCTRL_TX_BOOST_MASK;
104         val |= FIELD_PREP(RXTXCTRL_TX_BOOST_MASK, 0x5);
105         val &= ~RXTXCTRL_TX_EDGERATE_MASK;
106         val |= FIELD_PREP(RXTXCTRL_TX_EDGERATE_MASK, 0x0);
107         writel(val, priv->base + RXTXCTRL);
108
109         return 0;
110 }
111
112 static int uniphier_ahciphy_pro4_power_on(struct uniphier_ahciphy_priv *priv)
113 {
114         u32 val;
115         int ret;
116
117         /* enable reference clock for phy */
118         val = readl(priv->base + CKCTRL0);
119         val &= ~CKCTRL0_CK_OFF;
120         writel(val, priv->base + CKCTRL0);
121
122         /* enable TX clock */
123         val = readl(priv->base + RXTXCTRL);
124         val |= RXTXCTRL_TX_CKO_EN;
125         writel(val, priv->base + RXTXCTRL);
126
127         /* wait until RX is ready */
128         ret = readl_poll_timeout(priv->base + RSTPWR, val,
129                                  !(val & RSTPWR_RX_EN_VAL), 200, 2000);
130         if (ret) {
131                 dev_err(priv->dev, "Failed to check whether Rx is ready\n");
132                 goto out_disable_clock;
133         }
134
135         /* release all reset */
136         ret = reset_control_deassert(priv->rst_pm);
137         if (ret) {
138                 dev_err(priv->dev, "Failed to release PM reset\n");
139                 goto out_disable_clock;
140         }
141
142         ret = reset_control_deassert(priv->rst_tx);
143         if (ret) {
144                 dev_err(priv->dev, "Failed to release Tx reset\n");
145                 goto out_reset_pm_assert;
146         }
147
148         ret = reset_control_deassert(priv->rst_rx);
149         if (ret) {
150                 dev_err(priv->dev, "Failed to release Rx reset\n");
151                 goto out_reset_tx_assert;
152         }
153
154         return 0;
155
156 out_reset_tx_assert:
157         reset_control_assert(priv->rst_tx);
158 out_reset_pm_assert:
159         reset_control_assert(priv->rst_pm);
160
161 out_disable_clock:
162         /* disable TX clock */
163         val = readl(priv->base + RXTXCTRL);
164         val &= ~RXTXCTRL_TX_CKO_EN;
165         writel(val, priv->base + RXTXCTRL);
166
167         /* disable reference clock for phy */
168         val = readl(priv->base + CKCTRL0);
169         val |= CKCTRL0_CK_OFF;
170         writel(val, priv->base + CKCTRL0);
171
172         return ret;
173 }
174
175 static int uniphier_ahciphy_pro4_power_off(struct uniphier_ahciphy_priv *priv)
176 {
177         u32 val;
178
179         reset_control_assert(priv->rst_rx);
180         reset_control_assert(priv->rst_tx);
181         reset_control_assert(priv->rst_pm);
182
183         /* disable TX clock */
184         val = readl(priv->base + RXTXCTRL);
185         val &= ~RXTXCTRL_TX_CKO_EN;
186         writel(val, priv->base + RXTXCTRL);
187
188         /* disable reference clock for phy */
189         val = readl(priv->base + CKCTRL0);
190         val |= CKCTRL0_CK_OFF;
191         writel(val, priv->base + CKCTRL0);
192
193         return 0;
194 }
195
196 static void uniphier_ahciphy_pxs2_enable(struct uniphier_ahciphy_priv *priv,
197                                          bool enable)
198 {
199         u32 val;
200
201         val = readl(priv->base + CKCTRL);
202
203         if (enable) {
204                 val |= CKCTRL_REF_SSP_EN;
205                 writel(val, priv->base + CKCTRL);
206                 val &= ~CKCTRL_P0_RESET;
207                 writel(val, priv->base + CKCTRL);
208         } else {
209                 val |= CKCTRL_P0_RESET;
210                 writel(val, priv->base + CKCTRL);
211                 val &= ~CKCTRL_REF_SSP_EN;
212                 writel(val, priv->base + CKCTRL);
213         }
214 }
215
216 static int uniphier_ahciphy_pxs2_power_on(struct uniphier_ahciphy_priv *priv)
217 {
218         int ret;
219         u32 val;
220
221         uniphier_ahciphy_pxs2_enable(priv, true);
222
223         /* wait until PLL is ready */
224         if (priv->data->is_ready_high)
225                 ret = readl_poll_timeout(priv->base + CKCTRL, val,
226                                          (val & CKCTRL_P0_READY), 200, 400);
227         else
228                 ret = readl_poll_timeout(priv->base + CKCTRL, val,
229                                          !(val & CKCTRL_P0_READY), 200, 400);
230         if (ret) {
231                 dev_err(priv->dev, "Failed to check whether PHY PLL is ready\n");
232                 uniphier_ahciphy_pxs2_enable(priv, false);
233         }
234
235         return ret;
236 }
237
238 static int uniphier_ahciphy_pxs2_power_off(struct uniphier_ahciphy_priv *priv)
239 {
240         uniphier_ahciphy_pxs2_enable(priv, false);
241
242         return 0;
243 }
244
245 static int uniphier_ahciphy_pxs3_init(struct uniphier_ahciphy_priv *priv)
246 {
247         int i;
248         u32 val;
249
250         /* setup port parameter */
251         val = readl(priv->base + TXCTRL0);
252         val &= ~TXCTRL0_AMP_G3_MASK;
253         val |= FIELD_PREP(TXCTRL0_AMP_G3_MASK, 0x73);
254         val &= ~TXCTRL0_AMP_G2_MASK;
255         val |= FIELD_PREP(TXCTRL0_AMP_G2_MASK, 0x46);
256         val &= ~TXCTRL0_AMP_G1_MASK;
257         val |= FIELD_PREP(TXCTRL0_AMP_G1_MASK, 0x42);
258         writel(val, priv->base + TXCTRL0);
259
260         val = readl(priv->base + TXCTRL1);
261         val &= ~TXCTRL1_DEEMPH_G3_MASK;
262         val |= FIELD_PREP(TXCTRL1_DEEMPH_G3_MASK, 0x23);
263         val &= ~TXCTRL1_DEEMPH_G2_MASK;
264         val |= FIELD_PREP(TXCTRL1_DEEMPH_G2_MASK, 0x05);
265         val &= ~TXCTRL1_DEEMPH_G1_MASK;
266         val |= FIELD_PREP(TXCTRL1_DEEMPH_G1_MASK, 0x05);
267
268         val = readl(priv->base + RXCTRL);
269         val &= ~RXCTRL_LOS_LVL_MASK;
270         val |= FIELD_PREP(RXCTRL_LOS_LVL_MASK, 0x9);
271         val &= ~RXCTRL_LOS_BIAS_MASK;
272         val |= FIELD_PREP(RXCTRL_LOS_BIAS_MASK, 0x2);
273         val &= ~RXCTRL_RX_EQ_MASK;
274         val |= FIELD_PREP(RXCTRL_RX_EQ_MASK, 0x1);
275
276         /* dummy read 25 times to make a wait time for the phy to stabilize */
277         for (i = 0; i < 25; i++)
278                 readl(priv->base + CKCTRL);
279
280         return 0;
281 }
282
283 static int uniphier_ahciphy_init(struct phy *phy)
284 {
285         struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy);
286         int ret;
287
288         ret = clk_prepare_enable(priv->clk_parent_gio);
289         if (ret)
290                 return ret;
291
292         ret = clk_prepare_enable(priv->clk_parent);
293         if (ret)
294                 goto out_clk_gio_disable;
295
296         ret = reset_control_deassert(priv->rst_parent_gio);
297         if (ret)
298                 goto out_clk_disable;
299
300         ret = reset_control_deassert(priv->rst_parent);
301         if (ret)
302                 goto out_rst_gio_assert;
303
304         if (priv->data->init) {
305                 ret = priv->data->init(priv);
306                 if (ret)
307                         goto out_rst_assert;
308         }
309
310         return 0;
311
312 out_rst_assert:
313         reset_control_assert(priv->rst_parent);
314 out_rst_gio_assert:
315         reset_control_assert(priv->rst_parent_gio);
316 out_clk_disable:
317         clk_disable_unprepare(priv->clk_parent);
318 out_clk_gio_disable:
319         clk_disable_unprepare(priv->clk_parent_gio);
320
321         return ret;
322 }
323
324 static int uniphier_ahciphy_exit(struct phy *phy)
325 {
326         struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy);
327
328         reset_control_assert(priv->rst_parent);
329         reset_control_assert(priv->rst_parent_gio);
330         clk_disable_unprepare(priv->clk_parent);
331         clk_disable_unprepare(priv->clk_parent_gio);
332
333         return 0;
334 }
335
336 static int uniphier_ahciphy_power_on(struct phy *phy)
337 {
338         struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy);
339         int ret = 0;
340
341         ret = clk_prepare_enable(priv->clk);
342         if (ret)
343                 return ret;
344
345         ret = reset_control_deassert(priv->rst);
346         if (ret)
347                 goto out_clk_disable;
348
349         if (priv->data->power_on) {
350                 ret = priv->data->power_on(priv);
351                 if (ret)
352                         goto out_reset_assert;
353         }
354
355         return 0;
356
357 out_reset_assert:
358         reset_control_assert(priv->rst);
359 out_clk_disable:
360         clk_disable_unprepare(priv->clk);
361
362         return ret;
363 }
364
365 static int uniphier_ahciphy_power_off(struct phy *phy)
366 {
367         struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy);
368         int ret = 0;
369
370         if (priv->data->power_off)
371                 ret = priv->data->power_off(priv);
372
373         reset_control_assert(priv->rst);
374         clk_disable_unprepare(priv->clk);
375
376         return ret;
377 }
378
379 static const struct phy_ops uniphier_ahciphy_ops = {
380         .init  = uniphier_ahciphy_init,
381         .exit  = uniphier_ahciphy_exit,
382         .power_on  = uniphier_ahciphy_power_on,
383         .power_off = uniphier_ahciphy_power_off,
384         .owner = THIS_MODULE,
385 };
386
387 static int uniphier_ahciphy_probe(struct platform_device *pdev)
388 {
389         struct device *dev = &pdev->dev;
390         struct uniphier_ahciphy_priv *priv;
391         struct phy *phy;
392         struct phy_provider *phy_provider;
393
394         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
395         if (!priv)
396                 return -ENOMEM;
397
398         priv->dev = dev;
399         priv->data = of_device_get_match_data(dev);
400         if (WARN_ON(!priv->data))
401                 return -EINVAL;
402
403         priv->base = devm_platform_ioremap_resource(pdev, 0);
404         if (IS_ERR(priv->base))
405                 return PTR_ERR(priv->base);
406
407         priv->clk_parent = devm_clk_get(dev, "link");
408         if (IS_ERR(priv->clk_parent))
409                 return PTR_ERR(priv->clk_parent);
410
411         if (priv->data->is_phy_clk) {
412                 priv->clk = devm_clk_get(dev, "phy");
413                 if (IS_ERR(priv->clk))
414                         return PTR_ERR(priv->clk);
415         }
416
417         priv->rst_parent = devm_reset_control_get_shared(dev, "link");
418         if (IS_ERR(priv->rst_parent))
419                 return PTR_ERR(priv->rst_parent);
420
421         priv->rst = devm_reset_control_get_shared(dev, "phy");
422         if (IS_ERR(priv->rst))
423                 return PTR_ERR(priv->rst);
424
425         if (priv->data->is_legacy) {
426                 priv->clk_parent_gio = devm_clk_get(dev, "gio");
427                 if (IS_ERR(priv->clk_parent_gio))
428                         return PTR_ERR(priv->clk_parent_gio);
429                 priv->rst_parent_gio =
430                         devm_reset_control_get_shared(dev, "gio");
431                 if (IS_ERR(priv->rst_parent_gio))
432                         return PTR_ERR(priv->rst_parent_gio);
433
434                 priv->rst_pm = devm_reset_control_get_shared(dev, "pm");
435                 if (IS_ERR(priv->rst_pm))
436                         return PTR_ERR(priv->rst_pm);
437
438                 priv->rst_tx = devm_reset_control_get_shared(dev, "tx");
439                 if (IS_ERR(priv->rst_tx))
440                         return PTR_ERR(priv->rst_tx);
441
442                 priv->rst_rx = devm_reset_control_get_shared(dev, "rx");
443                 if (IS_ERR(priv->rst_rx))
444                         return PTR_ERR(priv->rst_rx);
445         }
446
447         phy = devm_phy_create(dev, dev->of_node, &uniphier_ahciphy_ops);
448         if (IS_ERR(phy)) {
449                 dev_err(dev, "failed to create phy\n");
450                 return PTR_ERR(phy);
451         }
452
453         phy_set_drvdata(phy, priv);
454         phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
455         if (IS_ERR(phy_provider))
456                 return PTR_ERR(phy_provider);
457
458         return 0;
459 }
460
461 static const struct uniphier_ahciphy_soc_data uniphier_pro4_data = {
462         .init = uniphier_ahciphy_pro4_init,
463         .power_on  = uniphier_ahciphy_pro4_power_on,
464         .power_off = uniphier_ahciphy_pro4_power_off,
465         .is_legacy = true,
466         .is_phy_clk = false,
467 };
468
469 static const struct uniphier_ahciphy_soc_data uniphier_pxs2_data = {
470         .power_on  = uniphier_ahciphy_pxs2_power_on,
471         .power_off = uniphier_ahciphy_pxs2_power_off,
472         .is_legacy = false,
473         .is_ready_high = false,
474         .is_phy_clk = false,
475 };
476
477 static const struct uniphier_ahciphy_soc_data uniphier_pxs3_data = {
478         .init      = uniphier_ahciphy_pxs3_init,
479         .power_on  = uniphier_ahciphy_pxs2_power_on,
480         .power_off = uniphier_ahciphy_pxs2_power_off,
481         .is_legacy = false,
482         .is_ready_high = true,
483         .is_phy_clk = true,
484 };
485
486 static const struct of_device_id uniphier_ahciphy_match[] = {
487         {
488                 .compatible = "socionext,uniphier-pro4-ahci-phy",
489                 .data = &uniphier_pro4_data,
490         },
491         {
492                 .compatible = "socionext,uniphier-pxs2-ahci-phy",
493                 .data = &uniphier_pxs2_data,
494         },
495         {
496                 .compatible = "socionext,uniphier-pxs3-ahci-phy",
497                 .data = &uniphier_pxs3_data,
498         },
499         { /* Sentinel */ },
500 };
501 MODULE_DEVICE_TABLE(of, uniphier_ahciphy_match);
502
503 static struct platform_driver uniphier_ahciphy_driver = {
504         .probe = uniphier_ahciphy_probe,
505         .driver = {
506                 .name = "uniphier-ahci-phy",
507                 .of_match_table = uniphier_ahciphy_match,
508         },
509 };
510 module_platform_driver(uniphier_ahciphy_driver);
511
512 MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>");
513 MODULE_DESCRIPTION("UniPhier PHY driver for AHCI controller");
514 MODULE_LICENSE("GPL v2");