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

Commit 0d998891 authored by Ville Syrjälä's avatar Ville Syrjälä
Browse files

drm/fb-helper: Eliminate the .best_encoder() usage



Instead of using the .best_encoder() hook to figure out whether a given
connector+crtc combo will work, let's instead do what userspace does and
just iterate over all the encoders for the connector, and then check
each crtc against each encoder's possible_crtcs bitmask.

v2: Avoid oopsing on NULL encoders (Daniel)
    s/connector_crtc_ok/connector_has_possible_crtc/

Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Suggested-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180628131315.14156-2-ville.syrjala@linux.intel.com
parent c91b007e
Loading
Loading
Loading
Loading
+24 −17
Original line number Diff line number Diff line
@@ -2323,6 +2323,27 @@ static bool drm_target_preferred(struct drm_fb_helper *fb_helper,
	return true;
}

static bool connector_has_possible_crtc(struct drm_connector *connector,
					struct drm_crtc *crtc)
{
	int i;

	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
		struct drm_encoder *encoder;

		if (connector->encoder_ids[i] == 0)
			break;

		encoder = drm_encoder_find(connector->dev, NULL,
					   connector->encoder_ids[i]);

		if (encoder->possible_crtcs & drm_crtc_mask(crtc))
			return true;
	}

	return false;
}

static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
			  struct drm_fb_helper_crtc **best_crtcs,
			  struct drm_display_mode **modes,
@@ -2331,7 +2352,6 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
	int c, o;
	struct drm_connector *connector;
	const struct drm_connector_helper_funcs *connector_funcs;
	struct drm_encoder *encoder;
	int my_score, best_score, score;
	struct drm_fb_helper_crtc **crtcs, *crtc;
	struct drm_fb_helper_connector *fb_helper_conn;
@@ -2362,20 +2382,6 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,

	connector_funcs = connector->helper_private;

	/*
	 * If the DRM device implements atomic hooks and ->best_encoder() is
	 * NULL we fallback to the default drm_atomic_helper_best_encoder()
	 * helper.
	 */
	if (drm_drv_uses_atomic_modeset(fb_helper->dev) &&
	    !connector_funcs->best_encoder)
		encoder = drm_atomic_helper_best_encoder(connector);
	else
		encoder = connector_funcs->best_encoder(connector);

	if (!encoder)
		goto out;

	/*
	 * select a crtc for this connector and then attempt to configure
	 * remaining connectors
@@ -2383,7 +2389,8 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
	for (c = 0; c < fb_helper->crtc_count; c++) {
		crtc = &fb_helper->crtc_info[c];

		if ((encoder->possible_crtcs & (1 << c)) == 0)
		if (!connector_has_possible_crtc(connector,
						 crtc->mode_set.crtc))
			continue;

		for (o = 0; o < n; o++)
@@ -2410,7 +2417,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
			       sizeof(struct drm_fb_helper_crtc *));
		}
	}
out:

	kfree(crtcs);
	return best_score;
}