diff options
author | Damien Lespiau <damien.lespiau@intel.com> | 2013-09-27 07:11:48 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-10-01 01:45:44 -0400 |
commit | f7e121b76469624459152542c1b809a1ebc835fe (patch) | |
tree | 295475386ab301b48c0010d1f3d3eb84baeffb7b /drivers/gpu/drm/drm_edid.c | |
parent | e454a05da623c26544721b159caaacdb6dfe448c (diff) |
drm: Code stereo layouts as an enum rather than a bit field
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>
Diffstat (limited to 'drivers/gpu/drm/drm_edid.c')
-rw-r--r-- | drivers/gpu/drm/drm_edid.c | 47 |
1 files changed, 15 insertions, 32 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index c24af1d6cb47..7d1e8a90480a 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -2562,16 +2562,16 @@ struct stereo_mandatory_mode { | |||
2562 | }; | 2562 | }; |
2563 | 2563 | ||
2564 | static const struct stereo_mandatory_mode stereo_mandatory_modes[] = { | 2564 | static const struct stereo_mandatory_mode stereo_mandatory_modes[] = { |
2565 | { 1920, 1080, 24, | 2565 | { 1920, 1080, 24, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM }, |
2566 | DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | DRM_MODE_FLAG_3D_FRAME_PACKING }, | 2566 | { 1920, 1080, 24, DRM_MODE_FLAG_3D_FRAME_PACKING }, |
2567 | { 1920, 1080, 50, | 2567 | { 1920, 1080, 50, |
2568 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF }, | 2568 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF }, |
2569 | { 1920, 1080, 60, | 2569 | { 1920, 1080, 60, |
2570 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF }, | 2570 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF }, |
2571 | { 1280, 720, 50, | 2571 | { 1280, 720, 50, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM }, |
2572 | DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | DRM_MODE_FLAG_3D_FRAME_PACKING }, | 2572 | { 1280, 720, 50, DRM_MODE_FLAG_3D_FRAME_PACKING }, |
2573 | { 1280, 720, 60, | 2573 | { 1280, 720, 60, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM }, |
2574 | DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | DRM_MODE_FLAG_3D_FRAME_PACKING } | 2574 | { 1280, 720, 60, DRM_MODE_FLAG_3D_FRAME_PACKING } |
2575 | }; | 2575 | }; |
2576 | 2576 | ||
2577 | static bool | 2577 | static bool |
@@ -2586,50 +2586,33 @@ stereo_match_mandatory(const struct drm_display_mode *mode, | |||
2586 | drm_mode_vrefresh(mode) == stereo_mode->vrefresh; | 2586 | drm_mode_vrefresh(mode) == stereo_mode->vrefresh; |
2587 | } | 2587 | } |
2588 | 2588 | ||
2589 | static const struct stereo_mandatory_mode * | ||
2590 | hdmi_find_stereo_mandatory_mode(const struct drm_display_mode *mode) | ||
2591 | { | ||
2592 | int i; | ||
2593 | |||
2594 | for (i = 0; i < ARRAY_SIZE(stereo_mandatory_modes); i++) | ||
2595 | if (stereo_match_mandatory(mode, &stereo_mandatory_modes[i])) | ||
2596 | return &stereo_mandatory_modes[i]; | ||
2597 | |||
2598 | return NULL; | ||
2599 | } | ||
2600 | |||
2601 | static int add_hdmi_mandatory_stereo_modes(struct drm_connector *connector) | 2589 | static int add_hdmi_mandatory_stereo_modes(struct drm_connector *connector) |
2602 | { | 2590 | { |
2603 | struct drm_device *dev = connector->dev; | 2591 | struct drm_device *dev = connector->dev; |
2604 | const struct drm_display_mode *mode; | 2592 | const struct drm_display_mode *mode; |
2605 | struct list_head stereo_modes; | 2593 | struct list_head stereo_modes; |
2606 | int modes = 0; | 2594 | int modes = 0, i; |
2607 | 2595 | ||
2608 | INIT_LIST_HEAD(&stereo_modes); | 2596 | INIT_LIST_HEAD(&stereo_modes); |
2609 | 2597 | ||
2610 | list_for_each_entry(mode, &connector->probed_modes, head) { | 2598 | list_for_each_entry(mode, &connector->probed_modes, head) { |
2611 | const struct stereo_mandatory_mode *mandatory; | 2599 | for (i = 0; i < ARRAY_SIZE(stereo_mandatory_modes); i++) { |
2612 | u32 stereo_layouts, layout; | 2600 | const struct stereo_mandatory_mode *mandatory; |
2613 | |||
2614 | mandatory = hdmi_find_stereo_mandatory_mode(mode); | ||
2615 | if (!mandatory) | ||
2616 | continue; | ||
2617 | |||
2618 | stereo_layouts = mandatory->flags & DRM_MODE_FLAG_3D_MASK; | ||
2619 | do { | ||
2620 | struct drm_display_mode *new_mode; | 2601 | struct drm_display_mode *new_mode; |
2621 | 2602 | ||
2622 | layout = 1 << (ffs(stereo_layouts) - 1); | 2603 | if (!stereo_match_mandatory(mode, |
2623 | stereo_layouts &= ~layout; | 2604 | &stereo_mandatory_modes[i])) |
2605 | continue; | ||
2624 | 2606 | ||
2607 | mandatory = &stereo_mandatory_modes[i]; | ||
2625 | new_mode = drm_mode_duplicate(dev, mode); | 2608 | new_mode = drm_mode_duplicate(dev, mode); |
2626 | if (!new_mode) | 2609 | if (!new_mode) |
2627 | continue; | 2610 | continue; |
2628 | 2611 | ||
2629 | new_mode->flags |= layout; | 2612 | new_mode->flags |= mandatory->flags; |
2630 | list_add_tail(&new_mode->head, &stereo_modes); | 2613 | list_add_tail(&new_mode->head, &stereo_modes); |
2631 | modes++; | 2614 | modes++; |
2632 | } while (stereo_layouts); | 2615 | } |
2633 | } | 2616 | } |
2634 | 2617 | ||
2635 | list_splice_tail(&stereo_modes, &connector->probed_modes); | 2618 | list_splice_tail(&stereo_modes, &connector->probed_modes); |