Lines Matching +full:uniphier +full:- +full:pxs3 +full:- +full:ahci +full:- +full:phy

1 // SPDX-License-Identifier: GPL-2.0
3 * phy-uniphier-ahci.c - PHY driver for UniPhier AHCI controller
4 * Copyright 2016-2020, Socionext Inc.
15 #include <linux/phy/phy.h>
56 /* for PXs2/PXs3 */
78 /* set phy MPLL parameters */ in uniphier_ahciphy_pro4_init()
79 val = readl(priv->base + CKCTRL0); in uniphier_ahciphy_pro4_init()
86 writel(val, priv->base + CKCTRL0); in uniphier_ahciphy_pro4_init()
88 /* setup phy control parameters */ in uniphier_ahciphy_pro4_init()
89 val = readl(priv->base + CKCTRL1); in uniphier_ahciphy_pro4_init()
94 writel(val, priv->base + CKCTRL1); in uniphier_ahciphy_pro4_init()
96 val = readl(priv->base + RXTXCTRL); in uniphier_ahciphy_pro4_init()
107 writel(val, priv->base + RXTXCTRL); in uniphier_ahciphy_pro4_init()
117 /* enable reference clock for phy */ in uniphier_ahciphy_pro4_power_on()
118 val = readl(priv->base + CKCTRL0); in uniphier_ahciphy_pro4_power_on()
120 writel(val, priv->base + CKCTRL0); in uniphier_ahciphy_pro4_power_on()
123 val = readl(priv->base + RXTXCTRL); in uniphier_ahciphy_pro4_power_on()
125 writel(val, priv->base + RXTXCTRL); in uniphier_ahciphy_pro4_power_on()
128 ret = readl_poll_timeout(priv->base + RSTPWR, val, in uniphier_ahciphy_pro4_power_on()
131 dev_err(priv->dev, "Failed to check whether Rx is ready\n"); in uniphier_ahciphy_pro4_power_on()
136 ret = reset_control_deassert(priv->rst_pm); in uniphier_ahciphy_pro4_power_on()
138 dev_err(priv->dev, "Failed to release PM reset\n"); in uniphier_ahciphy_pro4_power_on()
142 ret = reset_control_deassert(priv->rst_tx); in uniphier_ahciphy_pro4_power_on()
144 dev_err(priv->dev, "Failed to release Tx reset\n"); in uniphier_ahciphy_pro4_power_on()
148 ret = reset_control_deassert(priv->rst_rx); in uniphier_ahciphy_pro4_power_on()
150 dev_err(priv->dev, "Failed to release Rx reset\n"); in uniphier_ahciphy_pro4_power_on()
157 reset_control_assert(priv->rst_tx); in uniphier_ahciphy_pro4_power_on()
159 reset_control_assert(priv->rst_pm); in uniphier_ahciphy_pro4_power_on()
163 val = readl(priv->base + RXTXCTRL); in uniphier_ahciphy_pro4_power_on()
165 writel(val, priv->base + RXTXCTRL); in uniphier_ahciphy_pro4_power_on()
167 /* disable reference clock for phy */ in uniphier_ahciphy_pro4_power_on()
168 val = readl(priv->base + CKCTRL0); in uniphier_ahciphy_pro4_power_on()
170 writel(val, priv->base + CKCTRL0); in uniphier_ahciphy_pro4_power_on()
179 reset_control_assert(priv->rst_rx); in uniphier_ahciphy_pro4_power_off()
180 reset_control_assert(priv->rst_tx); in uniphier_ahciphy_pro4_power_off()
181 reset_control_assert(priv->rst_pm); in uniphier_ahciphy_pro4_power_off()
184 val = readl(priv->base + RXTXCTRL); in uniphier_ahciphy_pro4_power_off()
186 writel(val, priv->base + RXTXCTRL); in uniphier_ahciphy_pro4_power_off()
188 /* disable reference clock for phy */ in uniphier_ahciphy_pro4_power_off()
189 val = readl(priv->base + CKCTRL0); in uniphier_ahciphy_pro4_power_off()
191 writel(val, priv->base + CKCTRL0); in uniphier_ahciphy_pro4_power_off()
201 val = readl(priv->base + CKCTRL); in uniphier_ahciphy_pxs2_enable()
205 writel(val, priv->base + CKCTRL); in uniphier_ahciphy_pxs2_enable()
207 writel(val, priv->base + CKCTRL); in uniphier_ahciphy_pxs2_enable()
210 writel(val, priv->base + CKCTRL); in uniphier_ahciphy_pxs2_enable()
212 writel(val, priv->base + CKCTRL); in uniphier_ahciphy_pxs2_enable()
224 if (priv->data->is_ready_high) in uniphier_ahciphy_pxs2_power_on()
225 ret = readl_poll_timeout(priv->base + CKCTRL, val, in uniphier_ahciphy_pxs2_power_on()
228 ret = readl_poll_timeout(priv->base + CKCTRL, val, in uniphier_ahciphy_pxs2_power_on()
231 dev_err(priv->dev, "Failed to check whether PHY PLL is ready\n"); in uniphier_ahciphy_pxs2_power_on()
251 val = readl(priv->base + TXCTRL0); in uniphier_ahciphy_pxs3_init()
258 writel(val, priv->base + TXCTRL0); in uniphier_ahciphy_pxs3_init()
260 val = readl(priv->base + TXCTRL1); in uniphier_ahciphy_pxs3_init()
268 val = readl(priv->base + RXCTRL); in uniphier_ahciphy_pxs3_init()
276 /* dummy read 25 times to make a wait time for the phy to stabilize */ in uniphier_ahciphy_pxs3_init()
278 readl(priv->base + CKCTRL); in uniphier_ahciphy_pxs3_init()
283 static int uniphier_ahciphy_init(struct phy *phy) in uniphier_ahciphy_init() argument
285 struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy); in uniphier_ahciphy_init()
288 ret = clk_prepare_enable(priv->clk_parent_gio); in uniphier_ahciphy_init()
292 ret = clk_prepare_enable(priv->clk_parent); in uniphier_ahciphy_init()
296 ret = reset_control_deassert(priv->rst_parent_gio); in uniphier_ahciphy_init()
300 ret = reset_control_deassert(priv->rst_parent); in uniphier_ahciphy_init()
304 if (priv->data->init) { in uniphier_ahciphy_init()
305 ret = priv->data->init(priv); in uniphier_ahciphy_init()
313 reset_control_assert(priv->rst_parent); in uniphier_ahciphy_init()
315 reset_control_assert(priv->rst_parent_gio); in uniphier_ahciphy_init()
317 clk_disable_unprepare(priv->clk_parent); in uniphier_ahciphy_init()
319 clk_disable_unprepare(priv->clk_parent_gio); in uniphier_ahciphy_init()
324 static int uniphier_ahciphy_exit(struct phy *phy) in uniphier_ahciphy_exit() argument
326 struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy); in uniphier_ahciphy_exit()
328 reset_control_assert(priv->rst_parent); in uniphier_ahciphy_exit()
329 reset_control_assert(priv->rst_parent_gio); in uniphier_ahciphy_exit()
330 clk_disable_unprepare(priv->clk_parent); in uniphier_ahciphy_exit()
331 clk_disable_unprepare(priv->clk_parent_gio); in uniphier_ahciphy_exit()
336 static int uniphier_ahciphy_power_on(struct phy *phy) in uniphier_ahciphy_power_on() argument
338 struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy); in uniphier_ahciphy_power_on()
341 ret = clk_prepare_enable(priv->clk); in uniphier_ahciphy_power_on()
345 ret = reset_control_deassert(priv->rst); in uniphier_ahciphy_power_on()
349 if (priv->data->power_on) { in uniphier_ahciphy_power_on()
350 ret = priv->data->power_on(priv); in uniphier_ahciphy_power_on()
358 reset_control_assert(priv->rst); in uniphier_ahciphy_power_on()
360 clk_disable_unprepare(priv->clk); in uniphier_ahciphy_power_on()
365 static int uniphier_ahciphy_power_off(struct phy *phy) in uniphier_ahciphy_power_off() argument
367 struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy); in uniphier_ahciphy_power_off()
370 if (priv->data->power_off) in uniphier_ahciphy_power_off()
371 ret = priv->data->power_off(priv); in uniphier_ahciphy_power_off()
373 reset_control_assert(priv->rst); in uniphier_ahciphy_power_off()
374 clk_disable_unprepare(priv->clk); in uniphier_ahciphy_power_off()
389 struct device *dev = &pdev->dev; in uniphier_ahciphy_probe()
391 struct phy *phy; in uniphier_ahciphy_probe() local
396 return -ENOMEM; in uniphier_ahciphy_probe()
398 priv->dev = dev; in uniphier_ahciphy_probe()
399 priv->data = of_device_get_match_data(dev); in uniphier_ahciphy_probe()
400 if (WARN_ON(!priv->data)) in uniphier_ahciphy_probe()
401 return -EINVAL; in uniphier_ahciphy_probe()
403 priv->base = devm_platform_ioremap_resource(pdev, 0); in uniphier_ahciphy_probe()
404 if (IS_ERR(priv->base)) in uniphier_ahciphy_probe()
405 return PTR_ERR(priv->base); in uniphier_ahciphy_probe()
407 priv->clk_parent = devm_clk_get(dev, "link"); in uniphier_ahciphy_probe()
408 if (IS_ERR(priv->clk_parent)) in uniphier_ahciphy_probe()
409 return PTR_ERR(priv->clk_parent); in uniphier_ahciphy_probe()
411 if (priv->data->is_phy_clk) { in uniphier_ahciphy_probe()
412 priv->clk = devm_clk_get(dev, "phy"); in uniphier_ahciphy_probe()
413 if (IS_ERR(priv->clk)) in uniphier_ahciphy_probe()
414 return PTR_ERR(priv->clk); in uniphier_ahciphy_probe()
417 priv->rst_parent = devm_reset_control_get_shared(dev, "link"); in uniphier_ahciphy_probe()
418 if (IS_ERR(priv->rst_parent)) in uniphier_ahciphy_probe()
419 return PTR_ERR(priv->rst_parent); in uniphier_ahciphy_probe()
421 priv->rst = devm_reset_control_get_shared(dev, "phy"); in uniphier_ahciphy_probe()
422 if (IS_ERR(priv->rst)) in uniphier_ahciphy_probe()
423 return PTR_ERR(priv->rst); in uniphier_ahciphy_probe()
425 if (priv->data->is_legacy) { in uniphier_ahciphy_probe()
426 priv->clk_parent_gio = devm_clk_get(dev, "gio"); in uniphier_ahciphy_probe()
427 if (IS_ERR(priv->clk_parent_gio)) in uniphier_ahciphy_probe()
428 return PTR_ERR(priv->clk_parent_gio); in uniphier_ahciphy_probe()
429 priv->rst_parent_gio = in uniphier_ahciphy_probe()
431 if (IS_ERR(priv->rst_parent_gio)) in uniphier_ahciphy_probe()
432 return PTR_ERR(priv->rst_parent_gio); in uniphier_ahciphy_probe()
434 priv->rst_pm = devm_reset_control_get_shared(dev, "pm"); in uniphier_ahciphy_probe()
435 if (IS_ERR(priv->rst_pm)) in uniphier_ahciphy_probe()
436 return PTR_ERR(priv->rst_pm); in uniphier_ahciphy_probe()
438 priv->rst_tx = devm_reset_control_get_shared(dev, "tx"); in uniphier_ahciphy_probe()
439 if (IS_ERR(priv->rst_tx)) in uniphier_ahciphy_probe()
440 return PTR_ERR(priv->rst_tx); in uniphier_ahciphy_probe()
442 priv->rst_rx = devm_reset_control_get_shared(dev, "rx"); in uniphier_ahciphy_probe()
443 if (IS_ERR(priv->rst_rx)) in uniphier_ahciphy_probe()
444 return PTR_ERR(priv->rst_rx); in uniphier_ahciphy_probe()
447 phy = devm_phy_create(dev, dev->of_node, &uniphier_ahciphy_ops); in uniphier_ahciphy_probe()
448 if (IS_ERR(phy)) { in uniphier_ahciphy_probe()
449 dev_err(dev, "failed to create phy\n"); in uniphier_ahciphy_probe()
450 return PTR_ERR(phy); in uniphier_ahciphy_probe()
453 phy_set_drvdata(phy, priv); in uniphier_ahciphy_probe()
488 .compatible = "socionext,uniphier-pro4-ahci-phy",
492 .compatible = "socionext,uniphier-pxs2-ahci-phy",
496 .compatible = "socionext,uniphier-pxs3-ahci-phy",
506 .name = "uniphier-ahci-phy",
513 MODULE_DESCRIPTION("UniPhier PHY driver for AHCI controller");