Commit fc646236 authored by Dmitry Baryshkov's avatar Dmitry Baryshkov Committed by Vinod Koul
Browse files

phy: qcom-qmp-combo,usb: add support for separate PCS_USB region



Different QMP USB PHYs might have different offset from PCS to PCS_USB
register space, but the same PCS_USB register layout. Add separate
PCS_USB region space and merge related PCS_USB definitions.

Signed-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://lore.kernel.org/r/20220705094320.1313312-4-dmitry.baryshkov@linaro.org


Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 2eb2920a
Loading
Loading
Loading
Loading
+36 −11
Original line number Diff line number Diff line
@@ -155,8 +155,10 @@ static const unsigned int qmp_v4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
	[QPHY_START_CTRL]		= 0x44,
	[QPHY_PCS_STATUS]		= 0x14,
	[QPHY_PCS_POWER_DOWN_CONTROL]	= 0x40,
	[QPHY_PCS_AUTONOMOUS_MODE_CTRL]	= 0x308,
	[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x314,

	/* In PCS_USB */
	[QPHY_PCS_AUTONOMOUS_MODE_CTRL]	= 0x008,
	[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x014,
};

static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl[] = {
@@ -451,6 +453,9 @@ static const struct qmp_phy_init_tbl sm8150_usb3_pcs_tbl[] = {
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
};

static const struct qmp_phy_init_tbl sm8150_usb3_pcs_usb_tbl[] = {
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
};
@@ -520,6 +525,9 @@ static const struct qmp_phy_init_tbl sm8250_usb3_pcs_tbl[] = {
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
};

static const struct qmp_phy_init_tbl sm8250_usb3_pcs_usb_tbl[] = {
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
};
@@ -634,6 +642,8 @@ struct qmp_phy_cfg {
	int rx_tbl_num;
	const struct qmp_phy_init_tbl *pcs_tbl;
	int pcs_tbl_num;
	const struct qmp_phy_init_tbl *pcs_usb_tbl;
	int pcs_usb_tbl_num;

	/* Init sequence for DP PHY block link rates */
	const struct qmp_phy_init_tbl *serdes_tbl_rbr;
@@ -679,6 +689,10 @@ struct qmp_phy_cfg {
	bool has_phy_dp_com_ctrl;
	/* true, if PHY has secondary tx/rx lanes to be configured */
	bool is_dual_lane_phy;

	/* Offset from PCS to PCS_USB region */
	unsigned int pcs_usb_offset;

};

struct qmp_phy_combo_cfg {
@@ -698,6 +712,7 @@ struct qmp_phy_combo_cfg {
 * @tx2: iomapped memory space for second lane's tx (in dual lane PHYs)
 * @rx2: iomapped memory space for second lane's rx (in dual lane PHYs)
 * @pcs_misc: iomapped memory space for lane's pcs_misc
 * @pcs_usb: iomapped memory space for lane's pcs_usb
 * @pipe_clk: pipe clock
 * @index: lane index
 * @qmp: QMP phy to which this lane belongs
@@ -717,6 +732,7 @@ struct qmp_phy {
	void __iomem *tx2;
	void __iomem *rx2;
	void __iomem *pcs_misc;
	void __iomem *pcs_usb;
	struct clk *pipe_clk;
	unsigned int index;
	struct qcom_qmp *qmp;
@@ -905,6 +921,8 @@ static const struct qmp_phy_cfg sm8150_usb3phy_cfg = {
	.rx_tbl_num		= ARRAY_SIZE(sm8150_usb3_rx_tbl),
	.pcs_tbl		= sm8150_usb3_pcs_tbl,
	.pcs_tbl_num		= ARRAY_SIZE(sm8150_usb3_pcs_tbl),
	.pcs_usb_tbl		= sm8150_usb3_pcs_usb_tbl,
	.pcs_usb_tbl_num	= ARRAY_SIZE(sm8150_usb3_pcs_usb_tbl),
	.clk_list		= qmp_v4_phy_clk_l,
	.num_clks		= ARRAY_SIZE(qmp_v4_phy_clk_l),
	.reset_list		= msm8996_usb3phy_reset_l,
@@ -912,6 +930,7 @@ static const struct qmp_phy_cfg sm8150_usb3phy_cfg = {
	.vreg_list		= qmp_phy_vreg_l,
	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
	.regs			= qmp_v4_usb3phy_regs_layout,
	.pcs_usb_offset		= 0x300,

	.start_ctrl		= SERDES_START | PCS_START,
	.pwrdn_ctrl		= SW_PWRDN,
@@ -978,6 +997,8 @@ static const struct qmp_phy_cfg sm8250_usb3phy_cfg = {
	.rx_tbl_num		= ARRAY_SIZE(sm8250_usb3_rx_tbl),
	.pcs_tbl		= sm8250_usb3_pcs_tbl,
	.pcs_tbl_num		= ARRAY_SIZE(sm8250_usb3_pcs_tbl),
	.pcs_usb_tbl		= sm8250_usb3_pcs_usb_tbl,
	.pcs_usb_tbl_num	= ARRAY_SIZE(sm8250_usb3_pcs_usb_tbl),
	.clk_list		= qmp_v4_sm8250_usbphy_clk_l,
	.num_clks		= ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l),
	.reset_list		= msm8996_usb3phy_reset_l,
@@ -985,6 +1006,7 @@ static const struct qmp_phy_cfg sm8250_usb3phy_cfg = {
	.vreg_list		= qmp_phy_vreg_l,
	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
	.regs			= qmp_v4_usb3phy_regs_layout,
	.pcs_usb_offset		= 0x300,

	.start_ctrl		= SERDES_START | PCS_START,
	.pwrdn_ctrl		= SW_PWRDN,
@@ -1869,7 +1891,7 @@ static int qcom_qmp_phy_combo_set_mode(struct phy *phy,
static void qcom_qmp_phy_combo_enable_autonomous_mode(struct qmp_phy *qphy)
{
	const struct qmp_phy_cfg *cfg = qphy->cfg;
	void __iomem *pcs = qphy->pcs;
	void __iomem *pcs_usb = qphy->pcs_usb ?: qphy->pcs;
	void __iomem *pcs_misc = qphy->pcs_misc;
	u32 intr_mask;

@@ -1880,15 +1902,15 @@ static void qcom_qmp_phy_combo_enable_autonomous_mode(struct qmp_phy *qphy)
		intr_mask = ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL;

	/* Clear any pending interrupts status */
	qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
	qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
	/* Writing 1 followed by 0 clears the interrupt */
	qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
	qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);

	qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
	qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
		     ARCVR_DTCT_EN | ALFPS_DTCT_EN | ARCVR_DTCT_EVENT_SEL);

	/* Enable required PHY autonomous mode interrupts */
	qphy_setbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask);
	qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask);

	/* Enable i/o clamp_n for autonomous mode */
	if (pcs_misc)
@@ -1898,19 +1920,19 @@ static void qcom_qmp_phy_combo_enable_autonomous_mode(struct qmp_phy *qphy)
static void qcom_qmp_phy_combo_disable_autonomous_mode(struct qmp_phy *qphy)
{
	const struct qmp_phy_cfg *cfg = qphy->cfg;
	void __iomem *pcs = qphy->pcs;
	void __iomem *pcs_usb = qphy->pcs_usb ?: qphy->pcs_usb;
	void __iomem *pcs_misc = qphy->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);

	qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
	qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
		     ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL | ALFPS_DTCT_EN);

	qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
	qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
	/* Writing 1 followed by 0 clears the interrupt */
	qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
	qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
}

static int __maybe_unused qcom_qmp_phy_combo_runtime_suspend(struct device *dev)
@@ -2346,6 +2368,9 @@ int qcom_qmp_phy_combo_create(struct device *dev, struct device_node *np, int id
	if (!qphy->pcs)
		return -ENOMEM;

	if (cfg->pcs_usb_offset)
		qphy->pcs_usb = qphy->pcs + cfg->pcs_usb_offset;

	/*
	 * If this is a dual-lane PHY, then there should be registers for the
	 * second lane. Some old device trees did not specify this, so fall
+77 −41
Original line number Diff line number Diff line
@@ -169,26 +169,10 @@ static const unsigned int qmp_v4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
	[QPHY_START_CTRL]		= 0x44,
	[QPHY_PCS_STATUS]		= 0x14,
	[QPHY_PCS_POWER_DOWN_CONTROL]	= 0x40,
	[QPHY_PCS_AUTONOMOUS_MODE_CTRL]	= 0x308,
	[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x314,
};

static const unsigned int qmp_v4_usb3_uniphy_regs_layout[QPHY_LAYOUT_SIZE] = {
	[QPHY_SW_RESET]			= 0x00,
	[QPHY_START_CTRL]		= 0x44,
	[QPHY_PCS_STATUS]		= 0x14,
	[QPHY_PCS_POWER_DOWN_CONTROL]	= 0x40,
	[QPHY_PCS_AUTONOMOUS_MODE_CTRL]	= 0x608,
	[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x614,
};

static const unsigned int sm8350_usb3_uniphy_regs_layout[QPHY_LAYOUT_SIZE] = {
	[QPHY_SW_RESET]			= 0x00,
	[QPHY_START_CTRL]		= 0x44,
	[QPHY_PCS_STATUS]		= 0x14,
	[QPHY_PCS_POWER_DOWN_CONTROL]	= 0x40,
	[QPHY_PCS_AUTONOMOUS_MODE_CTRL]	= 0x1008,
	[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x1014,
	/* In PCS_USB */
	[QPHY_PCS_AUTONOMOUS_MODE_CTRL]	= 0x008,
	[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x014,
};

static const unsigned int qcm2290_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
@@ -777,6 +761,9 @@ static const struct qmp_phy_init_tbl sm8150_usb3_pcs_tbl[] = {
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
};

static const struct qmp_phy_init_tbl sm8150_usb3_pcs_usb_tbl[] = {
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
};
@@ -878,8 +865,6 @@ static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_pcs_tbl[] = {
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_RXEQTRAINING_DFE_TIME_S2, 0x07),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0f),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
@@ -889,6 +874,11 @@ static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_pcs_tbl[] = {
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
};

static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_pcs_usb_tbl[] = {
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
};

static const struct qmp_phy_init_tbl sm8250_usb3_tx_tbl[] = {
	QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_TX, 0x60),
	QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_RX, 0x60),
@@ -954,6 +944,9 @@ static const struct qmp_phy_init_tbl sm8250_usb3_pcs_tbl[] = {
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
};

static const struct qmp_phy_init_tbl sm8250_usb3_pcs_usb_tbl[] = {
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
};
@@ -1015,8 +1008,6 @@ static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_pcs_tbl[] = {
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xa9),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_RXEQTRAINING_DFE_TIME_S2, 0x07),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_UNI_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
@@ -1025,6 +1016,11 @@ static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_pcs_tbl[] = {
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
};

static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_pcs_usb_tbl[] = {
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
};

static const struct qmp_phy_init_tbl sdx55_usb3_uniphy_tx_tbl[] = {
	QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
	QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),
@@ -1171,8 +1167,6 @@ static const struct qmp_phy_init_tbl sm8350_usb3_rx_tbl[] = {
};

static const struct qmp_phy_init_tbl sm8350_usb3_pcs_tbl[] = {
	QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RCVR_DTCT_DLY_U3_L, 0x40),
	QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RCVR_DTCT_DLY_U3_H, 0x00),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
@@ -1187,6 +1181,11 @@ static const struct qmp_phy_init_tbl sm8350_usb3_pcs_tbl[] = {
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
};

static const struct qmp_phy_init_tbl sm8350_usb3_pcs_usb_tbl[] = {
	QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RCVR_DTCT_DLY_U3_L, 0x40),
	QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RCVR_DTCT_DLY_U3_H, 0x00),
	QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
	QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
};
@@ -1244,8 +1243,6 @@ static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_pcs_tbl[] = {
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
	QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_UNI_RXEQTRAINING_DFE_TIME_S2, 0x07),
	QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_UNI_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
