From patchwork Wed Jun 26 01:36:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rodrigo Siqueira X-Patchwork-Id: 11016711 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 09058924 for ; Wed, 26 Jun 2019 01:36:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EBDB8271CB for ; Wed, 26 Jun 2019 01:36:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E0287285F2; Wed, 26 Jun 2019 01:36:26 +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,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,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 841D7271CB for ; Wed, 26 Jun 2019 01:36:26 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D4E4E6E1BB; Wed, 26 Jun 2019 01:36:25 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-qt1-x841.google.com (mail-qt1-x841.google.com [IPv6:2607:f8b0:4864:20::841]) by gabe.freedesktop.org (Postfix) with ESMTPS id 179736E1BB for ; Wed, 26 Jun 2019 01:36:24 +0000 (UTC) Received: by mail-qt1-x841.google.com with SMTP id x47so627988qtk.11 for ; Tue, 25 Jun 2019 18:36:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=Z5NrdX7NWwAoR74sTDNwhmRnjPJuMOFlYOfia6fSoF0=; b=fvmUOQqMtgqHXiJOQW562/tS66vU2tnpBWWPokDwFYCAfUp5SB/i9BZHYMdstwArKD M2Vvy+OE3m2AFOsl+VVdT89S9luPMFB6qrAHpThkhiuNv8xvFQPOEDSH8vLHmCeb9xBq 3xuEhURjOrBW4Dvi+ZU6FszaqrpkiTf/ILi+6LkDBwjnnEwSFBj0SRA9zuO40HULonnV Om3sBy98rRm+zvsQTBk9Z3OVUM9tvw8qkhuKBX7NYvCMQTusH1/JgEsvhP1TCQ5IdVkd 5soaY/PGsirirzQrcDrijQg1971TfVdZoCmokpfHKfDru9uidz3NtlDVwiLXWPE1KJiF RR0Q== X-Gm-Message-State: APjAAAVLYYN8zEz3Jk996qlR/w7Hk+mXllOBxzQyLMUM4XBnAp+joxMj qkwckGTbcJboQRUHJVztM44= X-Google-Smtp-Source: APXvYqwGsxCL242iIdEU4rNVTpJKxMlXP+fmKwcNueML+N/BprK0zHQHzHQ6gOhAYyCUgth2h/NuJQ== X-Received: by 2002:ac8:17e6:: with SMTP id r35mr1292524qtk.215.1561512983200; Tue, 25 Jun 2019 18:36:23 -0700 (PDT) Received: from smtp.gmail.com ([187.121.151.146]) by smtp.gmail.com with ESMTPSA id c5sm8641883qkb.41.2019.06.25.18.36.20 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Tue, 25 Jun 2019 18:36:22 -0700 (PDT) Date: Tue, 25 Jun 2019 22:36:18 -0300 From: Rodrigo Siqueira To: Brian Starkey , Liviu Dudau , Daniel Vetter , Haneen Mohammed , Simon Ser Subject: [PATCH V3 1/5] drm/vkms: Avoid assigning 0 for possible_crtc Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: NeoMutt/20180716 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=Z5NrdX7NWwAoR74sTDNwhmRnjPJuMOFlYOfia6fSoF0=; b=AEfuWP65YYdqezhUt9Nl1emQyjaECK5qQwk7hrbZkP9cB8u9dyggDWOVgkQXMVEXlM i4Gb7BFWNZcCoTnlzijHQ0Bu7OagWa9qJH55mozGBqrfw6Uo3nOS6SikMx9mKy2OtFNp GMXsPpGvML02cMESF1OGC1ruB1sosAsriTZQv2/wXhGx+QjUsNGd1neSDKMa4BvsKxFk 1j+q+w5HnMc+PqnHVDpmvw1p6ul83sF0/gMzkVTQ6IZMrN257C5bDNSfEW0ZHy4fGELX NthS+POR7/9jtHo5OnTmhRpbqyys0Cl+RoS4IpXLscaWKk/RfOmlpxWquli5yxMXSKA1 Yl3w== 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: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP When vkms invoke drm_universal_plane_init(), it sets 0 for possible_crtcs parameter which means that planes can't be attached to any CRTC. It currently works due to some safeguard in the drm_crtc file; however, it is possible to identify the problem by trying to append a second connector. This patch fixes this issue by modifying vkms_plane_init() to accept an index parameter which makes the code a little bit more flexible and avoid set zero to possible_crtcs. Signed-off-by: Rodrigo Siqueira Reviewed-by: Daniel Vetter --- drivers/gpu/drm/vkms/vkms_drv.c | 2 +- drivers/gpu/drm/vkms/vkms_drv.h | 4 ++-- drivers/gpu/drm/vkms/vkms_output.c | 6 +++--- drivers/gpu/drm/vkms/vkms_plane.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index cc53ef88a331..966b3d653189 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -127,7 +127,7 @@ static int vkms_modeset_init(struct vkms_device *vkmsdev) dev->mode_config.preferred_depth = 24; dev->mode_config.helper_private = &vkms_mode_config_helpers; - return vkms_output_init(vkmsdev); + return vkms_output_init(vkmsdev, 0); } static int __init vkms_init(void) diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index 12b4db7ac641..e2d1aa089dec 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -115,10 +115,10 @@ bool vkms_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, int *max_error, ktime_t *vblank_time, bool in_vblank_irq); -int vkms_output_init(struct vkms_device *vkmsdev); +int vkms_output_init(struct vkms_device *vkmsdev, int index); struct drm_plane *vkms_plane_init(struct vkms_device *vkmsdev, - enum drm_plane_type type); + enum drm_plane_type type, int index); /* Gem stuff */ struct drm_gem_object *vkms_gem_create(struct drm_device *dev, diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c index 56fb5c2a2315..fb1941a6522c 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -35,7 +35,7 @@ static const struct drm_connector_helper_funcs vkms_conn_helper_funcs = { .get_modes = vkms_conn_get_modes, }; -int vkms_output_init(struct vkms_device *vkmsdev) +int vkms_output_init(struct vkms_device *vkmsdev, int index) { struct vkms_output *output = &vkmsdev->output; struct drm_device *dev = &vkmsdev->drm; @@ -45,12 +45,12 @@ int vkms_output_init(struct vkms_device *vkmsdev) struct drm_plane *primary, *cursor = NULL; int ret; - primary = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_PRIMARY); + primary = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_PRIMARY, index); if (IS_ERR(primary)) return PTR_ERR(primary); if (enable_cursor) { - cursor = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_CURSOR); + cursor = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_CURSOR, index); if (IS_ERR(cursor)) { ret = PTR_ERR(cursor); goto err_cursor; diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index 0fceb6258422..18c630cfc485 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -176,7 +176,7 @@ static const struct drm_plane_helper_funcs vkms_primary_helper_funcs = { }; struct drm_plane *vkms_plane_init(struct vkms_device *vkmsdev, - enum drm_plane_type type) + enum drm_plane_type type, int index) { struct drm_device *dev = &vkmsdev->drm; const struct drm_plane_helper_funcs *funcs; @@ -198,7 +198,7 @@ struct drm_plane *vkms_plane_init(struct vkms_device *vkmsdev, funcs = &vkms_primary_helper_funcs; } - ret = drm_universal_plane_init(dev, plane, 0, + ret = drm_universal_plane_init(dev, plane, 1 << index, &vkms_plane_funcs, formats, nformats, NULL, type, NULL); From patchwork Wed Jun 26 01:37:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rodrigo Siqueira X-Patchwork-Id: 11016715 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 5A0CE924 for ; Wed, 26 Jun 2019 01:37:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 449AF271CB for ; Wed, 26 Jun 2019 01:37:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 37B85285F2; Wed, 26 Jun 2019 01:37:15 +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,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,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 2A448271CB for ; Wed, 26 Jun 2019 01:37:14 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5CE4F6E1C0; Wed, 26 Jun 2019 01:37:13 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-qt1-x841.google.com (mail-qt1-x841.google.com [IPv6:2607:f8b0:4864:20::841]) by gabe.freedesktop.org (Postfix) with ESMTPS id D21D56E1C0 for ; Wed, 26 Jun 2019 01:37:11 +0000 (UTC) Received: by mail-qt1-x841.google.com with SMTP id y57so674540qtk.4 for ; Tue, 25 Jun 2019 18:37:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=MTm41ch/IfvllWh6ceCA6B/jdUDfYL6v6ai7er0SEjM=; b=PVYDhQYREz82T/qvxE2Jet0KNn7CPlD/rQCySufd54sWy3jnl8UaE1RVFWOhBstBAL msKNqjsRtyOdXE90RwWWCEWZdnO1KELKGm/cH14QgFk5z2+9cDSJl2oIKQWQ/X8kf+Rn M22KJPz6H5TXX8w9NpCa4NCWG+hzcByOYuqgIUjh3gNNG8ehhokitmyL7YBQnPQBZzeH D1n4YiZKMYHJSBBDyntM925R0x4EgHSqh3InEGMzJ2arrmk8DexUMypyj1pwlKj139gE urrUM27JYoZPuckDfX4BO3P+NCsw53T/8QZOUE9B/ddyEYs/1py0/ioCYEogUHiGqmdN mBuw== X-Gm-Message-State: APjAAAXi7eNfh4i5xFBDn5aMMr+98dv8Oc672tYQ8bkMs/QKtIcbwdmf Nd6mpM3wV7Tp/gq8tKQ6Jbo= X-Google-Smtp-Source: APXvYqzxA+g6e5QrKilO8wnViqL2u7CvVy8VVi4GfIy0gRitpkA2gxLb8qoJ+j6lZ3+IlRBQ6zsYWA== X-Received: by 2002:a0c:8af0:: with SMTP id 45mr1221276qvw.111.1561513030816; Tue, 25 Jun 2019 18:37:10 -0700 (PDT) Received: from smtp.gmail.com ([187.121.151.146]) by smtp.gmail.com with ESMTPSA id k123sm8562327qkf.13.2019.06.25.18.37.07 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Tue, 25 Jun 2019 18:37:10 -0700 (PDT) Date: Tue, 25 Jun 2019 22:37:05 -0300 From: Rodrigo Siqueira To: Brian Starkey , Liviu Dudau , Daniel Vetter , Haneen Mohammed , Simon Ser Subject: [PATCH V3 2/5] drm/vkms: Rename vkms_crc.c into vkms_composer.c Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: NeoMutt/20180716 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=MTm41ch/IfvllWh6ceCA6B/jdUDfYL6v6ai7er0SEjM=; b=PEBeUKwWSA1k0XFj/VGoMqYYtgXCq2FZV37WLIOLfobE7ShUVuJZhGl5Ubftuzh6ga 0ZHGv0Je291rq/UHeMPkuUwLnk62xQngAy36yNf+oOp/BjZkO15pmfrZf6hlIt5csA48 GaxtCsT1woEFmXGmIxFNuYbjZw8SxLMQvOlaQYYvhXhd5Yl205UbcNdrmGyfCUymG1b7 TE6fMXA79m2QAeBd8YsiXkj+5/7XhwZIrCY7bEjIPnn4OKFSPSc05/vO+aAtinvrYnpc 1Gg/c20QY6TMJj57P5f7gEWAACMB1NcWSUmjRIJFprKp7OoSqy+SH+/UuQpnmcJcaPhP tSzg== 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: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP As a preparation work for introducing writeback to vkms, this patch renames the file vkms_crc.c into vkms_composer.c. Accordingly, it also adjusts the functions and data structures to match the changes. No functional change. Signed-off-by: Rodrigo Siqueira Acked-by: Daniel Vetter --- drivers/gpu/drm/vkms/Makefile | 2 +- .../drm/vkms/{vkms_crc.c => vkms_composer.c} | 98 ++++++++++--------- drivers/gpu/drm/vkms/vkms_crtc.c | 30 +++--- drivers/gpu/drm/vkms/vkms_drv.c | 4 +- drivers/gpu/drm/vkms/vkms_drv.h | 28 +++--- drivers/gpu/drm/vkms/vkms_plane.c | 36 +++---- 6 files changed, 101 insertions(+), 97 deletions(-) rename drivers/gpu/drm/vkms/{vkms_crc.c => vkms_composer.c} (65%) diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile index 89f09bec7b23..0b767d7efa24 100644 --- a/drivers/gpu/drm/vkms/Makefile +++ b/drivers/gpu/drm/vkms/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -vkms-y := vkms_drv.o vkms_plane.o vkms_output.o vkms_crtc.o vkms_gem.o vkms_crc.o +vkms-y := vkms_drv.o vkms_plane.o vkms_output.o vkms_crtc.o vkms_gem.o vkms_composer.o obj-$(CONFIG_DRM_VKMS) += vkms.o diff --git a/drivers/gpu/drm/vkms/vkms_crc.c b/drivers/gpu/drm/vkms/vkms_composer.c similarity index 65% rename from drivers/gpu/drm/vkms/vkms_crc.c rename to drivers/gpu/drm/vkms/vkms_composer.c index 30b048b67a32..eb7ea8be1f98 100644 --- a/drivers/gpu/drm/vkms/vkms_crc.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -10,25 +10,25 @@ * compute_crc - Compute CRC value on output frame * * @vaddr_out: address to final framebuffer - * @crc_out: framebuffer's metadata + * @composer: framebuffer's metadata * * returns CRC value computed using crc32 on the visible portion of * the final framebuffer at vaddr_out */ -static uint32_t compute_crc(void *vaddr_out, struct vkms_crc_data *crc_out) +static uint32_t compute_crc(void *vaddr_out, struct vkms_composer *composer) { int i, j, src_offset; - int x_src = crc_out->src.x1 >> 16; - int y_src = crc_out->src.y1 >> 16; - int h_src = drm_rect_height(&crc_out->src) >> 16; - int w_src = drm_rect_width(&crc_out->src) >> 16; + int x_src = composer->src.x1 >> 16; + int y_src = composer->src.y1 >> 16; + int h_src = drm_rect_height(&composer->src) >> 16; + int w_src = drm_rect_width(&composer->src) >> 16; u32 crc = 0; for (i = y_src; i < y_src + h_src; ++i) { for (j = x_src; j < x_src + w_src; ++j) { - src_offset = crc_out->offset - + (i * crc_out->pitch) - + (j * crc_out->cpp); + src_offset = composer->offset + + (i * composer->pitch) + + (j * composer->cpp); /* XRGB format ignores Alpha channel */ memset(vaddr_out + src_offset + 24, 0, 8); crc = crc32_le(crc, vaddr_out + src_offset, @@ -43,8 +43,8 @@ static uint32_t compute_crc(void *vaddr_out, struct vkms_crc_data *crc_out) * blend - belnd value at vaddr_src with value at vaddr_dst * @vaddr_dst: destination address * @vaddr_src: source address - * @crc_dst: destination framebuffer's metadata - * @crc_src: source framebuffer's metadata + * @dest_composer: destination framebuffer's metadata + * @src_composer: source framebuffer's metadata * * Blend value at vaddr_src with value at vaddr_dst. * Currently, this function write value at vaddr_src on value @@ -55,31 +55,31 @@ static uint32_t compute_crc(void *vaddr_out, struct vkms_crc_data *crc_out) * instead of overwriting it. */ static void blend(void *vaddr_dst, void *vaddr_src, - struct vkms_crc_data *crc_dst, - struct vkms_crc_data *crc_src) + struct vkms_composer *dest_composer, + struct vkms_composer *src_composer) { int i, j, j_dst, i_dst; int offset_src, offset_dst; - int x_src = crc_src->src.x1 >> 16; - int y_src = crc_src->src.y1 >> 16; + int x_src = src_composer->src.x1 >> 16; + int y_src = src_composer->src.y1 >> 16; - int x_dst = crc_src->dst.x1; - int y_dst = crc_src->dst.y1; - int h_dst = drm_rect_height(&crc_src->dst); - int w_dst = drm_rect_width(&crc_src->dst); + int x_dst = src_composer->dst.x1; + int y_dst = src_composer->dst.y1; + int h_dst = drm_rect_height(&src_composer->dst); + int w_dst = drm_rect_width(&src_composer->dst); int y_limit = y_src + h_dst; int x_limit = x_src + w_dst; for (i = y_src, i_dst = y_dst; i < y_limit; ++i) { for (j = x_src, j_dst = x_dst; j < x_limit; ++j) { - offset_dst = crc_dst->offset - + (i_dst * crc_dst->pitch) - + (j_dst++ * crc_dst->cpp); - offset_src = crc_src->offset - + (i * crc_src->pitch) - + (j * crc_src->cpp); + offset_dst = dest_composer->offset + + (i_dst * dest_composer->pitch) + + (j_dst++ * dest_composer->cpp); + offset_src = src_composer->offset + + (i * src_composer->pitch) + + (j * src_composer->cpp); memcpy(vaddr_dst + offset_dst, vaddr_src + offset_src, sizeof(u32)); @@ -88,25 +88,27 @@ static void blend(void *vaddr_dst, void *vaddr_src, } } -static void compose_cursor(struct vkms_crc_data *cursor_crc, - struct vkms_crc_data *primary_crc, void *vaddr_out) +static void compose_cursor(struct vkms_composer *cursor_composer, + struct vkms_composer *primary_composer, + void *vaddr_out) { struct drm_gem_object *cursor_obj; struct vkms_gem_object *cursor_vkms_obj; - cursor_obj = drm_gem_fb_get_obj(&cursor_crc->fb, 0); + cursor_obj = drm_gem_fb_get_obj(&cursor_composer->fb, 0); cursor_vkms_obj = drm_gem_to_vkms_gem(cursor_obj); if (WARN_ON(!cursor_vkms_obj->vaddr)) return; - blend(vaddr_out, cursor_vkms_obj->vaddr, primary_crc, cursor_crc); + blend(vaddr_out, cursor_vkms_obj->vaddr, + primary_composer, cursor_composer); } -static uint32_t _vkms_get_crc(struct vkms_crc_data *primary_crc, - struct vkms_crc_data *cursor_crc) +static uint32_t _vkms_get_crc(struct vkms_composer *primary_composer, + struct vkms_composer *cursor_composer) { - struct drm_framebuffer *fb = &primary_crc->fb; + struct drm_framebuffer *fb = &primary_composer->fb; struct drm_gem_object *gem_obj = drm_gem_fb_get_obj(fb, 0); struct vkms_gem_object *vkms_obj = drm_gem_to_vkms_gem(gem_obj); void *vaddr_out = kzalloc(vkms_obj->gem.size, GFP_KERNEL); @@ -124,10 +126,10 @@ static uint32_t _vkms_get_crc(struct vkms_crc_data *primary_crc, memcpy(vaddr_out, vkms_obj->vaddr, vkms_obj->gem.size); - if (cursor_crc) - compose_cursor(cursor_crc, primary_crc, vaddr_out); + if (cursor_composer) + compose_cursor(cursor_composer, primary_composer, vaddr_out); - crc = compute_crc(vaddr_out, primary_crc); + crc = compute_crc(vaddr_out, primary_composer); kfree(vaddr_out); @@ -135,35 +137,35 @@ static uint32_t _vkms_get_crc(struct vkms_crc_data *primary_crc, } /** - * vkms_crc_work_handle - ordered work_struct to compute CRC + * vkms_composer_worker - ordered work_struct to compute CRC * * @work: work_struct * - * Work handler for computing CRCs. work_struct scheduled in + * Work handler for composing and computing CRCs. work_struct scheduled in * an ordered workqueue that's periodically scheduled to run by * _vblank_handle() and flushed at vkms_atomic_crtc_destroy_state(). */ -void vkms_crc_work_handle(struct work_struct *work) +void vkms_composer_worker(struct work_struct *work) { struct vkms_crtc_state *crtc_state = container_of(work, struct vkms_crtc_state, - crc_work); + composer_work); struct drm_crtc *crtc = crtc_state->base.crtc; struct vkms_output *out = drm_crtc_to_vkms_output(crtc); - struct vkms_crc_data *primary_crc = NULL; - struct vkms_crc_data *cursor_crc = NULL; + struct vkms_composer *primary_composer = NULL; + struct vkms_composer *cursor_composer = NULL; u32 crc32 = 0; u64 frame_start, frame_end; bool crc_pending; - spin_lock_irq(&out->crc_lock); + spin_lock_irq(&out->composer_lock); frame_start = crtc_state->frame_start; frame_end = crtc_state->frame_end; crc_pending = crtc_state->crc_pending; crtc_state->frame_start = 0; crtc_state->frame_end = 0; crtc_state->crc_pending = false; - spin_unlock_irq(&out->crc_lock); + spin_unlock_irq(&out->composer_lock); /* * We raced with the vblank hrtimer and previous work already computed @@ -173,13 +175,13 @@ void vkms_crc_work_handle(struct work_struct *work) return; if (crtc_state->num_active_planes >= 1) - primary_crc = crtc_state->active_planes[0]->crc_data; + primary_composer = crtc_state->active_planes[0]->composer; if (crtc_state->num_active_planes == 2) - cursor_crc = crtc_state->active_planes[1]->crc_data; + cursor_composer = crtc_state->active_planes[1]->composer; - if (primary_crc) - crc32 = _vkms_get_crc(primary_crc, cursor_crc); + if (primary_composer) + crc32 = _vkms_get_crc(primary_composer, cursor_composer); /* * The worker can fall behind the vblank hrtimer, make sure we catch up. @@ -237,7 +239,7 @@ int vkms_set_crc_source(struct drm_crtc *crtc, const char *src_name) ret = vkms_crc_parse_source(src_name, &enabled); spin_lock_irq(&out->lock); - out->crc_enabled = enabled; + out->composer_enabled = enabled; spin_unlock_irq(&out->lock); return ret; diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index a648892379c3..04c6f4250dea 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -24,14 +24,14 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer) if (!ret) DRM_ERROR("vkms failure on handling vblank"); - state = output->crc_state; - if (state && output->crc_enabled) { + state = output->composer_state; + if (state && output->composer_enabled) { u64 frame = drm_crtc_accurate_vblank_count(crtc); - /* update frame_start only if a queued vkms_crc_work_handle() + /* update frame_start only if a queued vkms_composer_worker() * has read the data */ - spin_lock(&output->crc_lock); + spin_lock(&output->composer_lock); if (!state->crc_pending) state->frame_start = frame; else @@ -39,11 +39,11 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer) state->frame_start, frame); state->frame_end = frame; state->crc_pending = true; - spin_unlock(&output->crc_lock); + spin_unlock(&output->composer_lock); - ret = queue_work(output->crc_workq, &state->crc_work); + ret = queue_work(output->composer_workq, &state->composer_work); if (!ret) - DRM_DEBUG_DRIVER("vkms_crc_work_handle already queued\n"); + DRM_DEBUG_DRIVER("Composer worker already queued\n"); } spin_unlock(&output->lock); @@ -114,7 +114,7 @@ vkms_atomic_crtc_duplicate_state(struct drm_crtc *crtc) __drm_atomic_helper_crtc_duplicate_state(crtc, &vkms_state->base); - INIT_WORK(&vkms_state->crc_work, vkms_crc_work_handle); + INIT_WORK(&vkms_state->composer_work, vkms_composer_worker); return &vkms_state->base; } @@ -126,7 +126,7 @@ static void vkms_atomic_crtc_destroy_state(struct drm_crtc *crtc, __drm_atomic_helper_crtc_destroy_state(state); - WARN_ON(work_pending(&vkms_state->crc_work)); + WARN_ON(work_pending(&vkms_state->composer_work)); kfree(vkms_state->active_planes); kfree(vkms_state); } @@ -141,7 +141,7 @@ static void vkms_atomic_crtc_reset(struct drm_crtc *crtc) __drm_atomic_helper_crtc_reset(crtc, &vkms_state->base); if (vkms_state) - INIT_WORK(&vkms_state->crc_work, vkms_crc_work_handle); + INIT_WORK(&vkms_state->composer_work, vkms_composer_worker); } static const struct drm_crtc_funcs vkms_crtc_funcs = { @@ -222,7 +222,7 @@ static void vkms_crtc_atomic_begin(struct drm_crtc *crtc, struct vkms_output *vkms_output = drm_crtc_to_vkms_output(crtc); /* This lock is held across the atomic commit to block vblank timer - * from scheduling vkms_crc_work_handle until the crc_data is updated + * from scheduling vkms_composer_worker until the composer is updated */ spin_lock_irq(&vkms_output->lock); } @@ -245,7 +245,7 @@ static void vkms_crtc_atomic_flush(struct drm_crtc *crtc, crtc->state->event = NULL; } - vkms_output->crc_state = to_vkms_crtc_state(crtc->state); + vkms_output->composer_state = to_vkms_crtc_state(crtc->state); spin_unlock_irq(&vkms_output->lock); } @@ -274,10 +274,10 @@ int vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, drm_crtc_helper_add(crtc, &vkms_crtc_helper_funcs); spin_lock_init(&vkms_out->lock); - spin_lock_init(&vkms_out->crc_lock); + spin_lock_init(&vkms_out->composer_lock); - vkms_out->crc_workq = alloc_ordered_workqueue("vkms_crc_workq", 0); - if (!vkms_out->crc_workq) + vkms_out->composer_workq = alloc_ordered_workqueue("vkms_composer", 0); + if (!vkms_out->composer_workq) return -ENOMEM; return ret; diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index 966b3d653189..ac790b6527e4 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -56,7 +56,7 @@ static void vkms_release(struct drm_device *dev) drm_atomic_helper_shutdown(&vkms->drm); drm_mode_config_cleanup(&vkms->drm); drm_dev_fini(&vkms->drm); - destroy_workqueue(vkms->output.crc_workq); + destroy_workqueue(vkms->output.composer_workq); } static void vkms_atomic_commit_tail(struct drm_atomic_state *old_state) @@ -82,7 +82,7 @@ static void vkms_atomic_commit_tail(struct drm_atomic_state *old_state) struct vkms_crtc_state *vkms_state = to_vkms_crtc_state(old_crtc_state); - flush_work(&vkms_state->crc_work); + flush_work(&vkms_state->composer_work); } drm_atomic_helper_cleanup_planes(dev, old_state); diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index e2d1aa089dec..fc6cda164336 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -20,7 +20,7 @@ extern bool enable_cursor; -struct vkms_crc_data { +struct vkms_composer { struct drm_framebuffer fb; struct drm_rect src, dst; unsigned int offset; @@ -31,29 +31,29 @@ struct vkms_crc_data { /** * vkms_plane_state - Driver specific plane state * @base: base plane state - * @crc_data: data required for CRC computation + * @composer: data required for composing computation */ struct vkms_plane_state { struct drm_plane_state base; - struct vkms_crc_data *crc_data; + struct vkms_composer *composer; }; /** * vkms_crtc_state - Driver specific CRTC state * @base: base CRTC state - * @crc_work: work struct to compute and add CRC entries + * @composer_work: work struct to compose and add CRC entries * @n_frame_start: start frame number for computed CRC * @n_frame_end: end frame number for computed CRC */ struct vkms_crtc_state { struct drm_crtc_state base; - struct work_struct crc_work; + struct work_struct composer_work; int num_active_planes; /* stack of active planes for crc computation, should be in z order */ struct vkms_plane_state **active_planes; - /* below three are protected by vkms_output.crc_lock */ + /* below three are protected by vkms_output.composer_lock */ bool crc_pending; u64 frame_start; u64 frame_end; @@ -66,16 +66,16 @@ struct vkms_output { struct hrtimer vblank_hrtimer; ktime_t period_ns; struct drm_pending_vblank_event *event; - /* ordered wq for crc_work */ - struct workqueue_struct *crc_workq; - /* protects concurrent access to crc_data */ + /* ordered wq for composer_work */ + struct workqueue_struct *composer_workq; + /* protects concurrent access to composer */ spinlock_t lock; /* protected by @lock */ - bool crc_enabled; - struct vkms_crtc_state *crc_state; + bool composer_enabled; + struct vkms_crtc_state *composer_state; - spinlock_t crc_lock; + spinlock_t composer_lock; }; struct vkms_device { @@ -143,6 +143,8 @@ const char *const *vkms_get_crc_sources(struct drm_crtc *crtc, int vkms_set_crc_source(struct drm_crtc *crtc, const char *src_name); int vkms_verify_crc_source(struct drm_crtc *crtc, const char *source_name, size_t *values_cnt); -void vkms_crc_work_handle(struct work_struct *work); + +/* Composer Support */ +void vkms_composer_worker(struct work_struct *work); #endif /* _VKMS_DRV_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index 18c630cfc485..8b60d3434d75 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -18,20 +18,20 @@ static struct drm_plane_state * vkms_plane_duplicate_state(struct drm_plane *plane) { struct vkms_plane_state *vkms_state; - struct vkms_crc_data *crc_data; + struct vkms_composer *composer; vkms_state = kzalloc(sizeof(*vkms_state), GFP_KERNEL); if (!vkms_state) return NULL; - crc_data = kzalloc(sizeof(*crc_data), GFP_KERNEL); - if (!crc_data) { - DRM_DEBUG_KMS("Couldn't allocate crc_data\n"); + composer = kzalloc(sizeof(*composer), GFP_KERNEL); + if (!composer) { + DRM_DEBUG_KMS("Couldn't allocate composer\n"); kfree(vkms_state); return NULL; } - vkms_state->crc_data = crc_data; + vkms_state->composer = composer; __drm_atomic_helper_plane_duplicate_state(plane, &vkms_state->base); @@ -49,12 +49,12 @@ static void vkms_plane_destroy_state(struct drm_plane *plane, /* dropping the reference we acquired in * vkms_primary_plane_update() */ - if (drm_framebuffer_read_refcount(&vkms_state->crc_data->fb)) - drm_framebuffer_put(&vkms_state->crc_data->fb); + if (drm_framebuffer_read_refcount(&vkms_state->composer->fb)) + drm_framebuffer_put(&vkms_state->composer->fb); } - kfree(vkms_state->crc_data); - vkms_state->crc_data = NULL; + kfree(vkms_state->composer); + vkms_state->composer = NULL; __drm_atomic_helper_plane_destroy_state(old_state); kfree(vkms_state); @@ -91,21 +91,21 @@ static void vkms_plane_atomic_update(struct drm_plane *plane, { struct vkms_plane_state *vkms_plane_state; struct drm_framebuffer *fb = plane->state->fb; - struct vkms_crc_data *crc_data; + struct vkms_composer *composer; if (!plane->state->crtc || !fb) return; vkms_plane_state = to_vkms_plane_state(plane->state); - crc_data = vkms_plane_state->crc_data; - memcpy(&crc_data->src, &plane->state->src, sizeof(struct drm_rect)); - memcpy(&crc_data->dst, &plane->state->dst, sizeof(struct drm_rect)); - memcpy(&crc_data->fb, fb, sizeof(struct drm_framebuffer)); - drm_framebuffer_get(&crc_data->fb); - crc_data->offset = fb->offsets[0]; - crc_data->pitch = fb->pitches[0]; - crc_data->cpp = fb->format->cpp[0]; + composer = vkms_plane_state->composer; + memcpy(&composer->src, &plane->state->src, sizeof(struct drm_rect)); + memcpy(&composer->dst, &plane->state->dst, sizeof(struct drm_rect)); + memcpy(&composer->fb, fb, sizeof(struct drm_framebuffer)); + drm_framebuffer_get(&composer->fb); + composer->offset = fb->offsets[0]; + composer->pitch = fb->pitches[0]; + composer->cpp = fb->format->cpp[0]; } static int vkms_plane_atomic_check(struct drm_plane *plane, From patchwork Wed Jun 26 01:37:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rodrigo Siqueira X-Patchwork-Id: 11016717 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 9A0CD924 for ; Wed, 26 Jun 2019 01:38:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 893C0271CB for ; Wed, 26 Jun 2019 01:38:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7B9AD285F2; Wed, 26 Jun 2019 01:38:07 +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,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,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 2CB36271CB for ; Wed, 26 Jun 2019 01:38:07 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4EEC06E1D2; Wed, 26 Jun 2019 01:38:06 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-qt1-x841.google.com (mail-qt1-x841.google.com [IPv6:2607:f8b0:4864:20::841]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4BA7E6E1D2 for ; Wed, 26 Jun 2019 01:38:04 +0000 (UTC) Received: by mail-qt1-x841.google.com with SMTP id x47so631451qtk.11 for ; Tue, 25 Jun 2019 18:38:04 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=Dcji4DG1mYdfSzaoYm1b9GBfrTHcBOQ4lNkuX8kgim8=; b=rpIF3Ji7Y0FvmF5CIIdaI3WMS2KFdSmH+CjUcyY3R5phG31m5ULZcrVyY6zbOZ/o26 UXwdnbPbwX0f5SJpgMbLZrvpPyzPOV6ftP1o9zVnee+58srjMsoBEDnbHiqJzEs05BDZ /JFxc/eTVjCGQGjJ56akN5QcpYAj5MfyfJrQr/r4ohHwqtY4B3jopjiim13XTlBIeOSL rk99YCeD8tL7NLV3YkJB1YxHLdKtIJcUryb3hvd2zhqaMvAd7mV7ScFGd8JFtZWnIgUA lWDciUnzanrsLG+JnlQZPXH08xfyyj/SqEC8/oygdbPcvqqJuPWtRY7zxrgpujnJectM 1fcg== X-Gm-Message-State: APjAAAWqBKo+cUGY8nwGAg20PF3OlelgyYtEj5rJwTYBb6+8WQ0YH1OD ql+zjV2qe+ZoQScilJMX0DA= X-Google-Smtp-Source: APXvYqwJv4ZMACGc1XJpqCZdYEetDgEmL+h2ns1p1TA6Wm0McZDXDfxD+AdQ2jcvbnMU6UqRAJyk/w== X-Received: by 2002:aed:3747:: with SMTP id i65mr1413779qtb.166.1561513083429; Tue, 25 Jun 2019 18:38:03 -0700 (PDT) Received: from smtp.gmail.com ([187.121.151.146]) by smtp.gmail.com with ESMTPSA id e18sm7441097qkm.49.2019.06.25.18.37.59 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Tue, 25 Jun 2019 18:38:03 -0700 (PDT) Date: Tue, 25 Jun 2019 22:37:58 -0300 From: Rodrigo Siqueira To: Brian Starkey , Liviu Dudau , Daniel Vetter , Haneen Mohammed , Simon Ser Subject: [PATCH V3 3/5] drm/vkms: Decouple crc operations from composer Message-ID: <6e8a03dc7c666ee998ee36172a96cff39f8dd46d.1561491964.git.rodrigosiqueiramelo@gmail.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: NeoMutt/20180716 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=Dcji4DG1mYdfSzaoYm1b9GBfrTHcBOQ4lNkuX8kgim8=; b=QYqgls57UiwrwknJ+w6IfGJFDRY1zpL306MGaJVEbcPuLpkedTVidtXe12U7J8ObsL wbnA98tWBTOmbjCY4W6urdJT+XoYAkh1CMcVlx23yB2q185Up7fYoNTmG8kzB+1/RXnu 1kS6yqT8hEIPPbhn6lbU7EFU1vfucpe3BpG1N0TGYR7rFzGl4nRcDpEGHVtzhuU0BUiV AiNtow8FBlAob7PeSyxcmPQ0fiE5FrR5FI86blq5dGPvL6wPw/dXpnyy0tFYD+hzrr+U BLE7As7vn5cIA+q4uxelG6GUVjGeEi4yJ6O1WqKcvlmAcbmG+pE4gulRp6NQ1AezulbF PRBA== 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: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP In the vkms_composer.c, some of the functions related to CRC and compose have interdependence between each other. This patch reworks some functions inside vkms_composer to make crc and composer computation decoupled. This patch is preparation work for making vkms able to support new features. Signed-off-by: Rodrigo Siqueira --- drivers/gpu/drm/vkms/vkms_composer.c | 49 ++++++++++++++++------------ 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index eb7ea8be1f98..51a270514219 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -105,35 +105,31 @@ static void compose_cursor(struct vkms_composer *cursor_composer, primary_composer, cursor_composer); } -static uint32_t _vkms_get_crc(struct vkms_composer *primary_composer, - struct vkms_composer *cursor_composer) +static int compose_planes(void **vaddr_out, + struct vkms_composer *primary_composer, + struct vkms_composer *cursor_composer) { struct drm_framebuffer *fb = &primary_composer->fb; struct drm_gem_object *gem_obj = drm_gem_fb_get_obj(fb, 0); struct vkms_gem_object *vkms_obj = drm_gem_to_vkms_gem(gem_obj); - void *vaddr_out = kzalloc(vkms_obj->gem.size, GFP_KERNEL); - u32 crc = 0; - if (!vaddr_out) { - DRM_ERROR("Failed to allocate memory for output frame."); - return 0; + if (!*vaddr_out) { + *vaddr_out = kzalloc(vkms_obj->gem.size, GFP_KERNEL); + if (!*vaddr_out) { + DRM_ERROR("Cannot allocate memory for output frame."); + return -ENOMEM; + } } - if (WARN_ON(!vkms_obj->vaddr)) { - kfree(vaddr_out); - return crc; - } + if (WARN_ON(!vkms_obj->vaddr)) + return -EINVAL; - memcpy(vaddr_out, vkms_obj->vaddr, vkms_obj->gem.size); + memcpy(*vaddr_out, vkms_obj->vaddr, vkms_obj->gem.size); if (cursor_composer) - compose_cursor(cursor_composer, primary_composer, vaddr_out); + compose_cursor(cursor_composer, primary_composer, *vaddr_out); - crc = compute_crc(vaddr_out, primary_composer); - - kfree(vaddr_out); - - return crc; + return 0; } /** @@ -154,9 +150,11 @@ void vkms_composer_worker(struct work_struct *work) struct vkms_output *out = drm_crtc_to_vkms_output(crtc); struct vkms_composer *primary_composer = NULL; struct vkms_composer *cursor_composer = NULL; + void *vaddr_out = NULL; u32 crc32 = 0; u64 frame_start, frame_end; bool crc_pending; + int ret; spin_lock_irq(&out->composer_lock); frame_start = crtc_state->frame_start; @@ -180,14 +178,25 @@ void vkms_composer_worker(struct work_struct *work) if (crtc_state->num_active_planes == 2) cursor_composer = crtc_state->active_planes[1]->composer; - if (primary_composer) - crc32 = _vkms_get_crc(primary_composer, cursor_composer); + if (!primary_composer) + return; + + ret = compose_planes(&vaddr_out, primary_composer, cursor_composer); + if (ret) { + if (ret == -EINVAL) + kfree(vaddr_out); + return; + } + + crc32 = compute_crc(vaddr_out, primary_composer); /* * The worker can fall behind the vblank hrtimer, make sure we catch up. */ while (frame_start <= frame_end) drm_crtc_add_crc_entry(crtc, true, frame_start++, &crc32); + + kfree(vaddr_out); } static const char * const pipe_crc_sources[] = {"auto"}; From patchwork Wed Jun 26 01:38:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rodrigo Siqueira X-Patchwork-Id: 11016719 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 DE2DE924 for ; Wed, 26 Jun 2019 01:38:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CA582271CB for ; Wed, 26 Jun 2019 01:38:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BAABB285F2; Wed, 26 Jun 2019 01:38:39 +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,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,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 6EF3B271CB for ; Wed, 26 Jun 2019 01:38:39 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8701A6E1D3; Wed, 26 Jun 2019 01:38:38 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-qk1-x744.google.com (mail-qk1-x744.google.com [IPv6:2607:f8b0:4864:20::744]) by gabe.freedesktop.org (Postfix) with ESMTPS id 206FC6E1D3 for ; Wed, 26 Jun 2019 01:38:37 +0000 (UTC) Received: by mail-qk1-x744.google.com with SMTP id i125so346924qkd.6 for ; Tue, 25 Jun 2019 18:38:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=VhvsA2mFJL5Xe5+RHkMF0VDR29nwFdCWp8jzkz78NKs=; b=JuEY+K+Q7LNXdcwF6pFIDekSRRucFs+z/FnytpMhGK59dGIdcaianMYbAbJjN5LILh gfLqZYVdxuaEMJeqiwlOkufhabGgsUM8CeLVMauzLramsxfiExbIGcPlwRD92YjxVRrN FpQ3fMnDNteGPEcjQkMLmEMBoRWatnOM5CeVjAFfX0ASC+1zCb0kh3AtuLKpSSRQd7Fx +LQMKnTdbSmwpjU4MZ5Yq1/MPEBHuqXSp9alTA7XS/0T2CE293K0H/EcEiijoduEf8BF BJnvLuK66TfOkihu6cm/V7W7ytlWOV7QOpdE8p5k03F1So1E3UTFD+XZbOi6bWNwpRXx FUMA== X-Gm-Message-State: APjAAAX7PYi6IFMgKB1lHcSP6xhdXo1WkX0OqbK1onmwBBTTpPhsFNKT dRaMl0NmLDpMML+7UgPptaI= X-Google-Smtp-Source: APXvYqxZZf0LF7ILRzNdTHyeclwzLjQ3OWXOXs+v+XxDfPqPWC8/3w4blmvuCJH391wQzNWiyx780A== X-Received: by 2002:a37:668c:: with SMTP id a134mr1564017qkc.477.1561513116203; Tue, 25 Jun 2019 18:38:36 -0700 (PDT) Received: from smtp.gmail.com ([187.121.151.146]) by smtp.gmail.com with ESMTPSA id h40sm9967150qth.4.2019.06.25.18.38.33 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Tue, 25 Jun 2019 18:38:35 -0700 (PDT) Date: Tue, 25 Jun 2019 22:38:31 -0300 From: Rodrigo Siqueira To: Brian Starkey , Liviu Dudau , Daniel Vetter , Haneen Mohammed , Simon Ser Subject: [PATCH V3 4/5] drm/vkms: Compute CRC without change input data Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: NeoMutt/20180716 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=VhvsA2mFJL5Xe5+RHkMF0VDR29nwFdCWp8jzkz78NKs=; b=rwstq9SV12XPNESW3bHDHzxMr1EbE9kLJvo0w/fufz8IIyTZmnFvZ5I0iflsdlXn1M EZ356wSG1KOO40stlTjAjI/D9Wm64ctkumXNZZIrSFfuyMpm68Xxn1/xGSpDuSxCfvyp nM81CeAOeXw3tiT6smx1EVrBpt08DuAqPWQyWS8yHQ7ZQrtZra7c+V5YSuk+Bm2da2O+ 8myyuA5/z5qJY4aB4EGlNih5NEihjgGWqddNIcPNnao0NReUTUpy8cLiiPq5DPM3haCa HpvJ6m7EtIhDXO9/mE+WUCaTmP/pWcHeGIStjWNU1VBab7O5vZ5c1WDOqx5g8OZ/fX+F 40Jg== 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: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP The compute_crc() function is responsible for calculating the framebuffer CRC value; due to the XRGB format, this function has to ignore the alpha channel during the CRC computation. Therefore, compute_crc() set zero to the alpha channel directly in the input framebuffer, which is not a problem since this function receives a copy of the original buffer. However, if we want to use this function in a context without a buffer copy, it will change the initial value. This patch makes compute_crc() calculate the CRC value without modifying the input framebuffer. Signed-off-by: Rodrigo Siqueira --- drivers/gpu/drm/vkms/vkms_composer.c | 31 +++++++++++++++++----------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index 51a270514219..8126aa0f968f 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -6,33 +6,40 @@ #include #include +static u32 get_pixel_from_buffer(int x, int y, const u8 *buffer, + const struct vkms_composer *composer) +{ + int src_offset = composer->offset + (y * composer->pitch) + + (x * composer->cpp); + + return *(u32 *)&buffer[src_offset]; +} + /** * compute_crc - Compute CRC value on output frame * - * @vaddr_out: address to final framebuffer + * @vaddr: address to final framebuffer * @composer: framebuffer's metadata * * returns CRC value computed using crc32 on the visible portion of * the final framebuffer at vaddr_out */ -static uint32_t compute_crc(void *vaddr_out, struct vkms_composer *composer) +static uint32_t compute_crc(const u8 *vaddr, + const struct vkms_composer *composer) { - int i, j, src_offset; + int x, y; int x_src = composer->src.x1 >> 16; int y_src = composer->src.y1 >> 16; int h_src = drm_rect_height(&composer->src) >> 16; int w_src = drm_rect_width(&composer->src) >> 16; - u32 crc = 0; + u32 crc = 0, pixel = 0; - for (i = y_src; i < y_src + h_src; ++i) { - for (j = x_src; j < x_src + w_src; ++j) { - src_offset = composer->offset - + (i * composer->pitch) - + (j * composer->cpp); + for (y = y_src; y < y_src + h_src; ++y) { + for (x = x_src; x < x_src + w_src; ++x) { /* XRGB format ignores Alpha channel */ - memset(vaddr_out + src_offset + 24, 0, 8); - crc = crc32_le(crc, vaddr_out + src_offset, - sizeof(u32)); + pixel = get_pixel_from_buffer(x, y, vaddr, composer); + bitmap_clear((void *)&pixel, 0, 8); + crc = crc32_le(crc, (void *)&pixel, sizeof(u32)); } } From patchwork Wed Jun 26 01:39:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rodrigo Siqueira X-Patchwork-Id: 11016721 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 12CC9924 for ; Wed, 26 Jun 2019 01:39:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F1C79271CB for ; Wed, 26 Jun 2019 01:39:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E41BF285F2; Wed, 26 Jun 2019 01:39:11 +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,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,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 3A36E271CB for ; Wed, 26 Jun 2019 01:39:11 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8D6736E1D6; Wed, 26 Jun 2019 01:39:10 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-qk1-x743.google.com (mail-qk1-x743.google.com [IPv6:2607:f8b0:4864:20::743]) by gabe.freedesktop.org (Postfix) with ESMTPS id 769956E1D6 for ; Wed, 26 Jun 2019 01:39:08 +0000 (UTC) Received: by mail-qk1-x743.google.com with SMTP id d15so356015qkl.4 for ; Tue, 25 Jun 2019 18:39:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=+TXqSwTZjDGWj2L4S+KWzT9OrVj0CDUBdtM8IFJVBGA=; b=MbUkJ02ZyFN67Bq3VP7949cLh1E8kxHMNJ+XWDvNozCBC+3Zu5AL9q/ov8iOCyIzLo MVAr2A2I67Nv2/j/yFXeBtiF56wZshyf4Dx2BtnZmuKIuSJL3wG0f9a1GEHeMmyjB9j4 oRp2UxVu3nJMXfOObcdJTn7r5PTUOEFN1VHq4kf2kl9fahhUk/4f+W6vyY+KEsME01oS 5zk3HbsK2KR6XmE/1+61vHXmPsJFHkSTiwXp37C+LEoM4OVcqXU+ABkfhEHvxVWvLzCl j3ImRL9ADsbnosKckaEOH7oPGt5vxOJwKZvUxC+S+8VrNCIRjvha3mMrGko+z8akuQrf VqLw== X-Gm-Message-State: APjAAAVohQ4dT/UD/ZJu+R602Cv3j7+xHTHunUGz4fEo8HsBwfr8pXP5 AELNWxpcKluTzRqHg9u18Oc= X-Google-Smtp-Source: APXvYqyDm2BNTI3hkynfdVEW0uNDWRhaj/k3V+V3hMvZHuUvQvsEyv0xpzQ4c2GCjDSMKsAURE7XJA== X-Received: by 2002:a05:620a:624:: with SMTP id 4mr1470510qkv.15.1561513147526; Tue, 25 Jun 2019 18:39:07 -0700 (PDT) Received: from smtp.gmail.com ([187.121.151.146]) by smtp.gmail.com with ESMTPSA id q29sm8219747qkq.77.2019.06.25.18.39.04 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Tue, 25 Jun 2019 18:39:07 -0700 (PDT) Date: Tue, 25 Jun 2019 22:39:03 -0300 From: Rodrigo Siqueira To: Brian Starkey , Liviu Dudau , Daniel Vetter , Haneen Mohammed , Simon Ser Subject: [PATCH V3 5/5] drm/vkms: Add support for writeback Message-ID: <917fda9b620cd84a0826d2d5a59bff9ea07bfde2.1561491964.git.rodrigosiqueiramelo@gmail.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: NeoMutt/20180716 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=+TXqSwTZjDGWj2L4S+KWzT9OrVj0CDUBdtM8IFJVBGA=; b=ervszTLUC9g6PMkHh8xFdbXLwqy2ptpocTo5YeYt7pVLR20sibEuff45n1pnTXuW3D vN6A5y05aPfQ6lDOMxGnPVSncqduSje1eBfEjligVaL64TqIPlgCC8scG9v7lVXQx/6n FA30vHpln56hKSmoCAevu372laHXG40EzMEVP4/4gsHce62dR29poZ0da+dY39dMQQET yawTCqi9v10NrFqsLpVDqg4TUvoPNd1GM7CPa9ffhLCF5G37F2Az93mo6aGvPAaFhSl2 iaySm6RVe9bJ+V7uC00uya9turvVA0ngBh4FXgSyvPlH9fqpjcGCefoh1nIkH7KmwX// r3fA== 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: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch implements the necessary functions to add writeback support for vkms. This feature is useful for testing compositors if you don't have hardware with writeback support. Change in V3 (Daniel): - If writeback is enabled, compose everything into the writeback buffer instead of CRC private buffer. - Guarantees that the CRC will match exactly what we have in the writeback buffer. Change in V2: - Rework signal completion (Brian) - Integrates writeback with active_planes (Daniel) - Compose cursor (Daniel) Signed-off-by: Rodrigo Siqueira --- drivers/gpu/drm/vkms/Makefile | 9 +- drivers/gpu/drm/vkms/vkms_composer.c | 16 ++- drivers/gpu/drm/vkms/vkms_drv.c | 4 + drivers/gpu/drm/vkms/vkms_drv.h | 8 ++ drivers/gpu/drm/vkms/vkms_output.c | 10 ++ drivers/gpu/drm/vkms/vkms_writeback.c | 141 ++++++++++++++++++++++++++ 6 files changed, 185 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/vkms/vkms_writeback.c diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile index 0b767d7efa24..333d3cead0e3 100644 --- a/drivers/gpu/drm/vkms/Makefile +++ b/drivers/gpu/drm/vkms/Makefile @@ -1,4 +1,11 @@ # SPDX-License-Identifier: GPL-2.0-only -vkms-y := vkms_drv.o vkms_plane.o vkms_output.o vkms_crtc.o vkms_gem.o vkms_composer.o +vkms-y := \ + vkms_drv.o \ + vkms_plane.o \ + vkms_output.o \ + vkms_crtc.o \ + vkms_gem.o \ + vkms_composer.o \ + vkms_writeback.o obj-$(CONFIG_DRM_VKMS) += vkms.o diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index 8126aa0f968f..2317803e7320 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -157,16 +157,17 @@ void vkms_composer_worker(struct work_struct *work) struct vkms_output *out = drm_crtc_to_vkms_output(crtc); struct vkms_composer *primary_composer = NULL; struct vkms_composer *cursor_composer = NULL; + bool crc_pending, wb_pending; void *vaddr_out = NULL; u32 crc32 = 0; u64 frame_start, frame_end; - bool crc_pending; int ret; spin_lock_irq(&out->composer_lock); frame_start = crtc_state->frame_start; frame_end = crtc_state->frame_end; crc_pending = crtc_state->crc_pending; + wb_pending = crtc_state->wb_pending; crtc_state->frame_start = 0; crtc_state->frame_end = 0; crtc_state->crc_pending = false; @@ -188,9 +189,12 @@ void vkms_composer_worker(struct work_struct *work) if (!primary_composer) return; + if (wb_pending) + vaddr_out = crtc_state->active_writeback; + ret = compose_planes(&vaddr_out, primary_composer, cursor_composer); if (ret) { - if (ret == -EINVAL) + if (ret == -EINVAL && !wb_pending) kfree(vaddr_out); return; } @@ -203,6 +207,14 @@ void vkms_composer_worker(struct work_struct *work) while (frame_start <= frame_end) drm_crtc_add_crc_entry(crtc, true, frame_start++, &crc32); + if (wb_pending) { + drm_writeback_signal_completion(&out->wb_connector, 0); + spin_lock_irq(&out->composer_lock); + crtc_state->wb_pending = false; + spin_unlock_irq(&out->composer_lock); + return; + } + kfree(vaddr_out); } diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index ac790b6527e4..152d7de24a76 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -30,6 +30,10 @@ bool enable_cursor; module_param_named(enable_cursor, enable_cursor, bool, 0444); MODULE_PARM_DESC(enable_cursor, "Enable/Disable cursor support"); +bool enable_writeback; +module_param_named(enable_writeback, enable_writeback, bool, 0444); +MODULE_PARM_DESC(enable_writeback, "Enable/Disable writeback connector"); + static const struct file_operations vkms_driver_fops = { .owner = THIS_MODULE, .open = drm_open, diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index fc6cda164336..9ff2cd4ebf81 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #define XRES_MIN 20 @@ -19,6 +20,7 @@ #define YRES_MAX 8192 extern bool enable_cursor; +extern bool enable_writeback; struct vkms_composer { struct drm_framebuffer fb; @@ -52,9 +54,11 @@ struct vkms_crtc_state { int num_active_planes; /* stack of active planes for crc computation, should be in z order */ struct vkms_plane_state **active_planes; + void *active_writeback; /* below three are protected by vkms_output.composer_lock */ bool crc_pending; + bool wb_pending; u64 frame_start; u64 frame_end; }; @@ -63,6 +67,7 @@ struct vkms_output { struct drm_crtc crtc; struct drm_encoder encoder; struct drm_connector connector; + struct drm_writeback_connector wb_connector; struct hrtimer vblank_hrtimer; ktime_t period_ns; struct drm_pending_vblank_event *event; @@ -147,4 +152,7 @@ int vkms_verify_crc_source(struct drm_crtc *crtc, const char *source_name, /* Composer Support */ void vkms_composer_worker(struct work_struct *work); +/* Writeback */ +int enable_writeback_connector(struct vkms_device *vkmsdev); + #endif /* _VKMS_DRV_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c index fb1941a6522c..aea1d4410864 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -84,6 +84,16 @@ int vkms_output_init(struct vkms_device *vkmsdev, int index) goto err_attach; } + if (enable_writeback) { + ret = enable_writeback_connector(vkmsdev); + if (!ret) { + output->composer_enabled = true; + DRM_INFO("Writeback connector enabled"); + } else { + DRM_ERROR("Failed to init writeback connector\n"); + } + } + drm_mode_config_reset(dev); return 0; diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c b/drivers/gpu/drm/vkms/vkms_writeback.c new file mode 100644 index 000000000000..34dad37a0236 --- /dev/null +++ b/drivers/gpu/drm/vkms/vkms_writeback.c @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include "vkms_drv.h" +#include +#include +#include +#include + +static const u32 vkms_wb_formats[] = { + DRM_FORMAT_XRGB8888, +}; + +static const struct drm_connector_funcs vkms_wb_connector_funcs = { + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = drm_connector_cleanup, + .reset = drm_atomic_helper_connector_reset, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static int vkms_wb_encoder_atomic_check(struct drm_encoder *encoder, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + struct drm_framebuffer *fb; + const struct drm_display_mode *mode = &crtc_state->mode; + + if (!conn_state->writeback_job || !conn_state->writeback_job->fb) + return 0; + + fb = conn_state->writeback_job->fb; + if (fb->width != mode->hdisplay || fb->height != mode->vdisplay) { + DRM_DEBUG_KMS("Invalid framebuffer size %ux%u\n", + fb->width, fb->height); + return -EINVAL; + } + + if (fb->format->format != DRM_FORMAT_XRGB8888) { + struct drm_format_name_buf format_name; + + DRM_DEBUG_KMS("Invalid pixel format %s\n", + drm_get_format_name(fb->format->format, + &format_name)); + return -EINVAL; + } + + return 0; +} + +static const struct drm_encoder_helper_funcs vkms_wb_encoder_helper_funcs = { + .atomic_check = vkms_wb_encoder_atomic_check, +}; + +static int vkms_wb_connector_get_modes(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + + return drm_add_modes_noedid(connector, dev->mode_config.max_width, + dev->mode_config.max_height); +} + +static int vkms_wb_prepare_job(struct drm_writeback_connector *wb_connector, + struct drm_writeback_job *job) +{ + struct vkms_gem_object *vkms_obj; + struct drm_gem_object *gem_obj; + int ret; + + if (!job->fb) + return 0; + + gem_obj = drm_gem_fb_get_obj(job->fb, 0); + ret = vkms_gem_vmap(gem_obj); + if (ret) { + DRM_ERROR("vmap failed: %d\n", ret); + return ret; + } + + vkms_obj = drm_gem_to_vkms_gem(gem_obj); + job->priv = vkms_obj->vaddr; + + return 0; +} + +static void vkms_wb_cleanup_job(struct drm_writeback_connector *connector, + struct drm_writeback_job *job) +{ + struct drm_gem_object *gem_obj; + + if (!job->fb) + return; + + gem_obj = drm_gem_fb_get_obj(job->fb, 0); + vkms_gem_vunmap(gem_obj); +} + +static void vkms_wb_atomic_commit(struct drm_connector *conn, + struct drm_connector_state *state) +{ + struct vkms_device *vkmsdev = drm_device_to_vkms_device(conn->dev); + struct vkms_output *output = &vkmsdev->output; + struct drm_writeback_connector *wb_conn = &output->wb_connector; + struct drm_connector_state *conn_state = wb_conn->base.state; + struct vkms_crtc_state *crtc_state = output->composer_state; + + if (!conn_state) + return; + + if (!conn_state->writeback_job || !conn_state->writeback_job->fb) { + DRM_DEBUG_DRIVER("Disable writeback\n"); + return; + } + + spin_lock_irq(&output->composer_lock); + crtc_state->active_writeback = conn_state->writeback_job->priv; + crtc_state->wb_pending = true; + spin_unlock_irq(&output->composer_lock); + drm_writeback_queue_job(wb_conn, state); +} + +static const struct drm_connector_helper_funcs vkms_wb_conn_helper_funcs = { + .get_modes = vkms_wb_connector_get_modes, + .prepare_writeback_job = vkms_wb_prepare_job, + .cleanup_writeback_job = vkms_wb_cleanup_job, + .atomic_commit = vkms_wb_atomic_commit, +}; + +int enable_writeback_connector(struct vkms_device *vkmsdev) +{ + struct drm_writeback_connector *wb = &vkmsdev->output.wb_connector; + + vkmsdev->output.wb_connector.encoder.possible_crtcs = 1; + drm_connector_helper_add(&wb->base, &vkms_wb_conn_helper_funcs); + + return drm_writeback_connector_init(&vkmsdev->drm, wb, + &vkms_wb_connector_funcs, + &vkms_wb_encoder_helper_funcs, + vkms_wb_formats, + ARRAY_SIZE(vkms_wb_formats)); +} +