linux/drivers/phy/qualcomm/phy-qcom-qmp.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2 and
   6 * only version 2 as published by the Free Software Foundation.
   7 *
   8 * This program is distributed in the hope that it will be useful,
   9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11 * GNU General Public License for more details.
  12 *
  13 */
  14
  15#include <linux/clk.h>
  16#include <linux/clk-provider.h>
  17#include <linux/delay.h>
  18#include <linux/err.h>
  19#include <linux/io.h>
  20#include <linux/iopoll.h>
  21#include <linux/kernel.h>
  22#include <linux/module.h>
  23#include <linux/of.h>
  24#include <linux/of_device.h>
  25#include <linux/of_address.h>
  26#include <linux/phy/phy.h>
  27#include <linux/platform_device.h>
  28#include <linux/regulator/consumer.h>
  29#include <linux/reset.h>
  30#include <linux/slab.h>
  31
  32#include <dt-bindings/phy/phy.h>
  33
  34/* QMP PHY QSERDES COM registers */
  35#define QSERDES_COM_BG_TIMER                            0x00c
  36#define QSERDES_COM_SSC_EN_CENTER                       0x010
  37#define QSERDES_COM_SSC_ADJ_PER1                        0x014
  38#define QSERDES_COM_SSC_ADJ_PER2                        0x018
  39#define QSERDES_COM_SSC_PER1                            0x01c
  40#define QSERDES_COM_SSC_PER2                            0x020
  41#define QSERDES_COM_SSC_STEP_SIZE1                      0x024
  42#define QSERDES_COM_SSC_STEP_SIZE2                      0x028
  43#define QSERDES_COM_BIAS_EN_CLKBUFLR_EN                 0x034
  44#define QSERDES_COM_CLK_ENABLE1                         0x038
  45#define QSERDES_COM_SYS_CLK_CTRL                        0x03c
  46#define QSERDES_COM_SYSCLK_BUF_ENABLE                   0x040
  47#define QSERDES_COM_PLL_IVCO                            0x048
  48#define QSERDES_COM_LOCK_CMP1_MODE0                     0x04c
  49#define QSERDES_COM_LOCK_CMP2_MODE0                     0x050
  50#define QSERDES_COM_LOCK_CMP3_MODE0                     0x054
  51#define QSERDES_COM_LOCK_CMP1_MODE1                     0x058
  52#define QSERDES_COM_LOCK_CMP2_MODE1                     0x05c
  53#define QSERDES_COM_LOCK_CMP3_MODE1                     0x060
  54#define QSERDES_COM_BG_TRIM                             0x070
  55#define QSERDES_COM_CLK_EP_DIV                          0x074
  56#define QSERDES_COM_CP_CTRL_MODE0                       0x078
  57#define QSERDES_COM_CP_CTRL_MODE1                       0x07c
  58#define QSERDES_COM_PLL_RCTRL_MODE0                     0x084
  59#define QSERDES_COM_PLL_RCTRL_MODE1                     0x088
  60#define QSERDES_COM_PLL_CCTRL_MODE0                     0x090
  61#define QSERDES_COM_PLL_CCTRL_MODE1                     0x094
  62#define QSERDES_COM_BIAS_EN_CTRL_BY_PSM                 0x0a8
  63#define QSERDES_COM_SYSCLK_EN_SEL                       0x0ac
  64#define QSERDES_COM_RESETSM_CNTRL                       0x0b4
  65#define QSERDES_COM_RESTRIM_CTRL                        0x0bc
  66#define QSERDES_COM_RESCODE_DIV_NUM                     0x0c4
  67#define QSERDES_COM_LOCK_CMP_EN                         0x0c8
  68#define QSERDES_COM_LOCK_CMP_CFG                        0x0cc
  69#define QSERDES_COM_DEC_START_MODE0                     0x0d0
  70#define QSERDES_COM_DEC_START_MODE1                     0x0d4
  71#define QSERDES_COM_DIV_FRAC_START1_MODE0               0x0dc
  72#define QSERDES_COM_DIV_FRAC_START2_MODE0               0x0e0
  73#define QSERDES_COM_DIV_FRAC_START3_MODE0               0x0e4
  74#define QSERDES_COM_DIV_FRAC_START1_MODE1               0x0e8
  75#define QSERDES_COM_DIV_FRAC_START2_MODE1               0x0ec
  76#define QSERDES_COM_DIV_FRAC_START3_MODE1               0x0f0
  77#define QSERDES_COM_INTEGLOOP_GAIN0_MODE0               0x108
  78#define QSERDES_COM_INTEGLOOP_GAIN1_MODE0               0x10c
  79#define QSERDES_COM_INTEGLOOP_GAIN0_MODE1               0x110
  80#define QSERDES_COM_INTEGLOOP_GAIN1_MODE1               0x114
  81#define QSERDES_COM_VCO_TUNE_CTRL                       0x124
  82#define QSERDES_COM_VCO_TUNE_MAP                        0x128
  83#define QSERDES_COM_VCO_TUNE1_MODE0                     0x12c
  84#define QSERDES_COM_VCO_TUNE2_MODE0                     0x130
  85#define QSERDES_COM_VCO_TUNE1_MODE1                     0x134
  86#define QSERDES_COM_VCO_TUNE2_MODE1                     0x138
  87#define QSERDES_COM_VCO_TUNE_TIMER1                     0x144
  88#define QSERDES_COM_VCO_TUNE_TIMER2                     0x148
  89#define QSERDES_COM_BG_CTRL                             0x170
  90#define QSERDES_COM_CLK_SELECT                          0x174
  91#define QSERDES_COM_HSCLK_SEL                           0x178
  92#define QSERDES_COM_CORECLK_DIV                         0x184
  93#define QSERDES_COM_CORE_CLK_EN                         0x18c
  94#define QSERDES_COM_C_READY_STATUS                      0x190
  95#define QSERDES_COM_CMN_CONFIG                          0x194
  96#define QSERDES_COM_SVS_MODE_CLK_SEL                    0x19c
  97#define QSERDES_COM_DEBUG_BUS0                          0x1a0
  98#define QSERDES_COM_DEBUG_BUS1                          0x1a4
  99#define QSERDES_COM_DEBUG_BUS2                          0x1a8
 100#define QSERDES_COM_DEBUG_BUS3                          0x1ac
 101#define QSERDES_COM_DEBUG_BUS_SEL                       0x1b0
 102#define QSERDES_COM_CORECLK_DIV_MODE1                   0x1bc
 103
 104/* QMP PHY TX registers */
 105#define QSERDES_TX_RES_CODE_LANE_OFFSET                 0x054
 106#define QSERDES_TX_DEBUG_BUS_SEL                        0x064
 107#define QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN     0x068
 108#define QSERDES_TX_LANE_MODE                            0x094
 109#define QSERDES_TX_RCV_DETECT_LVL_2                     0x0ac
 110
 111/* QMP PHY RX registers */
 112#define QSERDES_RX_UCDR_SO_GAIN_HALF                    0x010
 113#define QSERDES_RX_UCDR_SO_GAIN                         0x01c
 114#define QSERDES_RX_UCDR_FASTLOCK_FO_GAIN                0x040
 115#define QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE        0x048
 116#define QSERDES_RX_RX_TERM_BW                           0x090
 117#define QSERDES_RX_RX_EQ_GAIN1_LSB                      0x0c4
 118#define QSERDES_RX_RX_EQ_GAIN1_MSB                      0x0c8
 119#define QSERDES_RX_RX_EQ_GAIN2_LSB                      0x0cc
 120#define QSERDES_RX_RX_EQ_GAIN2_MSB                      0x0d0
 121#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2                0x0d8
 122#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3                0x0dc
 123#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4                0x0e0
 124#define QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1          0x108
 125#define QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2             0x10c
 126#define QSERDES_RX_SIGDET_ENABLES                       0x110
 127#define QSERDES_RX_SIGDET_CNTRL                         0x114
 128#define QSERDES_RX_SIGDET_LVL                           0x118
 129#define QSERDES_RX_SIGDET_DEGLITCH_CNTRL                0x11c
 130#define QSERDES_RX_RX_BAND                              0x120
 131#define QSERDES_RX_RX_INTERFACE_MODE                    0x12c
 132
 133/* QMP PHY PCS registers */
 134#define QPHY_POWER_DOWN_CONTROL                         0x04
 135#define QPHY_TXDEEMPH_M6DB_V0                           0x24
 136#define QPHY_TXDEEMPH_M3P5DB_V0                         0x28
 137#define QPHY_ENDPOINT_REFCLK_DRIVE                      0x54
 138#define QPHY_RX_IDLE_DTCT_CNTRL                         0x58
 139#define QPHY_POWER_STATE_CONFIG1                        0x60
 140#define QPHY_POWER_STATE_CONFIG2                        0x64
 141#define QPHY_POWER_STATE_CONFIG4                        0x6c
 142#define QPHY_LOCK_DETECT_CONFIG1                        0x80
 143#define QPHY_LOCK_DETECT_CONFIG2                        0x84
 144#define QPHY_LOCK_DETECT_CONFIG3                        0x88
 145#define QPHY_PWRUP_RESET_DLY_TIME_AUXCLK                0xa0
 146#define QPHY_LP_WAKEUP_DLY_TIME_AUXCLK                  0xa4
 147#define QPHY_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB           0x1A8
 148#define QPHY_OSC_DTCT_ACTIONS                           0x1AC
 149#define QPHY_RX_SIGDET_LVL                              0x1D8
 150#define QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB            0x1DC
 151#define QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB            0x1E0
 152
 153/* QPHY_SW_RESET bit */
 154#define SW_RESET                                BIT(0)
 155/* QPHY_POWER_DOWN_CONTROL */
 156#define SW_PWRDN                                BIT(0)
 157#define REFCLK_DRV_DSBL                         BIT(1)
 158/* QPHY_START_CONTROL bits */
 159#define SERDES_START                            BIT(0)
 160#define PCS_START                               BIT(1)
 161#define PLL_READY_GATE_EN                       BIT(3)
 162/* QPHY_PCS_STATUS bit */
 163#define PHYSTATUS                               BIT(6)
 164/* QPHY_COM_PCS_READY_STATUS bit */
 165#define PCS_READY                               BIT(0)
 166
 167#define PHY_INIT_COMPLETE_TIMEOUT               1000
 168#define POWER_DOWN_DELAY_US_MIN                 10
 169#define POWER_DOWN_DELAY_US_MAX                 11
 170
 171#define MAX_PROP_NAME                           32
 172
 173struct qmp_phy_init_tbl {
 174        unsigned int offset;
 175        unsigned int val;
 176        /*
 177         * register part of layout ?
 178         * if yes, then offset gives index in the reg-layout
 179         */
 180        int in_layout;
 181};
 182
 183#define QMP_PHY_INIT_CFG(o, v)          \
 184        {                               \
 185                .offset = o,            \
 186                .val = v,               \
 187        }
 188
 189#define QMP_PHY_INIT_CFG_L(o, v)        \
 190        {                               \
 191                .offset = o,            \
 192                .val = v,               \
 193                .in_layout = 1,         \
 194        }
 195
 196/* set of registers with offsets different per-PHY */
 197enum qphy_reg_layout {
 198        /* Common block control registers */
 199        QPHY_COM_SW_RESET,
 200        QPHY_COM_POWER_DOWN_CONTROL,
 201        QPHY_COM_START_CONTROL,
 202        QPHY_COM_PCS_READY_STATUS,
 203        /* PCS registers */
 204        QPHY_PLL_LOCK_CHK_DLY_TIME,
 205        QPHY_FLL_CNTRL1,
 206        QPHY_FLL_CNTRL2,
 207        QPHY_FLL_CNT_VAL_L,
 208        QPHY_FLL_CNT_VAL_H_TOL,
 209        QPHY_FLL_MAN_CODE,
 210        QPHY_SW_RESET,
 211        QPHY_START_CTRL,
 212        QPHY_PCS_READY_STATUS,
 213};
 214
 215static const unsigned int pciephy_regs_layout[] = {
 216        [QPHY_COM_SW_RESET]             = 0x400,
 217        [QPHY_COM_POWER_DOWN_CONTROL]   = 0x404,
 218        [QPHY_COM_START_CONTROL]        = 0x408,
 219        [QPHY_COM_PCS_READY_STATUS]     = 0x448,
 220        [QPHY_PLL_LOCK_CHK_DLY_TIME]    = 0xa8,
 221        [QPHY_FLL_CNTRL1]               = 0xc4,
 222        [QPHY_FLL_CNTRL2]               = 0xc8,
 223        [QPHY_FLL_CNT_VAL_L]            = 0xcc,
 224        [QPHY_FLL_CNT_VAL_H_TOL]        = 0xd0,
 225        [QPHY_FLL_MAN_CODE]             = 0xd4,
 226        [QPHY_SW_RESET]                 = 0x00,
 227        [QPHY_START_CTRL]               = 0x08,
 228        [QPHY_PCS_READY_STATUS]         = 0x174,
 229};
 230
 231static const unsigned int usb3phy_regs_layout[] = {
 232        [QPHY_FLL_CNTRL1]               = 0xc0,
 233        [QPHY_FLL_CNTRL2]               = 0xc4,
 234        [QPHY_FLL_CNT_VAL_L]            = 0xc8,
 235        [QPHY_FLL_CNT_VAL_H_TOL]        = 0xcc,
 236        [QPHY_FLL_MAN_CODE]             = 0xd0,
 237        [QPHY_SW_RESET]                 = 0x00,
 238        [QPHY_START_CTRL]               = 0x08,
 239        [QPHY_PCS_READY_STATUS]         = 0x17c,
 240};
 241
 242static const struct qmp_phy_init_tbl msm8996_pcie_serdes_tbl[] = {
 243        QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x1c),
 244        QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
 245        QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
 246        QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
 247        QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x42),
 248        QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
 249        QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
 250        QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x1f),
 251        QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x01),
 252        QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
 253        QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
 254        QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
 255        QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x09),
 256        QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
 257        QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
 258        QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
 259        QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
 260        QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
 261        QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x1a),
 262        QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x0a),
 263        QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
 264        QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),
 265        QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1f),
 266        QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x04),
 267        QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
 268        QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
 269        QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
 270        QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
 271        QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
 272        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
 273        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
 274        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
 275        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x02),
 276        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
 277        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0x2f),
 278        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x19),
 279        QMP_PHY_INIT_CFG(QSERDES_COM_RESCODE_DIV_NUM, 0x15),
 280        QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
 281        QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
 282        QMP_PHY_INIT_CFG(QSERDES_COM_CLK_EP_DIV, 0x19),
 283        QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
 284        QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
 285        QMP_PHY_INIT_CFG(QSERDES_COM_RESCODE_DIV_NUM, 0x40),
 286};
 287
 288static const struct qmp_phy_init_tbl msm8996_pcie_tx_tbl[] = {
 289        QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
 290        QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
 291};
 292
 293static const struct qmp_phy_init_tbl msm8996_pcie_rx_tbl[] = {
 294        QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x1c),
 295        QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x01),
 296        QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x00),
 297        QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xdb),
 298        QMP_PHY_INIT_CFG(QSERDES_RX_RX_BAND, 0x18),
 299        QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x04),
 300        QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN_HALF, 0x04),
 301        QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
 302        QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
 303        QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x19),
 304};
 305
 306static const struct qmp_phy_init_tbl msm8996_pcie_pcs_tbl[] = {
 307        QMP_PHY_INIT_CFG(QPHY_RX_IDLE_DTCT_CNTRL, 0x4c),
 308        QMP_PHY_INIT_CFG(QPHY_PWRUP_RESET_DLY_TIME_AUXCLK, 0x00),
 309        QMP_PHY_INIT_CFG(QPHY_LP_WAKEUP_DLY_TIME_AUXCLK, 0x01),
 310
 311        QMP_PHY_INIT_CFG_L(QPHY_PLL_LOCK_CHK_DLY_TIME, 0x05),
 312
 313        QMP_PHY_INIT_CFG(QPHY_ENDPOINT_REFCLK_DRIVE, 0x05),
 314        QMP_PHY_INIT_CFG(QPHY_POWER_DOWN_CONTROL, 0x02),
 315        QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG4, 0x00),
 316        QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG1, 0xa3),
 317        QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M3P5DB_V0, 0x0e),
 318};
 319
 320static const struct qmp_phy_init_tbl msm8996_usb3_serdes_tbl[] = {
 321        QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
 322        QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
 323        QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
 324        QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
 325        QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
 326        QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
 327        QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
 328        QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
 329        QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x04),
 330        /* PLL and Loop filter settings */
 331        QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
 332        QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
 333        QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
 334        QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
 335        QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
 336        QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
 337        QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
 338        QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
 339        QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
 340        QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15),
 341        QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34),
 342        QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
 343        QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
 344        QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
 345        QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
 346        QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
 347        /* SSC settings */
 348        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
 349        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
 350        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
 351        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
 352        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
 353        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde),
 354        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07),
 355};
 356
 357static const struct qmp_phy_init_tbl msm8996_usb3_tx_tbl[] = {
 358        QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
 359        QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2, 0x12),
 360        QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
 361};
 362
 363static const struct qmp_phy_init_tbl msm8996_usb3_rx_tbl[] = {
 364        QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
 365        QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x04),
 366        QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
 367        QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4c),
 368        QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xbb),
 369        QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
 370        QMP_PHY_INIT_CFG(QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
 371        QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x03),
 372        QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x18),
 373        QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
 374};
 375
 376static const struct qmp_phy_init_tbl msm8996_usb3_pcs_tbl[] = {
 377        /* FLL settings */
 378        QMP_PHY_INIT_CFG_L(QPHY_FLL_CNTRL2, 0x03),
 379        QMP_PHY_INIT_CFG_L(QPHY_FLL_CNTRL1, 0x02),
 380        QMP_PHY_INIT_CFG_L(QPHY_FLL_CNT_VAL_L, 0x09),
 381        QMP_PHY_INIT_CFG_L(QPHY_FLL_CNT_VAL_H_TOL, 0x42),
 382        QMP_PHY_INIT_CFG_L(QPHY_FLL_MAN_CODE, 0x85),
 383
 384        /* Lock Det settings */
 385        QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG1, 0xd1),
 386        QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG2, 0x1f),
 387        QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG3, 0x47),
 388        QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG2, 0x08),
 389};
 390
 391static const struct qmp_phy_init_tbl ipq8074_pcie_serdes_tbl[] = {
 392        QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x18),
 393        QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
 394        QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0xf),
 395        QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x1),
 396        QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x0),
 397        QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0x1f),
 398        QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
 399        QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x6),
 400        QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0xf),
 401        QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x0),
 402        QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x1),
 403        QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x20),
 404        QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0xa),
 405        QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
 406        QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0xa),
 407        QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xa),
 408        QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
 409        QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x3),
 410        QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
 411        QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
 412        QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x0),
 413        QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0xD),
 414        QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xD04),
 415        QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
 416        QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x2),
 417        QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1f),
 418        QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0xb),
 419        QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
 420        QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
 421        QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x0),
 422        QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
 423        QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x1),
 424        QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0xa),
 425        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x1),
 426        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
 427        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x1),
 428        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x2),
 429        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x0),
 430        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0x2f),
 431        QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x19),
 432        QMP_PHY_INIT_CFG(QSERDES_COM_CLK_EP_DIV, 0x19),
 433        QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x7),
 434};
 435
 436static const struct qmp_phy_init_tbl ipq8074_pcie_tx_tbl[] = {
 437        QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
 438        QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x6),
 439        QMP_PHY_INIT_CFG(QSERDES_TX_RES_CODE_LANE_OFFSET, 0x2),
 440        QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2, 0x12),
 441};
 442
 443static const struct qmp_phy_init_tbl ipq8074_pcie_rx_tbl[] = {
 444        QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x1c),
 445        QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
 446        QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x1),
 447        QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x0),
 448        QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xdb),
 449        QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
 450        QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x4),
 451        QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN_HALF, 0x4),
 452};
 453
 454static const struct qmp_phy_init_tbl ipq8074_pcie_pcs_tbl[] = {
 455        QMP_PHY_INIT_CFG(QPHY_ENDPOINT_REFCLK_DRIVE, 0x4),
 456        QMP_PHY_INIT_CFG(QPHY_OSC_DTCT_ACTIONS, 0x0),
 457        QMP_PHY_INIT_CFG(QPHY_PWRUP_RESET_DLY_TIME_AUXCLK, 0x40),
 458        QMP_PHY_INIT_CFG(QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x0),
 459        QMP_PHY_INIT_CFG(QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB, 0x40),
 460        QMP_PHY_INIT_CFG(QPHY_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB, 0x0),
 461        QMP_PHY_INIT_CFG(QPHY_LP_WAKEUP_DLY_TIME_AUXCLK, 0x40),
 462        QMP_PHY_INIT_CFG_L(QPHY_PLL_LOCK_CHK_DLY_TIME, 0x73),
 463        QMP_PHY_INIT_CFG(QPHY_RX_SIGDET_LVL, 0x99),
 464        QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M6DB_V0, 0x15),
 465        QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M3P5DB_V0, 0xe),
 466        QMP_PHY_INIT_CFG_L(QPHY_SW_RESET, 0x0),
 467        QMP_PHY_INIT_CFG_L(QPHY_START_CTRL, 0x3),
 468};
 469
 470/* struct qmp_phy_cfg - per-PHY initialization config */
 471struct qmp_phy_cfg {
 472        /* phy-type - PCIE/UFS/USB */
 473        unsigned int type;
 474        /* number of lanes provided by phy */
 475        int nlanes;
 476
 477        /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
 478        const struct qmp_phy_init_tbl *serdes_tbl;
 479        int serdes_tbl_num;
 480        const struct qmp_phy_init_tbl *tx_tbl;
 481        int tx_tbl_num;
 482        const struct qmp_phy_init_tbl *rx_tbl;
 483        int rx_tbl_num;
 484        const struct qmp_phy_init_tbl *pcs_tbl;
 485        int pcs_tbl_num;
 486
 487        /* clock ids to be requested */
 488        const char * const *clk_list;
 489        int num_clks;
 490        /* resets to be requested */
 491        const char * const *reset_list;
 492        int num_resets;
 493        /* regulators to be requested */
 494        const char * const *vreg_list;
 495        int num_vregs;
 496
 497        /* array of registers with different offsets */
 498        const unsigned int *regs;
 499
 500        unsigned int start_ctrl;
 501        unsigned int pwrdn_ctrl;
 502        unsigned int mask_pcs_ready;
 503        unsigned int mask_com_pcs_ready;
 504
 505        /* true, if PHY has a separate PHY_COM control block */
 506        bool has_phy_com_ctrl;
 507        /* true, if PHY has a reset for individual lanes */
 508        bool has_lane_rst;
 509        /* true, if PHY needs delay after POWER_DOWN */
 510        bool has_pwrdn_delay;
 511        /* power_down delay in usec */
 512        int pwrdn_delay_min;
 513        int pwrdn_delay_max;
 514};
 515
 516/**
 517 * struct qmp_phy - per-lane phy descriptor
 518 *
 519 * @phy: generic phy
 520 * @tx: iomapped memory space for lane's tx
 521 * @rx: iomapped memory space for lane's rx
 522 * @pcs: iomapped memory space for lane's pcs
 523 * @pipe_clk: pipe lock
 524 * @index: lane index
 525 * @qmp: QMP phy to which this lane belongs
 526 * @lane_rst: lane's reset controller
 527 */
 528struct qmp_phy {
 529        struct phy *phy;
 530        void __iomem *tx;
 531        void __iomem *rx;
 532        void __iomem *pcs;
 533        struct clk *pipe_clk;
 534        unsigned int index;
 535        struct qcom_qmp *qmp;
 536        struct reset_control *lane_rst;
 537};
 538
 539/**
 540 * struct qcom_qmp - structure holding QMP phy block attributes
 541 *
 542 * @dev: device
 543 * @serdes: iomapped memory space for phy's serdes
 544 *
 545 * @clks: array of clocks required by phy
 546 * @resets: array of resets required by phy
 547 * @vregs: regulator supplies bulk data
 548 *
 549 * @cfg: phy specific configuration
 550 * @phys: array of per-lane phy descriptors
 551 * @phy_mutex: mutex lock for PHY common block initialization
 552 * @init_count: phy common block initialization count
 553 */
 554struct qcom_qmp {
 555        struct device *dev;
 556        void __iomem *serdes;
 557
 558        struct clk **clks;
 559        struct reset_control **resets;
 560        struct regulator_bulk_data *vregs;
 561
 562        const struct qmp_phy_cfg *cfg;
 563        struct qmp_phy **phys;
 564
 565        struct mutex phy_mutex;
 566        int init_count;
 567};
 568
 569static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
 570{
 571        u32 reg;
 572
 573        reg = readl(base + offset);
 574        reg |= val;
 575        writel(reg, base + offset);
 576
 577        /* ensure that above write is through */
 578        readl(base + offset);
 579}
 580
 581static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
 582{
 583        u32 reg;
 584
 585        reg = readl(base + offset);
 586        reg &= ~val;
 587        writel(reg, base + offset);
 588
 589        /* ensure that above write is through */
 590        readl(base + offset);
 591}
 592
 593/* list of clocks required by phy */
 594static const char * const msm8996_phy_clk_l[] = {
 595        "aux", "cfg_ahb", "ref",
 596};
 597
 598/* list of resets */
 599static const char * const msm8996_pciephy_reset_l[] = {
 600        "phy", "common", "cfg",
 601};
 602
 603static const char * const msm8996_usb3phy_reset_l[] = {
 604        "phy", "common",
 605};
 606
 607/* list of regulators */
 608static const char * const msm8996_phy_vreg_l[] = {
 609        "vdda-phy", "vdda-pll",
 610};
 611
 612static const struct qmp_phy_cfg msm8996_pciephy_cfg = {
 613        .type                   = PHY_TYPE_PCIE,
 614        .nlanes                 = 3,
 615
 616        .serdes_tbl             = msm8996_pcie_serdes_tbl,
 617        .serdes_tbl_num         = ARRAY_SIZE(msm8996_pcie_serdes_tbl),
 618        .tx_tbl                 = msm8996_pcie_tx_tbl,
 619        .tx_tbl_num             = ARRAY_SIZE(msm8996_pcie_tx_tbl),
 620        .rx_tbl                 = msm8996_pcie_rx_tbl,
 621        .rx_tbl_num             = ARRAY_SIZE(msm8996_pcie_rx_tbl),
 622        .pcs_tbl                = msm8996_pcie_pcs_tbl,
 623        .pcs_tbl_num            = ARRAY_SIZE(msm8996_pcie_pcs_tbl),
 624        .clk_list               = msm8996_phy_clk_l,
 625        .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
 626        .reset_list             = msm8996_pciephy_reset_l,
 627        .num_resets             = ARRAY_SIZE(msm8996_pciephy_reset_l),
 628        .vreg_list              = msm8996_phy_vreg_l,
 629        .num_vregs              = ARRAY_SIZE(msm8996_phy_vreg_l),
 630        .regs                   = pciephy_regs_layout,
 631
 632        .start_ctrl             = PCS_START | PLL_READY_GATE_EN,
 633        .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
 634        .mask_com_pcs_ready     = PCS_READY,
 635
 636        .has_phy_com_ctrl       = true,
 637        .has_lane_rst           = true,
 638        .has_pwrdn_delay        = true,
 639        .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
 640        .pwrdn_delay_max        = POWER_DOWN_DELAY_US_MAX,
 641};
 642
 643static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
 644        .type                   = PHY_TYPE_USB3,
 645        .nlanes                 = 1,
 646
 647        .serdes_tbl             = msm8996_usb3_serdes_tbl,
 648        .serdes_tbl_num         = ARRAY_SIZE(msm8996_usb3_serdes_tbl),
 649        .tx_tbl                 = msm8996_usb3_tx_tbl,
 650        .tx_tbl_num             = ARRAY_SIZE(msm8996_usb3_tx_tbl),
 651        .rx_tbl                 = msm8996_usb3_rx_tbl,
 652        .rx_tbl_num             = ARRAY_SIZE(msm8996_usb3_rx_tbl),
 653        .pcs_tbl                = msm8996_usb3_pcs_tbl,
 654        .pcs_tbl_num            = ARRAY_SIZE(msm8996_usb3_pcs_tbl),
 655        .clk_list               = msm8996_phy_clk_l,
 656        .num_clks               = ARRAY_SIZE(msm8996_phy_clk_l),
 657        .reset_list             = msm8996_usb3phy_reset_l,
 658        .num_resets             = ARRAY_SIZE(msm8996_usb3phy_reset_l),
 659        .vreg_list              = msm8996_phy_vreg_l,
 660        .num_vregs              = ARRAY_SIZE(msm8996_phy_vreg_l),
 661        .regs                   = usb3phy_regs_layout,
 662
 663        .start_ctrl             = SERDES_START | PCS_START,
 664        .pwrdn_ctrl             = SW_PWRDN,
 665        .mask_pcs_ready         = PHYSTATUS,
 666};
 667
 668/* list of resets */
 669static const char * const ipq8074_pciephy_reset_l[] = {
 670        "phy", "common",
 671};
 672
 673static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
 674        .type                   = PHY_TYPE_PCIE,
 675        .nlanes                 = 1,
 676
 677        .serdes_tbl             = ipq8074_pcie_serdes_tbl,
 678        .serdes_tbl_num         = ARRAY_SIZE(ipq8074_pcie_serdes_tbl),
 679        .tx_tbl                 = ipq8074_pcie_tx_tbl,
 680        .tx_tbl_num             = ARRAY_SIZE(ipq8074_pcie_tx_tbl),
 681        .rx_tbl                 = ipq8074_pcie_rx_tbl,
 682        .rx_tbl_num             = ARRAY_SIZE(ipq8074_pcie_rx_tbl),
 683        .pcs_tbl                = ipq8074_pcie_pcs_tbl,
 684        .pcs_tbl_num            = ARRAY_SIZE(ipq8074_pcie_pcs_tbl),
 685        .clk_list               = NULL,
 686        .num_clks               = 0,
 687        .reset_list             = ipq8074_pciephy_reset_l,
 688        .num_resets             = ARRAY_SIZE(ipq8074_pciephy_reset_l),
 689        .vreg_list              = NULL,
 690        .num_vregs              = 0,
 691        .regs                   = pciephy_regs_layout,
 692
 693        .start_ctrl             = SERDES_START | PCS_START,
 694        .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
 695        .mask_pcs_ready         = PHYSTATUS,
 696
 697        .has_phy_com_ctrl       = false,
 698        .has_lane_rst           = false,
 699        .has_pwrdn_delay        = true,
 700        .pwrdn_delay_min        = 995,          /* us */
 701        .pwrdn_delay_max        = 1005,         /* us */
 702};
 703
 704static void qcom_qmp_phy_configure(void __iomem *base,
 705                                   const unsigned int *regs,
 706                                   const struct qmp_phy_init_tbl tbl[],
 707                                   int num)
 708{
 709        int i;
 710        const struct qmp_phy_init_tbl *t = tbl;
 711
 712        if (!t)
 713                return;
 714
 715        for (i = 0; i < num; i++, t++) {
 716                if (t->in_layout)
 717                        writel(t->val, base + regs[t->offset]);
 718                else
 719                        writel(t->val, base + t->offset);
 720        }
 721}
 722
 723static int qcom_qmp_phy_poweron(struct phy *phy)
 724{
 725        struct qmp_phy *qphy = phy_get_drvdata(phy);
 726        struct qcom_qmp *qmp = qphy->qmp;
 727        int num = qmp->cfg->num_vregs;
 728        int ret;
 729
 730        dev_vdbg(&phy->dev, "Powering on QMP phy\n");
 731
 732        /* turn on regulator supplies */
 733        ret = regulator_bulk_enable(num, qmp->vregs);
 734        if (ret) {
 735                dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
 736                return ret;
 737        }
 738
 739        ret = clk_prepare_enable(qphy->pipe_clk);
 740        if (ret) {
 741                dev_err(qmp->dev, "pipe_clk enable failed, err=%d\n", ret);
 742                regulator_bulk_disable(num, qmp->vregs);
 743                return ret;
 744        }
 745
 746        return 0;
 747}
 748
 749static int qcom_qmp_phy_poweroff(struct phy *phy)
 750{
 751        struct qmp_phy *qphy = phy_get_drvdata(phy);
 752        struct qcom_qmp *qmp = qphy->qmp;
 753
 754        clk_disable_unprepare(qphy->pipe_clk);
 755
 756        regulator_bulk_disable(qmp->cfg->num_vregs, qmp->vregs);
 757
 758        return 0;
 759}
 760
 761static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
 762{
 763        const struct qmp_phy_cfg *cfg = qmp->cfg;
 764        void __iomem *serdes = qmp->serdes;
 765        int ret, i;
 766
 767        mutex_lock(&qmp->phy_mutex);
 768        if (qmp->init_count++) {
 769                mutex_unlock(&qmp->phy_mutex);
 770                return 0;
 771        }
 772
 773        for (i = 0; i < cfg->num_resets; i++) {
 774                ret = reset_control_deassert(qmp->resets[i]);
 775                if (ret) {
 776                        dev_err(qmp->dev, "%s reset deassert failed\n",
 777                                qmp->cfg->reset_list[i]);
 778                        goto err_rst;
 779                }
 780        }
 781
 782        if (cfg->has_phy_com_ctrl)
 783                qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
 784                             SW_PWRDN);
 785
 786        /* Serdes configuration */
 787        qcom_qmp_phy_configure(serdes, cfg->regs, cfg->serdes_tbl,
 788                               cfg->serdes_tbl_num);
 789
 790        if (cfg->has_phy_com_ctrl) {
 791                void __iomem *status;
 792                unsigned int mask, val;
 793
 794                qphy_clrbits(serdes, cfg->regs[QPHY_COM_SW_RESET], SW_RESET);
 795                qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL],
 796                             SERDES_START | PCS_START);
 797
 798                status = serdes + cfg->regs[QPHY_COM_PCS_READY_STATUS];
 799                mask = cfg->mask_com_pcs_ready;
 800
 801                ret = readl_poll_timeout(status, val, (val & mask), 10,
 802                                         PHY_INIT_COMPLETE_TIMEOUT);
 803                if (ret) {
 804                        dev_err(qmp->dev,
 805                                "phy common block init timed-out\n");
 806                        goto err_rst;
 807                }
 808        }
 809
 810        mutex_unlock(&qmp->phy_mutex);
 811
 812        return 0;
 813
 814err_rst:
 815        while (--i >= 0)
 816                reset_control_assert(qmp->resets[i]);
 817        mutex_unlock(&qmp->phy_mutex);
 818
 819        return ret;
 820}
 821
 822static int qcom_qmp_phy_com_exit(struct qcom_qmp *qmp)
 823{
 824        const struct qmp_phy_cfg *cfg = qmp->cfg;
 825        void __iomem *serdes = qmp->serdes;
 826        int i = cfg->num_resets;
 827
 828        mutex_lock(&qmp->phy_mutex);
 829        if (--qmp->init_count) {
 830                mutex_unlock(&qmp->phy_mutex);
 831                return 0;
 832        }
 833
 834        if (cfg->has_phy_com_ctrl) {
 835                qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL],
 836                             SERDES_START | PCS_START);
 837                qphy_clrbits(serdes, cfg->regs[QPHY_COM_SW_RESET],
 838                             SW_RESET);
 839                qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
 840                             SW_PWRDN);
 841        }
 842
 843        while (--i >= 0)
 844                reset_control_assert(qmp->resets[i]);
 845
 846        mutex_unlock(&qmp->phy_mutex);
 847
 848        return 0;
 849}
 850
 851/* PHY Initialization */
 852static int qcom_qmp_phy_init(struct phy *phy)
 853{
 854        struct qmp_phy *qphy = phy_get_drvdata(phy);
 855        struct qcom_qmp *qmp = qphy->qmp;
 856        const struct qmp_phy_cfg *cfg = qmp->cfg;
 857        void __iomem *tx = qphy->tx;
 858        void __iomem *rx = qphy->rx;
 859        void __iomem *pcs = qphy->pcs;
 860        void __iomem *status;
 861        unsigned int mask, val;
 862        int ret, i;
 863
 864        dev_vdbg(qmp->dev, "Initializing QMP phy\n");
 865
 866        for (i = 0; i < qmp->cfg->num_clks; i++) {
 867                ret = clk_prepare_enable(qmp->clks[i]);
 868                if (ret) {
 869                        dev_err(qmp->dev, "failed to enable %s clk, err=%d\n",
 870                                qmp->cfg->clk_list[i], ret);
 871                        goto err_clk;
 872                }
 873        }
 874
 875        ret = qcom_qmp_phy_com_init(qmp);
 876        if (ret)
 877                goto err_clk;
 878
 879        if (cfg->has_lane_rst) {
 880                ret = reset_control_deassert(qphy->lane_rst);
 881                if (ret) {
 882                        dev_err(qmp->dev, "lane%d reset deassert failed\n",
 883                                qphy->index);
 884                        goto err_lane_rst;
 885                }
 886        }
 887
 888        /* Tx, Rx, and PCS configurations */
 889        qcom_qmp_phy_configure(tx, cfg->regs, cfg->tx_tbl, cfg->tx_tbl_num);
 890        qcom_qmp_phy_configure(rx, cfg->regs, cfg->rx_tbl, cfg->rx_tbl_num);
 891        qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num);
 892
 893        /*
 894         * Pull out PHY from POWER DOWN state.
 895         * This is active low enable signal to power-down PHY.
 896         */
 897        qphy_setbits(pcs, QPHY_POWER_DOWN_CONTROL, cfg->pwrdn_ctrl);
 898
 899        if (cfg->has_pwrdn_delay)
 900                usleep_range(cfg->pwrdn_delay_min, cfg->pwrdn_delay_max);
 901
 902        /* start SerDes and Phy-Coding-Sublayer */
 903        qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
 904
 905        /* Pull PHY out of reset state */
 906        qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
 907
 908        status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
 909        mask = cfg->mask_pcs_ready;
 910
 911        ret = readl_poll_timeout(status, val, !(val & mask), 1,
 912                                 PHY_INIT_COMPLETE_TIMEOUT);
 913        if (ret) {
 914                dev_err(qmp->dev, "phy initialization timed-out\n");
 915                goto err_pcs_ready;
 916        }
 917
 918        return ret;
 919
 920err_pcs_ready:
 921        if (cfg->has_lane_rst)
 922                reset_control_assert(qphy->lane_rst);
 923err_lane_rst:
 924        qcom_qmp_phy_com_exit(qmp);
 925err_clk:
 926        while (--i >= 0)
 927                clk_disable_unprepare(qmp->clks[i]);
 928
 929        return ret;
 930}
 931
 932static int qcom_qmp_phy_exit(struct phy *phy)
 933{
 934        struct qmp_phy *qphy = phy_get_drvdata(phy);
 935        struct qcom_qmp *qmp = qphy->qmp;
 936        const struct qmp_phy_cfg *cfg = qmp->cfg;
 937        int i = cfg->num_clks;
 938
 939        /* PHY reset */
 940        qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
 941
 942        /* stop SerDes and Phy-Coding-Sublayer */
 943        qphy_clrbits(qphy->pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
 944
 945        /* Put PHY into POWER DOWN state: active low */
 946        qphy_clrbits(qphy->pcs, QPHY_POWER_DOWN_CONTROL, cfg->pwrdn_ctrl);
 947
 948        if (cfg->has_lane_rst)
 949                reset_control_assert(qphy->lane_rst);
 950
 951        qcom_qmp_phy_com_exit(qmp);
 952
 953        while (--i >= 0)
 954                clk_disable_unprepare(qmp->clks[i]);
 955
 956        return 0;
 957}
 958
 959static int qcom_qmp_phy_vreg_init(struct device *dev)
 960{
 961        struct qcom_qmp *qmp = dev_get_drvdata(dev);
 962        int num = qmp->cfg->num_vregs;
 963        int i;
 964
 965        qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
 966        if (!qmp->vregs)
 967                return -ENOMEM;
 968
 969        for (i = 0; i < num; i++)
 970                qmp->vregs[i].supply = qmp->cfg->vreg_list[i];
 971
 972        return devm_regulator_bulk_get(dev, num, qmp->vregs);
 973}
 974
 975static int qcom_qmp_phy_reset_init(struct device *dev)
 976{
 977        struct qcom_qmp *qmp = dev_get_drvdata(dev);
 978        int i;
 979
 980        qmp->resets = devm_kcalloc(dev, qmp->cfg->num_resets,
 981                                   sizeof(*qmp->resets), GFP_KERNEL);
 982        if (!qmp->resets)
 983                return -ENOMEM;
 984
 985        for (i = 0; i < qmp->cfg->num_resets; i++) {
 986                struct reset_control *rst;
 987                const char *name = qmp->cfg->reset_list[i];
 988
 989                rst = devm_reset_control_get(dev, name);
 990                if (IS_ERR(rst)) {
 991                        dev_err(dev, "failed to get %s reset\n", name);
 992                        return PTR_ERR(rst);
 993                }
 994                qmp->resets[i] = rst;
 995        }
 996
 997        return 0;
 998}
 999
1000static int qcom_qmp_phy_clk_init(struct device *dev)
1001{
1002        struct qcom_qmp *qmp = dev_get_drvdata(dev);
1003        int ret, i;
1004
1005        qmp->clks = devm_kcalloc(dev, qmp->cfg->num_clks,
1006                                 sizeof(*qmp->clks), GFP_KERNEL);
1007        if (!qmp->clks)
1008                return -ENOMEM;
1009
1010        for (i = 0; i < qmp->cfg->num_clks; i++) {
1011                struct clk *_clk;
1012                const char *name = qmp->cfg->clk_list[i];
1013
1014                _clk = devm_clk_get(dev, name);
1015                if (IS_ERR(_clk)) {
1016                        ret = PTR_ERR(_clk);
1017                        if (ret != -EPROBE_DEFER)
1018                                dev_err(dev, "failed to get %s clk, %d\n",
1019                                        name, ret);
1020                        return ret;
1021                }
1022                qmp->clks[i] = _clk;
1023        }
1024
1025        return 0;
1026}
1027
1028/*
1029 * Register a fixed rate pipe clock.
1030 *
1031 * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
1032 * controls it. The <s>_pipe_clk coming out of the GCC is requested
1033 * by the PHY driver for its operations.
1034 * We register the <s>_pipe_clksrc here. The gcc driver takes care
1035 * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
1036 * Below picture shows this relationship.
1037 *
1038 *         +---------------+
1039 *         |   PHY block   |<<---------------------------------------+
1040 *         |               |                                         |
1041 *         |   +-------+   |                   +-----+               |
1042 *   I/P---^-->|  PLL  |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
1043 *    clk  |   +-------+   |                   +-----+
1044 *         +---------------+
1045 */
1046static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np)
1047{
1048        struct clk_fixed_rate *fixed;
1049        struct clk_init_data init = { };
1050        int ret;
1051
1052        if ((qmp->cfg->type != PHY_TYPE_USB3) &&
1053            (qmp->cfg->type != PHY_TYPE_PCIE)) {
1054                /* not all phys register pipe clocks, so return success */
1055                return 0;
1056        }
1057
1058        ret = of_property_read_string(np, "clock-output-names", &init.name);
1059        if (ret) {
1060                dev_err(qmp->dev, "%s: No clock-output-names\n", np->name);
1061                return ret;
1062        }
1063
1064        fixed = devm_kzalloc(qmp->dev, sizeof(*fixed), GFP_KERNEL);
1065        if (!fixed)
1066                return -ENOMEM;
1067
1068        init.ops = &clk_fixed_rate_ops;
1069
1070        /* controllers using QMP phys use 125MHz pipe clock interface */
1071        fixed->fixed_rate = 125000000;
1072        fixed->hw.init = &init;
1073
1074        return devm_clk_hw_register(qmp->dev, &fixed->hw);
1075}
1076
1077static const struct phy_ops qcom_qmp_phy_gen_ops = {
1078        .init           = qcom_qmp_phy_init,
1079        .exit           = qcom_qmp_phy_exit,
1080        .power_on       = qcom_qmp_phy_poweron,
1081        .power_off      = qcom_qmp_phy_poweroff,
1082        .owner          = THIS_MODULE,
1083};
1084
1085static
1086int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id)
1087{
1088        struct qcom_qmp *qmp = dev_get_drvdata(dev);
1089        struct phy *generic_phy;
1090        struct qmp_phy *qphy;
1091        char prop_name[MAX_PROP_NAME];
1092        int ret;
1093
1094        qphy = devm_kzalloc(dev, sizeof(*qphy), GFP_KERNEL);
1095        if (!qphy)
1096                return -ENOMEM;
1097
1098        /*
1099         * Get memory resources for each phy lane:
1100         * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
1101         */
1102        qphy->tx = of_iomap(np, 0);
1103        if (!qphy->tx)
1104                return -ENOMEM;
1105
1106        qphy->rx = of_iomap(np, 1);
1107        if (!qphy->rx)
1108                return -ENOMEM;
1109
1110        qphy->pcs = of_iomap(np, 2);
1111        if (!qphy->pcs)
1112                return -ENOMEM;
1113
1114        /*
1115         * Get PHY's Pipe clock, if any. USB3 and PCIe are PIPE3
1116         * based phys, so they essentially have pipe clock. So,
1117         * we return error in case phy is USB3 or PIPE type.
1118         * Otherwise, we initialize pipe clock to NULL for
1119         * all phys that don't need this.
1120         */
1121        snprintf(prop_name, sizeof(prop_name), "pipe%d", id);
1122        qphy->pipe_clk = of_clk_get_by_name(np, prop_name);
1123        if (IS_ERR(qphy->pipe_clk)) {
1124                if (qmp->cfg->type == PHY_TYPE_PCIE ||
1125                    qmp->cfg->type == PHY_TYPE_USB3) {
1126                        ret = PTR_ERR(qphy->pipe_clk);
1127                        if (ret != -EPROBE_DEFER)
1128                                dev_err(dev,
1129                                        "failed to get lane%d pipe_clk, %d\n",
1130                                        id, ret);
1131                        return ret;
1132                }
1133                qphy->pipe_clk = NULL;
1134        }
1135
1136        /* Get lane reset, if any */
1137        if (qmp->cfg->has_lane_rst) {
1138                snprintf(prop_name, sizeof(prop_name), "lane%d", id);
1139                qphy->lane_rst = of_reset_control_get(np, prop_name);
1140                if (IS_ERR(qphy->lane_rst)) {
1141                        dev_err(dev, "failed to get lane%d reset\n", id);
1142                        return PTR_ERR(qphy->lane_rst);
1143                }
1144        }
1145
1146        generic_phy = devm_phy_create(dev, np, &qcom_qmp_phy_gen_ops);
1147        if (IS_ERR(generic_phy)) {
1148                ret = PTR_ERR(generic_phy);
1149                dev_err(dev, "failed to create qphy %d\n", ret);
1150                return ret;
1151        }
1152
1153        qphy->phy = generic_phy;
1154        qphy->index = id;
1155        qphy->qmp = qmp;
1156        qmp->phys[id] = qphy;
1157        phy_set_drvdata(generic_phy, qphy);
1158
1159        return 0;
1160}
1161
1162static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
1163        {
1164                .compatible = "qcom,msm8996-qmp-pcie-phy",
1165                .data = &msm8996_pciephy_cfg,
1166        }, {
1167                .compatible = "qcom,msm8996-qmp-usb3-phy",
1168                .data = &msm8996_usb3phy_cfg,
1169        }, {
1170                .compatible = "qcom,ipq8074-qmp-pcie-phy",
1171                .data = &ipq8074_pciephy_cfg,
1172        },
1173        { },
1174};
1175MODULE_DEVICE_TABLE(of, qcom_qmp_phy_of_match_table);
1176
1177static int qcom_qmp_phy_probe(struct platform_device *pdev)
1178{
1179        struct qcom_qmp *qmp;
1180        struct device *dev = &pdev->dev;
1181        struct resource *res;
1182        struct device_node *child;
1183        struct phy_provider *phy_provider;
1184        void __iomem *base;
1185        int num, id;
1186        int ret;
1187
1188        qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
1189        if (!qmp)
1190                return -ENOMEM;
1191
1192        qmp->dev = dev;
1193        dev_set_drvdata(dev, qmp);
1194
1195        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1196        base = devm_ioremap_resource(dev, res);
1197        if (IS_ERR(base))
1198                return PTR_ERR(base);
1199
1200        /* per PHY serdes; usually located at base address */
1201        qmp->serdes = base;
1202
1203        mutex_init(&qmp->phy_mutex);
1204
1205        /* Get the specific init parameters of QMP phy */
1206        qmp->cfg = of_device_get_match_data(dev);
1207
1208        ret = qcom_qmp_phy_clk_init(dev);
1209        if (ret)
1210                return ret;
1211
1212        ret = qcom_qmp_phy_reset_init(dev);
1213        if (ret)
1214                return ret;
1215
1216        ret = qcom_qmp_phy_vreg_init(dev);
1217        if (ret) {
1218                dev_err(dev, "failed to get regulator supplies\n");
1219                return ret;
1220        }
1221
1222        num = of_get_available_child_count(dev->of_node);
1223        /* do we have a rogue child node ? */
1224        if (num > qmp->cfg->nlanes)
1225                return -EINVAL;
1226
1227        qmp->phys = devm_kcalloc(dev, num, sizeof(*qmp->phys), GFP_KERNEL);
1228        if (!qmp->phys)
1229                return -ENOMEM;
1230
1231        id = 0;
1232        for_each_available_child_of_node(dev->of_node, child) {
1233                /* Create per-lane phy */
1234                ret = qcom_qmp_phy_create(dev, child, id);
1235                if (ret) {
1236                        dev_err(dev, "failed to create lane%d phy, %d\n",
1237                                id, ret);
1238                        return ret;
1239                }
1240
1241                /*
1242                 * Register the pipe clock provided by phy.
1243                 * See function description to see details of this pipe clock.
1244                 */
1245                ret = phy_pipe_clk_register(qmp, child);
1246                if (ret) {
1247                        dev_err(qmp->dev,
1248                                "failed to register pipe clock source\n");
1249                        return ret;
1250                }
1251                id++;
1252        }
1253
1254        phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
1255        if (!IS_ERR(phy_provider))
1256                dev_info(dev, "Registered Qcom-QMP phy\n");
1257
1258        return PTR_ERR_OR_ZERO(phy_provider);
1259}
1260
1261static struct platform_driver qcom_qmp_phy_driver = {
1262        .probe          = qcom_qmp_phy_probe,
1263        .driver = {
1264                .name   = "qcom-qmp-phy",
1265                .of_match_table = qcom_qmp_phy_of_match_table,
1266        },
1267};
1268
1269module_platform_driver(qcom_qmp_phy_driver);
1270
1271MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
1272MODULE_DESCRIPTION("Qualcomm QMP PHY driver");
1273MODULE_LICENSE("GPL v2");
1274