]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/bridge: imx8mp-hdmi-tx: allow 0.5% margin with selected clock
authorDominique Martinet <dominique.martinet@atmark-techno.com>
Sat, 7 Sep 2024 05:54:33 +0000 (14:54 +0900)
committerNeil Armstrong <neil.armstrong@linaro.org>
Fri, 13 Sep 2024 08:10:16 +0000 (10:10 +0200)
This allows the hdmi driver to pick e.g. 64.8MHz instead of 65Mhz when we
cannot output the exact frequency, enabling the imx8mp HDMI output to
support more modes

Tested-by: Adam Ford <aford173@gmail.com> #imx8mp-beacon
Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
Tested-by: Frieder Schrempf <frieder.schrempf@kontron.de>
Signed-off-by: Dominique Martinet <dominique.martinet@atmark-techno.com>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://lore.kernel.org/r/20240907-hdmi-tolerance-v2-1-b9d7abd89f5c@codewreck.org
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20240907-hdmi-tolerance-v2-1-b9d7abd89f5c@codewreck.org
drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c

index 4a3a8a3ce250ea31631becccda0ae8257c3c0643..8fcc6d18f4ab9b05b8482f9576ade5f7a93dde56 100644 (file)
@@ -23,6 +23,7 @@ imx8mp_hdmi_mode_valid(struct dw_hdmi *dw_hdmi, void *data,
                       const struct drm_display_mode *mode)
 {
        struct imx8mp_hdmi *hdmi = (struct imx8mp_hdmi *)data;
+       long round_rate;
 
        if (mode->clock < 13500)
                return MODE_CLOCK_LOW;
@@ -30,8 +31,14 @@ imx8mp_hdmi_mode_valid(struct dw_hdmi *dw_hdmi, void *data,
        if (mode->clock > 297000)
                return MODE_CLOCK_HIGH;
 
-       if (clk_round_rate(hdmi->pixclk, mode->clock * 1000) !=
-           mode->clock * 1000)
+       round_rate = clk_round_rate(hdmi->pixclk, mode->clock * 1000);
+       /* imx8mp's pixel clock generator (fsl-samsung-hdmi) cannot generate
+        * all possible frequencies, so allow some tolerance to support more
+        * modes.
+        * Allow 0.5% difference allowed in various standards (VESA, CEA861)
+        * 0.5% = 5/1000 tolerance (mode->clock is 1/1000)
+        */
+       if (abs(round_rate - mode->clock * 1000) > mode->clock * 5)
                return MODE_CLOCK_RANGE;
 
        /* We don't support double-clocked and Interlaced modes */