From patchwork Mon Dec 3 07:35:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Zhang, Tina" X-Patchwork-Id: 10708677 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 5EA6C14BD for ; Mon, 3 Dec 2018 07:40:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 523C62ACBB for ; Mon, 3 Dec 2018 07:40:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4696B2ACC3; Mon, 3 Dec 2018 07:40:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D32762ACD0 for ; Mon, 3 Dec 2018 07:40:53 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9CA0C89CD3; Mon, 3 Dec 2018 07:40:52 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id EC4F389AB5; Mon, 3 Dec 2018 07:40:50 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 Dec 2018 23:40:50 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,309,1539673200"; d="scan'208";a="126550083" Received: from tinazhang-linux-1.bj.intel.com ([10.238.158.97]) by fmsmga001.fm.intel.com with ESMTP; 02 Dec 2018 23:40:49 -0800 From: Tina Zhang To: Date: Mon, 3 Dec 2018 15:35:16 +0800 Message-Id: <1543822522-3413-2-git-send-email-tina.zhang@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1543822522-3413-1-git-send-email-tina.zhang@intel.com> References: <1543822522-3413-1-git-send-email-tina.zhang@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [RFC PATCH 1/7] drm/i915: Introduce meta framebuffer X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Daniel Vetter , intel-gfx@lists.freedesktop.org, kalyan.kondapally@intel.com, intel-gvt-dev@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Meta framebuffer, as a special intel_framebuffer, is used to describe an intel_framebuffer which is already pinned to the GGTT space and can be accessed by the display engine HW. In the virtualization world, with the help of GVT-g, vGPUs can share the entire global GTT space and be able to pin their framebuffers to the global GTT space. However, vGPUs cannot be able to access the display HW registers which are fully controlled by host i915. In order to support the vGPU local display direct flip feature, which is the vGPU can have several assigned display planes and can post its framebuffers to those assigned planes, host i915 must program the display plane registers on behalf of the vGPU. However, without the knowledge of the vGPU's framebuffers, host i915 cannot program those plane registers correctly. To fill this gap, the meta framebuffer is introduced. The meta framebuffer is used by host i915 to describe the framebuffer pinned to the GGTT space by guest OS. Signed-off-by: Tina Zhang Signed-off-by: Zhi Wang Cc: Ville Syrjälä Cc: Daniel Vetter --- drivers/gpu/drm/i915/intel_drv.h | 15 +++++++++++++++ drivers/gpu/drm/i915/intel_sprite.c | 19 ++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f575ba2..6cf345c 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -187,6 +187,12 @@ enum intel_output_type { #define INTEL_DSI_VIDEO_MODE 0 #define INTEL_DSI_COMMAND_MODE 1 + +enum { + INTEL_META_FB_VGPU = 1, + INTEL_META_FB_MAX, +}; + struct intel_framebuffer { struct drm_framebuffer base; struct intel_rotation_info rot_info; @@ -200,6 +206,15 @@ struct intel_framebuffer { unsigned int x, y; unsigned int pitch; /* pixels */ } rotated[2]; + + struct { + u32 type_id; + u32 ggtt_offset; + void *private; + void (*update)(struct intel_framebuffer *intel_fb, + enum pipe pipe, enum plane_id plane_id); + bool should_be_offscreen; + } meta_fb; }; struct intel_fbdev { diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index abe1938..16a0a5d4 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -486,9 +486,26 @@ skl_program_plane(struct intel_plane *plane, uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16; struct intel_plane *linked = plane_state->linked_plane; const struct drm_framebuffer *fb = plane_state->base.fb; + struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); u8 alpha = plane_state->base.alpha >> 8; unsigned long irqflags; u32 keymsk, keymax; + u32 offset; + + if (intel_fb->meta_fb.type_id == INTEL_META_FB_VGPU) { + + if (!intel_fb->meta_fb.update) + return; + + intel_fb->meta_fb.update(intel_fb, pipe, plane_id); + + if (intel_fb->meta_fb.should_be_offscreen) + return; + + offset = intel_fb->meta_fb.ggtt_offset; + } else { + offset = intel_plane_ggtt_offset(plane_state); + } /* Sizes are 0 based */ src_w--; @@ -558,7 +575,7 @@ skl_program_plane(struct intel_plane *plane, I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl); I915_WRITE_FW(PLANE_SURF(pipe, plane_id), - intel_plane_ggtt_offset(plane_state) + surf_addr); + offset + surf_addr); spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); } From patchwork Mon Dec 3 07:35:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Tina" X-Patchwork-Id: 10708679 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 401DA14BD for ; Mon, 3 Dec 2018 07:40:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 330832ACCC for ; Mon, 3 Dec 2018 07:40:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 26E362ACC4; Mon, 3 Dec 2018 07:40:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 853B82AC79 for ; Mon, 3 Dec 2018 07:40:55 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8546689CDE; Mon, 3 Dec 2018 07:40:54 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id 08C0889CD8; Mon, 3 Dec 2018 07:40:53 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 Dec 2018 23:40:52 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,309,1539673200"; d="scan'208";a="126550086" Received: from tinazhang-linux-1.bj.intel.com ([10.238.158.97]) by fmsmga001.fm.intel.com with ESMTP; 02 Dec 2018 23:40:51 -0800 From: Tina Zhang To: Date: Mon, 3 Dec 2018 15:35:17 +0800 Message-Id: <1543822522-3413-3-git-send-email-tina.zhang@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1543822522-3413-1-git-send-email-tina.zhang@intel.com> References: <1543822522-3413-1-git-send-email-tina.zhang@intel.com> Subject: [Intel-gfx] [RFC PATCH 2/7] drm/i915/gvt: Use meta fbs to stand for vGPU's planes X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, kalyan.kondapally@intel.com, intel-gvt-dev@lists.freedesktop.org MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Create and initialize vGPU meta framebuffers during vGPU's creation. Each meta framebuffer is an intel_framebuffer. Userspace can get the userspace visible identifier of that meta framebuffer by accessing plane_id_index attribute. For example: In "/sys/bus/pci/devices/0000\:00\:02.0/$vGPU_id/intel_vgpu/" directory, /* plane_id_index: pipe#(bit16:8) and plane#(bit7:0)*/ echo "0x10" > plane_index_id //Set the index to the plane 0 of pipe 1 /* * Dump userspace visible identifier of the meta framebuffer * standing for the primary plane of the vGPU's pipe one */ cat plane_index_id //dump the id for plane 0 of pipe 1 Then userspace can use this id with the exsting KMS IOCTL, e.g. drmModeSetPlane, to assign a physical plane to this virtual plane. Signed-off-by: Tina Zhang Cc: Zhenyu Wang Cc: Zhi Wang --- drivers/gpu/drm/i915/gvt/display.c | 150 +++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/gvt/gvt.h | 16 ++++ drivers/gpu/drm/i915/gvt/kvmgt.c | 46 ++++++++++++ 3 files changed, 212 insertions(+) diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c index df1e141..a9176a1 100644 --- a/drivers/gpu/drm/i915/gvt/display.c +++ b/drivers/gpu/drm/i915/gvt/display.c @@ -442,6 +442,152 @@ void intel_gvt_emulate_vblank(struct intel_gvt *gvt) mutex_unlock(&gvt->lock); } +struct intel_vgpu_fb_meta_data { + u32 vgpu_plane_id; /* vgpu_id(23:16):vgpu_pipe(15:8):vgpu_plane(7:0)*/ + struct intel_vgpu *vgpu; // the vGPU this meta_fb belongs to +}; + +static void meta_fb_destroy(struct drm_framebuffer *fb) +{ + struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); + + if (intel_fb->meta_fb.type_id != INTEL_META_FB_VGPU) + return; + + kfree(intel_fb->meta_fb.private); + intel_fb->meta_fb.private = NULL; + + drm_framebuffer_cleanup(fb); + kfree(intel_fb); +} + +static void clean_meta_fb(struct intel_vgpu *vgpu) +{ + enum pipe pipe; + enum plane_id plane_id; + struct intel_framebuffer *intel_fb; + + for (pipe = 0; pipe < I915_MAX_PIPES; pipe++) { + for (plane_id = 0; plane_id < I915_MAX_PLANES; plane_id++) { + intel_fb = vgpu->display.meta_fbs.meta_fb[pipe][plane_id]; + if (!intel_fb) + drm_framebuffer_put(&intel_fb->base); + + intel_fb = NULL; + } + } +} + +static int meta_fb_create_handle(struct drm_framebuffer *fb, + struct drm_file *file, + unsigned int *handle) +{ + return -ENODEV; +} + +static int meta_fb_dirty(struct drm_framebuffer *fb, + struct drm_file *file, + unsigned int flags, + unsigned int color, + struct drm_clip_rect *clips, + unsigned int num_clips) +{ + return 0; +} + +static const struct drm_framebuffer_funcs meta_fb_funcs = { + .destroy = meta_fb_destroy, + .create_handle = meta_fb_create_handle, + .dirty = meta_fb_dirty, +}; + +static void meta_fb_update(struct intel_framebuffer *intel_fb, + enum pipe pipe, enum plane_id plane_id) +{ + struct intel_vgpu_fb_meta_data *meta_data; + struct intel_gvt *gvt; + + if (!intel_fb || intel_fb->meta_fb.type_id != INTEL_META_FB_VGPU) + return; + + meta_data = intel_fb->meta_fb.private; + gvt = meta_data->vgpu->gvt; + + if (gvt->assigned_plane[pipe][plane_id].vgpu_plane_id != + meta_data->vgpu_plane_id) { + gvt->assigned_plane[pipe][plane_id].vgpu_plane_id = + meta_data->vgpu_plane_id; + gvt->assigned_plane[pipe][plane_id].framebuffer_id = + intel_fb->base.base.id; + intel_fb->meta_fb.ggtt_offset = 0; + intel_fb->meta_fb.should_be_offscreen = true; + } else if (!intel_fb->meta_fb.ggtt_offset) { + intel_fb->meta_fb.should_be_offscreen = true; + } else { + intel_fb->meta_fb.should_be_offscreen = false; + } +} + +static int init_meta_fb(struct intel_vgpu *vgpu) +{ + struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; + struct intel_vgpu_fb_meta_data *meta_data; + struct drm_mode_fb_cmd2 mode_cmd; + struct intel_framebuffer *intel_fb; + enum pipe pipe; + enum plane_id plane_id; + int ret = 0; + + for (pipe = 0; pipe < I915_MAX_PIPES; pipe++) { + for (plane_id = 0; plane_id < I915_MAX_PLANES; plane_id++) { + intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); + if (!intel_fb) + return -ENOMEM; + + /* + * Create a drm_framebuffer with defaults. + */ + mode_cmd.pixel_format = DRM_FORMAT_XRGB8888; + mode_cmd.width = dev_priv->drm.mode_config.max_width; + mode_cmd.height = dev_priv->drm.mode_config.max_height; + mode_cmd.flags = DRM_MODE_FB_MODIFIERS; + mode_cmd.handles[0] = 0; + mode_cmd.pitches[0] = mode_cmd.width * 4; + mode_cmd.offsets[0] = 0; + mode_cmd.modifier[0] = DRM_FORMAT_MOD_LINEAR; + + drm_helper_mode_fill_fb_struct(&dev_priv->drm, + &intel_fb->base, &mode_cmd); + + ret = drm_framebuffer_init(&dev_priv->drm, + &intel_fb->base, &meta_fb_funcs); + if (ret) { + DRM_ERROR("%s: framebuffer init failed %d\n", + __func__, ret); + kfree(intel_fb); + return ret; + } + + meta_data = kmalloc(sizeof(struct intel_vgpu_fb_meta_data), + GFP_KERNEL); + if (unlikely(!meta_data)) { + return -ENOMEM; + } + + meta_data->vgpu_plane_id = (vgpu->id << 16) | + (pipe << 8) | plane_id; + meta_data->vgpu = vgpu; + + intel_fb->meta_fb.private = meta_data; + intel_fb->meta_fb.update = meta_fb_update; + intel_fb->meta_fb.type_id = INTEL_META_FB_VGPU; + + vgpu->display.meta_fbs.meta_fb[pipe][plane_id] = intel_fb; + } + } + return 0; +} + /** * intel_vgpu_clean_display - clean vGPU virtual display emulation * @vgpu: a vGPU @@ -457,6 +603,8 @@ void intel_vgpu_clean_display(struct intel_vgpu *vgpu) clean_virtual_dp_monitor(vgpu, PORT_D); else clean_virtual_dp_monitor(vgpu, PORT_B); + + clean_meta_fb(vgpu); } /** @@ -476,6 +624,8 @@ int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 resolution) intel_vgpu_init_i2c_edid(vgpu); + init_meta_fb(vgpu); + if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) return setup_virtual_dp_monitor(vgpu, PORT_D, GVT_DP_D, resolution); diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 31f6cdb..0ab10b0 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -131,10 +131,16 @@ struct intel_vgpu_opregion { #define vgpu_opregion(vgpu) (&(vgpu->opregion)) +struct intel_vgpu_meta_fbs { + struct intel_framebuffer *meta_fb[I915_MAX_PIPES][I915_MAX_PLANES]; + u32 plane_id_index; +}; + struct intel_vgpu_display { struct intel_vgpu_i2c_edid i2c_edid; struct intel_vgpu_port ports[I915_MAX_PORTS]; struct intel_vgpu_sbi sbi; + struct intel_vgpu_meta_fbs meta_fbs; }; struct vgpu_sched_ctl { @@ -301,6 +307,13 @@ struct intel_vgpu_type { enum intel_vgpu_edid resolution; }; +struct assigned_plane { + u32 vgpu_plane_id; + + /* userspace visible identifier */ + int framebuffer_id; +}; + struct intel_gvt { /* GVT scope lock, protect GVT itself, and all resource currently * not yet protected by special locks(vgpu and scheduler lock). @@ -340,6 +353,9 @@ struct intel_gvt { } engine_mmio_list; struct dentry *debugfs_root; + + /* vGPU plane assignment */ + struct assigned_plane assigned_plane[I915_MAX_PIPES][I915_MAX_PLANES]; }; static inline struct intel_gvt *to_gvt(struct drm_i915_private *i915) diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index c107214..7f4704d 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -1420,12 +1420,58 @@ hw_id_show(struct device *dev, struct device_attribute *attr, return sprintf(buf, "\n"); } +static ssize_t +plane_id_index_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct mdev_device *mdev = mdev_from_dev(dev); + + if (mdev) { + struct intel_vgpu *vgpu = (struct intel_vgpu *) + mdev_get_drvdata(mdev); + enum pipe pipe = vgpu->display.meta_fbs.plane_id_index & + 0x000000F0; + enum plane_id plane_id = vgpu->display.meta_fbs.plane_id_index & + 0x0000000F; + + if ((pipe < I915_MAX_PIPES || plane_id < I915_MAX_PLANES) && + vgpu->display.meta_fbs.meta_fb[pipe][plane_id]) { + return sprintf(buf, "%u\n", + vgpu->display.meta_fbs.meta_fb[pipe][plane_id]->base.base.id); + } + } + return sprintf(buf, "\n"); +} + +static ssize_t +plane_id_index_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t n) +{ + struct mdev_device *mdev = mdev_from_dev(dev); + ssize_t ret; + u32 val; + + ret = kstrtou32(buf, 0, &val); + if (ret) + return ret; + + if (mdev) { + struct intel_vgpu *vgpu = (struct intel_vgpu *) + mdev_get_drvdata(mdev); + vgpu->display.meta_fbs.plane_id_index = val; + } + + return n; +} + static DEVICE_ATTR_RO(vgpu_id); static DEVICE_ATTR_RO(hw_id); +static DEVICE_ATTR_RW(plane_id_index); static struct attribute *intel_vgpu_attrs[] = { &dev_attr_vgpu_id.attr, &dev_attr_hw_id.attr, + &dev_attr_plane_id_index.attr, NULL }; From patchwork Mon Dec 3 07:35:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Zhang, Tina" X-Patchwork-Id: 10708681 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 BA68013AF for ; Mon, 3 Dec 2018 07:40:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AD9EF2A27C for ; Mon, 3 Dec 2018 07:40:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A187E2ACBF; Mon, 3 Dec 2018 07:40:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3C1DA2ACC2 for ; Mon, 3 Dec 2018 07:40:58 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9C69689AB5; Mon, 3 Dec 2018 07:40:57 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5E3F989CD8; Mon, 3 Dec 2018 07:40:54 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 Dec 2018 23:40:54 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,309,1539673200"; d="scan'208";a="126550090" Received: from tinazhang-linux-1.bj.intel.com ([10.238.158.97]) by fmsmga001.fm.intel.com with ESMTP; 02 Dec 2018 23:40:52 -0800 From: Tina Zhang To: Date: Mon, 3 Dec 2018 15:35:18 +0800 Message-Id: <1543822522-3413-4-git-send-email-tina.zhang@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1543822522-3413-1-git-send-email-tina.zhang@intel.com> References: <1543822522-3413-1-git-send-email-tina.zhang@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [RFC PATCH 3/7] drm/i915: Introduce async plane update to i915 X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Daniel Vetter , intel-gfx@lists.freedesktop.org, Gustavo Padovan , Helen Koike , Enric Balletbo i Serra , kalyan.kondapally@intel.com, intel-gvt-dev@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP This patch is separated from the following patch: https://lists.freedesktop.org/archives/dri-devel/2018-June/179592.html This patch introduces the implementation async plane update callbacks to i915. The original idea is to use async plane update framework to update cursors. The next patch of this series try to extend this idea to support other planes. Signed-off-by: Tina Zhang Cc: Gustavo Padovan Cc: Enric Balletbo i Serra Cc: Helen Koike Cc: Daniel Vetter Cc: Ville Syrjälä --- drivers/gpu/drm/i915/intel_atomic_plane.c | 69 +++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 11 +++++ 2 files changed, 80 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c index 905f8ef..dddd3a7 100644 --- a/drivers/gpu/drm/i915/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c @@ -217,10 +217,79 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *old_state, } } +static int intel_plane_atomic_async_check(struct drm_plane *plane, + struct drm_plane_state *state) +{ + struct drm_crtc_state *crtc_state; + + if (plane->type != DRM_PLANE_TYPE_CURSOR) + return -EINVAL; + + crtc_state = drm_atomic_get_existing_crtc_state(state->state, + state->crtc); + if (WARN_ON(!crtc_state)) + return -EINVAL; + + /* + * When crtc is inactive or there is a modeset pending, + * wait for it to complete in the slowpath + */ + if (!crtc_state->active || to_intel_crtc_state(crtc_state)->update_pipe) + return -EINVAL; + + /* + * If any parameters change that may affect watermarks, + * take the slowpath. Only changing fb or position should be + * in the fastpath. + */ + if (plane->state->crtc != state->crtc || + plane->state->src_w != state->src_w || + plane->state->src_h != state->src_h || + plane->state->crtc_w != state->crtc_w || + plane->state->crtc_h != state->crtc_h || + !plane->state->fb != !state->fb) + return -EINVAL; + + return 0; +} + +static void intel_plane_atomic_async_update(struct drm_plane *plane, + struct drm_plane_state *new_state) +{ + struct intel_plane *intel_plane = to_intel_plane(plane); + struct drm_crtc *crtc = plane->state->crtc; + struct drm_framebuffer *old_fb; + + old_fb = plane->state->fb; + + i915_gem_track_fb(intel_fb_obj(old_fb), intel_fb_obj(new_state->fb), + intel_plane->frontbuffer_bit); + + plane->state->src_x = new_state->src_x; + plane->state->src_y = new_state->src_y; + plane->state->crtc_x = new_state->crtc_x; + plane->state->crtc_y = new_state->crtc_y; + plane->state->fb = new_state->fb; + + new_state->fb = old_fb; + + if (plane->state->visible) { + trace_intel_update_plane(plane, to_intel_crtc(crtc)); + intel_plane->update_plane(intel_plane, + to_intel_crtc_state(crtc->state), + to_intel_plane_state(plane->state)); + } else { + trace_intel_disable_plane(plane, to_intel_crtc(crtc)); + intel_plane->disable_plane(intel_plane, to_intel_crtc(crtc)); + } +} + const struct drm_plane_helper_funcs intel_plane_helper_funcs = { .prepare_fb = intel_prepare_plane_fb, .cleanup_fb = intel_cleanup_plane_fb, .atomic_check = intel_plane_atomic_check, + .atomic_async_check = intel_plane_atomic_async_check, + .atomic_async_update = intel_plane_atomic_async_update, }; /** diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 132e978..b64708b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13050,6 +13050,14 @@ static int intel_atomic_commit(struct drm_device *dev, struct drm_i915_private *dev_priv = to_i915(dev); int ret = 0; + if (state->async_update) { + ret = drm_atomic_helper_prepare_planes(dev, state); + if (ret) + return ret; + drm_atomic_helper_async_commit(dev, state); + return 0; + } + drm_atomic_state_get(state); i915_sw_fence_init(&intel_state->commit_ready, intel_atomic_commit_ready); @@ -13275,6 +13283,9 @@ intel_prepare_plane_fb(struct drm_plane *plane, struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->state->fb); int ret; + if (new_state->state->async_update) + return 0; + if (old_obj) { struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(new_state->state, From patchwork Mon Dec 3 07:35:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Zhang, Tina" X-Patchwork-Id: 10708683 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 66AED13AF for ; Mon, 3 Dec 2018 07:40:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5B4782AC85 for ; Mon, 3 Dec 2018 07:40:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4FF7F2ACD0; Mon, 3 Dec 2018 07:40:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0D4472ACC4 for ; Mon, 3 Dec 2018 07:40:59 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8521B89A56; Mon, 3 Dec 2018 07:40:57 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4E28789CF3; Mon, 3 Dec 2018 07:40:56 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 Dec 2018 23:40:56 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,309,1539673200"; d="scan'208";a="126550093" Received: from tinazhang-linux-1.bj.intel.com ([10.238.158.97]) by fmsmga001.fm.intel.com with ESMTP; 02 Dec 2018 23:40:54 -0800 From: Tina Zhang To: Date: Mon, 3 Dec 2018 15:35:19 +0800 Message-Id: <1543822522-3413-5-git-send-email-tina.zhang@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1543822522-3413-1-git-send-email-tina.zhang@intel.com> References: <1543822522-3413-1-git-send-email-tina.zhang@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [RFC PATCH 4/7] drm/i915: Extend async plane update to other planes X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Daniel Vetter , intel-gfx@lists.freedesktop.org, Gustavo Padovan , Helen Koike , Enric Balletbo i Serra , kalyan.kondapally@intel.com, intel-gvt-dev@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Extend async plane update idea to more planes. Signed-off-by: Tina Zhang Cc: Gustavo Padovan Cc: Enric Balletbo i Serra Cc: Helen Koike Cc: Daniel Vetter Cc: Ville Syrjälä --- drivers/gpu/drm/i915/intel_atomic_plane.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c index dddd3a7..b4c37ee 100644 --- a/drivers/gpu/drm/i915/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c @@ -222,9 +222,6 @@ static int intel_plane_atomic_async_check(struct drm_plane *plane, { struct drm_crtc_state *crtc_state; - if (plane->type != DRM_PLANE_TYPE_CURSOR) - return -EINVAL; - crtc_state = drm_atomic_get_existing_crtc_state(state->state, state->crtc); if (WARN_ON(!crtc_state)) From patchwork Mon Dec 3 07:35:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Tina" X-Patchwork-Id: 10708685 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 6EE0316B1 for ; Mon, 3 Dec 2018 07:41:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 61D822ACCF for ; Mon, 3 Dec 2018 07:41:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 55DFC2ACD0; Mon, 3 Dec 2018 07:41:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B68252AC96 for ; Mon, 3 Dec 2018 07:41:00 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 22B8289D42; Mon, 3 Dec 2018 07:41:00 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id C794E89CFA; Mon, 3 Dec 2018 07:40:57 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 Dec 2018 23:40:57 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,309,1539673200"; d="scan'208";a="126550096" Received: from tinazhang-linux-1.bj.intel.com ([10.238.158.97]) by fmsmga001.fm.intel.com with ESMTP; 02 Dec 2018 23:40:56 -0800 From: Tina Zhang To: Date: Mon, 3 Dec 2018 15:35:20 +0800 Message-Id: <1543822522-3413-6-git-send-email-tina.zhang@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1543822522-3413-1-git-send-email-tina.zhang@intel.com> References: <1543822522-3413-1-git-send-email-tina.zhang@intel.com> Subject: [Intel-gfx] [RFC PATCH 5/7] drm/i915/gvt: Introduce vGPU plane page flip framework X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, kalyan.kondapally@intel.com, intel-gvt-dev@lists.freedesktop.org MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP The vGPU plane page flip framework supports to update the assigned planes with the meta framebuffer information during guest vGPU page flip. With the updated meta framebuffer information, the proposed framework will use the asynchronous atomic commit path to do the plane update on behalf of vGPUs as much as possible. Signed-off-by: Tina Zhang Cc: Zhenyu Wang Cc: Zhi Wang --- drivers/gpu/drm/i915/gvt/display.c | 265 +++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/gvt/display.h | 18 +++ 2 files changed, 283 insertions(+) diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c index a9176a1..e06d8d6 100644 --- a/drivers/gpu/drm/i915/gvt/display.c +++ b/drivers/gpu/drm/i915/gvt/display.c @@ -32,6 +32,9 @@ * */ +#include +#include +#include #include "i915_drv.h" #include "gvt.h" @@ -442,6 +445,268 @@ void intel_gvt_emulate_vblank(struct intel_gvt *gvt) mutex_unlock(&gvt->lock); } +static bool check_vgpu_plane_table(struct intel_gvt *gvt, u32 vgpu_plane_id, + enum pipe *pipe, enum plane_id *plane_id, + u32 *framebuffer_id) +{ + int i, j; + + for (i = 0; i < I915_MAX_PIPES; i++) { + for (j = 0; j < I915_MAX_PLANES; j++) + if (gvt->assigned_plane[i][j].vgpu_plane_id == + vgpu_plane_id) { + *pipe = i; + *plane_id = j; + *framebuffer_id = + gvt->assigned_plane[i][j].framebuffer_id; + break; + } + + if (j < I915_MAX_PLANES) + return true; + } + + return false; +} + +static u64 plane_ctl_modifier(u64 fb_tiling) +{ + switch (fb_tiling) { + case PLANE_CTL_TILED_LINEAR: + return DRM_FORMAT_MOD_LINEAR; + case PLANE_CTL_TILED_X: + return I915_FORMAT_MOD_X_TILED; + case PLANE_CTL_TILED_Y: + return I915_FORMAT_MOD_Y_TILED; + case PLANE_CTL_TILED_Y | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE: + return I915_FORMAT_MOD_Y_TILED_CCS; + case PLANE_CTL_TILED_YF: + return I915_FORMAT_MOD_Yf_TILED; + case PLANE_CTL_TILED_YF | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE: + return I915_FORMAT_MOD_Yf_TILED_CCS; + default: + MISSING_CASE(fb_tiling); + } + + return 0; +} + +static int vgpu_fb_update(struct intel_gvt *gvt, + struct drm_framebuffer *fb, + struct intel_vgpu_plane_info *vgpu_plane_info, + struct drm_mode_fb_cmd2 *mode_cmd) +{ + int ret; + + if (vgpu_plane_info->plane == PLANE_PRIMARY) { + struct intel_vgpu_primary_plane_format plane; + + ret = intel_vgpu_decode_primary_plane(vgpu_plane_info->vgpu, &plane); + if (ret) + return ret; + + mode_cmd->pixel_format = plane.drm_format; + mode_cmd->width = plane.width; + mode_cmd->height = plane.height; + mode_cmd->handles[0] = 0; + mode_cmd->offsets[0] = 0; + mode_cmd->pitches[0] = plane.stride; + mode_cmd->flags = DRM_MODE_FB_MODIFIERS; + mode_cmd->modifier[0] = plane_ctl_modifier(plane.tiled); + } else if (vgpu_plane_info->plane == PLANE_CURSOR) { + struct intel_vgpu_cursor_plane_format plane; + + ret = intel_vgpu_decode_cursor_plane(vgpu_plane_info->vgpu, &plane); + if (ret) + return ret; + + mode_cmd->pixel_format = plane.drm_format; + mode_cmd->width = plane.width; + mode_cmd->height = plane.height; + mode_cmd->handles[0] = 0; + mode_cmd->offsets[0] = 0; + mode_cmd->pitches[0] = plane.width * (plane.bpp / 8); + mode_cmd->flags = DRM_MODE_FB_MODIFIERS; + mode_cmd->modifier[0] = 0; + } else { + struct intel_vgpu_sprite_plane_format plane; + + ret = intel_vgpu_decode_sprite_plane(vgpu_plane_info->vgpu, &plane); + if (ret) + return ret; + + mode_cmd->pixel_format = plane.hw_format; + mode_cmd->width = plane.width; + mode_cmd->height = plane.height; + mode_cmd->handles[0] = 0; + mode_cmd->offsets[0] = 0; + mode_cmd->pitches[0] = plane.stride; + mode_cmd->flags = DRM_MODE_FB_MODIFIERS; + mode_cmd->modifier[0] = plane_ctl_modifier(plane.tiled); + } + + return ret; +} + +static int update_vgpu_assigned_plane(struct intel_gvt *gvt, + struct drm_plane *plane, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_modeset_acquire_ctx *ctx, + struct intel_vgpu_plane_info *vgpu_plane_info) +{ + struct drm_device *drm = &gvt->dev_priv->drm; + struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); + struct drm_atomic_state *state; + struct drm_plane_state *plane_state; + struct drm_mode_fb_cmd2 mode_cmd; + int ret = 0; + + state = drm_atomic_state_alloc(plane->dev); + if (!state) + return -ENOMEM; + + state->acquire_ctx = ctx; + plane_state = drm_atomic_get_plane_state(state, plane); + if (IS_ERR(plane_state)) { + ret = PTR_ERR(plane_state); + goto fail; + } + + ret = drm_atomic_set_crtc_for_plane(plane_state, crtc); + if (ret != 0) + goto fail; + drm_atomic_set_fb_for_plane(plane_state, fb); + + ret = vgpu_fb_update(gvt, fb, vgpu_plane_info, &mode_cmd); + if (ret) + goto fail; + + if (memcmp(mode_cmd.pitches, fb->pitches, 16) || + memcmp(mode_cmd.offsets, fb->offsets, 16) || + drm_get_format_info(drm, &mode_cmd) != fb->format || + mode_cmd.modifier[0] != fb->modifier || + drm_atomic_helper_async_check(drm, state)) + state->async_update = false; + else + state->async_update = true; + + drm_helper_mode_fill_fb_struct(plane->dev, fb, &mode_cmd); + plane_state->src_x = vgpu_plane_info->plane_offset & 0x0000ffff; + plane_state->src_y = (vgpu_plane_info->plane_offset >> 16) & 0x0000ffff; + plane_state->src_w = mode_cmd.width << 16; + plane_state->src_h = mode_cmd.height << 16; + + intel_fb->meta_fb.ggtt_offset = vgpu_plane_info->offset; + + /* Don't allow full modeset */ + state->allow_modeset = false; + + ret = drm_atomic_commit(state); +fail: + drm_atomic_state_put(state); + return ret; +} + +static int vgpu_plane_update_internal(struct intel_gvt *gvt, + struct drm_plane *plane, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_modeset_acquire_ctx *ctx, + struct intel_vgpu_plane_info *vgpu_plane_info) +{ + int ret = 0; + + /* Check whether this plane is usable on this CRTC */ + if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) { + DRM_DEBUG_KMS("Invalid crtc for plane\n"); + ret = -EINVAL; + goto out; + } + + ret = update_vgpu_assigned_plane(gvt, plane, crtc, fb, ctx, vgpu_plane_info); + +out: + return ret; +} + +void intel_vgpu_plane_update(struct intel_gvt *gvt, + struct intel_vgpu_plane_info *vgpu_plane_info) +{ + struct drm_device *drm = &gvt->dev_priv->drm; + struct drm_modeset_acquire_ctx ctx; + struct drm_mode_object *obj_fb = NULL; + struct drm_plane *plane; + struct intel_plane *intel_plane = NULL; + struct intel_crtc *intel_crtc; + struct intel_framebuffer *intel_fb; + u32 framebuffer_id = 0; + enum pipe pipe; + enum plane_id plane_id; + int ret; + + drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); +retry: + ret = drm_modeset_lock_all_ctx(drm, &ctx); + if (ret) + goto fail; + + ret = check_vgpu_plane_table(gvt, vgpu_plane_info->id, &pipe, + &plane_id, &framebuffer_id); + if (!ret) { + ret = -EINVAL; + goto fail; + } + + DRM_DEBUG_KMS("%s: pipe is %d, plane_id is %d, fb_id is %d\n", + __func__, pipe, plane_id, framebuffer_id); + + if (framebuffer_id) { + intel_crtc = intel_get_crtc_for_pipe(gvt->dev_priv, pipe); + + drm_for_each_plane(plane, drm) { + intel_plane = to_intel_plane(plane); + if (intel_plane->pipe == pipe && + intel_plane->id == plane_id) + break; + + intel_plane = NULL; + } + if (!intel_plane) + goto fail; + + //vGPU might want to disable the assigned plane + if (vgpu_plane_info->offset == 0) { + intel_plane->disable_plane(intel_plane, intel_crtc); + goto out; + } + + obj_fb = idr_find(&drm->mode_config.crtc_idr, framebuffer_id); + intel_fb = to_intel_framebuffer(obj_to_fb(obj_fb)); + + } else { + DRM_DEBUG_KMS("no assgined plane for the vGPU plane 0x%x\n", + vgpu_plane_info->id); + goto fail; + } + + ret = vgpu_plane_update_internal(gvt, &intel_plane->base, + &intel_crtc->base, &intel_fb->base, + &ctx, vgpu_plane_info); + +fail: + if (ret == -EDEADLK) { + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry; + } +out: + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); +} + + + struct intel_vgpu_fb_meta_data { u32 vgpu_plane_id; /* vgpu_id(23:16):vgpu_pipe(15:8):vgpu_plane(7:0)*/ struct intel_vgpu *vgpu; // the vGPU this meta_fb belongs to diff --git a/drivers/gpu/drm/i915/gvt/display.h b/drivers/gpu/drm/i915/gvt/display.h index ea7c1c5..5d929bb 100644 --- a/drivers/gpu/drm/i915/gvt/display.h +++ b/drivers/gpu/drm/i915/gvt/display.h @@ -160,6 +160,20 @@ enum intel_vgpu_edid { GVT_EDID_NUM, }; +struct intel_vgpu_plane_info { + u32 id;; /* vgpu plane id */ + enum plane_id plane; + struct intel_vgpu *vgpu; + + /* vGPU plane registers values. */ + u32 offset; + u32 stride; + u32 control; + u32 plane_offset; + + u32 size; +}; + static inline char *vgpu_edid_str(enum intel_vgpu_edid id) { switch (id) { @@ -181,4 +195,8 @@ void intel_vgpu_clean_display(struct intel_vgpu *vgpu); int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe); + +void intel_vgpu_plane_update(struct intel_gvt *gvt, + struct intel_vgpu_plane_info *plane_info); + #endif From patchwork Mon Dec 3 07:35:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Tina" X-Patchwork-Id: 10708687 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 4F07B14BD for ; Mon, 3 Dec 2018 07:41:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4075F2AC85 for ; Mon, 3 Dec 2018 07:41:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 34A352ACCC; Mon, 3 Dec 2018 07:41:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D389D2AC96 for ; Mon, 3 Dec 2018 07:41:01 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9B24D89D49; Mon, 3 Dec 2018 07:41:00 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id 39EB589CFA; Mon, 3 Dec 2018 07:40:59 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 Dec 2018 23:40:59 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,309,1539673200"; d="scan'208";a="126550102" Received: from tinazhang-linux-1.bj.intel.com ([10.238.158.97]) by fmsmga001.fm.intel.com with ESMTP; 02 Dec 2018 23:40:57 -0800 From: Tina Zhang To: Date: Mon, 3 Dec 2018 15:35:21 +0800 Message-Id: <1543822522-3413-7-git-send-email-tina.zhang@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1543822522-3413-1-git-send-email-tina.zhang@intel.com> References: <1543822522-3413-1-git-send-email-tina.zhang@intel.com> Subject: [Intel-gfx] [RFC PATCH 6/7] drm/i915/gvt: Enable guest direct page flip X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, kalyan.kondapally@intel.com, intel-gvt-dev@lists.freedesktop.org MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Use the vGPU direct plane flip framework do the guest direct page flip. Signed-off-by: Tina Zhang Cc: Zhenyu Wang Cc: Zhi Wang --- drivers/gpu/drm/i915/gvt/handlers.c | 38 +++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index b5475c9..89a22a5 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -743,6 +743,35 @@ static int south_chicken2_mmio_write(struct intel_vgpu *vgpu, return 0; } +static int handle_vgpu_page_flip(struct intel_vgpu *vgpu, int pipe, + enum plane_id plane) +{ + struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; + struct intel_vgpu_plane_info vgpu_plane_info; + u32 vgpu_id = vgpu->id; + u32 pipe_id = pipe; + u32 plane_id = plane; + u32 vgpu_plane_id = (vgpu_id << 16) | (pipe_id << 8) | plane_id; + + if (plane == PLANE_CURSOR) { + DRM_DEBUG_KMS("Assigning CURSOR plane hasn't been supported\n"); + } else { /* primary plane and sprite plane */ + vgpu_plane_info.id = vgpu_plane_id; + vgpu_plane_info.plane = PLANE_PRIMARY; + vgpu_plane_info.offset = vgpu_vreg_t(vgpu, DSPSURF(pipe)) & + I915_GTT_PAGE_MASK; + vgpu_plane_info.stride = vgpu_vreg_t(vgpu, DSPSTRIDE(pipe)) & 0x3ff; + vgpu_plane_info.control = vgpu_vreg_t(vgpu, DSPCNTR(pipe)); + vgpu_plane_info.size = vgpu_vreg_t(vgpu, DSPSIZE(pipe)); + vgpu_plane_info.plane_offset = vgpu_vreg_t(vgpu, DSPOFFSET(pipe)); + vgpu_plane_info.vgpu = vgpu; + } + + intel_vgpu_plane_update(vgpu->gvt, &vgpu_plane_info); + + return 0; +} + #define DSPSURF_TO_PIPE(offset) \ calc_index(offset, _DSPASURF, _DSPBSURF, 0, DSPSURF(PIPE_C)) @@ -761,6 +790,8 @@ static int pri_surf_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, write_vreg(vgpu, offset, p_data, bytes); vgpu_vreg_t(vgpu, surflive_reg) = vgpu_vreg(vgpu, offset); + handle_vgpu_page_flip(vgpu, index, PLANE_PRIMARY); + set_bit(flip_event[index], vgpu->irq.flip_done_event[index]); return 0; } @@ -768,10 +799,15 @@ static int pri_surf_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, #define SPRSURF_TO_PIPE(offset) \ calc_index(offset, _SPRA_SURF, _SPRB_SURF, 0, SPRSURF(PIPE_C)) +#define SPRSURF_TO_PLANE(offset, pipe) \ + calc_index(offset, _PLANE_SURF_1(pipe), _PLANE_SURF_2(pipe), \ + _PLANE_SURF_3(pipe), PLANE_SURF(PIPE_C, PLANE_CURSOR)) + static int spr_surf_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, void *p_data, unsigned int bytes) { unsigned int index = SPRSURF_TO_PIPE(offset); + unsigned int plane = SPRSURF_TO_PLANE(offset, index); i915_reg_t surflive_reg = SPRSURFLIVE(index); int flip_event[] = { [PIPE_A] = SPRITE_A_FLIP_DONE, @@ -782,6 +818,8 @@ static int spr_surf_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, write_vreg(vgpu, offset, p_data, bytes); vgpu_vreg_t(vgpu, surflive_reg) = vgpu_vreg(vgpu, offset); + handle_vgpu_page_flip(vgpu, index, plane); + set_bit(flip_event[index], vgpu->irq.flip_done_event[index]); return 0; } From patchwork Mon Dec 3 07:35:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Tina" X-Patchwork-Id: 10708689 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 A66FC13AF for ; Mon, 3 Dec 2018 07:41:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 99B772AC96 for ; Mon, 3 Dec 2018 07:41:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8E2E72ACD8; Mon, 3 Dec 2018 07:41:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id DD1522AC96 for ; Mon, 3 Dec 2018 07:41:02 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B12CF89D4A; Mon, 3 Dec 2018 07:41:01 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id A539489D4A; Mon, 3 Dec 2018 07:41:00 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 Dec 2018 23:41:00 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,309,1539673200"; d="scan'208";a="126550110" Received: from tinazhang-linux-1.bj.intel.com ([10.238.158.97]) by fmsmga001.fm.intel.com with ESMTP; 02 Dec 2018 23:40:59 -0800 From: Tina Zhang To: Date: Mon, 3 Dec 2018 15:35:22 +0800 Message-Id: <1543822522-3413-8-git-send-email-tina.zhang@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1543822522-3413-1-git-send-email-tina.zhang@intel.com> References: <1543822522-3413-1-git-send-email-tina.zhang@intel.com> Subject: [Intel-gfx] [RFC PATCH 7/7] drm/i915/gvt: Introduce HW Vblank interrupt to vGPU X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, kalyan.kondapally@intel.com, intel-gvt-dev@lists.freedesktop.org MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP For each physical crtc, Gvt-g has a kernel thread to get the HW vblank event on time and inject the interrupt event to the vGPUs which the display planes of the crtc are assigned to. Signed-off-by: Tina Zhang Cc: Zhenyu Wang Cc: Zhi Wang --- drivers/gpu/drm/i915/gvt/display.c | 30 ++++++---- drivers/gpu/drm/i915/gvt/display.h | 3 +- drivers/gpu/drm/i915/gvt/gvt.c | 112 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/gvt/gvt.h | 3 + drivers/gpu/drm/i915/gvt/handlers.c | 4 +- drivers/gpu/drm/i915/gvt/interrupt.c | 54 +++++++++++++++++ drivers/gpu/drm/i915/gvt/interrupt.h | 2 + 7 files changed, 193 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c index e06d8d6..eec8336 100644 --- a/drivers/gpu/drm/i915/gvt/display.c +++ b/drivers/gpu/drm/i915/gvt/display.c @@ -358,7 +358,7 @@ static int setup_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num, * enabled/disabled virtual pipes. * */ -void intel_gvt_check_vblank_emulation(struct intel_gvt *gvt) +void intel_gvt_check_vblank_emulation(struct intel_gvt *gvt, bool use_hw_vblank) { struct intel_gvt_irq *irq = &gvt->irq; struct intel_vgpu *vgpu; @@ -369,25 +369,29 @@ void intel_gvt_check_vblank_emulation(struct intel_gvt *gvt) for_each_active_vgpu(gvt, vgpu, id) { for (pipe = 0; pipe < I915_MAX_PIPES; pipe++) { if (pipe_is_enabled(vgpu, pipe)) { - found = true; - break; + if (use_hw_vblank) { + wake_up_process(gvt->vblank_thread[pipe]); + } else { + found = true; + break; + } } } - if (found) - break; } - /* all the pipes are disabled */ - if (!found) - hrtimer_cancel(&irq->vblank_timer.timer); - else - hrtimer_start(&irq->vblank_timer.timer, - ktime_add_ns(ktime_get(), irq->vblank_timer.period), - HRTIMER_MODE_ABS); + if (!use_hw_vblank) { + /* all the pipes are disabled */ + if (!found) + hrtimer_cancel(&irq->vblank_timer.timer); + else + hrtimer_start(&irq->vblank_timer.timer, + ktime_add_ns(ktime_get(), irq->vblank_timer.period), + HRTIMER_MODE_ABS); + } mutex_unlock(&gvt->lock); } -static void emulate_vblank_on_pipe(struct intel_vgpu *vgpu, int pipe) +void emulate_vblank_on_pipe(struct intel_vgpu *vgpu, int pipe) { struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; struct intel_vgpu_irq *irq = &vgpu->irq; diff --git a/drivers/gpu/drm/i915/gvt/display.h b/drivers/gpu/drm/i915/gvt/display.h index 5d929bb..e0a85df 100644 --- a/drivers/gpu/drm/i915/gvt/display.h +++ b/drivers/gpu/drm/i915/gvt/display.h @@ -187,12 +187,13 @@ static inline char *vgpu_edid_str(enum intel_vgpu_edid id) } void intel_gvt_emulate_vblank(struct intel_gvt *gvt); -void intel_gvt_check_vblank_emulation(struct intel_gvt *gvt); +void intel_gvt_check_vblank_emulation(struct intel_gvt *gvt, bool use_hw_vblank); int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 resolution); void intel_vgpu_reset_display(struct intel_vgpu *vgpu); void intel_vgpu_clean_display(struct intel_vgpu *vgpu); +void emulate_vblank_on_pipe(struct intel_vgpu *vgpu, int pipe); int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe); diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c index 733a2a0..a017ac4 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.c +++ b/drivers/gpu/drm/i915/gvt/gvt.c @@ -250,6 +250,94 @@ static void init_device_info(struct intel_gvt *gvt) info->msi_cap_offset = pdev->msi_cap; } +static int emulate_crtc_a_vblank_thread(void *data) +{ + struct intel_gvt *gvt = (struct intel_gvt *)data; + struct drm_device *dev = &gvt->dev_priv->drm; + struct intel_vgpu *vgpu; + struct completion vblank_done = gvt->vblank_done[PIPE_A]; + int ret; + int id; + + DRM_DEBUG_KMS("vblank service thread a start\n"); + + while (!kthread_should_stop()) { + init_completion(&vblank_done); +retry: + ret = intel_gvt_register_HW_vblank_event(dev, &vblank_done, PIPE_A); + if (ret) { + goto retry; + } + + /* wait for the complete */ + wait_for_completion_interruptible(&vblank_done); + + /* inject the vblank to gvt */ + for_each_active_vgpu(gvt, vgpu, id) + emulate_vblank_on_pipe(vgpu, PIPE_A); + } + + return 0; +} + +static int emulate_crtc_b_vblank_thread(void *data) +{ + struct intel_gvt *gvt = (struct intel_gvt *)data; + struct drm_device *dev = &gvt->dev_priv->drm; + struct intel_vgpu *vgpu; + struct completion vblank_done = gvt->vblank_done[PIPE_B]; + int ret; + int id; + + DRM_DEBUG_KMS("vblank service thread b start\n"); + + while (!kthread_should_stop()) { + init_completion(&vblank_done); +retry: + ret = intel_gvt_register_HW_vblank_event(dev, &vblank_done, PIPE_B); + if (ret) + goto retry; + + /* wait for the complete */ + wait_for_completion_interruptible(&vblank_done); + + /* inject the vblank to gvt */ + for_each_active_vgpu(gvt, vgpu, id) + emulate_vblank_on_pipe(vgpu, PIPE_B); + } + + return 0; +} + +static int emulate_crtc_c_vblank_thread(void *data) +{ + struct intel_gvt *gvt = (struct intel_gvt *)data; + struct drm_device *dev = &gvt->dev_priv->drm; + struct intel_vgpu *vgpu; + struct completion vblank_done = gvt->vblank_done[PIPE_C]; + int ret; + int id; + + DRM_DEBUG_KMS("vblank service thread c start\n"); + + while (!kthread_should_stop()) { + init_completion(&vblank_done); +retry: + ret = intel_gvt_register_HW_vblank_event(dev, &vblank_done, PIPE_C); + if (ret) + goto retry; + + /* wait for the complete */ + wait_for_completion_interruptible(&vblank_done); + + /* inject the vblank to gvt */ + for_each_active_vgpu(gvt, vgpu, id) + emulate_vblank_on_pipe(vgpu, PIPE_C); + } + + return 0; +} + static int gvt_service_thread(void *data) { struct intel_gvt *gvt = (struct intel_gvt *)data; @@ -285,6 +373,9 @@ static int gvt_service_thread(void *data) static void clean_service_thread(struct intel_gvt *gvt) { kthread_stop(gvt->service_thread); + kthread_stop(gvt->vblank_thread[PIPE_A]); + kthread_stop(gvt->vblank_thread[PIPE_B]); + kthread_stop(gvt->vblank_thread[PIPE_C]); } static int init_service_thread(struct intel_gvt *gvt) @@ -297,6 +388,27 @@ static int init_service_thread(struct intel_gvt *gvt) gvt_err("fail to start service thread.\n"); return PTR_ERR(gvt->service_thread); } + + gvt->vblank_thread[PIPE_A] = kthread_create(emulate_crtc_a_vblank_thread, + gvt, "emulate_crtc_a_vblank_thread"); + if (IS_ERR(gvt->vblank_thread[PIPE_A])) { + gvt_err("fail to start service thread.\n"); + return PTR_ERR(gvt->vblank_thread[PIPE_A]); + } + + gvt->vblank_thread[PIPE_B] = kthread_create(emulate_crtc_b_vblank_thread, + gvt, "emulate_crtc_b_vblank_thread"); + if (IS_ERR(gvt->vblank_thread[PIPE_B])) { + gvt_err("fail to start service thread.\n"); + return PTR_ERR(gvt->vblank_thread[PIPE_B]); + } + + gvt->vblank_thread[PIPE_C] = kthread_create(emulate_crtc_c_vblank_thread, + gvt, "emulate_crtc_c_vblank_thread"); + if (IS_ERR(gvt->vblank_thread[PIPE_C])) { + gvt_err("fail to start service thread.\n"); + return PTR_ERR(gvt->vblank_thread[PIPE_C]); + } return 0; } diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 0ab10b0..96903d2 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -356,6 +356,9 @@ struct intel_gvt { /* vGPU plane assignment */ struct assigned_plane assigned_plane[I915_MAX_PIPES][I915_MAX_PLANES]; + + struct task_struct *vblank_thread[I915_MAX_PIPES]; + struct completion vblank_done[I915_MAX_PIPES]; }; static inline struct intel_gvt *to_gvt(struct drm_i915_private *i915) diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 89a22a5..4ad6611 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -449,10 +449,12 @@ static int pipeconf_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, vgpu_vreg(vgpu, offset) |= I965_PIPECONF_ACTIVE; else vgpu_vreg(vgpu, offset) &= ~I965_PIPECONF_ACTIVE; + /* vgpu_lock already hold by emulate mmio r/w */ mutex_unlock(&vgpu->vgpu_lock); - intel_gvt_check_vblank_emulation(vgpu->gvt); + intel_gvt_check_vblank_emulation(vgpu->gvt, true); mutex_lock(&vgpu->vgpu_lock); + return 0; } diff --git a/drivers/gpu/drm/i915/gvt/interrupt.c b/drivers/gpu/drm/i915/gvt/interrupt.c index 5daa23a..cb92ce4 100644 --- a/drivers/gpu/drm/i915/gvt/interrupt.c +++ b/drivers/gpu/drm/i915/gvt/interrupt.c @@ -633,6 +633,60 @@ void intel_vgpu_trigger_virtual_event(struct intel_vgpu *vgpu, ops->check_pending_irq(vgpu); } +static void release_vblank_event(struct completion *completion) +{ + ; +} + +int intel_gvt_register_HW_vblank_event(struct drm_device *dev, + struct completion *vblank_done, int pipe) +{ + struct drm_pending_vblank_event *e; + struct drm_crtc *crtc; + unsigned long flags; + int ret; + + DRM_DEBUG_KMS("%s begin with pipe %d, com %p, dev %p", __func__, pipe, vblank_done, dev); + + crtc = drm_crtc_from_index(dev, pipe); + if (!crtc) { + DRM_ERROR("cannot get crtc %d\n", pipe); + ret = -EINVAL; + goto out; + } + + ret = drm_crtc_vblank_get(crtc); + if (ret) { + DRM_DEBUG("crtc %d failed to acquire vblank counter, %d\n", pipe, ret); + goto out; + } + + e = kzalloc(sizeof *e, GFP_KERNEL); + if (!e) { + drm_crtc_vblank_put(crtc); + ret = -ENOMEM; + goto out; + } + + /* create a vblank event */ + e->event.base.type = DRM_EVENT_VBLANK; + e->event.base.length = sizeof(e->event); + e->pipe = pipe; + e->base.completion = vblank_done; + e->base.completion_release = release_vblank_event; + + spin_lock_irqsave(&dev->event_lock, flags); + e->sequence = drm_crtc_accurate_vblank_count(crtc) + 1; + + /* add the event to vblank list */ + list_add_tail(&e->base.link, &dev->vblank_event_list); + spin_unlock_irqrestore(&dev->event_lock, flags); + + DRM_DEBUG_KMS("%s: success \n", __func__); +out: + return ret; +} + static void init_events( struct intel_gvt_irq *irq) { diff --git a/drivers/gpu/drm/i915/gvt/interrupt.h b/drivers/gpu/drm/i915/gvt/interrupt.h index 5313fb1..ed4936e 100644 --- a/drivers/gpu/drm/i915/gvt/interrupt.h +++ b/drivers/gpu/drm/i915/gvt/interrupt.h @@ -213,6 +213,8 @@ struct intel_gvt_irq { int intel_gvt_init_irq(struct intel_gvt *gvt); void intel_gvt_clean_irq(struct intel_gvt *gvt); +int intel_gvt_register_HW_vblank_event(struct drm_device *dev, + struct completion *vblank_done, int pipe); void intel_vgpu_trigger_virtual_event(struct intel_vgpu *vgpu, enum intel_gvt_event_type event);