From patchwork Mon Mar 27 22:01:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sinclair Yeh X-Patchwork-Id: 9647593 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0B18A602C8 for ; Mon, 27 Mar 2017 22:03:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F0B3B27CF3 for ; Mon, 27 Mar 2017 22:03:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E57A22815E; Mon, 27 Mar 2017 22:03:50 +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=-4.2 required=2.0 tests=BAYES_00, 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 13AA627CF3 for ; Mon, 27 Mar 2017 22:03:50 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7824A6E375; Mon, 27 Mar 2017 22:03:49 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from EX13-EDG-OU-001.vmware.com (ex13-edg-ou-001.vmware.com [208.91.0.189]) by gabe.freedesktop.org (Postfix) with ESMTPS id B96CC6E373 for ; Mon, 27 Mar 2017 22:03:47 +0000 (UTC) Received: from sc9-mailhost3.vmware.com (10.113.161.73) by EX13-EDG-OU-001.vmware.com (10.113.208.155) with Microsoft SMTP Server id 15.0.1156.6; Mon, 27 Mar 2017 15:02:34 -0700 Received: from vmware.com (unknown [10.16.254.220]) by sc9-mailhost3.vmware.com (Postfix) with SMTP id 32F0940427; Mon, 27 Mar 2017 15:03:40 -0700 (PDT) Received: by vmware.com (sSMTP sendmail emulation); Mon, 27 Mar 2017 15:03:37 -0700 From: Sinclair Yeh To: Subject: [PATCH 11/11] drm/vmwgfx: Switch over to internal atomic API for SOU and LDU Date: Mon, 27 Mar 2017 15:01:04 -0700 Message-ID: <1490652064-44817-12-git-send-email-syeh@vmware.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1490652064-44817-1-git-send-email-syeh@vmware.com> References: <1490652064-44817-1-git-send-email-syeh@vmware.com> MIME-Version: 1.0 Received-SPF: None (EX13-EDG-OU-001.vmware.com: syeh@vmware.com does not designate permitted sender hosts) Cc: daniel.vetter@ffwll.ch, thellstrom@vmware.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Switch over to internal atomic API. This completes the atomic internal atomic switch for all the Display Units. Signed-off-by: Sinclair Yeh Signed-off-by: Thomas Hellstrom Reviewed-by: Thomas Hellstrom --- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 103 ++--------------- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 217 +++-------------------------------- 2 files changed, 25 insertions(+), 295 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 282a0ef..4954f26 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -95,7 +95,7 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) if (crtc == NULL) return 0; - fb = entry->base.crtc.primary->fb; + fb = entry->base.crtc.primary->state->fb; return vmw_kms_write_svga(dev_priv, w, h, fb->pitches[0], fb->format->cpp[0] * 8, @@ -104,7 +104,7 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) if (!list_empty(&lds->active)) { entry = list_entry(lds->active.next, typeof(*entry), active); - fb = entry->base.crtc.primary->fb; + fb = entry->base.crtc.primary->state->fb; vmw_kms_write_svga(dev_priv, fb->width, fb->height, fb->pitches[0], fb->format->cpp[0] * 8, fb->format->depth); @@ -255,102 +255,13 @@ static void vmw_ldu_crtc_helper_disable(struct drm_crtc *crtc) { } -static int vmw_ldu_crtc_set_config(struct drm_mode_set *set) -{ - struct vmw_private *dev_priv; - struct vmw_legacy_display_unit *ldu; - struct drm_connector *connector; - struct drm_display_mode *mode; - struct drm_encoder *encoder; - struct vmw_framebuffer *vfb; - struct drm_framebuffer *fb; - struct drm_crtc *crtc; - - if (!set) - return -EINVAL; - - if (!set->crtc) - return -EINVAL; - - /* get the ldu */ - crtc = set->crtc; - ldu = vmw_crtc_to_ldu(crtc); - vfb = set->fb ? vmw_framebuffer_to_vfb(set->fb) : NULL; - dev_priv = vmw_priv(crtc->dev); - - if (set->num_connectors > 1) { - DRM_ERROR("to many connectors\n"); - return -EINVAL; - } - - if (set->num_connectors == 1 && - set->connectors[0] != &ldu->base.connector) { - DRM_ERROR("connector doesn't match %p %p\n", - set->connectors[0], &ldu->base.connector); - return -EINVAL; - } - - /* ldu only supports one fb active at the time */ - if (dev_priv->ldu_priv->fb && vfb && - !(dev_priv->ldu_priv->num_active == 1 && - !list_empty(&ldu->active)) && - dev_priv->ldu_priv->fb != vfb) { - DRM_ERROR("Multiple framebuffers not supported\n"); - return -EINVAL; - } - - /* since they always map one to one these are safe */ - connector = &ldu->base.connector; - encoder = &ldu->base.encoder; - - /* should we turn the crtc off? */ - if (set->num_connectors == 0 || !set->mode || !set->fb) { - - connector->encoder = NULL; - encoder->crtc = NULL; - crtc->primary->fb = NULL; - crtc->enabled = false; - - vmw_ldu_del_active(dev_priv, ldu); - - return vmw_ldu_commit_list(dev_priv); - } - - - /* we now know we want to set a mode */ - mode = set->mode; - fb = set->fb; - - if (set->x + mode->hdisplay > fb->width || - set->y + mode->vdisplay > fb->height) { - DRM_ERROR("set outside of framebuffer\n"); - return -EINVAL; - } - - vmw_svga_enable(dev_priv); - - crtc->primary->fb = fb; - encoder->crtc = crtc; - connector->encoder = encoder; - crtc->x = set->x; - crtc->y = set->y; - crtc->mode = *mode; - crtc->enabled = true; - ldu->base.set_gui_x = set->x; - ldu->base.set_gui_y = set->y; - - vmw_ldu_add_active(dev_priv, ldu, vfb); - - return vmw_ldu_commit_list(dev_priv); -} - static const struct drm_crtc_funcs vmw_legacy_crtc_funcs = { .gamma_set = vmw_du_crtc_gamma_set, .destroy = vmw_ldu_crtc_destroy, .reset = vmw_du_crtc_reset, .atomic_duplicate_state = vmw_du_crtc_duplicate_state, .atomic_destroy_state = vmw_du_crtc_destroy_state, - .set_config = vmw_ldu_crtc_set_config, + .set_config = vmw_kms_set_config, }; @@ -439,8 +350,8 @@ vmw_ldu_primary_plane_atomic_update(struct drm_plane *plane, static const struct drm_plane_funcs vmw_ldu_plane_funcs = { - .update_plane = drm_primary_helper_update, - .disable_plane = drm_primary_helper_disable, + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, .destroy = vmw_du_primary_plane_destroy, .reset = vmw_du_plane_reset, .atomic_duplicate_state = vmw_du_plane_duplicate_state, @@ -448,8 +359,8 @@ static const struct drm_plane_funcs vmw_ldu_plane_funcs = { }; static const struct drm_plane_funcs vmw_ldu_cursor_funcs = { - .update_plane = vmw_du_cursor_plane_update, - .disable_plane = vmw_du_cursor_plane_disable, + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, .destroy = vmw_du_cursor_plane_destroy, .reset = vmw_du_plane_reset, .atomic_duplicate_state = vmw_du_plane_duplicate_state, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index e4154f1..9d73f79 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -205,52 +205,6 @@ static int vmw_sou_fifo_destroy(struct vmw_private *dev_priv, } /** - * Free the backing store. - */ -static void vmw_sou_backing_free(struct vmw_private *dev_priv, - struct vmw_screen_object_unit *sou) -{ - vmw_dmabuf_unreference(&sou->buffer); - sou->buffer_size = 0; -} - -/** - * Allocate the backing store for the buffer. - */ -static int vmw_sou_backing_alloc(struct vmw_private *dev_priv, - struct vmw_screen_object_unit *sou, - unsigned long size) -{ - int ret; - - if (sou->buffer_size == size) - return 0; - - if (sou->buffer) - vmw_sou_backing_free(dev_priv, sou); - - sou->buffer = kzalloc(sizeof(*sou->buffer), GFP_KERNEL); - if (unlikely(sou->buffer == NULL)) - return -ENOMEM; - - /* After we have alloced the backing store might not be able to - * resume the overlays, this is preferred to failing to alloc. - */ - vmw_overlay_pause_all(dev_priv); - ret = vmw_dmabuf_init(dev_priv, sou->buffer, size, - &vmw_vram_ne_placement, - false, &vmw_dmabuf_bo_free); - vmw_overlay_resume_all(dev_priv); - - if (unlikely(ret != 0)) - sou->buffer = NULL; /* vmw_dmabuf_init frees on error */ - else - sou->buffer_size = size; - - return ret; -} - -/** * vmw_sou_crtc_mode_set_nofb - Create new screen * * @crtc: CRTC associated with the new screen @@ -353,158 +307,14 @@ static void vmw_sou_crtc_helper_disable(struct drm_crtc *crtc) } } -static int vmw_sou_crtc_set_config(struct drm_mode_set *set) -{ - struct vmw_private *dev_priv; - struct vmw_screen_object_unit *sou; - struct drm_connector *connector; - struct drm_display_mode *mode; - struct drm_encoder *encoder; - struct vmw_framebuffer *vfb; - struct drm_framebuffer *fb; - struct drm_crtc *crtc; - int ret = 0; - - if (!set) - return -EINVAL; - - if (!set->crtc) - return -EINVAL; - - /* get the sou */ - crtc = set->crtc; - sou = vmw_crtc_to_sou(crtc); - vfb = set->fb ? vmw_framebuffer_to_vfb(set->fb) : NULL; - dev_priv = vmw_priv(crtc->dev); - - if (set->num_connectors > 1) { - DRM_ERROR("Too many connectors\n"); - return -EINVAL; - } - - if (set->num_connectors == 1 && - set->connectors[0] != &sou->base.connector) { - DRM_ERROR("Connector doesn't match %p %p\n", - set->connectors[0], &sou->base.connector); - return -EINVAL; - } - - /* Only one active implicit frame-buffer at a time. */ - mutex_lock(&dev_priv->global_kms_state_mutex); - if (sou->base.is_implicit && - dev_priv->implicit_fb && vfb && - !(dev_priv->num_implicit == 1 && - sou->base.active_implicit) && - dev_priv->implicit_fb != vfb) { - mutex_unlock(&dev_priv->global_kms_state_mutex); - DRM_ERROR("Multiple implicit framebuffers not supported.\n"); - return -EINVAL; - } - mutex_unlock(&dev_priv->global_kms_state_mutex); - - /* since they always map one to one these are safe */ - connector = &sou->base.connector; - encoder = &sou->base.encoder; - - /* should we turn the crtc off */ - if (set->num_connectors == 0 || !set->mode || !set->fb) { - ret = vmw_sou_fifo_destroy(dev_priv, sou); - /* the hardware has hung don't do anything more */ - if (unlikely(ret != 0)) - return ret; - - connector->encoder = NULL; - encoder->crtc = NULL; - crtc->primary->fb = NULL; - crtc->x = 0; - crtc->y = 0; - crtc->enabled = false; - - vmw_kms_del_active(dev_priv, &sou->base); - - vmw_sou_backing_free(dev_priv, sou); - - return 0; - } - - - /* we now know we want to set a mode */ - mode = set->mode; - fb = set->fb; - - if (set->x + mode->hdisplay > fb->width || - set->y + mode->vdisplay > fb->height) { - DRM_ERROR("set outside of framebuffer\n"); - return -EINVAL; - } - - vmw_svga_enable(dev_priv); - - if (mode->hdisplay != crtc->mode.hdisplay || - mode->vdisplay != crtc->mode.vdisplay) { - /* no need to check if depth is different, because backing - * store depth is forced to 4 by the device. - */ - - ret = vmw_sou_fifo_destroy(dev_priv, sou); - /* the hardware has hung don't do anything more */ - if (unlikely(ret != 0)) - return ret; - - vmw_sou_backing_free(dev_priv, sou); - } - - if (!sou->buffer) { - /* forced to depth 4 by the device */ - size_t size = mode->hdisplay * mode->vdisplay * 4; - ret = vmw_sou_backing_alloc(dev_priv, sou, size); - if (unlikely(ret != 0)) - return ret; - } - - ret = vmw_sou_fifo_create(dev_priv, sou, set->x, set->y, mode); - if (unlikely(ret != 0)) { - /* - * We are in a bit of a situation here, the hardware has - * hung and we may or may not have a buffer hanging of - * the screen object, best thing to do is not do anything - * if we where defined, if not just turn the crtc of. - * Not what userspace wants but it needs to htfu. - */ - if (sou->defined) - return ret; - - connector->encoder = NULL; - encoder->crtc = NULL; - crtc->primary->fb = NULL; - crtc->x = 0; - crtc->y = 0; - crtc->enabled = false; - - return ret; - } - - vmw_kms_add_active(dev_priv, &sou->base, vfb); - - connector->encoder = encoder; - encoder->crtc = crtc; - crtc->mode = *mode; - crtc->primary->fb = fb; - crtc->x = set->x; - crtc->y = set->y; - crtc->enabled = true; - - return 0; -} - static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc, - struct drm_framebuffer *fb, + struct drm_framebuffer *new_fb, struct drm_pending_vblank_event *event, uint32_t flags) { struct vmw_private *dev_priv = vmw_priv(crtc->dev); struct drm_framebuffer *old_fb = crtc->primary->fb; - struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb); + struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(new_fb); struct vmw_fence_obj *fence = NULL; struct drm_vmw_rect vclips; int ret; @@ -512,7 +322,12 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc, if (!vmw_kms_crtc_flippable(dev_priv, crtc)) return -EINVAL; - crtc->primary->fb = fb; + flags &= ~DRM_MODE_PAGE_FLIP_ASYNC; + ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags); + if (ret) { + DRM_ERROR("Page flip error %d.\n", ret); + return ret; + } /* do a full screen dirty update */ vclips.x = crtc->x; @@ -559,7 +374,7 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc, return ret; out_no_fence: - crtc->primary->fb = old_fb; + drm_atomic_set_fb_for_plane(crtc->primary->state, old_fb); return ret; } @@ -569,7 +384,7 @@ static const struct drm_crtc_funcs vmw_screen_object_crtc_funcs = { .reset = vmw_du_crtc_reset, .atomic_duplicate_state = vmw_du_crtc_duplicate_state, .atomic_destroy_state = vmw_du_crtc_destroy_state, - .set_config = vmw_sou_crtc_set_config, + .set_config = vmw_kms_set_config, .page_flip = vmw_sou_crtc_page_flip, }; @@ -711,12 +526,16 @@ static void vmw_sou_primary_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { + struct drm_crtc *crtc = plane->state->crtc; + + if (crtc) + crtc->primary->fb = plane->state->fb; } static const struct drm_plane_funcs vmw_sou_plane_funcs = { - .update_plane = drm_primary_helper_update, - .disable_plane = drm_primary_helper_disable, + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, .destroy = vmw_du_primary_plane_destroy, .reset = vmw_du_plane_reset, .atomic_duplicate_state = vmw_du_plane_duplicate_state, @@ -724,8 +543,8 @@ static const struct drm_plane_funcs vmw_sou_plane_funcs = { }; static const struct drm_plane_funcs vmw_sou_cursor_funcs = { - .update_plane = vmw_du_cursor_plane_update, - .disable_plane = vmw_du_cursor_plane_disable, + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, .destroy = vmw_du_cursor_plane_destroy, .reset = vmw_du_plane_reset, .atomic_duplicate_state = vmw_du_plane_duplicate_state,