linux/drivers/phy/broadcom/phy-brcm-sata.c
<<
>>
Prefs
   1/*
   2 * Broadcom SATA3 AHCI Controller PHY Driver
   3 *
   4 * Copyright (C) 2016 Broadcom
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2, or (at your option)
   9 * any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 */
  16
  17#include <linux/delay.h>
  18#include <linux/device.h>
  19#include <linux/init.h>
  20#include <linux/interrupt.h>
  21#include <linux/io.h>
  22#include <linux/kernel.h>
  23#include <linux/module.h>
  24#include <linux/of.h>
  25#include <linux/phy/phy.h>
  26#include <linux/platform_device.h>
  27
  28#define SATA_PCB_BANK_OFFSET                            0x23c
  29#define SATA_PCB_REG_OFFSET(ofs)                        ((ofs) * 4)
  30
  31#define MAX_PORTS                                       2
  32
  33/* Register offset between PHYs in PCB space */
  34#define SATA_PCB_REG_28NM_SPACE_SIZE                    0x1000
  35
  36/* The older SATA PHY registers duplicated per port registers within the map,
  37 * rather than having a separate map per port.
  38 */
  39#define SATA_PCB_REG_40NM_SPACE_SIZE                    0x10
  40
  41/* Register offset between PHYs in PHY control space */
  42#define SATA_PHY_CTRL_REG_28NM_SPACE_SIZE               0x8
  43
  44enum brcm_sata_phy_version {
  45        BRCM_SATA_PHY_STB_28NM,
  46        BRCM_SATA_PHY_STB_40NM,
  47        BRCM_SATA_PHY_IPROC_NS2,
  48        BRCM_SATA_PHY_IPROC_NSP,
  49        BRCM_SATA_PHY_IPROC_SR,
  50        BRCM_SATA_PHY_DSL_28NM,
  51};
  52
  53enum brcm_sata_phy_rxaeq_mode {
  54        RXAEQ_MODE_OFF = 0,
  55        RXAEQ_MODE_AUTO,
  56        RXAEQ_MODE_MANUAL,
  57};
  58
  59static enum brcm_sata_phy_rxaeq_mode rxaeq_to_val(const char *m)
  60{
  61        if (!strcmp(m, "auto"))
  62                return RXAEQ_MODE_AUTO;
  63        else if (!strcmp(m, "manual"))
  64                return RXAEQ_MODE_MANUAL;
  65        else
  66                return RXAEQ_MODE_OFF;
  67}
  68
  69struct brcm_sata_port {
  70        int portnum;
  71        struct phy *phy;
  72        struct brcm_sata_phy *phy_priv;
  73        bool ssc_en;
  74        enum brcm_sata_phy_rxaeq_mode rxaeq_mode;
  75        u32 rxaeq_val;
  76};
  77
  78struct brcm_sata_phy {
  79        struct device *dev;
  80        void __iomem *phy_base;
  81        void __iomem *ctrl_base;
  82        enum brcm_sata_phy_version version;
  83
  84        struct brcm_sata_port phys[MAX_PORTS];
  85};
  86
  87enum sata_phy_regs {
  88        BLOCK0_REG_BANK                         = 0x000,
  89        BLOCK0_XGXSSTATUS                       = 0x81,
  90        BLOCK0_XGXSSTATUS_PLL_LOCK              = BIT(12),
  91        BLOCK0_SPARE                            = 0x8d,
  92        BLOCK0_SPARE_OOB_CLK_SEL_MASK           = 0x3,
  93        BLOCK0_SPARE_OOB_CLK_SEL_REFBY2         = 0x1,
  94
  95        PLL_REG_BANK_0                          = 0x050,
  96        PLL_REG_BANK_0_PLLCONTROL_0             = 0x81,
  97        PLLCONTROL_0_FREQ_DET_RESTART           = BIT(13),
  98        PLLCONTROL_0_FREQ_MONITOR               = BIT(12),
  99        PLLCONTROL_0_SEQ_START                  = BIT(15),
 100        PLL_CAP_CHARGE_TIME                     = 0x83,
 101        PLL_VCO_CAL_THRESH                      = 0x84,
 102        PLL_CAP_CONTROL                         = 0x85,
 103        PLL_FREQ_DET_TIME                       = 0x86,
 104        PLL_ACTRL2                              = 0x8b,
 105        PLL_ACTRL2_SELDIV_MASK                  = 0x1f,
 106        PLL_ACTRL2_SELDIV_SHIFT                 = 9,
 107        PLL_ACTRL6                              = 0x86,
 108
 109        PLL1_REG_BANK                           = 0x060,
 110        PLL1_ACTRL2                             = 0x82,
 111        PLL1_ACTRL3                             = 0x83,
 112        PLL1_ACTRL4                             = 0x84,
 113        PLL1_ACTRL5                             = 0x85,
 114        PLL1_ACTRL6                             = 0x86,
 115        PLL1_ACTRL7                             = 0x87,
 116
 117        TX_REG_BANK                             = 0x070,
 118        TX_ACTRL0                               = 0x80,
 119        TX_ACTRL0_TXPOL_FLIP                    = BIT(6),
 120
 121        AEQRX_REG_BANK_0                        = 0xd0,
 122        AEQ_CONTROL1                            = 0x81,
 123        AEQ_CONTROL1_ENABLE                     = BIT(2),
 124        AEQ_CONTROL1_FREEZE                     = BIT(3),
 125        AEQ_FRC_EQ                              = 0x83,
 126        AEQ_FRC_EQ_FORCE                        = BIT(0),
 127        AEQ_FRC_EQ_FORCE_VAL                    = BIT(1),
 128        AEQRX_REG_BANK_1                        = 0xe0,
 129        AEQRX_SLCAL0_CTRL0                      = 0x82,
 130        AEQRX_SLCAL1_CTRL0                      = 0x86,
 131
 132        OOB_REG_BANK                            = 0x150,
 133        OOB1_REG_BANK                           = 0x160,
 134        OOB_CTRL1                               = 0x80,
 135        OOB_CTRL1_BURST_MAX_MASK                = 0xf,
 136        OOB_CTRL1_BURST_MAX_SHIFT               = 12,
 137        OOB_CTRL1_BURST_MIN_MASK                = 0xf,
 138        OOB_CTRL1_BURST_MIN_SHIFT               = 8,
 139        OOB_CTRL1_WAKE_IDLE_MAX_MASK            = 0xf,
 140        OOB_CTRL1_WAKE_IDLE_MAX_SHIFT           = 4,
 141        OOB_CTRL1_WAKE_IDLE_MIN_MASK            = 0xf,
 142        OOB_CTRL1_WAKE_IDLE_MIN_SHIFT           = 0,
 143        OOB_CTRL2                               = 0x81,
 144        OOB_CTRL2_SEL_ENA_SHIFT                 = 15,
 145        OOB_CTRL2_SEL_ENA_RC_SHIFT              = 14,
 146        OOB_CTRL2_RESET_IDLE_MAX_MASK           = 0x3f,
 147        OOB_CTRL2_RESET_IDLE_MAX_SHIFT          = 8,
 148        OOB_CTRL2_BURST_CNT_MASK                = 0x3,
 149        OOB_CTRL2_BURST_CNT_SHIFT               = 6,
 150        OOB_CTRL2_RESET_IDLE_MIN_MASK           = 0x3f,
 151        OOB_CTRL2_RESET_IDLE_MIN_SHIFT          = 0,
 152
 153        TXPMD_REG_BANK                          = 0x1a0,
 154        TXPMD_CONTROL1                          = 0x81,
 155        TXPMD_CONTROL1_TX_SSC_EN_FRC            = BIT(0),
 156        TXPMD_CONTROL1_TX_SSC_EN_FRC_VAL        = BIT(1),
 157        TXPMD_TX_FREQ_CTRL_CONTROL1             = 0x82,
 158        TXPMD_TX_FREQ_CTRL_CONTROL2             = 0x83,
 159        TXPMD_TX_FREQ_CTRL_CONTROL2_FMIN_MASK   = 0x3ff,
 160        TXPMD_TX_FREQ_CTRL_CONTROL3             = 0x84,
 161        TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK   = 0x3ff,
 162
 163        RXPMD_REG_BANK                          = 0x1c0,
 164        RXPMD_RX_FREQ_MON_CONTROL1              = 0x87,
 165};
 166
 167enum sata_phy_ctrl_regs {
 168        PHY_CTRL_1                              = 0x0,
 169        PHY_CTRL_1_RESET                        = BIT(0),
 170};
 171
 172static inline void __iomem *brcm_sata_pcb_base(struct brcm_sata_port *port)
 173{
 174        struct brcm_sata_phy *priv = port->phy_priv;
 175        u32 size = 0;
 176
 177        switch (priv->version) {
 178        case BRCM_SATA_PHY_STB_28NM:
 179        case BRCM_SATA_PHY_IPROC_NS2:
 180        case BRCM_SATA_PHY_DSL_28NM:
 181                size = SATA_PCB_REG_28NM_SPACE_SIZE;
 182                break;
 183        case BRCM_SATA_PHY_STB_40NM:
 184                size = SATA_PCB_REG_40NM_SPACE_SIZE;
 185                break;
 186        default:
 187                dev_err(priv->dev, "invalid phy version\n");
 188                break;
 189        }
 190
 191        return priv->phy_base + (port->portnum * size);
 192}
 193
 194static inline void __iomem *brcm_sata_ctrl_base(struct brcm_sata_port *port)
 195{
 196        struct brcm_sata_phy *priv = port->phy_priv;
 197        u32 size = 0;
 198
 199        switch (priv->version) {
 200        case BRCM_SATA_PHY_IPROC_NS2:
 201                size = SATA_PHY_CTRL_REG_28NM_SPACE_SIZE;
 202                break;
 203        default:
 204                dev_err(priv->dev, "invalid phy version\n");
 205                break;
 206        }
 207
 208        return priv->ctrl_base + (port->portnum * size);
 209}
 210
 211static void brcm_sata_phy_wr(void __iomem *pcb_base, u32 bank,
 212                             u32 ofs, u32 msk, u32 value)
 213{
 214        u32 tmp;
 215
 216        writel(bank, pcb_base + SATA_PCB_BANK_OFFSET);
 217        tmp = readl(pcb_base + SATA_PCB_REG_OFFSET(ofs));
 218        tmp = (tmp & msk) | value;
 219        writel(tmp, pcb_base + SATA_PCB_REG_OFFSET(ofs));
 220}
 221
 222static u32 brcm_sata_phy_rd(void __iomem *pcb_base, u32 bank, u32 ofs)
 223{
 224        writel(bank, pcb_base + SATA_PCB_BANK_OFFSET);
 225        return readl(pcb_base + SATA_PCB_REG_OFFSET(ofs));
 226}
 227
 228/* These defaults were characterized by H/W group */
 229#define STB_FMIN_VAL_DEFAULT    0x3df
 230#define STB_FMAX_VAL_DEFAULT    0x3df
 231#define STB_FMAX_VAL_SSC        0x83
 232
 233static void brcm_stb_sata_ssc_init(struct brcm_sata_port *port)
 234{
 235        void __iomem *base = brcm_sata_pcb_base(port);
 236        struct brcm_sata_phy *priv = port->phy_priv;
 237        u32 tmp;
 238
 239        /* override the TX spread spectrum setting */
 240        tmp = TXPMD_CONTROL1_TX_SSC_EN_FRC_VAL | TXPMD_CONTROL1_TX_SSC_EN_FRC;
 241        brcm_sata_phy_wr(base, TXPMD_REG_BANK, TXPMD_CONTROL1, ~tmp, tmp);
 242
 243        /* set fixed min freq */
 244        brcm_sata_phy_wr(base, TXPMD_REG_BANK, TXPMD_TX_FREQ_CTRL_CONTROL2,
 245                         ~TXPMD_TX_FREQ_CTRL_CONTROL2_FMIN_MASK,
 246                         STB_FMIN_VAL_DEFAULT);
 247
 248        /* set fixed max freq depending on SSC config */
 249        if (port->ssc_en) {
 250                dev_info(priv->dev, "enabling SSC on port%d\n", port->portnum);
 251                tmp = STB_FMAX_VAL_SSC;
 252        } else {
 253                tmp = STB_FMAX_VAL_DEFAULT;
 254        }
 255
 256        brcm_sata_phy_wr(base, TXPMD_REG_BANK, TXPMD_TX_FREQ_CTRL_CONTROL3,
 257                          ~TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK, tmp);
 258}
 259
 260#define AEQ_FRC_EQ_VAL_SHIFT    2
 261#define AEQ_FRC_EQ_VAL_MASK     0x3f
 262
 263static int brcm_stb_sata_rxaeq_init(struct brcm_sata_port *port)
 264{
 265        void __iomem *base = brcm_sata_pcb_base(port);
 266        u32 tmp = 0, reg = 0;
 267
 268        switch (port->rxaeq_mode) {
 269        case RXAEQ_MODE_OFF:
 270                return 0;
 271
 272        case RXAEQ_MODE_AUTO:
 273                reg = AEQ_CONTROL1;
 274                tmp = AEQ_CONTROL1_ENABLE | AEQ_CONTROL1_FREEZE;
 275                break;
 276
 277        case RXAEQ_MODE_MANUAL:
 278                reg = AEQ_FRC_EQ;
 279                tmp = AEQ_FRC_EQ_FORCE | AEQ_FRC_EQ_FORCE_VAL;
 280                if (port->rxaeq_val > AEQ_FRC_EQ_VAL_MASK)
 281                        return -EINVAL;
 282                tmp |= port->rxaeq_val << AEQ_FRC_EQ_VAL_SHIFT;
 283                break;
 284        }
 285
 286        brcm_sata_phy_wr(base, AEQRX_REG_BANK_0, reg, ~tmp, tmp);
 287        brcm_sata_phy_wr(base, AEQRX_REG_BANK_1, reg, ~tmp, tmp);
 288
 289        return 0;
 290}
 291
 292static int brcm_stb_sata_init(struct brcm_sata_port *port)
 293{
 294        brcm_stb_sata_ssc_init(port);
 295
 296        return brcm_stb_sata_rxaeq_init(port);
 297}
 298
 299/* NS2 SATA PLL1 defaults were characterized by H/W group */
 300#define NS2_PLL1_ACTRL2_MAGIC   0x1df8
 301#define NS2_PLL1_ACTRL3_MAGIC   0x2b00
 302#define NS2_PLL1_ACTRL4_MAGIC   0x8824
 303
 304static int brcm_ns2_sata_init(struct brcm_sata_port *port)
 305{
 306        int try;
 307        unsigned int val;
 308        void __iomem *base = brcm_sata_pcb_base(port);
 309        void __iomem *ctrl_base = brcm_sata_ctrl_base(port);
 310        struct device *dev = port->phy_priv->dev;
 311
 312        /* Configure OOB control */
 313        val = 0x0;
 314        val |= (0xc << OOB_CTRL1_BURST_MAX_SHIFT);
 315        val |= (0x4 << OOB_CTRL1_BURST_MIN_SHIFT);
 316        val |= (0x9 << OOB_CTRL1_WAKE_IDLE_MAX_SHIFT);
 317        val |= (0x3 << OOB_CTRL1_WAKE_IDLE_MIN_SHIFT);
 318        brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL1, 0x0, val);
 319        val = 0x0;
 320        val |= (0x1b << OOB_CTRL2_RESET_IDLE_MAX_SHIFT);
 321        val |= (0x2 << OOB_CTRL2_BURST_CNT_SHIFT);
 322        val |= (0x9 << OOB_CTRL2_RESET_IDLE_MIN_SHIFT);
 323        brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL2, 0x0, val);
 324
 325        /* Configure PHY PLL register bank 1 */
 326        val = NS2_PLL1_ACTRL2_MAGIC;
 327        brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL2, 0x0, val);
 328        val = NS2_PLL1_ACTRL3_MAGIC;
 329        brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL3, 0x0, val);
 330        val = NS2_PLL1_ACTRL4_MAGIC;
 331        brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL4, 0x0, val);
 332
 333        /* Configure PHY BLOCK0 register bank */
 334        /* Set oob_clk_sel to refclk/2 */
 335        brcm_sata_phy_wr(base, BLOCK0_REG_BANK, BLOCK0_SPARE,
 336                         ~BLOCK0_SPARE_OOB_CLK_SEL_MASK,
 337                         BLOCK0_SPARE_OOB_CLK_SEL_REFBY2);
 338
 339        /* Strobe PHY reset using PHY control register */
 340        writel(PHY_CTRL_1_RESET, ctrl_base + PHY_CTRL_1);
 341        mdelay(1);
 342        writel(0x0, ctrl_base + PHY_CTRL_1);
 343        mdelay(1);
 344
 345        /* Wait for PHY PLL lock by polling pll_lock bit */
 346        try = 50;
 347        while (try) {
 348                val = brcm_sata_phy_rd(base, BLOCK0_REG_BANK,
 349                                        BLOCK0_XGXSSTATUS);
 350                if (val & BLOCK0_XGXSSTATUS_PLL_LOCK)
 351                        break;
 352                msleep(20);
 353                try--;
 354        }
 355        if (!try) {
 356                /* PLL did not lock; give up */
 357                dev_err(dev, "port%d PLL did not lock\n", port->portnum);
 358                return -ETIMEDOUT;
 359        }
 360
 361        dev_dbg(dev, "port%d initialized\n", port->portnum);
 362
 363        return 0;
 364}
 365
 366static int brcm_nsp_sata_init(struct brcm_sata_port *port)
 367{
 368        struct brcm_sata_phy *priv = port->phy_priv;
 369        struct device *dev = port->phy_priv->dev;
 370        void __iomem *base = priv->phy_base;
 371        unsigned int oob_bank;
 372        unsigned int val, try;
 373
 374        /* Configure OOB control */
 375        if (port->portnum == 0)
 376                oob_bank = OOB_REG_BANK;
 377        else if (port->portnum == 1)
 378                oob_bank = OOB1_REG_BANK;
 379        else
 380                return -EINVAL;
 381
 382        val = 0x0;
 383        val |= (0x0f << OOB_CTRL1_BURST_MAX_SHIFT);
 384        val |= (0x06 << OOB_CTRL1_BURST_MIN_SHIFT);
 385        val |= (0x0f << OOB_CTRL1_WAKE_IDLE_MAX_SHIFT);
 386        val |= (0x06 << OOB_CTRL1_WAKE_IDLE_MIN_SHIFT);
 387        brcm_sata_phy_wr(base, oob_bank, OOB_CTRL1, 0x0, val);
 388
 389        val = 0x0;
 390        val |= (0x2e << OOB_CTRL2_RESET_IDLE_MAX_SHIFT);
 391        val |= (0x02 << OOB_CTRL2_BURST_CNT_SHIFT);
 392        val |= (0x16 << OOB_CTRL2_RESET_IDLE_MIN_SHIFT);
 393        brcm_sata_phy_wr(base, oob_bank, OOB_CTRL2, 0x0, val);
 394
 395
 396        brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_ACTRL2,
 397                ~(PLL_ACTRL2_SELDIV_MASK << PLL_ACTRL2_SELDIV_SHIFT),
 398                0x0c << PLL_ACTRL2_SELDIV_SHIFT);
 399
 400        brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_CAP_CONTROL,
 401                                                0xff0, 0x4f0);
 402
 403        val = PLLCONTROL_0_FREQ_DET_RESTART | PLLCONTROL_0_FREQ_MONITOR;
 404        brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
 405                                                                ~val, val);
 406        val = PLLCONTROL_0_SEQ_START;
 407        brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
 408                                                                ~val, 0);
 409        mdelay(10);
 410        brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
 411                                                                ~val, val);
 412
 413        /* Wait for pll_seq_done bit */
 414        try = 50;
 415        while (--try) {
 416                val = brcm_sata_phy_rd(base, BLOCK0_REG_BANK,
 417                                        BLOCK0_XGXSSTATUS);
 418                if (val & BLOCK0_XGXSSTATUS_PLL_LOCK)
 419                        break;
 420                msleep(20);
 421        }
 422        if (!try) {
 423                /* PLL did not lock; give up */
 424                dev_err(dev, "port%d PLL did not lock\n", port->portnum);
 425                return -ETIMEDOUT;
 426        }
 427
 428        dev_dbg(dev, "port%d initialized\n", port->portnum);
 429
 430        return 0;
 431}
 432
 433/* SR PHY PLL0 registers */
 434#define SR_PLL0_ACTRL6_MAGIC                    0xa
 435
 436/* SR PHY PLL1 registers */
 437#define SR_PLL1_ACTRL2_MAGIC                    0x32
 438#define SR_PLL1_ACTRL3_MAGIC                    0x2
 439#define SR_PLL1_ACTRL4_MAGIC                    0x3e8
 440
 441static int brcm_sr_sata_init(struct brcm_sata_port *port)
 442{
 443        struct brcm_sata_phy *priv = port->phy_priv;
 444        struct device *dev = port->phy_priv->dev;
 445        void __iomem *base = priv->phy_base;
 446        unsigned int val, try;
 447
 448        /* Configure PHY PLL register bank 1 */
 449        val = SR_PLL1_ACTRL2_MAGIC;
 450        brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL2, 0x0, val);
 451        val = SR_PLL1_ACTRL3_MAGIC;
 452        brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL3, 0x0, val);
 453        val = SR_PLL1_ACTRL4_MAGIC;
 454        brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL4, 0x0, val);
 455
 456        /* Configure PHY PLL register bank 0 */
 457        val = SR_PLL0_ACTRL6_MAGIC;
 458        brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_ACTRL6, 0x0, val);
 459
 460        /* Wait for PHY PLL lock by polling pll_lock bit */
 461        try = 50;
 462        do {
 463                val = brcm_sata_phy_rd(base, BLOCK0_REG_BANK,
 464                                        BLOCK0_XGXSSTATUS);
 465                if (val & BLOCK0_XGXSSTATUS_PLL_LOCK)
 466                        break;
 467                msleep(20);
 468                try--;
 469        } while (try);
 470
 471        if ((val & BLOCK0_XGXSSTATUS_PLL_LOCK) == 0) {
 472                /* PLL did not lock; give up */
 473                dev_err(dev, "port%d PLL did not lock\n", port->portnum);
 474                return -ETIMEDOUT;
 475        }
 476
 477        /* Invert Tx polarity */
 478        brcm_sata_phy_wr(base, TX_REG_BANK, TX_ACTRL0,
 479                         ~TX_ACTRL0_TXPOL_FLIP, TX_ACTRL0_TXPOL_FLIP);
 480
 481        /* Configure OOB control to handle 100MHz reference clock */
 482        val = ((0xc << OOB_CTRL1_BURST_MAX_SHIFT) |
 483                (0x4 << OOB_CTRL1_BURST_MIN_SHIFT) |
 484                (0x8 << OOB_CTRL1_WAKE_IDLE_MAX_SHIFT) |
 485                (0x3 << OOB_CTRL1_WAKE_IDLE_MIN_SHIFT));
 486        brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL1, 0x0, val);
 487        val = ((0x1b << OOB_CTRL2_RESET_IDLE_MAX_SHIFT) |
 488                (0x2 << OOB_CTRL2_BURST_CNT_SHIFT) |
 489                (0x9 << OOB_CTRL2_RESET_IDLE_MIN_SHIFT));
 490        brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL2, 0x0, val);
 491
 492        return 0;
 493}
 494
 495static int brcm_dsl_sata_init(struct brcm_sata_port *port)
 496{
 497        void __iomem *base = brcm_sata_pcb_base(port);
 498        struct device *dev = port->phy_priv->dev;
 499        unsigned int try;
 500        u32 tmp;
 501
 502        brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL7, 0, 0x873);
 503
 504        brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL6, 0, 0xc000);
 505
 506        brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
 507                         0, 0x3089);
 508        usleep_range(1000, 2000);
 509
 510        brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
 511                         0, 0x3088);
 512        usleep_range(1000, 2000);
 513
 514        brcm_sata_phy_wr(base, AEQRX_REG_BANK_1, AEQRX_SLCAL0_CTRL0,
 515                         0, 0x3000);
 516
 517        brcm_sata_phy_wr(base, AEQRX_REG_BANK_1, AEQRX_SLCAL1_CTRL0,
 518                         0, 0x3000);
 519        usleep_range(1000, 2000);
 520
 521        brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_CAP_CHARGE_TIME, 0, 0x32);
 522
 523        brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_VCO_CAL_THRESH, 0, 0xa);
 524
 525        brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_FREQ_DET_TIME, 0, 0x64);
 526        usleep_range(1000, 2000);
 527
 528        /* Acquire PLL lock */
 529        try = 50;
 530        while (try) {
 531                tmp = brcm_sata_phy_rd(base, BLOCK0_REG_BANK,
 532                                       BLOCK0_XGXSSTATUS);
 533                if (tmp & BLOCK0_XGXSSTATUS_PLL_LOCK)
 534                        break;
 535                msleep(20);
 536                try--;
 537        };
 538
 539        if (!try) {
 540                /* PLL did not lock; give up */
 541                dev_err(dev, "port%d PLL did not lock\n", port->portnum);
 542                return -ETIMEDOUT;
 543        }
 544
 545        dev_dbg(dev, "port%d initialized\n", port->portnum);
 546
 547        return 0;
 548}
 549
 550static int brcm_sata_phy_init(struct phy *phy)
 551{
 552        int rc;
 553        struct brcm_sata_port *port = phy_get_drvdata(phy);
 554
 555        switch (port->phy_priv->version) {
 556        case BRCM_SATA_PHY_STB_28NM:
 557        case BRCM_SATA_PHY_STB_40NM:
 558                rc = brcm_stb_sata_init(port);
 559                break;
 560        case BRCM_SATA_PHY_IPROC_NS2:
 561                rc = brcm_ns2_sata_init(port);
 562                break;
 563        case BRCM_SATA_PHY_IPROC_NSP:
 564                rc = brcm_nsp_sata_init(port);
 565                break;
 566        case BRCM_SATA_PHY_IPROC_SR:
 567                rc = brcm_sr_sata_init(port);
 568                break;
 569        case BRCM_SATA_PHY_DSL_28NM:
 570                rc = brcm_dsl_sata_init(port);
 571                break;
 572        default:
 573                rc = -ENODEV;
 574        }
 575
 576        return rc;
 577}
 578
 579static void brcm_stb_sata_calibrate(struct brcm_sata_port *port)
 580{
 581        void __iomem *base = brcm_sata_pcb_base(port);
 582        u32 tmp = BIT(8);
 583
 584        brcm_sata_phy_wr(base, RXPMD_REG_BANK, RXPMD_RX_FREQ_MON_CONTROL1,
 585                         ~tmp, tmp);
 586}
 587
 588static int brcm_sata_phy_calibrate(struct phy *phy)
 589{
 590        struct brcm_sata_port *port = phy_get_drvdata(phy);
 591        int rc = -EOPNOTSUPP;
 592
 593        switch (port->phy_priv->version) {
 594        case BRCM_SATA_PHY_STB_28NM:
 595        case BRCM_SATA_PHY_STB_40NM:
 596                brcm_stb_sata_calibrate(port);
 597                rc = 0;
 598                break;
 599        default:
 600                break;
 601        }
 602
 603        return rc;
 604}
 605
 606static const struct phy_ops phy_ops = {
 607        .init           = brcm_sata_phy_init,
 608        .calibrate      = brcm_sata_phy_calibrate,
 609        .owner          = THIS_MODULE,
 610};
 611
 612static const struct of_device_id brcm_sata_phy_of_match[] = {
 613        { .compatible   = "brcm,bcm7445-sata-phy",
 614          .data = (void *)BRCM_SATA_PHY_STB_28NM },
 615        { .compatible   = "brcm,bcm7425-sata-phy",
 616          .data = (void *)BRCM_SATA_PHY_STB_40NM },
 617        { .compatible   = "brcm,iproc-ns2-sata-phy",
 618          .data = (void *)BRCM_SATA_PHY_IPROC_NS2 },
 619        { .compatible = "brcm,iproc-nsp-sata-phy",
 620          .data = (void *)BRCM_SATA_PHY_IPROC_NSP },
 621        { .compatible   = "brcm,iproc-sr-sata-phy",
 622          .data = (void *)BRCM_SATA_PHY_IPROC_SR },
 623        { .compatible   = "brcm,bcm63138-sata-phy",
 624          .data = (void *)BRCM_SATA_PHY_DSL_28NM },
 625        {},
 626};
 627MODULE_DEVICE_TABLE(of, brcm_sata_phy_of_match);
 628
 629static int brcm_sata_phy_probe(struct platform_device *pdev)
 630{
 631        const char *rxaeq_mode;
 632        struct device *dev = &pdev->dev;
 633        struct device_node *dn = dev->of_node, *child;
 634        const struct of_device_id *of_id;
 635        struct brcm_sata_phy *priv;
 636        struct resource *res;
 637        struct phy_provider *provider;
 638        int ret, count = 0;
 639
 640        if (of_get_child_count(dn) == 0)
 641                return -ENODEV;
 642
 643        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 644        if (!priv)
 645                return -ENOMEM;
 646        dev_set_drvdata(dev, priv);
 647        priv->dev = dev;
 648
 649        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
 650        priv->phy_base = devm_ioremap_resource(dev, res);
 651        if (IS_ERR(priv->phy_base))
 652                return PTR_ERR(priv->phy_base);
 653
 654        of_id = of_match_node(brcm_sata_phy_of_match, dn);
 655        if (of_id)
 656                priv->version = (enum brcm_sata_phy_version)of_id->data;
 657        else
 658                priv->version = BRCM_SATA_PHY_STB_28NM;
 659
 660        if (priv->version == BRCM_SATA_PHY_IPROC_NS2) {
 661                res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 662                                                   "phy-ctrl");
 663                priv->ctrl_base = devm_ioremap_resource(dev, res);
 664                if (IS_ERR(priv->ctrl_base))
 665                        return PTR_ERR(priv->ctrl_base);
 666        }
 667
 668        for_each_available_child_of_node(dn, child) {
 669                unsigned int id;
 670                struct brcm_sata_port *port;
 671
 672                if (of_property_read_u32(child, "reg", &id)) {
 673                        dev_err(dev, "missing reg property in node %pOFn\n",
 674                                        child);
 675                        ret = -EINVAL;
 676                        goto put_child;
 677                }
 678
 679                if (id >= MAX_PORTS) {
 680                        dev_err(dev, "invalid reg: %u\n", id);
 681                        ret = -EINVAL;
 682                        goto put_child;
 683                }
 684                if (priv->phys[id].phy) {
 685                        dev_err(dev, "already registered port %u\n", id);
 686                        ret = -EINVAL;
 687                        goto put_child;
 688                }
 689
 690                port = &priv->phys[id];
 691                port->portnum = id;
 692                port->phy_priv = priv;
 693                port->phy = devm_phy_create(dev, child, &phy_ops);
 694                port->rxaeq_mode = RXAEQ_MODE_OFF;
 695                if (!of_property_read_string(child, "brcm,rxaeq-mode",
 696                                             &rxaeq_mode))
 697                        port->rxaeq_mode = rxaeq_to_val(rxaeq_mode);
 698                if (port->rxaeq_mode == RXAEQ_MODE_MANUAL)
 699                        of_property_read_u32(child, "brcm,rxaeq-value",
 700                                             &port->rxaeq_val);
 701                port->ssc_en = of_property_read_bool(child, "brcm,enable-ssc");
 702                if (IS_ERR(port->phy)) {
 703                        dev_err(dev, "failed to create PHY\n");
 704                        ret = PTR_ERR(port->phy);
 705                        goto put_child;
 706                }
 707
 708                phy_set_drvdata(port->phy, port);
 709                count++;
 710        }
 711
 712        provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
 713        if (IS_ERR(provider)) {
 714                dev_err(dev, "could not register PHY provider\n");
 715                return PTR_ERR(provider);
 716        }
 717
 718        dev_info(dev, "registered %d port(s)\n", count);
 719
 720        return 0;
 721put_child:
 722        of_node_put(child);
 723        return ret;
 724}
 725
 726static struct platform_driver brcm_sata_phy_driver = {
 727        .probe  = brcm_sata_phy_probe,
 728        .driver = {
 729                .of_match_table = brcm_sata_phy_of_match,
 730                .name           = "brcm-sata-phy",
 731        }
 732};
 733module_platform_driver(brcm_sata_phy_driver);
 734
 735MODULE_DESCRIPTION("Broadcom SATA PHY driver");
 736MODULE_LICENSE("GPL");
 737MODULE_AUTHOR("Marc Carino");
 738MODULE_AUTHOR("Brian Norris");
 739MODULE_ALIAS("platform:phy-brcm-sata");
 740