diff options
| author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2018-06-28 09:13:07 -0400 |
|---|---|---|
| committer | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2018-07-05 09:52:07 -0400 |
| commit | 0d99889109892396a8164bf6dd178e36d3fe3166 (patch) | |
| tree | b40c0d143556d1fcb33013e8504374280d742579 /drivers | |
| parent | c91b007ed137c8497fa89993cc6757a8e81ff99b (diff) | |
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: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180628131315.14156-2-ville.syrjala@linux.intel.com
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index cab14f253384..b37f06317d51 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
| @@ -2323,6 +2323,27 @@ retry: | |||
| 2323 | return true; | 2323 | return true; |
| 2324 | } | 2324 | } |
| 2325 | 2325 | ||
| 2326 | static bool connector_has_possible_crtc(struct drm_connector *connector, | ||
| 2327 | struct drm_crtc *crtc) | ||
| 2328 | { | ||
| 2329 | int i; | ||
| 2330 | |||
| 2331 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { | ||
| 2332 | struct drm_encoder *encoder; | ||
| 2333 | |||
| 2334 | if (connector->encoder_ids[i] == 0) | ||
| 2335 | break; | ||
| 2336 | |||
| 2337 | encoder = drm_encoder_find(connector->dev, NULL, | ||
| 2338 | connector->encoder_ids[i]); | ||
| 2339 | |||
| 2340 | if (encoder->possible_crtcs & drm_crtc_mask(crtc)) | ||
| 2341 | return true; | ||
| 2342 | } | ||
| 2343 | |||
| 2344 | return false; | ||
| 2345 | } | ||
| 2346 | |||
| 2326 | static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, | 2347 | static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, |
| 2327 | struct drm_fb_helper_crtc **best_crtcs, | 2348 | struct drm_fb_helper_crtc **best_crtcs, |
| 2328 | struct drm_display_mode **modes, | 2349 | struct drm_display_mode **modes, |
| @@ -2331,7 +2352,6 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, | |||
| 2331 | int c, o; | 2352 | int c, o; |
| 2332 | struct drm_connector *connector; | 2353 | struct drm_connector *connector; |
| 2333 | const struct drm_connector_helper_funcs *connector_funcs; | 2354 | const struct drm_connector_helper_funcs *connector_funcs; |
| 2334 | struct drm_encoder *encoder; | ||
| 2335 | int my_score, best_score, score; | 2355 | int my_score, best_score, score; |
| 2336 | struct drm_fb_helper_crtc **crtcs, *crtc; | 2356 | struct drm_fb_helper_crtc **crtcs, *crtc; |
| 2337 | struct drm_fb_helper_connector *fb_helper_conn; | 2357 | struct drm_fb_helper_connector *fb_helper_conn; |
| @@ -2363,27 +2383,14 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, | |||
| 2363 | connector_funcs = connector->helper_private; | 2383 | connector_funcs = connector->helper_private; |
| 2364 | 2384 | ||
| 2365 | /* | 2385 | /* |
| 2366 | * If the DRM device implements atomic hooks and ->best_encoder() is | ||
| 2367 | * NULL we fallback to the default drm_atomic_helper_best_encoder() | ||
| 2368 | * helper. | ||
| 2369 | */ | ||
| 2370 | if (drm_drv_uses_atomic_modeset(fb_helper->dev) && | ||
| 2371 | !connector_funcs->best_encoder) | ||
| 2372 | encoder = drm_atomic_helper_best_encoder(connector); | ||
| 2373 | else | ||
| 2374 | encoder = connector_funcs->best_encoder(connector); | ||
| 2375 | |||
| 2376 | if (!encoder) | ||
| 2377 | goto out; | ||
| 2378 | |||
| 2379 | /* | ||
| 2380 | * select a crtc for this connector and then attempt to configure | 2386 | * select a crtc for this connector and then attempt to configure |
| 2381 | * remaining connectors | 2387 | * remaining connectors |
| 2382 | */ | 2388 | */ |
| 2383 | for (c = 0; c < fb_helper->crtc_count; c++) { | 2389 | for (c = 0; c < fb_helper->crtc_count; c++) { |
| 2384 | crtc = &fb_helper->crtc_info[c]; | 2390 | crtc = &fb_helper->crtc_info[c]; |
| 2385 | 2391 | ||
| 2386 | if ((encoder->possible_crtcs & (1 << c)) == 0) | 2392 | if (!connector_has_possible_crtc(connector, |
| 2393 | crtc->mode_set.crtc)) | ||
| 2387 | continue; | 2394 | continue; |
| 2388 | 2395 | ||
| 2389 | for (o = 0; o < n; o++) | 2396 | for (o = 0; o < n; o++) |
| @@ -2410,7 +2417,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, | |||
| 2410 | sizeof(struct drm_fb_helper_crtc *)); | 2417 | sizeof(struct drm_fb_helper_crtc *)); |
| 2411 | } | 2418 | } |
| 2412 | } | 2419 | } |
| 2413 | out: | 2420 | |
| 2414 | kfree(crtcs); | 2421 | kfree(crtcs); |
| 2415 | return best_score; | 2422 | return best_score; |
| 2416 | } | 2423 | } |
