Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / drivers / phy / socionext / phy-uniphier-ahci.c
blob28cf3efe06956db1415f225ac3e53eeb9cc9a8bd
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 */
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>
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;
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;
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)
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)
74 static int uniphier_ahciphy_pro4_init(struct uniphier_ahciphy_priv *priv)
76 u32 val;
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);
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);
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);
109 return 0;
112 static int uniphier_ahciphy_pro4_power_on(struct uniphier_ahciphy_priv *priv)
114 u32 val;
115 int ret;
117 /* enable reference clock for phy */
118 val = readl(priv->base + CKCTRL0);
119 val &= ~CKCTRL0_CK_OFF;
120 writel(val, priv->base + CKCTRL0);
122 /* enable TX clock */
123 val = readl(priv->base + RXTXCTRL);
124 val |= RXTXCTRL_TX_CKO_EN;
125 writel(val, priv->base + RXTXCTRL);
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;
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;
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;
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;
154 return 0;
156 out_reset_tx_assert:
157 reset_control_assert(priv->rst_tx);
158 out_reset_pm_assert:
159 reset_control_assert(priv->rst_pm);
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);
167 /* disable reference clock for phy */
168 val = readl(priv->base + CKCTRL0);
169 val |= CKCTRL0_CK_OFF;
170 writel(val, priv->base + CKCTRL0);
172 return ret;
175 static int uniphier_ahciphy_pro4_power_off(struct uniphier_ahciphy_priv *priv)
177 u32 val;
179 reset_control_assert(priv->rst_rx);
180 reset_control_assert(priv->rst_tx);
181 reset_control_assert(priv->rst_pm);
183 /* disable TX clock */
184 val = readl(priv->base + RXTXCTRL);
185 val &= ~RXTXCTRL_TX_CKO_EN;
186 writel(val, priv->base + RXTXCTRL);
188 /* disable reference clock for phy */
189 val = readl(priv->base + CKCTRL0);
190 val |= CKCTRL0_CK_OFF;
191 writel(val, priv->base + CKCTRL0);
193 return 0;
196 static void uniphier_ahciphy_pxs2_enable(struct uniphier_ahciphy_priv *priv,
197 bool enable)
199 u32 val;
201 val = readl(priv->base + CKCTRL);
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);
216 static int uniphier_ahciphy_pxs2_power_on(struct uniphier_ahciphy_priv *priv)
218 int ret;
219 u32 val;
221 uniphier_ahciphy_pxs2_enable(priv, true);
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);
235 return ret;
238 static int uniphier_ahciphy_pxs2_power_off(struct uniphier_ahciphy_priv *priv)
240 uniphier_ahciphy_pxs2_enable(priv, false);
242 return 0;
245 static int uniphier_ahciphy_pxs3_init(struct uniphier_ahciphy_priv *priv)
247 int i;
248 u32 val;
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);
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);
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);
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);
280 return 0;
283 static int uniphier_ahciphy_init(struct phy *phy)
285 struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy);
286 int ret;
288 ret = clk_prepare_enable(priv->clk_parent_gio);
289 if (ret)
290 return ret;
292 ret = clk_prepare_enable(priv->clk_parent);
293 if (ret)
294 goto out_clk_gio_disable;
296 ret = reset_control_deassert(priv->rst_parent_gio);
297 if (ret)
298 goto out_clk_disable;
300 ret = reset_control_deassert(priv->rst_parent);
301 if (ret)
302 goto out_rst_gio_assert;
304 if (priv->data->init) {
305 ret = priv->data->init(priv);
306 if (ret)
307 goto out_rst_assert;
310 return 0;
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);
321 return ret;
324 static int uniphier_ahciphy_exit(struct phy *phy)
326 struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy);
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);
333 return 0;
336 static int uniphier_ahciphy_power_on(struct phy *phy)
338 struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy);
339 int ret = 0;
341 ret = clk_prepare_enable(priv->clk);
342 if (ret)
343 return ret;
345 ret = reset_control_deassert(priv->rst);
346 if (ret)
347 goto out_clk_disable;
349 if (priv->data->power_on) {
350 ret = priv->data->power_on(priv);
351 if (ret)
352 goto out_reset_assert;
355 return 0;
357 out_reset_assert:
358 reset_control_assert(priv->rst);
359 out_clk_disable:
360 clk_disable_unprepare(priv->clk);
362 return ret;
365 static int uniphier_ahciphy_power_off(struct phy *phy)
367 struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy);
368 int ret = 0;
370 if (priv->data->power_off)
371 ret = priv->data->power_off(priv);
373 reset_control_assert(priv->rst);
374 clk_disable_unprepare(priv->clk);
376 return ret;
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,
387 static int uniphier_ahciphy_probe(struct platform_device *pdev)
389 struct device *dev = &pdev->dev;
390 struct uniphier_ahciphy_priv *priv;
391 struct phy *phy;
392 struct phy_provider *phy_provider;
394 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
395 if (!priv)
396 return -ENOMEM;
398 priv->dev = dev;
399 priv->data = of_device_get_match_data(dev);
400 if (WARN_ON(!priv->data))
401 return -EINVAL;
403 priv->base = devm_platform_ioremap_resource(pdev, 0);
404 if (IS_ERR(priv->base))
405 return PTR_ERR(priv->base);
407 priv->clk_parent = devm_clk_get(dev, "link");
408 if (IS_ERR(priv->clk_parent))
409 return PTR_ERR(priv->clk_parent);
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);
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);
421 priv->rst = devm_reset_control_get_shared(dev, "phy");
422 if (IS_ERR(priv->rst))
423 return PTR_ERR(priv->rst);
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);
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);
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);
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);
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);
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);
458 return 0;
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,
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,
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,
486 static const struct of_device_id uniphier_ahciphy_match[] = {
488 .compatible = "socionext,uniphier-pro4-ahci-phy",
489 .data = &uniphier_pro4_data,
492 .compatible = "socionext,uniphier-pxs2-ahci-phy",
493 .data = &uniphier_pxs2_data,
496 .compatible = "socionext,uniphier-pxs3-ahci-phy",
497 .data = &uniphier_pxs3_data,
499 { /* Sentinel */ },
501 MODULE_DEVICE_TABLE(of, uniphier_ahciphy_match);
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,
510 module_platform_driver(uniphier_ahciphy_driver);
512 MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>");
513 MODULE_DESCRIPTION("UniPhier PHY driver for AHCI controller");
514 MODULE_LICENSE("GPL v2");