Commit dd7c2626 authored by Ville Syrjälä's avatar Ville Syrjälä Committed by Maarten Lankhorst

drm/modes: Introduce drm_mode_match()

Make mode matching less confusing by allowing the caller to specify
which parts of the modes should match via some flags.
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarShashank Sharma <shashank.sharma@intel.com>
Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1525777785-9740-2-git-send-email-ankit.k.nautiyal@intel.com
parent 818c05d8
...@@ -939,17 +939,68 @@ struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev, ...@@ -939,17 +939,68 @@ struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
} }
EXPORT_SYMBOL(drm_mode_duplicate); EXPORT_SYMBOL(drm_mode_duplicate);
static bool drm_mode_match_timings(const struct drm_display_mode *mode1,
const struct drm_display_mode *mode2)
{
return mode1->hdisplay == mode2->hdisplay &&
mode1->hsync_start == mode2->hsync_start &&
mode1->hsync_end == mode2->hsync_end &&
mode1->htotal == mode2->htotal &&
mode1->hskew == mode2->hskew &&
mode1->vdisplay == mode2->vdisplay &&
mode1->vsync_start == mode2->vsync_start &&
mode1->vsync_end == mode2->vsync_end &&
mode1->vtotal == mode2->vtotal &&
mode1->vscan == mode2->vscan;
}
static bool drm_mode_match_clock(const struct drm_display_mode *mode1,
const struct drm_display_mode *mode2)
{
/*
* do clock check convert to PICOS
* so fb modes get matched the same
*/
if (mode1->clock && mode2->clock)
return KHZ2PICOS(mode1->clock) == KHZ2PICOS(mode2->clock);
else
return mode1->clock == mode2->clock;
}
static bool drm_mode_match_flags(const struct drm_display_mode *mode1,
const struct drm_display_mode *mode2)
{
return (mode1->flags & ~DRM_MODE_FLAG_3D_MASK) ==
(mode2->flags & ~DRM_MODE_FLAG_3D_MASK);
}
static bool drm_mode_match_3d_flags(const struct drm_display_mode *mode1,
const struct drm_display_mode *mode2)
{
return (mode1->flags & DRM_MODE_FLAG_3D_MASK) ==
(mode2->flags & DRM_MODE_FLAG_3D_MASK);
}
static bool drm_mode_match_aspect_ratio(const struct drm_display_mode *mode1,
const struct drm_display_mode *mode2)
{
return mode1->picture_aspect_ratio == mode2->picture_aspect_ratio;
}
/** /**
* drm_mode_equal - test modes for equality * drm_mode_match - test modes for (partial) equality
* @mode1: first mode * @mode1: first mode
* @mode2: second mode * @mode2: second mode
* @match_flags: which parts need to match (DRM_MODE_MATCH_*)
* *
* Check to see if @mode1 and @mode2 are equivalent. * Check to see if @mode1 and @mode2 are equivalent.
* *
* Returns: * Returns:
* True if the modes are equal, false otherwise. * True if the modes are (partially) equal, false otherwise.
*/ */
bool drm_mode_equal(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2) bool drm_mode_match(const struct drm_display_mode *mode1,
const struct drm_display_mode *mode2,
unsigned int match_flags)
{ {
if (!mode1 && !mode2) if (!mode1 && !mode2)
return true; return true;
...@@ -957,15 +1008,48 @@ bool drm_mode_equal(const struct drm_display_mode *mode1, const struct drm_displ ...@@ -957,15 +1008,48 @@ bool drm_mode_equal(const struct drm_display_mode *mode1, const struct drm_displ
if (!mode1 || !mode2) if (!mode1 || !mode2)
return false; return false;
/* do clock check convert to PICOS so fb modes get matched if (match_flags & DRM_MODE_MATCH_TIMINGS &&
* the same */ !drm_mode_match_timings(mode1, mode2))
if (mode1->clock && mode2->clock) {
if (KHZ2PICOS(mode1->clock) != KHZ2PICOS(mode2->clock))
return false; return false;
} else if (mode1->clock != mode2->clock)
if (match_flags & DRM_MODE_MATCH_CLOCK &&
!drm_mode_match_clock(mode1, mode2))
return false; return false;
return drm_mode_equal_no_clocks(mode1, mode2); if (match_flags & DRM_MODE_MATCH_FLAGS &&
!drm_mode_match_flags(mode1, mode2))
return false;
if (match_flags & DRM_MODE_MATCH_3D_FLAGS &&
!drm_mode_match_3d_flags(mode1, mode2))
return false;
if (match_flags & DRM_MODE_MATCH_ASPECT_RATIO &&
!drm_mode_match_aspect_ratio(mode1, mode2))
return false;
return true;
}
EXPORT_SYMBOL(drm_mode_match);
/**
* drm_mode_equal - test modes for equality
* @mode1: first mode
* @mode2: second mode
*
* Check to see if @mode1 and @mode2 are equivalent.
*
* Returns:
* True if the modes are equal, false otherwise.
*/
bool drm_mode_equal(const struct drm_display_mode *mode1,
const struct drm_display_mode *mode2)
{
return drm_mode_match(mode1, mode2,
DRM_MODE_MATCH_TIMINGS |
DRM_MODE_MATCH_CLOCK |
DRM_MODE_MATCH_FLAGS |
DRM_MODE_MATCH_3D_FLAGS);
} }
EXPORT_SYMBOL(drm_mode_equal); EXPORT_SYMBOL(drm_mode_equal);
...@@ -980,13 +1064,13 @@ EXPORT_SYMBOL(drm_mode_equal); ...@@ -980,13 +1064,13 @@ EXPORT_SYMBOL(drm_mode_equal);
* Returns: * Returns:
* True if the modes are equal, false otherwise. * True if the modes are equal, false otherwise.
*/ */
bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2) bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1,
const struct drm_display_mode *mode2)
{ {
if ((mode1->flags & DRM_MODE_FLAG_3D_MASK) != return drm_mode_match(mode1, mode2,
(mode2->flags & DRM_MODE_FLAG_3D_MASK)) DRM_MODE_MATCH_TIMINGS |
return false; DRM_MODE_MATCH_FLAGS |
DRM_MODE_MATCH_3D_FLAGS);
return drm_mode_equal_no_clocks_no_stereo(mode1, mode2);
} }
EXPORT_SYMBOL(drm_mode_equal_no_clocks); EXPORT_SYMBOL(drm_mode_equal_no_clocks);
...@@ -1004,21 +1088,9 @@ EXPORT_SYMBOL(drm_mode_equal_no_clocks); ...@@ -1004,21 +1088,9 @@ EXPORT_SYMBOL(drm_mode_equal_no_clocks);
bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1, bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1,
const struct drm_display_mode *mode2) const struct drm_display_mode *mode2)
{ {
if (mode1->hdisplay == mode2->hdisplay && return drm_mode_match(mode1, mode2,
mode1->hsync_start == mode2->hsync_start && DRM_MODE_MATCH_TIMINGS |
mode1->hsync_end == mode2->hsync_end && DRM_MODE_MATCH_FLAGS);
mode1->htotal == mode2->htotal &&
mode1->hskew == mode2->hskew &&
mode1->vdisplay == mode2->vdisplay &&
mode1->vsync_start == mode2->vsync_start &&
mode1->vsync_end == mode2->vsync_end &&
mode1->vtotal == mode2->vtotal &&
mode1->vscan == mode2->vscan &&
(mode1->flags & ~DRM_MODE_FLAG_3D_MASK) ==
(mode2->flags & ~DRM_MODE_FLAG_3D_MASK))
return true;
return false;
} }
EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo); EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo);
......
...@@ -147,6 +147,12 @@ enum drm_mode_status { ...@@ -147,6 +147,12 @@ enum drm_mode_status {
#define DRM_MODE_FLAG_3D_MAX DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF #define DRM_MODE_FLAG_3D_MAX DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF
#define DRM_MODE_MATCH_TIMINGS (1 << 0)
#define DRM_MODE_MATCH_CLOCK (1 << 1)
#define DRM_MODE_MATCH_FLAGS (1 << 2)
#define DRM_MODE_MATCH_3D_FLAGS (1 << 3)
#define DRM_MODE_MATCH_ASPECT_RATIO (1 << 4)
/** /**
* struct drm_display_mode - DRM kernel-internal display mode structure * struct drm_display_mode - DRM kernel-internal display mode structure
* @hdisplay: horizontal display size * @hdisplay: horizontal display size
...@@ -490,6 +496,9 @@ void drm_mode_copy(struct drm_display_mode *dst, ...@@ -490,6 +496,9 @@ void drm_mode_copy(struct drm_display_mode *dst,
const struct drm_display_mode *src); const struct drm_display_mode *src);
struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev, struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
const struct drm_display_mode *mode); const struct drm_display_mode *mode);
bool drm_mode_match(const struct drm_display_mode *mode1,
const struct drm_display_mode *mode2,
unsigned int match_flags);
bool drm_mode_equal(const struct drm_display_mode *mode1, bool drm_mode_equal(const struct drm_display_mode *mode1,
const struct drm_display_mode *mode2); const struct drm_display_mode *mode2);
bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1, bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment