Re: [PATCH v4 0/4] drm: sun4i: set proper TCON0 DCLK rate in DSI mode

2023-05-09 Thread Roman Beranek
Hello Frank,

On Mon May 8, 2023 at 10:47 AM CEST, Frank Oltmanns wrote:
> I tested this on my pinephone on drm-next, using additional patches for
> the pinephone's panel. [1] [2] [3]

Thank you for testing this and all the previous version of this
patchset. I appreciate your help.

> I played back a 60 fps video (10 seconds) and recorded the panel's
> output with a 240 fps camera. I noticed only 2 dropped frames, that I
> account to the imperfect data rate of 107.8MHz instead of 108 MHz due to
> pll-video0's rate being 294MHz instead of the 297 MHz for reasons I
> described in the thread on your v2 of this patch [4]).

Yes. That's what should happen, right? Or do you report this as a
defect?

Roman


[PATCH v4 4/4] drm: sun4i: calculate proper DCLK rate for DSI

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

Signed-off-by: Roman Beranek 
---
 drivers/gpu/drm/sun4i/sun4i_tcon.c | 36 +-
 1 file changed, 21 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c 
b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index eec26b1faa4b..b263de7a8237 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -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);
-- 
2.32.0 (Apple Git-132)



[PATCH v4 3/4] drm: sun4i: rename sun4i_dotclock to sun4i_tcon_dclk

2023-05-04 Thread Roman Beranek
While the rate of TCON0's DCLK matches dotclock for parallel and LVDS
outputs, this doesn't hold for DSI. The 'D' in DCLK actually stands for
'Data' according to Allwinner's manuals. The clock is mostly referred to
as dclk throughout this driver already anyway, so stick with that.

Signed-off-by: Roman Beranek 
---
 drivers/gpu/drm/sun4i/Makefile |  2 +-
 drivers/gpu/drm/sun4i/sun4i_tcon.c | 10 +-
 .../drm/sun4i/{sun4i_dotclock.c => sun4i_tcon_dclk.c}  |  2 +-
 .../drm/sun4i/{sun4i_dotclock.h => sun4i_tcon_dclk.h}  |  0
 4 files changed, 7 insertions(+), 7 deletions(-)
 rename drivers/gpu/drm/sun4i/{sun4i_dotclock.c => sun4i_tcon_dclk.c} (99%)
 rename drivers/gpu/drm/sun4i/{sun4i_dotclock.h => sun4i_tcon_dclk.h} (100%)

diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile
index 0d04f2447b01..bad7497a0d11 100644
--- a/drivers/gpu/drm/sun4i/Makefile
+++ b/drivers/gpu/drm/sun4i/Makefile
@@ -19,7 +19,7 @@ sun8i-mixer-y += sun8i_mixer.o 
sun8i_ui_layer.o \
   sun8i_vi_scaler.o sun8i_csc.o
 
 sun4i-tcon-y   += sun4i_crtc.o
-sun4i-tcon-y   += sun4i_dotclock.o
+sun4i-tcon-y   += sun4i_tcon_dclk.o
 sun4i-tcon-y   += sun4i_lvds.o
 sun4i-tcon-y   += sun4i_tcon.o
 sun4i-tcon-y   += sun4i_rgb.o
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c 
b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 523a6d787921..eec26b1faa4b 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -31,12 +31,12 @@
 #include 
 
 #include "sun4i_crtc.h"
-#include "sun4i_dotclock.h"
 #include "sun4i_drv.h"
 #include "sun4i_lvds.h"
 #include "sun4i_rgb.h"
 #include "sun4i_tcon.h"
 #include "sun6i_mipi_dsi.h"
+#include "sun4i_tcon_dclk.h"
 #include "sun8i_tcon_top.h"
 #include "sunxi_engine.h"
 
