Skip to contentSkip to conversation

Fixing the DSI dot clock on Allwinner

PATCH In review Frank Oltmanns 3 participants 5 messages Mar 19, 2023 – Mar 22, 2023

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover Fixing the DSI dot clock on Allwinner

According to the Allwinner A64's BSP code, the PLL rate needs to be set to the following frequency when using DSI:
PLL rate = DCLK * bpp / lanes

Source: [1]
The relevant lines for DSI (ommisions and comments mine):
dclk_rate = lcdp->panel_info.lcd_dclk_freq * 1000000;
lcd_rate = dclk_rate * clk_info.dsi_div; // dsi_div = bpp/lane pll_rate = lcd_rate * clk_info.lcd_div; // lcd_div = 1 --> pll_rate = lcd_rate
dsi_rate = pll_rate / clk_info.dsi_div // --> dsi_rate = dclk_rate
clk_set_rate(lcdp->clk_parent, pll_rate);

This was already discussed by Maxime, Jagan and Michael in the past in the thread following this message: [2]. Unfortunately, there never was a conclusion in the form of code.

The attached patch is a slight variation of a patch that is part of megi's kernel branch that many PinePhone distributions (e.g. postmarketOS) use [3]. It calculates the TCON clock rate by using the formula above and dividing it by SUN6I_DSI_TCON_DIV, in order to force the parent clock to be set to the correct rate.

If I read the thread following this message [2] correctly, this was also what Maxime had in mind.

Please also note that, unfortunately, I only have a single board and panel (namely the PinePhone) to test this on.

Thanks,
Frank

[1] https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L781
[2] https://lore.kernel.org/lkml/CAMty3ZAsH2iZ+JEqTE3D58aXfGuhMSg9YoO56ZhhOeE4c4yQHQ@mail.gmail.com/
[3] https://github.com/megous/linux/commit/eb5f28fb58727f4a6546f211486aad0d19cdea3f

Frank Oltmanns (1):
drm/sun4i: tcon: Fix setting PLL rate when using DSI

 drivers/gpu/drm/sun4i/sun4i_tcon.c | 46 ++++++++++++++++++++----------
 1 file changed, 31 insertions(+), 15 deletions(-)
Signature · 1 line
2.39.2
#1 lore raw

PATCH 1/1 drm/sun4i: tcon: Fix setting PLL rate when using DSI

Set the required PLL rate by adjusting the dotclock rate when calling clk_set_rate() when using DSI.

According to the Allwinners A64's BSP code, a TCON divider of 4 has to be used and the PLL rate needs to be set to the following frequency when using DSI:
PLL rate = DCLK * bpp / lanes

After this change the common mode set function would only contain setting the resolution. Therefore, dissolve the function and transfer the functionality to the individual mode set functions.

---
 drivers/gpu/drm/sun4i/sun4i_tcon.c | 46 ++++++++++++++++++++----------
 1 file changed, 31 insertions(+), 15 deletions(-)
drivers/gpu/drm/sun4i/sun4i_tcon.c +31 -15
index 62b3538bd81f..02d52be42f06 100644
@@ -323,18 +323,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)
 {
@@ -399,10 +387,24 @@ static void sun4i_tcon0_mode_set_cpu(struct sun4i_tcon *tcon,
 	u32 block_space, start_delay;
 	u32 tcon_div;
 
+	/*
+	 * Configure the dot clock:
+	 * For DSI the PLL rate has to respect the bits per pixel and
+	 * number of lanes.
+	 *
+	 * According to the BSP code:
+	 * TCON divider = 4
+	 * PLL rate = DCLK * bpp / lanes
+	 */
 	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));
@@ -470,7 +472,14 @@ 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);
+
+	/* 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));
 
 	/* Set dithering if needed */
 	sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
@@ -549,7 +558,14 @@ 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);
+
+	/* 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));
 
 	/* Set dithering if needed */
 	sun4i_tcon0_mode_set_dithering(tcon, connector);
Signature · 1 line
2.39.2
#2 lore raw

Re: [PATCH 1/1] drm/sun4i: tcon: Fix setting PLL rate when using DSI

Hi,

Quoted 8 lines · Frank Oltmanns

Set the required PLL rate by adjusting the dotclock rate when calling clk_set_rate() when using DSI.

According to the Allwinners A64's BSP code, a TCON divider of 4 has to be used and the PLL rate needs to be set to the following frequency when using DSI:
PLL rate = DCLK * bpp / lanes

Quoted 5 lines

After this change the common mode set function would only contain setting the resolution. Therefore, dissolve the function and transfer the functionality to the individual mode set functions.

This is similar to:
https://lore.kernel.org/all/[email protected]/

What's the story there?

Maxime

#3 lore raw

Re: [PATCH 1/1] drm/sun4i: tcon: Fix setting PLL rate when using DSI

Hi Maxime,

Quoted 15 lines · Maxime Ripard

Hi,

Quoted 12 lines · Frank Oltmanns

Set the required PLL rate by adjusting the dotclock rate when calling clk_set_rate() when using DSI.

According to the Allwinners A64’s BSP code, a TCON divider of 4 has to be used and the PLL rate needs to be set to the following frequency when using DSI:
PLL rate = DCLK * bpp / lanes

After this change the common mode set function would only contain setting the resolution. Therefore, dissolve the function and transfer the functionality to the individual mode set functions.

Quoted 6 lines
Quoted 1 line

This is similar to:
<https://lore.kernel.org/all/[email protected]/>

What’s the story there?

Sorry, as Roman wrote in the other thread, I submitted the patch after not hearing back from him for a week. My apologies, I wasn’t patient enough. So now there are two submissions to consider. FWIW, I think this patch is a bit more straightforward than the other one.

Best regards,
Frank

Quoted 2 lines

Maxime

#4 lore raw

Re: [PATCH 1/1] drm/sun4i: tcon: Fix setting PLL rate when using DSI

Quoted 1 line · Frank Oltmanns

My apologies, I wasn’t patient enough.

Frank, there's no need to apologize, in my judgement. You weren't impatient, we simply happened to run into a coordination problem for which, I think, neither of us was particularly to blamew. Take it easy :)

Roman