diff options
Diffstat (limited to 'drivers/phy')
-rw-r--r-- | drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c | 146 | ||||
-rw-r--r-- | drivers/phy/qualcomm/phy-qcom-m31.c | 59 | ||||
-rw-r--r-- | drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v4.h | 17 | ||||
-rw-r--r-- | drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 142 | ||||
-rw-r--r-- | drivers/phy/qualcomm/phy-qcom-qmp-usb.c | 225 | ||||
-rw-r--r-- | drivers/phy/qualcomm/phy-qcom-qmp.h | 8 |
6 files changed, 431 insertions, 166 deletions
diff --git a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c index 52c275fbb2a1..a623f092b11f 100644 --- a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c +++ b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c @@ -24,23 +24,73 @@ #define EUSB2_FORCE_VAL_5 0xeD #define V_CLK_19P2M_EN BIT(6) +#define EUSB2_TUNE_USB2_CROSSOVER 0x50 #define EUSB2_TUNE_IUSB2 0x51 +#define EUSB2_TUNE_RES_FSDIF 0x52 +#define EUSB2_TUNE_HSDISC 0x53 #define EUSB2_TUNE_SQUELCH_U 0x54 +#define EUSB2_TUNE_USB2_SLEW 0x55 +#define EUSB2_TUNE_USB2_EQU 0x56 #define EUSB2_TUNE_USB2_PREEM 0x57 +#define EUSB2_TUNE_USB2_HS_COMP_CUR 0x58 +#define EUSB2_TUNE_EUSB_SLEW 0x59 +#define EUSB2_TUNE_EUSB_EQU 0x5A +#define EUSB2_TUNE_EUSB_HS_COMP_CUR 0x5B -#define QCOM_EUSB2_REPEATER_INIT_CFG(o, v) \ +#define QCOM_EUSB2_REPEATER_INIT_CFG(r, v) \ { \ - .offset = o, \ + .reg = r, \ .val = v, \ } -struct eusb2_repeater_init_tbl { - unsigned int offset; - unsigned int val; +enum reg_fields { + F_TUNE_EUSB_HS_COMP_CUR, + F_TUNE_EUSB_EQU, + F_TUNE_EUSB_SLEW, + F_TUNE_USB2_HS_COMP_CUR, + F_TUNE_USB2_PREEM, + F_TUNE_USB2_EQU, + F_TUNE_USB2_SLEW, + F_TUNE_SQUELCH_U, + F_TUNE_HSDISC, + F_TUNE_RES_FSDIF, + F_TUNE_IUSB2, + F_TUNE_USB2_CROSSOVER, + F_NUM_TUNE_FIELDS, + + F_FORCE_VAL_5 = F_NUM_TUNE_FIELDS, + F_FORCE_EN_5, + + F_EN_CTL1, + + F_RPTR_STATUS, + F_NUM_FIELDS, +}; + +static struct reg_field eusb2_repeater_tune_reg_fields[F_NUM_FIELDS] = { + [F_TUNE_EUSB_HS_COMP_CUR] = REG_FIELD(EUSB2_TUNE_EUSB_HS_COMP_CUR, 0, 1), + [F_TUNE_EUSB_EQU] = REG_FIELD(EUSB2_TUNE_EUSB_EQU, 0, 1), + [F_TUNE_EUSB_SLEW] = REG_FIELD(EUSB2_TUNE_EUSB_SLEW, 0, 1), + [F_TUNE_USB2_HS_COMP_CUR] = REG_FIELD(EUSB2_TUNE_USB2_HS_COMP_CUR, 0, 1), + [F_TUNE_USB2_PREEM] = REG_FIELD(EUSB2_TUNE_USB2_PREEM, 0, 2), + [F_TUNE_USB2_EQU] = REG_FIELD(EUSB2_TUNE_USB2_EQU, 0, 1), + [F_TUNE_USB2_SLEW] = REG_FIELD(EUSB2_TUNE_USB2_SLEW, 0, 1), + [F_TUNE_SQUELCH_U] = REG_FIELD(EUSB2_TUNE_SQUELCH_U, 0, 2), + [F_TUNE_HSDISC] = REG_FIELD(EUSB2_TUNE_HSDISC, 0, 2), + [F_TUNE_RES_FSDIF] = REG_FIELD(EUSB2_TUNE_RES_FSDIF, 0, 2), + [F_TUNE_IUSB2] = REG_FIELD(EUSB2_TUNE_IUSB2, 0, 3), + [F_TUNE_USB2_CROSSOVER] = REG_FIELD(EUSB2_TUNE_USB2_CROSSOVER, 0, 2), + + [F_FORCE_VAL_5] = REG_FIELD(EUSB2_FORCE_VAL_5, 0, 7), + [F_FORCE_EN_5] = REG_FIELD(EUSB2_FORCE_EN_5, 0, 7), + + [F_EN_CTL1] = REG_FIELD(EUSB2_EN_CTL1, 0, 7), + + [F_RPTR_STATUS] = REG_FIELD(EUSB2_RPTR_STATUS, 0, 7), }; struct eusb2_repeater_cfg { - const struct eusb2_repeater_init_tbl *init_tbl; + const u32 *init_tbl; int init_tbl_num; const char * const *vreg_list; int num_vregs; @@ -48,11 +98,10 @@ struct eusb2_repeater_cfg { struct eusb2_repeater { struct device *dev; - struct regmap *regmap; + struct regmap_field *regs[F_NUM_FIELDS]; struct phy *phy; struct regulator_bulk_data *vregs; const struct eusb2_repeater_cfg *cfg; - u16 base; enum phy_mode mode; }; @@ -60,10 +109,10 @@ static const char * const pm8550b_vreg_l[] = { "vdd18", "vdd3", }; -static const struct eusb2_repeater_init_tbl pm8550b_init_tbl[] = { - QCOM_EUSB2_REPEATER_INIT_CFG(EUSB2_TUNE_IUSB2, 0x8), - QCOM_EUSB2_REPEATER_INIT_CFG(EUSB2_TUNE_SQUELCH_U, 0x3), - QCOM_EUSB2_REPEATER_INIT_CFG(EUSB2_TUNE_USB2_PREEM, 0x5), +static const u32 pm8550b_init_tbl[F_NUM_TUNE_FIELDS] = { + [F_TUNE_IUSB2] = 0x8, + [F_TUNE_SQUELCH_U] = 0x3, + [F_TUNE_USB2_PREEM] = 0x5, }; static const struct eusb2_repeater_cfg pm8550b_eusb2_cfg = { @@ -91,9 +140,11 @@ static int eusb2_repeater_init_vregs(struct eusb2_repeater *rptr) static int eusb2_repeater_init(struct phy *phy) { + struct reg_field *regfields = eusb2_repeater_tune_reg_fields; struct eusb2_repeater *rptr = phy_get_drvdata(phy); - const struct eusb2_repeater_init_tbl *init_tbl = rptr->cfg->init_tbl; - int num = rptr->cfg->init_tbl_num; + struct device_node *np = rptr->dev->of_node; + u32 init_tbl[F_NUM_TUNE_FIELDS] = { 0 }; + u8 override; u32 val; int ret; int i; @@ -102,17 +153,34 @@ static int eusb2_repeater_init(struct phy *phy) if (ret) return ret; - regmap_update_bits(rptr->regmap, rptr->base + EUSB2_EN_CTL1, - EUSB2_RPTR_EN, EUSB2_RPTR_EN); + regmap_field_update_bits(rptr->regs[F_EN_CTL1], EUSB2_RPTR_EN, EUSB2_RPTR_EN); - for (i = 0; i < num; i++) - regmap_update_bits(rptr->regmap, - rptr->base + init_tbl[i].offset, - init_tbl[i].val, init_tbl[i].val); + for (i = 0; i < F_NUM_TUNE_FIELDS; i++) { + if (init_tbl[i]) { + regmap_field_update_bits(rptr->regs[i], init_tbl[i], init_tbl[i]); + } else { + /* Write 0 if there's no value set */ + u32 mask = GENMASK(regfields[i].msb, regfields[i].lsb); + + regmap_field_update_bits(rptr->regs[i], mask, 0); + } + } + memcpy(init_tbl, rptr->cfg->init_tbl, sizeof(init_tbl)); + + if (!of_property_read_u8(np, "qcom,tune-usb2-amplitude", &override)) + init_tbl[F_TUNE_IUSB2] = override; + + if (!of_property_read_u8(np, "qcom,tune-usb2-disc-thres", &override)) + init_tbl[F_TUNE_HSDISC] = override; - ret = regmap_read_poll_timeout(rptr->regmap, - rptr->base + EUSB2_RPTR_STATUS, val, - val & RPTR_OK, 10, 5); + if (!of_property_read_u8(np, "qcom,tune-usb2-preem", &override)) + init_tbl[F_TUNE_USB2_PREEM] = override; + + for (i = 0; i < F_NUM_TUNE_FIELDS; i++) + regmap_field_update_bits(rptr->regs[i], init_tbl[i], init_tbl[i]); + + ret = regmap_field_read_poll_timeout(rptr->regs[F_RPTR_STATUS], + val, val & RPTR_OK, 10, 5); if (ret) dev_err(rptr->dev, "initialization timed-out\n"); @@ -131,10 +199,10 @@ static int eusb2_repeater_set_mode(struct phy *phy, * per eUSB 1.2 Spec. Below implement software workaround until * PHY and controller is fixing seen observation. */ - regmap_update_bits(rptr->regmap, rptr->base + EUSB2_FORCE_EN_5, - F_CLK_19P2M_EN, F_CLK_19P2M_EN); - regmap_update_bits(rptr->regmap, rptr->base + EUSB2_FORCE_VAL_5, - V_CLK_19P2M_EN, V_CLK_19P2M_EN); + regmap_field_update_bits(rptr->regs[F_FORCE_EN_5], + F_CLK_19P2M_EN, F_CLK_19P2M_EN); + regmap_field_update_bits(rptr->regs[F_FORCE_VAL_5], + V_CLK_19P2M_EN, V_CLK_19P2M_EN); break; case PHY_MODE_USB_DEVICE: /* @@ -143,10 +211,10 @@ static int eusb2_repeater_set_mode(struct phy *phy, * repeater doesn't clear previous value due to shared * regulators (say host <-> device mode switch). */ - regmap_update_bits(rptr->regmap, rptr->base + EUSB2_FORCE_EN_5, - F_CLK_19P2M_EN, 0); - regmap_update_bits(rptr->regmap, rptr->base + EUSB2_FORCE_VAL_5, - V_CLK_19P2M_EN, 0); + regmap_field_update_bits(rptr->regs[F_FORCE_EN_5], + F_CLK_19P2M_EN, 0); + regmap_field_update_bits(rptr->regs[F_FORCE_VAL_5], + V_CLK_19P2M_EN, 0); break; default: return -EINVAL; @@ -175,8 +243,9 @@ static int eusb2_repeater_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct phy_provider *phy_provider; struct device_node *np = dev->of_node; + struct regmap *regmap; + int i, ret; u32 res; - int ret; rptr = devm_kzalloc(dev, sizeof(*rptr), GFP_KERNEL); if (!rptr) @@ -189,15 +258,22 @@ static int eusb2_repeater_probe(struct platform_device *pdev) if (!rptr->cfg) return -EINVAL; - rptr->regmap = dev_get_regmap(dev->parent, NULL); - if (!rptr->regmap) + regmap = dev_get_regmap(dev->parent, NULL); + if (!regmap) return -ENODEV; ret = of_property_read_u32(np, "reg", &res); if (ret < 0) return ret; - rptr->base = res; + for (i = 0; i < F_NUM_FIELDS; i++) + eusb2_repeater_tune_reg_fields[i].reg += res; + + ret = devm_regmap_field_bulk_alloc(dev, regmap, rptr->regs, + eusb2_repeater_tune_reg_fields, + F_NUM_FIELDS); + if (ret) + return ret; ret = eusb2_repeater_init_vregs(rptr); if (ret < 0) { diff --git a/drivers/phy/qualcomm/phy-qcom-m31.c b/drivers/phy/qualcomm/phy-qcom-m31.c index 5cb7e79b99b3..c2590579190a 100644 --- a/drivers/phy/qualcomm/phy-qcom-m31.c +++ b/drivers/phy/qualcomm/phy-qcom-m31.c @@ -82,6 +82,50 @@ struct m31_priv_data { unsigned int nregs; }; +static const struct m31_phy_regs m31_ipq5018_regs[] = { + { + .off = USB_PHY_CFG0, + .val = UTMI_PHY_OVERRIDE_EN + }, + { + .off = USB_PHY_UTMI_CTRL5, + .val = POR_EN, + .delay = 15 + }, + { + .off = USB_PHY_FSEL_SEL, + .val = FREQ_SEL + }, + { + .off = USB_PHY_HS_PHY_CTRL_COMMON0, + .val = COMMONONN | FSEL | RETENABLEN + }, + { + .off = USB_PHY_REFCLK_CTRL, + .val = CLKCORE + }, + { + .off = USB_PHY_UTMI_CTRL5, + .val = POR_EN + }, + { + .off = USB_PHY_HS_PHY_CTRL2, + .val = USB2_SUSPEND_N_SEL | USB2_SUSPEND_N | USB2_UTMI_CLK_EN + }, + { + .off = USB_PHY_UTMI_CTRL5, + .val = 0x0 + }, + { + .off = USB_PHY_HS_PHY_CTRL2, + .val = USB2_SUSPEND_N | USB2_UTMI_CLK_EN + }, + { + .off = USB_PHY_CFG0, + .val = 0x0 + }, +}; + static struct m31_phy_regs m31_ipq5332_regs[] = { { USB_PHY_CFG0, @@ -241,7 +285,7 @@ static int m31usb_phy_probe(struct platform_device *pdev) qphy->clk = devm_clk_get(dev, NULL); if (IS_ERR(qphy->clk)) return dev_err_probe(dev, PTR_ERR(qphy->clk), - "failed to get clk\n"); + "failed to get clk\n"); data = of_device_get_match_data(dev); qphy->regs = data->regs; @@ -251,12 +295,12 @@ static int m31usb_phy_probe(struct platform_device *pdev) qphy->phy = devm_phy_create(dev, NULL, &m31usb_phy_gen_ops); if (IS_ERR(qphy->phy)) return dev_err_probe(dev, PTR_ERR(qphy->phy), - "failed to create phy\n"); + "failed to create phy\n"); qphy->vreg = devm_regulator_get(dev, "vdda-phy"); if (IS_ERR(qphy->vreg)) - return dev_err_probe(dev, PTR_ERR(qphy->vreg), - "failed to get vreg\n"); + return dev_err_probe(dev, PTR_ERR(qphy->phy), + "failed to get vreg\n"); phy_set_drvdata(qphy->phy, qphy); @@ -267,6 +311,12 @@ static int m31usb_phy_probe(struct platform_device *pdev) return PTR_ERR_OR_ZERO(phy_provider); } +static const struct m31_priv_data m31_ipq5018_data = { + .ulpi_mode = false, + .regs = m31_ipq5018_regs, + .nregs = ARRAY_SIZE(m31_ipq5018_regs), +}; + static const struct m31_priv_data m31_ipq5332_data = { .ulpi_mode = false, .regs = m31_ipq5332_regs, @@ -274,6 +324,7 @@ static const struct m31_priv_data m31_ipq5332_data = { }; static const struct of_device_id m31usb_phy_id_table[] = { + { .compatible = "qcom,ipq5018-usb-hsphy", .data = &m31_ipq5018_data }, { .compatible = "qcom,ipq5332-usb-hsphy", .data = &m31_ipq5332_data }, { }, }; diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v4.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v4.h new file mode 100644 index 000000000000..e256a089f228 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v4.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_PCS_MISC_V4_H_ +#define QCOM_PHY_QMP_PCS_MISC_V4_H_ + +/* Only for QMP V4 PHY - PCS_MISC registers */ +#define QPHY_V4_PCS_MISC_TYPEC_CTRL 0x00 +#define QPHY_V4_PCS_MISC_TYPEC_PWRDN_CTRL 0x04 +#define QPHY_V4_PCS_MISC_PCS_MISC_CONFIG1 0x08 +#define QPHY_V4_PCS_MISC_CLAMP_ENABLE 0x0c +#define QPHY_V4_PCS_MISC_TYPEC_STATUS 0x10 +#define QPHY_V4_PCS_MISC_PLACEHOLDER_STATUS 0x14 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c index 3927eba8e468..514fa14df634 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c @@ -177,6 +177,111 @@ static const struct qmp_phy_init_tbl msm8996_ufsphy_rx[] = { 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), @@ -888,6 +993,40 @@ static const struct qmp_phy_cfg sa8775p_ufsphy_cfg = { .regs = ufsphy_v5_regs_layout, }; +static const struct qmp_phy_cfg sc7280_ufsphy_cfg = { + .lanes = 2, + + .offsets = &qmp_ufs_offsets, + + .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_g4 = { + .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), + }, + .clk_list = sm8450_ufs_phy_clk_l, + .num_clks = ARRAY_SIZE(sm8450_ufs_phy_clk_l), + .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, @@ -1649,6 +1788,9 @@ static const struct of_device_id qmp_ufs_of_match_table[] = { .compatible = "qcom,sa8775p-qmp-ufs-phy", .data = &sa8775p_ufsphy_cfg, }, { + .compatible = "qcom,sc7280-qmp-ufs-phy", + .data = &sc7280_ufsphy_cfg, + }, { .compatible = "qcom,sc8180x-qmp-ufs-phy", .data = &sm8150_ufsphy_cfg, }, { diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c index c69577601ae0..02f156298e77 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c @@ -21,6 +21,7 @@ #include "phy-qcom-qmp.h" #include "phy-qcom-qmp-pcs-misc-v3.h" +#include "phy-qcom-qmp-pcs-misc-v4.h" #include "phy-qcom-qmp-pcs-usb-v4.h" #include "phy-qcom-qmp-pcs-usb-v5.h" @@ -94,6 +95,7 @@ enum qphy_reg_layout { QPHY_PCS_AUTONOMOUS_MODE_CTRL, QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR, QPHY_PCS_POWER_DOWN_CONTROL, + QPHY_PCS_MISC_CLAMP_ENABLE, /* Keep last to ensure regs_layout arrays are properly initialized */ QPHY_LAYOUT_SIZE }; @@ -114,6 +116,16 @@ static const unsigned int qmp_v3_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V3_PCS_AUTONOMOUS_MODE_CTRL, [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V3_PCS_LFPS_RXTERM_IRQ_CLEAR, [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V3_PCS_POWER_DOWN_CONTROL, + [QPHY_PCS_MISC_CLAMP_ENABLE] = QPHY_V3_PCS_MISC_CLAMP_ENABLE, +}; + +static const unsigned int qmp_v3_usb3phy_regs_layout_qcm2290[QPHY_LAYOUT_SIZE] = { + [QPHY_SW_RESET] = QPHY_V3_PCS_SW_RESET, + [QPHY_START_CTRL] = QPHY_V3_PCS_START_CONTROL, + [QPHY_PCS_STATUS] = QPHY_V3_PCS_PCS_STATUS, + [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V3_PCS_AUTONOMOUS_MODE_CTRL, + [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V3_PCS_LFPS_RXTERM_IRQ_CLEAR, + [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V3_PCS_POWER_DOWN_CONTROL, }; static const unsigned int qmp_v4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { @@ -125,6 +137,7 @@ static const unsigned int qmp_v4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { /* In PCS_USB */ [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V4_PCS_USB3_AUTONOMOUS_MODE_CTRL, [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V4_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR, + [QPHY_PCS_MISC_CLAMP_ENABLE] = QPHY_V4_PCS_MISC_CLAMP_ENABLE, }; static const unsigned int qmp_v5_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { @@ -1178,12 +1191,6 @@ struct qmp_phy_cfg { const struct qmp_phy_init_tbl *pcs_usb_tbl; int pcs_usb_tbl_num; - /* clock ids to be requested */ - const char * const *clk_list; - int num_clks; - /* resets to be requested */ - const char * const *reset_list; - int num_resets; /* regulators to be requested */ const char * const *vreg_list; int num_vregs; @@ -1214,6 +1221,8 @@ struct qmp_usb { struct clk *pipe_clk; struct clk_bulk_data *clks; + int num_clks; + int num_resets; struct reset_control_bulk_data *resets; struct regulator_bulk_data *vregs; @@ -1249,37 +1258,16 @@ static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val) } /* list of clocks required by phy */ -static const char * const msm8996_phy_clk_l[] = { - "aux", "cfg_ahb", "ref", -}; - -static const char * const qmp_v3_phy_clk_l[] = { +static const char * const qmp_usb_phy_clk_l[] = { "aux", "cfg_ahb", "ref", "com_aux", }; -static const char * const qmp_v4_phy_clk_l[] = { - "aux", "ref", "com_aux", -}; - -static const char * const qmp_v4_ref_phy_clk_l[] = { - "aux", "ref_clk_src", "ref", "com_aux", -}; - -/* usb3 phy on sdx55 doesn't have com_aux clock */ -static const char * const qmp_v4_sdx55_usbphy_clk_l[] = { - "aux", "cfg_ahb", "ref" -}; - -static const char * const qcm2290_usb3phy_clk_l[] = { - "cfg_ahb", "ref", "com_aux", -}; - /* list of resets */ -static const char * const msm8996_usb3phy_reset_l[] = { +static const char * const usb3phy_legacy_reset_l[] = { "phy", "common", }; -static const char * const qcm2290_usb3phy_reset_l[] = { +static const char * const usb3phy_reset_l[] = { "phy_phy", "phy", }; @@ -1298,6 +1286,13 @@ static const struct qmp_usb_offsets qmp_usb_offsets_ipq9574 = { static const struct qmp_usb_offsets qmp_usb_offsets_v3 = { .serdes = 0, + .pcs = 0x600, + .tx = 0x200, + .rx = 0x400, +}; + +static const struct qmp_usb_offsets qmp_usb_offsets_v3_qcm2290 = { + .serdes = 0x0, .pcs = 0xc00, .pcs_misc = 0xa00, .tx = 0x200, @@ -1306,6 +1301,14 @@ static const struct qmp_usb_offsets qmp_usb_offsets_v3 = { .rx2 = 0x800, }; +static const struct qmp_usb_offsets qmp_usb_offsets_v4 = { + .serdes = 0, + .pcs = 0x0800, + .pcs_usb = 0x0e00, + .tx = 0x0200, + .rx = 0x0400, +}; + static const struct qmp_usb_offsets qmp_usb_offsets_v5 = { .serdes = 0, .pcs = 0x0200, @@ -1317,6 +1320,8 @@ static const struct qmp_usb_offsets qmp_usb_offsets_v5 = { static const struct qmp_phy_cfg ipq8074_usb3phy_cfg = { .lanes = 1, + .offsets = &qmp_usb_offsets_v3, + .serdes_tbl = ipq8074_usb3_serdes_tbl, .serdes_tbl_num = ARRAY_SIZE(ipq8074_usb3_serdes_tbl), .tx_tbl = msm8996_usb3_tx_tbl, @@ -1325,10 +1330,6 @@ static const struct qmp_phy_cfg ipq8074_usb3phy_cfg = { .rx_tbl_num = ARRAY_SIZE(ipq8074_usb3_rx_tbl), .pcs_tbl = ipq8074_usb3_pcs_tbl, .pcs_tbl_num = ARRAY_SIZE(ipq8074_usb3_pcs_tbl), - .clk_list = msm8996_phy_clk_l, - .num_clks = ARRAY_SIZE(msm8996_phy_clk_l), - .reset_list = msm8996_usb3phy_reset_l, - .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), .vreg_list = qmp_phy_vreg_l, .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), .regs = qmp_v3_usb3phy_regs_layout, @@ -1347,10 +1348,6 @@ static const struct qmp_phy_cfg ipq9574_usb3phy_cfg = { .rx_tbl_num = ARRAY_SIZE(ipq9574_usb3_rx_tbl), .pcs_tbl = ipq9574_usb3_pcs_tbl, .pcs_tbl_num = ARRAY_SIZE(ipq9574_usb3_pcs_tbl), - .clk_list = msm8996_phy_clk_l, - .num_clks = ARRAY_SIZE(msm8996_phy_clk_l), - .reset_list = qcm2290_usb3phy_reset_l, - .num_resets = ARRAY_SIZE(qcm2290_usb3phy_reset_l), .vreg_list = qmp_phy_vreg_l, .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), .regs = qmp_v3_usb3phy_regs_layout, @@ -1359,6 +1356,8 @@ static const struct qmp_phy_cfg ipq9574_usb3phy_cfg = { static const struct qmp_phy_cfg msm8996_usb3phy_cfg = { .lanes = 1, + .offsets = &qmp_usb_offsets_v3, + .serdes_tbl = msm8996_usb3_serdes_tbl, .serdes_tbl_num = ARRAY_SIZE(msm8996_usb3_serdes_tbl), .tx_tbl = msm8996_usb3_tx_tbl, @@ -1367,10 +1366,6 @@ static const struct qmp_phy_cfg msm8996_usb3phy_cfg = { .rx_tbl_num = ARRAY_SIZE(msm8996_usb3_rx_tbl), .pcs_tbl = msm8996_usb3_pcs_tbl, .pcs_tbl_num = ARRAY_SIZE(msm8996_usb3_pcs_tbl), - .clk_list = msm8996_phy_clk_l, - .num_clks = ARRAY_SIZE(msm8996_phy_clk_l), - .reset_list = msm8996_usb3phy_reset_l, - .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), .vreg_list = qmp_phy_vreg_l, .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), .regs = qmp_v2_usb3phy_regs_layout, @@ -1391,10 +1386,6 @@ static const struct qmp_phy_cfg sa8775p_usb3_uniphy_cfg = { .pcs_tbl_num = ARRAY_SIZE(sa8775p_usb3_uniphy_pcs_tbl), .pcs_usb_tbl = sa8775p_usb3_uniphy_pcs_usb_tbl, .pcs_usb_tbl_num = ARRAY_SIZE(sa8775p_usb3_uniphy_pcs_usb_tbl), - .clk_list = qmp_v4_phy_clk_l, - .num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l), - .reset_list = qcm2290_usb3phy_reset_l, - .num_resets = ARRAY_SIZE(qcm2290_usb3phy_reset_l), .vreg_list = qmp_phy_vreg_l, .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), .regs = qmp_v5_usb3phy_regs_layout, @@ -1415,10 +1406,6 @@ static const struct qmp_phy_cfg sc8280xp_usb3_uniphy_cfg = { .pcs_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_pcs_tbl), .pcs_usb_tbl = sc8280xp_usb3_uniphy_pcs_usb_tbl, .pcs_usb_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_pcs_usb_tbl), - .clk_list = qmp_v4_phy_clk_l, - .num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l), - .reset_list = qcm2290_usb3phy_reset_l, - .num_resets = ARRAY_SIZE(qcm2290_usb3phy_reset_l), .vreg_list = qmp_phy_vreg_l, .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), .regs = qmp_v5_usb3phy_regs_layout, @@ -1427,6 +1414,8 @@ static const struct qmp_phy_cfg sc8280xp_usb3_uniphy_cfg = { static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = { .lanes = 1, + .offsets = &qmp_usb_offsets_v3, + .serdes_tbl = qmp_v3_usb3_uniphy_serdes_tbl, .serdes_tbl_num = ARRAY_SIZE(qmp_v3_usb3_uniphy_serdes_tbl), .tx_tbl = qmp_v3_usb3_uniphy_tx_tbl, @@ -1435,10 +1424,6 @@ static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = { .rx_tbl_num = ARRAY_SIZE(qmp_v3_usb3_uniphy_rx_tbl), .pcs_tbl = qmp_v3_usb3_uniphy_pcs_tbl, .pcs_tbl_num = ARRAY_SIZE(qmp_v3_usb3_uniphy_pcs_tbl), - .clk_list = qmp_v3_phy_clk_l, - .num_clks = ARRAY_SIZE(qmp_v3_phy_clk_l), - .reset_list = msm8996_usb3phy_reset_l, - .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), .vreg_list = qmp_phy_vreg_l, .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), .regs = qmp_v3_usb3phy_regs_layout, @@ -1449,6 +1434,8 @@ static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = { static const struct qmp_phy_cfg msm8998_usb3phy_cfg = { .lanes = 2, + .offsets = &qmp_usb_offsets_v3_qcm2290, + .serdes_tbl = msm8998_usb3_serdes_tbl, .serdes_tbl_num = ARRAY_SIZE(msm8998_usb3_serdes_tbl), .tx_tbl = msm8998_usb3_tx_tbl, @@ -1457,10 +1444,6 @@ static const struct qmp_phy_cfg msm8998_usb3phy_cfg = { .rx_tbl_num = ARRAY_SIZE(msm8998_usb3_rx_tbl), .pcs_tbl = msm8998_usb3_pcs_tbl, .pcs_tbl_num = ARRAY_SIZE(msm8998_usb3_pcs_tbl), - .clk_list = msm8996_phy_clk_l, - .num_clks = ARRAY_SIZE(msm8996_phy_clk_l), - .reset_list = msm8996_usb3phy_reset_l, - .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), .vreg_list = qmp_phy_vreg_l, .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), .regs = qmp_v3_usb3phy_regs_layout, @@ -1469,6 +1452,8 @@ static const struct qmp_phy_cfg msm8998_usb3phy_cfg = { static const struct qmp_phy_cfg sm8150_usb3_uniphy_cfg = { .lanes = 1, + .offsets = &qmp_usb_offsets_v4, + .serdes_tbl = sm8150_usb3_uniphy_serdes_tbl, .serdes_tbl_num = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl), .tx_tbl = sm8150_usb3_uniphy_tx_tbl, @@ -1479,10 +1464,6 @@ static const struct qmp_phy_cfg sm8150_usb3_uniphy_cfg = { .pcs_tbl_num = ARRAY_SIZE(sm8150_usb3_uniphy_pcs_tbl), .pcs_usb_tbl = sm8150_usb3_uniphy_pcs_usb_tbl, .pcs_usb_tbl_num = ARRAY_SIZE(sm8150_usb3_uniphy_pcs_usb_tbl), - .clk_list = qmp_v4_ref_phy_clk_l, - .num_clks = ARRAY_SIZE(qmp_v4_ref_phy_clk_l), - .reset_list = msm8996_usb3phy_reset_l, - .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), .vreg_list = qmp_phy_vreg_l, .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), .regs = qmp_v4_usb3phy_regs_layout, @@ -1494,6 +1475,8 @@ static const struct qmp_phy_cfg sm8150_usb3_uniphy_cfg = { static const struct qmp_phy_cfg sm8250_usb3_uniphy_cfg = { .lanes = 1, + .offsets = &qmp_usb_offsets_v4, + .serdes_tbl = sm8150_usb3_uniphy_serdes_tbl, .serdes_tbl_num = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl), .tx_tbl = sm8250_usb3_uniphy_tx_tbl, @@ -1504,10 +1487,6 @@ static const struct qmp_phy_cfg sm8250_usb3_uniphy_cfg = { .pcs_tbl_num = ARRAY_SIZE(sm8250_usb3_uniphy_pcs_tbl), .pcs_usb_tbl = sm8250_usb3_uniphy_pcs_usb_tbl, .pcs_usb_tbl_num = ARRAY_SIZE(sm8250_usb3_uniphy_pcs_usb_tbl), - .clk_list = qmp_v4_ref_phy_clk_l, - .num_clks = ARRAY_SIZE(qmp_v4_ref_phy_clk_l), - .reset_list = msm8996_usb3phy_reset_l, - .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), .vreg_list = qmp_phy_vreg_l, .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), .regs = qmp_v4_usb3phy_regs_layout, @@ -1519,6 +1498,8 @@ static const struct qmp_phy_cfg sm8250_usb3_uniphy_cfg = { static const struct qmp_phy_cfg sdx55_usb3_uniphy_cfg = { .lanes = 1, + .offsets = &qmp_usb_offsets_v4, + .serdes_tbl = sm8150_usb3_uniphy_serdes_tbl, .serdes_tbl_num = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl), .tx_tbl = sdx55_usb3_uniphy_tx_tbl, @@ -1529,10 +1510,6 @@ static const struct qmp_phy_cfg sdx55_usb3_uniphy_cfg = { .pcs_tbl_num = ARRAY_SIZE(sm8250_usb3_uniphy_pcs_tbl), .pcs_usb_tbl = sm8250_usb3_uniphy_pcs_usb_tbl, .pcs_usb_tbl_num = ARRAY_SIZE(sm8250_usb3_uniphy_pcs_usb_tbl), - .clk_list = qmp_v4_sdx55_usbphy_clk_l, - .num_clks = ARRAY_SIZE(qmp_v4_sdx55_usbphy_clk_l), - .reset_list = msm8996_usb3phy_reset_l, - .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), .vreg_list = qmp_phy_vreg_l, .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), .regs = qmp_v4_usb3phy_regs_layout, @@ -1544,6 +1521,8 @@ static const struct qmp_phy_cfg sdx55_usb3_uniphy_cfg = { static const struct qmp_phy_cfg sdx65_usb3_uniphy_cfg = { .lanes = 1, + .offsets = &qmp_usb_offsets_v5, + .serdes_tbl = sm8150_usb3_uniphy_serdes_tbl, .serdes_tbl_num = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl), .tx_tbl = sdx65_usb3_uniphy_tx_tbl, @@ -1554,10 +1533,6 @@ static const struct qmp_phy_cfg sdx65_usb3_uniphy_cfg = { .pcs_tbl_num = ARRAY_SIZE(sm8350_usb3_uniphy_pcs_tbl), .pcs_usb_tbl = sm8350_usb3_uniphy_pcs_usb_tbl, .pcs_usb_tbl_num = ARRAY_SIZE(sm8350_usb3_uniphy_pcs_usb_tbl), - .clk_list = qmp_v4_sdx55_usbphy_clk_l, - .num_clks = ARRAY_SIZE(qmp_v4_sdx55_usbphy_clk_l), - .reset_list = msm8996_usb3phy_reset_l, - .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), .vreg_list = qmp_phy_vreg_l, .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), .regs = qmp_v5_usb3phy_regs_layout, @@ -1569,6 +1544,8 @@ static const struct qmp_phy_cfg sdx65_usb3_uniphy_cfg = { static const struct qmp_phy_cfg sm8350_usb3_uniphy_cfg = { .lanes = 1, + .offsets = &qmp_usb_offsets_v5, + .serdes_tbl = sm8150_usb3_uniphy_serdes_tbl, .serdes_tbl_num = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl), .tx_tbl = sm8350_usb3_uniphy_tx_tbl, @@ -1579,10 +1556,6 @@ static const struct qmp_phy_cfg sm8350_usb3_uniphy_cfg = { .pcs_tbl_num = ARRAY_SIZE(sm8350_usb3_uniphy_pcs_tbl), .pcs_usb_tbl = sm8350_usb3_uniphy_pcs_usb_tbl, .pcs_usb_tbl_num = ARRAY_SIZE(sm8350_usb3_uniphy_pcs_usb_tbl), - .clk_list = qmp_v4_ref_phy_clk_l, - .num_clks = ARRAY_SIZE(qmp_v4_ref_phy_clk_l), - .reset_list = msm8996_usb3phy_reset_l, - .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), .vreg_list = qmp_phy_vreg_l, .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), .regs = qmp_v5_usb3phy_regs_layout, @@ -1594,7 +1567,7 @@ static const struct qmp_phy_cfg sm8350_usb3_uniphy_cfg = { static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = { .lanes = 2, - .offsets = &qmp_usb_offsets_v3, + .offsets = &qmp_usb_offsets_v3_qcm2290, .serdes_tbl = qcm2290_usb3_serdes_tbl, .serdes_tbl_num = ARRAY_SIZE(qcm2290_usb3_serdes_tbl), @@ -1604,13 +1577,9 @@ static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = { .rx_tbl_num = ARRAY_SIZE(qcm2290_usb3_rx_tbl), .pcs_tbl = qcm2290_usb3_pcs_tbl, .pcs_tbl_num = ARRAY_SIZE(qcm2290_usb3_pcs_tbl), - .clk_list = qcm2290_usb3phy_clk_l, - .num_clks = ARRAY_SIZE(qcm2290_usb3phy_clk_l), - .reset_list = qcm2290_usb3phy_reset_l, - .num_resets = ARRAY_SIZE(qcm2290_usb3phy_reset_l), .vreg_list = qmp_phy_vreg_l, .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), - .regs = qmp_v3_usb3phy_regs_layout, + .regs = qmp_v3_usb3phy_regs_layout_qcm2290, }; static void qmp_usb_configure_lane(void __iomem *base, @@ -1664,19 +1633,19 @@ static int qmp_usb_init(struct phy *phy) return ret; } - ret = reset_control_bulk_assert(cfg->num_resets, qmp->resets); + ret = reset_control_bulk_assert(qmp->num_resets, qmp->resets); if (ret) { dev_err(qmp->dev, "reset assert failed\n"); goto err_disable_regulators; } - ret = reset_control_bulk_deassert(cfg->num_resets, qmp->resets); + ret = reset_control_bulk_deassert(qmp->num_resets, qmp->resets); if (ret) { dev_err(qmp->dev, "reset deassert failed\n"); goto err_disable_regulators; } - ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks); + ret = clk_bulk_prepare_enable(qmp->num_clks, qmp->clks); if (ret) goto err_assert_reset; @@ -1685,7 +1654,7 @@ static int qmp_usb_init(struct phy *phy) return 0; err_assert_reset: - reset_control_bulk_assert(cfg->num_resets, qmp->resets); + reset_control_bulk_assert(qmp->num_resets, qmp->resets); err_disable_regulators: regulator_bulk_disable(cfg->num_vregs, qmp->vregs); @@ -1697,9 +1666,9 @@ static int qmp_usb_exit(struct phy *phy) struct qmp_usb *qmp = phy_get_drvdata(phy); const struct qmp_phy_cfg *cfg = qmp->cfg; - reset_control_bulk_assert(cfg->num_resets, qmp->resets); + reset_control_bulk_assert(qmp->num_resets, qmp->resets); - clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks); + clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks); regulator_bulk_disable(cfg->num_vregs, qmp->vregs); @@ -1852,8 +1821,8 @@ static void qmp_usb_enable_autonomous_mode(struct qmp_usb *qmp) qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask); /* Enable i/o clamp_n for autonomous mode */ - if (pcs_misc) - qphy_clrbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN); + if (pcs_misc && cfg->regs[QPHY_PCS_MISC_CLAMP_ENABLE]) + qphy_clrbits(pcs_misc, cfg->regs[QPHY_PCS_MISC_CLAMP_ENABLE], CLAMP_EN); } static void qmp_usb_disable_autonomous_mode(struct qmp_usb *qmp) @@ -1863,8 +1832,8 @@ static void qmp_usb_disable_autonomous_mode(struct qmp_usb *qmp) void __iomem *pcs_misc = qmp->pcs_misc; /* Disable i/o clamp_n on resume for normal mode */ - if (pcs_misc) - qphy_setbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN); + if (pcs_misc && cfg->regs[QPHY_PCS_MISC_CLAMP_ENABLE]) + qphy_setbits(pcs_misc, cfg->regs[QPHY_PCS_MISC_CLAMP_ENABLE], CLAMP_EN); qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL | ALFPS_DTCT_EN); @@ -1877,7 +1846,6 @@ static void qmp_usb_disable_autonomous_mode(struct qmp_usb *qmp) static int __maybe_unused qmp_usb_runtime_suspend(struct device *dev) { struct qmp_usb *qmp = dev_get_drvdata(dev); - const struct qmp_phy_cfg *cfg = qmp->cfg; dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode); @@ -1889,7 +1857,7 @@ static int __maybe_unused qmp_usb_runtime_suspend(struct device *dev) qmp_usb_enable_autonomous_mode(qmp); clk_disable_unprepare(qmp->pipe_clk); - clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks); + clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks); return 0; } @@ -1897,7 +1865,6 @@ static int __maybe_unused qmp_usb_runtime_suspend(struct device *dev) static int __maybe_unused qmp_usb_runtime_resume(struct device *dev) { struct qmp_usb *qmp = dev_get_drvdata(dev); - const struct qmp_phy_cfg *cfg = qmp->cfg; int ret = 0; dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode); @@ -1907,14 +1874,14 @@ static int __maybe_unused qmp_usb_runtime_resume(struct device *dev) return 0; } - ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks); + ret = clk_bulk_prepare_enable(qmp->num_clks, qmp->clks); if (ret) return ret; ret = clk_prepare_enable(qmp->pipe_clk); if (ret) { dev_err(dev, "pipe_clk enable failed, err=%d\n", ret); - clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks); + clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks); return ret; } @@ -1945,22 +1912,25 @@ static int qmp_usb_vreg_init(struct qmp_usb *qmp) return devm_regulator_bulk_get(dev, num, qmp->vregs); } -static int qmp_usb_reset_init(struct qmp_usb *qmp) +static int qmp_usb_reset_init(struct qmp_usb *qmp, + const char *const *reset_list, + int num_resets) { - const struct qmp_phy_cfg *cfg = qmp->cfg; struct device *dev = qmp->dev; int i; int ret; - qmp->resets = devm_kcalloc(dev, cfg->num_resets, + qmp->resets = devm_kcalloc(dev, num_resets, sizeof(*qmp->resets), GFP_KERNEL); if (!qmp->resets) return -ENOMEM; - for (i = 0; i < cfg->num_resets; i++) - qmp->resets[i].id = cfg->reset_list[i]; + for (i = 0; i < num_resets; i++) + qmp->resets[i].id = reset_list[i]; + + qmp->num_resets = num_resets; - ret = devm_reset_control_bulk_get_exclusive(dev, cfg->num_resets, qmp->resets); + ret = devm_reset_control_bulk_get_exclusive(dev, num_resets, qmp->resets); if (ret) return dev_err_probe(dev, ret, "failed to get resets\n"); @@ -1969,9 +1939,8 @@ static int qmp_usb_reset_init(struct qmp_usb *qmp) static int qmp_usb_clk_init(struct qmp_usb *qmp) { - const struct qmp_phy_cfg *cfg = qmp->cfg; struct device *dev = qmp->dev; - int num = cfg->num_clks; + int num = ARRAY_SIZE(qmp_usb_phy_clk_l); int i; qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL); @@ -1979,9 +1948,11 @@ static int qmp_usb_clk_init(struct qmp_usb *qmp) return -ENOMEM; for (i = 0; i < num; i++) - qmp->clks[i].id = cfg->clk_list[i]; + qmp->clks[i].id = qmp_usb_phy_clk_l[i]; + + qmp->num_clks = num; - return devm_clk_bulk_get(dev, num, qmp->clks); + return devm_clk_bulk_get_optional(dev, num, qmp->clks); } static void phy_clk_release_provider(void *res) @@ -2061,6 +2032,7 @@ static int qmp_usb_parse_dt_legacy(struct qmp_usb *qmp, struct device_node *np) const struct qmp_phy_cfg *cfg = qmp->cfg; struct device *dev = qmp->dev; bool exclusive = true; + int ret; qmp->serdes = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(qmp->serdes)) @@ -2121,6 +2093,17 @@ static int qmp_usb_parse_dt_legacy(struct qmp_usb *qmp, struct device_node *np) "failed to get pipe clock\n"); } + ret = devm_clk_bulk_get_all(qmp->dev, &qmp->clks); + if (ret < 0) + return ret; + + qmp->num_clks = ret; + + ret = qmp_usb_reset_init(qmp, usb3phy_legacy_reset_l, + ARRAY_SIZE(usb3phy_legacy_reset_l)); + if (ret) + return ret; + return 0; } @@ -2131,6 +2114,7 @@ static int qmp_usb_parse_dt(struct qmp_usb *qmp) const struct qmp_usb_offsets *offs = cfg->offsets; struct device *dev = qmp->dev; void __iomem *base; + int ret; if (!offs) return -EINVAL; @@ -2141,8 +2125,10 @@ static int qmp_usb_parse_dt(struct qmp_usb *qmp) qmp->serdes = base + offs->serdes; qmp->pcs = base + offs->pcs; - qmp->pcs_misc = base + offs->pcs_misc; - qmp->pcs_usb = base + offs->pcs_usb; + if (offs->pcs_usb) + qmp->pcs_usb = base + offs->pcs_usb; + if (offs->pcs_misc) + qmp->pcs_misc = base + offs->pcs_misc; qmp->tx = base + offs->tx; qmp->rx = base + offs->rx; @@ -2151,12 +2137,21 @@ static int qmp_usb_parse_dt(struct qmp_usb *qmp) qmp->rx2 = base + offs->rx2; } + ret = qmp_usb_clk_init(qmp); + if (ret) + return ret; + qmp->pipe_clk = devm_clk_get(dev, "pipe"); if (IS_ERR(qmp->pipe_clk)) { return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk), "failed to get pipe clock\n"); } + ret = qmp_usb_reset_init(qmp, usb3phy_reset_l, + ARRAY_SIZE(usb3phy_reset_l)); + if (ret) + return ret; + return 0; } @@ -2178,14 +2173,6 @@ static int qmp_usb_probe(struct platform_device *pdev) if (!qmp->cfg) return -EINVAL; - ret = qmp_usb_clk_init(qmp); - if (ret) - return ret; - - ret = qmp_usb_reset_init(qmp); - if (ret) - return ret; - ret = qmp_usb_vreg_init(qmp); if (ret) return ret; diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h index 32d897684755..71f063f4a56e 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp.h @@ -126,14 +126,6 @@ #define QSERDES_V4_DP_PHY_AUX_INTERRUPT_STATUS 0x0d8 #define QSERDES_V4_DP_PHY_STATUS 0x0dc -/* Only for QMP V4 PHY - PCS_MISC registers */ -#define QPHY_V4_PCS_MISC_TYPEC_CTRL 0x00 -#define QPHY_V4_PCS_MISC_TYPEC_PWRDN_CTRL 0x04 -#define QPHY_V4_PCS_MISC_PCS_MISC_CONFIG1 0x08 -#define QPHY_V4_PCS_MISC_CLAMP_ENABLE 0x0c -#define QPHY_V4_PCS_MISC_TYPEC_STATUS 0x10 -#define QPHY_V4_PCS_MISC_PLACEHOLDER_STATUS 0x14 - #define QSERDES_V5_DP_PHY_STATUS 0x0dc /* Only for QMP V6 PHY - DP PHY registers */ |