From patchwork Wed Apr 3 19:35:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Rodrigo Siqueira X-Patchwork-Id: 10884413 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 A71111390 for ; Wed, 3 Apr 2019 19:35:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 84480288A7 for ; Wed, 3 Apr 2019 19:35:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 73586289E0; Wed, 3 Apr 2019 19:35:21 +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 49DAA288A7 for ; Wed, 3 Apr 2019 19:35:20 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2F7B46E41D; Wed, 3 Apr 2019 19:35:18 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-qt1-x842.google.com (mail-qt1-x842.google.com [IPv6:2607:f8b0:4864:20::842]) by gabe.freedesktop.org (Postfix) with ESMTPS id 360906E41D for ; Wed, 3 Apr 2019 19:35:16 +0000 (UTC) Received: by mail-qt1-x842.google.com with SMTP id w30so393441qta.8 for ; Wed, 03 Apr 2019 12:35:16 -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:mime-version :content-disposition:user-agent; bh=pisV2cnnair7KN82bnY5h6+nuIIOWiEKU5RPVnaehUE=; b=oXNFmcc0U3Sm6HRoTr5/fOa00wieeegnZECJ9ORjFfNDQWFQdJuINQrhq6k6qAu1gF /PHmoaVXoZkmGb3L4Q50bqrF0X/l4Kpkm/U2LOUJxeyhQ4qu0Ds6c30F1oLVDIZ+KCzk QzN39XdMS9j5fAxaCRepGqRXcUjW6SHTPG4un/gA4jD+WT/J2FHXbQs9mPFviWeM2lyi oyENDhKCCrcueLB6gMBGFvdeYjmtw7fKtKsVfmHlY8HjK3D2W2Q8U1yW2PJrnZTPuARD 4dUgcSRrXVWSZzKXkyZ24hSwgm4gkAamhGYi1FS5l44y+O+GDfD2uV+scBrcetkr7yyZ Qq8w== X-Gm-Message-State: APjAAAUdvM+2AYvLChldiMkZ6l2M1qoW08B6xf46mOvX6GJoW2IAPJ3H ziXg0WgCywjUZ4XbYiYUglY= X-Google-Smtp-Source: APXvYqyvDdN6GsE+/cHo+43YVDsPq4KlM2hDzhnKacONIUvAlmhod5ZEhG+SP6MDXp5qdvram7/wkA== X-Received: by 2002:a0c:d685:: with SMTP id k5mr1238277qvi.15.1554320115085; Wed, 03 Apr 2019 12:35:15 -0700 (PDT) Received: from smtp.gmail.com ([143.107.45.1]) by smtp.gmail.com with ESMTPSA id q51sm11030573qtc.38.2019.04.03.12.35.13 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Wed, 03 Apr 2019 12:35:14 -0700 (PDT) Date: Wed, 3 Apr 2019 16:35:11 -0300 From: Rodrigo Siqueira To: Brian Starkey , Liviu Dudau , Daniel Vetter Subject: Assistance with a problem related to GEM and Atomic Commit inside vkms Message-ID: <20190403193511.4waspuspncu7xrn7@smtp.gmail.com> MIME-Version: 1.0 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:mime-version:content-disposition :user-agent; bh=pisV2cnnair7KN82bnY5h6+nuIIOWiEKU5RPVnaehUE=; b=fCUpcyhPIWzs+2IvFysOHRLyW8+mJAoARP71kvMgZvE21cDK/rgaU84AGvC5qvVov5 4b+15GFk2BBEomqMK8fPcxVAm522HO0z5jOpy9o6BpQU9DZCFpzDCZzMhXI7cS6XP/eF IIhWwhmNBetOzAHjDiN8EsN9h5IPutxpPdHLfNGrV6NeTZkkHe/tpWPlPVib9y8LqVlB b40AL36D3Tg/zFP1npAXI9vLoNzY/+46nuXx3XfuP0O+0SZzhnYARaty8DyvyAc4TPhh 7BRjLS8ILLh0/7L6EVKal6r1AneifR11tgBTes2J5vaMVqPGjb/u2J6lL1zfIdoyEtv6 LpAg== 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: dri-devel@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Hi, I’m working to add writeback support to vkms; you can see my current patch at the end of this email (some prints highlight the issue that I’m asking for help here). I’m using the Liviu Dudau and Brian Starkey IGT patchset, which can be seen here: https://patchwork.freedesktop.org/series/39229/. I’m stuck with a problem that happens in my vkms_wb_atomic_commit() function, which is a helper function at drm_connector_helper_funcs. You can see the full implementation of this function at the end of this email, but here is the important part: struct drm_framebuffer *fb = conn_state->writeback_job->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); A few lines after this variable initialization, I try to make a memory copy like this: memcpy(vkms_conn->writeback_vaddr, vkms_obj->vaddr, vkms_obj->gem.size); If I test my implementation with the subtest writeback-fb-id, everything work as expected; for extra details, this is the dmesg output after this test and with a debug print: => writeback-fb-id [Apr 3 11:30] CIFS: Attempting to mount //10.0.2.4/qemu [ +1.601900] Console: switching to colour dummy device 80x25 [ +0.000017] [IGT] kms_writeback: executing [ +0.032532] [IGT] kms_writeback: starting subtest writeback-fb-id [ +0.001932] VKMS_OBJ (1): Buff (1) - Vaddr (1) - Size = 1228800 - count = 1 [ +0.050524] [IGT] kms_writeback: exiting, ret=0 [ +0.005202] Console: switching to colour frame buffer device 100x37 In the above log, you can see the print info; notice that Vaddr is the output of vkms_obj->vaddr (Vaddr -> vkms_obj->vaddr != NULL). On the other hand, if I try the subtest writeback-check-output, something weird happens in this function. Here is the dmesg output for this test: => writeback-check-output [ +29.911185] Console: switching to colour dummy device 80x25 [ +0.000017] [IGT] kms_writeback: executing [ +0.021289] [IGT] kms_writeback: starting subtest writeback-check-output [ +0.016270] VKMS_OBJ (1): Buff (1) - Vaddr (0) - Size = 1228800 - count = 0 [ +0.000005] BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 [ +0.000004] #PF error: [normal kernel read fault] [ +0.000001] PGD 0 P4D 0 [ +0.000003] Oops: 0000 [#1] PREEMPT SMP PTI [ +0.000002] CPU: 3 PID: 426 Comm: kms_writeback Not tainted 5.0.0-VKMS-RULES+ #102 [ +0.000002] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-20181126_142135-anatol 04/01/2014 [ +0.000021] RIP: 0010:__memcpy+0x12/0x20 [ +0.000002] Code: ff 0f 31 48 c1 e2 20 48 09 c2 48 31 d3 e9 79 ff ff ff 90 90 90 90 90 90 0f 1f 44 00 00 48 89 f8 48 89 d1 48 c1 e9 03 83 e2 07 48 a5 89 d1 f3 a4 c3 66 0f 1f 44 00 00 48 89 f8 48 89 d1 f3 a4 [ +0.000001] RSP: 0018:ffffadaf0098fbd8 EFLAGS: 00010246 [ +0.000002] RAX: ffff9f1bf5400000 RBX: ffff9f1bfa28df00 RCX: 0000000000025800 [ +0.000001] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff9f1bf5400000 [ +0.000001] RBP: 0000000000000001 R08: 00000017818788be R09: ffffadaf0098fb60 [ +0.000001] R10: ffff9f1bfffdc998 R11: ffffffffa25ec401 R12: ffff9f1b777ff430 [ +0.000001] R13: ffffffffc06558b8 R14: ffffffffc06853c0 R15: ffffffffc0685520 [ +0.000002] FS: 00007f2862deae80(0000) GS:ffff9f1bfc980000(0000) knlGS:0000000000000000 [ +0.000001] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ +0.000001] CR2: 0000000000000000 CR3: 00000000baf6c000 CR4: 00000000000006e0 [ +0.000004] Call Trace: [ +0.000023] drm_atomic_helper_commit_modeset_enables+0x15d/0x1e0 [drm_kms_helper] [ +0.000028] drm_atomic_helper_commit_tail+0x31/0x60 [drm_kms_helper] [ +0.000008] commit_tail+0x58/0x70 [drm_kms_helper] [ +0.000008] drm_atomic_helper_commit+0x103/0x110 [drm_kms_helper] [ +0.000040] drm_mode_atomic_ioctl+0x829/0x950 [drm] [ +0.000012] ? drm_atomic_set_property+0x960/0x960 [drm] [ +0.000029] drm_ioctl_kernel+0xb2/0xf0 [drm] [ +0.000011] drm_ioctl+0x25f/0x3f0 [drm] [ +0.000009] ? drm_atomic_set_property+0x960/0x960 [drm] [ +0.000004] ? n_tty_open+0xa0/0xa0 [ +0.000004] do_vfs_ioctl+0xa4/0x630 [ +0.000003] ksys_ioctl+0x60/0x90 [ +0.000003] ? ksys_write+0x4f/0xb0 [ +0.000002] __x64_sys_ioctl+0x16/0x20 [ +0.000003] do_syscall_64+0x5b/0x170 [ +0.000003] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ +0.000002] RIP: 0033:0x7f286677580b [ +0.000001] Code: 0f 1e fa 48 8b 05 55 b6 0c 00 64 c7 00 26 00 00 00 48 c7 c0 ff Notice that Vaddr became NULL for some reason that I cannot understand. From the userspace perspective it looks like that drmModeAtomicCommit() is the entry point for this problem. I tried to debug many things related to GEM and atomic commit, and the only thing that is worth to highlight here is the fact that vkms_gem_fault() function is invoked 1500 times when the test writeback-check-output is executed. After many attempts to try to find out the root of the problem, I’m out of ideas. In this sense, I would like to know if anyone can help by shedding some light on any issues I'm missing or by pointing at any other direction. Best Regards Rodrigo Siqueira --- drivers/gpu/drm/vkms/vkms_crtc.c | 5 + drivers/gpu/drm/vkms/vkms_drv.c | 8 ++ drivers/gpu/drm/vkms/vkms_drv.h | 27 ++++++ drivers/gpu/drm/vkms/vkms_gem.c | 2 +- drivers/gpu/drm/vkms/vkms_output.c | 145 ++++++++++++++++++++++++++++- drivers/gpu/drm/vkms/vkms_plane.c | 2 +- 6 files changed, 184 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index 8a9aeb0a9ea8..e54265a1c67d 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -19,6 +19,11 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer) if (!ret) DRM_ERROR("vkms failure on handling vblank"); + if (output->wb_state == MW_ONESHOT) { + drm_writeback_signal_completion(&output->wb_connector, 0); + output->wb_state = MW_STOP; + } + if (state && output->crc_enabled) { u64 frame = drm_crtc_accurate_vblank_count(crtc); diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index 738dd6206d85..e0d7f94e3972 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -29,6 +29,10 @@ bool enable_cursor; module_param_named(enable_cursor, enable_cursor, bool, 0444); MODULE_PARM_DESC(enable_cursor, "Enable/Disable cursor support"); +int enable_writeback; +module_param_named(enable_writeback, enable_writeback, int, 0444); +MODULE_PARM_DESC(enable_writeback, "Enable/Disable writeback connector"); + static const struct file_operations vkms_driver_fops = { .owner = THIS_MODULE, .open = drm_open, @@ -123,6 +127,10 @@ static int __init vkms_init(void) goto out_fini; } + vkms_device->output.writeback_enabled = enable_writeback; + if (enable_writeback) + DRM_INFO("Writeback connector enabled"); + ret = vkms_modeset_init(vkms_device); if (ret) goto out_fini; diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index 81f1cfbeb936..d11dcf6b5d55 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -8,6 +8,7 @@ #include #include #include +#include #define XRES_MIN 20 #define YRES_MIN 20 @@ -20,6 +21,11 @@ extern bool enable_cursor; +enum { + MW_STOP = 0, + MW_ONESHOT, +}; + static const u32 vkms_formats[] = { DRM_FORMAT_XRGB8888, }; @@ -46,6 +52,16 @@ struct vkms_plane_state { struct vkms_crc_data *crc_data; }; +/** + * vkms_connector_state - Driver connector specific state + * @base: base connector state + * @writeback_vaddr: keep track for writeback framebuffer destination + */ +struct vkms_connector_state { + struct drm_connector_state base; + void *writeback_vaddr; +}; + /** * vkms_crtc_state - Driver specific CRTC state * @base: base CRTC state @@ -64,10 +80,13 @@ 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; bool crc_enabled; + int writeback_enabled; + u8 wb_state; /* ordered wq for crc_work */ struct workqueue_struct *crc_workq; /* protects concurrent access to crc_data */ @@ -93,6 +112,12 @@ struct vkms_gem_object { #define drm_crtc_to_vkms_output(target) \ container_of(target, struct vkms_output, crtc) +#define drm_connector_to_wb_connector(target) \ + container_of(target, struct drm_writeback_connector, base) + +#define drm_wb_to_vkms_output(target) \ + container_of(target, struct vkms_output, wb_connector) + #define drm_device_to_vkms_device(target) \ container_of(target, struct vkms_device, drm) @@ -105,6 +130,8 @@ struct vkms_gem_object { #define to_vkms_plane_state(target)\ container_of(target, struct vkms_plane_state, base) +#define to_wb_state(_state) (struct vkms_connector_state *)(_state) + /* CRTC */ int vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, struct drm_plane *primary, struct drm_plane *cursor); diff --git a/drivers/gpu/drm/vkms/vkms_gem.c b/drivers/gpu/drm/vkms/vkms_gem.c index 138b0bb325cf..9e3d25de6aba 100644 --- a/drivers/gpu/drm/vkms/vkms_gem.c +++ b/drivers/gpu/drm/vkms/vkms_gem.c @@ -51,7 +51,7 @@ vm_fault_t vkms_gem_fault(struct vm_fault *vmf) page_offset = (vaddr - vma->vm_start) >> PAGE_SHIFT; num_pages = DIV_ROUND_UP(obj->gem.size, PAGE_SIZE); - if (page_offset > num_pages) + if (page_offset >= num_pages) return VM_FAULT_SIGBUS; mutex_lock(&obj->pages_lock); diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c index 3b162b25312e..66b25c380f21 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -3,6 +3,8 @@ #include "vkms_drv.h" #include #include +#include +#include static void vkms_connector_destroy(struct drm_connector *connector) { @@ -10,6 +12,51 @@ static void vkms_connector_destroy(struct drm_connector *connector) drm_connector_cleanup(connector); } +static void vkms_wb_connector_reset(struct drm_connector *connector) +{ + struct vkms_connector_state *wb_state; + + wb_state = kzalloc(sizeof(*wb_state), GFP_KERNEL); + if (!wb_state) { + DRM_ERROR("Failed to allocate memory for connector state"); + return; + } + + if (connector->state) + __drm_atomic_helper_connector_destroy_state(connector->state); + + kfree(connector->state); + __drm_atomic_helper_connector_reset(connector, &wb_state->base); +} + +static struct drm_connector_state * +vkms_wb_connector_duplicate_state(struct drm_connector *connector) +{ + struct vkms_connector_state *wb_state, *wb_current_state; + + if (WARN_ON(!connector->state)) + return NULL; + + wb_state = kzalloc(sizeof(*wb_state), GFP_KERNEL); + if (!wb_state) + return NULL; + + wb_current_state = to_wb_state(connector->state); + wb_state->writeback_vaddr = wb_current_state->writeback_vaddr; + + __drm_atomic_helper_connector_duplicate_state(connector, &wb_state->base); + + return &wb_state->base; +} + +static const struct drm_connector_funcs vkms_wb_connector_funcs = { + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = vkms_connector_destroy, + .reset = vkms_wb_connector_reset, + .atomic_duplicate_state = vkms_wb_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + static const struct drm_connector_funcs vkms_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, .destroy = vkms_connector_destroy, @@ -18,8 +65,37 @@ static const struct drm_connector_funcs vkms_connector_funcs = { .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; -static const struct drm_encoder_funcs vkms_encoder_funcs = { - .destroy = drm_encoder_cleanup, +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; + + if (!conn_state->writeback_job || !conn_state->writeback_job->fb) + return 0; + + fb = conn_state->writeback_job->fb; + if (fb->width != crtc_state->mode.hdisplay || + fb->height != crtc_state->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_conn_get_modes(struct drm_connector *connector) @@ -32,10 +108,66 @@ static int vkms_conn_get_modes(struct drm_connector *connector) return count; } +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_connector_state *vkms_conn = to_wb_state(conn_state); + + if (!conn_state) + return; + + if (conn_state->writeback_job && conn_state->writeback_job->fb) { + struct drm_framebuffer *fb = conn_state->writeback_job->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); + + vkms_conn->writeback_vaddr = kzalloc(vkms_obj->gem.size, GFP_KERNEL); + + drm_writeback_queue_job(wb_conn, conn_state->writeback_job); + conn_state->writeback_job = NULL; + + output->wb_state = MW_ONESHOT; +pr_info("VKMS_OBJ (%d): Buff (%d) - Vaddr (%d) - Size = %ld - count = %d", vkms_obj != NULL, + vkms_conn->writeback_vaddr != NULL, vkms_obj->vaddr != NULL, vkms_obj->gem.size, + vkms_obj->vmap_count); + + memcpy(vkms_conn->writeback_vaddr, vkms_obj->vaddr, vkms_obj->gem.size); + } else { + output->wb_state = MW_STOP; + } +} + static const struct drm_connector_helper_funcs vkms_conn_helper_funcs = { .get_modes = vkms_conn_get_modes, }; +static const struct drm_encoder_funcs vkms_encoder_funcs = { + .destroy = drm_encoder_cleanup, +}; + +static const struct drm_connector_helper_funcs vkms_wb_conn_helper_funcs = { + .get_modes = vkms_conn_get_modes, + .atomic_commit = vkms_wb_atomic_commit, +}; + +static 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_formats, + ARRAY_SIZE(vkms_formats)); +} + int vkms_output_init(struct vkms_device *vkmsdev) { struct vkms_output *output = &vkmsdev->output; @@ -77,13 +209,14 @@ int vkms_output_init(struct vkms_device *vkmsdev) goto err_connector_register; } + encoder->possible_crtcs = 1; + ret = drm_encoder_init(dev, encoder, &vkms_encoder_funcs, DRM_MODE_ENCODER_VIRTUAL, NULL); if (ret) { DRM_ERROR("Failed to init encoder\n"); goto err_encoder; } - encoder->possible_crtcs = 1; ret = drm_connector_attach_encoder(connector, encoder); if (ret) { @@ -91,6 +224,12 @@ int vkms_output_init(struct vkms_device *vkmsdev) goto err_attach; } + if (vkmsdev->output.writeback_enabled) { + ret = enable_writeback_connector(vkmsdev); + if (ret) + DRM_ERROR("Failed to init writeback connector\n"); + } + drm_mode_config_reset(dev); return 0; diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index 0e67d2d42f0c..14259ffe47d8 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -190,7 +190,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, &vkms_plane_funcs, formats, nformats, NULL, type, NULL);