Move the modeset commit code to drm_client.
No changes except exporting API.
Signed-off-by: Noralf Trønnes
---
drivers/gpu/drm/drm_client.c| 236
drivers/gpu/drm/drm_fb_helper.c | 232 ---
include/drm/drm_client.h| 3 +
3 files changed, 239 insertions(+), 232 deletions(-)
diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
index 84f848f21679..5b199c051960 100644
--- a/drivers/gpu/drm/drm_client.c
+++ b/drivers/gpu/drm/drm_client.c
@@ -9,6 +9,7 @@
#include
#include
+#include
#include
#include
#include
@@ -485,6 +486,241 @@ struct drm_mode_set *drm_client_find_modeset(struct
drm_mode_set *modesets, stru
}
EXPORT_SYMBOL(drm_client_find_modeset);
+/**
+ * drm_client_panel_rotation() - Check panel orientation
+ * @modeset: DRM modeset
+ * @rotation: Returned rotation value
+ *
+ * This function checks if the primary plane in @modeset can hw rotate to match
+ * the panel orientation on its connector.
+ *
+ * Note: Currently only 0 and 180 degrees are supported.
+ *
+ * Return:
+ * True if the plane can do the rotation, false otherwise.
+ */
+bool drm_client_panel_rotation(struct drm_mode_set *modeset, unsigned int
*rotation)
+{
+ struct drm_connector *connector = modeset->connectors[0];
+ struct drm_plane *plane = modeset->crtc->primary;
+ u64 valid_mask = 0;
+ unsigned int i;
+
+ if (!modeset->num_connectors)
+ return false;
+
+ switch (connector->display_info.panel_orientation) {
+ case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
+ *rotation = DRM_MODE_ROTATE_180;
+ break;
+ case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
+ *rotation = DRM_MODE_ROTATE_90;
+ break;
+ case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
+ *rotation = DRM_MODE_ROTATE_270;
+ break;
+ default:
+ *rotation = DRM_MODE_ROTATE_0;
+ }
+
+ /*
+* TODO: support 90 / 270 degree hardware rotation,
+* depending on the hardware this may require the framebuffer
+* to be in a specific tiling format.
+*/
+ if (*rotation != DRM_MODE_ROTATE_180 || !plane->rotation_property)
+ return false;
+
+ for (i = 0; i < plane->rotation_property->num_values; i++)
+ valid_mask |= (1ULL << plane->rotation_property->values[i]);
+
+ if (!(*rotation & valid_mask))
+ return false;
+
+ return true;
+}
+EXPORT_SYMBOL(drm_client_panel_rotation);
+
+static int drm_client_modesets_commit_atomic(struct drm_device *dev, struct
drm_mode_set *modesets,
+bool active)
+{
+ struct drm_plane_state *plane_state;
+ struct drm_plane *plane;
+ struct drm_atomic_state *state;
+ struct drm_modeset_acquire_ctx ctx;
+ struct drm_mode_set *mode_set;
+ int ret;
+
+ drm_modeset_acquire_init(&ctx, 0);
+
+ state = drm_atomic_state_alloc(dev);
+ if (!state) {
+ ret = -ENOMEM;
+ goto out_ctx;
+ }
+
+ state->acquire_ctx = &ctx;
+retry:
+ drm_for_each_plane(plane, dev) {
+ plane_state = drm_atomic_get_plane_state(state, plane);
+ if (IS_ERR(plane_state)) {
+ ret = PTR_ERR(plane_state);
+ goto out_state;
+ }
+
+ plane_state->rotation = DRM_MODE_ROTATE_0;
+
+ /* disable non-primary: */
+ if (plane->type == DRM_PLANE_TYPE_PRIMARY)
+ continue;
+
+ ret = __drm_atomic_helper_disable_plane(plane, plane_state);
+ if (ret != 0)
+ goto out_state;
+ }
+
+ drm_client_for_each_modeset(mode_set, modesets) {
+ struct drm_plane *primary = mode_set->crtc->primary;
+ unsigned int rotation;
+
+ if (drm_client_panel_rotation(mode_set, &rotation)) {
+ /* Cannot fail as we've already gotten the plane state
above */
+ plane_state = drm_atomic_get_new_plane_state(state,
primary);
+ plane_state->rotation = rotation;
+ }
+
+ ret = __drm_atomic_helper_set_config(mode_set, state);
+ if (ret != 0)
+ goto out_state;
+
+ /*
+* __drm_atomic_helper_set_config() sets active when a
+* mode is set, unconditionally clear it if we force DPMS off
+*/
+ if (!active) {
+ struct drm_crtc *crtc = mode_set->crtc;
+ struct drm_crtc_state *crtc_state =
drm_atomic_get_new_crtc_state(state, crtc);
+
+ crtc_state->active = false;
+ }
+ }
+
+ ret = drm_atomic_commit(state);
+
+out_state: