Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c5d1b51d authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915: Clear pfit registers when not used by any outputs

... otherwise the panel-fitter may be left enabled with random settings
and cause unintended filtering (i.e. blurring of native modes on external
panels).

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=31942


Reported-and-tested-by: default avatarBen Kohler <bkohler@gmail.com>
Tested-by: default avatarCiprian Docan <docan@eden.rutgers.edu>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent de18a29e
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -5336,9 +5336,14 @@ static void intel_setup_outputs(struct drm_device *dev)
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_encoder *encoder;
	bool dpd_is_edp = false;
	bool has_lvds = false;

	if (IS_MOBILE(dev) && !IS_I830(dev))
		intel_lvds_init(dev);
		has_lvds = intel_lvds_init(dev);
	if (!has_lvds && !HAS_PCH_SPLIT(dev)) {
		/* disable the panel fitter on everything but LVDS */
		I915_WRITE(PFIT_CONTROL, 0);
	}

	if (HAS_PCH_SPLIT(dev)) {
		dpd_is_edp = intel_dpd_is_edp(dev);
+1 −1
Original line number Diff line number Diff line
@@ -237,7 +237,7 @@ extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
extern void intel_dvo_init(struct drm_device *dev);
extern void intel_tv_init(struct drm_device *dev);
extern void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj);
extern void intel_lvds_init(struct drm_device *dev);
extern bool intel_lvds_init(struct drm_device *dev);
extern void intel_dp_init(struct drm_device *dev, int dp_reg);
void
intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
+10 −9
Original line number Diff line number Diff line
@@ -837,7 +837,7 @@ static bool intel_lvds_ddc_probe(struct drm_device *dev, u8 pin)
 * Create the connector, register the LVDS DDC bus, and try to figure out what
 * modes we can display on the LVDS panel (if present).
 */
void intel_lvds_init(struct drm_device *dev)
bool intel_lvds_init(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_lvds *intel_lvds;
@@ -853,37 +853,37 @@ void intel_lvds_init(struct drm_device *dev)

	/* Skip init on machines we know falsely report LVDS */
	if (dmi_check_system(intel_no_lvds))
		return;
		return false;

	pin = GMBUS_PORT_PANEL;
	if (!lvds_is_present_in_vbt(dev, &pin)) {
		DRM_DEBUG_KMS("LVDS is not present in VBT\n");
		return;
		return false;
	}

	if (HAS_PCH_SPLIT(dev)) {
		if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0)
			return;
			return false;
		if (dev_priv->edp.support) {
			DRM_DEBUG_KMS("disable LVDS for eDP support\n");
			return;
			return false;
		}
	}

	if (!intel_lvds_ddc_probe(dev, pin)) {
		DRM_DEBUG_KMS("LVDS did not respond to DDC probe\n");
		return;
		return false;
	}

	intel_lvds = kzalloc(sizeof(struct intel_lvds), GFP_KERNEL);
	if (!intel_lvds) {
		return;
		return false;
	}

	intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
	if (!intel_connector) {
		kfree(intel_lvds);
		return;
		return false;
	}

	if (!HAS_PCH_SPLIT(dev)) {
@@ -1026,7 +1026,7 @@ out:
	/* keep the LVDS connector */
	dev_priv->int_lvds_connector = connector;
	drm_sysfs_connector_add(connector);
	return;
	return true;

failed:
	DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
@@ -1034,4 +1034,5 @@ failed:
	drm_encoder_cleanup(encoder);
	kfree(intel_lvds);
	kfree(intel_connector);
	return false;
}