Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * phy-uniphier-ahci.c - PHY driver for UniPhier AHCI controller
0004  * Copyright 2016-2020, Socionext Inc.
0005  * Author: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
0006  */
0007 
0008 #include <linux/bitfield.h>
0009 #include <linux/bitops.h>
0010 #include <linux/clk.h>
0011 #include <linux/iopoll.h>
0012 #include <linux/module.h>
0013 #include <linux/of.h>
0014 #include <linux/of_platform.h>
0015 #include <linux/phy/phy.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/reset.h>
0018 
0019 struct uniphier_ahciphy_priv {
0020     struct device *dev;
0021     void __iomem  *base;
0022     struct clk *clk, *clk_parent, *clk_parent_gio;
0023     struct reset_control *rst, *rst_parent, *rst_parent_gio;
0024     struct reset_control *rst_pm, *rst_tx, *rst_rx;
0025     const struct uniphier_ahciphy_soc_data *data;
0026 };
0027 
0028 struct uniphier_ahciphy_soc_data {
0029     int (*init)(struct uniphier_ahciphy_priv *priv);
0030     int (*power_on)(struct uniphier_ahciphy_priv *priv);
0031     int (*power_off)(struct uniphier_ahciphy_priv *priv);
0032     bool is_legacy;
0033     bool is_ready_high;
0034     bool is_phy_clk;
0035 };
0036 
0037 /* for Pro4 */
0038 #define CKCTRL0             0x0
0039 #define CKCTRL0_CK_OFF          BIT(9)
0040 #define CKCTRL0_NCY_MASK        GENMASK(8, 4)
0041 #define CKCTRL0_NCY5_MASK       GENMASK(3, 2)
0042 #define CKCTRL0_PRESCALE_MASK       GENMASK(1, 0)
0043 #define CKCTRL1             0x4
0044 #define CKCTRL1_LOS_LVL_MASK        GENMASK(20, 16)
0045 #define CKCTRL1_TX_LVL_MASK     GENMASK(12, 8)
0046 #define RXTXCTRL            0x8
0047 #define RXTXCTRL_RX_EQ_VALL_MASK    GENMASK(31, 29)
0048 #define RXTXCTRL_RX_DPLL_MODE_MASK  GENMASK(28, 26)
0049 #define RXTXCTRL_TX_ATTEN_MASK      GENMASK(14, 12)
0050 #define RXTXCTRL_TX_BOOST_MASK      GENMASK(11, 8)
0051 #define RXTXCTRL_TX_EDGERATE_MASK   GENMASK(3, 2)
0052 #define RXTXCTRL_TX_CKO_EN      BIT(0)
0053 #define RSTPWR              0x30
0054 #define RSTPWR_RX_EN_VAL        BIT(18)
0055 
0056 /* for PXs2/PXs3 */
0057 #define CKCTRL              0x0
0058 #define CKCTRL_P0_READY         BIT(15)
0059 #define CKCTRL_P0_RESET         BIT(10)
0060 #define CKCTRL_REF_SSP_EN       BIT(9)
0061 #define TXCTRL0             0x4
0062 #define TXCTRL0_AMP_G3_MASK     GENMASK(22, 16)
0063 #define TXCTRL0_AMP_G2_MASK     GENMASK(14, 8)
0064 #define TXCTRL0_AMP_G1_MASK     GENMASK(6, 0)
0065 #define TXCTRL1             0x8
0066 #define TXCTRL1_DEEMPH_G3_MASK      GENMASK(21, 16)
0067 #define TXCTRL1_DEEMPH_G2_MASK      GENMASK(13, 8)
0068 #define TXCTRL1_DEEMPH_G1_MASK      GENMASK(5, 0)
0069 #define RXCTRL              0xc
0070 #define RXCTRL_LOS_LVL_MASK     GENMASK(20, 16)
0071 #define RXCTRL_LOS_BIAS_MASK        GENMASK(10, 8)
0072 #define RXCTRL_RX_EQ_MASK       GENMASK(2, 0)
0073 
0074 static int uniphier_ahciphy_pro4_init(struct uniphier_ahciphy_priv *priv)
0075 {
0076     u32 val;
0077 
0078     /* set phy MPLL parameters */
0079     val = readl(priv->base + CKCTRL0);
0080     val &= ~CKCTRL0_NCY_MASK;
0081     val |= FIELD_PREP(CKCTRL0_NCY_MASK, 0x6);
0082     val &= ~CKCTRL0_NCY5_MASK;
0083     val |= FIELD_PREP(CKCTRL0_NCY5_MASK, 0x2);
0084     val &= ~CKCTRL0_PRESCALE_MASK;
0085     val |= FIELD_PREP(CKCTRL0_PRESCALE_MASK, 0x1);
0086     writel(val, priv->base + CKCTRL0);
0087 
0088     /* setup phy control parameters */
0089     val = readl(priv->base + CKCTRL1);
0090     val &= ~CKCTRL1_LOS_LVL_MASK;
0091     val |= FIELD_PREP(CKCTRL1_LOS_LVL_MASK, 0x10);
0092     val &= ~CKCTRL1_TX_LVL_MASK;
0093     val |= FIELD_PREP(CKCTRL1_TX_LVL_MASK, 0x06);
0094     writel(val, priv->base + CKCTRL1);
0095 
0096     val = readl(priv->base + RXTXCTRL);
0097     val &= ~RXTXCTRL_RX_EQ_VALL_MASK;
0098     val |= FIELD_PREP(RXTXCTRL_RX_EQ_VALL_MASK, 0x6);
0099     val &= ~RXTXCTRL_RX_DPLL_MODE_MASK;
0100     val |= FIELD_PREP(RXTXCTRL_RX_DPLL_MODE_MASK, 0x3);
0101     val &= ~RXTXCTRL_TX_ATTEN_MASK;
0102     val |= FIELD_PREP(RXTXCTRL_TX_ATTEN_MASK, 0x3);
0103     val &= ~RXTXCTRL_TX_BOOST_MASK;
0104     val |= FIELD_PREP(RXTXCTRL_TX_BOOST_MASK, 0x5);
0105     val &= ~RXTXCTRL_TX_EDGERATE_MASK;
0106     val |= FIELD_PREP(RXTXCTRL_TX_EDGERATE_MASK, 0x0);
0107     writel(val, priv->base + RXTXCTRL);
0108 
0109     return 0;
0110 }
0111 
0112 static int uniphier_ahciphy_pro4_power_on(struct uniphier_ahciphy_priv *priv)
0113 {
0114     u32 val;
0115     int ret;
0116 
0117     /* enable reference clock for phy */
0118     val = readl(priv->base + CKCTRL0);
0119     val &= ~CKCTRL0_CK_OFF;
0120     writel(val, priv->base + CKCTRL0);
0121 
0122     /* enable TX clock */
0123     val = readl(priv->base + RXTXCTRL);
0124     val |= RXTXCTRL_TX_CKO_EN;
0125     writel(val, priv->base + RXTXCTRL);
0126 
0127     /* wait until RX is ready */
0128     ret = readl_poll_timeout(priv->base + RSTPWR, val,
0129                  !(val & RSTPWR_RX_EN_VAL), 200, 2000);
0130     if (ret) {
0131         dev_err(priv->dev, "Failed to check whether Rx is ready\n");
0132         goto out_disable_clock;
0133     }
0134 
0135     /* release all reset */
0136     ret = reset_control_deassert(priv->rst_pm);
0137     if (ret) {
0138         dev_err(priv->dev, "Failed to release PM reset\n");
0139         goto out_disable_clock;
0140     }
0141 
0142     ret = reset_control_deassert(priv->rst_tx);
0143     if (ret) {
0144         dev_err(priv->dev, "Failed to release Tx reset\n");
0145         goto out_reset_pm_assert;
0146     }
0147 
0148     ret = reset_control_deassert(priv->rst_rx);
0149     if (ret) {
0150         dev_err(priv->dev, "Failed to release Rx reset\n");
0151         goto out_reset_tx_assert;
0152     }
0153 
0154     return 0;
0155 
0156 out_reset_tx_assert:
0157     reset_control_assert(priv->rst_tx);
0158 out_reset_pm_assert:
0159     reset_control_assert(priv->rst_pm);
0160 
0161 out_disable_clock:
0162     /* disable TX clock */
0163     val = readl(priv->base + RXTXCTRL);
0164     val &= ~RXTXCTRL_TX_CKO_EN;
0165     writel(val, priv->base + RXTXCTRL);
0166 
0167     /* disable reference clock for phy */
0168     val = readl(priv->base + CKCTRL0);
0169     val |= CKCTRL0_CK_OFF;
0170     writel(val, priv->base + CKCTRL0);
0171 
0172     return ret;
0173 }
0174 
0175 static int uniphier_ahciphy_pro4_power_off(struct uniphier_ahciphy_priv *priv)
0176 {
0177     u32 val;
0178 
0179     reset_control_assert(priv->rst_rx);
0180     reset_control_assert(priv->rst_tx);
0181     reset_control_assert(priv->rst_pm);
0182 
0183     /* disable TX clock */
0184     val = readl(priv->base + RXTXCTRL);
0185     val &= ~RXTXCTRL_TX_CKO_EN;
0186     writel(val, priv->base + RXTXCTRL);
0187 
0188     /* disable reference clock for phy */
0189     val = readl(priv->base + CKCTRL0);
0190     val |= CKCTRL0_CK_OFF;
0191     writel(val, priv->base + CKCTRL0);
0192 
0193     return 0;
0194 }
0195 
0196 static void uniphier_ahciphy_pxs2_enable(struct uniphier_ahciphy_priv *priv,
0197                      bool enable)
0198 {
0199     u32 val;
0200 
0201     val = readl(priv->base + CKCTRL);
0202 
0203     if (enable) {
0204         val |= CKCTRL_REF_SSP_EN;
0205         writel(val, priv->base + CKCTRL);
0206         val &= ~CKCTRL_P0_RESET;
0207         writel(val, priv->base + CKCTRL);
0208     } else {
0209         val |= CKCTRL_P0_RESET;
0210         writel(val, priv->base + CKCTRL);
0211         val &= ~CKCTRL_REF_SSP_EN;
0212         writel(val, priv->base + CKCTRL);
0213     }
0214 }
0215 
0216 static int uniphier_ahciphy_pxs2_power_on(struct uniphier_ahciphy_priv *priv)
0217 {
0218     int ret;
0219     u32 val;
0220 
0221     uniphier_ahciphy_pxs2_enable(priv, true);
0222 
0223     /* wait until PLL is ready */
0224     if (priv->data->is_ready_high)
0225         ret = readl_poll_timeout(priv->base + CKCTRL, val,
0226                      (val & CKCTRL_P0_READY), 200, 400);
0227     else
0228         ret = readl_poll_timeout(priv->base + CKCTRL, val,
0229                      !(val & CKCTRL_P0_READY), 200, 400);
0230     if (ret) {
0231         dev_err(priv->dev, "Failed to check whether PHY PLL is ready\n");
0232         uniphier_ahciphy_pxs2_enable(priv, false);
0233     }
0234 
0235     return ret;
0236 }
0237 
0238 static int uniphier_ahciphy_pxs2_power_off(struct uniphier_ahciphy_priv *priv)
0239 {
0240     uniphier_ahciphy_pxs2_enable(priv, false);
0241 
0242     return 0;
0243 }
0244 
0245 static int uniphier_ahciphy_pxs3_init(struct uniphier_ahciphy_priv *priv)
0246 {
0247     int i;
0248     u32 val;
0249 
0250     /* setup port parameter */
0251     val = readl(priv->base + TXCTRL0);
0252     val &= ~TXCTRL0_AMP_G3_MASK;
0253     val |= FIELD_PREP(TXCTRL0_AMP_G3_MASK, 0x73);
0254     val &= ~TXCTRL0_AMP_G2_MASK;
0255     val |= FIELD_PREP(TXCTRL0_AMP_G2_MASK, 0x46);
0256     val &= ~TXCTRL0_AMP_G1_MASK;
0257     val |= FIELD_PREP(TXCTRL0_AMP_G1_MASK, 0x42);
0258     writel(val, priv->base + TXCTRL0);
0259 
0260     val = readl(priv->base + TXCTRL1);
0261     val &= ~TXCTRL1_DEEMPH_G3_MASK;
0262     val |= FIELD_PREP(TXCTRL1_DEEMPH_G3_MASK, 0x23);
0263     val &= ~TXCTRL1_DEEMPH_G2_MASK;
0264     val |= FIELD_PREP(TXCTRL1_DEEMPH_G2_MASK, 0x05);
0265     val &= ~TXCTRL1_DEEMPH_G1_MASK;
0266     val |= FIELD_PREP(TXCTRL1_DEEMPH_G1_MASK, 0x05);
0267 
0268     val = readl(priv->base + RXCTRL);
0269     val &= ~RXCTRL_LOS_LVL_MASK;
0270     val |= FIELD_PREP(RXCTRL_LOS_LVL_MASK, 0x9);
0271     val &= ~RXCTRL_LOS_BIAS_MASK;
0272     val |= FIELD_PREP(RXCTRL_LOS_BIAS_MASK, 0x2);
0273     val &= ~RXCTRL_RX_EQ_MASK;
0274     val |= FIELD_PREP(RXCTRL_RX_EQ_MASK, 0x1);
0275 
0276     /* dummy read 25 times to make a wait time for the phy to stabilize */
0277     for (i = 0; i < 25; i++)
0278         readl(priv->base + CKCTRL);
0279 
0280     return 0;
0281 }
0282 
0283 static int uniphier_ahciphy_init(struct phy *phy)
0284 {
0285     struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy);
0286     int ret;
0287 
0288     ret = clk_prepare_enable(priv->clk_parent_gio);
0289     if (ret)
0290         return ret;
0291 
0292     ret = clk_prepare_enable(priv->clk_parent);
0293     if (ret)
0294         goto out_clk_gio_disable;
0295 
0296     ret = reset_control_deassert(priv->rst_parent_gio);
0297     if (ret)
0298         goto out_clk_disable;
0299 
0300     ret = reset_control_deassert(priv->rst_parent);
0301     if (ret)
0302         goto out_rst_gio_assert;
0303 
0304     if (priv->data->init) {
0305         ret = priv->data->init(priv);
0306         if (ret)
0307             goto out_rst_assert;
0308     }
0309 
0310     return 0;
0311 
0312 out_rst_assert:
0313     reset_control_assert(priv->rst_parent);
0314 out_rst_gio_assert:
0315     reset_control_assert(priv->rst_parent_gio);
0316 out_clk_disable:
0317     clk_disable_unprepare(priv->clk_parent);
0318 out_clk_gio_disable:
0319     clk_disable_unprepare(priv->clk_parent_gio);
0320 
0321     return ret;
0322 }
0323 
0324 static int uniphier_ahciphy_exit(struct phy *phy)
0325 {
0326     struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy);
0327 
0328     reset_control_assert(priv->rst_parent);
0329     reset_control_assert(priv->rst_parent_gio);
0330     clk_disable_unprepare(priv->clk_parent);
0331     clk_disable_unprepare(priv->clk_parent_gio);
0332 
0333     return 0;
0334 }
0335 
0336 static int uniphier_ahciphy_power_on(struct phy *phy)
0337 {
0338     struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy);
0339     int ret = 0;
0340 
0341     ret = clk_prepare_enable(priv->clk);
0342     if (ret)
0343         return ret;
0344 
0345     ret = reset_control_deassert(priv->rst);
0346     if (ret)
0347         goto out_clk_disable;
0348 
0349     if (priv->data->power_on) {
0350         ret = priv->data->power_on(priv);
0351         if (ret)
0352             goto out_reset_assert;
0353     }
0354 
0355     return 0;
0356 
0357 out_reset_assert:
0358     reset_control_assert(priv->rst);
0359 out_clk_disable:
0360     clk_disable_unprepare(priv->clk);
0361 
0362     return ret;
0363 }
0364 
0365 static int uniphier_ahciphy_power_off(struct phy *phy)
0366 {
0367     struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy);
0368     int ret = 0;
0369 
0370     if (priv->data->power_off)
0371         ret = priv->data->power_off(priv);
0372 
0373     reset_control_assert(priv->rst);
0374     clk_disable_unprepare(priv->clk);
0375 
0376     return ret;
0377 }
0378 
0379 static const struct phy_ops uniphier_ahciphy_ops = {
0380     .init  = uniphier_ahciphy_init,
0381     .exit  = uniphier_ahciphy_exit,
0382     .power_on  = uniphier_ahciphy_power_on,
0383     .power_off = uniphier_ahciphy_power_off,
0384     .owner = THIS_MODULE,
0385 };
0386 
0387 static int uniphier_ahciphy_probe(struct platform_device *pdev)
0388 {
0389     struct device *dev = &pdev->dev;
0390     struct uniphier_ahciphy_priv *priv;
0391     struct phy *phy;
0392     struct phy_provider *phy_provider;
0393 
0394     priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0395     if (!priv)
0396         return -ENOMEM;
0397 
0398     priv->dev = dev;
0399     priv->data = of_device_get_match_data(dev);
0400     if (WARN_ON(!priv->data))
0401         return -EINVAL;
0402 
0403     priv->base = devm_platform_ioremap_resource(pdev, 0);
0404     if (IS_ERR(priv->base))
0405         return PTR_ERR(priv->base);
0406 
0407     priv->clk_parent = devm_clk_get(dev, "link");
0408     if (IS_ERR(priv->clk_parent))
0409         return PTR_ERR(priv->clk_parent);
0410 
0411     if (priv->data->is_phy_clk) {
0412         priv->clk = devm_clk_get(dev, "phy");
0413         if (IS_ERR(priv->clk))
0414             return PTR_ERR(priv->clk);
0415     }
0416 
0417     priv->rst_parent = devm_reset_control_get_shared(dev, "link");
0418     if (IS_ERR(priv->rst_parent))
0419         return PTR_ERR(priv->rst_parent);
0420 
0421     priv->rst = devm_reset_control_get_shared(dev, "phy");
0422     if (IS_ERR(priv->rst))
0423         return PTR_ERR(priv->rst);
0424 
0425     if (priv->data->is_legacy) {
0426         priv->clk_parent_gio = devm_clk_get(dev, "gio");
0427         if (IS_ERR(priv->clk_parent_gio))
0428             return PTR_ERR(priv->clk_parent_gio);
0429         priv->rst_parent_gio =
0430             devm_reset_control_get_shared(dev, "gio");
0431         if (IS_ERR(priv->rst_parent_gio))
0432             return PTR_ERR(priv->rst_parent_gio);
0433 
0434         priv->rst_pm = devm_reset_control_get_shared(dev, "pm");
0435         if (IS_ERR(priv->rst_pm))
0436             return PTR_ERR(priv->rst_pm);
0437 
0438         priv->rst_tx = devm_reset_control_get_shared(dev, "tx");
0439         if (IS_ERR(priv->rst_tx))
0440             return PTR_ERR(priv->rst_tx);
0441 
0442         priv->rst_rx = devm_reset_control_get_shared(dev, "rx");
0443         if (IS_ERR(priv->rst_rx))
0444             return PTR_ERR(priv->rst_rx);
0445     }
0446 
0447     phy = devm_phy_create(dev, dev->of_node, &uniphier_ahciphy_ops);
0448     if (IS_ERR(phy)) {
0449         dev_err(dev, "failed to create phy\n");
0450         return PTR_ERR(phy);
0451     }
0452 
0453     phy_set_drvdata(phy, priv);
0454     phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
0455     if (IS_ERR(phy_provider))
0456         return PTR_ERR(phy_provider);
0457 
0458     return 0;
0459 }
0460 
0461 static const struct uniphier_ahciphy_soc_data uniphier_pro4_data = {
0462     .init = uniphier_ahciphy_pro4_init,
0463     .power_on  = uniphier_ahciphy_pro4_power_on,
0464     .power_off = uniphier_ahciphy_pro4_power_off,
0465     .is_legacy = true,
0466     .is_phy_clk = false,
0467 };
0468 
0469 static const struct uniphier_ahciphy_soc_data uniphier_pxs2_data = {
0470     .power_on  = uniphier_ahciphy_pxs2_power_on,
0471     .power_off = uniphier_ahciphy_pxs2_power_off,
0472     .is_legacy = false,
0473     .is_ready_high = false,
0474     .is_phy_clk = false,
0475 };
0476 
0477 static const struct uniphier_ahciphy_soc_data uniphier_pxs3_data = {
0478     .init      = uniphier_ahciphy_pxs3_init,
0479     .power_on  = uniphier_ahciphy_pxs2_power_on,
0480     .power_off = uniphier_ahciphy_pxs2_power_off,
0481     .is_legacy = false,
0482     .is_ready_high = true,
0483     .is_phy_clk = true,
0484 };
0485 
0486 static const struct of_device_id uniphier_ahciphy_match[] = {
0487     {
0488         .compatible = "socionext,uniphier-pro4-ahci-phy",
0489         .data = &uniphier_pro4_data,
0490     },
0491     {
0492         .compatible = "socionext,uniphier-pxs2-ahci-phy",
0493         .data = &uniphier_pxs2_data,
0494     },
0495     {
0496         .compatible = "socionext,uniphier-pxs3-ahci-phy",
0497         .data = &uniphier_pxs3_data,
0498     },
0499     { /* Sentinel */ },
0500 };
0501 MODULE_DEVICE_TABLE(of, uniphier_ahciphy_match);
0502 
0503 static struct platform_driver uniphier_ahciphy_driver = {
0504     .probe = uniphier_ahciphy_probe,
0505     .driver = {
0506         .name = "uniphier-ahci-phy",
0507         .of_match_table = uniphier_ahciphy_match,
0508     },
0509 };
0510 module_platform_driver(uniphier_ahciphy_driver);
0511 
0512 MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>");
0513 MODULE_DESCRIPTION("UniPhier PHY driver for AHCI controller");
0514 MODULE_LICENSE("GPL v2");