From patchwork Tue Mar 26 17:55:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Noralf_Tr=C3=B8nnes?= X-Patchwork-Id: 10871821 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E31281669 for ; Tue, 26 Mar 2019 17:56:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CEBAB28D54 for ; Tue, 26 Mar 2019 17:56:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BFC9528D66; Tue, 26 Mar 2019 17:56:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D69B628D54 for ; Tue, 26 Mar 2019 17:56:28 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8EC566E06C; Tue, 26 Mar 2019 17:56:11 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from smtp.domeneshop.no (smtp.domeneshop.no [IPv6:2a01:5b40:0:3005::1]) by gabe.freedesktop.org (Postfix) with ESMTPS id C05F06E075; Tue, 26 Mar 2019 17:56:08 +0000 (UTC) Received: from 211.81-166-168.customer.lyse.net ([81.166.168.211]:46322 helo=localhost.localdomain) by smtp.domeneshop.no with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.84_2) (envelope-from ) id 1h8qIw-0006Mj-RN; Tue, 26 Mar 2019 18:56:06 +0100 From: =?utf-8?q?Noralf_Tr=C3=B8nnes?= To: dri-devel@lists.freedesktop.org Subject: [PATCH 09/16] drm/fb-helper: Move out commit code Date: Tue, 26 Mar 2019 18:55:39 +0100 Message-Id: <20190326175546.18126-10-noralf@tronnes.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190326175546.18126-1-noralf@tronnes.org> References: <20190326175546.18126-1-noralf@tronnes.org> MIME-Version: 1.0 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tronnes.org; s=ds201810; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=oLfGyN9o8dKvbFYefpq6NwM/H9qqwOci9HCVOgB0K1Y=; b=mqfmcJIXJ8J9Dg+eRMXvhiaZCfG/Q8o2SZjB5APQai0zpEFSTU41QD3Xw1y0lqbeQC+2S8I9Gp3GE93RtZum4i3rnOMEQwXC2HU42nBMC4GhObTsk06+gfdHJuWZ8aGsGtpZm5c8ibeX13SKGTuDbxqfKP2VdHXSY0Rp/3uCv89V6ug3bDzYCu2hKQMux69sfsyKwTpa0KgpiCfQz+swrSR/4GnKWJR1kxdbgUvMWYKTzQsdQL0pwNddLVLNP4DSCeAQoRcgt7k0lYcRaJAe/GFBdXTyravEiHVcBFXSuN20dcpX+/sE0aMQ2Z4KrPO4iGXtE7OQypvDwFxiLdCXeA==; X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, mstaudt@suse.de Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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: + if (ret == -EDEADLK) + goto backoff; + + drm_atomic_state_put(state); +out_ctx: + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); + + return ret; + +backoff: + drm_atomic_state_clear(state); + drm_modeset_backoff(&ctx); + + goto retry; +} + +static int drm_client_modesets_commit_legacy(struct drm_device *dev, struct drm_mode_set *modesets) +{ + struct drm_mode_set *mode_set; + struct drm_plane *plane; + int ret = 0; + + drm_modeset_lock_all(dev); + drm_for_each_plane(plane, dev) { + if (plane->type != DRM_PLANE_TYPE_PRIMARY) + drm_plane_force_disable(plane); + + if (plane->rotation_property) + drm_mode_plane_set_obj_prop(plane, + plane->rotation_property, + DRM_MODE_ROTATE_0); + } + + drm_client_for_each_modeset(mode_set, modesets) { + struct drm_crtc *crtc = mode_set->crtc; + + if (crtc->funcs->cursor_set2) { + ret = crtc->funcs->cursor_set2(crtc, NULL, 0, 0, 0, 0, 0); + if (ret) + goto out; + } else if (crtc->funcs->cursor_set) { + ret = crtc->funcs->cursor_set(crtc, NULL, 0, 0, 0); + if (ret) + goto out; + } + + ret = drm_mode_set_config_internal(mode_set); + if (ret) + goto out; + } +out: + drm_modeset_unlock_all(dev); + + return ret; +} + +/** + * drm_client_modesets_commit() - Commit CRTC configuration + * @dev: DRM device + * @modesets: Modeset array + * + * Returns: + * Zero on success or negative error code on failure. + */ +int drm_client_modesets_commit(struct drm_device *dev, struct drm_mode_set *modesets) +{ + if (drm_drv_uses_atomic_modeset(dev)) + return drm_client_modesets_commit_atomic(dev, modesets, true); + else + return drm_client_modesets_commit_legacy(dev, modesets); +} +EXPORT_SYMBOL(drm_client_modesets_commit); + +static void drm_client_modesets_dpms_legacy(struct drm_device *dev, struct drm_mode_set *modesets, + int dpms_mode) +{ + struct drm_connector *connector; + struct drm_mode_set *modeset; + int j; + + drm_modeset_lock_all(dev); + drm_client_for_each_modeset(modeset, modesets) { + if (!modeset->crtc->enabled) + continue; + + for (j = 0; j < modeset->num_connectors; j++) { + connector = modeset->connectors[j]; + connector->funcs->dpms(connector, dpms_mode); + drm_object_property_set_value(&connector->base, + dev->mode_config.dpms_property, dpms_mode); + } + } + drm_modeset_unlock_all(dev); +} + +/** + * drm_client_modesets_dpms() - Set DPMS mode + * @dev: DRM device + * @modesets: Modeset array + * @mode: DPMS mode + * + * Note: For atomic drivers @mode is reduced to on/off. + */ +void drm_client_modesets_dpms(struct drm_device *dev, struct drm_mode_set *modesets, int mode) +{ + if (drm_drv_uses_atomic_modeset(dev)) + drm_client_modesets_commit_atomic(dev, modesets, mode == DRM_MODE_DPMS_ON); + else + drm_client_modesets_dpms_legacy(dev, modesets, mode); +} +EXPORT_SYMBOL(drm_client_modesets_dpms); + #ifdef CONFIG_DEBUG_FS static int drm_client_debugfs_internal_clients(struct seq_file *m, void *data) { diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 9dcb77dfff0a..be946d702019 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -382,200 +382,6 @@ int drm_fb_helper_debug_leave(struct fb_info *info) } EXPORT_SYMBOL(drm_fb_helper_debug_leave); -/** - * 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; -} - -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: - if (ret == -EDEADLK) - goto backoff; - - drm_atomic_state_put(state); -out_ctx: - drm_modeset_drop_locks(&ctx); - drm_modeset_acquire_fini(&ctx); - - return ret; - -backoff: - drm_atomic_state_clear(state); - drm_modeset_backoff(&ctx); - - goto retry; -} - -static int drm_client_modesets_commit_legacy(struct drm_device *dev, struct drm_mode_set *modesets) -{ - struct drm_mode_set *mode_set; - struct drm_plane *plane; - int ret = 0; - - drm_modeset_lock_all(dev); - drm_for_each_plane(plane, dev) { - if (plane->type != DRM_PLANE_TYPE_PRIMARY) - drm_plane_force_disable(plane); - - if (plane->rotation_property) - drm_mode_plane_set_obj_prop(plane, - plane->rotation_property, - DRM_MODE_ROTATE_0); - } - - drm_client_for_each_modeset(mode_set, modesets) { - struct drm_crtc *crtc = mode_set->crtc; - - if (crtc->funcs->cursor_set2) { - ret = crtc->funcs->cursor_set2(crtc, NULL, 0, 0, 0, 0, 0); - if (ret) - goto out; - } else if (crtc->funcs->cursor_set) { - ret = crtc->funcs->cursor_set(crtc, NULL, 0, 0, 0); - if (ret) - goto out; - } - - ret = drm_mode_set_config_internal(mode_set); - if (ret) - goto out; - } -out: - drm_modeset_unlock_all(dev); - - return ret; -} - -/** - * drm_client_modesets_commit() - Commit CRTC configuration - * @dev: DRM device - * @modesets: Modeset array - * - * Returns: - * Zero on success or negative error code on failure. - */ -int drm_client_modesets_commit(struct drm_device *dev, struct drm_mode_set *modesets) -{ - if (drm_drv_uses_atomic_modeset(dev)) - return drm_client_modesets_commit_atomic(dev, modesets, true); - else - return drm_client_modesets_commit_legacy(dev, modesets); -} - /** * drm_fb_helper_restore_fbdev_mode_unlocked - restore fbdev configuration * @fb_helper: driver-allocated fbdev helper, can be NULL @@ -693,44 +499,6 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { }; #endif -static void drm_client_modesets_dpms_legacy(struct drm_device *dev, struct drm_mode_set *modesets, - int dpms_mode) -{ - struct drm_connector *connector; - struct drm_mode_set *modeset; - int j; - - drm_modeset_lock_all(dev); - drm_client_for_each_modeset(modeset, modesets) { - if (!modeset->crtc->enabled) - continue; - - for (j = 0; j < modeset->num_connectors; j++) { - connector = modeset->connectors[j]; - connector->funcs->dpms(connector, dpms_mode); - drm_object_property_set_value(&connector->base, - dev->mode_config.dpms_property, dpms_mode); - } - } - drm_modeset_unlock_all(dev); -} - -/** - * drm_client_modesets_dpms() - Set DPMS mode - * @dev: DRM device - * @modesets: Modeset array - * @mode: DPMS mode - * - * Note: For atomic drivers @mode is reduced to on/off. - */ -void drm_client_modesets_dpms(struct drm_device *dev, struct drm_mode_set *modesets, int mode) -{ - if (drm_drv_uses_atomic_modeset(dev)) - drm_client_modesets_commit_atomic(dev, modesets, mode == DRM_MODE_DPMS_ON); - else - drm_client_modesets_dpms_legacy(dev, modesets, mode); -} - static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode) { struct drm_fb_helper *fb_helper = info->par; diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index b2efce3f7781..01e787f8bc12 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -142,6 +142,9 @@ void drm_client_framebuffer_delete(struct drm_client_buffer *buffer); struct drm_mode_set *drm_client_modesets_create(struct drm_device *dev); void drm_client_modesets_release(struct drm_mode_set *modesets); struct drm_mode_set *drm_client_find_modeset(struct drm_mode_set *modesets, struct drm_crtc *crtc); +bool drm_client_panel_rotation(struct drm_mode_set *modeset, unsigned int *rotation); +int drm_client_modesets_commit(struct drm_device *dev, struct drm_mode_set *modesets); +void drm_client_modesets_dpms(struct drm_device *dev, struct drm_mode_set *modesets, int mode); /** * drm_client_for_each_modeset() - Iterate over modesets