Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aaa757a0 authored by Andy Yan's avatar Andy Yan Committed by Philipp Zabel
Browse files

drm: imx: imx-hdmi: split phy configuration to platform driver



hdmi phy configuration is platform specific, which can be adjusted
according to the board to get the best SI

Signed-off-by: default avatarAndy Yan <andy.yan@rock-chips.com>
Tested-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
Acked-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
parent 3d1b35a3
Loading
Loading
Loading
Loading
+15 −70
Original line number Diff line number Diff line
@@ -713,76 +713,14 @@ static void imx_hdmi_phy_sel_interface_control(struct imx_hdmi *hdmi, u8 enable)
			 HDMI_PHY_CONF0_SELDIPIF_MASK);
}

enum {
	RES_8,
	RES_10,
	RES_12,
	RES_MAX,
};

struct mpll_config {
	unsigned long mpixelclock;
	struct {
		u16 cpce;
		u16 gmp;
	} res[RES_MAX];
};

static const struct mpll_config mpll_config[] = {
	{
		45250000, {
			{ 0x01e0, 0x0000 },
			{ 0x21e1, 0x0000 },
			{ 0x41e2, 0x0000 }
		},
	}, {
		92500000, {
			{ 0x0140, 0x0005 },
			{ 0x2141, 0x0005 },
			{ 0x4142, 0x0005 },
		},
	}, {
		148500000, {
			{ 0x00a0, 0x000a },
			{ 0x20a1, 0x000a },
			{ 0x40a2, 0x000a },
		},
	}, {
		~0UL, {
			{ 0x00a0, 0x000a },
			{ 0x2001, 0x000f },
			{ 0x4002, 0x000f },
		},
	}
};

struct curr_ctrl {
	unsigned long mpixelclock;
	u16 curr[RES_MAX];
};

static const struct curr_ctrl curr_ctrl[] = {
	/*	pixelclk     bpp8    bpp10   bpp12 */
	{
		 54000000, { 0x091c, 0x091c, 0x06dc },
	}, {
		 58400000, { 0x091c, 0x06dc, 0x06dc },
	}, {
		 72000000, { 0x06dc, 0x06dc, 0x091c },
	}, {
		 74250000, { 0x06dc, 0x0b5c, 0x091c },
	}, {
		118800000, { 0x091c, 0x091c, 0x06dc },
	}, {
		216000000, { 0x06dc, 0x0b5c, 0x091c },
	}
};

static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
			      unsigned char res, int cscon)
{
	unsigned res_idx, i;
	u8 val, msec;
	const struct mpll_config *mpll_config = hdmi->plat_data->mpll_cfg;
	const struct curr_ctrl   *curr_ctrl = hdmi->plat_data->cur_ctr;
	const struct sym_term *sym_term =  hdmi->plat_data->sym_term;

	if (prep)
		return -EINVAL;
@@ -828,7 +766,7 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
	hdmi_phy_test_clear(hdmi, 0);

	/* PLL/MPLL Cfg - always match on final entry */
	for (i = 0; i < ARRAY_SIZE(mpll_config) - 1; i++)
	for (i = 0; mpll_config[i].mpixelclock != (~0UL); i++)
		if (hdmi->hdmi_data.video_mode.mpixelclock <=
		    mpll_config[i].mpixelclock)
			break;
@@ -836,12 +774,12 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
	hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].cpce, 0x06);
	hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].gmp, 0x15);

	for (i = 0; i < ARRAY_SIZE(curr_ctrl); i++)
	for (i = 0; curr_ctrl[i].mpixelclock != (~0UL); i++)
		if (hdmi->hdmi_data.video_mode.mpixelclock <=
		    curr_ctrl[i].mpixelclock)
			break;

	if (i >= ARRAY_SIZE(curr_ctrl)) {
	if (curr_ctrl[i].mpixelclock == (~0UL)) {
		dev_err(hdmi->dev, "Pixel clock %d - unsupported by HDMI\n",
			hdmi->hdmi_data.video_mode.mpixelclock);
		return -EINVAL;
@@ -852,10 +790,17 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,

	hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);  /* PLLPHBYCTRL */
	hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);

	for (i = 0; sym_term[i].mpixelclock != (~0UL); i++)
		if (hdmi->hdmi_data.video_mode.mpixelclock <=
		    sym_term[i].mpixelclock)
			break;

	/* RESISTANCE TERM 133Ohm Cfg */
	hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);  /* TXTERM */
	hdmi_phy_i2c_write(hdmi, sym_term[i].term, 0x19);  /* TXTERM */
	/* PREEMP Cgf 0.00 */
	hdmi_phy_i2c_write(hdmi, 0x800d, 0x09);  /* CKSYMTXCTRL */
	hdmi_phy_i2c_write(hdmi, sym_term[i].sym_ctr, 0x09);  /* CKSYMTXCTRL */

	/* TX/CK LVL 10 */
	hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E);  /* VLEVCTRL */
	/* REMOVE CLK TERM */
