Unverified Commit 4795c787 authored by Roman Beranek's avatar Roman Beranek Committed by Maxime Ripard
Browse files

drm: sun4i: calculate proper DCLK rate for DSI



In DSI mode, TCON0's data clock is required to run at 1/4 the per-lane
bit rate.

Signed-off-by: default avatarRoman Beranek <me@crly.cz>
Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20230505052110.67514-5-me@crly.cz
parent 71ffeafb
Loading
Loading
Loading
Loading
+21 −15
Original line number Diff line number Diff line
@@ -291,18 +291,6 @@ static int sun4i_tcon_get_clk_delay(const struct drm_display_mode *mode,
	return delay;
}

static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
					const struct drm_display_mode *mode)
{
	/* Configure the dot clock */
	clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);

	/* Set the resolution */
	regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
		     SUN4I_TCON0_BASIC0_X(mode->crtc_hdisplay) |
		     SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay));
}

static void sun4i_tcon0_mode_set_dithering(struct sun4i_tcon *tcon,
					   const struct drm_connector *connector)
{
@@ -367,10 +355,18 @@ static void sun4i_tcon0_mode_set_cpu(struct sun4i_tcon *tcon,
	u32 block_space, start_delay;
	u32 tcon_div;

	/*
	 * dclk is required to run at 1/4 the DSI per-lane bit rate.
	 */
	tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
	tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
	clk_set_rate(tcon->dclk, mode->crtc_clock * 1000 * (bpp / lanes)
						  / SUN6I_DSI_TCON_DIV);

	sun4i_tcon0_mode_set_common(tcon, mode);
	/* Set the resolution */
	regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
		     SUN4I_TCON0_BASIC0_X(mode->crtc_hdisplay) |
		     SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay));

	/* Set dithering if needed */
	sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
@@ -438,7 +434,12 @@ static void sun4i_tcon0_mode_set_lvds(struct sun4i_tcon *tcon,

	tcon->dclk_min_div = 7;
	tcon->dclk_max_div = 7;
	sun4i_tcon0_mode_set_common(tcon, mode);
	clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);

	/* Set the resolution */
	regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
		     SUN4I_TCON0_BASIC0_X(mode->crtc_hdisplay) |
		     SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay));

	/* Set dithering if needed */
	sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
@@ -515,7 +516,12 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon,

	tcon->dclk_min_div = tcon->quirks->dclk_min_div;
	tcon->dclk_max_div = 127;
	sun4i_tcon0_mode_set_common(tcon, mode);
	clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);

	/* Set the resolution */
	regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
		     SUN4I_TCON0_BASIC0_X(mode->crtc_hdisplay) |
		     SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay));

	/* Set dithering if needed */
	sun4i_tcon0_mode_set_dithering(tcon, connector);