drm: Code stereo layouts as an enum rather than a bit field
authorDamien Lespiau <damien.lespiau@intel.com>
Fri, 27 Sep 2013 11:11:48 +0000 (12:11 +0100)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 1 Oct 2013 05:45:44 +0000 (07:45 +0200)
This allows us to use fewer bits in the mode structure, leaving room for
future work while allowing more stereo layouts types than we could have
ever dreamt of.

I also exposed the previously private DRM_MODE_FLAG_3D_MASK to set in
stone that we are using 5 bits for the stereo layout enum, reserving 32
values.

Even with that reservation, we gain 3 bits from the previous encoding.

The code adding the mandatory stereo modes needeed to be adapted as it was
relying or being able to or stereo layouts together.

Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/drm_edid.c
include/drm/drm_crtc.h
include/uapi/drm/drm_mode.h

index c24af1d..7d1e8a9 100644 (file)
@@ -2562,16 +2562,16 @@ struct stereo_mandatory_mode {
 };
 
 static const struct stereo_mandatory_mode stereo_mandatory_modes[] = {
-       { 1920, 1080, 24,
-         DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | DRM_MODE_FLAG_3D_FRAME_PACKING },
+       { 1920, 1080, 24, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM },
+       { 1920, 1080, 24, DRM_MODE_FLAG_3D_FRAME_PACKING },
        { 1920, 1080, 50,
          DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF },
        { 1920, 1080, 60,
          DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF },
-       { 1280, 720,  50,
-         DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | DRM_MODE_FLAG_3D_FRAME_PACKING },
-       { 1280, 720,  60,
-         DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | DRM_MODE_FLAG_3D_FRAME_PACKING }
+       { 1280, 720,  50, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM },
+       { 1280, 720,  50, DRM_MODE_FLAG_3D_FRAME_PACKING },
+       { 1280, 720,  60, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM },
+       { 1280, 720,  60, DRM_MODE_FLAG_3D_FRAME_PACKING }
 };
 
 static bool
@@ -2586,50 +2586,33 @@ stereo_match_mandatory(const struct drm_display_mode *mode,
               drm_mode_vrefresh(mode) == stereo_mode->vrefresh;
 }
 
-static const struct stereo_mandatory_mode *
-hdmi_find_stereo_mandatory_mode(const struct drm_display_mode *mode)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(stereo_mandatory_modes); i++)
-               if (stereo_match_mandatory(mode, &stereo_mandatory_modes[i]))
-                       return &stereo_mandatory_modes[i];
-
-       return NULL;
-}
-
 static int add_hdmi_mandatory_stereo_modes(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        const struct drm_display_mode *mode;
        struct list_head stereo_modes;
-       int modes = 0;
+       int modes = 0, i;
 
        INIT_LIST_HEAD(&stereo_modes);
 
        list_for_each_entry(mode, &connector->probed_modes, head) {
-               const struct stereo_mandatory_mode *mandatory;
-               u32 stereo_layouts, layout;
-
-               mandatory = hdmi_find_stereo_mandatory_mode(mode);
-               if (!mandatory)
-                       continue;
-
-               stereo_layouts = mandatory->flags & DRM_MODE_FLAG_3D_MASK;
-               do {
+               for (i = 0; i < ARRAY_SIZE(stereo_mandatory_modes); i++) {
+                       const struct stereo_mandatory_mode *mandatory;
                        struct drm_display_mode *new_mode;
 
-                       layout = 1 << (ffs(stereo_layouts) - 1);
-                       stereo_layouts &= ~layout;
+                       if (!stereo_match_mandatory(mode,
+                                                   &stereo_mandatory_modes[i]))
+                               continue;
 
+                       mandatory = &stereo_mandatory_modes[i];
                        new_mode = drm_mode_duplicate(dev, mode);
                        if (!new_mode)
                                continue;
 
-                       new_mode->flags |= layout;
+                       new_mode->flags |= mandatory->flags;
                        list_add_tail(&new_mode->head, &stereo_modes);
                        modes++;
-               } while (stereo_layouts);
+               }
        }
 
        list_splice_tail(&stereo_modes, &connector->probed_modes);
index b2d08ca..eb6b8dc 100644 (file)
@@ -181,15 +181,6 @@ struct drm_display_mode {
        int hsync;              /* in kHz */
 };
 
-#define DRM_MODE_FLAG_3D_MASK  (DRM_MODE_FLAG_3D_FRAME_PACKING         | \
-                                DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE     | \
-                                DRM_MODE_FLAG_3D_LINE_ALTERNATIVE      | \
-                                DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL     | \
-                                DRM_MODE_FLAG_3D_L_DEPTH               | \
-                                DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH | \
-                                DRM_MODE_FLAG_3D_TOP_AND_BOTTOM        | \
-                                DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF)
-
 static inline bool drm_mode_is_stereo(const struct drm_display_mode *mode)
 {
        return mode->flags & DRM_MODE_FLAG_3D_MASK;
index bafe612..7980f89 100644 (file)
 #define DRM_MODE_FLAG_PIXMUX                   (1<<11)
 #define DRM_MODE_FLAG_DBLCLK                   (1<<12)
 #define DRM_MODE_FLAG_CLKDIV2                  (1<<13)
-#define DRM_MODE_FLAG_3D_FRAME_PACKING         (1<<14)
-#define DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE     (1<<15)
-#define DRM_MODE_FLAG_3D_LINE_ALTERNATIVE      (1<<16)
-#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL     (1<<17)
-#define DRM_MODE_FLAG_3D_L_DEPTH               (1<<18)
-#define DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH (1<<19)
-#define DRM_MODE_FLAG_3D_TOP_AND_BOTTOM                (1<<20)
-#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF     (1<<21)
+#define DRM_MODE_FLAG_3D_MASK                  (0x1f<<14)
+#define  DRM_MODE_FLAG_3D_NONE                 (0<<14)
+#define  DRM_MODE_FLAG_3D_FRAME_PACKING                (1<<14)
+#define  DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE    (2<<14)
+#define  DRM_MODE_FLAG_3D_LINE_ALTERNATIVE     (3<<14)
+#define  DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL    (4<<14)
+#define  DRM_MODE_FLAG_3D_L_DEPTH              (5<<14)
+#define  DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH        (6<<14)
+#define  DRM_MODE_FLAG_3D_TOP_AND_BOTTOM       (7<<14)
+#define  DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF    (8<<14)
+
 
 /* DPMS flags */
 /* bit compatible with the xorg definitions. */