+29 −0
Original line number Diff line number Diff line
@@ -1037,6 +1037,35 @@ enum imx_hdmi_devtype {

struct imx_hdmi_plat_data {
	enum imx_hdmi_devtype dev_type;
	const struct mpll_config *mpll_cfg;
	const struct curr_ctrl *cur_ctr;
	const struct sym_term *sym_term;
};

enum {
	RES_8,
	RES_10,
	RES_12,
	RES_MAX,
};

struct mpll_config {
	unsigned long mpixelclock;
	struct {
		u16 cpce;
		u16 gmp;
	} res[RES_MAX];
};

struct curr_ctrl {
	unsigned long mpixelclock;
	u16 curr[RES_MAX];
};

struct sym_term {
	unsigned long mpixelclock;
	u16 sym_ctr;    /*clock symbol and transmitter control*/
	u16 term;       /*transmission termination value*/
};

int imx_hdmi_bind(struct device *dev, struct device *master,
+57 −0
Original line number Diff line number Diff line
@@ -28,6 +28,57 @@ struct imx_hdmi_priv {
	struct regmap *regmap;
};

static const struct mpll_config imx_mpll_cfg[] = {
	{
		45250000, {
			{ 0x01e0, 0x0000 },
			{ 0x21e1, 0x0000 },
			{ 0x41e2, 0x0000 }
		},
	}, {
		92500000, {
			{ 0x0140, 0x0005 },
			{ 0x2141, 0x0005 },
			{ 0x4142, 0x0005 },
	},
	}, {
		148500000, {
			{ 0x00a0, 0x000a },
			{ 0x20a1, 0x000a },
			{ 0x40a2, 0x000a },
		},
	}, {
		~0UL, {
			{ 0x00a0, 0x000a },
			{ 0x2001, 0x000f },
			{ 0x4002, 0x000f },
		},
	}
};

static const struct curr_ctrl imx_cur_ctr[] = {
	/*      pixelclk     bpp8    bpp10   bpp12 */
	{
		54000000, { 0x091c, 0x091c, 0x06dc },
	}, {
		58400000, { 0x091c, 0x06dc, 0x06dc },
	}, {
		72000000, { 0x06dc, 0x06dc, 0x091c },
	}, {
		74250000, { 0x06dc, 0x0b5c, 0x091c },
	}, {
		118800000, { 0x091c, 0x091c, 0x06dc },
	}, {
		216000000, { 0x06dc, 0x0b5c, 0x091c },
	}
};

static const struct sym_term imx_sym_term[] = {
	/*pixelclk   symbol   term*/
	{ 148500000, 0x800d, 0x0005 },
	{ ~0UL,      0x0000, 0x0000 }
};

static int imx_hdmi_parse_dt(struct imx_hdmi_priv *hdmi)
{
	struct device_node *np = hdmi->dev->of_node;
@@ -88,10 +139,16 @@ static struct drm_encoder_funcs imx_hdmi_encoder_funcs = {
};

static struct imx_hdmi_plat_data imx6q_hdmi_drv_data = {
	.mpll_cfg = imx_mpll_cfg,
	.cur_ctr  = imx_cur_ctr,
	.sym_term = imx_sym_term,
	.dev_type = IMX6Q_HDMI,
};

static struct imx_hdmi_plat_data imx6dl_hdmi_drv_data = {
	.mpll_cfg = imx_mpll_cfg,
	.cur_ctr  = imx_cur_ctr,
	.sym_term = imx_sym_term,
	.dev_type = IMX6DL_HDMI,
};