linux/drivers/phy/cadence/phy-cadence-sierra.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Cadence Sierra PHY Driver
   4 *
   5 * Copyright (c) 2018 Cadence Design Systems
   6 * Author: Alan Douglas <adouglas@cadence.com>
   7 *
   8 */
   9#include <linux/clk.h>
  10#include <linux/clk-provider.h>
  11#include <linux/delay.h>
  12#include <linux/err.h>
  13#include <linux/io.h>
  14#include <linux/module.h>
  15#include <linux/phy/phy.h>
  16#include <linux/platform_device.h>
  17#include <linux/pm_runtime.h>
  18#include <linux/regmap.h>
  19#include <linux/reset.h>
  20#include <linux/slab.h>
  21#include <linux/of.h>
  22#include <linux/of_platform.h>
  23#include <dt-bindings/phy/phy.h>
  24#include <dt-bindings/phy/phy-cadence.h>
  25
  26/* PHY register offsets */
  27#define SIERRA_COMMON_CDB_OFFSET                        0x0
  28#define SIERRA_MACRO_ID_REG                             0x0
  29#define SIERRA_CMN_PLLLC_GEN_PREG                       0x42
  30#define SIERRA_CMN_PLLLC_MODE_PREG                      0x48
  31#define SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG            0x49
  32#define SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG            0x4A
  33#define SIERRA_CMN_PLLLC_LOCK_CNTSTART_PREG             0x4B
  34#define SIERRA_CMN_PLLLC_BWCAL_MODE1_PREG               0x4F
  35#define SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG               0x50
  36#define SIERRA_CMN_PLLLC_SS_TIME_STEPSIZE_MODE_PREG     0x62
  37#define SIERRA_CMN_REFRCV_PREG                          0x98
  38#define SIERRA_CMN_REFRCV1_PREG                         0xB8
  39#define SIERRA_CMN_PLLLC1_GEN_PREG                      0xC2
  40
  41#define SIERRA_LANE_CDB_OFFSET(ln, block_offset, reg_offset)    \
  42                                ((0x4000 << (block_offset)) + \
  43                                 (((ln) << 9) << (reg_offset)))
  44
  45#define SIERRA_DET_STANDEC_A_PREG                       0x000
  46#define SIERRA_DET_STANDEC_B_PREG                       0x001
  47#define SIERRA_DET_STANDEC_C_PREG                       0x002
  48#define SIERRA_DET_STANDEC_D_PREG                       0x003
  49#define SIERRA_DET_STANDEC_E_PREG                       0x004
  50#define SIERRA_PSM_LANECAL_DLY_A1_RESETS_PREG           0x008
  51#define SIERRA_PSM_A0IN_TMR_PREG                        0x009
  52#define SIERRA_PSM_DIAG_PREG                            0x015
  53#define SIERRA_PSC_TX_A0_PREG                           0x028
  54#define SIERRA_PSC_TX_A1_PREG                           0x029
  55#define SIERRA_PSC_TX_A2_PREG                           0x02A
  56#define SIERRA_PSC_TX_A3_PREG                           0x02B
  57#define SIERRA_PSC_RX_A0_PREG                           0x030
  58#define SIERRA_PSC_RX_A1_PREG                           0x031
  59#define SIERRA_PSC_RX_A2_PREG                           0x032
  60#define SIERRA_PSC_RX_A3_PREG                           0x033
  61#define SIERRA_PLLCTRL_SUBRATE_PREG                     0x03A
  62#define SIERRA_PLLCTRL_GEN_D_PREG                       0x03E
  63#define SIERRA_PLLCTRL_CPGAIN_MODE_PREG                 0x03F
  64#define SIERRA_PLLCTRL_STATUS_PREG                      0x044
  65#define SIERRA_CLKPATH_BIASTRIM_PREG                    0x04B
  66#define SIERRA_DFE_BIASTRIM_PREG                        0x04C
  67#define SIERRA_DRVCTRL_ATTEN_PREG                       0x06A
  68#define SIERRA_CLKPATHCTRL_TMR_PREG                     0x081
  69#define SIERRA_RX_CREQ_FLTR_A_MODE3_PREG                0x085
  70#define SIERRA_RX_CREQ_FLTR_A_MODE2_PREG                0x086
  71#define SIERRA_RX_CREQ_FLTR_A_MODE1_PREG                0x087
  72#define SIERRA_RX_CREQ_FLTR_A_MODE0_PREG                0x088
  73#define SIERRA_CREQ_CCLKDET_MODE01_PREG                 0x08E
  74#define SIERRA_RX_CTLE_MAINTENANCE_PREG                 0x091
  75#define SIERRA_CREQ_FSMCLK_SEL_PREG                     0x092
  76#define SIERRA_CREQ_EQ_CTRL_PREG                        0x093
  77#define SIERRA_CREQ_SPARE_PREG                          0x096
  78#define SIERRA_CREQ_EQ_OPEN_EYE_THRESH_PREG             0x097
  79#define SIERRA_CTLELUT_CTRL_PREG                        0x098
  80#define SIERRA_DFE_ECMP_RATESEL_PREG                    0x0C0
  81#define SIERRA_DFE_SMP_RATESEL_PREG                     0x0C1
  82#define SIERRA_DEQ_PHALIGN_CTRL                         0x0C4
  83#define SIERRA_DEQ_CONCUR_CTRL1_PREG                    0x0C8
  84#define SIERRA_DEQ_CONCUR_CTRL2_PREG                    0x0C9
  85#define SIERRA_DEQ_EPIPWR_CTRL2_PREG                    0x0CD
  86#define SIERRA_DEQ_FAST_MAINT_CYCLES_PREG               0x0CE
  87#define SIERRA_DEQ_ERRCMP_CTRL_PREG                     0x0D0
  88#define SIERRA_DEQ_OFFSET_CTRL_PREG                     0x0D8
  89#define SIERRA_DEQ_GAIN_CTRL_PREG                       0x0E0
  90#define SIERRA_DEQ_VGATUNE_CTRL_PREG                    0x0E1
  91#define SIERRA_DEQ_GLUT0                                0x0E8
  92#define SIERRA_DEQ_GLUT1                                0x0E9
  93#define SIERRA_DEQ_GLUT2                                0x0EA
  94#define SIERRA_DEQ_GLUT3                                0x0EB
  95#define SIERRA_DEQ_GLUT4                                0x0EC
  96#define SIERRA_DEQ_GLUT5                                0x0ED
  97#define SIERRA_DEQ_GLUT6                                0x0EE
  98#define SIERRA_DEQ_GLUT7                                0x0EF
  99#define SIERRA_DEQ_GLUT8                                0x0F0
 100#define SIERRA_DEQ_GLUT9                                0x0F1
 101#define SIERRA_DEQ_GLUT10                               0x0F2
 102#define SIERRA_DEQ_GLUT11                               0x0F3
 103#define SIERRA_DEQ_GLUT12                               0x0F4
 104#define SIERRA_DEQ_GLUT13                               0x0F5
 105#define SIERRA_DEQ_GLUT14                               0x0F6
 106#define SIERRA_DEQ_GLUT15                               0x0F7
 107#define SIERRA_DEQ_GLUT16                               0x0F8
 108#define SIERRA_DEQ_ALUT0                                0x108
 109#define SIERRA_DEQ_ALUT1                                0x109
 110#define SIERRA_DEQ_ALUT2                                0x10A
 111#define SIERRA_DEQ_ALUT3                                0x10B
 112#define SIERRA_DEQ_ALUT4                                0x10C
 113#define SIERRA_DEQ_ALUT5                                0x10D
 114#define SIERRA_DEQ_ALUT6                                0x10E
 115#define SIERRA_DEQ_ALUT7                                0x10F
 116#define SIERRA_DEQ_ALUT8                                0x110
 117#define SIERRA_DEQ_ALUT9                                0x111
 118#define SIERRA_DEQ_ALUT10                               0x112
 119#define SIERRA_DEQ_ALUT11                               0x113
 120#define SIERRA_DEQ_ALUT12                               0x114
 121#define SIERRA_DEQ_ALUT13                               0x115
 122#define SIERRA_DEQ_DFETAP_CTRL_PREG                     0x128
 123#define SIERRA_DFE_EN_1010_IGNORE_PREG                  0x134
 124#define SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG            0x150
 125#define SIERRA_DEQ_TAU_CTRL2_PREG                       0x151
 126#define SIERRA_DEQ_PICTRL_PREG                          0x161
 127#define SIERRA_CPICAL_TMRVAL_MODE1_PREG                 0x170
 128#define SIERRA_CPICAL_TMRVAL_MODE0_PREG                 0x171
 129#define SIERRA_CPICAL_PICNT_MODE1_PREG                  0x174
 130#define SIERRA_CPI_OUTBUF_RATESEL_PREG                  0x17C
 131#define SIERRA_CPICAL_RES_STARTCODE_MODE23_PREG         0x183
 132#define SIERRA_LFPSDET_SUPPORT_PREG                     0x188
 133#define SIERRA_LFPSFILT_NS_PREG                         0x18A
 134#define SIERRA_LFPSFILT_RD_PREG                         0x18B
 135#define SIERRA_LFPSFILT_MP_PREG                         0x18C
 136#define SIERRA_SIGDET_SUPPORT_PREG                      0x190
 137#define SIERRA_SDFILT_H2L_A_PREG                        0x191
 138#define SIERRA_SDFILT_L2H_PREG                          0x193
 139#define SIERRA_RXBUFFER_CTLECTRL_PREG                   0x19E
 140#define SIERRA_RXBUFFER_RCDFECTRL_PREG                  0x19F
 141#define SIERRA_RXBUFFER_DFECTRL_PREG                    0x1A0
 142#define SIERRA_DEQ_TAU_CTRL1_FAST_MAINT_PREG            0x14F
 143#define SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG            0x150
 144
 145#define SIERRA_PHY_CONFIG_CTRL_OFFSET(block_offset)     \
 146                                      (0xc000 << (block_offset))
 147#define SIERRA_PHY_PLL_CFG                              0xe
 148
 149#define SIERRA_MACRO_ID                                 0x00007364
 150#define SIERRA_MAX_LANES                                16
 151#define PLL_LOCK_TIME                                   100000
 152
 153#define CDNS_SIERRA_OUTPUT_CLOCKS                       2
 154#define CDNS_SIERRA_INPUT_CLOCKS                        5
 155enum cdns_sierra_clock_input {
 156        PHY_CLK,
 157        CMN_REFCLK_DIG_DIV,
 158        CMN_REFCLK1_DIG_DIV,
 159        PLL0_REFCLK,
 160        PLL1_REFCLK,
 161};
 162
 163#define SIERRA_NUM_CMN_PLLC                             2
 164#define SIERRA_NUM_CMN_PLLC_PARENTS                     2
 165
 166static const struct reg_field macro_id_type =
 167                                REG_FIELD(SIERRA_MACRO_ID_REG, 0, 15);
 168static const struct reg_field phy_pll_cfg_1 =
 169                                REG_FIELD(SIERRA_PHY_PLL_CFG, 1, 1);
 170static const struct reg_field pllctrl_lock =
 171                                REG_FIELD(SIERRA_PLLCTRL_STATUS_PREG, 0, 0);
 172
 173static const char * const clk_names[] = {
 174        [CDNS_SIERRA_PLL_CMNLC] = "pll_cmnlc",
 175        [CDNS_SIERRA_PLL_CMNLC1] = "pll_cmnlc1",
 176};
 177
 178enum cdns_sierra_cmn_plllc {
 179        CMN_PLLLC,
 180        CMN_PLLLC1,
 181};
 182
 183struct cdns_sierra_pll_mux_reg_fields {
 184        struct reg_field        pfdclk_sel_preg;
 185        struct reg_field        plllc1en_field;
 186        struct reg_field        termen_field;
 187};
 188
 189static const struct cdns_sierra_pll_mux_reg_fields cmn_plllc_pfdclk1_sel_preg[] = {
 190        [CMN_PLLLC] = {
 191                .pfdclk_sel_preg = REG_FIELD(SIERRA_CMN_PLLLC_GEN_PREG, 1, 1),
 192                .plllc1en_field = REG_FIELD(SIERRA_CMN_REFRCV1_PREG, 8, 8),
 193                .termen_field = REG_FIELD(SIERRA_CMN_REFRCV1_PREG, 0, 0),
 194        },
 195        [CMN_PLLLC1] = {
 196                .pfdclk_sel_preg = REG_FIELD(SIERRA_CMN_PLLLC1_GEN_PREG, 1, 1),
 197                .plllc1en_field = REG_FIELD(SIERRA_CMN_REFRCV_PREG, 8, 8),
 198                .termen_field = REG_FIELD(SIERRA_CMN_REFRCV_PREG, 0, 0),
 199        },
 200};
 201
 202struct cdns_sierra_pll_mux {
 203        struct clk_hw           hw;
 204        struct regmap_field     *pfdclk_sel_preg;
 205        struct regmap_field     *plllc1en_field;
 206        struct regmap_field     *termen_field;
 207        struct clk_init_data    clk_data;
 208};
 209
 210#define to_cdns_sierra_pll_mux(_hw)     \
 211                        container_of(_hw, struct cdns_sierra_pll_mux, hw)
 212
 213static const int pll_mux_parent_index[][SIERRA_NUM_CMN_PLLC_PARENTS] = {
 214        [CMN_PLLLC] = { PLL0_REFCLK, PLL1_REFCLK },
 215        [CMN_PLLLC1] = { PLL1_REFCLK, PLL0_REFCLK },
 216};
 217
 218static u32 cdns_sierra_pll_mux_table[] = { 0, 1 };
 219
 220struct cdns_sierra_inst {
 221        struct phy *phy;
 222        u32 phy_type;
 223        u32 num_lanes;
 224        u32 mlane;
 225        struct reset_control *lnk_rst;
 226};
 227
 228struct cdns_reg_pairs {
 229        u16 val;
 230        u32 off;
 231};
 232
 233struct cdns_sierra_data {
 234                u32 id_value;
 235                u8 block_offset_shift;
 236                u8 reg_offset_shift;
 237                u32 pcie_cmn_regs;
 238                u32 pcie_ln_regs;
 239                u32 usb_cmn_regs;
 240                u32 usb_ln_regs;
 241                const struct cdns_reg_pairs *pcie_cmn_vals;
 242                const struct cdns_reg_pairs *pcie_ln_vals;
 243                const struct cdns_reg_pairs *usb_cmn_vals;
 244                const struct cdns_reg_pairs *usb_ln_vals;
 245};
 246
 247struct cdns_regmap_cdb_context {
 248        struct device *dev;
 249        void __iomem *base;
 250        u8 reg_offset_shift;
 251};
 252
 253struct cdns_sierra_phy {
 254        struct device *dev;
 255        struct regmap *regmap;
 256        struct cdns_sierra_data *init_data;
 257        struct cdns_sierra_inst phys[SIERRA_MAX_LANES];
 258        struct reset_control *phy_rst;
 259        struct reset_control *apb_rst;
 260        struct regmap *regmap_lane_cdb[SIERRA_MAX_LANES];
 261        struct regmap *regmap_phy_config_ctrl;
 262        struct regmap *regmap_common_cdb;
 263        struct regmap_field *macro_id_type;
 264        struct regmap_field *phy_pll_cfg_1;
 265        struct regmap_field *pllctrl_lock[SIERRA_MAX_LANES];
 266        struct regmap_field *cmn_refrcv_refclk_plllc1en_preg[SIERRA_NUM_CMN_PLLC];
 267        struct regmap_field *cmn_refrcv_refclk_termen_preg[SIERRA_NUM_CMN_PLLC];
 268        struct regmap_field *cmn_plllc_pfdclk1_sel_preg[SIERRA_NUM_CMN_PLLC];
 269        struct clk *input_clks[CDNS_SIERRA_INPUT_CLOCKS];
 270        int nsubnodes;
 271        u32 num_lanes;
 272        bool autoconf;
 273        struct clk_onecell_data clk_data;
 274        struct clk *output_clks[CDNS_SIERRA_OUTPUT_CLOCKS];
 275};
 276
 277static int cdns_regmap_write(void *context, unsigned int reg, unsigned int val)
 278{
 279        struct cdns_regmap_cdb_context *ctx = context;
 280        u32 offset = reg << ctx->reg_offset_shift;
 281
 282        writew(val, ctx->base + offset);
 283
 284        return 0;
 285}
 286
 287static int cdns_regmap_read(void *context, unsigned int reg, unsigned int *val)
 288{
 289        struct cdns_regmap_cdb_context *ctx = context;
 290        u32 offset = reg << ctx->reg_offset_shift;
 291
 292        *val = readw(ctx->base + offset);
 293        return 0;
 294}
 295
 296#define SIERRA_LANE_CDB_REGMAP_CONF(n) \
 297{ \
 298        .name = "sierra_lane" n "_cdb", \
 299        .reg_stride = 1, \
 300        .fast_io = true, \
 301        .reg_write = cdns_regmap_write, \
 302        .reg_read = cdns_regmap_read, \
 303}
 304
 305static const struct regmap_config cdns_sierra_lane_cdb_config[] = {
 306        SIERRA_LANE_CDB_REGMAP_CONF("0"),
 307        SIERRA_LANE_CDB_REGMAP_CONF("1"),
 308        SIERRA_LANE_CDB_REGMAP_CONF("2"),
 309        SIERRA_LANE_CDB_REGMAP_CONF("3"),
 310        SIERRA_LANE_CDB_REGMAP_CONF("4"),
 311        SIERRA_LANE_CDB_REGMAP_CONF("5"),
 312        SIERRA_LANE_CDB_REGMAP_CONF("6"),
 313        SIERRA_LANE_CDB_REGMAP_CONF("7"),
 314        SIERRA_LANE_CDB_REGMAP_CONF("8"),
 315        SIERRA_LANE_CDB_REGMAP_CONF("9"),
 316        SIERRA_LANE_CDB_REGMAP_CONF("10"),
 317        SIERRA_LANE_CDB_REGMAP_CONF("11"),
 318        SIERRA_LANE_CDB_REGMAP_CONF("12"),
 319        SIERRA_LANE_CDB_REGMAP_CONF("13"),
 320        SIERRA_LANE_CDB_REGMAP_CONF("14"),
 321        SIERRA_LANE_CDB_REGMAP_CONF("15"),
 322};
 323
 324static const struct regmap_config cdns_sierra_common_cdb_config = {
 325        .name = "sierra_common_cdb",
 326        .reg_stride = 1,
 327        .fast_io = true,
 328        .reg_write = cdns_regmap_write,
 329        .reg_read = cdns_regmap_read,
 330};
 331
 332static const struct regmap_config cdns_sierra_phy_config_ctrl_config = {
 333        .name = "sierra_phy_config_ctrl",
 334        .reg_stride = 1,
 335        .fast_io = true,
 336        .reg_write = cdns_regmap_write,
 337        .reg_read = cdns_regmap_read,
 338};
 339
 340static int cdns_sierra_phy_init(struct phy *gphy)
 341{
 342        struct cdns_sierra_inst *ins = phy_get_drvdata(gphy);
 343        struct cdns_sierra_phy *phy = dev_get_drvdata(gphy->dev.parent);
 344        struct regmap *regmap;
 345        int i, j;
 346        const struct cdns_reg_pairs *cmn_vals, *ln_vals;
 347        u32 num_cmn_regs, num_ln_regs;
 348
 349        /* Initialise the PHY registers, unless auto configured */
 350        if (phy->autoconf)
 351                return 0;
 352
 353        clk_set_rate(phy->input_clks[CMN_REFCLK_DIG_DIV], 25000000);
 354        clk_set_rate(phy->input_clks[CMN_REFCLK1_DIG_DIV], 25000000);
 355        if (ins->phy_type == PHY_TYPE_PCIE) {
 356                num_cmn_regs = phy->init_data->pcie_cmn_regs;
 357                num_ln_regs = phy->init_data->pcie_ln_regs;
 358                cmn_vals = phy->init_data->pcie_cmn_vals;
 359                ln_vals = phy->init_data->pcie_ln_vals;
 360        } else if (ins->phy_type == PHY_TYPE_USB3) {
 361                num_cmn_regs = phy->init_data->usb_cmn_regs;
 362                num_ln_regs = phy->init_data->usb_ln_regs;
 363                cmn_vals = phy->init_data->usb_cmn_vals;
 364                ln_vals = phy->init_data->usb_ln_vals;
 365        } else {
 366                return -EINVAL;
 367        }
 368
 369        regmap = phy->regmap_common_cdb;
 370        for (j = 0; j < num_cmn_regs ; j++)
 371                regmap_write(regmap, cmn_vals[j].off, cmn_vals[j].val);
 372
 373        for (i = 0; i < ins->num_lanes; i++) {
 374                for (j = 0; j < num_ln_regs ; j++) {
 375                        regmap = phy->regmap_lane_cdb[i + ins->mlane];
 376                        regmap_write(regmap, ln_vals[j].off, ln_vals[j].val);
 377                }
 378        }
 379
 380        return 0;
 381}
 382
 383static int cdns_sierra_phy_on(struct phy *gphy)
 384{
 385        struct cdns_sierra_phy *sp = dev_get_drvdata(gphy->dev.parent);
 386        struct cdns_sierra_inst *ins = phy_get_drvdata(gphy);
 387        struct device *dev = sp->dev;
 388        u32 val;
 389        int ret;
 390
 391        ret = reset_control_deassert(sp->phy_rst);
 392        if (ret) {
 393                dev_err(dev, "Failed to take the PHY out of reset\n");
 394                return ret;
 395        }
 396
 397        /* Take the PHY lane group out of reset */
 398        ret = reset_control_deassert(ins->lnk_rst);
 399        if (ret) {
 400                dev_err(dev, "Failed to take the PHY lane out of reset\n");
 401                return ret;
 402        }
 403
 404        ret = regmap_field_read_poll_timeout(sp->pllctrl_lock[ins->mlane],
 405                                             val, val, 1000, PLL_LOCK_TIME);
 406        if (ret < 0)
 407                dev_err(dev, "PLL lock of lane failed\n");
 408
 409        return ret;
 410}
 411
 412static int cdns_sierra_phy_off(struct phy *gphy)
 413{
 414        struct cdns_sierra_inst *ins = phy_get_drvdata(gphy);
 415
 416        return reset_control_assert(ins->lnk_rst);
 417}
 418
 419static int cdns_sierra_phy_reset(struct phy *gphy)
 420{
 421        struct cdns_sierra_phy *sp = dev_get_drvdata(gphy->dev.parent);
 422
 423        reset_control_assert(sp->phy_rst);
 424        reset_control_deassert(sp->phy_rst);
 425        return 0;
 426};
 427
 428static const struct phy_ops ops = {
 429        .init           = cdns_sierra_phy_init,
 430        .power_on       = cdns_sierra_phy_on,
 431        .power_off      = cdns_sierra_phy_off,
 432        .reset          = cdns_sierra_phy_reset,
 433        .owner          = THIS_MODULE,
 434};
 435
 436static u8 cdns_sierra_pll_mux_get_parent(struct clk_hw *hw)
 437{
 438        struct cdns_sierra_pll_mux *mux = to_cdns_sierra_pll_mux(hw);
 439        struct regmap_field *field = mux->pfdclk_sel_preg;
 440        unsigned int val;
 441
 442        regmap_field_read(field, &val);
 443        return clk_mux_val_to_index(hw, cdns_sierra_pll_mux_table, 0, val);
 444}
 445
 446static int cdns_sierra_pll_mux_set_parent(struct clk_hw *hw, u8 index)
 447{
 448        struct cdns_sierra_pll_mux *mux = to_cdns_sierra_pll_mux(hw);
 449        struct regmap_field *plllc1en_field = mux->plllc1en_field;
 450        struct regmap_field *termen_field = mux->termen_field;
 451        struct regmap_field *field = mux->pfdclk_sel_preg;
 452        int val, ret;
 453
 454        ret = regmap_field_write(plllc1en_field, 0);
 455        ret |= regmap_field_write(termen_field, 0);
 456        if (index == 1) {
 457                ret |= regmap_field_write(plllc1en_field, 1);
 458                ret |= regmap_field_write(termen_field, 1);
 459        }
 460
 461        val = cdns_sierra_pll_mux_table[index];
 462        ret |= regmap_field_write(field, val);
 463
 464        return ret;
 465}
 466
 467static const struct clk_ops cdns_sierra_pll_mux_ops = {
 468        .set_parent = cdns_sierra_pll_mux_set_parent,
 469        .get_parent = cdns_sierra_pll_mux_get_parent,
 470};
 471
 472static int cdns_sierra_pll_mux_register(struct cdns_sierra_phy *sp,
 473                                        struct regmap_field *pfdclk1_sel_field,
 474                                        struct regmap_field *plllc1en_field,
 475                                        struct regmap_field *termen_field,
 476                                        int clk_index)
 477{
 478        struct cdns_sierra_pll_mux *mux;
 479        struct device *dev = sp->dev;
 480        struct clk_init_data *init;
 481        const char **parent_names;
 482        unsigned int num_parents;
 483        char clk_name[100];
 484        struct clk *clk;
 485        int i;
 486
 487        mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
 488        if (!mux)
 489                return -ENOMEM;
 490
 491        num_parents = SIERRA_NUM_CMN_PLLC_PARENTS;
 492        parent_names = devm_kzalloc(dev, (sizeof(char *) * num_parents), GFP_KERNEL);
 493        if (!parent_names)
 494                return -ENOMEM;
 495
 496        for (i = 0; i < num_parents; i++) {
 497                clk = sp->input_clks[pll_mux_parent_index[clk_index][i]];
 498                if (IS_ERR_OR_NULL(clk)) {
 499                        dev_err(dev, "No parent clock for derived_refclk\n");
 500                        return PTR_ERR(clk);
 501                }
 502                parent_names[i] = __clk_get_name(clk);
 503        }
 504
 505        snprintf(clk_name, sizeof(clk_name), "%s_%s", dev_name(dev), clk_names[clk_index]);
 506
 507        init = &mux->clk_data;
 508
 509        init->ops = &cdns_sierra_pll_mux_ops;
 510        init->flags = CLK_SET_RATE_NO_REPARENT;
 511        init->parent_names = parent_names;
 512        init->num_parents = num_parents;
 513        init->name = clk_name;
 514
 515        mux->pfdclk_sel_preg = pfdclk1_sel_field;
 516        mux->plllc1en_field = plllc1en_field;
 517        mux->termen_field = termen_field;
 518        mux->hw.init = init;
 519
 520        clk = devm_clk_register(dev, &mux->hw);
 521        if (IS_ERR(clk))
 522                return PTR_ERR(clk);
 523
 524        sp->output_clks[clk_index] = clk;
 525
 526        return 0;
 527}
 528
 529static int cdns_sierra_phy_register_pll_mux(struct cdns_sierra_phy *sp)
 530{
 531        struct regmap_field *pfdclk1_sel_field;
 532        struct regmap_field *plllc1en_field;
 533        struct regmap_field *termen_field;
 534        struct device *dev = sp->dev;
 535        int ret = 0, i, clk_index;
 536
 537        clk_index = CDNS_SIERRA_PLL_CMNLC;
 538        for (i = 0; i < SIERRA_NUM_CMN_PLLC; i++, clk_index++) {
 539                pfdclk1_sel_field = sp->cmn_plllc_pfdclk1_sel_preg[i];
 540                plllc1en_field = sp->cmn_refrcv_refclk_plllc1en_preg[i];
 541                termen_field = sp->cmn_refrcv_refclk_termen_preg[i];
 542
 543                ret = cdns_sierra_pll_mux_register(sp, pfdclk1_sel_field, plllc1en_field,
 544                                                   termen_field, clk_index);
 545                if (ret) {
 546                        dev_err(dev, "Fail to register cmn plllc mux\n");
 547                        return ret;
 548                }
 549        }
 550
 551        return 0;
 552}
 553
 554static void cdns_sierra_clk_unregister(struct cdns_sierra_phy *sp)
 555{
 556        struct device *dev = sp->dev;
 557        struct device_node *node = dev->of_node;
 558
 559        of_clk_del_provider(node);
 560}
 561
 562static int cdns_sierra_clk_register(struct cdns_sierra_phy *sp)
 563{
 564        struct device *dev = sp->dev;
 565        struct device_node *node = dev->of_node;
 566        int ret;
 567
 568        ret = cdns_sierra_phy_register_pll_mux(sp);
 569        if (ret) {
 570                dev_err(dev, "Failed to pll mux clocks\n");
 571                return ret;
 572        }
 573
 574        sp->clk_data.clks = sp->output_clks;
 575        sp->clk_data.clk_num = CDNS_SIERRA_OUTPUT_CLOCKS;
 576        ret = of_clk_add_provider(node, of_clk_src_onecell_get, &sp->clk_data);
 577        if (ret)
 578                dev_err(dev, "Failed to add clock provider: %s\n", node->name);
 579
 580        return ret;
 581}
 582
 583static int cdns_sierra_get_optional(struct cdns_sierra_inst *inst,
 584                                    struct device_node *child)
 585{
 586        if (of_property_read_u32(child, "reg", &inst->mlane))
 587                return -EINVAL;
 588
 589        if (of_property_read_u32(child, "cdns,num-lanes", &inst->num_lanes))
 590                return -EINVAL;
 591
 592        if (of_property_read_u32(child, "cdns,phy-type", &inst->phy_type))
 593                return -EINVAL;
 594
 595        return 0;
 596}
 597
 598static const struct of_device_id cdns_sierra_id_table[];
 599
 600static struct regmap *cdns_regmap_init(struct device *dev, void __iomem *base,
 601                                       u32 block_offset, u8 reg_offset_shift,
 602                                       const struct regmap_config *config)
 603{
 604        struct cdns_regmap_cdb_context *ctx;
 605
 606        ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
 607        if (!ctx)
 608                return ERR_PTR(-ENOMEM);
 609
 610        ctx->dev = dev;
 611        ctx->base = base + block_offset;
 612        ctx->reg_offset_shift = reg_offset_shift;
 613
 614        return devm_regmap_init(dev, NULL, ctx, config);
 615}
 616
 617static int cdns_regfield_init(struct cdns_sierra_phy *sp)
 618{
 619        struct device *dev = sp->dev;
 620        struct regmap_field *field;
 621        struct reg_field reg_field;
 622        struct regmap *regmap;
 623        int i;
 624
 625        regmap = sp->regmap_common_cdb;
 626        field = devm_regmap_field_alloc(dev, regmap, macro_id_type);
 627        if (IS_ERR(field)) {
 628                dev_err(dev, "MACRO_ID_TYPE reg field init failed\n");
 629                return PTR_ERR(field);
 630        }
 631        sp->macro_id_type = field;
 632
 633        for (i = 0; i < SIERRA_NUM_CMN_PLLC; i++) {
 634                reg_field = cmn_plllc_pfdclk1_sel_preg[i].pfdclk_sel_preg;
 635                field = devm_regmap_field_alloc(dev, regmap, reg_field);
 636                if (IS_ERR(field)) {
 637                        dev_err(dev, "PLLLC%d_PFDCLK1_SEL failed\n", i);
 638                        return PTR_ERR(field);
 639                }
 640                sp->cmn_plllc_pfdclk1_sel_preg[i] = field;
 641
 642                reg_field = cmn_plllc_pfdclk1_sel_preg[i].plllc1en_field;
 643                field = devm_regmap_field_alloc(dev, regmap, reg_field);
 644                if (IS_ERR(field)) {
 645                        dev_err(dev, "REFRCV%d_REFCLK_PLLLC1EN failed\n", i);
 646                        return PTR_ERR(field);
 647                }
 648                sp->cmn_refrcv_refclk_plllc1en_preg[i] = field;
 649
 650                reg_field = cmn_plllc_pfdclk1_sel_preg[i].termen_field;
 651                field = devm_regmap_field_alloc(dev, regmap, reg_field);
 652                if (IS_ERR(field)) {
 653                        dev_err(dev, "REFRCV%d_REFCLK_TERMEN failed\n", i);
 654                        return PTR_ERR(field);
 655                }
 656                sp->cmn_refrcv_refclk_termen_preg[i] = field;
 657        }
 658
 659        regmap = sp->regmap_phy_config_ctrl;
 660        field = devm_regmap_field_alloc(dev, regmap, phy_pll_cfg_1);
 661        if (IS_ERR(field)) {
 662                dev_err(dev, "PHY_PLL_CFG_1 reg field init failed\n");
 663                return PTR_ERR(field);
 664        }
 665        sp->phy_pll_cfg_1 = field;
 666
 667        for (i = 0; i < SIERRA_MAX_LANES; i++) {
 668                regmap = sp->regmap_lane_cdb[i];
 669                field = devm_regmap_field_alloc(dev, regmap, pllctrl_lock);
 670                if (IS_ERR(field)) {
 671                        dev_err(dev, "P%d_ENABLE reg field init failed\n", i);
 672                        return PTR_ERR(field);
 673                }
 674                sp->pllctrl_lock[i] =  field;
 675        }
 676
 677        return 0;
 678}
 679
 680static int cdns_regmap_init_blocks(struct cdns_sierra_phy *sp,
 681                                   void __iomem *base, u8 block_offset_shift,
 682                                   u8 reg_offset_shift)
 683{
 684        struct device *dev = sp->dev;
 685        struct regmap *regmap;
 686        u32 block_offset;
 687        int i;
 688
 689        for (i = 0; i < SIERRA_MAX_LANES; i++) {
 690                block_offset = SIERRA_LANE_CDB_OFFSET(i, block_offset_shift,
 691                                                      reg_offset_shift);
 692                regmap = cdns_regmap_init(dev, base, block_offset,
 693                                          reg_offset_shift,
 694                                          &cdns_sierra_lane_cdb_config[i]);
 695                if (IS_ERR(regmap)) {
 696                        dev_err(dev, "Failed to init lane CDB regmap\n");
 697                        return PTR_ERR(regmap);
 698                }
 699                sp->regmap_lane_cdb[i] = regmap;
 700        }
 701
 702        regmap = cdns_regmap_init(dev, base, SIERRA_COMMON_CDB_OFFSET,
 703                                  reg_offset_shift,
 704                                  &cdns_sierra_common_cdb_config);
 705        if (IS_ERR(regmap)) {
 706                dev_err(dev, "Failed to init common CDB regmap\n");
 707                return PTR_ERR(regmap);
 708        }
 709        sp->regmap_common_cdb = regmap;
 710
 711        block_offset = SIERRA_PHY_CONFIG_CTRL_OFFSET(block_offset_shift);
 712        regmap = cdns_regmap_init(dev, base, block_offset, reg_offset_shift,
 713                                  &cdns_sierra_phy_config_ctrl_config);
 714        if (IS_ERR(regmap)) {
 715                dev_err(dev, "Failed to init PHY config and control regmap\n");
 716                return PTR_ERR(regmap);
 717        }
 718        sp->regmap_phy_config_ctrl = regmap;
 719
 720        return 0;
 721}
 722
 723static int cdns_sierra_phy_get_clocks(struct cdns_sierra_phy *sp,
 724                                      struct device *dev)
 725{
 726        struct clk *clk;
 727        int ret;
 728
 729        clk = devm_clk_get_optional(dev, "phy_clk");
 730        if (IS_ERR(clk)) {
 731                dev_err(dev, "failed to get clock phy_clk\n");
 732                return PTR_ERR(clk);
 733        }
 734        sp->input_clks[PHY_CLK] = clk;
 735
 736        clk = devm_clk_get_optional(dev, "cmn_refclk_dig_div");
 737        if (IS_ERR(clk)) {
 738                dev_err(dev, "cmn_refclk_dig_div clock not found\n");
 739                ret = PTR_ERR(clk);
 740                return ret;
 741        }
 742        sp->input_clks[CMN_REFCLK_DIG_DIV] = clk;
 743
 744        clk = devm_clk_get_optional(dev, "cmn_refclk1_dig_div");
 745        if (IS_ERR(clk)) {
 746                dev_err(dev, "cmn_refclk1_dig_div clock not found\n");
 747                ret = PTR_ERR(clk);
 748                return ret;
 749        }
 750        sp->input_clks[CMN_REFCLK1_DIG_DIV] = clk;
 751
 752        clk = devm_clk_get_optional(dev, "pll0_refclk");
 753        if (IS_ERR(clk)) {
 754                dev_err(dev, "pll0_refclk clock not found\n");
 755                ret = PTR_ERR(clk);
 756                return ret;
 757        }
 758        sp->input_clks[PLL0_REFCLK] = clk;
 759
 760        clk = devm_clk_get_optional(dev, "pll1_refclk");
 761        if (IS_ERR(clk)) {
 762                dev_err(dev, "pll1_refclk clock not found\n");
 763                ret = PTR_ERR(clk);
 764                return ret;
 765        }
 766        sp->input_clks[PLL1_REFCLK] = clk;
 767
 768        return 0;
 769}
 770
 771static int cdns_sierra_phy_enable_clocks(struct cdns_sierra_phy *sp)
 772{
 773        int ret;
 774
 775        ret = clk_prepare_enable(sp->input_clks[PHY_CLK]);
 776        if (ret)
 777                return ret;
 778
 779        ret = clk_prepare_enable(sp->output_clks[CDNS_SIERRA_PLL_CMNLC]);
 780        if (ret)
 781                goto err_pll_cmnlc;
 782
 783        ret = clk_prepare_enable(sp->output_clks[CDNS_SIERRA_PLL_CMNLC1]);
 784        if (ret)
 785                goto err_pll_cmnlc1;
 786
 787        return 0;
 788
 789err_pll_cmnlc1:
 790        clk_disable_unprepare(sp->output_clks[CDNS_SIERRA_PLL_CMNLC]);
 791
 792err_pll_cmnlc:
 793        clk_disable_unprepare(sp->input_clks[PHY_CLK]);
 794
 795        return ret;
 796}
 797
 798static void cdns_sierra_phy_disable_clocks(struct cdns_sierra_phy *sp)
 799{
 800        clk_disable_unprepare(sp->output_clks[CDNS_SIERRA_PLL_CMNLC1]);
 801        clk_disable_unprepare(sp->output_clks[CDNS_SIERRA_PLL_CMNLC]);
 802        clk_disable_unprepare(sp->input_clks[PHY_CLK]);
 803}
 804
 805static int cdns_sierra_phy_get_resets(struct cdns_sierra_phy *sp,
 806                                      struct device *dev)
 807{
 808        struct reset_control *rst;
 809
 810        rst = devm_reset_control_get_exclusive(dev, "sierra_reset");
 811        if (IS_ERR(rst)) {
 812                dev_err(dev, "failed to get reset\n");
 813                return PTR_ERR(rst);
 814        }
 815        sp->phy_rst = rst;
 816
 817        rst = devm_reset_control_get_optional_exclusive(dev, "sierra_apb");
 818        if (IS_ERR(rst)) {
 819                dev_err(dev, "failed to get apb reset\n");
 820                return PTR_ERR(rst);
 821        }
 822        sp->apb_rst = rst;
 823
 824        return 0;
 825}
 826
 827static int cdns_sierra_phy_probe(struct platform_device *pdev)
 828{
 829        struct cdns_sierra_phy *sp;
 830        struct phy_provider *phy_provider;
 831        struct device *dev = &pdev->dev;
 832        const struct of_device_id *match;
 833        struct cdns_sierra_data *data;
 834        unsigned int id_value;
 835        int i, ret, node = 0;
 836        void __iomem *base;
 837        struct device_node *dn = dev->of_node, *child;
 838
 839        if (of_get_child_count(dn) == 0)
 840                return -ENODEV;
 841
 842        /* Get init data for this PHY */
 843        match = of_match_device(cdns_sierra_id_table, dev);
 844        if (!match)
 845                return -EINVAL;
 846
 847        data = (struct cdns_sierra_data *)match->data;
 848
 849        sp = devm_kzalloc(dev, sizeof(*sp), GFP_KERNEL);
 850        if (!sp)
 851                return -ENOMEM;
 852        dev_set_drvdata(dev, sp);
 853        sp->dev = dev;
 854        sp->init_data = data;
 855
 856        base = devm_platform_ioremap_resource(pdev, 0);
 857        if (IS_ERR(base)) {
 858                dev_err(dev, "missing \"reg\"\n");
 859                return PTR_ERR(base);
 860        }
 861
 862        ret = cdns_regmap_init_blocks(sp, base, data->block_offset_shift,
 863                                      data->reg_offset_shift);
 864        if (ret)
 865                return ret;
 866
 867        ret = cdns_regfield_init(sp);
 868        if (ret)
 869                return ret;
 870
 871        platform_set_drvdata(pdev, sp);
 872
 873        ret = cdns_sierra_phy_get_clocks(sp, dev);
 874        if (ret)
 875                return ret;
 876
 877        ret = cdns_sierra_clk_register(sp);
 878        if (ret)
 879                return ret;
 880
 881        ret = cdns_sierra_phy_get_resets(sp, dev);
 882        if (ret)
 883                goto unregister_clk;
 884
 885        ret = cdns_sierra_phy_enable_clocks(sp);
 886        if (ret)
 887                goto unregister_clk;
 888
 889        /* Enable APB */
 890        reset_control_deassert(sp->apb_rst);
 891
 892        /* Check that PHY is present */
 893        regmap_field_read(sp->macro_id_type, &id_value);
 894        if  (sp->init_data->id_value != id_value) {
 895                ret = -EINVAL;
 896                goto clk_disable;
 897        }
 898
 899        sp->autoconf = of_property_read_bool(dn, "cdns,autoconf");
 900
 901        for_each_available_child_of_node(dn, child) {
 902                struct phy *gphy;
 903
 904                if (!(of_node_name_eq(child, "phy") ||
 905                      of_node_name_eq(child, "link")))
 906                        continue;
 907
 908                sp->phys[node].lnk_rst =
 909                        of_reset_control_array_get_exclusive(child);
 910
 911                if (IS_ERR(sp->phys[node].lnk_rst)) {
 912                        dev_err(dev, "failed to get reset %s\n",
 913                                child->full_name);
 914                        ret = PTR_ERR(sp->phys[node].lnk_rst);
 915                        goto put_child2;
 916                }
 917
 918                if (!sp->autoconf) {
 919                        ret = cdns_sierra_get_optional(&sp->phys[node], child);
 920                        if (ret) {
 921                                dev_err(dev, "missing property in node %s\n",
 922                                        child->name);
 923                                goto put_child;
 924                        }
 925                }
 926
 927                sp->num_lanes += sp->phys[node].num_lanes;
 928
 929                gphy = devm_phy_create(dev, child, &ops);
 930
 931                if (IS_ERR(gphy)) {
 932                        ret = PTR_ERR(gphy);
 933                        goto put_child;
 934                }
 935                sp->phys[node].phy = gphy;
 936                phy_set_drvdata(gphy, &sp->phys[node]);
 937
 938                node++;
 939        }
 940        sp->nsubnodes = node;
 941
 942        if (sp->num_lanes > SIERRA_MAX_LANES) {
 943                ret = -EINVAL;
 944                dev_err(dev, "Invalid lane configuration\n");
 945                goto put_child2;
 946        }
 947
 948        /* If more than one subnode, configure the PHY as multilink */
 949        if (!sp->autoconf && sp->nsubnodes > 1)
 950                regmap_field_write(sp->phy_pll_cfg_1, 0x1);
 951
 952        pm_runtime_enable(dev);
 953        phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
 954        return PTR_ERR_OR_ZERO(phy_provider);
 955
 956put_child:
 957        node++;
 958put_child2:
 959        for (i = 0; i < node; i++)
 960                reset_control_put(sp->phys[i].lnk_rst);
 961        of_node_put(child);
 962clk_disable:
 963        cdns_sierra_phy_disable_clocks(sp);
 964        reset_control_assert(sp->apb_rst);
 965unregister_clk:
 966        cdns_sierra_clk_unregister(sp);
 967        return ret;
 968}
 969
 970static int cdns_sierra_phy_remove(struct platform_device *pdev)
 971{
 972        struct cdns_sierra_phy *phy = platform_get_drvdata(pdev);
 973        int i;
 974
 975        reset_control_assert(phy->phy_rst);
 976        reset_control_assert(phy->apb_rst);
 977        pm_runtime_disable(&pdev->dev);
 978
 979        cdns_sierra_phy_disable_clocks(phy);
 980        /*
 981         * The device level resets will be put automatically.
 982         * Need to put the subnode resets here though.
 983         */
 984        for (i = 0; i < phy->nsubnodes; i++) {
 985                reset_control_assert(phy->phys[i].lnk_rst);
 986                reset_control_put(phy->phys[i].lnk_rst);
 987        }
 988
 989        cdns_sierra_clk_unregister(phy);
 990
 991        return 0;
 992}
 993
 994/* refclk100MHz_32b_PCIe_cmn_pll_ext_ssc */
 995static const struct cdns_reg_pairs cdns_pcie_cmn_regs_ext_ssc[] = {
 996        {0x2106, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
 997        {0x2106, SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG},
 998        {0x8A06, SIERRA_CMN_PLLLC_BWCAL_MODE1_PREG},
 999        {0x8A06, SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG},
1000        {0x1B1B, SIERRA_CMN_PLLLC_SS_TIME_STEPSIZE_MODE_PREG}
1001};
1002
1003/* refclk100MHz_32b_PCIe_ln_ext_ssc */
1004static const struct cdns_reg_pairs cdns_pcie_ln_regs_ext_ssc[] = {
1005        {0x813E, SIERRA_CLKPATHCTRL_TMR_PREG},
1006        {0x8047, SIERRA_RX_CREQ_FLTR_A_MODE3_PREG},
1007        {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE2_PREG},
1008        {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE1_PREG},
1009        {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG},
1010        {0x033C, SIERRA_RX_CTLE_MAINTENANCE_PREG},
1011        {0x44CC, SIERRA_CREQ_EQ_OPEN_EYE_THRESH_PREG}
1012};
1013
1014/* refclk100MHz_20b_USB_cmn_pll_ext_ssc */
1015static const struct cdns_reg_pairs cdns_usb_cmn_regs_ext_ssc[] = {
1016        {0x2085, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
1017        {0x2085, SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG},
1018        {0x0000, SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG},
1019        {0x0000, SIERRA_CMN_PLLLC_SS_TIME_STEPSIZE_MODE_PREG}
1020};
1021
1022/* refclk100MHz_20b_USB_ln_ext_ssc */
1023static const struct cdns_reg_pairs cdns_usb_ln_regs_ext_ssc[] = {
1024        {0xFE0A, SIERRA_DET_STANDEC_A_PREG},
1025        {0x000F, SIERRA_DET_STANDEC_B_PREG},
1026        {0x55A5, SIERRA_DET_STANDEC_C_PREG},
1027        {0x69ad, SIERRA_DET_STANDEC_D_PREG},
1028        {0x0241, SIERRA_DET_STANDEC_E_PREG},
1029        {0x0110, SIERRA_PSM_LANECAL_DLY_A1_RESETS_PREG},
1030        {0x0014, SIERRA_PSM_A0IN_TMR_PREG},
1031        {0xCF00, SIERRA_PSM_DIAG_PREG},
1032        {0x001F, SIERRA_PSC_TX_A0_PREG},
1033        {0x0007, SIERRA_PSC_TX_A1_PREG},
1034        {0x0003, SIERRA_PSC_TX_A2_PREG},
1035        {0x0003, SIERRA_PSC_TX_A3_PREG},
1036        {0x0FFF, SIERRA_PSC_RX_A0_PREG},
1037        {0x0003, SIERRA_PSC_RX_A1_PREG},
1038        {0x0003, SIERRA_PSC_RX_A2_PREG},
1039        {0x0001, SIERRA_PSC_RX_A3_PREG},
1040        {0x0001, SIERRA_PLLCTRL_SUBRATE_PREG},
1041        {0x0406, SIERRA_PLLCTRL_GEN_D_PREG},
1042        {0x5233, SIERRA_PLLCTRL_CPGAIN_MODE_PREG},
1043        {0x00CA, SIERRA_CLKPATH_BIASTRIM_PREG},
1044        {0x2512, SIERRA_DFE_BIASTRIM_PREG},
1045        {0x0000, SIERRA_DRVCTRL_ATTEN_PREG},
1046        {0x823E, SIERRA_CLKPATHCTRL_TMR_PREG},
1047        {0x078F, SIERRA_RX_CREQ_FLTR_A_MODE1_PREG},
1048        {0x078F, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG},
1049        {0x7B3C, SIERRA_CREQ_CCLKDET_MODE01_PREG},
1050        {0x023C, SIERRA_RX_CTLE_MAINTENANCE_PREG},
1051        {0x3232, SIERRA_CREQ_FSMCLK_SEL_PREG},
1052        {0x0000, SIERRA_CREQ_EQ_CTRL_PREG},
1053        {0x0000, SIERRA_CREQ_SPARE_PREG},
1054        {0xCC44, SIERRA_CREQ_EQ_OPEN_EYE_THRESH_PREG},
1055        {0x8452, SIERRA_CTLELUT_CTRL_PREG},
1056        {0x4121, SIERRA_DFE_ECMP_RATESEL_PREG},
1057        {0x4121, SIERRA_DFE_SMP_RATESEL_PREG},
1058        {0x0003, SIERRA_DEQ_PHALIGN_CTRL},
1059        {0x3200, SIERRA_DEQ_CONCUR_CTRL1_PREG},
1060        {0x5064, SIERRA_DEQ_CONCUR_CTRL2_PREG},
1061        {0x0030, SIERRA_DEQ_EPIPWR_CTRL2_PREG},
1062        {0x0048, SIERRA_DEQ_FAST_MAINT_CYCLES_PREG},
1063        {0x5A5A, SIERRA_DEQ_ERRCMP_CTRL_PREG},
1064        {0x02F5, SIERRA_DEQ_OFFSET_CTRL_PREG},
1065        {0x02F5, SIERRA_DEQ_GAIN_CTRL_PREG},
1066        {0x9999, SIERRA_DEQ_VGATUNE_CTRL_PREG},
1067        {0x0014, SIERRA_DEQ_GLUT0},
1068        {0x0014, SIERRA_DEQ_GLUT1},
1069        {0x0014, SIERRA_DEQ_GLUT2},
1070        {0x0014, SIERRA_DEQ_GLUT3},
1071        {0x0014, SIERRA_DEQ_GLUT4},
1072        {0x0014, SIERRA_DEQ_GLUT5},
1073        {0x0014, SIERRA_DEQ_GLUT6},
1074        {0x0014, SIERRA_DEQ_GLUT7},
1075        {0x0014, SIERRA_DEQ_GLUT8},
1076        {0x0014, SIERRA_DEQ_GLUT9},
1077        {0x0014, SIERRA_DEQ_GLUT10},
1078        {0x0014, SIERRA_DEQ_GLUT11},
1079        {0x0014, SIERRA_DEQ_GLUT12},
1080        {0x0014, SIERRA_DEQ_GLUT13},
1081        {0x0014, SIERRA_DEQ_GLUT14},
1082        {0x0014, SIERRA_DEQ_GLUT15},
1083        {0x0014, SIERRA_DEQ_GLUT16},
1084        {0x0BAE, SIERRA_DEQ_ALUT0},
1085        {0x0AEB, SIERRA_DEQ_ALUT1},
1086        {0x0A28, SIERRA_DEQ_ALUT2},
1087        {0x0965, SIERRA_DEQ_ALUT3},
1088        {0x08A2, SIERRA_DEQ_ALUT4},
1089        {0x07DF, SIERRA_DEQ_ALUT5},
1090        {0x071C, SIERRA_DEQ_ALUT6},
1091        {0x0659, SIERRA_DEQ_ALUT7},
1092        {0x0596, SIERRA_DEQ_ALUT8},
1093        {0x0514, SIERRA_DEQ_ALUT9},
1094        {0x0492, SIERRA_DEQ_ALUT10},
1095        {0x0410, SIERRA_DEQ_ALUT11},
1096        {0x038E, SIERRA_DEQ_ALUT12},
1097        {0x030C, SIERRA_DEQ_ALUT13},
1098        {0x03F4, SIERRA_DEQ_DFETAP_CTRL_PREG},
1099        {0x0001, SIERRA_DFE_EN_1010_IGNORE_PREG},
1100        {0x3C01, SIERRA_DEQ_TAU_CTRL1_FAST_MAINT_PREG},
1101        {0x3C40, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG},
1102        {0x1C08, SIERRA_DEQ_TAU_CTRL2_PREG},
1103        {0x0033, SIERRA_DEQ_PICTRL_PREG},
1104        {0x0400, SIERRA_CPICAL_TMRVAL_MODE1_PREG},
1105        {0x0330, SIERRA_CPICAL_TMRVAL_MODE0_PREG},
1106        {0x01FF, SIERRA_CPICAL_PICNT_MODE1_PREG},
1107        {0x0009, SIERRA_CPI_OUTBUF_RATESEL_PREG},
1108        {0x3232, SIERRA_CPICAL_RES_STARTCODE_MODE23_PREG},
1109        {0x0005, SIERRA_LFPSDET_SUPPORT_PREG},
1110        {0x000F, SIERRA_LFPSFILT_NS_PREG},
1111        {0x0009, SIERRA_LFPSFILT_RD_PREG},
1112        {0x0001, SIERRA_LFPSFILT_MP_PREG},
1113        {0x6013, SIERRA_SIGDET_SUPPORT_PREG},
1114        {0x8013, SIERRA_SDFILT_H2L_A_PREG},
1115        {0x8009, SIERRA_SDFILT_L2H_PREG},
1116        {0x0024, SIERRA_RXBUFFER_CTLECTRL_PREG},
1117        {0x0020, SIERRA_RXBUFFER_RCDFECTRL_PREG},
1118        {0x4243, SIERRA_RXBUFFER_DFECTRL_PREG}
1119};
1120
1121static const struct cdns_sierra_data cdns_map_sierra = {
1122        SIERRA_MACRO_ID,
1123        0x2,
1124        0x2,
1125        ARRAY_SIZE(cdns_pcie_cmn_regs_ext_ssc),
1126        ARRAY_SIZE(cdns_pcie_ln_regs_ext_ssc),
1127        ARRAY_SIZE(cdns_usb_cmn_regs_ext_ssc),
1128        ARRAY_SIZE(cdns_usb_ln_regs_ext_ssc),
1129        cdns_pcie_cmn_regs_ext_ssc,
1130        cdns_pcie_ln_regs_ext_ssc,
1131        cdns_usb_cmn_regs_ext_ssc,
1132        cdns_usb_ln_regs_ext_ssc,
1133};
1134
1135static const struct cdns_sierra_data cdns_ti_map_sierra = {
1136        SIERRA_MACRO_ID,
1137        0x0,
1138        0x1,
1139        ARRAY_SIZE(cdns_pcie_cmn_regs_ext_ssc),
1140        ARRAY_SIZE(cdns_pcie_ln_regs_ext_ssc),
1141        ARRAY_SIZE(cdns_usb_cmn_regs_ext_ssc),
1142        ARRAY_SIZE(cdns_usb_ln_regs_ext_ssc),
1143        cdns_pcie_cmn_regs_ext_ssc,
1144        cdns_pcie_ln_regs_ext_ssc,
1145        cdns_usb_cmn_regs_ext_ssc,
1146        cdns_usb_ln_regs_ext_ssc,
1147};
1148
1149static const struct of_device_id cdns_sierra_id_table[] = {
1150        {
1151                .compatible = "cdns,sierra-phy-t0",
1152                .data = &cdns_map_sierra,
1153        },
1154        {
1155                .compatible = "ti,sierra-phy-t0",
1156                .data = &cdns_ti_map_sierra,
1157        },
1158        {}
1159};
1160MODULE_DEVICE_TABLE(of, cdns_sierra_id_table);
1161
1162static struct platform_driver cdns_sierra_driver = {
1163        .probe          = cdns_sierra_phy_probe,
1164        .remove         = cdns_sierra_phy_remove,
1165        .driver         = {
1166                .name   = "cdns-sierra-phy",
1167                .of_match_table = cdns_sierra_id_table,
1168        },
1169};
1170module_platform_driver(cdns_sierra_driver);
1171
1172MODULE_ALIAS("platform:cdns_sierra");
1173MODULE_AUTHOR("Cadence Design Systems");
1174MODULE_DESCRIPTION("CDNS sierra phy driver");
1175MODULE_LICENSE("GPL v2");
1176