When the DI cannot be programmed to the requested pixel clock the only symptom is a "flip_done timed out" ten seconds later, because the display never starts and the IDMAC EOF interrupt that ipuv3-crtc uses as its vblank source never arrives. Working out that the clock is at fault currently requires rebuilding with dynamic debug enabled.
Print an error when the rate the DI ends up with differs from the requested one by more than 1%. The CLKMODE_SYNC case is skipped, as there the encoder programs the pixel clock after this runs. Assisted-by: Claude:claude-opus-5 Signed-off-by: Dmitry Baryshkov <[email protected]> --- drivers/gpu/ipu-v3/ipu-di.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/ipu-v3/ipu-di.c b/drivers/gpu/ipu-v3/ipu-di.c index 0a34e0ab4fe6..c971c37356f4 100644 --- a/drivers/gpu/ipu-v3/ipu-di.c +++ b/drivers/gpu/ipu-v3/ipu-di.c @@ -497,6 +497,22 @@ static void ipu_di_config_clock(struct ipu_di *di, clk_get_rate(di->clk_di), clk == di->clk_di ? "DI" : "IPU", clk_get_rate(di->clk_di_pixel) / (clkgen0 >> 4)); + + /* + * With CLKMODE_SYNC the encoder programs the pixel clock after us, so + * there is nothing to check yet. Otherwise the rate is final, and a + * wrong one only shows up later as a "flip_done timed out". + */ + if (!(sig->clkflags & IPU_DI_CLKMODE_SYNC)) { + unsigned long rate = clk_get_rate(di->clk_di_pixel) / + (clkgen0 >> 4); + + if (abs((long)(rate - sig->mode.pixelclock)) > + sig->mode.pixelclock / 100) + dev_err(di->ipu->dev, + "DI%d: cannot generate %luHz pixel clock, got %luHz\n", + di->id, sig->mode.pixelclock, rate); + } } /* -- 2.47.3
