Re: [PATCH v3 08/13] drm/bridge: tc358762: Support VTG

From: Andreas Kemnade

Date: Sun Jun 21 2026 - 02:52:00 EST


On Wed, 13 May 2026 16:10:17 +0300
Tomi Valkeinen <tomi.valkeinen@xxxxxxxxxxxxxxxx> wrote:

> TC358762 can generate the DPI output's timings in two ways, either Video
> Timings Generator (VTG) on or off:
> - VTG off: Duplicate the timings coming from the DSI. This requires DSI
> pulse mode.
> - VTG on: Sync frame on DSI VSync Start, but the exact output timings
> are defined in TC358762 registers. This can be used with DSI
> event/burst mode.
>
> We are currently using VTG off in the driver.
>
> I observe that the hsync signal, on my HW setup, is not 100% stable with
> VTG off, and it seems to lengthen by a single clock every now and then.
> However, it then stabilizes later. To me the DSI input looks solid, but
> that is more challenging to measure exactly. So I have not found the
> root cause for this.
>
> Turning VTG on removes that instability. As I dont' see any downsides
> with enabling VTG (and it would allow extending the driver to use
> event/burst mode in the future), let's always enable the VTG.
>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@xxxxxxxxxxxxxxxx>

Seems to produce beside of HFP the same values as the variant with hard
coded values with the same videomode struct value. So this looks sane.

So based on that.

Reviewed-by: Andreas Kemnade <andreas@xxxxxxxxxxxx>

> ---
> drivers/gpu/drm/bridge/tc358762.c | 33 +++++++++++++++++++++++++++++++++
> 1 file changed, 33 insertions(+)
>
> diff --git a/drivers/gpu/drm/bridge/tc358762.c b/drivers/gpu/drm/bridge/tc358762.c
> index c5734c4df440..2d9491e8e582 100644
> --- a/drivers/gpu/drm/bridge/tc358762.c
> +++ b/drivers/gpu/drm/bridge/tc358762.c
> @@ -19,6 +19,7 @@
> #include <linux/regulator/consumer.h>
>
> #include <video/mipi_display.h>
> +#include <video/videomode.h>
>
> #include <drm/drm_atomic_helper.h>
> #include <drm/drm_bridge.h>
> @@ -64,6 +65,12 @@
> #define LCDCTRL_VSYNC_POL BIT(19) /* Polarity of VSYNC signal */
> #define LCDCTRL_DCLK_POL BIT(20) /* Polarity of pixel clock */
>
> +#define LCDC_HSR_HBPR 0x0424
> +#define LCDC_HDISPR_HFPR 0x0428
> +#define LCDC_VSR_VBPR 0x042C
> +#define LCDC_VDISPR_VFPR 0x0430
> +#define LCDC_VFUEN 0x0434
> +
> /* SPI Master Registers */
> #define SPICMR 0x0450
> #define SPITCR 0x0454
> @@ -95,6 +102,7 @@ struct tc358762 {
> struct drm_display_mode mode;
> bool pre_enabled;
> int error;
> + bool use_vtg;
> };
>
> static int tc358762_clear_error(struct tc358762 *ctx)
> @@ -156,9 +164,31 @@ static int tc358762_init(struct tc358762 *ctx)
> tc358762_write(ctx, PPI_D1S_ATMR, 0);
> tc358762_write(ctx, PPI_LPTXTIMECNT, LPX_PERIOD);
>
> + if (ctx->use_vtg) {
> + struct videomode vm = { 0 };
> +
> + drm_display_mode_to_videomode(&ctx->mode, &vm);
> +
> + tc358762_write(ctx, LCDC_HSR_HBPR,
> + vm.hsync_len | (vm.hback_porch << 16));
> + tc358762_write(ctx, LCDC_HDISPR_HFPR,
> + vm.hactive | (vm.hfront_porch << 16));
> +
> + tc358762_write(ctx, LCDC_VSR_VBPR,
> + vm.vsync_len | (vm.vback_porch << 16));
> + tc358762_write(ctx, LCDC_VDISPR_VFPR,
> + vm.vactive | (vm.vfront_porch << 16));
> +
> + /* Upload VTG timings */
> + tc358762_write(ctx, LCDC_VFUEN, BIT(0));
> + }
> +
> lcdctrl = FIELD_PREP(LCDCTRL_PXLFORM, LCDCTRL_PXLFORM_RGB888) |
> LCDCTRL_DPI_EN;
>
> + if (ctx->use_vtg)
> + lcdctrl |= LCDCTRL_VTGEN;
> +
> lcdctrl |= LCDCTRL_DCLK_POL;
>
> if (ctx->mode.flags & DRM_MODE_FLAG_NHSYNC)
> @@ -306,6 +336,9 @@ static int tc358762_probe(struct mipi_dsi_device *dsi)
> ctx->dev = dev;
> ctx->pre_enabled = false;
>
> + /* Always use VTG */
> + ctx->use_vtg = true;
> +
> /*
> * When using DSI clk for pixel clock (only mode supported in the driver),
> * the pclk is derived directly from the DSI byteclk via simple divider,
>