linux/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c
<<
>>
Prefs
   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
  53struct 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
  62static 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
  69static 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
  99static 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
 132static 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
 185static 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
 194static 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
 275static 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
 296static 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
 303static 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
 326static 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
 332static 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
 390err_disable_clk_ref:
 391        clk_disable_unprepare(priv->clk_ref);
 392
 393        return ret;
 394}
 395
 396static const struct of_device_id phy_g12a_usb3_pcie_of_match[] = {
 397        { .compatible = "amlogic,g12a-usb3-pcie-phy", },
 398        { },
 399};
 400MODULE_DEVICE_TABLE(of, phy_g12a_usb3_pcie_of_match);
 401
 402static 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};
 409module_platform_driver(phy_g12a_usb3_pcie_driver);
 410
 411MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
 412MODULE_DESCRIPTION("Amlogic G12A USB3 + PCIE Combo PHY driver");
 413MODULE_LICENSE("GPL v2");
 414