Hi Prabhakar, Thanks for the patch.
> -----Original Message----- > From: Prabhakar <prabhakar.cse...@gmail.com> > Sent: 30 April 2025 21:41 > Subject: [PATCH v4 13/15] drm: renesas: rz-du: mipi_dsi: Add function > pointers for configuring VCLK > and mode validation > > From: Lad Prabhakar <prabhakar.mahadev-lad...@bp.renesas.com> > > 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...@renesas.com> > Signed-off-by: Fabrizio Castro <fabrizio.castro...@renesas.com> > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad...@bp.renesas.com> Reviewed-by: Biju Das <biju.das...@bp.renesas.com> Cheers, Biju > --- > v3->v4: > - Replaced KILO with MILLI > > v2->v3: > - Replaced unsigned long long with u64 > > v1->v2: > - No changes > --- > .../gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c | 59 +++++++++++++------ > 1 file changed, 42 insertions(+), 17 deletions(-) > > 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 66eef39af35e..df43ff59e08e 100644 > --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > @@ -37,6 +37,10 @@ struct rzg2l_mipi_dsi_hw_info { > int (*dphy_init)(struct rzg2l_mipi_dsi *dsi, u64 hsfreq_millihz); > void (*dphy_late_init)(struct rzg2l_mipi_dsi *dsi); > void (*dphy_exit)(struct rzg2l_mipi_dsi *dsi); > + int (*dphy_conf_clks)(struct rzg2l_mipi_dsi *dsi, unsigned long > mode_freq, > + u64 *hsfreq_millihz); > + unsigned int (*dphy_mode_clk_check)(struct rzg2l_mipi_dsi *dsi, > + unsigned long mode_freq); > u32 phy_reg_offset; > u32 link_reg_offset; > unsigned long max_dclk; > @@ -276,12 +280,36 @@ static void rzg2l_mipi_dsi_dphy_exit(struct > rzg2l_mipi_dsi *dsi) > reset_control_assert(dsi->rstc); > } > > +static int rzg2l_dphy_conf_clks(struct rzg2l_mipi_dsi *dsi, unsigned long > mode_freq, > + u64 *hsfreq_millihz) > +{ > + unsigned long vclk_rate; > + unsigned int bpp; > + > + clk_set_rate(dsi->vclk, mode_freq * MILLI); > + /* > + * Relationship between hsclk and vclk must follow > + * vclk * bpp = hsclk * 8 * lanes > + * where vclk: video clock (Hz) > + * bpp: video pixel bit depth > + * hsclk: DSI HS Byte clock frequency (Hz) > + * lanes: number of data lanes > + * > + * hsclk(bit) = hsclk(byte) * 8 = hsfreq > + */ > + bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); > + vclk_rate = clk_get_rate(dsi->vclk); > + *hsfreq_millihz = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(vclk_rate, bpp * > MILLI), > + dsi->lanes); > + > + return 0; > +} > + > static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi, > const struct drm_display_mode *mode) { > - unsigned long hsfreq, vclk_rate; > + unsigned long hsfreq; > u64 hsfreq_millihz; > - unsigned int bpp; > u32 txsetr; > u32 clstptsetr; > u32 lptrnstsetr; > @@ -295,21 +323,9 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi > *dsi, > if (ret < 0) > return ret; > > - clk_set_rate(dsi->vclk, mode->clock * MILLI); > - > - /* > - * Relationship between hsclk and vclk must follow > - * vclk * bpp = hsclk * 8 * lanes > - * where vclk: video clock (Hz) > - * bpp: video pixel bit depth > - * hsclk: DSI HS Byte clock frequency (Hz) > - * lanes: number of data lanes > - * > - * hsclk(bit) = hsclk(byte) * 8 = hsfreq > - */ > - bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); > - vclk_rate = clk_get_rate(dsi->vclk); > - hsfreq_millihz = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(vclk_rate, bpp * > MILLI), dsi->lanes); > + ret = dsi->info->dphy_conf_clks(dsi, mode->clock, &hsfreq_millihz); > + if (ret < 0) > + goto err_phy; > > ret = dsi->info->dphy_init(dsi, hsfreq_millihz); > if (ret < 0) > @@ -616,6 +632,14 @@ rzg2l_mipi_dsi_bridge_mode_valid(struct drm_bridge > *bridge, > if (mode->clock < dsi->info->min_dclk) > return MODE_CLOCK_LOW; > > + if (dsi->info->dphy_mode_clk_check) { > + enum drm_mode_status status; > + > + status = dsi->info->dphy_mode_clk_check(dsi, mode->clock); > + if (status != MODE_OK) > + return status; > + } > + > return MODE_OK; > } > > @@ -835,6 +859,7 @@ static void rzg2l_mipi_dsi_remove(struct platform_device > *pdev) static const > struct rzg2l_mipi_dsi_hw_info rzg2l_mipi_dsi_info = { > .dphy_init = rzg2l_mipi_dsi_dphy_init, > .dphy_exit = rzg2l_mipi_dsi_dphy_exit, > + .dphy_conf_clks = rzg2l_dphy_conf_clks, > .link_reg_offset = 0x10000, > .max_dclk = 148500, > .min_dclk = 5803, > -- > 2.49.0