From: Lad Prabhakar Date: Mon, 9 Jun 2025 22:56:24 +0000 (+0100) Subject: drm: renesas: rz-du: mipi_dsi: Use VCLK for HSFREQ calculation X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3c55c4f05c7ac4fd741cbe92574598324f843d94;p=thirdparty%2Flinux.git drm: renesas: rz-du: mipi_dsi: Use VCLK for HSFREQ calculation Update the RZ/G2L MIPI DSI driver to calculate HSFREQ using the actual VCLK rate instead of the mode clock. The relationship between HSCLK and VCLK is: vclk * bpp <= hsclk * 8 * lanes Retrieve the VCLK rate using `clk_get_rate(dsi->vclk)`, ensuring that HSFREQ accurately reflects the clock rate set in hardware, leading to better precision in data transmission. Additionally, use `DIV_ROUND_CLOSEST_ULL` for a more precise division when computing `hsfreq`. Also, update unit conversions to use correct scaling factors for better clarity and correctness. Since `clk_get_rate()` returns the clock rate in Hz, update the HSFREQ threshold comparisons to use Hz instead of kHz to ensure correct behavior. Co-developed-by: Fabrizio Castro Signed-off-by: Fabrizio Castro Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Reviewed-by: Laurent Pinchart Signed-off-by: Biju Das Link: https://lore.kernel.org/r/20250609225630.502888-4-prabhakar.mahadev-lad.rj@bp.renesas.com --- diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c index 7fa5bb2a62b64..b08274e5dfcff 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -18,6 +19,7 @@ #include #include #include +#include #include #include @@ -85,7 +87,7 @@ struct rzg2l_mipi_dsi_timings { static const struct rzg2l_mipi_dsi_timings rzg2l_mipi_dsi_global_timings[] = { { - .hsfreq_max = 80000, + .hsfreq_max = 80000000, .t_init = 79801, .tclk_prepare = 8, .ths_prepare = 13, @@ -99,7 +101,7 @@ static const struct rzg2l_mipi_dsi_timings rzg2l_mipi_dsi_global_timings[] = { .tlpx = 6, }, { - .hsfreq_max = 125000, + .hsfreq_max = 125000000, .t_init = 79801, .tclk_prepare = 8, .ths_prepare = 12, @@ -113,7 +115,7 @@ static const struct rzg2l_mipi_dsi_timings rzg2l_mipi_dsi_global_timings[] = { .tlpx = 6, }, { - .hsfreq_max = 250000, + .hsfreq_max = 250000000, .t_init = 79801, .tclk_prepare = 8, .ths_prepare = 12, @@ -127,7 +129,7 @@ static const struct rzg2l_mipi_dsi_timings rzg2l_mipi_dsi_global_timings[] = { .tlpx = 6, }, { - .hsfreq_max = 360000, + .hsfreq_max = 360000000, .t_init = 79801, .tclk_prepare = 8, .ths_prepare = 10, @@ -141,7 +143,7 @@ static const struct rzg2l_mipi_dsi_timings rzg2l_mipi_dsi_global_timings[] = { .tlpx = 6, }, { - .hsfreq_max = 720000, + .hsfreq_max = 720000000, .t_init = 79801, .tclk_prepare = 8, .ths_prepare = 9, @@ -155,7 +157,7 @@ static const struct rzg2l_mipi_dsi_timings rzg2l_mipi_dsi_global_timings[] = { .tlpx = 6, }, { - .hsfreq_max = 1500000, + .hsfreq_max = 1500000000, .t_init = 79801, .tclk_prepare = 8, .ths_prepare = 9, @@ -268,7 +270,7 @@ static void rzg2l_mipi_dsi_dphy_exit(struct rzg2l_mipi_dsi *dsi) static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi, const struct drm_display_mode *mode) { - unsigned long hsfreq; + unsigned long hsfreq, vclk_rate; unsigned int bpp; u32 txsetr; u32 clstptsetr; @@ -280,6 +282,16 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi, u32 dsisetr; int ret; + ret = pm_runtime_resume_and_get(dsi->dev); + if (ret < 0) + return ret; + + clk_set_rate(dsi->vclk, mode->clock * KILO); + vclk_rate = clk_get_rate(dsi->vclk); + if (vclk_rate != mode->clock * KILO) + dev_dbg(dsi->dev, "Requested vclk rate %lu, actual %lu mismatch\n", + mode->clock * KILO, vclk_rate); + /* * Relationship between hsclk and vclk must follow * vclk * bpp = hsclk * 8 * lanes @@ -291,13 +303,7 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi, * hsclk(bit) = hsclk(byte) * 8 = hsfreq */ bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); - hsfreq = mode->clock * bpp / dsi->lanes; - - ret = pm_runtime_resume_and_get(dsi->dev); - if (ret < 0) - return ret; - - clk_set_rate(dsi->vclk, mode->clock * 1000); + hsfreq = DIV_ROUND_CLOSEST_ULL(vclk_rate * bpp, dsi->lanes); ret = rzg2l_mipi_dsi_dphy_init(dsi, hsfreq); if (ret < 0) @@ -315,12 +321,12 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi, * - data lanes: maximum 4 lanes * Therefore maximum hsclk will be 891 Mbps. */ - if (hsfreq > 445500) { + if (hsfreq > 445500000) { clkkpt = 12; clkbfht = 15; clkstpt = 48; golpbkt = 75; - } else if (hsfreq > 250000) { + } else if (hsfreq > 250000000) { clkkpt = 7; clkbfht = 8; clkstpt = 27; @@ -942,7 +948,7 @@ static int rzg2l_mipi_dsi_probe(struct platform_device *pdev) * mode->clock and format are not available. So initialize DPHY with * timing parameters for 80Mbps. */ - ret = rzg2l_mipi_dsi_dphy_init(dsi, 80000); + ret = rzg2l_mipi_dsi_dphy_init(dsi, 80000000); if (ret < 0) goto err_phy;