Commit c9a7b0dd authored by Manivannan Sadhasivam's avatar Manivannan Sadhasivam Committed by Vinod Koul
Browse files

phy: qcom-qmp-ufs: Move register settings to qmp_phy_cfg_tbls struct



As done for Qcom PCIe PHY driver, let's move the register settings to the
common qmp_phy_cfg_tbls struct. This helps in adding any additional PHY
settings needed for functionalities like HS-G4 in the future by adding one
more instance of the qmp_phy_cfg_tbls.

Reviewed-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # Qdrive3/sa8540p-ride
Signed-off-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Link: https://lore.kernel.org/r/20230114071009.88102-4-manivannan.sadhasivam@linaro.org


Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent fcfcae3b
Loading
Loading
Loading
Loading
+113 −83
Original line number Diff line number Diff line
@@ -532,21 +532,26 @@ struct qmp_ufs_offsets {
	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;
};

/* struct qmp_phy_cfg - per-PHY initialization config */
struct qmp_phy_cfg {
	int lanes;

	const struct qmp_ufs_offsets *offsets;

	/* Init sequence for PHY blocks - serdes, tx, rx, pcs */
	const struct qmp_phy_init_tbl *serdes_tbl;
	int serdes_tbl_num;
	const struct qmp_phy_init_tbl *tx_tbl;
	int tx_tbl_num;
	const struct qmp_phy_init_tbl *rx_tbl;
	int rx_tbl_num;
	const struct qmp_phy_init_tbl *pcs_tbl;
	int pcs_tbl_num;
	/* Main init sequence for PHY blocks - serdes, tx, rx, pcs */
	const struct qmp_phy_cfg_tbls tbls;

	/* clock ids to be requested */
	const char * const *clk_list;
@@ -637,12 +642,14 @@ static const struct qmp_ufs_offsets qmp_ufs_offsets_v5 = {
static const struct qmp_phy_cfg msm8996_ufsphy_cfg = {
	.lanes			= 1,

	.serdes_tbl		= msm8996_ufsphy_serdes,
	.serdes_tbl_num		= ARRAY_SIZE(msm8996_ufsphy_serdes),
	.tx_tbl			= msm8996_ufsphy_tx,
	.tx_tbl_num		= ARRAY_SIZE(msm8996_ufsphy_tx),
	.rx_tbl			= msm8996_ufsphy_rx,
	.rx_tbl_num		= ARRAY_SIZE(msm8996_ufsphy_rx),
	.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),
	},

	.clk_list		= msm8996_ufs_phy_clk_l,
	.num_clks		= ARRAY_SIZE(msm8996_ufs_phy_clk_l),
@@ -660,14 +667,16 @@ static const struct qmp_phy_cfg sc8280xp_ufsphy_cfg = {

	.offsets		= &qmp_ufs_offsets_v5,

	.serdes_tbl		= sm8350_ufsphy_serdes,
	.serdes_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_serdes),
	.tx_tbl			= sm8350_ufsphy_tx,
	.tx_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_tx),
	.rx_tbl			= sm8350_ufsphy_rx,
	.rx_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_rx),
	.pcs_tbl		= sm8350_ufsphy_pcs,
	.pcs_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_pcs),
	.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),
	},
	.clk_list		= sdm845_ufs_phy_clk_l,
	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),
	.vreg_list		= qmp_phy_vreg_l,
@@ -678,14 +687,16 @@ static const struct qmp_phy_cfg sc8280xp_ufsphy_cfg = {
static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
	.lanes			= 2,

	.serdes_tbl		= sdm845_ufsphy_serdes,
	.serdes_tbl_num		= ARRAY_SIZE(sdm845_ufsphy_serdes),
	.tx_tbl			= sdm845_ufsphy_tx,
	.tx_tbl_num		= ARRAY_SIZE(sdm845_ufsphy_tx),
	.rx_tbl			= sdm845_ufsphy_rx,
	.rx_tbl_num		= ARRAY_SIZE(sdm845_ufsphy_rx),
	.pcs_tbl		= sdm845_ufsphy_pcs,
	.pcs_tbl_num		= ARRAY_SIZE(sdm845_ufsphy_pcs),
	.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),
	},
	.clk_list		= sdm845_ufs_phy_clk_l,
	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),
	.vreg_list		= qmp_phy_vreg_l,
@@ -700,14 +711,16 @@ static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {

	.offsets		= &qmp_ufs_offsets_v5,

	.serdes_tbl		= sm6115_ufsphy_serdes,
	.serdes_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_serdes),
	.tx_tbl			= sm6115_ufsphy_tx,
	.tx_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_tx),
	.rx_tbl			= sm6115_ufsphy_rx,
	.rx_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_rx),
	.pcs_tbl		= sm6115_ufsphy_pcs,
	.pcs_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_pcs),
	.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),
	},
	.clk_list		= sdm845_ufs_phy_clk_l,
	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),
	.vreg_list		= qmp_phy_vreg_l,
@@ -720,14 +733,16 @@ static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {
	.lanes			= 2,

	.serdes_tbl		= sm8150_ufsphy_serdes,
	.serdes_tbl_num		= ARRAY_SIZE(sm8150_ufsphy_serdes),
	.tx_tbl			= sm8150_ufsphy_tx,
	.tx_tbl_num		= ARRAY_SIZE(sm8150_ufsphy_tx),
	.rx_tbl			= sm8150_ufsphy_rx,
	.rx_tbl_num		= ARRAY_SIZE(sm8150_ufsphy_rx),
	.pcs_tbl		= sm8150_ufsphy_pcs,
	.pcs_tbl_num		= ARRAY_SIZE(sm8150_ufsphy_pcs),
	.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),
	},
	.clk_list		= sdm845_ufs_phy_clk_l,
	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),
	.vreg_list		= qmp_phy_vreg_l,
@@ -738,14 +753,16 @@ static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {
static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {
	.lanes			= 2,

	.serdes_tbl		= sm8350_ufsphy_serdes,
	.serdes_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_serdes),
	.tx_tbl			= sm8350_ufsphy_tx,
	.tx_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_tx),
	.rx_tbl			= sm8350_ufsphy_rx,
	.rx_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_rx),
	.pcs_tbl		= sm8350_ufsphy_pcs,
	.pcs_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_pcs),
	.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),
	},
	.clk_list		= sdm845_ufs_phy_clk_l,
	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),
	.vreg_list		= qmp_phy_vreg_l,
@@ -756,14 +773,16 @@ static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {
static const struct qmp_phy_cfg sm8450_ufsphy_cfg = {
	.lanes			= 2,

	.serdes_tbl		= sm8350_ufsphy_serdes,
	.serdes_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_serdes),
	.tx_tbl			= sm8350_ufsphy_tx,
	.tx_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_tx),
	.rx_tbl			= sm8350_ufsphy_rx,
	.rx_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_rx),
	.pcs_tbl		= sm8350_ufsphy_pcs,
	.pcs_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_pcs),
	.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),
	},
	.clk_list		= sm8450_ufs_phy_clk_l,
	.num_clks		= ARRAY_SIZE(sm8450_ufs_phy_clk_l),
	.vreg_list		= qmp_phy_vreg_l,
@@ -797,16 +816,40 @@ static void qmp_ufs_configure(void __iomem *base,
	qmp_ufs_configure_lane(base, tbl, num, 0xff);
}

static int qmp_ufs_serdes_init(struct qmp_ufs *qmp)
static void qmp_ufs_serdes_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls *tbls)
{
	const struct qmp_phy_cfg *cfg = qmp->cfg;
	void __iomem *serdes = qmp->serdes;
	const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;
	int serdes_tbl_num = cfg->serdes_tbl_num;

	qmp_ufs_configure(serdes, serdes_tbl, serdes_tbl_num);
	qmp_ufs_configure(serdes, tbls->serdes, tbls->serdes_num);
}

	return 0;
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_ufs_configure_lane(tx, tbls->tx, tbls->tx_num, 1);
	qmp_ufs_configure_lane(rx, tbls->rx, tbls->rx_num, 1);

	if (cfg->lanes >= 2) {
		qmp_ufs_configure_lane(qmp->tx2, tbls->tx, tbls->tx_num, 2);
		qmp_ufs_configure_lane(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_ufs_configure(pcs, tbls->pcs, tbls->pcs_num);
}

static void qmp_ufs_init_registers(struct qmp_ufs *qmp, const struct qmp_phy_cfg *cfg)
{
	qmp_ufs_serdes_init(qmp, &cfg->tbls);
	qmp_ufs_lanes_init(qmp, &cfg->tbls);
	qmp_ufs_pcs_init(qmp, &cfg->tbls);
}

static int qmp_ufs_com_init(struct qmp_ufs *qmp)
@@ -893,25 +936,12 @@ 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 *tx = qmp->tx;
	void __iomem *rx = qmp->rx;
	void __iomem *pcs = qmp->pcs;
	void __iomem *status;
	unsigned int val;
	int ret;

	qmp_ufs_serdes_init(qmp);

	/* Tx, Rx, and PCS configurations */
	qmp_ufs_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
	qmp_ufs_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);

	if (cfg->lanes >= 2) {
		qmp_ufs_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
		qmp_ufs_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
	}

	qmp_ufs_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
	qmp_ufs_init_registers(qmp, cfg);

	ret = reset_control_deassert(qmp->ufs_reset);
	if (ret)