@@ -1254,6 +1251,11 @@ static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_pcs_tbl[] = {
	QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
};

static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_pcs_usb_tbl[] = {
	QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
	QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
};

static const struct qmp_phy_init_tbl qcm2290_usb3_serdes_tbl[] = {
	QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
	QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
@@ -1365,6 +1367,8 @@ struct qmp_phy_cfg {
	int rx_tbl_num;
	const struct qmp_phy_init_tbl *pcs_tbl;
	int pcs_tbl_num;
	const struct qmp_phy_init_tbl *pcs_usb_tbl;
	int pcs_usb_tbl_num;

	/* clock ids to be requested */
	const char * const *clk_list;
@@ -1394,6 +1398,9 @@ struct qmp_phy_cfg {
	bool has_phy_dp_com_ctrl;
	/* true, if PHY has secondary tx/rx lanes to be configured */
	bool is_dual_lane_phy;

	/* Offset from PCS to PCS_USB region */
	unsigned int pcs_usb_offset;
};

/**
@@ -1408,6 +1415,7 @@ struct qmp_phy_cfg {
 * @tx2: iomapped memory space for second lane's tx (in dual lane PHYs)
 * @rx2: iomapped memory space for second lane's rx (in dual lane PHYs)
 * @pcs_misc: iomapped memory space for lane's pcs_misc
 * @pcs_usb: iomapped memory space for lane's pcs_usb
 * @pipe_clk: pipe clock
 * @index: lane index
 * @qmp: QMP phy to which this lane belongs
@@ -1423,6 +1431,7 @@ struct qmp_phy {
	void __iomem *tx2;
	void __iomem *rx2;
	void __iomem *pcs_misc;
	void __iomem *pcs_usb;
	struct clk *pipe_clk;
	unsigned int index;
	struct qcom_qmp *qmp;
@@ -1703,6 +1712,8 @@ static const struct qmp_phy_cfg sm8150_usb3phy_cfg = {
	.rx_tbl_num		= ARRAY_SIZE(sm8150_usb3_rx_tbl),
	.pcs_tbl		= sm8150_usb3_pcs_tbl,
	.pcs_tbl_num		= ARRAY_SIZE(sm8150_usb3_pcs_tbl),
	.pcs_usb_tbl		= sm8150_usb3_pcs_usb_tbl,
	.pcs_usb_tbl_num	= ARRAY_SIZE(sm8150_usb3_pcs_usb_tbl),
	.clk_list		= qmp_v4_phy_clk_l,
	.num_clks		= ARRAY_SIZE(qmp_v4_phy_clk_l),
	.reset_list		= msm8996_usb3phy_reset_l,
@@ -1710,6 +1721,7 @@ static const struct qmp_phy_cfg sm8150_usb3phy_cfg = {
	.vreg_list		= qmp_phy_vreg_l,
	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
	.regs			= qmp_v4_usb3phy_regs_layout,
	.pcs_usb_offset		= 0x300,

	.start_ctrl		= SERDES_START | PCS_START,
	.pwrdn_ctrl		= SW_PWRDN,
@@ -1736,13 +1748,16 @@ static const struct qmp_phy_cfg sm8150_usb3_uniphy_cfg = {
	.rx_tbl_num		= ARRAY_SIZE(sm8150_usb3_uniphy_rx_tbl),
	.pcs_tbl		= sm8150_usb3_uniphy_pcs_tbl,
	.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_phy_clk_l,
	.num_clks		= ARRAY_SIZE(qmp_v4_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_usb3_uniphy_regs_layout,
	.regs			= qmp_v4_usb3phy_regs_layout,
	.pcs_usb_offset		= 0x600,

	.start_ctrl		= SERDES_START | PCS_START,
	.pwrdn_ctrl		= SW_PWRDN,
@@ -1765,6 +1780,8 @@ static const struct qmp_phy_cfg sm8250_usb3phy_cfg = {
	.rx_tbl_num		= ARRAY_SIZE(sm8250_usb3_rx_tbl),
	.pcs_tbl		= sm8250_usb3_pcs_tbl,
	.pcs_tbl_num		= ARRAY_SIZE(sm8250_usb3_pcs_tbl),
	.pcs_usb_tbl		= sm8250_usb3_pcs_usb_tbl,
	.pcs_usb_tbl_num	= ARRAY_SIZE(sm8250_usb3_pcs_usb_tbl),
	.clk_list		= qmp_v4_sm8250_usbphy_clk_l,
	.num_clks		= ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l),
	.reset_list		= msm8996_usb3phy_reset_l,
@@ -1772,6 +1789,7 @@ static const struct qmp_phy_cfg sm8250_usb3phy_cfg = {
	.vreg_list		= qmp_phy_vreg_l,
	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
	.regs			= qmp_v4_usb3phy_regs_layout,
	.pcs_usb_offset		= 0x300,

	.start_ctrl		= SERDES_START | PCS_START,
	.pwrdn_ctrl		= SW_PWRDN,
@@ -1797,13 +1815,16 @@ static const struct qmp_phy_cfg sm8250_usb3_uniphy_cfg = {
	.rx_tbl_num		= ARRAY_SIZE(sm8250_usb3_uniphy_rx_tbl),
	.pcs_tbl		= sm8250_usb3_uniphy_pcs_tbl,
	.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_phy_clk_l,
	.num_clks		= ARRAY_SIZE(qmp_v4_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_usb3_uniphy_regs_layout,
	.regs			= qmp_v4_usb3phy_regs_layout,
	.pcs_usb_offset		= 0x600,

	.start_ctrl		= SERDES_START | PCS_START,
	.pwrdn_ctrl		= SW_PWRDN,
@@ -1826,13 +1847,16 @@ static const struct qmp_phy_cfg sdx55_usb3_uniphy_cfg = {
	.rx_tbl_num		= ARRAY_SIZE(sdx55_usb3_uniphy_rx_tbl),
	.pcs_tbl		= sm8250_usb3_uniphy_pcs_tbl,
	.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_usb3_uniphy_regs_layout,
	.regs			= qmp_v4_usb3phy_regs_layout,
	.pcs_usb_offset		= 0x600,

	.start_ctrl		= SERDES_START | PCS_START,
	.pwrdn_ctrl		= SW_PWRDN,
@@ -1855,13 +1879,16 @@ static const struct qmp_phy_cfg sdx65_usb3_uniphy_cfg = {
	.rx_tbl_num		= ARRAY_SIZE(sdx65_usb3_uniphy_rx_tbl),
	.pcs_tbl		= sm8350_usb3_uniphy_pcs_tbl,
	.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			= sm8350_usb3_uniphy_regs_layout,
	.regs			= qmp_v4_usb3phy_regs_layout,
	.pcs_usb_offset		= 0x1000,

	.start_ctrl		= SERDES_START | PCS_START,
	.pwrdn_ctrl		= SW_PWRDN,
@@ -1884,6 +1911,8 @@ static const struct qmp_phy_cfg sm8350_usb3phy_cfg = {
	.rx_tbl_num		= ARRAY_SIZE(sm8350_usb3_rx_tbl),
	.pcs_tbl		= sm8350_usb3_pcs_tbl,
	.pcs_tbl_num		= ARRAY_SIZE(sm8350_usb3_pcs_tbl),
	.pcs_usb_tbl		= sm8350_usb3_pcs_usb_tbl,
	.pcs_usb_tbl_num	= ARRAY_SIZE(sm8350_usb3_pcs_usb_tbl),
	.clk_list		= qmp_v4_sm8250_usbphy_clk_l,
	.num_clks		= ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l),
	.reset_list		= msm8996_usb3phy_reset_l,
@@ -1891,6 +1920,7 @@ static const struct qmp_phy_cfg sm8350_usb3phy_cfg = {
	.vreg_list		= qmp_phy_vreg_l,
	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
	.regs			= qmp_v4_usb3phy_regs_layout,
	.pcs_usb_offset		= 0x300,

	.start_ctrl		= SERDES_START | PCS_START,
	.pwrdn_ctrl		= SW_PWRDN,
@@ -1916,13 +1946,16 @@ static const struct qmp_phy_cfg sm8350_usb3_uniphy_cfg = {
	.rx_tbl_num		= ARRAY_SIZE(sm8350_usb3_uniphy_rx_tbl),
	.pcs_tbl		= sm8350_usb3_uniphy_pcs_tbl,
	.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_phy_clk_l,
	.num_clks		= ARRAY_SIZE(qmp_v4_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			= sm8350_usb3_uniphy_regs_layout,
	.regs			= qmp_v4_usb3phy_regs_layout,
	.pcs_usb_offset		= 0x1000,

	.start_ctrl		= SERDES_START | PCS_START,
	.pwrdn_ctrl		= SW_PWRDN,
@@ -2244,7 +2277,7 @@ static int qcom_qmp_phy_usb_set_mode(struct phy *phy,
static void qcom_qmp_phy_usb_enable_autonomous_mode(struct qmp_phy *qphy)
{
	const struct qmp_phy_cfg *cfg = qphy->cfg;
	void __iomem *pcs = qphy->pcs;
	void __iomem *pcs_usb = qphy->pcs_usb ?: qphy->pcs;
	void __iomem *pcs_misc = qphy->pcs_misc;
	u32 intr_mask;

@@ -2255,15 +2288,15 @@ static void qcom_qmp_phy_usb_enable_autonomous_mode(struct qmp_phy *qphy)
		intr_mask = ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL;

	/* Clear any pending interrupts status */
	qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
	qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
	/* Writing 1 followed by 0 clears the interrupt */
	qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
	qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);

	qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
	qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
		     ARCVR_DTCT_EN | ALFPS_DTCT_EN | ARCVR_DTCT_EVENT_SEL);

	/* Enable required PHY autonomous mode interrupts */
	qphy_setbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask);
	qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask);

	/* Enable i/o clamp_n for autonomous mode */
	if (pcs_misc)