@@ -1237,14 +1237,14 @@ static int sun4i_tcon_bind(struct device *dev, struct 
device *master,
ret = sun4i_tcon_init_irq(dev, tcon);
if (ret) {
dev_err(dev, "Couldn't init our TCON interrupts\n");
-   goto err_free_dotclock;
+   goto err_free_dclk;
}
 
tcon->crtc = sun4i_crtc_init(drm, engine, tcon);
if (IS_ERR(tcon->crtc)) {
dev_err(dev, "Couldn't create our CRTC\n");
ret = PTR_ERR(tcon->crtc);
-   goto err_free_dotclock;
+   goto err_free_dclk;
}
 
if (tcon->quirks->has_channel_0) {
@@ -1264,7 +1264,7 @@ static int sun4i_tcon_bind(struct device *dev, struct 
device *master,
of_node_put(remote);
 
if (ret < 0)
-   goto err_free_dotclock;
+   goto err_free_dclk;
}
 
if (tcon->quirks->needs_de_be_mux) {
@@ -1290,7 +1290,7 @@ static int sun4i_tcon_bind(struct device *dev, struct 
device *master,
 
return 0;
 
-err_free_dotclock:
+err_free_dclk:
if (tcon->quirks->has_channel_0)
sun4i_dclk_free(tcon);
 err_free_clocks:
diff --git a/drivers/gpu/drm/sun4i/sun4i_dotclock.c 
b/drivers/gpu/drm/sun4i/sun4i_tcon_dclk.c
similarity index 99%
rename from drivers/gpu/drm/sun4i/sun4i_dotclock.c
rename to drivers/gpu/drm/sun4i/sun4i_tcon_dclk.c
index 417ade3d2565..03d7de1911cd 100644
--- a/drivers/gpu/drm/sun4i/sun4i_dotclock.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon_dclk.c
@@ -10,7 +10,7 @@
 #include 
 
 #include "sun4i_tcon.h"
-#include "sun4i_dotclock.h"
+#include "sun4i_tcon_dclk.h"
 
 struct sun4i_dclk {
struct clk_hw   hw;
diff --git a/drivers/gpu/drm/sun4i/sun4i_dotclock.h 
b/drivers/gpu/drm/sun4i/sun4i_tcon_dclk.h
similarity index 100%
rename from drivers/gpu/drm/sun4i/sun4i_dotclock.h
rename to drivers/gpu/drm/sun4i/sun4i_tcon_dclk.h
-- 
2.32.0 (Apple Git-132)



[PATCH v4 2/4] ARM: dts: sunxi: rename tcon's clock output

2023-05-04 Thread Roman Beranek
While the rate of TCON0's DCLK matches dotclock for parallel and LVDS
outputs, this doesn't hold for DSI. According manuals from Allwinner,
DCLK is an abbreviation of Data Clock, not dotclock, so go with that
instead.

Signed-off-by: Roman Beranek 
---
 arch/arm/boot/dts/sun5i.dtsi  | 2 +-
 arch/arm/boot/dts/sun8i-a23-a33.dtsi  | 2 +-
 arch/arm/boot/dts/sun8i-a83t.dtsi | 2 +-
 arch/arm/boot/dts/sun8i-v3s.dtsi  | 2 +-
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/sun5i.dtsi b/arch/arm/boot/dts/sun5i.dtsi
index 250d6b87ab4d..2f901a013676 100644
--- a/arch/arm/boot/dts/sun5i.dtsi
+++ b/arch/arm/boot/dts/sun5i.dtsi
@@ -286,7 +286,7 @@ tcon0: lcd-controller@1c0c000 {
clock-names = "ahb",
  "tcon-ch0",
  "tcon-ch1";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
status = "disabled";
 
diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi 
b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
index f630ab55bb6a..ddc87cc15e51 100644
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
@@ -190,7 +190,7 @@ tcon0: lcd-controller@1c0c000 {
clock-names = "ahb",
  "tcon-ch0",
  "lvds-alt";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
resets = < RST_BUS_LCD>,
 < RST_BUS_LVDS>;
diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi 
b/arch/arm/boot/dts/sun8i-a83t.dtsi
index 82fdb04122ca..94eb3bfc989e 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -456,7 +456,7 @@ tcon0: lcd-controller@1c0c000 {
interrupts = ;
clocks = < CLK_BUS_TCON0>, < CLK_TCON0>;
clock-names = "ahb", "tcon-ch0";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
resets = < RST_BUS_TCON0>, < RST_BUS_LVDS>;
reset-names = "lcd", "lvds";
diff --git a/arch/arm/boot/dts/sun8i-v3s.dtsi b/arch/arm/boot/dts/sun8i-v3s.dtsi
index db194c606fdc..ab2a0e1235e4 100644
--- a/arch/arm/boot/dts/sun8i-v3s.dtsi
+++ b/arch/arm/boot/dts/sun8i-v3s.dtsi
@@ -191,7 +191,7 @@ tcon0: lcd-controller@1c0c000 {
 < CLK_TCON0>;
clock-names = "ahb",
  "tcon-ch0";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
resets = < RST_BUS_TCON0>;
reset-names = "lcd";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 62f45f71ec65..e3b17575699c 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -407,7 +407,7 @@ tcon0: lcd-controller@1c0c000 {
interrupts = ;
clocks = < CLK_BUS_TCON0>, < CLK_TCON0>;
clock-names = "ahb", "tcon-ch0";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
resets = < RST_BUS_TCON0>, < RST_BUS_LVDS>;
reset-names = "lcd", "lvds";
-- 
2.32.0 (Apple Git-132)



[PATCH v4 1/4] clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux

2023-05-04 Thread Roman Beranek
TCON0's source clock can be fed from either PLL_MIPI, or PLL_VIDEO0(2X),
however MIPI DSI output only seems to work when PLL_MIPI is selected and
thus the choice must be hardcoded in.

Currently, this driver can't propagate rate change from N-K-M clocks
(such as PLL_MIPI) upwards. This prevents PLL_VIDEO0 from participating
in setting of the TCON0 data clock rate, limiting the precision with
which a target pixel clock can be matched.

For outputs with fixed TCON0 divider, that is DSI and LVDS, the dotclock
can deviate up to 8% off target.

Signed-off-by: Roman Beranek 
---
 drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c 
b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
index 41519185600a..eb36f8f77d55 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
@@ -528,11 +528,18 @@ static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
 0x104, 0, 4, 24, 3, BIT(31),
 CLK_SET_RATE_PARENT);
 
+/*
+ * DSI output seems to work only when PLL_MIPI selected. Set it and prevent
+ * the mux from reparenting.
+ */
+#define SUN50I_A64_TCON0_CLK_REG   0x118
+
 static const char * const tcon0_parents[] = { "pll-mipi", "pll-video0-2x" };
 static const u8 tcon0_table[] = { 0, 2, };
 static SUNXI_CCU_MUX_TABLE_WITH_GATE(tcon0_clk, "tcon0", tcon0_parents,
 tcon0_table, 0x118, 24, 3, BIT(31),
-CLK_SET_RATE_PARENT);
+CLK_SET_RATE_PARENT |
+CLK_SET_RATE_NO_REPARENT);
 
 static const char * const tcon1_parents[] = { "pll-video0", "pll-video1" };
 static const u8 tcon1_table[] = { 0, 2, };
@@ -953,6 +960,11 @@ static int sun50i_a64_ccu_probe(struct platform_device 
*pdev)
 
writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG);
 
+   /* Set PLL MIPI as parent for TCON0 */
+   val = readl(reg + SUN50I_A64_TCON0_CLK_REG);
+   val &= ~GENMASK(26, 24);
+   writel(val | (0 << 24), reg + SUN50I_A64_TCON0_CLK_REG);
+
ret = devm_sunxi_ccu_probe(>dev, reg, _a64_ccu_desc);
if (ret)
return ret;
-- 
2.32.0 (Apple Git-132)



[PATCH v4 0/4] drm: sun4i: set proper TCON0 DCLK rate in DSI mode

2023-05-04 Thread Roman Beranek


According to Allwinner's BSP code, in DSI mode, TCON0 clock needs to be
running at what's effectively the per-lane datarate of the DSI link.
Given that the TCON DCLK divider is fixed to 4 (SUN6I_DSI_TCON_DIV),
DCLK can't be set equal to the dotclock. Therefore labeling TCON DCLK
as sun4i_dotclock or tcon-pixel-clock shall be avoided.

With bpp bits per pixel transmitted over n DSI lanes, the target DCLK
rate for a given pixel clock is obtained as follows:

DCLK rate = 1/4 * bpp / n * pixel clock

Effect of this change can be observed through the rate of Vblank IRQs
which should now match refresh rate implied by set display mode. It
was verified to do so on a A64 board with a 2-lane and a 4-lane panel.

v2:
1. prevent reparent of tcon0 to pll-video0-2x
2. include pll-video0 in setting TCON0 DCLK rate
3. tested the whole thing also on a PinePhone

v3:
1. accept that pll-video0 can't be included in setting TCON0 DCLK rate
2. reset pll-video0 to its default rate in case u-boot changed it

v4:
1. keep pll-video0 as is
2. assign parent to TCON0 mux in sun50i_a64_ccu_probe (not in DT)

Roman Beranek (4):
  clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux
  ARM: dts: sunxi: rename tcon's clock output
  drm: sun4i: rename sun4i_dotclock to sun4i_tcon_dclk
  drm: sun4i: calculate proper DCLK rate for DSI

 arch/arm/boot/dts/sun5i.dtsi  |  2 +-
 arch/arm/boot/dts/sun8i-a23-a33.dtsi  |  2 +-
 arch/arm/boot/dts/sun8i-a83t.dtsi |  2 +-
 arch/arm/boot/dts/sun8i-v3s.dtsi  |  2 +-
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi |  2 +-
 drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 14 +-
 drivers/gpu/drm/sun4i/Makefile|  2 +-
 drivers/gpu/drm/sun4i/sun4i_tcon.c| 46 +++
 .../{sun4i_dotclock.c => sun4i_tcon_dclk.c}   |  2 +-
 .../{sun4i_dotclock.h => sun4i_tcon_dclk.h}   |  0
 10 files changed, 46 insertions(+), 28 deletions(-)
 rename drivers/gpu/drm/sun4i/{sun4i_dotclock.c => sun4i_tcon_dclk.c} (99%)
 rename drivers/gpu/drm/sun4i/{sun4i_dotclock.h => sun4i_tcon_dclk.h} (100%)


base-commit: 8a91b29f1f50ce7742cdbe5cf11d17f128511f3f
-- 
2.32.0 (Apple Git-132)


Re: [PATCH v2 0/7] drm: sun4i: set proper TCON0 DCLK rate in DSI mode

2023-05-04 Thread Roman Beranek
Hello everyone,

I apologize for my absence from the discussion during past week, I got
hit with tonsillitis.

On Mon May 1, 2023 at 3:40 PM CEST, Frank Oltmanns wrote:
> Looking at ccu_nkm_determine_rate(), we've found our culprit because it
> does not try parent clock rates other than the current one. The same
> applies to all other ccu_nkm_* functions.

Yes, that's why I dropped CLK_SET_RATE_PARENT from pll-mipi in v3.

>  b. Add functionality to ccu_nkm_* to also update the parent clock rate.
>
> I'm actually interested in tackling b, but I can't make any promises as
> to if and when I'll be able to solve it. I'm not certain about any side
> effects this might have.

It sounds like an interesting exercise. But what if HDMI is then added
to the mix?

Best regards
Roman


[PATCH v3 7/7] drm: sun4i: calculate proper DCLK rate for DSI

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

Signed-off-by: Roman Beranek 
---
 drivers/gpu/drm/sun4i/sun4i_tcon.c | 36 +-
 1 file changed, 21 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c 
b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index eec26b1faa4b..b263de7a8237 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -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);
-- 
2.34.1



[PATCH v3 4/7] arm64: dts: allwinner: a64: reset pll-video0 rate

2023-04-28 Thread Roman Beranek
With pll-mipi as its source clock, the exact rate to which TCON0's data
clock can be set to is constrained by the current rate of pll-video0.
Unless changed on a request of another consumer, the rate of pll-video0
is left as inherited from the bootloader.

The default rate on reset is 297 MHz, a value preferable to what it is
later set to in u-boot (294 MHz). This happens unintentionally though,
as u-boot, for the sake of simplicity, rounds the rate requested by DE2
driver (297 MHz) to 6 MHz steps.

Reset the PLL to its default rate of 297 MHz.

Signed-off-by: Roman Beranek 
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index e6a194db420d..cfc60dce80b0 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -667,6 +667,9 @@ ccu: clock@1c2 {
clock-names = "hosc", "losc";
#clock-cells = <1>;
#reset-cells = <1>;
+
+   assigned-clocks = < CLK_PLL_VIDEO0>;
+   assigned-clock-rates = <29700>;
};
 
pio: pinctrl@1c20800 {
-- 
2.34.1



[PATCH v3 5/7] ARM: dts: sunxi: rename tcon's clock output

2023-04-28 Thread Roman Beranek
While the rate of TCON0's DCLK matches dotclock for parallel and LVDS
outputs, this doesn't hold for DSI. According manuals from Allwinner,
DCLK is an abbreviation of Data Clock, not dotclock, so go with that
instead.

Signed-off-by: Roman Beranek 
---
 arch/arm/boot/dts/sun5i.dtsi  | 2 +-
 arch/arm/boot/dts/sun8i-a23-a33.dtsi  | 2 +-
 arch/arm/boot/dts/sun8i-a83t.dtsi | 2 +-
 arch/arm/boot/dts/sun8i-v3s.dtsi  | 2 +-
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/sun5i.dtsi b/arch/arm/boot/dts/sun5i.dtsi
index 250d6b87ab4d..2f901a013676 100644
--- a/arch/arm/boot/dts/sun5i.dtsi
+++ b/arch/arm/boot/dts/sun5i.dtsi
@@ -286,7 +286,7 @@ tcon0: lcd-controller@1c0c000 {
clock-names = "ahb",
  "tcon-ch0",
  "tcon-ch1";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
status = "disabled";
 
diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi 
b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
index f630ab55bb6a..ddc87cc15e51 100644
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
@@ -190,7 +190,7 @@ tcon0: lcd-controller@1c0c000 {
clock-names = "ahb",
  "tcon-ch0",
  "lvds-alt";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
resets = < RST_BUS_LCD>,
 < RST_BUS_LVDS>;
diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi 
b/arch/arm/boot/dts/sun8i-a83t.dtsi
index 82fdb04122ca..94eb3bfc989e 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -456,7 +456,7 @@ tcon0: lcd-controller@1c0c000 {
interrupts = ;
clocks = < CLK_BUS_TCON0>, < CLK_TCON0>;
clock-names = "ahb", "tcon-ch0";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
resets = < RST_BUS_TCON0>, < RST_BUS_LVDS>;
reset-names = "lcd", "lvds";
diff --git a/arch/arm/boot/dts/sun8i-v3s.dtsi b/arch/arm/boot/dts/sun8i-v3s.dtsi
index db194c606fdc..ab2a0e1235e4 100644
--- a/arch/arm/boot/dts/sun8i-v3s.dtsi
+++ b/arch/arm/boot/dts/sun8i-v3s.dtsi
@@ -191,7 +191,7 @@ tcon0: lcd-controller@1c0c000 {
 < CLK_TCON0>;
clock-names = "ahb",
  "tcon-ch0";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
resets = < RST_BUS_TCON0>;
reset-names = "lcd";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index cfc60dce80b0..b40474c92d48 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -407,7 +407,7 @@ tcon0: lcd-controller@1c0c000 {
interrupts = ;
clocks = < CLK_BUS_TCON0>, < CLK_TCON0>;
clock-names = "ahb", "tcon-ch0";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
resets = < RST_BUS_TCON0>, < RST_BUS_LVDS>;
reset-names = "lcd", "lvds";
-- 
2.34.1



[PATCH v3 2/7] clk: sunxi-ng: a64: prevent CLK_TCON0 being reparented

2023-04-28 Thread Roman Beranek
TCON0's source clock can be fed from either pll-mipi, or pll-video0-2x,
however MIPI DSI output only seem to work when pll-mipi is selected and
thus some restriction have to be put on reparenting CLK_TCON0.

Functionally, there's no harm to other TCON0 users (LVDS, parallel RGB)
in also forcing them to settle on pll-mipi. The parent will be assigned
during boot based off of tcon0's DT node.

Signed-off-by: Roman Beranek 
---
 drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c 
b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
index 41519185600a..044f301a8c61 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
@@ -532,7 +532,8 @@ static const char * const tcon0_parents[] = { "pll-mipi", 
"pll-video0-2x" };
 static const u8 tcon0_table[] = { 0, 2, };
 static SUNXI_CCU_MUX_TABLE_WITH_GATE(tcon0_clk, "tcon0", tcon0_parents,
 tcon0_table, 0x118, 24, 3, BIT(31),
-CLK_SET_RATE_PARENT);
+CLK_SET_RATE_PARENT |
+CLK_SET_RATE_NO_REPARENT);
 
 static const char * const tcon1_parents[] = { "pll-video0", "pll-video1" };
 static const u8 tcon1_table[] = { 0, 2, };
-- 
2.34.1



[PATCH v3 6/7] drm: sun4i: rename sun4i_dotclock to sun4i_tcon_dclk

2023-04-28 Thread Roman Beranek
While the rate of TCON0's DCLK matches dotclock for parallel and LVDS
outputs, this doesn't hold for DSI. The 'D' in DCLK actually stands for
'Data' according to Allwinner's manuals. The clock is mostly referred to
as dclk throughout this driver already anyway, so stick with that.

Signed-off-by: Roman Beranek 
---
 drivers/gpu/drm/sun4i/Makefile |  2 +-
 drivers/gpu/drm/sun4i/sun4i_tcon.c | 10 +-
 .../drm/sun4i/{sun4i_dotclock.c => sun4i_tcon_dclk.c}  |  2 +-
 .../drm/sun4i/{sun4i_dotclock.h => sun4i_tcon_dclk.h}  |  0
 4 files changed, 7 insertions(+), 7 deletions(-)
 rename drivers/gpu/drm/sun4i/{sun4i_dotclock.c => sun4i_tcon_dclk.c} (99%)
 rename drivers/gpu/drm/sun4i/{sun4i_dotclock.h => sun4i_tcon_dclk.h} (100%)

diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile
index 0d04f2447b01..bad7497a0d11 100644
--- a/drivers/gpu/drm/sun4i/Makefile
+++ b/drivers/gpu/drm/sun4i/Makefile
@@ -19,7 +19,7 @@ sun8i-mixer-y += sun8i_mixer.o 
sun8i_ui_layer.o \
   sun8i_vi_scaler.o sun8i_csc.o
 
 sun4i-tcon-y   += sun4i_crtc.o
-sun4i-tcon-y   += sun4i_dotclock.o
+sun4i-tcon-y   += sun4i_tcon_dclk.o
 sun4i-tcon-y   += sun4i_lvds.o
 sun4i-tcon-y   += sun4i_tcon.o
 sun4i-tcon-y   += sun4i_rgb.o
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c 
b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 523a6d787921..eec26b1faa4b 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -31,12 +31,12 @@
 #include 
 
 #include "sun4i_crtc.h"
-#include "sun4i_dotclock.h"
 #include "sun4i_drv.h"
 #include "sun4i_lvds.h"
 #include "sun4i_rgb.h"
 #include "sun4i_tcon.h"
 #include "sun6i_mipi_dsi.h"
+#include "sun4i_tcon_dclk.h"
 #include "sun8i_tcon_top.h"
 #include "sunxi_engine.h"
 
@@ -1237,14 +1237,14 @@ static int sun4i_tcon_bind(struct device *dev, struct 
device *master,
ret = sun4i_tcon_init_irq(dev, tcon);
if (ret) {
dev_err(dev, "Couldn't init our TCON interrupts\n");
-   goto err_free_dotclock;
+   goto err_free_dclk;
}
 
tcon->crtc = sun4i_crtc_init(drm, engine, tcon);
if (IS_ERR(tcon->crtc)) {
dev_err(dev, "Couldn't create our CRTC\n");
ret = PTR_ERR(tcon->crtc);
-   goto err_free_dotclock;
+   goto err_free_dclk;
}
 
if (tcon->quirks->has_channel_0) {
@@ -1264,7 +1264,7 @@ static int sun4i_tcon_bind(struct device *dev, struct 
device *master,
of_node_put(remote);
 
if (ret < 0)
-   goto err_free_dotclock;
+   goto err_free_dclk;
}
 
if (tcon->quirks->needs_de_be_mux) {
@@ -1290,7 +1290,7 @@ static int sun4i_tcon_bind(struct device *dev, struct 
device *master,
 
return 0;
 
-err_free_dotclock:
+err_free_dclk:
if (tcon->quirks->has_channel_0)
sun4i_dclk_free(tcon);
 err_free_clocks:
diff --git a/drivers/gpu/drm/sun4i/sun4i_dotclock.c 
b/drivers/gpu/drm/sun4i/sun4i_tcon_dclk.c
similarity index 99%
rename from drivers/gpu/drm/sun4i/sun4i_dotclock.c
rename to drivers/gpu/drm/sun4i/sun4i_tcon_dclk.c
index 417ade3d2565..03d7de1911cd 100644
--- a/drivers/gpu/drm/sun4i/sun4i_dotclock.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon_dclk.c
@@ -10,7 +10,7 @@
 #include 
 
 #include "sun4i_tcon.h"
-#include "sun4i_dotclock.h"
+#include "sun4i_tcon_dclk.h"
 
 struct sun4i_dclk {
struct clk_hw   hw;
diff --git a/drivers/gpu/drm/sun4i/sun4i_dotclock.h 
b/drivers/gpu/drm/sun4i/sun4i_tcon_dclk.h
similarity index 100%
rename from drivers/gpu/drm/sun4i/sun4i_dotclock.h
rename to drivers/gpu/drm/sun4i/sun4i_tcon_dclk.h
-- 
2.34.1



[PATCH v3 1/7] clk: sunxi-ng: a64: export PLL_MIPI

2023-04-28 Thread Roman Beranek
PLL_MIPI will be referenced as assigned parent to TCON0

Signed-off-by: Roman Beranek 
---
 drivers/clk/sunxi-ng/ccu-sun50i-a64.h  | 4 +++-
 include/dt-bindings/clock/sun50i-a64-ccu.h | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h 
b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
index a8c11c0b4e06..35ab84e03e77 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
@@ -32,7 +32,9 @@
 #define CLK_PLL_PERIPH1_2X 14
 #define CLK_PLL_VIDEO1 15
 #define CLK_PLL_GPU16
-#define CLK_PLL_MIPI   17
+
+/* PLL_MIPI exported for TCON0 */
+
 #define CLK_PLL_HSIC   18
 #define CLK_PLL_DE 19
 #define CLK_PLL_DDR1   20
diff --git a/include/dt-bindings/clock/sun50i-a64-ccu.h 
b/include/dt-bindings/clock/sun50i-a64-ccu.h
index 175892189e9d..5ad769a29c4e 100644
--- a/include/dt-bindings/clock/sun50i-a64-ccu.h
+++ b/include/dt-bindings/clock/sun50i-a64-ccu.h
@@ -45,6 +45,7 @@
 
 #define CLK_PLL_VIDEO0 7
 #define CLK_PLL_PERIPH011
+#define CLK_PLL_MIPI   17
 
 #define CLK_CPUX   21
 #define CLK_BUS_MIPI_DSI   28
-- 
2.34.1



[PATCH v3 3/7] arm64: dts: allwinner: a64: assign PLL_MIPI to CLK_TCON0

2023-04-28 Thread Roman Beranek
Assign pll-mipi parent to tcon0's source clock via 'assigned-clocks'.

Signed-off-by: Roman Beranek 
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 62f45f71ec65..e6a194db420d 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -411,6 +411,8 @@ tcon0: lcd-controller@1c0c000 {
#clock-cells = <0>;
resets = < RST_BUS_TCON0>, < RST_BUS_LVDS>;
reset-names = "lcd", "lvds";
+   assigned-clocks = < CLK_TCON0>;
+   assigned-clock-parents = < CLK_PLL_MIPI>;
 
ports {
#address-cells = <1>;
-- 
2.34.1



[PATCH v3 0/7] drm: sun4i: set proper TCON0 DCLK rate in DSI mode

2023-04-28 Thread Roman Beranek
According to Allwinner's BSP code, in DSI mode, TCON0 clock needs to be
running at what's effectively the per-lane datarate of the DSI link.
Given that the TCON DCLK divider is fixed to 4 (SUN6I_DSI_TCON_DIV),
DCLK can't be set equal to the dotclock. Therefore labeling TCON DCLK
as sun4i_dotclock or tcon-pixel-clock shall be avoided.

With bpp bits per pixel transmitted over n DSI lanes, the target DCLK
rate for a given pixel clock is obtained as follows:

DCLK rate = 1/4 * bpp / n * pixel clock

Effect of this change can be observed through the rate of Vblank IRQs
which should now match refresh rate implied by set display mode. It
was verified to do so on a A64 board with a 2-lane and a 4-lane panel.

v2:
1. prevent reparent of tcon0 to pll-video0-2x
2. include pll-video0 in setting TCON0 DCLK rate
3. tested the whole thing also on a PinePhone

v3:
1. accept that pll-video0 can't be included in setting TCON0 DCLK rate
2. reset pll-video0 to its default rate in case u-boot changed it

Roman Beranek (7):
  clk: sunxi-ng: a64: export PLL_MIPI
  clk: sunxi-ng: a64: prevent CLK_TCON0 being reparented
  arm64: dts: allwinner: a64: assign PLL_MIPI to CLK_TCON0
  arm64: dts: allwinner: a64: reset pll-video0 rate
  ARM: dts: sunxi: rename tcon's clock output
  drm: sun4i: rename sun4i_dotclock to sun4i_tcon_dclk
  drm: sun4i: calculate proper DCLK rate for DSI

 arch/arm/boot/dts/sun5i.dtsi  |  2 +-
 arch/arm/boot/dts/sun8i-a23-a33.dtsi  |  2 +-
 arch/arm/boot/dts/sun8i-a83t.dtsi |  2 +-
 arch/arm/boot/dts/sun8i-v3s.dtsi  |  2 +-
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi |  7 ++-
 drivers/clk/sunxi-ng/ccu-sun50i-a64.c |  3 +-
 drivers/clk/sunxi-ng/ccu-sun50i-a64.h |  4 +-
 drivers/gpu/drm/sun4i/Makefile|  2 +-
 drivers/gpu/drm/sun4i/sun4i_tcon.c| 46 +++
 .../{sun4i_dotclock.c => sun4i_tcon_dclk.c}   |  2 +-
 .../{sun4i_dotclock.h => sun4i_tcon_dclk.h}   |  0
 include/dt-bindings/clock/sun50i-a64-ccu.h|  1 +
 12 files changed, 44 insertions(+), 29 deletions(-)
 rename drivers/gpu/drm/sun4i/{sun4i_dotclock.c => sun4i_tcon_dclk.c} (99%)
 rename drivers/gpu/drm/sun4i/{sun4i_dotclock.h => sun4i_tcon_dclk.h} (100%)


base-commit: 40aeab044a352b9af106960542257c1b9b652e8a
-- 
2.34.1



[PATCH v2 6/7] drm: sun4i: rename sun4i_dotclock to sun4i_tcon_dclk

2023-04-20 Thread Roman Beranek
While the rate of TCON0's DCLK matches dotclock for parallel and LVDS
outputs, this doesn't hold for DSI. The 'D' in DCLK actually stands for
'Data' according to Allwinner's manuals. The clock is mostly referred to
as dclk throughout this driver already anyway, so stick with that.

Signed-off-by: Roman Beranek 
---
 drivers/gpu/drm/sun4i/Makefile |  2 +-
 drivers/gpu/drm/sun4i/sun4i_tcon.c | 10 +-
 .../drm/sun4i/{sun4i_dotclock.c => sun4i_tcon_dclk.c}  |  2 +-
 .../drm/sun4i/{sun4i_dotclock.h => sun4i_tcon_dclk.h}  |  0
 4 files changed, 7 insertions(+), 7 deletions(-)
 rename drivers/gpu/drm/sun4i/{sun4i_dotclock.c => sun4i_tcon_dclk.c} (99%)
 rename drivers/gpu/drm/sun4i/{sun4i_dotclock.h => sun4i_tcon_dclk.h} (100%)

diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile
index 0d04f2447b01..bad7497a0d11 100644
--- a/drivers/gpu/drm/sun4i/Makefile
+++ b/drivers/gpu/drm/sun4i/Makefile
@@ -19,7 +19,7 @@ sun8i-mixer-y += sun8i_mixer.o 
sun8i_ui_layer.o \
   sun8i_vi_scaler.o sun8i_csc.o
 
 sun4i-tcon-y   += sun4i_crtc.o
-sun4i-tcon-y   += sun4i_dotclock.o
+sun4i-tcon-y   += sun4i_tcon_dclk.o
 sun4i-tcon-y   += sun4i_lvds.o
 sun4i-tcon-y   += sun4i_tcon.o
 sun4i-tcon-y   += sun4i_rgb.o
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c 
b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 523a6d787921..eec26b1faa4b 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -31,12 +31,12 @@
 #include 
 
 #include "sun4i_crtc.h"
-#include "sun4i_dotclock.h"
 #include "sun4i_drv.h"
 #include "sun4i_lvds.h"
 #include "sun4i_rgb.h"
 #include "sun4i_tcon.h"
 #include "sun6i_mipi_dsi.h"
+#include "sun4i_tcon_dclk.h"
 #include "sun8i_tcon_top.h"
 #include "sunxi_engine.h"
 
@@ -1237,14 +1237,14 @@ static int sun4i_tcon_bind(struct device *dev, struct 
device *master,
ret = sun4i_tcon_init_irq(dev, tcon);
if (ret) {
dev_err(dev, "Couldn't init our TCON interrupts\n");
-   goto err_free_dotclock;
+   goto err_free_dclk;
}
 
tcon->crtc = sun4i_crtc_init(drm, engine, tcon);
if (IS_ERR(tcon->crtc)) {
dev_err(dev, "Couldn't create our CRTC\n");
ret = PTR_ERR(tcon->crtc);
-   goto err_free_dotclock;
+   goto err_free_dclk;
}
 
if (tcon->quirks->has_channel_0) {
@@ -1264,7 +1264,7 @@ static int sun4i_tcon_bind(struct device *dev, struct 
device *master,
of_node_put(remote);
 
if (ret < 0)
-   goto err_free_dotclock;
+   goto err_free_dclk;
}
 
if (tcon->quirks->needs_de_be_mux) {
@@ -1290,7 +1290,7 @@ static int sun4i_tcon_bind(struct device *dev, struct 
device *master,
 
return 0;
 
-err_free_dotclock:
+err_free_dclk:
if (tcon->quirks->has_channel_0)
sun4i_dclk_free(tcon);
 err_free_clocks:
diff --git a/drivers/gpu/drm/sun4i/sun4i_dotclock.c 
b/drivers/gpu/drm/sun4i/sun4i_tcon_dclk.c
similarity index 99%
rename from drivers/gpu/drm/sun4i/sun4i_dotclock.c
rename to drivers/gpu/drm/sun4i/sun4i_tcon_dclk.c
index 417ade3d2565..03d7de1911cd 100644
--- a/drivers/gpu/drm/sun4i/sun4i_dotclock.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon_dclk.c
@@ -10,7 +10,7 @@
 #include 
 
 #include "sun4i_tcon.h"
-#include "sun4i_dotclock.h"
+#include "sun4i_tcon_dclk.h"
 
 struct sun4i_dclk {
struct clk_hw   hw;
diff --git a/drivers/gpu/drm/sun4i/sun4i_dotclock.h 
b/drivers/gpu/drm/sun4i/sun4i_tcon_dclk.h
similarity index 100%
rename from drivers/gpu/drm/sun4i/sun4i_dotclock.h
rename to drivers/gpu/drm/sun4i/sun4i_tcon_dclk.h
-- 
2.34.1




[PATCH v2 5/7] ARM: dts: sunxi: rename tcon's clock output

2023-04-20 Thread Roman Beranek
While the rate of TCON0's DCLK matches dotclock for parallel and LVDS
outputs, this doesn't hold for DSI. According manuals from Allwinner,
DCLK is an abbreviation of Data Clock, not dotclock, so go with that
instead.

Signed-off-by: Roman Beranek 
---
 arch/arm/boot/dts/sun5i.dtsi  | 2 +-
 arch/arm/boot/dts/sun8i-a23-a33.dtsi  | 2 +-
 arch/arm/boot/dts/sun8i-a83t.dtsi | 2 +-
 arch/arm/boot/dts/sun8i-v3s.dtsi  | 2 +-
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/sun5i.dtsi b/arch/arm/boot/dts/sun5i.dtsi
index 250d6b87ab4d..2f901a013676 100644
--- a/arch/arm/boot/dts/sun5i.dtsi
+++ b/arch/arm/boot/dts/sun5i.dtsi
@@ -286,7 +286,7 @@ tcon0: lcd-controller@1c0c000 {
clock-names = "ahb",
  "tcon-ch0",
  "tcon-ch1";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
status = "disabled";
 
diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi 
b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
index f630ab55bb6a..ddc87cc15e51 100644
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
@@ -190,7 +190,7 @@ tcon0: lcd-controller@1c0c000 {
clock-names = "ahb",
  "tcon-ch0",
  "lvds-alt";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
resets = < RST_BUS_LCD>,
 < RST_BUS_LVDS>;
diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi 
b/arch/arm/boot/dts/sun8i-a83t.dtsi
index 82fdb04122ca..94eb3bfc989e 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -456,7 +456,7 @@ tcon0: lcd-controller@1c0c000 {
interrupts = ;
clocks = < CLK_BUS_TCON0>, < CLK_TCON0>;
clock-names = "ahb", "tcon-ch0";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
resets = < RST_BUS_TCON0>, < RST_BUS_LVDS>;
reset-names = "lcd", "lvds";
diff --git a/arch/arm/boot/dts/sun8i-v3s.dtsi b/arch/arm/boot/dts/sun8i-v3s.dtsi
index db194c606fdc..ab2a0e1235e4 100644
--- a/arch/arm/boot/dts/sun8i-v3s.dtsi
+++ b/arch/arm/boot/dts/sun8i-v3s.dtsi
@@ -191,7 +191,7 @@ tcon0: lcd-controller@1c0c000 {
 < CLK_TCON0>;
clock-names = "ahb",
  "tcon-ch0";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
resets = < RST_BUS_TCON0>;
reset-names = "lcd";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index e6a194db420d..caf35d2dd5d0 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -407,7 +407,7 @@ tcon0: lcd-controller@1c0c000 {
interrupts = ;
clocks = < CLK_BUS_TCON0>, < CLK_TCON0>;
clock-names = "ahb", "tcon-ch0";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
resets = < RST_BUS_TCON0>, < RST_BUS_LVDS>;
reset-names = "lcd", "lvds";
-- 
2.34.1




[PATCH v2 1/7] clk: sunxi-ng: a64: propagate rate change from pll-mipi

2023-04-20 Thread Roman Beranek
Propagating rate change from tcon0 all the way to pll-video0 allows for
greater precision in matching requested display timing.

Signed-off-by: Roman Beranek 
---
 drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c 
b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
index 41519185600a..dd6212286dcd 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
@@ -179,7 +179,8 @@ static struct ccu_nkm pll_mipi_clk = {
.common = {
.reg= 0x040,
.hw.init= CLK_HW_INIT("pll-mipi", "pll-video0",
- _nkm_ops, 
CLK_SET_RATE_UNGATE),
+ _nkm_ops, CLK_SET_RATE_UNGATE
+ | 
CLK_SET_RATE_PARENT),
},
 };
 
-- 
2.34.1




[PATCH v2 2/7] clk: sunxi-ng: a64: export PLL_MIPI

2023-04-20 Thread Roman Beranek
PLL_MIPI will be referenced as assigned parent to TCON0

Signed-off-by: Roman Beranek 
---
 drivers/clk/sunxi-ng/ccu-sun50i-a64.h  | 4 +++-
 include/dt-bindings/clock/sun50i-a64-ccu.h | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h 
b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
index a8c11c0b4e06..35ab84e03e77 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
@@ -32,7 +32,9 @@
 #define CLK_PLL_PERIPH1_2X 14
 #define CLK_PLL_VIDEO1 15
 #define CLK_PLL_GPU16
-#define CLK_PLL_MIPI   17
+
+/* PLL_MIPI exported for TCON0 */
+
 #define CLK_PLL_HSIC   18
 #define CLK_PLL_DE 19
 #define CLK_PLL_DDR1   20
diff --git a/include/dt-bindings/clock/sun50i-a64-ccu.h 
b/include/dt-bindings/clock/sun50i-a64-ccu.h
index 175892189e9d..5ad769a29c4e 100644
--- a/include/dt-bindings/clock/sun50i-a64-ccu.h
+++ b/include/dt-bindings/clock/sun50i-a64-ccu.h
@@ -45,6 +45,7 @@
 
 #define CLK_PLL_VIDEO0 7
 #define CLK_PLL_PERIPH011
+#define CLK_PLL_MIPI   17
 
 #define CLK_CPUX   21
 #define CLK_BUS_MIPI_DSI   28
-- 
2.34.1




[PATCH v2 4/7] arm64: dts: allwinner: a64: assign PLL_MIPI to CLK_TCON0

2023-04-20 Thread Roman Beranek
Assign pll-mipi parent to tcon0's source clock via 'assigned-clocks'.

Signed-off-by: Roman Beranek 
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 62f45f71ec65..e6a194db420d 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -411,6 +411,8 @@ tcon0: lcd-controller@1c0c000 {
#clock-cells = <0>;
resets = < RST_BUS_TCON0>, < RST_BUS_LVDS>;
reset-names = "lcd", "lvds";
+   assigned-clocks = < CLK_TCON0>;
+   assigned-clock-parents = < CLK_PLL_MIPI>;
 
ports {
#address-cells = <1>;
-- 
2.34.1




[PATCH v2 3/7] clk: sunxi-ng: a64: prevent CLK_TCON0 being reparented

2023-04-20 Thread Roman Beranek
TCON0's source clock can be fed from either pll-mipi, or pll-video0-2x,
however MIPI DSI output only seem to work when pll-mipi is selected and
thus some restriction have to be put on reparenting CLK_TCON0.

Functionally, there's no harm to other TCON0 users (LVDS, parallel RGB)
in also forcing them to settle on pll-mipi. The parent will be assigned
during boot based off of tcon0's DT node.

Signed-off-by: Roman Beranek 
---
 drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c 
b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
index dd6212286dcd..ac9bf4e316bf 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
@@ -533,7 +533,8 @@ static const char * const tcon0_parents[] = { "pll-mipi", 
"pll-video0-2x" };
 static const u8 tcon0_table[] = { 0, 2, };
 static SUNXI_CCU_MUX_TABLE_WITH_GATE(tcon0_clk, "tcon0", tcon0_parents,
 tcon0_table, 0x118, 24, 3, BIT(31),
-CLK_SET_RATE_PARENT);
+CLK_SET_RATE_PARENT |
+CLK_SET_RATE_NO_REPARENT);
 
 static const char * const tcon1_parents[] = { "pll-video0", "pll-video1" };
 static const u8 tcon1_table[] = { 0, 2, };
-- 
2.34.1




[PATCH v2 7/7] drm: sun4i: calculate proper DCLK rate for DSI

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

Signed-off-by: Roman Beranek 
---
 drivers/gpu/drm/sun4i/sun4i_tcon.c | 36 +-
 1 file changed, 21 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c 
b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index eec26b1faa4b..b263de7a8237 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -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);
-- 
2.34.1



[PATCH v2 0/7] drm: sun4i: set proper TCON0 DCLK rate in DSI mode

2023-04-20 Thread Roman Beranek
According to Allwinner's BSP code, in DSI mode, TCON0 clock needs to be
running at what's effectively the per-lane datarate of the DSI link.
Given that the TCON DCLK divider is fixed to 4 (SUN6I_DSI_TCON_DIV),
DCLK can't be set equal to the dotclock. Therefore labeling TCON DCLK
as sun4i_dotclock or tcon-pixel-clock shall be avoided.

With bpp bits per pixel transmitted over n DSI lanes, the target DCLK
rate for a given pixel clock is obtained as follows:

DCLK rate = 1/4 * bpp / n * pixel clock

Effect of this change can be observed through the rate of Vblank IRQs
which should now match refresh rate implied by set display mode. It
was verified to do so on a A64 board with a 2-lane and a 4-lane panel.

v2:
1. prevent reparent of tcon0 to pll-video0-2x
2. include pll-video0 in setting TCON0 DCLK rate
3. tested the whole thing also on a PinePhone 

Roman Beranek (7):
  clk: sunxi-ng: a64: propagate rate change from pll-mipi
  clk: sunxi-ng: a64: export PLL_MIPI
  clk: sunxi-ng: a64: prevent CLK_TCON0 being reparented
  arm64: dts: allwinner: a64: assign PLL_MIPI to CLK_TCON0
  ARM: dts: sunxi: rename tcon's clock output
  drm: sun4i: rename sun4i_dotclock to sun4i_tcon_dclk
  drm: sun4i: calculate proper DCLK rate for DSI

 arch/arm/boot/dts/sun5i.dtsi  |  2 +-
 arch/arm/boot/dts/sun8i-a23-a33.dtsi  |  2 +-
 arch/arm/boot/dts/sun8i-a83t.dtsi |  2 +-
 arch/arm/boot/dts/sun8i-v3s.dtsi  |  2 +-
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi |  4 +-
 drivers/clk/sunxi-ng/ccu-sun50i-a64.c |  6 ++-
 drivers/clk/sunxi-ng/ccu-sun50i-a64.h |  4 +-
 drivers/gpu/drm/sun4i/Makefile|  2 +-
 drivers/gpu/drm/sun4i/sun4i_tcon.c| 46 +++
 .../{sun4i_dotclock.c => sun4i_tcon_dclk.c}   |  2 +-
 .../{sun4i_dotclock.h => sun4i_tcon_dclk.h}   |  0
 include/dt-bindings/clock/sun50i-a64-ccu.h|  1 +
 12 files changed, 43 insertions(+), 30 deletions(-)
 rename drivers/gpu/drm/sun4i/{sun4i_dotclock.c => sun4i_tcon_dclk.c} (99%)
 rename drivers/gpu/drm/sun4i/{sun4i_dotclock.h => sun4i_tcon_dclk.h} (100%)


base-commit: 4aa35a0130d6b8afbefc9ef530a521fb0fb9b8e1
-- 
2.34.1



Re: [PATCH] drm/sun4i: uncouple DSI dotclock divider from TCON0_DCLK_REG

2023-04-12 Thread Roman Beranek
On Wed Apr 5, 2023 at 5:03 PM CEST, Maxime Ripard wrote:
> On Wed, Apr 05, 2023 at 02:34:11PM +0200, Roman Beranek wrote:
> > It turns out however that the new dclk rates can't be set exactly as
> > requested without touching pll-video0*, tcon0 now therefore gets
> > reparented from pll-mipi to pll-video0-2x which, as it further turns
> > out, breaks DSI. While simply forbidding the video0-2x mux option seems
> > to me as the right way to go because there's not much use for it with
> > non-DSI interfaces either besides the opportunity to power pll-mipi
> > down, I'd like to run by you first.
>
> Sounds reasonable

Okay, I'm unsure of how to denote that in the code however. Should I
just comment the parent out of the table and put an explanation in
a comment nearby? Or just erase it? I couldn't find an applicable
precedent.

> > * As pll-mipi doesn't have CLK_SET_RATE_PARENT flag set, pll-video0
> >   retains its boot-time rate of 294 MHz set by sunxi-dw-hdmi driver
> >   in u-boot. Why 294 MHz (as opposed to the default rate of 297 MHz)?
> >   The driver actually asks for 297 MHz, clock_set_pll3 rounds it to
> >   294 MHz though because it limits itself to 6 MHz steps.
>
> We could also address that though

Should I include it in v2 of the series, or leave it for later?

Thanks,
Roman


Re: [PATCH] drm/sun4i: uncouple DSI dotclock divider from TCON0_DCLK_REG

2023-04-11 Thread Roman Beranek
On Sat Apr 8, 2023 at 9:07 AM CEST, Jernej Škrabec wrote:
> Dne sreda, 05. april 2023 ob 14:34:11 CEST je Roman Beranek napisal(a):
> > While simply forbidding the video0-2x mux option seems
> > to me as the right way to go because there's not much use for it with
> > non-DSI interfaces either besides the opportunity to power pll-mipi
> > down, I'd like to run by you first.
>
> It's been a long time since I looked at A64 HDMI clocks, but IIRC, pll-video0 
> is the only useful source for HDMI PHY (as opposed to HDMI controller.)
> So question remains how to properly support both displays at the same time.
>

Correct.

> Have you ever tried to make HDMI and DSI work at the same time? This is one 
> of 
> issues of the PinePhone IIUC.
>

Yes, I have. Prusa3D's SL1 printer, on which I previously worked on,
uses both outputs simultaneously. I had encountered the same reparenting
problem back then but since I hadn't been able to identify it,
I resorted to fiddling with the DSI pixelclock until it worked. 

DSI & HDMI co-existence is yet another reasoni though for forbidding
the pll-video-2x parent. megi's kernel includes Mr. Zheng's commit which
does the same.

<https://github.com/megous/linux/commit/7374d57>

Best wishes
Roman Beranek


Re: [PATCH] drm/sun4i: uncouple DSI dotclock divider from TCON0_DCLK_REG

2023-04-05 Thread Roman Beranek
Hello Maxime,

On Wed Mar 29, 2023 at 9:58 PM CEST, Maxime Ripard wrote:
> > In order to preserve semantic correctness however, I propose to preface
> > the change with a patch that renames sun4i_dotclock and tcon-pixel-clock
> > such that dot/pixel is replaced with d/data. What do you think?
>
> I don't think it's exposed to the userspace in any way so it makes sense to me
>

Here's a new series that includes those renames:


It turns out however that the new dclk rates can't be set exactly as
requested without touching pll-video0*, tcon0 now therefore gets
reparented from pll-mipi to pll-video0-2x which, as it further turns
out, breaks DSI. While simply forbidding the video0-2x mux option seems
to me as the right way to go because there's not much use for it with
non-DSI interfaces either besides the opportunity to power pll-mipi
down, I'd like to run by you first.

Kind regards,
Roman

* As pll-mipi doesn't have CLK_SET_RATE_PARENT flag set, pll-video0
  retains its boot-time rate of 294 MHz set by sunxi-dw-hdmi driver
  in u-boot. Why 294 MHz (as opposed to the default rate of 297 MHz)?
  The driver actually asks for 297 MHz, clock_set_pll3 rounds it to
  294 MHz though because it limits itself to 6 MHz steps.


Re: [PATCH 3/3] drm: sun4i: calculate proper DCLK rate for DSI

2023-04-04 Thread Roman Beranek
On Mon Apr 3, 2023 at 5:08 PM CEST, Frank Oltmanns wrote:
>
> On 2023-04-03 at 15:52:36 +0200, "Roman Beranek"  wrote:
> > As little a change as setting .clock in the default mode of PP's panel
> > to 73500 can fix it. Better yet, dropping pll-video0-2x from the set
> > of acceptable parents for tcon0 fixes it universally. And that's what
> > megi's kernel does, though the measure was introduced with a different
> > rationale:
> > <https://github.com/megous/linux/commit/7374d5756aa0cc3f11e494e3cbc54f6c7c01e1a8>
>
> For sake of completeness, the patch you referenced builds on this patch:
> https://github.com/megous/linux/commit/45e0aa8d9e34
>
> Are you saying that your other boards and panels work without these
> patches?

Yes, that was a bit of an oversight on my side as I wrote drivers for
both panels already with the intention of them being used besides
an HDMI output in mind, so I've deliberately picked a timing in each
case such that the dotclock lines up nicely with pll-video0 at 297 MHz.

All the best
Roman Beranek


Re: [PATCH 3/3] drm: sun4i: calculate proper DCLK rate for DSI

2023-04-04 Thread Roman Beranek
On Sun Apr 2, 2023 at 12:49 PM CEST, Frank Oltmanns wrote:
>
> When apply this to drm-next my panel stays dark. I haven't figured out
> yet why, though. The other two patches in this series work fine, i.e.
> they have no effect as they are just a refactoring.
>
> I'm testing this on my pinephone. It's the same with the patch I
> submitted. For whatever reason, it no longer works on drm-next.

I've reproduced the issue on my PinePhone and noticed that tcon0 had set
pll-video0-2x as its parent instead of pll-mipi. Having tried a whole
range of pll-video0 rates, I'm now convinced that DSI only works when
tcon0 has pll-mipi as its parent.

As little a change as setting .clock in the default mode of PP's panel
to 73500 can fix it. Better yet, dropping pll-video0-2x from the set
of acceptable parents for tcon0 fixes it universally. And that's what
megi's kernel does, though the measure was introduced with a different
rationale:


Roman


[PATCH 1/3] drm: sun4i: rename sun4i_dotclock to sun4i_tcon_dclk

2023-04-01 Thread Roman Beranek
While the rate of TCON0's DCLK matches dotclock for parallel and LVDS
outputs, this doesn't hold for DSI. The 'D' in DCLK actually stands for
'Data' according to Allwinner's manuals. The clock is mostly referred to
as dclk throughout this driver already anyway, so stick with that.

Signed-off-by: Roman Beranek 
---
 drivers/gpu/drm/sun4i/Makefile |  2 +-
 drivers/gpu/drm/sun4i/sun4i_tcon.c | 10 +-
 .../drm/sun4i/{sun4i_dotclock.c => sun4i_tcon_dclk.c}  |  2 +-
 .../drm/sun4i/{sun4i_dotclock.h => sun4i_tcon_dclk.h}  |  0
 4 files changed, 7 insertions(+), 7 deletions(-)
 rename drivers/gpu/drm/sun4i/{sun4i_dotclock.c => sun4i_tcon_dclk.c} (99%)
 rename drivers/gpu/drm/sun4i/{sun4i_dotclock.h => sun4i_tcon_dclk.h} (100%)

diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile
index 0d04f2447b01..bad7497a0d11 100644
--- a/drivers/gpu/drm/sun4i/Makefile
+++ b/drivers/gpu/drm/sun4i/Makefile
@@ -19,7 +19,7 @@ sun8i-mixer-y += sun8i_mixer.o 
sun8i_ui_layer.o \
   sun8i_vi_scaler.o sun8i_csc.o
 
 sun4i-tcon-y   += sun4i_crtc.o
-sun4i-tcon-y   += sun4i_dotclock.o
+sun4i-tcon-y   += sun4i_tcon_dclk.o
 sun4i-tcon-y   += sun4i_lvds.o
 sun4i-tcon-y   += sun4i_tcon.o
 sun4i-tcon-y   += sun4i_rgb.o
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c 
b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 523a6d787921..eec26b1faa4b 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -31,12 +31,12 @@
 #include 
 
 #include "sun4i_crtc.h"
-#include "sun4i_dotclock.h"
 #include "sun4i_drv.h"
 #include "sun4i_lvds.h"
 #include "sun4i_rgb.h"
 #include "sun4i_tcon.h"
 #include "sun6i_mipi_dsi.h"
+#include "sun4i_tcon_dclk.h"
 #include "sun8i_tcon_top.h"
 #include "sunxi_engine.h"
 
@@ -1237,14 +1237,14 @@ static int sun4i_tcon_bind(struct device *dev, struct 
device *master,
ret = sun4i_tcon_init_irq(dev, tcon);
if (ret) {
dev_err(dev, "Couldn't init our TCON interrupts\n");
-   goto err_free_dotclock;
+   goto err_free_dclk;
}
 
tcon->crtc = sun4i_crtc_init(drm, engine, tcon);
if (IS_ERR(tcon->crtc)) {
dev_err(dev, "Couldn't create our CRTC\n");
ret = PTR_ERR(tcon->crtc);
-   goto err_free_dotclock;
+   goto err_free_dclk;
}
 
if (tcon->quirks->has_channel_0) {
@@ -1264,7 +1264,7 @@ static int sun4i_tcon_bind(struct device *dev, struct 
device *master,
of_node_put(remote);
 
if (ret < 0)
-   goto err_free_dotclock;
+   goto err_free_dclk;
}
 
if (tcon->quirks->needs_de_be_mux) {
@@ -1290,7 +1290,7 @@ static int sun4i_tcon_bind(struct device *dev, struct 
device *master,
 
return 0;
 
-err_free_dotclock:
+err_free_dclk:
if (tcon->quirks->has_channel_0)
sun4i_dclk_free(tcon);
 err_free_clocks:
diff --git a/drivers/gpu/drm/sun4i/sun4i_dotclock.c 
b/drivers/gpu/drm/sun4i/sun4i_tcon_dclk.c
similarity index 99%
rename from drivers/gpu/drm/sun4i/sun4i_dotclock.c
rename to drivers/gpu/drm/sun4i/sun4i_tcon_dclk.c
index 417ade3d2565..03d7de1911cd 100644
--- a/drivers/gpu/drm/sun4i/sun4i_dotclock.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon_dclk.c
@@ -10,7 +10,7 @@
 #include 
 
 #include "sun4i_tcon.h"
-#include "sun4i_dotclock.h"
+#include "sun4i_tcon_dclk.h"
 
 struct sun4i_dclk {
struct clk_hw   hw;
diff --git a/drivers/gpu/drm/sun4i/sun4i_dotclock.h 
b/drivers/gpu/drm/sun4i/sun4i_tcon_dclk.h
similarity index 100%
rename from drivers/gpu/drm/sun4i/sun4i_dotclock.h
rename to drivers/gpu/drm/sun4i/sun4i_tcon_dclk.h
-- 
2.32.0 (Apple Git-132)



[PATCH 2/3] ARM: dts: sunxi: rename tcon's clock output

2023-04-01 Thread Roman Beranek
While the rate of TCON0's DCLK matches dotclock for parallel and LVDS
outputs, this doesn't hold for DSI. According manuals from Allwinner,
DCLK is an abbrebiation of Data Clock, not dotclock, so go with that
instead.

Signed-off-by: Roman Beranek 
---
 arch/arm/boot/dts/sun5i.dtsi  | 2 +-
 arch/arm/boot/dts/sun8i-a23-a33.dtsi  | 2 +-
 arch/arm/boot/dts/sun8i-a83t.dtsi | 2 +-
 arch/arm/boot/dts/sun8i-v3s.dtsi  | 2 +-
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/sun5i.dtsi b/arch/arm/boot/dts/sun5i.dtsi
index 250d6b87ab4d..2f901a013676 100644
--- a/arch/arm/boot/dts/sun5i.dtsi
+++ b/arch/arm/boot/dts/sun5i.dtsi
@@ -286,7 +286,7 @@ tcon0: lcd-controller@1c0c000 {
clock-names = "ahb",
  "tcon-ch0",
  "tcon-ch1";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
status = "disabled";
 
diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi 
b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
index f630ab55bb6a..ddc87cc15e51 100644
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
@@ -190,7 +190,7 @@ tcon0: lcd-controller@1c0c000 {
clock-names = "ahb",
  "tcon-ch0",
  "lvds-alt";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
resets = < RST_BUS_LCD>,
 < RST_BUS_LVDS>;
diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi 
b/arch/arm/boot/dts/sun8i-a83t.dtsi
index 82fdb04122ca..94eb3bfc989e 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -456,7 +456,7 @@ tcon0: lcd-controller@1c0c000 {
interrupts = ;
clocks = < CLK_BUS_TCON0>, < CLK_TCON0>;
clock-names = "ahb", "tcon-ch0";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
resets = < RST_BUS_TCON0>, < RST_BUS_LVDS>;
reset-names = "lcd", "lvds";
diff --git a/arch/arm/boot/dts/sun8i-v3s.dtsi b/arch/arm/boot/dts/sun8i-v3s.dtsi
index db194c606fdc..ab2a0e1235e4 100644
--- a/arch/arm/boot/dts/sun8i-v3s.dtsi
+++ b/arch/arm/boot/dts/sun8i-v3s.dtsi
@@ -191,7 +191,7 @@ tcon0: lcd-controller@1c0c000 {
 < CLK_TCON0>;
clock-names = "ahb",
  "tcon-ch0";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
resets = < RST_BUS_TCON0>;
reset-names = "lcd";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 62f45f71ec65..e3b17575699c 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -407,7 +407,7 @@ tcon0: lcd-controller@1c0c000 {
interrupts = ;
clocks = < CLK_BUS_TCON0>, < CLK_TCON0>;
clock-names = "ahb", "tcon-ch0";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
resets = < RST_BUS_TCON0>, < RST_BUS_LVDS>;
reset-names = "lcd", "lvds";
-- 
2.32.0 (Apple Git-132)



[PATCH 3/3] drm: sun4i: calculate proper DCLK rate for DSI

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

Signed-off-by: Roman Beranek 
---
 drivers/gpu/drm/sun4i/sun4i_tcon.c | 36 +-
 1 file changed, 21 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c 
b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index eec26b1faa4b..b263de7a8237 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -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);
-- 
2.32.0 (Apple Git-132)



[PATCH 2/3] ARM: dts: sunxi: rename tcon's clock output

2023-04-01 Thread Roman Beranek
While the rate of TCON0's DCLK matches dotclock for parallel and LVDS
outputs, this doesn't hold for DSI. According manuals from Allwinner,
DCLK is an abbrebiation of Data Clock, not dotclock, so go with that
instead.

Signed-off-by: Roman Beranek 
---
 arch/arm/boot/dts/sun5i.dtsi  | 2 +-
 arch/arm/boot/dts/sun8i-a23-a33.dtsi  | 2 +-
 arch/arm/boot/dts/sun8i-a83t.dtsi | 2 +-
 arch/arm/boot/dts/sun8i-v3s.dtsi  | 2 +-
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/sun5i.dtsi b/arch/arm/boot/dts/sun5i.dtsi
index 250d6b87ab4d..2f901a013676 100644
--- a/arch/arm/boot/dts/sun5i.dtsi
+++ b/arch/arm/boot/dts/sun5i.dtsi
@@ -286,7 +286,7 @@ tcon0: lcd-controller@1c0c000 {
clock-names = "ahb",
  "tcon-ch0",
  "tcon-ch1";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
status = "disabled";
 
diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi 
b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
index f630ab55bb6a..ddc87cc15e51 100644
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
@@ -190,7 +190,7 @@ tcon0: lcd-controller@1c0c000 {
clock-names = "ahb",
  "tcon-ch0",
  "lvds-alt";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
resets = < RST_BUS_LCD>,
 < RST_BUS_LVDS>;
diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi 
b/arch/arm/boot/dts/sun8i-a83t.dtsi
index 82fdb04122ca..94eb3bfc989e 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -456,7 +456,7 @@ tcon0: lcd-controller@1c0c000 {
interrupts = ;
clocks = < CLK_BUS_TCON0>, < CLK_TCON0>;
clock-names = "ahb", "tcon-ch0";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
resets = < RST_BUS_TCON0>, < RST_BUS_LVDS>;
reset-names = "lcd", "lvds";
diff --git a/arch/arm/boot/dts/sun8i-v3s.dtsi b/arch/arm/boot/dts/sun8i-v3s.dtsi
index db194c606fdc..ab2a0e1235e4 100644
--- a/arch/arm/boot/dts/sun8i-v3s.dtsi
+++ b/arch/arm/boot/dts/sun8i-v3s.dtsi
@@ -191,7 +191,7 @@ tcon0: lcd-controller@1c0c000 {
 < CLK_TCON0>;
clock-names = "ahb",
  "tcon-ch0";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
resets = < RST_BUS_TCON0>;
reset-names = "lcd";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 62f45f71ec65..e3b17575699c 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -407,7 +407,7 @@ tcon0: lcd-controller@1c0c000 {
interrupts = ;
clocks = < CLK_BUS_TCON0>, < CLK_TCON0>;
clock-names = "ahb", "tcon-ch0";
-   clock-output-names = "tcon-pixel-clock";
+   clock-output-names = "tcon-data-clock";
#clock-cells = <0>;
resets = < RST_BUS_TCON0>, < RST_BUS_LVDS>;
reset-names = "lcd", "lvds";
-- 
2.32.0 (Apple Git-132)



[PATCH 0/3] drm: sun4i: set proper TCON0 DCLK rate in DSI mode

2023-04-01 Thread Roman Beranek
With bpp bits per pixel transmitted over n DSI lanes, the target DCLK
rate for a given pixel clock is obtained as follows:

DCLK rate = 1/4 * bpp / n * pixel clock

Effect of this change can be observed through the rate of Vblank IRQs
which should now match refresh rate implied by set display mode. It
was verified to do so on a A64 board with a 2-lane and a 4-lane panel.

Roman Beranek (3):
  drm: sun4i: rename sun4i_dotclock to sun4i_tcon_dclk
  ARM: dts: sunxi: rename tcon's clock output
  drm: sun4i: calculate proper DCLK rate for DSI

 arch/arm/boot/dts/sun5i.dtsi  |  2 +-
 arch/arm/boot/dts/sun8i-a23-a33.dtsi  |  2 +-
 arch/arm/boot/dts/sun8i-a83t.dtsi |  2 +-
 arch/arm/boot/dts/sun8i-v3s.dtsi  |  2 +-
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi |  2 +-
 drivers/gpu/drm/sun4i/Makefile|  2 +-
 drivers/gpu/drm/sun4i/sun4i_tcon.c| 46 +++
 .../{sun4i_dotclock.c => sun4i_tcon_dclk.c}   |  2 +-
 .../{sun4i_dotclock.h => sun4i_tcon_dclk.h}   |  0
 9 files changed, 33 insertions(+), 27 deletions(-)
 rename drivers/gpu/drm/sun4i/{sun4i_dotclock.c => sun4i_tcon_dclk.c} (99%)
 rename drivers/gpu/drm/sun4i/{sun4i_dotclock.h => sun4i_tcon_dclk.h} (100%)

--
2.32.0 (Apple Git-132)




Re: [PATCH] drm/sun4i: uncouple DSI dotclock divider from TCON0_DCLK_REG

2023-03-30 Thread Roman Beranek
Hello Frank,

On Thu Mar 30, 2023 at 6:45 AM CEST, Frank Oltmanns wrote:
> Roman, will you please submit a V2 of the patch I submitted then? Or do
> you want me to do it?

Yes, I'm already on it, only missing a cover letter.

Roman


Re: [PATCH] drm/sun4i: uncouple DSI dotclock divider from TCON0_DCLK_REG

2023-03-27 Thread Roman Beranek
On Mon Mar 27, 2023 at 10:20 PM CEST, Maxime Ripard wrote:
>
> On Sat, Mar 25, 2023 at 12:40:04PM +0100, Frank Oltmanns wrote:
> > Claiming to set the divider to a different value (bpp / lanes) than what 
> > we’re actually using in
> > the end (SUN6I_DSIO_TCON_DIV) is somehow bugging me. I feel like the 
> > proposal that I submitted is
> > more direct: 
> > 
>
> Yeah, this patch looks better to me too: it's simpler, more straightforward. 
> If Roman can confirm it
> works with his testing, I'll be happy to merge it.
>

So I've just found out that my understanding of what sun4i_dotclock is
was wrong the whole time. I treated it as a virtual clock representing
the true CRTC pixel clock and only coincidentally also matching what
A64 Reference Manual labels as TCON0 data clock (a coincidence to which
DSI is an exception).

Now that I finally see dotclock as 'what could dclk be an abbreviation
to', I to agree that it's not only straightforward but also correct to
keep the divider at 4 and adjust the rate as is done it the patch Frank
submitted.

In order to preserve semantic correctness however, I propose to preface
the change with a patch that renames sun4i_dotclock and tcon-pixel-clock
such that dot/pixel is replaced with d/data. What do you think?

Roman


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

2023-03-21 Thread Roman Beranek
On Tue Mar 21, 2023 at 8:55 PM CET, Frank Oltmanns wrote:
> 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


Re: [PATCH] drm/sun4i: uncouple DSI dotclock divider from TCON0_DCLK_REG

2023-03-21 Thread Roman Beranek
On Tue Mar 21, 2023 at 5:50 PM CET, Roman Beranek wrote:

> > Also, how was it tested/confirmed?
>
> By counting Vblank interrupts (GIC 118).

Sorry, that was perhaps too abbreviated. To test this change, I set up
an A64 board running kmscube on DSI-1 and verified that the rate of
Vblank IRQs tracked with a video mode set on DSI-1, once with a 2-lane
panel and once with a 4-lane panel.

Roman


Re: [PATCH] drm/sun4i: uncouple DSI dotclock divider from TCON0_DCLK_REG

2023-03-21 Thread Roman Beranek
Hello Maxime,

On Tue Mar 21, 2023 at 3:56 PM CET, Maxime Ripard wrote:
>
> This is similar to
> https://lore.kernel.org/all/20230319160704.9858-2-fr...@oltmanns.dev/
>
> What's the story there?

Yes, Frank Oltmanns wrote me recently in relation to a patch I wrote
~ 3 years ago that addressed the framerate issue, proposing to
collaborate on pushing it upstream, however as I've been keeping up
with my inbox rather sporadically these days, by the time I read his
message, Frank had already taken the initiative and sent the patch.
So that's how we've got to this slightly awkward situation with two
patches on the same subject arriving 1 day apart of each other.

The problem with the original patch was that it went around
sun4i_dotclock by feeding it a rate adjusted such that the pll-mipi rate
was set correctly. I couldn't quite figure out at the time of how big
a portion of the tcon logic does the sun4i_dotclock code need to be made
aware of.

>Also, how was it tested/confirmed?

By counting Vblank interrupts (GIC 118).

Roman


[PATCH] drm/sun4i: uncouple DSI dotclock divider from TCON0_DCLK_REG

2023-03-21 Thread Roman Beranek
In the case of DSI output, the value of SUN4I_TCON0_DCLK_DIV (4) does
not represent the actual dotclock divider, PLL_MIPI instead runs at
(bpp / lanes )-multiple [1] of the dotclock. [2] Setting 4 as dotclock
divder thus leads to reduced frame rate, specifically by 1/3 on 4-lane
panels, and by 2/3 on 2-lane panels respectively.

As sun4i_dotclock driver stores its calculated divider directly in
the register, conditional handling of the DSI output scenario is needed.
Instead of reading the divider from SUN4I_TCON0_DCLK_REG, retrieve
the value from tcon->dclk_min_div.

[1] bits per pixel / number of DSI lanes
[2] 
https://github.com/BPI-SINOVOIP/BPI-M64-bsp-4.4/blob/66bef0f2f30b367eb93b1cbad21ce85e0361f7ae/linux-sunxi/drivers/video/fbdev/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L322

Signed-off-by: Roman Beranek 
---
 drivers/gpu/drm/sun4i/sun4i_dotclock.c | 6 +-
 drivers/gpu/drm/sun4i/sun4i_tcon.c | 5 +++--
 drivers/gpu/drm/sun4i/sun4i_tcon.h | 1 +
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_dotclock.c 
b/drivers/gpu/drm/sun4i/sun4i_dotclock.c
index 417ade3d2565..26fa99aff590 100644
--- a/drivers/gpu/drm/sun4i/sun4i_dotclock.c
+++ b/drivers/gpu/drm/sun4i/sun4i_dotclock.c
@@ -11,6 +11,7 @@
 
 #include "sun4i_tcon.h"
 #include "sun4i_dotclock.h"
+#include "sun6i_mipi_dsi.h"
 
 struct sun4i_dclk {
struct clk_hw   hw;
@@ -56,6 +57,9 @@ static unsigned long sun4i_dclk_recalc_rate(struct clk_hw *hw,
struct sun4i_dclk *dclk = hw_to_dclk(hw);
u32 val;
 
+   if (dclk->tcon->is_dsi)
+   return parent_rate / dclk->tcon->dclk_min_div;
+
regmap_read(dclk->regmap, SUN4I_TCON0_DCLK_REG, );
 
val >>= SUN4I_TCON0_DCLK_DIV_SHIFT;
@@ -116,7 +120,7 @@ static int sun4i_dclk_set_rate(struct clk_hw *hw, unsigned 
long rate,
   unsigned long parent_rate)
 {
struct sun4i_dclk *dclk = hw_to_dclk(hw);
-   u8 div = parent_rate / rate;
+   u8 div = dclk->tcon->is_dsi ? SUN6I_DSI_TCON_DIV : parent_rate / rate;
 
return regmap_update_bits(dclk->regmap, SUN4I_TCON0_DCLK_REG,
  GENMASK(6, 0), div);
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c 
b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 523a6d787921..7f5d3c135058 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -367,8 +367,9 @@ static void sun4i_tcon0_mode_set_cpu(struct sun4i_tcon 
*tcon,
u32 block_space, start_delay;
u32 tcon_div;
 
-   tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
-   tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
+   tcon->is_dsi = true;
+   tcon->dclk_min_div = bpp / lanes;
+   tcon->dclk_max_div = bpp / lanes;
 
sun4i_tcon0_mode_set_common(tcon, mode);
 
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h 
b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index fa23aa23fe4a..d8150ba2f319 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -271,6 +271,7 @@ struct sun4i_tcon {
struct clk  *dclk;
u8  dclk_max_div;
u8  dclk_min_div;
+   boolis_dsi;
 
/* Reset control */
struct reset_control*lcd_rst;
-- 
2.32.0 (Apple Git-132)