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: Roman Beranek <me@crly.cz>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20230505052110.67514-5-me@crly.cz
This commit is contained in:
Roman Beranek
2023-05-05 07:21:10 +02:00
committed by Maxime Ripard
parent 71ffeafb13
commit 4795c78768

View File

@@ -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);