@@ -2273,19 +2306,19 @@ static void qcom_qmp_phy_usb_enable_autonomous_mode(struct qmp_phy *qphy)
static void qcom_qmp_phy_usb_disable_autonomous_mode(struct qmp_phy *qphy)
{
	const struct qmp_phy_cfg *cfg = qphy->cfg;
	void __iomem *pcs = qphy->pcs;
	void __iomem *pcs_usb = qphy->pcs_usb ?: qphy->pcs;
	void __iomem *pcs_misc = qphy->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);

	qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
	qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
		     ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL | ALFPS_DTCT_EN);

	qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
	qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
	/* Writing 1 followed by 0 clears the interrupt */
	qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
	qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
}

static int __maybe_unused qcom_qmp_phy_usb_runtime_suspend(struct device *dev)
@@ -2501,6 +2534,9 @@ int qcom_qmp_phy_usb_create(struct device *dev, struct device_node *np, int id,
	if (!qphy->pcs)
		return -ENOMEM;

	if (cfg->pcs_usb_offset)
		qphy->pcs_usb = qphy->pcs + cfg->pcs_usb_offset;

	/*
	 * If this is a dual-lane PHY, then there should be registers for the
	 * second lane. Some old device trees did not specify this, so fall
+50 −56

File changed.

Preview size limit exceeded, changes collapsed.