diff options
-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 | } |