diff options
Diffstat (limited to 'drivers/gpu/drm/drm_fb_helper.c')
-rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 51 |
1 files changed, 14 insertions, 37 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index e673c13c7391..69cbab5e5c81 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -342,6 +342,7 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper) | |||
342 | struct drm_plane *plane; | 342 | struct drm_plane *plane; |
343 | struct drm_atomic_state *state; | 343 | struct drm_atomic_state *state; |
344 | int i, ret; | 344 | int i, ret; |
345 | unsigned plane_mask; | ||
345 | 346 | ||
346 | state = drm_atomic_state_alloc(dev); | 347 | state = drm_atomic_state_alloc(dev); |
347 | if (!state) | 348 | if (!state) |
@@ -349,11 +350,10 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper) | |||
349 | 350 | ||
350 | state->acquire_ctx = dev->mode_config.acquire_ctx; | 351 | state->acquire_ctx = dev->mode_config.acquire_ctx; |
351 | retry: | 352 | retry: |
353 | plane_mask = 0; | ||
352 | drm_for_each_plane(plane, dev) { | 354 | drm_for_each_plane(plane, dev) { |
353 | struct drm_plane_state *plane_state; | 355 | struct drm_plane_state *plane_state; |
354 | 356 | ||
355 | plane->old_fb = plane->fb; | ||
356 | |||
357 | plane_state = drm_atomic_get_plane_state(state, plane); | 357 | plane_state = drm_atomic_get_plane_state(state, plane); |
358 | if (IS_ERR(plane_state)) { | 358 | if (IS_ERR(plane_state)) { |
359 | ret = PTR_ERR(plane_state); | 359 | ret = PTR_ERR(plane_state); |
@@ -362,6 +362,9 @@ retry: | |||
362 | 362 | ||
363 | plane_state->rotation = BIT(DRM_ROTATE_0); | 363 | plane_state->rotation = BIT(DRM_ROTATE_0); |
364 | 364 | ||
365 | plane->old_fb = plane->fb; | ||
366 | plane_mask |= 1 << drm_plane_index(plane); | ||
367 | |||
365 | /* disable non-primary: */ | 368 | /* disable non-primary: */ |
366 | if (plane->type == DRM_PLANE_TYPE_PRIMARY) | 369 | if (plane->type == DRM_PLANE_TYPE_PRIMARY) |
367 | continue; | 370 | continue; |
@@ -382,19 +385,7 @@ retry: | |||
382 | ret = drm_atomic_commit(state); | 385 | ret = drm_atomic_commit(state); |
383 | 386 | ||
384 | fail: | 387 | fail: |
385 | drm_for_each_plane(plane, dev) { | 388 | drm_atomic_clean_old_fb(dev, plane_mask, ret); |
386 | if (ret == 0) { | ||
387 | struct drm_framebuffer *new_fb = plane->state->fb; | ||
388 | if (new_fb) | ||
389 | drm_framebuffer_reference(new_fb); | ||
390 | plane->fb = new_fb; | ||
391 | plane->crtc = plane->state->crtc; | ||
392 | |||
393 | if (plane->old_fb) | ||
394 | drm_framebuffer_unreference(plane->old_fb); | ||
395 | } | ||
396 | plane->old_fb = NULL; | ||
397 | } | ||
398 | 389 | ||
399 | if (ret == -EDEADLK) | 390 | if (ret == -EDEADLK) |
400 | goto backoff; | 391 | goto backoff; |
@@ -1236,7 +1227,9 @@ static int pan_display_atomic(struct fb_var_screeninfo *var, | |||
1236 | struct drm_fb_helper *fb_helper = info->par; | 1227 | struct drm_fb_helper *fb_helper = info->par; |
1237 | struct drm_device *dev = fb_helper->dev; | 1228 | struct drm_device *dev = fb_helper->dev; |
1238 | struct drm_atomic_state *state; | 1229 | struct drm_atomic_state *state; |
1230 | struct drm_plane *plane; | ||
1239 | int i, ret; | 1231 | int i, ret; |
1232 | unsigned plane_mask; | ||
1240 | 1233 | ||
1241 | state = drm_atomic_state_alloc(dev); | 1234 | state = drm_atomic_state_alloc(dev); |
1242 | if (!state) | 1235 | if (!state) |
@@ -1244,19 +1237,22 @@ static int pan_display_atomic(struct fb_var_screeninfo *var, | |||
1244 | 1237 | ||
1245 | state->acquire_ctx = dev->mode_config.acquire_ctx; | 1238 | state->acquire_ctx = dev->mode_config.acquire_ctx; |
1246 | retry: | 1239 | retry: |
1240 | plane_mask = 0; | ||
1247 | for(i = 0; i < fb_helper->crtc_count; i++) { | 1241 | for(i = 0; i < fb_helper->crtc_count; i++) { |
1248 | struct drm_mode_set *mode_set; | 1242 | struct drm_mode_set *mode_set; |
1249 | 1243 | ||
1250 | mode_set = &fb_helper->crtc_info[i].mode_set; | 1244 | mode_set = &fb_helper->crtc_info[i].mode_set; |
1251 | 1245 | ||
1252 | mode_set->crtc->primary->old_fb = mode_set->crtc->primary->fb; | ||
1253 | |||
1254 | mode_set->x = var->xoffset; | 1246 | mode_set->x = var->xoffset; |
1255 | mode_set->y = var->yoffset; | 1247 | mode_set->y = var->yoffset; |
1256 | 1248 | ||
1257 | ret = __drm_atomic_helper_set_config(mode_set, state); | 1249 | ret = __drm_atomic_helper_set_config(mode_set, state); |
1258 | if (ret != 0) | 1250 | if (ret != 0) |
1259 | goto fail; | 1251 | goto fail; |
1252 | |||
1253 | plane = mode_set->crtc->primary; | ||
1254 | plane_mask |= drm_plane_index(plane); | ||
1255 | plane->old_fb = plane->fb; | ||
1260 | } | 1256 | } |
1261 | 1257 | ||
1262 | ret = drm_atomic_commit(state); | 1258 | ret = drm_atomic_commit(state); |
@@ -1268,26 +1264,7 @@ retry: | |||
1268 | 1264 | ||
1269 | 1265 | ||
1270 | fail: | 1266 | fail: |
1271 | for(i = 0; i < fb_helper->crtc_count; i++) { | 1267 | drm_atomic_clean_old_fb(dev, plane_mask, ret); |
1272 | struct drm_mode_set *mode_set; | ||
1273 | struct drm_plane *plane; | ||
1274 | |||
1275 | mode_set = &fb_helper->crtc_info[i].mode_set; | ||
1276 | plane = mode_set->crtc->primary; | ||
1277 | |||
1278 | if (ret == 0) { | ||
1279 | struct drm_framebuffer *new_fb = plane->state->fb; | ||
1280 | |||
1281 | if (new_fb) | ||
1282 | drm_framebuffer_reference(new_fb); | ||
1283 | plane->fb = new_fb; | ||
1284 | plane->crtc = plane->state->crtc; | ||
1285 | |||
1286 | if (plane->old_fb) | ||
1287 | drm_framebuffer_unreference(plane->old_fb); | ||
1288 | } | ||
1289 | plane->old_fb = NULL; | ||
1290 | } | ||
1291 | 1268 | ||
1292 | if (ret == -EDEADLK) | 1269 | if (ret == -EDEADLK) |
1293 | goto backoff; | 1270 | goto backoff; |