Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm: renesas: rz-du: mipi_dsi: Add function pointers for configuring VCLK and mode validation

Introduce `dphy_conf_clks` and `dphy_mode_clk_check` callbacks in
`rzg2l_mipi_dsi_hw_info` to configure the VCLK and validate
supported display modes.

On the RZ/V2H(P) SoC, the DSI PLL dividers need to be as accurate as
possible. To ensure compatibility with both RZ/G2L and RZ/V2H(P) SoCs,
function pointers are introduced.

Modify `rzg2l_mipi_dsi_startup()` to use `dphy_conf_clks` for clock
configuration and `rzg2l_mipi_dsi_bridge_mode_valid()` to invoke
`dphy_mode_clk_check` for mode validation.

This change ensures proper operation across different SoC variants
by allowing fine-grained control over clock configuration and mode
validation.

Co-developed-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Link: https://lore.kernel.org/r/20250609225630.502888-10-prabhakar.mahadev-lad.rj@bp.renesas.com

authored by

Lad Prabhakar and committed by
Biju Das
e2944dc6 7c1e102c

+45 -20
+45 -20
drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
··· 42 42 int (*dphy_init)(struct rzg2l_mipi_dsi *dsi, u64 hsfreq_millihz); 43 43 void (*dphy_startup_late_init)(struct rzg2l_mipi_dsi *dsi); 44 44 void (*dphy_exit)(struct rzg2l_mipi_dsi *dsi); 45 + int (*dphy_conf_clks)(struct rzg2l_mipi_dsi *dsi, unsigned long mode_freq, 46 + u64 *hsfreq_millihz); 47 + unsigned int (*dphy_mode_clk_check)(struct rzg2l_mipi_dsi *dsi, 48 + unsigned long mode_freq); 45 49 u32 phy_reg_offset; 46 50 u32 link_reg_offset; 47 51 unsigned long min_dclk; ··· 289 285 reset_control_assert(dsi->rstc); 290 286 } 291 287 288 + static int rzg2l_dphy_conf_clks(struct rzg2l_mipi_dsi *dsi, unsigned long mode_freq, 289 + u64 *hsfreq_millihz) 290 + { 291 + unsigned long vclk_rate; 292 + unsigned int bpp; 293 + 294 + clk_set_rate(dsi->vclk, mode_freq * KILO); 295 + vclk_rate = clk_get_rate(dsi->vclk); 296 + if (vclk_rate != mode_freq * KILO) 297 + dev_dbg(dsi->dev, "Requested vclk rate %lu, actual %lu mismatch\n", 298 + mode_freq * KILO, vclk_rate); 299 + /* 300 + * Relationship between hsclk and vclk must follow 301 + * vclk * bpp = hsclk * 8 * lanes 302 + * where vclk: video clock (Hz) 303 + * bpp: video pixel bit depth 304 + * hsclk: DSI HS Byte clock frequency (Hz) 305 + * lanes: number of data lanes 306 + * 307 + * hsclk(bit) = hsclk(byte) * 8 = hsfreq 308 + */ 309 + bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); 310 + *hsfreq_millihz = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(vclk_rate, bpp * MILLI), 311 + dsi->lanes); 312 + 313 + return 0; 314 + } 315 + 292 316 static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi, 293 317 const struct drm_display_mode *mode) 294 318 { 295 - unsigned long hsfreq, vclk_rate; 319 + unsigned long hsfreq; 296 320 u64 hsfreq_millihz; 297 - unsigned int bpp; 298 321 u32 txsetr; 299 322 u32 clstptsetr; 300 323 u32 lptrnstsetr; ··· 336 305 if (ret < 0) 337 306 return ret; 338 307 339 - clk_set_rate(dsi->vclk, mode->clock * KILO); 340 - vclk_rate = clk_get_rate(dsi->vclk); 341 - if (vclk_rate != mode->clock * KILO) 342 - dev_dbg(dsi->dev, "Requested vclk rate %lu, actual %lu mismatch\n", 343 - mode->clock * KILO, vclk_rate); 344 - 345 - /* 346 - * Relationship between hsclk and vclk must follow 347 - * vclk * bpp = hsclk * 8 * lanes 348 - * where vclk: video clock (Hz) 349 - * bpp: video pixel bit depth 350 - * hsclk: DSI HS Byte clock frequency (Hz) 351 - * lanes: number of data lanes 352 - * 353 - * hsclk(bit) = hsclk(byte) * 8 = hsfreq 354 - */ 355 - bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); 356 - hsfreq_millihz = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(vclk_rate, bpp * MILLI), dsi->lanes); 308 + ret = dsi->info->dphy_conf_clks(dsi, mode->clock, &hsfreq_millihz); 309 + if (ret < 0) 310 + goto err_phy; 357 311 358 312 ret = dsi->info->dphy_init(dsi, hsfreq_millihz); 359 313 if (ret < 0) ··· 661 645 662 646 if (mode->clock < dsi->info->min_dclk) 663 647 return MODE_CLOCK_LOW; 648 + 649 + if (dsi->info->dphy_mode_clk_check) { 650 + enum drm_mode_status status; 651 + 652 + status = dsi->info->dphy_mode_clk_check(dsi, mode->clock); 653 + if (status != MODE_OK) 654 + return status; 655 + } 664 656 665 657 return MODE_OK; 666 658 } ··· 1054 1030 static const struct rzg2l_mipi_dsi_hw_info rzg2l_mipi_dsi_info = { 1055 1031 .dphy_init = rzg2l_mipi_dsi_dphy_init, 1056 1032 .dphy_exit = rzg2l_mipi_dsi_dphy_exit, 1033 + .dphy_conf_clks = rzg2l_dphy_conf_clks, 1057 1034 .link_reg_offset = 0x10000, 1058 1035 .min_dclk = 5803, 1059 1036 .max_dclk = 148500,