diff options
Diffstat (limited to 'drivers/gpu/drm/drm_modes.c')
-rw-r--r-- | drivers/gpu/drm/drm_modes.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index fc2adb62b757..85071a1c4547 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c | |||
@@ -707,18 +707,25 @@ EXPORT_SYMBOL(drm_mode_vrefresh); | |||
707 | /** | 707 | /** |
708 | * drm_mode_set_crtcinfo - set CRTC modesetting parameters | 708 | * drm_mode_set_crtcinfo - set CRTC modesetting parameters |
709 | * @p: mode | 709 | * @p: mode |
710 | * @adjust_flags: unused? (FIXME) | 710 | * @adjust_flags: a combination of adjustment flags |
711 | * | 711 | * |
712 | * LOCKING: | 712 | * LOCKING: |
713 | * None. | 713 | * None. |
714 | * | 714 | * |
715 | * Setup the CRTC modesetting parameters for @p, adjusting if necessary. | 715 | * Setup the CRTC modesetting parameters for @p, adjusting if necessary. |
716 | * | ||
717 | * - The CRTC_INTERLACE_HALVE_V flag can be used to halve vertical timings of | ||
718 | * interlaced modes. | ||
719 | * - The CRTC_STEREO_DOUBLE flag can be used to compute the timings for | ||
720 | * buffers containing two eyes (only adjust the timings when needed, eg. for | ||
721 | * "frame packing" or "side by side full"). | ||
716 | */ | 722 | */ |
717 | void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags) | 723 | void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags) |
718 | { | 724 | { |
719 | if ((p == NULL) || ((p->type & DRM_MODE_TYPE_CRTC_C) == DRM_MODE_TYPE_BUILTIN)) | 725 | if ((p == NULL) || ((p->type & DRM_MODE_TYPE_CRTC_C) == DRM_MODE_TYPE_BUILTIN)) |
720 | return; | 726 | return; |
721 | 727 | ||
728 | p->crtc_clock = p->clock; | ||
722 | p->crtc_hdisplay = p->hdisplay; | 729 | p->crtc_hdisplay = p->hdisplay; |
723 | p->crtc_hsync_start = p->hsync_start; | 730 | p->crtc_hsync_start = p->hsync_start; |
724 | p->crtc_hsync_end = p->hsync_end; | 731 | p->crtc_hsync_end = p->hsync_end; |
@@ -752,6 +759,20 @@ void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags) | |||
752 | p->crtc_vtotal *= p->vscan; | 759 | p->crtc_vtotal *= p->vscan; |
753 | } | 760 | } |
754 | 761 | ||
762 | if (adjust_flags & CRTC_STEREO_DOUBLE) { | ||
763 | unsigned int layout = p->flags & DRM_MODE_FLAG_3D_MASK; | ||
764 | |||
765 | switch (layout) { | ||
766 | case DRM_MODE_FLAG_3D_FRAME_PACKING: | ||
767 | p->crtc_clock *= 2; | ||
768 | p->crtc_vdisplay += p->crtc_vtotal; | ||
769 | p->crtc_vsync_start += p->crtc_vtotal; | ||
770 | p->crtc_vsync_end += p->crtc_vtotal; | ||
771 | p->crtc_vtotal += p->crtc_vtotal; | ||
772 | break; | ||
773 | } | ||
774 | } | ||
775 | |||
755 | p->crtc_vblank_start = min(p->crtc_vsync_start, p->crtc_vdisplay); | 776 | p->crtc_vblank_start = min(p->crtc_vsync_start, p->crtc_vdisplay); |
756 | p->crtc_vblank_end = max(p->crtc_vsync_end, p->crtc_vtotal); | 777 | p->crtc_vblank_end = max(p->crtc_vsync_end, p->crtc_vtotal); |
757 | p->crtc_hblank_start = min(p->crtc_hsync_start, p->crtc_hdisplay); | 778 | p->crtc_hblank_start = min(p->crtc_hsync_start, p->crtc_hdisplay); |
@@ -830,12 +851,16 @@ bool drm_mode_equal(const struct drm_display_mode *mode1, const struct drm_displ | |||
830 | } else if (mode1->clock != mode2->clock) | 851 | } else if (mode1->clock != mode2->clock) |
831 | return false; | 852 | return false; |
832 | 853 | ||
833 | return drm_mode_equal_no_clocks(mode1, mode2); | 854 | if ((mode1->flags & DRM_MODE_FLAG_3D_MASK) != |
855 | (mode2->flags & DRM_MODE_FLAG_3D_MASK)) | ||
856 | return false; | ||
857 | |||
858 | return drm_mode_equal_no_clocks_no_stereo(mode1, mode2); | ||
834 | } | 859 | } |
835 | EXPORT_SYMBOL(drm_mode_equal); | 860 | EXPORT_SYMBOL(drm_mode_equal); |
836 | 861 | ||
837 | /** | 862 | /** |
838 | * drm_mode_equal_no_clocks - test modes for equality | 863 | * drm_mode_equal_no_clocks_no_stereo - test modes for equality |
839 | * @mode1: first mode | 864 | * @mode1: first mode |
840 | * @mode2: second mode | 865 | * @mode2: second mode |
841 | * | 866 | * |
@@ -843,12 +868,13 @@ EXPORT_SYMBOL(drm_mode_equal); | |||
843 | * None. | 868 | * None. |
844 | * | 869 | * |
845 | * Check to see if @mode1 and @mode2 are equivalent, but | 870 | * Check to see if @mode1 and @mode2 are equivalent, but |
846 | * don't check the pixel clocks. | 871 | * don't check the pixel clocks nor the stereo layout. |
847 | * | 872 | * |
848 | * RETURNS: | 873 | * RETURNS: |
849 | * True if the modes are equal, false otherwise. | 874 | * True if the modes are equal, false otherwise. |
850 | */ | 875 | */ |
851 | bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2) | 876 | bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1, |
877 | const struct drm_display_mode *mode2) | ||
852 | { | 878 | { |
853 | if (mode1->hdisplay == mode2->hdisplay && | 879 | if (mode1->hdisplay == mode2->hdisplay && |
854 | mode1->hsync_start == mode2->hsync_start && | 880 | mode1->hsync_start == mode2->hsync_start && |
@@ -860,12 +886,13 @@ bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1, const struct | |||
860 | mode1->vsync_end == mode2->vsync_end && | 886 | mode1->vsync_end == mode2->vsync_end && |
861 | mode1->vtotal == mode2->vtotal && | 887 | mode1->vtotal == mode2->vtotal && |
862 | mode1->vscan == mode2->vscan && | 888 | mode1->vscan == mode2->vscan && |
863 | mode1->flags == mode2->flags) | 889 | (mode1->flags & ~DRM_MODE_FLAG_3D_MASK) == |
890 | (mode2->flags & ~DRM_MODE_FLAG_3D_MASK)) | ||
864 | return true; | 891 | return true; |
865 | 892 | ||
866 | return false; | 893 | return false; |
867 | } | 894 | } |
868 | EXPORT_SYMBOL(drm_mode_equal_no_clocks); | 895 | EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo); |
869 | 896 | ||
870 | /** | 897 | /** |
871 | * drm_mode_validate_size - make sure modes adhere to size constraints | 898 | * drm_mode_validate_size - make sure modes adhere to size constraints |
@@ -1014,7 +1041,7 @@ void drm_mode_connector_list_update(struct drm_connector *connector) | |||
1014 | /* if equal delete the probed mode */ | 1041 | /* if equal delete the probed mode */ |
1015 | mode->status = pmode->status; | 1042 | mode->status = pmode->status; |
1016 | /* Merge type bits together */ | 1043 | /* Merge type bits together */ |
1017 | mode->type |= pmode->type; | 1044 | mode->type = pmode->type; |
1018 | list_del(&pmode->head); | 1045 | list_del(&pmode->head); |
1019 | drm_mode_destroy(connector->dev, pmode); | 1046 | drm_mode_destroy(connector->dev, pmode); |
1020 | break; | 1047 | break; |