With the introduction of static input image format enumeration in DRM
bridges, add support to retrieve the format in rcar-lvds LVDS encoder
from both panel or bridge, to set the desired LVDS mode.

Do not rely on 'DRM_BUS_FLAG_DATA_LSB_TO_MSB' flag to mirror the LVDS
format, as it is only defined for drm connectors, but use the newly
introduced _LE version of LVDS mbus image formats.

Signed-off-by: Jacopo Mondi <jacopo+rene...@jmondi.org>
---
 drivers/gpu/drm/rcar-du/rcar_lvds.c | 64 +++++++++++++++++++++++++------------
 1 file changed, 44 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c 
b/drivers/gpu/drm/rcar-du/rcar_lvds.c
index 3d2d3bb..2fa875f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
@@ -280,41 +280,65 @@ static bool rcar_lvds_mode_fixup(struct drm_bridge 
*bridge,
        return true;
 }
 
-static void rcar_lvds_get_lvds_mode(struct rcar_lvds *lvds)
+static int rcar_lvds_get_lvds_mode_from_connector(struct rcar_lvds *lvds,
+                                                 unsigned int *bus_fmt)
 {
        struct drm_display_info *info = &lvds->connector.display_info;
-       enum rcar_lvds_mode mode;
-
-       /*
-        * There is no API yet to retrieve LVDS mode from a bridge, only panels
-        * are supported.
-        */
-       if (!lvds->panel)
-               return;
 
        if (!info->num_bus_formats || !info->bus_formats) {
                dev_err(lvds->dev, "no LVDS bus format reported\n");
-               return;
+               return -EINVAL;
+       }
+
+       *bus_fmt = info->bus_formats[0];
+
+       return 0;
+}
+
+static int rcar_lvds_get_lvds_mode_from_bridge(struct rcar_lvds *lvds,
+                                              unsigned int *bus_fmt)
+{
+       if (!lvds->next_bridge->num_bus_formats ||
+           !lvds->next_bridge->bus_formats) {
+               dev_err(lvds->dev, "no LVDS bus format reported\n");
+               return -EINVAL;
        }
 
-       switch (info->bus_formats[0]) {
+       *bus_fmt = lvds->next_bridge->bus_formats[0];
+
+       return 0;
+}
+
+static void rcar_lvds_get_lvds_mode(struct rcar_lvds *lvds)
+{
+       unsigned int bus_fmt;
+       int ret;
+
+       if (lvds->panel)
+               ret = rcar_lvds_get_lvds_mode_from_connector(lvds, &bus_fmt);
+       else
+               ret = rcar_lvds_get_lvds_mode_from_bridge(lvds, &bus_fmt);
+       if (ret)
+               return;
+
+       switch (bus_fmt) {
+       case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG_LE:
+       case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA_LE:
+               lvds->mode |= RCAR_LVDS_MODE_MIRROR;
        case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
        case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
-               mode = RCAR_LVDS_MODE_JEIDA;
+               lvds->mode = RCAR_LVDS_MODE_JEIDA;
                break;
+
+       case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG_LE:
+               lvds->mode |= RCAR_LVDS_MODE_MIRROR;
        case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
-               mode = RCAR_LVDS_MODE_VESA;
+               lvds->mode = RCAR_LVDS_MODE_VESA;
                break;
        default:
                dev_err(lvds->dev, "unsupported LVDS bus format 0x%04x\n",
-                       info->bus_formats[0]);
-               return;
+                       bus_fmt);
        }
-
-       if (info->bus_flags & DRM_BUS_FLAG_DATA_LSB_TO_MSB)
-               mode |= RCAR_LVDS_MODE_MIRROR;
-
-       lvds->mode = mode;
 }
 
 static void rcar_lvds_mode_set(struct drm_bridge *bridge,
-- 
2.7.4

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to