i.MX93 MIPI DPHY PLL has limitation for matching with some pixel clock
rates, e.g., the best DPHY PLL frequency is 445.333333MHz for a typical
1920x1080p@60Hz CEA/DMT display modes with a pixel clock rate running
at 148.5MHz with 4 data lanes + RGB888 pixel in MIPI DSI sync pulse mode,
while the expected PLL frequency is (148.5 * 24) / 4 / 2 MHz = 445.5MHz.
Fortunately, VESA Display Monitor Timing Standard allows +/-0.5% pixel
clock rate deviation for timings.  So, for those display modes read
from EDID through a bridge with DRM_BRIDGE_OP_DETECT and DRM_BRIDGE_OP_EDID
operation bit masks set, pixel clock rate could be adjusted to match
with the PLL frequency(for the above example, the pixel clock rate is
adjusted to be 148.444444MHz with about -0.03% deviation from the 148.5MHz
nominal rate so that the adjusted rate matches with the 445.333333MHz PLL
frequency).

Instead of checking the last bridge's operation bit masks against
DRM_BRIDGE_OP_DETECT and DRM_BRIDGE_OP_EDID to determine if allowing
+/-0.5% pixel clock rate deviation, check any bridge after this bridge,
because the last bridge is usually a display connector bridge without
any operation bit mask when the clock rate deviation is allowed.

Fixes: ce62f8ea7e3f ("drm/bridge: imx: Add i.MX93 MIPI DSI support")
Fixes: 5849eff7f067 ("drm/bridge: imx93-mipi-dsi: use 
drm_bridge_chain_get_last_bridge()")
Reviewed-by: Frank Li <[email protected]>
Signed-off-by: Liu Ying <[email protected]>
---
Changes in v2:
- Collect Frank's R-b tag.
- Add an explanation to commit message about the reason why mode validation
  checks bridge's operation bit masks.  (Dmitry)
- Copy Dmitry.
- Link to v1: 
https://lore.kernel.org/r/20260227-imx93-mipi-dsi-fix-mode-validation-v1-1-a9cd67991...@nxp.com

To: Liu Ying <[email protected]>
To: Andrzej Hajda <[email protected]>
To: Neil Armstrong <[email protected]>
To: Robert Foss <[email protected]>
To: Laurent Pinchart <[email protected]>
To: Jonas Karlman <[email protected]>
To: Jernej Skrabec <[email protected]>
To: Maarten Lankhorst <[email protected]>
To: Maxime Ripard <[email protected]>
To: Thomas Zimmermann <[email protected]>
To: David Airlie <[email protected]>
To: Simona Vetter <[email protected]>
To: Frank Li <[email protected]>
To: Sascha Hauer <[email protected]>
To: Pengutronix Kernel Team <[email protected]>
To: Fabio Estevam <[email protected]>
To: Luca Ceresoli <[email protected]>
Cc: Dmitry Baryshkov <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
 drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c | 29 ++++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c 
b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c
index 8f312f9edf97..6d65df9ed970 100644
--- a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c
@@ -493,21 +493,24 @@ static enum drm_mode_status
 imx93_dsi_validate_mode(struct imx93_dsi *dsi, const struct drm_display_mode 
*mode)
 {
        struct drm_bridge *dmd_bridge = dw_mipi_dsi_get_bridge(dsi->dmd);
-       struct drm_bridge *last_bridge __free(drm_bridge_put) =
-               drm_bridge_chain_get_last_bridge(dmd_bridge->encoder);
 
-       if ((last_bridge->ops & DRM_BRIDGE_OP_DETECT) &&
-           (last_bridge->ops & DRM_BRIDGE_OP_EDID)) {
-               unsigned long pixel_clock_rate = mode->clock * 1000;
-               unsigned long rounded_rate;
+       drm_for_each_bridge_in_chain_from(dmd_bridge, bridge) {
+               if ((bridge->ops & DRM_BRIDGE_OP_DETECT) &&
+                   (bridge->ops & DRM_BRIDGE_OP_EDID)) {
+                       unsigned long pixel_clock_rate = mode->clock * 1000;
+                       unsigned long rounded_rate;
 
-               /* Allow +/-0.5% pixel clock rate deviation */
-               rounded_rate = clk_round_rate(dsi->clk_pixel, pixel_clock_rate);
-               if (rounded_rate < pixel_clock_rate * 995 / 1000 ||
-                   rounded_rate > pixel_clock_rate * 1005 / 1000) {
-                       dev_dbg(dsi->dev, "failed to round clock for mode " 
DRM_MODE_FMT "\n",
-                               DRM_MODE_ARG(mode));
-                       return MODE_NOCLOCK;
+                       /* Allow +/-0.5% pixel clock rate deviation */
+                       rounded_rate = clk_round_rate(dsi->clk_pixel, 
pixel_clock_rate);
+                       if (rounded_rate < pixel_clock_rate * 995 / 1000 ||
+                           rounded_rate > pixel_clock_rate * 1005 / 1000) {
+                               dev_dbg(dsi->dev,
+                                       "failed to round clock for mode " 
DRM_MODE_FMT "\n",
+                                       DRM_MODE_ARG(mode));
+                               return MODE_NOCLOCK;
+                       }
+
+                       break;
                }
        }
 

---
base-commit: 877552aa875839314afad7154b5a561889e87ea9
change-id: 20260227-imx93-mipi-dsi-fix-mode-validation-425c872a2493

Best regards,
--  
Regards,
Liu Ying

Reply via email to