diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_panel.c')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_panel.c | 50 | 
1 files changed, 42 insertions, 8 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c index 41cec9dc4223..42aa04bac261 100644 --- a/drivers/gpu/drm/i915/display/intel_panel.c +++ b/drivers/gpu/drm/i915/display/intel_panel.c @@ -31,6 +31,9 @@  #include <linux/kernel.h>  #include <linux/pwm.h> +#include <drm/drm_edid.h> + +#include "i915_reg.h"  #include "intel_backlight.h"  #include "intel_connector.h"  #include "intel_de.h" @@ -85,9 +88,10 @@ static bool is_alt_drrs_mode(const struct drm_display_mode *mode,  static bool is_alt_fixed_mode(const struct drm_display_mode *mode,  			      const struct drm_display_mode *preferred_mode)  { -	return drm_mode_match(mode, preferred_mode, -			      DRM_MODE_MATCH_FLAGS | -			      DRM_MODE_MATCH_3D_FLAGS) && +	u32 sync_flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC | +		DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC; + +	return (mode->flags & ~sync_flags) == (preferred_mode->flags & ~sync_flags) &&  		mode->hdisplay == preferred_mode->hdisplay &&  		mode->vdisplay == preferred_mode->vdisplay;  } @@ -147,12 +151,24 @@ int intel_panel_get_modes(struct intel_connector *connector)  	return num_modes;  } -enum drrs_type intel_panel_drrs_type(struct intel_connector *connector) +static bool has_drrs_modes(struct intel_connector *connector)  { -	if (list_empty(&connector->panel.fixed_modes) || -	    list_is_singular(&connector->panel.fixed_modes)) -		return DRRS_TYPE_NONE; +	const struct drm_display_mode *mode1; + +	list_for_each_entry(mode1, &connector->panel.fixed_modes, head) { +		const struct drm_display_mode *mode2 = mode1; + +		list_for_each_entry_continue(mode2, &connector->panel.fixed_modes, head) { +			if (is_alt_drrs_mode(mode1, mode2)) +				return true; +		} +	} + +	return false; +} +enum drrs_type intel_panel_drrs_type(struct intel_connector *connector) +{  	return connector->panel.vbt.drrs_type;  } @@ -647,12 +663,27 @@ intel_panel_mode_valid(struct intel_connector *connector,  	return MODE_OK;  } -int intel_panel_init(struct intel_connector *connector) +void intel_panel_init_alloc(struct intel_connector *connector)  {  	struct intel_panel *panel = &connector->panel; +	connector->panel.vbt.panel_type = -1; +	connector->panel.vbt.backlight.controller = -1; +	INIT_LIST_HEAD(&panel->fixed_modes); +} + +int intel_panel_init(struct intel_connector *connector, +		     const struct drm_edid *fixed_edid) +{ +	struct intel_panel *panel = &connector->panel; + +	panel->fixed_edid = fixed_edid; +  	intel_backlight_init_funcs(panel); +	if (!has_drrs_modes(connector)) +		connector->panel.vbt.drrs_type = DRRS_TYPE_NONE; +  	drm_dbg_kms(connector->base.dev,  		    "[CONNECTOR:%d:%s] DRRS type: %s\n",  		    connector->base.base.id, connector->base.name, @@ -666,6 +697,9 @@ void intel_panel_fini(struct intel_connector *connector)  	struct intel_panel *panel = &connector->panel;  	struct drm_display_mode *fixed_mode, *next; +	if (!IS_ERR_OR_NULL(panel->fixed_edid)) +		drm_edid_free(panel->fixed_edid); +  	intel_backlight_destroy(panel);  	intel_bios_fini_panel(panel);  |