|
@@ -1217,6 +1217,57 @@ int drm_fb_helper_set_par(struct fb_info *info)
|
|
|
}
|
|
|
EXPORT_SYMBOL(drm_fb_helper_set_par);
|
|
|
|
|
|
+static int pan_display_atomic(struct fb_var_screeninfo *var,
|
|
|
+ struct fb_info *info)
|
|
|
+{
|
|
|
+ struct drm_fb_helper *fb_helper = info->par;
|
|
|
+ struct drm_device *dev = fb_helper->dev;
|
|
|
+ struct drm_atomic_state *state;
|
|
|
+ int i, ret;
|
|
|
+
|
|
|
+ state = drm_atomic_state_alloc(dev);
|
|
|
+ if (!state)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ state->acquire_ctx = dev->mode_config.acquire_ctx;
|
|
|
+retry:
|
|
|
+ for(i = 0; i < fb_helper->crtc_count; i++) {
|
|
|
+ struct drm_mode_set *mode_set;
|
|
|
+
|
|
|
+ mode_set = &fb_helper->crtc_info[i].mode_set;
|
|
|
+
|
|
|
+ mode_set->x = var->xoffset;
|
|
|
+ mode_set->y = var->yoffset;
|
|
|
+
|
|
|
+ ret = __drm_atomic_helper_set_config(mode_set, state);
|
|
|
+ if (ret != 0)
|
|
|
+ goto fail;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = drm_atomic_commit(state);
|
|
|
+ if (ret != 0)
|
|
|
+ goto fail;
|
|
|
+
|
|
|
+ info->var.xoffset = var->xoffset;
|
|
|
+ info->var.yoffset = var->yoffset;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+
|
|
|
+fail:
|
|
|
+ if (ret == -EDEADLK)
|
|
|
+ goto backoff;
|
|
|
+
|
|
|
+ drm_atomic_state_free(state);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+
|
|
|
+backoff:
|
|
|
+ drm_atomic_state_clear(state);
|
|
|
+ drm_atomic_legacy_backoff(state);
|
|
|
+
|
|
|
+ goto retry;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* drm_fb_helper_pan_display - implementation for ->fb_pan_display
|
|
|
* @var: updated screen information
|
|
@@ -1240,6 +1291,11 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
|
|
|
return -EBUSY;
|
|
|
}
|
|
|
|
|
|
+ if (fb_helper->atomic) {
|
|
|
+ ret = pan_display_atomic(var, info);
|
|
|
+ goto unlock;
|
|
|
+ }
|
|
|
+
|
|
|
for (i = 0; i < fb_helper->crtc_count; i++) {
|
|
|
modeset = &fb_helper->crtc_info[i].mode_set;
|
|
|
|
|
@@ -1254,6 +1310,7 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+unlock:
|
|
|
drm_modeset_unlock_all(dev);
|
|
|
return ret;
|
|
|
}
|