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