diff --git a/Documentation/devicetree/bindings/usb/msm-phy.txt b/Documentation/devicetree/bindings/usb/msm-phy.txt index 4abab6812aa0..e67d04f4d513 100644 --- a/Documentation/devicetree/bindings/usb/msm-phy.txt +++ b/Documentation/devicetree/bindings/usb/msm-phy.txt @@ -108,6 +108,8 @@ Required properties: - qcom,vdd-voltage-level: This property must be a list of three integer values (no, min, max) where each value represents either a voltage in microvolts or a value corresponding to voltage corner + - qcom,qmp-phy-init-seq: QMP PHY initialization sequence with reg offset, its + value, delay after register write. It is not must property to have for emulation. Optional properties: - reg: Additional register set of address and length to control QMP PHY @@ -115,8 +117,6 @@ Optional properties: the USB PHY and the controller must rely on external VBUS notification in order to manually relay the notification to the SSPHY. - qcom,emulation: Indicates that we are running on emulation platform. - - qcom,qmp-phy-init-seq: QMP PHY initialization sequence with reg offset, its - value, delay after register write. - qcom,qmp-phy-reg-offset: If present stores phy register offsets in an order defined in the phy driver. diff --git a/drivers/usb/phy/phy-msm-ssusb-qmp.c b/drivers/usb/phy/phy-msm-ssusb-qmp.c index 873051fcd527..b2189a0ca593 100644 --- a/drivers/usb/phy/phy-msm-ssusb-qmp.c +++ b/drivers/usb/phy/phy-msm-ssusb-qmp.c @@ -90,241 +90,6 @@ struct qmp_reg_val { u32 delay; }; -/* Use these offsets/values if PCIE_USB3_PHY_REVISION_ID0 == 0 */ -static const struct qmp_reg_val qmp_settings_rev0[] = { - {0x48, 0x08}, /* QSERDES_COM_SYSCLK_EN_SEL_TXBAND */ - {0xA4, 0x82}, /* QSERDES_COM_DEC_START1 */ - {0x104, 0x03}, /* QSERDES_COM_DEC_START2 */ - {0xF8, 0xD5}, /* QSERDES_COM_DIV_FRAC_START1 */ - {0xFC, 0xAA}, /* QSERDES_COM_DIV_FRAC_START2 */ - {0x100, 0x4D}, /* QSERDES_COM_DIV_FRAC_START3 */ - {0x94, 0x11}, /* QSERDES_COM_PLLLOCK_CMP_EN */ - {0x88, 0x2B}, /* QSERDES_COM_PLLLOCK_CMP1 */ - {0x8C, 0x68}, /* QSERDES_COM_PLLLOCK_CMP2 */ - {0x10C, 0x7C}, /* QSERDES_COM_PLL_CRCTRL */ - {0x34, 0x07}, /* QSERDES_COM_PLL_CP_SETI */ - {0x38, 0x1F}, /* QSERDES_COM_PLL_IP_SETP */ - {0x3C, 0x0F}, /* QSERDES_COM_PLL_CP_SETP */ - {0x24, 0x01}, /* QSERDES_COM_PLL_IP_SETI */ - {0x0C, 0x0F}, /* QSERDES_COM_IE_TRIM */ - {0x10, 0x0F}, /* QSERDES_COM_IP_TRIM */ - {0x14, 0x46}, /* QSERDES_COM_PLL_CNTRL */ - - /* CDR Settings */ - {0x400, 0xDA}, /* QSERDES_RX_CDR_CONTROL1 */ - {0x404, 0x42}, /* QSERDES_RX_CDR_CONTROL2 */ - {0x41c, 0x75}, /* QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE */ - - /* Calibration Settings */ - {0x4C, 0x90}, /* QSERDES_COM_RESETSM_CNTRL */ - {0x50, 0x05}, /* QSERDES_COM_RESETSM_CNTRL2 */ - - {0xD8, 0x20}, /* QSERDES_COM_RES_CODE_START_SEG1 */ - {0xE0, 0x77}, /* QSERDES_COM_RES_CODE_CAL_CSR */ - {0xE8, 0x15}, /* QSERDES_COM_RES_TRIM_CONTROL */ - {0x268, 0x02}, /* QSERDES_TX_RCV_DETECT_LVL */ - {0x4F0, 0x67}, /* QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 */ - {0x4F4, 0x80}, /* QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2 */ - {0x4BC, 0x06}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 */ - {0x4C0, 0x6C}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 */ - {0x4C4, 0xA7}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 */ - {0x4F8, 0x40}, /* QSERDES_RX_SIGDET_ENABLES */ - {0x500, 0x73}, /* QSERDES_RX_SIGDET_CNTRL */ - {0x504, 0x06}, /* QSERDES_RX_SIGDET_DEGLITCH_CNTRL */ - - {0x64C, 0x48}, /* PCIE_USB3_PHY_RX_IDLE_DTCT_CNTRL */ - {0xAC, 0x01}, /* QSERDES_COM_SSC_EN_CENTER */ - {0xB0, 0x02}, /* QSERDES_COM_SSC_ADJ_PER1 */ - {0xB8, 0x31}, /* QSERDES_COM_SSC_PER1 */ - {0xBC, 0x01}, /* QSERDES_COM_SSC_PER2 */ - {0xC0, 0x19}, /* QSERDES_COM_SSC_STEP_SIZE1 */ - {0xC4, 0x19}, /* QSERDES_COM_SSC_STEP_SIZE2 */ - {0x654, 0x08}, /* PCIE_USB3_PHY_POWER_STATE_CONFIG2 */ - {0x65C, 0xE5}, /* PCIE_USB3_PHY_RCVR_DTCT_DLY_P1U2_L */ - {0x660, 0x03}, /* PCIE_USB3_PHY_RCVR_DTCT_DLY_P1U2_H */ - {0x6A0, 0x13}, /* PCIE_USB3_PHY_RXEQTRAINING_RUN_TIME */ - {0x66C, 0xFF}, /* PCIE_USB3_PHY_LOCK_DETECT_CONFIG1 */ - {0x674, 0x17}, /* PCIE_USB3_PHY_LOCK_DETECT_CONFIG3 */ - {0x6AC, 0x05}, /* PCIE_USB3_PHY_FLL_CNTRL2 */ - - {-1, 0x00} /* terminating entry */ -}; - -/* - * Use these offsets/values if PCIE_USB3_PHY_REVISION_ID0 == 1 - * QSERDES_COM registers between 0x58 and 0x14C been moved (added) 8 bytes - */ -static const struct qmp_reg_val qmp_settings_rev1[] = { - {0x48, 0x08}, /* QSERDES_COM_SYSCLK_EN_SEL_TXBAND */ - {0xAC, 0x82}, /* QSERDES_COM_DEC_START1 */ - {0x10C, 0x03}, /* QSERDES_COM_DEC_START2 */ - {0x100, 0xD5}, /* QSERDES_COM_DIV_FRAC_START1 */ - {0x104, 0xAA}, /* QSERDES_COM_DIV_FRAC_START2 */ - {0x108, 0x4D}, /* QSERDES_COM_DIV_FRAC_START3 */ - {0x9C, 0x11}, /* QSERDES_COM_PLLLOCK_CMP_EN */ - {0x90, 0x2B}, /* QSERDES_COM_PLLLOCK_CMP1 */ - {0x94, 0x68}, /* QSERDES_COM_PLLLOCK_CMP2 */ - {0x114, 0x7C}, /* QSERDES_COM_PLL_CRCTRL */ - {0x34, 0x1F}, /* QSERDES_COM_PLL_CP_SETI */ - {0x38, 0x12}, /* QSERDES_COM_PLL_IP_SETP */ - {0x3C, 0x0F}, /* QSERDES_COM_PLL_CP_SETP */ - {0x24, 0x01}, /* QSERDES_COM_PLL_IP_SETI */ - {0x0C, 0x0F}, /* QSERDES_COM_IE_TRIM */ - {0x10, 0x0F}, /* QSERDES_COM_IP_TRIM */ - {0x14, 0x46}, /* QSERDES_COM_PLL_CNTRL */ - - /* CDR Settings */ - {0x41C, 0x75}, /* QSERDEX_RX_UCDR_SO_SATURATION_AND_ENABLE */ - - /* Calibration Settings */ - {0x4C, 0x90}, /* QSERDES_COM_RESETSM_CNTRL */ - {0x50, 0x07}, /* QSERDES_COM_RESETSM_CNTRL2 */ - {0x04, 0xE1}, /* QSERDES_COM_PLL_VCOTAIL_EN */ - - {0xE0, 0x24}, /* QSERDES_COM_RES_CODE_START_SEG1 */ - {0xE8, 0x77}, /* QSERDES_COM_RES_CODE_CAL_CSR */ - {0xF0, 0x15}, /* QSERDES_COM_RES_TRIM_CONTROL */ - {0x268, 0x02}, /* QSERDES_TX_RCV_DETECT_LVL */ - {0x4F0, 0x67}, /* QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 */ - {0x4F4, 0x80}, /* QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2 */ - {0x4BC, 0x06}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 */ - {0x4C0, 0x6C}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 */ - {0x4C4, 0xA7}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 */ - {0x4F8, 0x40}, /* QSERDES_RX_SIGDET_ENABLES */ - {0x500, 0x73}, /* QSERDES_RX_SIGDET_CNTRL */ - {0x504, 0x06}, /* QSERDES_RX_SIGDET_DEGLITCH_CNTRL */ - {0x64C, 0x48}, /* PCIE_USB3_PHY_RX_IDLE_DTCT_CNTRL */ - {0xB4, 0x01}, /* QSERDES_COM_SSC_EN_CENTER */ - {0xB8, 0x02}, /* QSERDES_COM_SSC_ADJ_PER1 */ - {0xC0, 0x31}, /* QSERDES_COM_SSC_PER1 */ - {0xC4, 0x01}, /* QSERDES_COM_SSC_PER2 */ - {0xC8, 0x19}, /* QSERDES_COM_SSC_STEP_SIZE1 */ - {0xCC, 0x19}, /* QSERDES_COM_SSC_STEP_SIZE2 */ - {0x654, 0x08}, /* PCIE_USB3_PHY_POWER_STATE_CONFIG2 */ - {0x65C, 0xE5}, /* PCIE_USB3_PHY_RCVR_DTCT_DLY_P1U2_L */ - {0x660, 0x03}, /* PCIE_USB3_PHY_RCVR_DTCT_DLY_P1U2_H */ - {0x6A0, 0x13}, /* PCIE_USB3_PHY_RXEQTRAINING_RUN_TIME */ - {0x66C, 0xFF}, /* PCIE_USB3_PHY_LOCK_DETECT_CONFIG1 */ - {0x674, 0x17}, /* PCIE_USB3_PHY_LOCK_DETECT_CONFIG3 */ - {0x6AC, 0x05}, /* PCIE_USB3_PHY_FLL_CNTRL2 */ - - {-1, 0x00} /* terminating entry */ -}; - -/* USB3PHY_REVISION_ID3 = 0x20 where register offset is being changed. */ -static const struct qmp_reg_val qmp_settings_rev2[] = { - /* Common block settings */ - {0xAC, 0x14}, /* QSERDES_COM_SYSCLK_EN_SEL */ - {0x34, 0x08}, /* QSERDES_COM_BIAS_EN_CLKBUFLR_EN */ - {0x174, 0x30}, /* QSERDES_COM_CLK_SELECT */ - {0x194, 0x06}, /* QSERDES_COM_CMN_CONFIG */ - {0x19C, 0x01}, /* QSERDES_COM_SVS_MODE_CLK_SEL */ - {0x178, 0x00}, /* QSERDES_COM_HSCLK_SEL */ - {0x70, 0x0F}, /* USB3PHY_QSERDES_COM_BG_TRIM */ - {0x48, 0x0F}, /* USB3PHY_QSERDES_COM_PLL_IVCO */ - {0x3C, 0x04}, /* QSERDES_COM_SYS_CLK_CTRL */ - - /* PLL and Loop filter settings */ - {0xD0, 0x82}, /* QSERDES_COM_DEC_START_MODE0 */ - {0xDC, 0x55}, /* QSERDES_COM_DIV_FRAC_START1_MODE0 */ - {0xE0, 0x55}, /* QSERDES_COM_DIV_FRAC_START2_MODE0 */ - {0xE4, 0x03}, /* QSERDES_COM_DIV_FRAC_START3_MODE0 */ - {0x78, 0x0B}, /* QSERDES_COM_CP_CTRL_MODE0 */ - {0x84, 0x16}, /* QSERDES_COM_PLL_RCTRL_MODE0 */ - {0x90, 0x28}, /* QSERDES_COM_PLL_CCTRL_MODE0 */ - {0x108, 0x80}, /*QSERDES_COM_INTEGLOOP_GAIN0_MODE0 */ - {0x124, 0x00}, /* USB3PHY_QSERDES_COM_VCO_TUNE_CTRL */ - {0x4C, 0x15}, /* QSERDES_COM_LOCK_CMP1_MODE0 */ - {0x50, 0x34}, /* QSERDES_COM_LOCK_CMP2_MODE0 */ - {0x54, 0x00}, /* QSERDES_COM_LOCK_CMP3_MODE0 */ - {0x18C, 0x00}, /* QSERDES_COM_CORE_CLK_EN */ - {0xCC, 0x00}, /* QSERDES_COM_LOCK_CMP_CFG */ - {0x128, 0x00}, /* QSERDES_COM_VCO_TUNE_MAP */ - {0x0C, 0x0A}, /* QSERDES_COM_BG_TIMER */ - - /* SSC settings */ - {0x10, 0x01}, /* QSERDES_COM_SSC_EN_CENTER */ - {0x1C, 0x31}, /* QSERDES_COM_SSC_PER1 */ - {0x20, 0x01}, /* QSERDES_COM_SSC_PER2 */ - {0x14, 0x00}, /* QSERDES_COM_SSC_ADJ_PER1 */ - {0x18, 0x00}, /* QSERDES_COM_SSC_ADJ_PER2 */ - {0x24, 0xDE}, /* QSERDES_COM_SSC_STEP_SIZE1 */ - {0x28, 0x07}, /* QSERDES_COM_SSC_STEP_SIZE2 */ - - /* Rx settings */ - {0x440, 0x0B}, /* QSERDES_RX_UCDR_FASTLOCK_FO_GAIN */ - {0x41C, 0x04}, /* QSERDES_RX_UCDR_SO_GAIN */ - {0x4D8, 0x02}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 */ - {0x4DC, 0x4C}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 */ - {0x4E0, 0xBB}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 */ - {0x508, 0x77}, /* QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 */ - {0x50C, 0x80}, /* QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2 */ - {0x514, 0x03}, /* QSERDES_RX_SIGDET_CNTRL */ - {0x518, 0x18}, /* QSERDES_RX_SIGDET_LVL */ - {0x51C, 0x16}, /* QSERDES_RX_SIGDET_DEGLITCH_CNTRL */ - - /* TX settings */ - {0x268, 0x45}, /* QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN */ - {0x2AC, 0x12}, /* QSERDES_TX_RCV_DETECT_LVL_2 */ - {0x294, 0x06}, /* QSERDES_TX_LANE_MODE */ - - /* FLL settings */ - {0x6C4, 0x03}, /* USB3_PHY_FLL_CNTRL2 */ - {0x6C0, 0x02}, /* USB3_PHY_FLL_CNTRL1 */ - {0x6C8, 0x09}, /* USB3_PHY_FLL_CNT_VAL_L */ - {0x6CC, 0x42}, /* USB3_PHY_FLL_CNT_VAL_H_TOL */ - {0x6D0, 0x85}, /* USB3_PHY_FLL_MAN_CODE */ - - /* Lock Det settings */ - {0x680, 0xD1}, /* USB3_PHY_LOCK_DETECT_CONFIG1 */ - {0x684, 0x1F}, /* USB3_PHY_LOCK_DETECT_CONFIG2 */ - {0x688, 0x47}, /* USB3_PHY_LOCK_DETECT_CONFIG3 */ - {0x664, 0x08}, /* USB3_PHY_POWER_STATE_CONFIG2 */ - - {-1, 0x00} /* terminating entry */ -}; - -/* Override for QMP PHY revision 2 */ -static const struct qmp_reg_val qmp_settings_rev2_misc[] = { - {0x178, 0x01}, /* QSERDES_COM_HSCLK_SEL */ - - /* Rx settings */ - {0x518, 0x1B}, /* QSERDES_RX_SIGDET_LVL */ - - /* Res_code settings */ - {0xC4, 0x15}, /* USB3PHY_QSERDES_COM_RESCODE_DIV_NUM */ - {0x1B8, 0x1F}, /* QSERDES_COM_CMN_MISC2 */ - {-1, 0x00} /* terminating entry */ -}; - -/* Override PLL Calibration */ -static const struct qmp_reg_val qmp_override_pll[] = { - {0x04, 0xE1}, /* QSERDES_COM_PLL_VCOTAIL_EN */ - {0x50, 0x07}, /* QSERDES_COM_RESETSM_CNTRL2 */ - {-1, 0x00} /* terminating entry */ -}; - -/* Foundry specific settings */ -static const struct qmp_reg_val qmp_settings_rev0_misc[] = { - {0x10C, 0x37}, /* QSERDES_COM_PLL_CRCTRL */ - {0x34, 0x04}, /* QSERDES_COM_PLL_CP_SETI */ - {0x38, 0x32}, /* QSERDES_COM_PLL_IP_SETP */ - {0x3C, 0x05}, /* QSERDES_COM_PLL_CP_SETP */ - {0x500, 0xF7}, /* QSERDES_RX_SIGDET_CNTRL */ - {0x4A8, 0xFF}, /* QSERDES_RX_RX_EQ_GAIN1_LSB */ - {0x6B0, 0xF4}, /* PCIE_USB3_PHY_FLL_CNT_VAL_L */ - {0x6B4, 0x41}, /* PCIE_USB3_PHY_FLL_CNT_VAL_H_TOL */ - {-1, 0x00} /* terminating entry */ -}; - -/* Vbg related settings */ -static const struct qmp_reg_val qmp_settings_rev1_misc[] = { - {0x0C, 0x03}, /* QSERDES_COM_IE_TRIM */ - {0x10, 0x00}, /* QSERDES_COM_IP_TRIM */ - {0xA0, 0xFF}, /* QSERDES_COM_BGTC */ - {-1, 0x00} /* terminating entry */ -}; - struct msm_ssphy_qmp { struct usb_phy phy; void __iomem *base; @@ -508,8 +273,7 @@ static int msm_ssphy_qmp_init(struct usb_phy *uphy) phy); int ret; unsigned init_timeout_usec = INIT_MAX_TIME_USEC; - u32 revid; - const struct qmp_reg_val *reg = NULL, *misc = NULL, *pll = NULL; + const struct qmp_reg_val *reg = NULL; dev_dbg(uphy->dev, "Initializing QMP phy\n"); @@ -528,47 +292,14 @@ static int msm_ssphy_qmp_init(struct usb_phy *uphy) phy->clk_enabled = true; } - /* Rev ID is made up each of the LSBs of REVISION_ID[0-3] */ - revid = (readl_relaxed(phy->base + - phy->phy_reg[USB3_REVISION_ID3]) & 0xFF) << 24; - revid |= (readl_relaxed(phy->base + - phy->phy_reg[USB3_REVISION_ID2]) & 0xFF) << 16; - revid |= (readl_relaxed(phy->base + - phy->phy_reg[USB3_REVISION_ID1]) & 0xFF) << 8; - revid |= readl_relaxed(phy->base + - phy->phy_reg[USB3_REVISION_ID0]) & 0xFF; - - pll = qmp_override_pll; - - switch (revid) { - case 0x10000000: - reg = qmp_settings_rev0; - misc = qmp_settings_rev0_misc; - break; - case 0x10000001: - reg = qmp_settings_rev1; - misc = qmp_settings_rev1_misc; - break; - case 0x20000000: - case 0x20000001: - reg = qmp_settings_rev2; - misc = qmp_settings_rev2_misc; - break; - default: - dev_err(uphy->dev, "Unknown revid 0x%x, cannot initialize PHY\n", - revid); - return -ENODEV; - } - - if (phy->qmp_phy_init_seq) - reg = (struct qmp_reg_val *)phy->qmp_phy_init_seq; - writel_relaxed(0x01, phy->base + phy->phy_reg[USB3_PHY_POWER_DOWN_CONTROL]); /* Make sure that above write completed to get PHY into POWER DOWN */ mb(); + reg = (struct qmp_reg_val *)phy->qmp_phy_init_seq; + /* Main configuration */ ret = configure_phy_regs(uphy, reg); if (ret) { @@ -576,27 +307,9 @@ static int msm_ssphy_qmp_init(struct usb_phy *uphy) return ret; } - /* Feature specific configurations */ - if (phy->override_pll_cal) { - ret = configure_phy_regs(uphy, pll); - if (ret) { - dev_err(uphy->dev, - "Failed the PHY PLL override configuration\n"); - return ret; - } - } - if (phy->misc_config) { - ret = configure_phy_regs(uphy, misc); - if (ret) { - dev_err(uphy->dev, "Failed the misc PHY configuration\n"); - return ret; - } - } - writel_relaxed(0x03, phy->base + phy->phy_reg[USB3_PHY_START]); writel_relaxed(0x00, phy->base + phy->phy_reg[USB3_PHY_SW_RESET]); - /* Wait for PHY initialization to be done */ do { if (readl_relaxed(phy->base + @@ -939,29 +652,34 @@ static int msm_ssphy_qmp_probe(struct platform_device *pdev) return PTR_ERR(phy->vls_clamp_reg); } - of_get_property(dev->of_node, "qcom,qmp-phy-init-seq", &size); - if (size) { - if (size % sizeof(*phy->qmp_phy_init_seq)) { - dev_err(dev, "invalid init_seq_len\n"); - return -EINVAL; - } - phy->qmp_phy_init_seq = devm_kzalloc(dev, - size, GFP_KERNEL); - if (phy->qmp_phy_init_seq) { - phy->init_seq_len = - (size / sizeof(*phy->qmp_phy_init_seq)); - - of_property_read_u32_array(dev->of_node, - "qcom,qmp-phy-init-seq", - phy->qmp_phy_init_seq, - phy->init_seq_len); - } else { - dev_err(dev, "error allocating memory for phy_init_seq\n"); - } - } - phy->emulation = of_property_read_bool(dev->of_node, "qcom,emulation"); + if (!phy->emulation) { + of_get_property(dev->of_node, "qcom,qmp-phy-init-seq", &size); + if (size) { + if (size % sizeof(*phy->qmp_phy_init_seq)) { + dev_err(dev, "invalid init_seq_len\n"); + return -EINVAL; + } + phy->qmp_phy_init_seq = devm_kzalloc(dev, + size, GFP_KERNEL); + if (phy->qmp_phy_init_seq) { + phy->init_seq_len = + (size / sizeof(*phy->qmp_phy_init_seq)); + + of_property_read_u32_array(dev->of_node, + "qcom,qmp-phy-init-seq", + phy->qmp_phy_init_seq, + phy->init_seq_len); + } else { + dev_err(dev, "error allocating memory for phy_init_seq\n"); + return -EINVAL; + } + } else { + dev_err(dev, "error need qmp-phy-init-seq\n"); + return -EINVAL; + } + } ret = of_property_read_u32_array(dev->of_node, "qcom,vdd-voltage-level", (u32 *) phy->vdd_levels,