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