root/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. phy_g12a_usb3_pcie_cr_bus_addr
  2. phy_g12a_usb3_pcie_cr_bus_read
  3. phy_g12a_usb3_pcie_cr_bus_write
  4. phy_g12a_usb3_init
  5. phy_g12a_usb3_pcie_init
  6. phy_g12a_usb3_pcie_exit
  7. phy_g12a_usb3_pcie_xlate
  8. phy_g12a_usb3_pcie_probe

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Amlogic G12A USB3 + PCIE Combo PHY driver
   4  *
   5  * Copyright (C) 2017 Amlogic, Inc. All rights reserved
   6  * Copyright (C) 2019 BayLibre, SAS
   7  * Author: Neil Armstrong <narmstrong@baylibre.com>
   8  */
   9 
  10 #include <linux/bitfield.h>
  11 #include <linux/bitops.h>
  12 #include <linux/clk.h>
  13 #include <linux/module.h>
  14 #include <linux/of_device.h>
  15 #include <linux/phy/phy.h>
  16 #include <linux/regmap.h>
  17 #include <linux/reset.h>
  18 #include <linux/platform_device.h>
  19 #include <dt-bindings/phy/phy.h>
  20 
  21 #define PHY_R0                                                  0x00
  22         #define PHY_R0_PCIE_POWER_STATE                         GENMASK(4, 0)
  23         #define PHY_R0_PCIE_USB3_SWITCH                         GENMASK(6, 5)
  24 
  25 #define PHY_R1                                                  0x04
  26         #define PHY_R1_PHY_TX1_TERM_OFFSET                      GENMASK(4, 0)
  27         #define PHY_R1_PHY_TX0_TERM_OFFSET                      GENMASK(9, 5)
  28         #define PHY_R1_PHY_RX1_EQ                               GENMASK(12, 10)
  29         #define PHY_R1_PHY_RX0_EQ                               GENMASK(15, 13)
  30         #define PHY_R1_PHY_LOS_LEVEL                            GENMASK(20, 16)
  31         #define PHY_R1_PHY_LOS_BIAS                             GENMASK(23, 21)
  32         #define PHY_R1_PHY_REF_CLKDIV2                          BIT(24)
  33         #define PHY_R1_PHY_MPLL_MULTIPLIER                      GENMASK(31, 25)
  34 
  35 #define PHY_R2                                                  0x08
  36         #define PHY_R2_PCS_TX_DEEMPH_GEN2_6DB                   GENMASK(5, 0)
  37         #define PHY_R2_PCS_TX_DEEMPH_GEN2_3P5DB                 GENMASK(11, 6)
  38         #define PHY_R2_PCS_TX_DEEMPH_GEN1                       GENMASK(17, 12)
  39         #define PHY_R2_PHY_TX_VBOOST_LVL                        GENMASK(20, 18)
  40 
  41 #define PHY_R4                                                  0x10
  42         #define PHY_R4_PHY_CR_WRITE                             BIT(0)
  43         #define PHY_R4_PHY_CR_READ                              BIT(1)
  44         #define PHY_R4_PHY_CR_DATA_IN                           GENMASK(17, 2)
  45         #define PHY_R4_PHY_CR_CAP_DATA                          BIT(18)
  46         #define PHY_R4_PHY_CR_CAP_ADDR                          BIT(19)
  47 
  48 #define PHY_R5                                                  0x14
  49         #define PHY_R5_PHY_CR_DATA_OUT                          GENMASK(15, 0)
  50         #define PHY_R5_PHY_CR_ACK                               BIT(16)
  51         #define PHY_R5_PHY_BS_OUT                               BIT(17)
  52 
  53 struct phy_g12a_usb3_pcie_priv {
  54         struct regmap           *regmap;
  55         struct regmap           *regmap_cr;
  56         struct clk              *clk_ref;
  57         struct reset_control    *reset;
  58         struct phy              *phy;
  59         unsigned int            mode;
  60 };
  61 
  62 static const struct regmap_config phy_g12a_usb3_pcie_regmap_conf = {
  63         .reg_bits = 8,
  64         .val_bits = 32,
  65         .reg_stride = 4,
  66         .max_register = PHY_R5,
  67 };
  68 
  69 static int phy_g12a_usb3_pcie_cr_bus_addr(struct phy_g12a_usb3_pcie_priv *priv,
  70                                           unsigned int addr)
  71 {
  72         unsigned int val, reg;
  73         int ret;
  74 
  75         reg = FIELD_PREP(PHY_R4_PHY_CR_DATA_IN, addr);
  76 
  77         regmap_write(priv->regmap, PHY_R4, reg);
  78         regmap_write(priv->regmap, PHY_R4, reg);
  79 
  80         regmap_write(priv->regmap, PHY_R4, reg | PHY_R4_PHY_CR_CAP_ADDR);
  81 
  82         ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
  83                                        (val & PHY_R5_PHY_CR_ACK),
  84                                        5, 1000);
  85         if (ret)
  86                 return ret;
  87 
  88         regmap_write(priv->regmap, PHY_R4, reg);
  89 
  90         ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
  91                                        !(val & PHY_R5_PHY_CR_ACK),
  92                                        5, 1000);
  93         if (ret)
  94                 return ret;
  95 
  96         return 0;
  97 }
  98 
  99 static int phy_g12a_usb3_pcie_cr_bus_read(void *context, unsigned int addr,
 100                                           unsigned int *data)
 101 {
 102         struct phy_g12a_usb3_pcie_priv *priv = context;
 103         unsigned int val;
 104         int ret;
 105 
 106         ret = phy_g12a_usb3_pcie_cr_bus_addr(priv, addr);
 107         if (ret)
 108                 return ret;
 109 
 110         regmap_write(priv->regmap, PHY_R4, 0);
 111         regmap_write(priv->regmap, PHY_R4, PHY_R4_PHY_CR_READ);
 112 
 113         ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
 114                                        (val & PHY_R5_PHY_CR_ACK),
 115                                        5, 1000);
 116         if (ret)
 117                 return ret;
 118 
 119         *data = FIELD_GET(PHY_R5_PHY_CR_DATA_OUT, val);
 120 
 121         regmap_write(priv->regmap, PHY_R4, 0);
 122 
 123         ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
 124                                        !(val & PHY_R5_PHY_CR_ACK),
 125                                        5, 1000);
 126         if (ret)
 127                 return ret;
 128 
 129         return 0;
 130 }
 131 
 132 static int phy_g12a_usb3_pcie_cr_bus_write(void *context, unsigned int addr,
 133                                            unsigned int data)
 134 {
 135         struct phy_g12a_usb3_pcie_priv *priv = context;
 136         unsigned int val, reg;
 137         int ret;
 138 
 139         ret = phy_g12a_usb3_pcie_cr_bus_addr(priv, addr);
 140         if (ret)
 141                 return ret;
 142 
 143         reg = FIELD_PREP(PHY_R4_PHY_CR_DATA_IN, data);
 144 
 145         regmap_write(priv->regmap, PHY_R4, reg);
 146         regmap_write(priv->regmap, PHY_R4, reg);
 147 
 148         regmap_write(priv->regmap, PHY_R4, reg | PHY_R4_PHY_CR_CAP_DATA);
 149 
 150         ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
 151                                        (val & PHY_R5_PHY_CR_ACK),
 152                                        5, 1000);
 153         if (ret)
 154                 return ret;
 155 
 156         regmap_write(priv->regmap, PHY_R4, reg);
 157 
 158         ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
 159                                        (val & PHY_R5_PHY_CR_ACK) == 0,
 160                                        5, 1000);
 161         if (ret)
 162                 return ret;
 163 
 164         regmap_write(priv->regmap, PHY_R4, reg);
 165 
 166         regmap_write(priv->regmap, PHY_R4, reg | PHY_R4_PHY_CR_WRITE);
 167 
 168         ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
 169                                        (val & PHY_R5_PHY_CR_ACK),
 170                                        5, 1000);
 171         if (ret)
 172                 return ret;
 173 
 174         regmap_write(priv->regmap, PHY_R4, reg);
 175 
 176         ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
 177                                        (val & PHY_R5_PHY_CR_ACK) == 0,
 178                                        5, 1000);
 179         if (ret)
 180                 return ret;
 181 
 182         return 0;
 183 }
 184 
 185 static const struct regmap_config phy_g12a_usb3_pcie_cr_regmap_conf = {
 186         .reg_bits = 16,
 187         .val_bits = 16,
 188         .reg_read = phy_g12a_usb3_pcie_cr_bus_read,
 189         .reg_write = phy_g12a_usb3_pcie_cr_bus_write,
 190         .max_register = 0xffff,
 191         .disable_locking = true,
 192 };
 193 
 194 static int phy_g12a_usb3_init(struct phy *phy)
 195 {
 196         struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy);
 197         int data, ret;
 198 
 199         /* Switch PHY to USB3 */
 200         /* TODO figure out how to handle when PCIe was set in the bootloader */
 201         regmap_update_bits(priv->regmap, PHY_R0,
 202                            PHY_R0_PCIE_USB3_SWITCH,
 203                            PHY_R0_PCIE_USB3_SWITCH);
 204 
 205         /*
 206          * WORKAROUND: There is SSPHY suspend bug due to
 207          * which USB enumerates
 208          * in HS mode instead of SS mode. Workaround it by asserting
 209          * LANE0.TX_ALT_BLOCK.EN_ALT_BUS to enable TX to use alt bus
 210          * mode
 211          */
 212         ret = regmap_update_bits(priv->regmap_cr, 0x102d, BIT(7), BIT(7));
 213         if (ret)
 214                 return ret;
 215 
 216         ret = regmap_update_bits(priv->regmap_cr, 0x1010, 0xff0, 20);
 217         if (ret)
 218                 return ret;
 219 
 220         /*
 221          * Fix RX Equalization setting as follows
 222          * LANE0.RX_OVRD_IN_HI. RX_EQ_EN set to 0
 223          * LANE0.RX_OVRD_IN_HI.RX_EQ_EN_OVRD set to 1
 224          * LANE0.RX_OVRD_IN_HI.RX_EQ set to 3
 225          * LANE0.RX_OVRD_IN_HI.RX_EQ_OVRD set to 1
 226          */
 227         ret = regmap_read(priv->regmap_cr, 0x1006, &data);
 228         if (ret)
 229                 return ret;
 230 
 231         data &= ~BIT(6);
 232         data |= BIT(7);
 233         data &= ~(0x7 << 8);
 234         data |= (0x3 << 8);
 235         data |= (1 << 11);
 236         ret = regmap_write(priv->regmap_cr, 0x1006, data);
 237         if (ret)
 238                 return ret;
 239 
 240         /*
 241          * Set EQ and TX launch amplitudes as follows
 242          * LANE0.TX_OVRD_DRV_LO.PREEMPH set to 22
 243          * LANE0.TX_OVRD_DRV_LO.AMPLITUDE set to 127
 244          * LANE0.TX_OVRD_DRV_LO.EN set to 1.
 245          */
 246         ret = regmap_read(priv->regmap_cr, 0x1002, &data);
 247         if (ret)
 248                 return ret;
 249 
 250         data &= ~0x3f80;
 251         data |= (0x16 << 7);
 252         data &= ~0x7f;
 253         data |= (0x7f | BIT(14));
 254         ret = regmap_write(priv->regmap_cr, 0x1002, data);
 255         if (ret)
 256                 return ret;
 257 
 258         /* MPLL_LOOP_CTL.PROP_CNTRL = 8 */
 259         ret = regmap_update_bits(priv->regmap_cr, 0x30, 0xf << 4, 8 << 4);
 260         if (ret)
 261                 return ret;
 262 
 263         regmap_update_bits(priv->regmap, PHY_R2,
 264                         PHY_R2_PHY_TX_VBOOST_LVL,
 265                         FIELD_PREP(PHY_R2_PHY_TX_VBOOST_LVL, 0x4));
 266 
 267         regmap_update_bits(priv->regmap, PHY_R1,
 268                         PHY_R1_PHY_LOS_BIAS | PHY_R1_PHY_LOS_LEVEL,
 269                         FIELD_PREP(PHY_R1_PHY_LOS_BIAS, 4) |
 270                         FIELD_PREP(PHY_R1_PHY_LOS_LEVEL, 9));
 271 
 272         return 0;
 273 }
 274 
 275 static int phy_g12a_usb3_pcie_init(struct phy *phy)
 276 {
 277         struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy);
 278         int ret;
 279 
 280         ret = reset_control_reset(priv->reset);
 281         if (ret)
 282                 return ret;
 283 
 284         if (priv->mode == PHY_TYPE_USB3)
 285                 return phy_g12a_usb3_init(phy);
 286 
 287         /* Power UP PCIE */
 288         /* TODO figure out when the bootloader has set USB3 mode before */
 289         regmap_update_bits(priv->regmap, PHY_R0,
 290                            PHY_R0_PCIE_POWER_STATE,
 291                            FIELD_PREP(PHY_R0_PCIE_POWER_STATE, 0x1c));
 292 
 293         return 0;
 294 }
 295 
 296 static int phy_g12a_usb3_pcie_exit(struct phy *phy)
 297 {
 298         struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy);
 299 
 300         return reset_control_reset(priv->reset);
 301 }
 302 
 303 static struct phy *phy_g12a_usb3_pcie_xlate(struct device *dev,
 304                                             struct of_phandle_args *args)
 305 {
 306         struct phy_g12a_usb3_pcie_priv *priv = dev_get_drvdata(dev);
 307         unsigned int mode;
 308 
 309         if (args->args_count < 1) {
 310                 dev_err(dev, "invalid number of arguments\n");
 311                 return ERR_PTR(-EINVAL);
 312         }
 313 
 314         mode = args->args[0];
 315 
 316         if (mode != PHY_TYPE_USB3 && mode != PHY_TYPE_PCIE) {
 317                 dev_err(dev, "invalid phy mode select argument\n");
 318                 return ERR_PTR(-EINVAL);
 319         }
 320 
 321         priv->mode = mode;
 322 
 323         return priv->phy;
 324 }
 325 
 326 static const struct phy_ops phy_g12a_usb3_pcie_ops = {
 327         .init           = phy_g12a_usb3_pcie_init,
 328         .exit           = phy_g12a_usb3_pcie_exit,
 329         .owner          = THIS_MODULE,
 330 };
 331 
 332 static int phy_g12a_usb3_pcie_probe(struct platform_device *pdev)
 333 {
 334         struct device *dev = &pdev->dev;
 335         struct device_node *np = dev->of_node;
 336         struct phy_g12a_usb3_pcie_priv *priv;
 337         struct resource *res;
 338         struct phy_provider *phy_provider;
 339         void __iomem *base;
 340         int ret;
 341 
 342         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 343         if (!priv)
 344                 return -ENOMEM;
 345 
 346         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 347         base = devm_ioremap_resource(dev, res);
 348         if (IS_ERR(base))
 349                 return PTR_ERR(base);
 350 
 351         priv->regmap = devm_regmap_init_mmio(dev, base,
 352                                              &phy_g12a_usb3_pcie_regmap_conf);
 353         if (IS_ERR(priv->regmap))
 354                 return PTR_ERR(priv->regmap);
 355 
 356         priv->regmap_cr = devm_regmap_init(dev, NULL, priv,
 357                                            &phy_g12a_usb3_pcie_cr_regmap_conf);
 358         if (IS_ERR(priv->regmap_cr))
 359                 return PTR_ERR(priv->regmap_cr);
 360 
 361         priv->clk_ref = devm_clk_get(dev, "ref_clk");
 362         if (IS_ERR(priv->clk_ref))
 363                 return PTR_ERR(priv->clk_ref);
 364 
 365         ret = clk_prepare_enable(priv->clk_ref);
 366         if (ret)
 367                 goto err_disable_clk_ref;
 368 
 369         priv->reset = devm_reset_control_array_get(dev, false, false);
 370         if (IS_ERR(priv->reset))
 371                 return PTR_ERR(priv->reset);
 372 
 373         priv->phy = devm_phy_create(dev, np, &phy_g12a_usb3_pcie_ops);
 374         if (IS_ERR(priv->phy)) {
 375                 ret = PTR_ERR(priv->phy);
 376                 if (ret != -EPROBE_DEFER)
 377                         dev_err(dev, "failed to create PHY\n");
 378 
 379                 return ret;
 380         }
 381 
 382         phy_set_drvdata(priv->phy, priv);
 383         dev_set_drvdata(dev, priv);
 384 
 385         phy_provider = devm_of_phy_provider_register(dev,
 386                                                      phy_g12a_usb3_pcie_xlate);
 387 
 388         return PTR_ERR_OR_ZERO(phy_provider);
 389 
 390 err_disable_clk_ref:
 391         clk_disable_unprepare(priv->clk_ref);
 392 
 393         return ret;
 394 }
 395 
 396 static const struct of_device_id phy_g12a_usb3_pcie_of_match[] = {
 397         { .compatible = "amlogic,g12a-usb3-pcie-phy", },
 398         { },
 399 };
 400 MODULE_DEVICE_TABLE(of, phy_g12a_usb3_pcie_of_match);
 401 
 402 static struct platform_driver phy_g12a_usb3_pcie_driver = {
 403         .probe  = phy_g12a_usb3_pcie_probe,
 404         .driver = {
 405                 .name           = "phy-g12a-usb3-pcie",
 406                 .of_match_table = phy_g12a_usb3_pcie_of_match,
 407         },
 408 };
 409 module_platform_driver(phy_g12a_usb3_pcie_driver);
 410 
 411 MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
 412 MODULE_DESCRIPTION("Amlogic G12A USB3 + PCIE Combo PHY driver");
 413 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */