Commit efcd5f52 authored by Rahul T R's avatar Rahul T R Committed by Vinod Koul
Browse files

phy: cdns-dphy: Add band config for dphy tx



Add support for band ctrl config for dphy tx.

Signed-off-by: default avatarRahul T R <r-ravikumar@ti.com>
Reviewed-by: default avatarPratyush Yadav <p.yadav@ti.com>
Link: https://lore.kernel.org/r/20220623125433.18467-3-r-ravikumar@ti.com


Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 79446a2d
Loading
Loading
Loading
Loading
+39 −1
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
 * Copyright: 2017-2018 Cadence Design Systems, Inc.
 */

#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/io.h>
@@ -45,6 +46,10 @@
#define DPHY_CMN_OPDIV_FROM_REG		BIT(6)
#define DPHY_CMN_OPDIV(x)		((x) << 7)

#define DPHY_BAND_CFG			DPHY_PCS(0x0)
#define DPHY_BAND_CFG_LEFT_BAND		GENMASK(4, 0)
#define DPHY_BAND_CFG_RIGHT_BAND	GENMASK(9, 5)

#define DPHY_PSM_CFG			DPHY_PCS(0x4)
#define DPHY_PSM_CFG_FROM_REG		BIT(0)
#define DPHY_PSM_CLK_DIV(x)		((x) << 1)
@@ -92,6 +97,12 @@ struct cdns_dphy {
	struct phy *phy;
};

/* Order of bands is important since the index is the band number. */
static const unsigned int tx_bands[] = {
	80, 100, 120, 160, 200, 240, 320, 390, 450, 510, 560, 640, 690, 770,
	870, 950, 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2500
};

static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
				     struct cdns_dphy_cfg *cfg,
				     struct phy_configure_opts_mipi_dphy *opts,
@@ -232,6 +243,24 @@ static int cdns_dphy_config_from_opts(struct phy *phy,
	return 0;
}

static int cdns_dphy_tx_get_band_ctrl(unsigned long hs_clk_rate)
{
	unsigned int rate;
	int i;

	rate = hs_clk_rate / 1000000UL;

	if (rate < tx_bands[0])
		return -EOPNOTSUPP;

	for (i = 0; i < ARRAY_SIZE(tx_bands) - 1; i++) {
		if (rate >= tx_bands[i] && rate < tx_bands[i + 1])
			return i;
	}

	return -EOPNOTSUPP;
}

static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
			      union phy_configure_opts *opts)
{
@@ -247,7 +276,8 @@ static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
{
	struct cdns_dphy *dphy = phy_get_drvdata(phy);
	struct cdns_dphy_cfg cfg = { 0 };
	int ret;
	int ret, band_ctrl;
	unsigned int reg;

	ret = cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg);
	if (ret)
@@ -276,6 +306,14 @@ static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
	 */
	cdns_dphy_set_pll_cfg(dphy, &cfg);

	band_ctrl = cdns_dphy_tx_get_band_ctrl(opts->mipi_dphy.hs_clk_rate);
	if (band_ctrl < 0)
		return band_ctrl;

	reg = FIELD_PREP(DPHY_BAND_CFG_LEFT_BAND, band_ctrl) |
	      FIELD_PREP(DPHY_BAND_CFG_RIGHT_BAND, band_ctrl);
	writel(reg, dphy->regs + DPHY_BAND_CFG);

	return 0;
}