Commit 3ade3ede authored by Johan Hovold's avatar Johan Hovold Committed by Vinod Koul
Browse files

phy: qcom-qmp-combo: separate USB and DP power-on ops



Separate the USB and DP power-on and power-off operations in two
dedicated implementations.

Note that the pipe clock is only used by the USB part of the PHY and
that no DP configuration has a pcs (or rx) table or has has_pwrdn_delay
set.

Reviewed-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: default avatarJohan Hovold <johan+linaro@kernel.org>
Link: https://lore.kernel.org/r/20221114110621.4639-11-johan+linaro@kernel.org


Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 186266f6
Loading
Loading
Loading
Loading
+59 −41
Original line number Diff line number Diff line
@@ -1988,7 +1988,39 @@ static int qmp_combo_dp_exit(struct phy *phy)
	return 0;
}

static int qmp_combo_power_on(struct phy *phy)
static int qmp_combo_dp_power_on(struct phy *phy)
{
	struct qmp_phy *qphy = phy_get_drvdata(phy);
	const struct qmp_phy_cfg *cfg = qphy->cfg;
	void __iomem *tx = qphy->tx;

	qmp_combo_serdes_init(qphy);

	qmp_combo_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);

	if (cfg->lanes >= 2)
		qmp_combo_configure_lane(qphy->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);

	/* Configure special DP tx tunings */
	cfg->configure_dp_tx(qphy);

	/* Configure link rate, swing, etc. */
	cfg->configure_dp_phy(qphy);

	return 0;
}

static int qmp_combo_dp_power_off(struct phy *phy)
{
	struct qmp_phy *qphy = phy_get_drvdata(phy);

	/* Assert DP PHY power down */
	writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_DP_PHY_PD_CTL);

	return 0;
}

static int qmp_combo_usb_power_on(struct phy *phy)
{
	struct qmp_phy *qphy = phy_get_drvdata(phy);
	struct qcom_qmp *qmp = qphy->qmp;
@@ -2014,30 +2046,21 @@ static int qmp_combo_power_on(struct phy *phy)
	if (cfg->lanes >= 2)
		qmp_combo_configure_lane(qphy->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);

	/* Configure special DP tx tunings */
	if (cfg->type == PHY_TYPE_DP)
		cfg->configure_dp_tx(qphy);

	qmp_combo_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);

	if (cfg->lanes >= 2)
		qmp_combo_configure_lane(qphy->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);

	/* Configure link rate, swing, etc. */
	if (cfg->type == PHY_TYPE_DP)
		cfg->configure_dp_phy(qphy);
	else
	qmp_combo_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);

	if (cfg->has_pwrdn_delay)
		usleep_range(10, 20);

	if (cfg->type != PHY_TYPE_DP) {
	/* Pull PHY out of reset state */
	qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);

	/* start SerDes and Phy-Coding-Sublayer */
		qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL],
				SERDES_START | PCS_START);
	qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START | PCS_START);

	status = pcs + cfg->regs[QPHY_PCS_STATUS];
	ret = readl_poll_timeout(status, val, !(val & PHYSTATUS), 200,
@@ -2046,7 +2069,7 @@ static int qmp_combo_power_on(struct phy *phy)
		dev_err(qmp->dev, "phy initialization timed-out\n");
		goto err_disable_pipe_clk;
	}
	}

	return 0;

err_disable_pipe_clk:
@@ -2055,17 +2078,13 @@ static int qmp_combo_power_on(struct phy *phy)
	return ret;
}

static int qmp_combo_power_off(struct phy *phy)
static int qmp_combo_usb_power_off(struct phy *phy)
{
	struct qmp_phy *qphy = phy_get_drvdata(phy);
	const struct qmp_phy_cfg *cfg = qphy->cfg;

	clk_disable_unprepare(qphy->pipe_clk);

	if (cfg->type == PHY_TYPE_DP) {
		/* Assert DP PHY power down */
		writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
	} else {
	/* PHY reset */
	qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);

@@ -2076,7 +2095,6 @@ static int qmp_combo_power_off(struct phy *phy)
	/* Put PHY into POWER DOWN state: active low */
	qphy_clrbits(qphy->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
			SW_PWRDN);
	}

	return 0;
}
@@ -2090,7 +2108,7 @@ static int qmp_combo_usb_init(struct phy *phy)
	if (ret)
		return ret;

	ret = qmp_combo_power_on(phy);
	ret = qmp_combo_usb_power_on(phy);
	if (ret)
		qmp_combo_com_exit(qphy);

@@ -2102,7 +2120,7 @@ static int qmp_combo_usb_exit(struct phy *phy)
	struct qmp_phy *qphy = phy_get_drvdata(phy);
	int ret;

	ret = qmp_combo_power_off(phy);
	ret = qmp_combo_usb_power_off(phy);
	if (ret)
		return ret;

@@ -2128,9 +2146,9 @@ static const struct phy_ops qmp_combo_usb_phy_ops = {
static const struct phy_ops qmp_combo_dp_phy_ops = {
	.init		= qmp_combo_dp_init,
	.configure	= qmp_combo_dp_configure,
	.power_on	= qmp_combo_power_on,
	.power_on	= qmp_combo_dp_power_on,
	.calibrate	= qmp_combo_dp_calibrate,
	.power_off	= qmp_combo_power_off,
	.power_off	= qmp_combo_dp_power_off,
	.exit		= qmp_combo_dp_exit,
	.owner		= THIS_MODULE,
};