mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-04 04:02:26 +00:00
4e92d50447
These register prints are useful to validate the init sequence against the Qcom internal documentation and also to share with the Qcom hw engineers to debug issues related to PHY. Sample debug prints: qcom-qmp-pcie-phy 1c0e000.phy: Writing Reg: QSERDES_V5_COM_SYSCLK_EN_SEL Offset: 0x0094 Val: 0xd9 qcom-qmp-pcie-phy 1c0e000.phy: Writing Reg: QSERDES_V5_COM_HSCLK_SEL Offset: 0x0158 Val: 0x11 Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Link: https://lore.kernel.org/r/20240731152548.102987-1-manivannan.sadhasivam@linaro.org Signed-off-by: Vinod Koul <vkoul@kernel.org>
2082 lines
73 KiB
C
2082 lines
73 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
|
*/
|
|
|
|
#include <linux/clk.h>
|
|
#include <linux/clk-provider.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/err.h>
|
|
#include <linux/io.h>
|
|
#include <linux/iopoll.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/of.h>
|
|
#include <linux/of_address.h>
|
|
#include <linux/phy/phy.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/regulator/consumer.h>
|
|
#include <linux/reset.h>
|
|
#include <linux/slab.h>
|
|
|
|
#include <ufs/unipro.h>
|
|
|
|
#include "phy-qcom-qmp-common.h"
|
|
|
|
#include "phy-qcom-qmp.h"
|
|
#include "phy-qcom-qmp-pcs-ufs-v2.h"
|
|
#include "phy-qcom-qmp-pcs-ufs-v3.h"
|
|
#include "phy-qcom-qmp-pcs-ufs-v4.h"
|
|
#include "phy-qcom-qmp-pcs-ufs-v5.h"
|
|
#include "phy-qcom-qmp-pcs-ufs-v6.h"
|
|
|
|
#include "phy-qcom-qmp-qserdes-txrx-ufs-v6.h"
|
|
|
|
/* QPHY_PCS_READY_STATUS bit */
|
|
#define PCS_READY BIT(0)
|
|
|
|
#define PHY_INIT_COMPLETE_TIMEOUT 10000
|
|
|
|
#define NUM_OVERLAY 2
|
|
|
|
/* set of registers with offsets different per-PHY */
|
|
enum qphy_reg_layout {
|
|
/* PCS registers */
|
|
QPHY_SW_RESET,
|
|
QPHY_START_CTRL,
|
|
QPHY_PCS_READY_STATUS,
|
|
QPHY_PCS_POWER_DOWN_CONTROL,
|
|
/* Keep last to ensure regs_layout arrays are properly initialized */
|
|
QPHY_LAYOUT_SIZE
|
|
};
|
|
|
|
static const unsigned int ufsphy_v2_regs_layout[QPHY_LAYOUT_SIZE] = {
|
|
[QPHY_START_CTRL] = QPHY_V2_PCS_UFS_PHY_START,
|
|
[QPHY_PCS_READY_STATUS] = QPHY_V2_PCS_UFS_READY_STATUS,
|
|
[QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V2_PCS_UFS_POWER_DOWN_CONTROL,
|
|
};
|
|
|
|
static const unsigned int ufsphy_v3_regs_layout[QPHY_LAYOUT_SIZE] = {
|
|
[QPHY_START_CTRL] = QPHY_V3_PCS_UFS_PHY_START,
|
|
[QPHY_PCS_READY_STATUS] = QPHY_V3_PCS_UFS_READY_STATUS,
|
|
[QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V3_PCS_UFS_POWER_DOWN_CONTROL,
|
|
};
|
|
|
|
static const unsigned int ufsphy_v4_regs_layout[QPHY_LAYOUT_SIZE] = {
|
|
[QPHY_START_CTRL] = QPHY_V4_PCS_UFS_PHY_START,
|
|
[QPHY_PCS_READY_STATUS] = QPHY_V4_PCS_UFS_READY_STATUS,
|
|
[QPHY_SW_RESET] = QPHY_V4_PCS_UFS_SW_RESET,
|
|
[QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V4_PCS_UFS_POWER_DOWN_CONTROL,
|
|
};
|
|
|
|
static const unsigned int ufsphy_v5_regs_layout[QPHY_LAYOUT_SIZE] = {
|
|
[QPHY_START_CTRL] = QPHY_V5_PCS_UFS_PHY_START,
|
|
[QPHY_PCS_READY_STATUS] = QPHY_V5_PCS_UFS_READY_STATUS,
|
|
[QPHY_SW_RESET] = QPHY_V5_PCS_UFS_SW_RESET,
|
|
[QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V5_PCS_UFS_POWER_DOWN_CONTROL,
|
|
};
|
|
|
|
static const unsigned int ufsphy_v6_regs_layout[QPHY_LAYOUT_SIZE] = {
|
|
[QPHY_START_CTRL] = QPHY_V6_PCS_UFS_PHY_START,
|
|
[QPHY_PCS_READY_STATUS] = QPHY_V6_PCS_UFS_READY_STATUS,
|
|
[QPHY_SW_RESET] = QPHY_V6_PCS_UFS_SW_RESET,
|
|
[QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V6_PCS_UFS_POWER_DOWN_CONTROL,
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl msm8996_ufsphy_serdes[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xd7),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x05),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x10),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x54),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl msm8996_ufsphy_tx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
|
|
QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x02),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl msm8996_ufsphy_rx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x02),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x18),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5b),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xff),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3f),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xff),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x0f),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0E),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sc7280_ufsphy_tx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x35),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sc7280_ufsphy_rx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x80),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0e),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x1b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x10),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x6d),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x6d),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xed),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x3b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3c),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe0),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xc8),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sc7280_ufsphy_pcs[] = {
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_PLL_CNTL, 0x03),
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TIMER_20US_CORECLK_STEPS_MSB, 0x16),
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TIMER_20US_CORECLK_STEPS_LSB, 0xd8),
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_PWM_GEAR_BAND, 0xaa),
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_HS_GEAR_BAND, 0x06),
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x03),
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x03),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sc7280_ufsphy_hs_g4_rx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x81),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0e),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x6f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x09),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x07),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x20),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0x80),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x01),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x2c),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x6d),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0x6d),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xed),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x3c),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x0f),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm6115_ufsphy_serdes[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL1, 0xff),
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL2, 0x00),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm6115_ufsphy_hs_b_serdes[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x44),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm6115_ufsphy_tx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
|
|
QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm6115_ufsphy_rx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x0F),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x40),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5B),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xFF),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3F),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xFF),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x3F),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0D),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5B),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm6115_ufsphy_pcs[] = {
|
|
QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_PWM_GEAR_BAND, 0x15),
|
|
QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
|
|
QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
|
|
QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
|
|
QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28),
|
|
QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_SYM_RESYNC_CTRL, 0x03),
|
|
QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_LARGE_AMP_POST_EMP_LVL, 0x12),
|
|
QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_SMALL_AMP_POST_EMP_LVL, 0x0f),
|
|
QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0xd5),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x05),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL1, 0xff),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL2, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xda),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0xff),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0c),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE1, 0x98),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE1, 0x06),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE1, 0x16),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE1, 0x36),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE1, 0xc1),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE1, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE1, 0x32),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE1, 0x0f),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sdm845_ufsphy_hs_b_serdes[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x44),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sdm845_ufsphy_tx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sdm845_ufsphy_rx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_TERM_BW, 0x5b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x81),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sdm845_ufsphy_pcs[] = {
|
|
QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL2, 0x6e),
|
|
QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
|
|
QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
|
|
QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SYM_RESYNC_CTRL, 0x03),
|
|
QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
|
|
QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL1, 0x0f),
|
|
QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_MIN_HIBERN8_TIME, 0x9a),
|
|
QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm7150_ufsphy_rx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_TERM_BW, 0x5b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x81),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
|
|
QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm7150_ufsphy_pcs[] = {
|
|
QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL2, 0x6f),
|
|
QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
|
|
QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
|
|
QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SYM_RESYNC_CTRL, 0x03),
|
|
QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
|
|
QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL1, 0x0f),
|
|
QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
|
|
QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8150_ufsphy_serdes[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0xd9),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x11),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x01),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_INITVAL2, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xff),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0c),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x98),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x32),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x0f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8150_ufsphy_hs_b_serdes[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x06),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8150_ufsphy_tx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x05),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8150_ufsphy_hs_g4_tx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x75),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8150_ufsphy_rx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x80),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x1b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x10),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x36),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x36),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xf6),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x3b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3d),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe0),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xc8),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8150_ufsphy_hs_g4_rx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x81),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0e),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x6f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x20),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0x80),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x01),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x6c),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x6d),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0x6d),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xed),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x3c),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8150_ufsphy_pcs[] = {
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8150_ufsphy_hs_g4_pcs[] = {
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x10),
|
|
QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_BIST_FIXED_PAT_CTRL, 0x0a),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8250_ufsphy_hs_g4_tx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xe5),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8250_ufsphy_hs_g4_rx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x81),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0e),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x6f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x09),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x07),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x20),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0x80),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x01),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x2c),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x6d),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0x6d),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xed),
|
|
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x3c),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8350_ufsphy_serdes[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0xd9),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x11),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x42),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_INITVAL2, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x14),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x18),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x18),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0xff),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x19),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0x98),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x14),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x18),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x18),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x65),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x1e),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8350_ufsphy_hs_b_serdes[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x06),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8350_ufsphy_tx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xf5),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x09),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_TX_TRAN_DRVR_EMP_EN, 0x0c),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8350_ufsphy_rx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_LVL, 0x24),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x0f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_BAND, 0x18),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf1),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CTRL2, 0x80),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0e),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_TERM_BW, 0x1b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_MEASURE_TIME, 0x10),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x6d),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x6d),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xed),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0x3c),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xe0),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xc8),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xc8),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x3b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xb7),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_LOW, 0xe0),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH, 0xc8),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH2, 0xc8),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x3b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH4, 0xb7),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1, 0x0c),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8350_ufsphy_pcs[] = {
|
|
QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
|
|
QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
|
|
QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
|
|
QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
|
|
QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
|
|
QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
|
|
QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL1, 0x0e),
|
|
QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8350_ufsphy_g4_tx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xe5),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8350_ufsphy_g4_rx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CTRL2, 0x81),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_TERM_BW, 0x6f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_MEASURE_TIME, 0x20),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0x80),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x01),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0xbf),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0xbf),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0x7f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x7f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0x2d),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x6d),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x6d),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xed),
|
|
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0x3c),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8350_ufsphy_g4_pcs[] = {
|
|
QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_BIST_FIXED_PAT_CTRL, 0x0a),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8475_ufsphy_serdes[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x82),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x18),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0xff),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x0c),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8475_ufsphy_g4_serdes[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x14),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x98),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x14),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x18),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x32),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x0f),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8475_ufsphy_g4_pcs[] = {
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x0b),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_serdes[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x1f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IETRIM, 0x1b),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x1c),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8550_ufsphy_tx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x05),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_tx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_FR_DCC_CTRL, 0x4c),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c),
|
|
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xc2),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xc2),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3, 0x1a),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B6, 0x60),
|
|
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B3, 0x9e),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B6, 0x60),
|
|
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B3, 0x9e),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B4, 0x0e),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B5, 0x36),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_rx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_rx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4, 0x0c),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x14),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS, 0x07),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3, 0x0e),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4, 0x02),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x1c),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4, 0x06),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x08),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B3, 0xb9),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B4, 0x4f),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B6, 0xff),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL, 0x30),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8550_ufsphy_pcs[] = {
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x69),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_pcs[] = {
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_pcs[] = {
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4f),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME, 0x9e),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8650_ufsphy_serdes[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x1f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO_MODE1, 0x1f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IETRIM, 0x0a),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x17),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x06),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
|
|
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8650_ufsphy_tx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x01),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8650_ufsphy_rx[] = {
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4, 0x0c),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4, 0x04),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x14),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS, 0x07),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3, 0x0e),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4, 0x02),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x1c),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4, 0x06),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x3e),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0f),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xce),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xce),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B2, 0x18),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3, 0x1a),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B4, 0x0f),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B6, 0x60),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B3, 0x9e),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B6, 0x60),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B3, 0x9e),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B4, 0x0e),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B5, 0x36),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B0, 0x24),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B1, 0x24),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B2, 0x20),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B3, 0xb9),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B4, 0x4f),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_SATURATION, 0x1f),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CTRL1, 0x94),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_RX_TERM_BW_CTRL0, 0xfa),
|
|
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL, 0x30),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8650_ufsphy_pcs[] = {
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PCS_CTRL1, 0xc1),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x68),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S4, 0x0e),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S5, 0x12),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S6, 0x15),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S7, 0x19),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8650_ufsphy_g4_pcs[] = {
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x13),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
|
|
};
|
|
|
|
static const struct qmp_phy_init_tbl sm8650_ufsphy_g5_pcs[] = {
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x05),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x05),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4d),
|
|
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME, 0x9e),
|
|
};
|
|
|
|
struct qmp_ufs_offsets {
|
|
u16 serdes;
|
|
u16 pcs;
|
|
u16 tx;
|
|
u16 rx;
|
|
u16 tx2;
|
|
u16 rx2;
|
|
};
|
|
|
|
struct qmp_phy_cfg_tbls {
|
|
/* Init sequence for PHY blocks - serdes, tx, rx, pcs */
|
|
const struct qmp_phy_init_tbl *serdes;
|
|
int serdes_num;
|
|
const struct qmp_phy_init_tbl *tx;
|
|
int tx_num;
|
|
const struct qmp_phy_init_tbl *rx;
|
|
int rx_num;
|
|
const struct qmp_phy_init_tbl *pcs;
|
|
int pcs_num;
|
|
/* Maximum supported Gear of this tbls */
|
|
u32 max_gear;
|
|
};
|
|
|
|
/* struct qmp_phy_cfg - per-PHY initialization config */
|
|
struct qmp_phy_cfg {
|
|
int lanes;
|
|
|
|
const struct qmp_ufs_offsets *offsets;
|
|
/* Maximum supported Gear of this config */
|
|
u32 max_supported_gear;
|
|
|
|
/* Main init sequence for PHY blocks - serdes, tx, rx, pcs */
|
|
const struct qmp_phy_cfg_tbls tbls;
|
|
/* Additional sequence for HS Series B */
|
|
const struct qmp_phy_cfg_tbls tbls_hs_b;
|
|
/* Additional sequence for different HS Gears */
|
|
const struct qmp_phy_cfg_tbls tbls_hs_overlay[NUM_OVERLAY];
|
|
|
|
/* regulators to be requested */
|
|
const char * const *vreg_list;
|
|
int num_vregs;
|
|
|
|
/* array of registers with different offsets */
|
|
const unsigned int *regs;
|
|
|
|
/* true, if PCS block has no separate SW_RESET register */
|
|
bool no_pcs_sw_reset;
|
|
};
|
|
|
|
struct qmp_ufs {
|
|
struct device *dev;
|
|
|
|
const struct qmp_phy_cfg *cfg;
|
|
|
|
void __iomem *serdes;
|
|
void __iomem *pcs;
|
|
void __iomem *pcs_misc;
|
|
void __iomem *tx;
|
|
void __iomem *rx;
|
|
void __iomem *tx2;
|
|
void __iomem *rx2;
|
|
|
|
struct clk_bulk_data *clks;
|
|
int num_clks;
|
|
struct regulator_bulk_data *vregs;
|
|
struct reset_control *ufs_reset;
|
|
|
|
struct phy *phy;
|
|
u32 mode;
|
|
u32 submode;
|
|
};
|
|
|
|
static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
|
|
{
|
|
u32 reg;
|
|
|
|
reg = readl(base + offset);
|
|
reg |= val;
|
|
writel(reg, base + offset);
|
|
|
|
/* ensure that above write is through */
|
|
readl(base + offset);
|
|
}
|
|
|
|
static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
|
|
{
|
|
u32 reg;
|
|
|
|
reg = readl(base + offset);
|
|
reg &= ~val;
|
|
writel(reg, base + offset);
|
|
|
|
/* ensure that above write is through */
|
|
readl(base + offset);
|
|
}
|
|
|
|
/* list of regulators */
|
|
static const char * const qmp_phy_vreg_l[] = {
|
|
"vdda-phy", "vdda-pll",
|
|
};
|
|
|
|
static const struct qmp_ufs_offsets qmp_ufs_offsets = {
|
|
.serdes = 0,
|
|
.pcs = 0xc00,
|
|
.tx = 0x400,
|
|
.rx = 0x600,
|
|
.tx2 = 0x800,
|
|
.rx2 = 0xa00,
|
|
};
|
|
|
|
static const struct qmp_ufs_offsets qmp_ufs_offsets_v6 = {
|
|
.serdes = 0,
|
|
.pcs = 0x0400,
|
|
.tx = 0x1000,
|
|
.rx = 0x1200,
|
|
.tx2 = 0x1800,
|
|
.rx2 = 0x1a00,
|
|
};
|
|
|
|
static const struct qmp_phy_cfg msm8996_ufsphy_cfg = {
|
|
.lanes = 1,
|
|
|
|
.offsets = &qmp_ufs_offsets,
|
|
.max_supported_gear = UFS_HS_G3,
|
|
|
|
.tbls = {
|
|
.serdes = msm8996_ufsphy_serdes,
|
|
.serdes_num = ARRAY_SIZE(msm8996_ufsphy_serdes),
|
|
.tx = msm8996_ufsphy_tx,
|
|
.tx_num = ARRAY_SIZE(msm8996_ufsphy_tx),
|
|
.rx = msm8996_ufsphy_rx,
|
|
.rx_num = ARRAY_SIZE(msm8996_ufsphy_rx),
|
|
},
|
|
|
|
.vreg_list = qmp_phy_vreg_l,
|
|
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
|
|
|
.regs = ufsphy_v2_regs_layout,
|
|
|
|
.no_pcs_sw_reset = true,
|
|
};
|
|
|
|
static const struct qmp_phy_cfg sa8775p_ufsphy_cfg = {
|
|
.lanes = 2,
|
|
|
|
.offsets = &qmp_ufs_offsets,
|
|
.max_supported_gear = UFS_HS_G4,
|
|
|
|
.tbls = {
|
|
.serdes = sm8350_ufsphy_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8350_ufsphy_serdes),
|
|
.tx = sm8350_ufsphy_tx,
|
|
.tx_num = ARRAY_SIZE(sm8350_ufsphy_tx),
|
|
.rx = sm8350_ufsphy_rx,
|
|
.rx_num = ARRAY_SIZE(sm8350_ufsphy_rx),
|
|
.pcs = sm8350_ufsphy_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8350_ufsphy_pcs),
|
|
},
|
|
.tbls_hs_b = {
|
|
.serdes = sm8350_ufsphy_hs_b_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8350_ufsphy_hs_b_serdes),
|
|
},
|
|
.tbls_hs_overlay[0] = {
|
|
.tx = sm8350_ufsphy_g4_tx,
|
|
.tx_num = ARRAY_SIZE(sm8350_ufsphy_g4_tx),
|
|
.rx = sm8350_ufsphy_g4_rx,
|
|
.rx_num = ARRAY_SIZE(sm8350_ufsphy_g4_rx),
|
|
.pcs = sm8350_ufsphy_g4_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs),
|
|
.max_gear = UFS_HS_G4,
|
|
},
|
|
.vreg_list = qmp_phy_vreg_l,
|
|
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
|
.regs = ufsphy_v5_regs_layout,
|
|
};
|
|
|
|
static const struct qmp_phy_cfg sc7280_ufsphy_cfg = {
|
|
.lanes = 2,
|
|
|
|
.offsets = &qmp_ufs_offsets,
|
|
.max_supported_gear = UFS_HS_G4,
|
|
|
|
.tbls = {
|
|
.serdes = sm8150_ufsphy_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8150_ufsphy_serdes),
|
|
.tx = sc7280_ufsphy_tx,
|
|
.tx_num = ARRAY_SIZE(sc7280_ufsphy_tx),
|
|
.rx = sc7280_ufsphy_rx,
|
|
.rx_num = ARRAY_SIZE(sc7280_ufsphy_rx),
|
|
.pcs = sc7280_ufsphy_pcs,
|
|
.pcs_num = ARRAY_SIZE(sc7280_ufsphy_pcs),
|
|
},
|
|
.tbls_hs_b = {
|
|
.serdes = sm8150_ufsphy_hs_b_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8150_ufsphy_hs_b_serdes),
|
|
},
|
|
.tbls_hs_overlay[0] = {
|
|
.tx = sm8250_ufsphy_hs_g4_tx,
|
|
.tx_num = ARRAY_SIZE(sm8250_ufsphy_hs_g4_tx),
|
|
.rx = sc7280_ufsphy_hs_g4_rx,
|
|
.rx_num = ARRAY_SIZE(sc7280_ufsphy_hs_g4_rx),
|
|
.pcs = sm8150_ufsphy_hs_g4_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),
|
|
.max_gear = UFS_HS_G4,
|
|
},
|
|
.vreg_list = qmp_phy_vreg_l,
|
|
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
|
.regs = ufsphy_v4_regs_layout,
|
|
};
|
|
|
|
static const struct qmp_phy_cfg sc8280xp_ufsphy_cfg = {
|
|
.lanes = 2,
|
|
|
|
.offsets = &qmp_ufs_offsets,
|
|
.max_supported_gear = UFS_HS_G4,
|
|
|
|
.tbls = {
|
|
.serdes = sm8350_ufsphy_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8350_ufsphy_serdes),
|
|
.tx = sm8350_ufsphy_tx,
|
|
.tx_num = ARRAY_SIZE(sm8350_ufsphy_tx),
|
|
.rx = sm8350_ufsphy_rx,
|
|
.rx_num = ARRAY_SIZE(sm8350_ufsphy_rx),
|
|
.pcs = sm8350_ufsphy_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8350_ufsphy_pcs),
|
|
},
|
|
.tbls_hs_b = {
|
|
.serdes = sm8350_ufsphy_hs_b_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8350_ufsphy_hs_b_serdes),
|
|
},
|
|
.tbls_hs_overlay[0] = {
|
|
.tx = sm8350_ufsphy_g4_tx,
|
|
.tx_num = ARRAY_SIZE(sm8350_ufsphy_g4_tx),
|
|
.rx = sm8350_ufsphy_g4_rx,
|
|
.rx_num = ARRAY_SIZE(sm8350_ufsphy_g4_rx),
|
|
.pcs = sm8350_ufsphy_g4_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs),
|
|
.max_gear = UFS_HS_G4,
|
|
},
|
|
.vreg_list = qmp_phy_vreg_l,
|
|
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
|
.regs = ufsphy_v5_regs_layout,
|
|
};
|
|
|
|
static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
|
|
.lanes = 2,
|
|
|
|
.offsets = &qmp_ufs_offsets,
|
|
.max_supported_gear = UFS_HS_G3,
|
|
|
|
.tbls = {
|
|
.serdes = sdm845_ufsphy_serdes,
|
|
.serdes_num = ARRAY_SIZE(sdm845_ufsphy_serdes),
|
|
.tx = sdm845_ufsphy_tx,
|
|
.tx_num = ARRAY_SIZE(sdm845_ufsphy_tx),
|
|
.rx = sdm845_ufsphy_rx,
|
|
.rx_num = ARRAY_SIZE(sdm845_ufsphy_rx),
|
|
.pcs = sdm845_ufsphy_pcs,
|
|
.pcs_num = ARRAY_SIZE(sdm845_ufsphy_pcs),
|
|
},
|
|
.tbls_hs_b = {
|
|
.serdes = sdm845_ufsphy_hs_b_serdes,
|
|
.serdes_num = ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes),
|
|
},
|
|
.vreg_list = qmp_phy_vreg_l,
|
|
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
|
.regs = ufsphy_v3_regs_layout,
|
|
|
|
.no_pcs_sw_reset = true,
|
|
};
|
|
|
|
static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
|
|
.lanes = 1,
|
|
|
|
.offsets = &qmp_ufs_offsets,
|
|
.max_supported_gear = UFS_HS_G3,
|
|
|
|
.tbls = {
|
|
.serdes = sm6115_ufsphy_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm6115_ufsphy_serdes),
|
|
.tx = sm6115_ufsphy_tx,
|
|
.tx_num = ARRAY_SIZE(sm6115_ufsphy_tx),
|
|
.rx = sm6115_ufsphy_rx,
|
|
.rx_num = ARRAY_SIZE(sm6115_ufsphy_rx),
|
|
.pcs = sm6115_ufsphy_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm6115_ufsphy_pcs),
|
|
},
|
|
.tbls_hs_b = {
|
|
.serdes = sm6115_ufsphy_hs_b_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm6115_ufsphy_hs_b_serdes),
|
|
},
|
|
.vreg_list = qmp_phy_vreg_l,
|
|
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
|
.regs = ufsphy_v2_regs_layout,
|
|
|
|
.no_pcs_sw_reset = true,
|
|
};
|
|
|
|
static const struct qmp_phy_cfg sm7150_ufsphy_cfg = {
|
|
.lanes = 1,
|
|
|
|
.offsets = &qmp_ufs_offsets,
|
|
.max_supported_gear = UFS_HS_G3,
|
|
|
|
.tbls = {
|
|
.serdes = sdm845_ufsphy_serdes,
|
|
.serdes_num = ARRAY_SIZE(sdm845_ufsphy_serdes),
|
|
.tx = sdm845_ufsphy_tx,
|
|
.tx_num = ARRAY_SIZE(sdm845_ufsphy_tx),
|
|
.rx = sm7150_ufsphy_rx,
|
|
.rx_num = ARRAY_SIZE(sm7150_ufsphy_rx),
|
|
.pcs = sm7150_ufsphy_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm7150_ufsphy_pcs),
|
|
},
|
|
.tbls_hs_b = {
|
|
.serdes = sdm845_ufsphy_hs_b_serdes,
|
|
.serdes_num = ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes),
|
|
},
|
|
.vreg_list = qmp_phy_vreg_l,
|
|
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
|
.regs = ufsphy_v3_regs_layout,
|
|
|
|
.no_pcs_sw_reset = true,
|
|
};
|
|
|
|
static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {
|
|
.lanes = 2,
|
|
|
|
.offsets = &qmp_ufs_offsets,
|
|
.max_supported_gear = UFS_HS_G4,
|
|
|
|
.tbls = {
|
|
.serdes = sm8150_ufsphy_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8150_ufsphy_serdes),
|
|
.tx = sm8150_ufsphy_tx,
|
|
.tx_num = ARRAY_SIZE(sm8150_ufsphy_tx),
|
|
.rx = sm8150_ufsphy_rx,
|
|
.rx_num = ARRAY_SIZE(sm8150_ufsphy_rx),
|
|
.pcs = sm8150_ufsphy_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8150_ufsphy_pcs),
|
|
},
|
|
.tbls_hs_b = {
|
|
.serdes = sm8150_ufsphy_hs_b_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8150_ufsphy_hs_b_serdes),
|
|
},
|
|
.tbls_hs_overlay[0] = {
|
|
.tx = sm8150_ufsphy_hs_g4_tx,
|
|
.tx_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_tx),
|
|
.rx = sm8150_ufsphy_hs_g4_rx,
|
|
.rx_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_rx),
|
|
.pcs = sm8150_ufsphy_hs_g4_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),
|
|
.max_gear = UFS_HS_G4,
|
|
},
|
|
.vreg_list = qmp_phy_vreg_l,
|
|
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
|
.regs = ufsphy_v4_regs_layout,
|
|
};
|
|
|
|
static const struct qmp_phy_cfg sm8250_ufsphy_cfg = {
|
|
.lanes = 2,
|
|
|
|
.offsets = &qmp_ufs_offsets,
|
|
.max_supported_gear = UFS_HS_G4,
|
|
|
|
.tbls = {
|
|
.serdes = sm8150_ufsphy_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8150_ufsphy_serdes),
|
|
.tx = sm8150_ufsphy_tx,
|
|
.tx_num = ARRAY_SIZE(sm8150_ufsphy_tx),
|
|
.rx = sm8150_ufsphy_rx,
|
|
.rx_num = ARRAY_SIZE(sm8150_ufsphy_rx),
|
|
.pcs = sm8150_ufsphy_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8150_ufsphy_pcs),
|
|
},
|
|
.tbls_hs_b = {
|
|
.serdes = sm8150_ufsphy_hs_b_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8150_ufsphy_hs_b_serdes),
|
|
},
|
|
.tbls_hs_overlay[0] = {
|
|
.tx = sm8250_ufsphy_hs_g4_tx,
|
|
.tx_num = ARRAY_SIZE(sm8250_ufsphy_hs_g4_tx),
|
|
.rx = sm8250_ufsphy_hs_g4_rx,
|
|
.rx_num = ARRAY_SIZE(sm8250_ufsphy_hs_g4_rx),
|
|
.pcs = sm8150_ufsphy_hs_g4_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),
|
|
.max_gear = UFS_HS_G4,
|
|
},
|
|
.vreg_list = qmp_phy_vreg_l,
|
|
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
|
.regs = ufsphy_v4_regs_layout,
|
|
};
|
|
|
|
static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {
|
|
.lanes = 2,
|
|
|
|
.offsets = &qmp_ufs_offsets,
|
|
.max_supported_gear = UFS_HS_G4,
|
|
|
|
.tbls = {
|
|
.serdes = sm8350_ufsphy_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8350_ufsphy_serdes),
|
|
.tx = sm8350_ufsphy_tx,
|
|
.tx_num = ARRAY_SIZE(sm8350_ufsphy_tx),
|
|
.rx = sm8350_ufsphy_rx,
|
|
.rx_num = ARRAY_SIZE(sm8350_ufsphy_rx),
|
|
.pcs = sm8350_ufsphy_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8350_ufsphy_pcs),
|
|
},
|
|
.tbls_hs_b = {
|
|
.serdes = sm8350_ufsphy_hs_b_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8350_ufsphy_hs_b_serdes),
|
|
},
|
|
.tbls_hs_overlay[0] = {
|
|
.tx = sm8350_ufsphy_g4_tx,
|
|
.tx_num = ARRAY_SIZE(sm8350_ufsphy_g4_tx),
|
|
.rx = sm8350_ufsphy_g4_rx,
|
|
.rx_num = ARRAY_SIZE(sm8350_ufsphy_g4_rx),
|
|
.pcs = sm8350_ufsphy_g4_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs),
|
|
.max_gear = UFS_HS_G4,
|
|
},
|
|
.vreg_list = qmp_phy_vreg_l,
|
|
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
|
.regs = ufsphy_v5_regs_layout,
|
|
};
|
|
|
|
static const struct qmp_phy_cfg sm8450_ufsphy_cfg = {
|
|
.lanes = 2,
|
|
|
|
.offsets = &qmp_ufs_offsets,
|
|
.max_supported_gear = UFS_HS_G4,
|
|
|
|
.tbls = {
|
|
.serdes = sm8350_ufsphy_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8350_ufsphy_serdes),
|
|
.tx = sm8350_ufsphy_tx,
|
|
.tx_num = ARRAY_SIZE(sm8350_ufsphy_tx),
|
|
.rx = sm8350_ufsphy_rx,
|
|
.rx_num = ARRAY_SIZE(sm8350_ufsphy_rx),
|
|
.pcs = sm8350_ufsphy_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8350_ufsphy_pcs),
|
|
},
|
|
.tbls_hs_b = {
|
|
.serdes = sm8350_ufsphy_hs_b_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8350_ufsphy_hs_b_serdes),
|
|
},
|
|
.tbls_hs_overlay[0] = {
|
|
.tx = sm8350_ufsphy_g4_tx,
|
|
.tx_num = ARRAY_SIZE(sm8350_ufsphy_g4_tx),
|
|
.rx = sm8350_ufsphy_g4_rx,
|
|
.rx_num = ARRAY_SIZE(sm8350_ufsphy_g4_rx),
|
|
.pcs = sm8350_ufsphy_g4_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs),
|
|
.max_gear = UFS_HS_G4,
|
|
},
|
|
.vreg_list = qmp_phy_vreg_l,
|
|
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
|
.regs = ufsphy_v5_regs_layout,
|
|
};
|
|
|
|
static const struct qmp_phy_cfg sm8475_ufsphy_cfg = {
|
|
.lanes = 2,
|
|
|
|
.offsets = &qmp_ufs_offsets_v6,
|
|
.max_supported_gear = UFS_HS_G4,
|
|
|
|
.tbls = {
|
|
.serdes = sm8475_ufsphy_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8475_ufsphy_serdes),
|
|
.tx = sm8550_ufsphy_tx,
|
|
.tx_num = ARRAY_SIZE(sm8550_ufsphy_tx),
|
|
.rx = sm8550_ufsphy_rx,
|
|
.rx_num = ARRAY_SIZE(sm8550_ufsphy_rx),
|
|
.pcs = sm8550_ufsphy_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8550_ufsphy_pcs),
|
|
},
|
|
.tbls_hs_b = {
|
|
.serdes = sm8550_ufsphy_hs_b_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8550_ufsphy_hs_b_serdes),
|
|
},
|
|
.tbls_hs_overlay[0] = {
|
|
.serdes = sm8475_ufsphy_g4_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8475_ufsphy_g4_serdes),
|
|
.tx = sm8550_ufsphy_g4_tx,
|
|
.tx_num = ARRAY_SIZE(sm8550_ufsphy_g4_tx),
|
|
.rx = sm8550_ufsphy_g4_rx,
|
|
.rx_num = ARRAY_SIZE(sm8550_ufsphy_g4_rx),
|
|
.pcs = sm8475_ufsphy_g4_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8475_ufsphy_g4_pcs),
|
|
.max_gear = UFS_HS_G4,
|
|
},
|
|
.vreg_list = qmp_phy_vreg_l,
|
|
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
|
.regs = ufsphy_v6_regs_layout,
|
|
};
|
|
|
|
static const struct qmp_phy_cfg sm8550_ufsphy_cfg = {
|
|
.lanes = 2,
|
|
|
|
.offsets = &qmp_ufs_offsets_v6,
|
|
.max_supported_gear = UFS_HS_G5,
|
|
|
|
.tbls = {
|
|
.serdes = sm8550_ufsphy_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8550_ufsphy_serdes),
|
|
.tx = sm8550_ufsphy_tx,
|
|
.tx_num = ARRAY_SIZE(sm8550_ufsphy_tx),
|
|
.rx = sm8550_ufsphy_rx,
|
|
.rx_num = ARRAY_SIZE(sm8550_ufsphy_rx),
|
|
.pcs = sm8550_ufsphy_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8550_ufsphy_pcs),
|
|
},
|
|
.tbls_hs_b = {
|
|
.serdes = sm8550_ufsphy_hs_b_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8550_ufsphy_hs_b_serdes),
|
|
},
|
|
.tbls_hs_overlay[0] = {
|
|
.serdes = sm8550_ufsphy_g4_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8550_ufsphy_g4_serdes),
|
|
.tx = sm8550_ufsphy_g4_tx,
|
|
.tx_num = ARRAY_SIZE(sm8550_ufsphy_g4_tx),
|
|
.rx = sm8550_ufsphy_g4_rx,
|
|
.rx_num = ARRAY_SIZE(sm8550_ufsphy_g4_rx),
|
|
.pcs = sm8550_ufsphy_g4_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8550_ufsphy_g4_pcs),
|
|
.max_gear = UFS_HS_G4,
|
|
},
|
|
.tbls_hs_overlay[1] = {
|
|
.serdes = sm8550_ufsphy_g5_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8550_ufsphy_g5_serdes),
|
|
.rx = sm8550_ufsphy_g5_rx,
|
|
.rx_num = ARRAY_SIZE(sm8550_ufsphy_g5_rx),
|
|
.pcs = sm8550_ufsphy_g5_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8550_ufsphy_g5_pcs),
|
|
.max_gear = UFS_HS_G5,
|
|
},
|
|
.vreg_list = qmp_phy_vreg_l,
|
|
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
|
.regs = ufsphy_v6_regs_layout,
|
|
};
|
|
|
|
static const struct qmp_phy_cfg sm8650_ufsphy_cfg = {
|
|
.lanes = 2,
|
|
|
|
.offsets = &qmp_ufs_offsets_v6,
|
|
.max_supported_gear = UFS_HS_G5,
|
|
|
|
.tbls = {
|
|
.serdes = sm8650_ufsphy_serdes,
|
|
.serdes_num = ARRAY_SIZE(sm8650_ufsphy_serdes),
|
|
.tx = sm8650_ufsphy_tx,
|
|
.tx_num = ARRAY_SIZE(sm8650_ufsphy_tx),
|
|
.rx = sm8650_ufsphy_rx,
|
|
.rx_num = ARRAY_SIZE(sm8650_ufsphy_rx),
|
|
.pcs = sm8650_ufsphy_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8650_ufsphy_pcs),
|
|
},
|
|
.tbls_hs_overlay[0] = {
|
|
.pcs = sm8650_ufsphy_g4_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8650_ufsphy_g4_pcs),
|
|
.max_gear = UFS_HS_G4,
|
|
},
|
|
.tbls_hs_overlay[1] = {
|
|
.pcs = sm8650_ufsphy_g5_pcs,
|
|
.pcs_num = ARRAY_SIZE(sm8650_ufsphy_g5_pcs),
|
|
.max_gear = UFS_HS_G5,
|
|
},
|
|
|
|
.vreg_list = qmp_phy_vreg_l,
|
|
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
|
.regs = ufsphy_v6_regs_layout,
|
|
};
|
|
|
|
static void qmp_ufs_serdes_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls *tbls)
|
|
{
|
|
void __iomem *serdes = qmp->serdes;
|
|
|
|
qmp_configure(qmp->dev, serdes, tbls->serdes, tbls->serdes_num);
|
|
}
|
|
|
|
static void qmp_ufs_lanes_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls *tbls)
|
|
{
|
|
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
|
void __iomem *tx = qmp->tx;
|
|
void __iomem *rx = qmp->rx;
|
|
|
|
qmp_configure_lane(qmp->dev, tx, tbls->tx, tbls->tx_num, 1);
|
|
qmp_configure_lane(qmp->dev, rx, tbls->rx, tbls->rx_num, 1);
|
|
|
|
if (cfg->lanes >= 2) {
|
|
qmp_configure_lane(qmp->dev, qmp->tx2, tbls->tx, tbls->tx_num, 2);
|
|
qmp_configure_lane(qmp->dev, qmp->rx2, tbls->rx, tbls->rx_num, 2);
|
|
}
|
|
}
|
|
|
|
static void qmp_ufs_pcs_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls *tbls)
|
|
{
|
|
void __iomem *pcs = qmp->pcs;
|
|
|
|
qmp_configure(qmp->dev, pcs, tbls->pcs, tbls->pcs_num);
|
|
}
|
|
|
|
static int qmp_ufs_get_gear_overlay(struct qmp_ufs *qmp, const struct qmp_phy_cfg *cfg)
|
|
{
|
|
u32 max_gear, floor_max_gear = cfg->max_supported_gear;
|
|
int idx, ret = -EINVAL;
|
|
|
|
for (idx = NUM_OVERLAY - 1; idx >= 0; idx--) {
|
|
max_gear = cfg->tbls_hs_overlay[idx].max_gear;
|
|
|
|
/* Skip if the table is not available */
|
|
if (max_gear == 0)
|
|
continue;
|
|
|
|
/* Direct matching, bail */
|
|
if (qmp->submode == max_gear)
|
|
return idx;
|
|
|
|
/* If no direct matching, the lowest gear is the best matching */
|
|
if (max_gear < floor_max_gear) {
|
|
ret = idx;
|
|
floor_max_gear = max_gear;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void qmp_ufs_init_registers(struct qmp_ufs *qmp, const struct qmp_phy_cfg *cfg)
|
|
{
|
|
int i;
|
|
|
|
qmp_ufs_serdes_init(qmp, &cfg->tbls);
|
|
qmp_ufs_lanes_init(qmp, &cfg->tbls);
|
|
qmp_ufs_pcs_init(qmp, &cfg->tbls);
|
|
|
|
i = qmp_ufs_get_gear_overlay(qmp, cfg);
|
|
if (i >= 0) {
|
|
qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_overlay[i]);
|
|
qmp_ufs_lanes_init(qmp, &cfg->tbls_hs_overlay[i]);
|
|
qmp_ufs_pcs_init(qmp, &cfg->tbls_hs_overlay[i]);
|
|
}
|
|
|
|
if (qmp->mode == PHY_MODE_UFS_HS_B)
|
|
qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_b);
|
|
}
|
|
|
|
static int qmp_ufs_com_init(struct qmp_ufs *qmp)
|
|
{
|
|
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
|
void __iomem *pcs = qmp->pcs;
|
|
int ret;
|
|
|
|
ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
|
|
if (ret) {
|
|
dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = clk_bulk_prepare_enable(qmp->num_clks, qmp->clks);
|
|
if (ret)
|
|
goto err_disable_regulators;
|
|
|
|
qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN);
|
|
|
|
return 0;
|
|
|
|
err_disable_regulators:
|
|
regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int qmp_ufs_com_exit(struct qmp_ufs *qmp)
|
|
{
|
|
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
|
|
|
reset_control_assert(qmp->ufs_reset);
|
|
|
|
clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
|
|
|
|
regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int qmp_ufs_init(struct phy *phy)
|
|
{
|
|
struct qmp_ufs *qmp = phy_get_drvdata(phy);
|
|
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
|
int ret;
|
|
dev_vdbg(qmp->dev, "Initializing QMP phy\n");
|
|
|
|
if (cfg->no_pcs_sw_reset) {
|
|
/*
|
|
* Get UFS reset, which is delayed until now to avoid a
|
|
* circular dependency where UFS needs its PHY, but the PHY
|
|
* needs this UFS reset.
|
|
*/
|
|
if (!qmp->ufs_reset) {
|
|
qmp->ufs_reset =
|
|
devm_reset_control_get_exclusive(qmp->dev,
|
|
"ufsphy");
|
|
|
|
if (IS_ERR(qmp->ufs_reset)) {
|
|
ret = PTR_ERR(qmp->ufs_reset);
|
|
dev_err(qmp->dev,
|
|
"failed to get UFS reset: %d\n",
|
|
ret);
|
|
|
|
qmp->ufs_reset = NULL;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
ret = reset_control_assert(qmp->ufs_reset);
|
|
if (ret)
|
|
return ret;
|
|
}
|
|
|
|
ret = qmp_ufs_com_init(qmp);
|
|
if (ret)
|
|
return ret;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int qmp_ufs_power_on(struct phy *phy)
|
|
{
|
|
struct qmp_ufs *qmp = phy_get_drvdata(phy);
|
|
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
|
void __iomem *pcs = qmp->pcs;
|
|
void __iomem *status;
|
|
unsigned int val;
|
|
int ret;
|
|
|
|
qmp_ufs_init_registers(qmp, cfg);
|
|
|
|
ret = reset_control_deassert(qmp->ufs_reset);
|
|
if (ret)
|
|
return ret;
|
|
|
|
/* Pull PHY out of reset state */
|
|
if (!cfg->no_pcs_sw_reset)
|
|
qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
|
|
|
|
/* start SerDes */
|
|
qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START);
|
|
|
|
status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
|
|
ret = readl_poll_timeout(status, val, (val & PCS_READY), 200,
|
|
PHY_INIT_COMPLETE_TIMEOUT);
|
|
if (ret) {
|
|
dev_err(qmp->dev, "phy initialization timed-out\n");
|
|
return ret;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int qmp_ufs_power_off(struct phy *phy)
|
|
{
|
|
struct qmp_ufs *qmp = phy_get_drvdata(phy);
|
|
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
|
|
|
/* PHY reset */
|
|
if (!cfg->no_pcs_sw_reset)
|
|
qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
|
|
|
|
/* stop SerDes */
|
|
qphy_clrbits(qmp->pcs, cfg->regs[QPHY_START_CTRL], SERDES_START);
|
|
|
|
/* Put PHY into POWER DOWN state: active low */
|
|
qphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
|
|
SW_PWRDN);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int qmp_ufs_exit(struct phy *phy)
|
|
{
|
|
struct qmp_ufs *qmp = phy_get_drvdata(phy);
|
|
|
|
qmp_ufs_com_exit(qmp);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int qmp_ufs_enable(struct phy *phy)
|
|
{
|
|
int ret;
|
|
|
|
ret = qmp_ufs_init(phy);
|
|
if (ret)
|
|
return ret;
|
|
|
|
ret = qmp_ufs_power_on(phy);
|
|
if (ret)
|
|
qmp_ufs_exit(phy);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int qmp_ufs_disable(struct phy *phy)
|
|
{
|
|
int ret;
|
|
|
|
ret = qmp_ufs_power_off(phy);
|
|
if (ret)
|
|
return ret;
|
|
return qmp_ufs_exit(phy);
|
|
}
|
|
|
|
static int qmp_ufs_set_mode(struct phy *phy, enum phy_mode mode, int submode)
|
|
{
|
|
struct qmp_ufs *qmp = phy_get_drvdata(phy);
|
|
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
|
|
|
if (submode > cfg->max_supported_gear || submode == 0) {
|
|
dev_err(qmp->dev, "Invalid PHY submode %d\n", submode);
|
|
return -EINVAL;
|
|
}
|
|
|
|
qmp->mode = mode;
|
|
qmp->submode = submode;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const struct phy_ops qcom_qmp_ufs_phy_ops = {
|
|
.power_on = qmp_ufs_enable,
|
|
.power_off = qmp_ufs_disable,
|
|
.set_mode = qmp_ufs_set_mode,
|
|
.owner = THIS_MODULE,
|
|
};
|
|
|
|
static int qmp_ufs_vreg_init(struct qmp_ufs *qmp)
|
|
{
|
|
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
|
struct device *dev = qmp->dev;
|
|
int num = cfg->num_vregs;
|
|
int i;
|
|
|
|
qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
|
|
if (!qmp->vregs)
|
|
return -ENOMEM;
|
|
|
|
for (i = 0; i < num; i++)
|
|
qmp->vregs[i].supply = cfg->vreg_list[i];
|
|
|
|
return devm_regulator_bulk_get(dev, num, qmp->vregs);
|
|
}
|
|
|
|
static int qmp_ufs_clk_init(struct qmp_ufs *qmp)
|
|
{
|
|
struct device *dev = qmp->dev;
|
|
|
|
qmp->num_clks = devm_clk_bulk_get_all(dev, &qmp->clks);
|
|
if (qmp->num_clks < 0)
|
|
return qmp->num_clks;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void qmp_ufs_clk_release_provider(void *res)
|
|
{
|
|
of_clk_del_provider(res);
|
|
}
|
|
|
|
#define UFS_SYMBOL_CLOCKS 3
|
|
|
|
static int qmp_ufs_register_clocks(struct qmp_ufs *qmp, struct device_node *np)
|
|
{
|
|
struct clk_hw_onecell_data *clk_data;
|
|
struct clk_hw *hw;
|
|
char name[64];
|
|
int ret;
|
|
|
|
clk_data = devm_kzalloc(qmp->dev,
|
|
struct_size(clk_data, hws, UFS_SYMBOL_CLOCKS),
|
|
GFP_KERNEL);
|
|
if (!clk_data)
|
|
return -ENOMEM;
|
|
|
|
clk_data->num = UFS_SYMBOL_CLOCKS;
|
|
|
|
snprintf(name, sizeof(name), "%s::rx_symbol_0", dev_name(qmp->dev));
|
|
hw = devm_clk_hw_register_fixed_rate(qmp->dev, name, NULL, 0, 0);
|
|
if (IS_ERR(hw))
|
|
return PTR_ERR(hw);
|
|
|
|
clk_data->hws[0] = hw;
|
|
|
|
snprintf(name, sizeof(name), "%s::rx_symbol_1", dev_name(qmp->dev));
|
|
hw = devm_clk_hw_register_fixed_rate(qmp->dev, name, NULL, 0, 0);
|
|
if (IS_ERR(hw))
|
|
return PTR_ERR(hw);
|
|
|
|
clk_data->hws[1] = hw;
|
|
|
|
snprintf(name, sizeof(name), "%s::tx_symbol_0", dev_name(qmp->dev));
|
|
hw = devm_clk_hw_register_fixed_rate(qmp->dev, name, NULL, 0, 0);
|
|
if (IS_ERR(hw))
|
|
return PTR_ERR(hw);
|
|
|
|
clk_data->hws[2] = hw;
|
|
|
|
ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
|
|
if (ret)
|
|
return ret;
|
|
|
|
/*
|
|
* Roll a devm action because the clock provider can be a child node.
|
|
*/
|
|
return devm_add_action_or_reset(qmp->dev, qmp_ufs_clk_release_provider, np);
|
|
}
|
|
|
|
static int qmp_ufs_parse_dt_legacy(struct qmp_ufs *qmp, struct device_node *np)
|
|
{
|
|
struct platform_device *pdev = to_platform_device(qmp->dev);
|
|
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
|
struct device *dev = qmp->dev;
|
|
|
|
qmp->serdes = devm_platform_ioremap_resource(pdev, 0);
|
|
if (IS_ERR(qmp->serdes))
|
|
return PTR_ERR(qmp->serdes);
|
|
|
|
/*
|
|
* Get memory resources for the PHY:
|
|
* Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
|
|
* For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5
|
|
* For single lane PHYs: pcs_misc (optional) -> 3.
|
|
*/
|
|
qmp->tx = devm_of_iomap(dev, np, 0, NULL);
|
|
if (IS_ERR(qmp->tx))
|
|
return PTR_ERR(qmp->tx);
|
|
|
|
qmp->rx = devm_of_iomap(dev, np, 1, NULL);
|
|
if (IS_ERR(qmp->rx))
|
|
return PTR_ERR(qmp->rx);
|
|
|
|
qmp->pcs = devm_of_iomap(dev, np, 2, NULL);
|
|
if (IS_ERR(qmp->pcs))
|
|
return PTR_ERR(qmp->pcs);
|
|
|
|
if (cfg->lanes >= 2) {
|
|
qmp->tx2 = devm_of_iomap(dev, np, 3, NULL);
|
|
if (IS_ERR(qmp->tx2))
|
|
return PTR_ERR(qmp->tx2);
|
|
|
|
qmp->rx2 = devm_of_iomap(dev, np, 4, NULL);
|
|
if (IS_ERR(qmp->rx2))
|
|
return PTR_ERR(qmp->rx2);
|
|
|
|
qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL);
|
|
} else {
|
|
qmp->pcs_misc = devm_of_iomap(dev, np, 3, NULL);
|
|
}
|
|
|
|
if (IS_ERR(qmp->pcs_misc))
|
|
dev_vdbg(dev, "PHY pcs_misc-reg not used\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int qmp_ufs_parse_dt(struct qmp_ufs *qmp)
|
|
{
|
|
struct platform_device *pdev = to_platform_device(qmp->dev);
|
|
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
|
const struct qmp_ufs_offsets *offs = cfg->offsets;
|
|
void __iomem *base;
|
|
|
|
if (!offs)
|
|
return -EINVAL;
|
|
|
|
base = devm_platform_ioremap_resource(pdev, 0);
|
|
if (IS_ERR(base))
|
|
return PTR_ERR(base);
|
|
|
|
qmp->serdes = base + offs->serdes;
|
|
qmp->pcs = base + offs->pcs;
|
|
qmp->tx = base + offs->tx;
|
|
qmp->rx = base + offs->rx;
|
|
|
|
if (cfg->lanes >= 2) {
|
|
qmp->tx2 = base + offs->tx2;
|
|
qmp->rx2 = base + offs->rx2;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int qmp_ufs_probe(struct platform_device *pdev)
|
|
{
|
|
struct device *dev = &pdev->dev;
|
|
struct phy_provider *phy_provider;
|
|
struct device_node *np;
|
|
struct qmp_ufs *qmp;
|
|
int ret;
|
|
|
|
qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
|
|
if (!qmp)
|
|
return -ENOMEM;
|
|
|
|
qmp->dev = dev;
|
|
|
|
qmp->cfg = of_device_get_match_data(dev);
|
|
if (!qmp->cfg)
|
|
return -EINVAL;
|
|
|
|
ret = qmp_ufs_clk_init(qmp);
|
|
if (ret)
|
|
return ret;
|
|
|
|
ret = qmp_ufs_vreg_init(qmp);
|
|
if (ret)
|
|
return ret;
|
|
|
|
/* Check for legacy binding with child node. */
|
|
np = of_get_next_available_child(dev->of_node, NULL);
|
|
if (np) {
|
|
ret = qmp_ufs_parse_dt_legacy(qmp, np);
|
|
} else {
|
|
np = of_node_get(dev->of_node);
|
|
ret = qmp_ufs_parse_dt(qmp);
|
|
}
|
|
if (ret)
|
|
goto err_node_put;
|
|
|
|
ret = qmp_ufs_register_clocks(qmp, np);
|
|
if (ret)
|
|
goto err_node_put;
|
|
|
|
qmp->phy = devm_phy_create(dev, np, &qcom_qmp_ufs_phy_ops);
|
|
if (IS_ERR(qmp->phy)) {
|
|
ret = PTR_ERR(qmp->phy);
|
|
dev_err(dev, "failed to create PHY: %d\n", ret);
|
|
goto err_node_put;
|
|
}
|
|
|
|
phy_set_drvdata(qmp->phy, qmp);
|
|
|
|
of_node_put(np);
|
|
|
|
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
|
|
|
return PTR_ERR_OR_ZERO(phy_provider);
|
|
|
|
err_node_put:
|
|
of_node_put(np);
|
|
return ret;
|
|
}
|
|
|
|
static const struct of_device_id qmp_ufs_of_match_table[] = {
|
|
{
|
|
.compatible = "qcom,msm8996-qmp-ufs-phy",
|
|
.data = &msm8996_ufsphy_cfg,
|
|
}, {
|
|
.compatible = "qcom,msm8998-qmp-ufs-phy",
|
|
.data = &sdm845_ufsphy_cfg,
|
|
}, {
|
|
.compatible = "qcom,sa8775p-qmp-ufs-phy",
|
|
.data = &sa8775p_ufsphy_cfg,
|
|
}, {
|
|
.compatible = "qcom,sc7180-qmp-ufs-phy",
|
|
.data = &sm7150_ufsphy_cfg,
|
|
}, {
|
|
.compatible = "qcom,sc7280-qmp-ufs-phy",
|
|
.data = &sc7280_ufsphy_cfg,
|
|
}, {
|
|
.compatible = "qcom,sc8180x-qmp-ufs-phy",
|
|
.data = &sm8150_ufsphy_cfg,
|
|
}, {
|
|
.compatible = "qcom,sc8280xp-qmp-ufs-phy",
|
|
.data = &sc8280xp_ufsphy_cfg,
|
|
}, {
|
|
.compatible = "qcom,sdm845-qmp-ufs-phy",
|
|
.data = &sdm845_ufsphy_cfg,
|
|
}, {
|
|
.compatible = "qcom,sm6115-qmp-ufs-phy",
|
|
.data = &sm6115_ufsphy_cfg,
|
|
}, {
|
|
.compatible = "qcom,sm6125-qmp-ufs-phy",
|
|
.data = &sm6115_ufsphy_cfg,
|
|
}, {
|
|
.compatible = "qcom,sm6350-qmp-ufs-phy",
|
|
.data = &sdm845_ufsphy_cfg,
|
|
}, {
|
|
.compatible = "qcom,sm7150-qmp-ufs-phy",
|
|
.data = &sm7150_ufsphy_cfg,
|
|
}, {
|
|
.compatible = "qcom,sm8150-qmp-ufs-phy",
|
|
.data = &sm8150_ufsphy_cfg,
|
|
}, {
|
|
.compatible = "qcom,sm8250-qmp-ufs-phy",
|
|
.data = &sm8250_ufsphy_cfg,
|
|
}, {
|
|
.compatible = "qcom,sm8350-qmp-ufs-phy",
|
|
.data = &sm8350_ufsphy_cfg,
|
|
}, {
|
|
.compatible = "qcom,sm8450-qmp-ufs-phy",
|
|
.data = &sm8450_ufsphy_cfg,
|
|
}, {
|
|
.compatible = "qcom,sm8475-qmp-ufs-phy",
|
|
.data = &sm8475_ufsphy_cfg,
|
|
}, {
|
|
.compatible = "qcom,sm8550-qmp-ufs-phy",
|
|
.data = &sm8550_ufsphy_cfg,
|
|
}, {
|
|
.compatible = "qcom,sm8650-qmp-ufs-phy",
|
|
.data = &sm8650_ufsphy_cfg,
|
|
},
|
|
{ },
|
|
};
|
|
MODULE_DEVICE_TABLE(of, qmp_ufs_of_match_table);
|
|
|
|
static struct platform_driver qmp_ufs_driver = {
|
|
.probe = qmp_ufs_probe,
|
|
.driver = {
|
|
.name = "qcom-qmp-ufs-phy",
|
|
.of_match_table = qmp_ufs_of_match_table,
|
|
},
|
|
};
|
|
|
|
module_platform_driver(qmp_ufs_driver);
|
|
|
|
MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
|
|
MODULE_DESCRIPTION("Qualcomm QMP UFS PHY driver");
|
|
MODULE_LICENSE("GPL v2");
|