uboot/drivers/phy/meson-g12a-usb3-pcie.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Meson G12A USB3+PCIE Combo PHY driver
   4 *
   5 * Copyright (C) 2018 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
   6 * Copyright (C) 2019 BayLibre, SAS
   7 * Author: Neil Armstrong <narmstron@baylibre.com>
   8 */
   9
  10#include <common.h>
  11#include <clk.h>
  12#include <dm.h>
  13#include <malloc.h>
  14#include <regmap.h>
  15#include <errno.h>
  16#include <asm/io.h>
  17#include <reset.h>
  18#include <bitfield.h>
  19#include <generic-phy.h>
  20#include <linux/delay.h>
  21
  22#include <linux/bitops.h>
  23#include <linux/compat.h>
  24#include <linux/bitfield.h>
  25
  26#define PHY_TYPE_PCIE           2
  27#define PHY_TYPE_USB3           4
  28
  29#define PHY_R0                                                  0x00
  30        #define PHY_R0_PCIE_POWER_STATE                         GENMASK(4, 0)
  31        #define PHY_R0_PCIE_USB3_SWITCH                         GENMASK(6, 5)
  32
  33#define PHY_R1                                                  0x04
  34        #define PHY_R1_PHY_TX1_TERM_OFFSET                      GENMASK(4, 0)
  35        #define PHY_R1_PHY_TX0_TERM_OFFSET                      GENMASK(9, 5)
  36        #define PHY_R1_PHY_RX1_EQ                               GENMASK(12, 10)
  37        #define PHY_R1_PHY_RX0_EQ                               GENMASK(15, 13)
  38        #define PHY_R1_PHY_LOS_LEVEL                            GENMASK(20, 16)
  39        #define PHY_R1_PHY_LOS_BIAS                             GENMASK(23, 21)
  40        #define PHY_R1_PHY_REF_CLKDIV2                          BIT(24)
  41        #define PHY_R1_PHY_MPLL_MULTIPLIER                      GENMASK(31, 25)
  42
  43#define PHY_R2                                                  0x08
  44        #define PHY_R2_PCS_TX_DEEMPH_GEN2_6DB                   GENMASK(5, 0)
  45        #define PHY_R2_PCS_TX_DEEMPH_GEN2_3P5DB                 GENMASK(11, 6)
  46        #define PHY_R2_PCS_TX_DEEMPH_GEN1                       GENMASK(17, 12)
  47        #define PHY_R2_PHY_TX_VBOOST_LVL                        GENMASK(20, 18)
  48
  49#define PHY_R4                                                  0x10
  50        #define PHY_R4_PHY_CR_WRITE                             BIT(0)
  51        #define PHY_R4_PHY_CR_READ                              BIT(1)
  52        #define PHY_R4_PHY_CR_DATA_IN                           GENMASK(17, 2)
  53        #define PHY_R4_PHY_CR_CAP_DATA                          BIT(18)
  54        #define PHY_R4_PHY_CR_CAP_ADDR                          BIT(19)
  55
  56#define PHY_R5                                                  0x14
  57        #define PHY_R5_PHY_CR_DATA_OUT                          GENMASK(15, 0)
  58        #define PHY_R5_PHY_CR_ACK                               BIT(16)
  59        #define PHY_R5_PHY_BS_OUT                               BIT(17)
  60
  61#define PCIE_RESET_DELAY                                        500
  62
  63struct phy_g12a_usb3_pcie_priv {
  64        struct regmap           *regmap;
  65#if CONFIG_IS_ENABLED(CLK)
  66        struct clk              clk;
  67#endif
  68        struct reset_ctl_bulk   resets;
  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
 102phy_g12a_usb3_pcie_cr_bus_read(struct phy_g12a_usb3_pcie_priv *priv,
 103                               unsigned int addr, unsigned int *data)
 104{
 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
 135phy_g12a_usb3_pcie_cr_bus_write(struct phy_g12a_usb3_pcie_priv *priv,
 136                                unsigned int addr, unsigned int data)
 137{
 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 int
 188phy_g12a_usb3_pcie_cr_bus_update_bits(struct phy_g12a_usb3_pcie_priv *priv,
 189                                      uint offset, uint mask, uint val)
 190{
 191        uint reg;
 192        int ret;
 193
 194        ret = phy_g12a_usb3_pcie_cr_bus_read(priv, offset, &reg);
 195        if (ret)
 196                return ret;
 197
 198        reg &= ~mask;
 199
 200        return phy_g12a_usb3_pcie_cr_bus_write(priv, offset, reg | val);
 201}
 202
 203static int phy_meson_g12a_usb3_init(struct phy *phy)
 204{
 205        struct udevice *dev = phy->dev;
 206        struct phy_g12a_usb3_pcie_priv *priv = dev_get_priv(dev);
 207        unsigned int data;
 208        int ret;
 209
 210        ret = reset_assert_bulk(&priv->resets);
 211        udelay(1);
 212        ret |= reset_deassert_bulk(&priv->resets);
 213        if (ret)
 214                return ret;
 215
 216        /* Switch PHY to USB3 */
 217        regmap_update_bits(priv->regmap, PHY_R0,
 218                           PHY_R0_PCIE_USB3_SWITCH,
 219                           PHY_R0_PCIE_USB3_SWITCH);
 220
 221        /*
 222         * WORKAROUND: There is SSPHY suspend bug due to
 223         * which USB enumerates
 224         * in HS mode instead of SS mode. Workaround it by asserting
 225         * LANE0.TX_ALT_BLOCK.EN_ALT_BUS to enable TX to use alt bus
 226         * mode
 227         */
 228        ret = phy_g12a_usb3_pcie_cr_bus_update_bits(priv, 0x102d,
 229                                                    BIT(7), BIT(7));
 230        if (ret)
 231                return ret;
 232
 233        ret = phy_g12a_usb3_pcie_cr_bus_update_bits(priv, 0x1010, 0xff0, 20);
 234        if (ret)
 235                return ret;
 236
 237        /*
 238         * Fix RX Equalization setting as follows
 239         * LANE0.RX_OVRD_IN_HI. RX_EQ_EN set to 0
 240         * LANE0.RX_OVRD_IN_HI.RX_EQ_EN_OVRD set to 1
 241         * LANE0.RX_OVRD_IN_HI.RX_EQ set to 3
 242         * LANE0.RX_OVRD_IN_HI.RX_EQ_OVRD set to 1
 243         */
 244        ret = phy_g12a_usb3_pcie_cr_bus_read(priv, 0x1006, &data);
 245        if (ret)
 246                return ret;
 247
 248        data &= ~BIT(6);
 249        data |= BIT(7);
 250        data &= ~(0x7 << 8);
 251        data |= (0x3 << 8);
 252        data |= (1 << 11);
 253        ret = phy_g12a_usb3_pcie_cr_bus_write(priv, 0x1006, data);
 254        if (ret)
 255                return ret;
 256
 257        /*
 258         * Set EQ and TX launch amplitudes as follows
 259         * LANE0.TX_OVRD_DRV_LO.PREEMPH set to 22
 260         * LANE0.TX_OVRD_DRV_LO.AMPLITUDE set to 127
 261         * LANE0.TX_OVRD_DRV_LO.EN set to 1.
 262         */
 263        ret = phy_g12a_usb3_pcie_cr_bus_read(priv, 0x1002, &data);
 264        if (ret)
 265                return ret;
 266
 267        data &= ~0x3f80;
 268        data |= (0x16 << 7);
 269        data &= ~0x7f;
 270        data |= (0x7f | BIT(14));
 271        ret = phy_g12a_usb3_pcie_cr_bus_write(priv, 0x1002, data);
 272        if (ret)
 273                return ret;
 274
 275        /*
 276         * MPLL_LOOP_CTL.PROP_CNTRL = 8
 277         */
 278        ret = phy_g12a_usb3_pcie_cr_bus_update_bits(priv, 0x30,
 279                                                    0xf << 4, 8 << 4);
 280        if (ret)
 281                return ret;
 282
 283        regmap_update_bits(priv->regmap, PHY_R2,
 284                        PHY_R2_PHY_TX_VBOOST_LVL,
 285                        FIELD_PREP(PHY_R2_PHY_TX_VBOOST_LVL, 0x4));
 286
 287        regmap_update_bits(priv->regmap, PHY_R1,
 288                        PHY_R1_PHY_LOS_BIAS | PHY_R1_PHY_LOS_LEVEL,
 289                        FIELD_PREP(PHY_R1_PHY_LOS_BIAS, 4) |
 290                        FIELD_PREP(PHY_R1_PHY_LOS_LEVEL, 9));
 291
 292        return ret;
 293}
 294
 295static int phy_meson_g12a_usb3_exit(struct phy *phy)
 296{
 297        struct phy_g12a_usb3_pcie_priv *priv = dev_get_priv(phy->dev);
 298
 299        return reset_assert_bulk(&priv->resets);
 300}
 301
 302static int phy_meson_g12a_usb3_pcie_init(struct phy *phy)
 303{
 304        if (phy->id == PHY_TYPE_USB3)
 305                return phy_meson_g12a_usb3_init(phy);
 306
 307        return 0;
 308}
 309
 310static int phy_meson_g12a_usb3_pcie_exit(struct phy *phy)
 311{
 312        if (phy->id == PHY_TYPE_USB3)
 313                return phy_meson_g12a_usb3_exit(phy);
 314
 315        return 0;
 316}
 317
 318static int phy_meson_g12a_usb3_pcie_power_on(struct phy *phy)
 319{
 320        struct phy_g12a_usb3_pcie_priv *priv = dev_get_priv(phy->dev);
 321
 322        if (phy->id == PHY_TYPE_USB3)
 323                return 0;
 324
 325        regmap_update_bits(priv->regmap, PHY_R0,
 326                           PHY_R0_PCIE_POWER_STATE,
 327                           FIELD_PREP(PHY_R0_PCIE_POWER_STATE, 0x1c));
 328
 329        return 0;
 330}
 331
 332static int phy_meson_g12a_usb3_pcie_power_off(struct phy *phy)
 333{
 334        struct phy_g12a_usb3_pcie_priv *priv = dev_get_priv(phy->dev);
 335
 336        if (phy->id == PHY_TYPE_USB3)
 337                return 0;
 338
 339        regmap_update_bits(priv->regmap, PHY_R0,
 340                           PHY_R0_PCIE_POWER_STATE,
 341                           FIELD_PREP(PHY_R0_PCIE_POWER_STATE, 0x1d));
 342
 343        return 0;
 344}
 345
 346static int phy_meson_g12a_usb3_pcie_reset(struct phy *phy)
 347{
 348        struct phy_g12a_usb3_pcie_priv *priv = dev_get_priv(phy->dev);
 349        int ret;
 350
 351        if (phy->id == PHY_TYPE_USB3)
 352                return 0;
 353
 354        ret = reset_assert_bulk(&priv->resets);
 355        if (ret)
 356                return ret;
 357
 358        udelay(PCIE_RESET_DELAY);
 359
 360        ret = reset_deassert_bulk(&priv->resets);
 361        if (ret)
 362                return ret;
 363
 364        udelay(PCIE_RESET_DELAY);
 365
 366        return 0;
 367}
 368
 369struct phy_ops meson_g12a_usb3_pcie_phy_ops = {
 370        .init = phy_meson_g12a_usb3_pcie_init,
 371        .exit = phy_meson_g12a_usb3_pcie_exit,
 372        .power_on = phy_meson_g12a_usb3_pcie_power_on,
 373        .power_off = phy_meson_g12a_usb3_pcie_power_off,
 374        .reset = phy_meson_g12a_usb3_pcie_reset,
 375};
 376
 377int meson_g12a_usb3_pcie_phy_probe(struct udevice *dev)
 378{
 379        struct phy_g12a_usb3_pcie_priv *priv = dev_get_priv(dev);
 380        int ret;
 381
 382        ret = regmap_init_mem(dev_ofnode(dev), &priv->regmap);
 383        if (ret)
 384                return ret;
 385
 386        ret = reset_get_bulk(dev, &priv->resets);
 387        if (ret == -ENOTSUPP)
 388                return 0;
 389        else if (ret)
 390                return ret;
 391
 392#if CONFIG_IS_ENABLED(CLK)
 393        ret = clk_get_by_index(dev, 0, &priv->clk);
 394        if (ret < 0)
 395                return ret;
 396
 397        ret = clk_enable(&priv->clk);
 398        if (ret && ret != -ENOENT && ret != -ENOTSUPP) {
 399                pr_err("failed to enable PHY clock\n");
 400                clk_free(&priv->clk);
 401                return ret;
 402        }
 403#endif
 404
 405        return 0;
 406}
 407
 408static const struct udevice_id meson_g12a_usb3_pcie_phy_ids[] = {
 409        { .compatible = "amlogic,g12a-usb3-pcie-phy" },
 410        { }
 411};
 412
 413U_BOOT_DRIVER(meson_g12a_usb3_pcie_phy) = {
 414        .name = "meson_g12a_usb3_pcie_phy",
 415        .id = UCLASS_PHY,
 416        .of_match = meson_g12a_usb3_pcie_phy_ids,
 417        .probe = meson_g12a_usb3_pcie_phy_probe,
 418        .ops = &meson_g12a_usb3_pcie_phy_ops,
 419        .priv_auto      = sizeof(struct phy_g12a_usb3_pcie_priv),
 420};
 421