From patchwork Tue Sep 30 10:05:37 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jike Song X-Patchwork-Id: 5001851 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 1EE419F349 for ; Tue, 30 Sep 2014 10:11:48 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 23AE3201BC for ; Tue, 30 Sep 2014 10:11:47 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 1A3A32017D for ; Tue, 30 Sep 2014 10:11:46 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 583886E88A; Tue, 30 Sep 2014 03:11:45 -0700 (PDT) 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 ESMTP id 535E56EAFE for ; Tue, 30 Sep 2014 03:11:42 -0700 (PDT) Received: from azsmga001.ch.intel.com ([10.2.17.19]) by fmsmga103.fm.intel.com with ESMTP; 30 Sep 2014 03:02:18 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.04,625,1406617200"; d="scan'208";a="480959953" Received: from kvmgt.bj.intel.com ([10.238.154.64]) by azsmga001.ch.intel.com with ESMTP; 30 Sep 2014 03:11:40 -0700 From: Jike Song To: daniel.vetter@ffwll.ch, intel-gfx@lists.freedesktop.org Date: Tue, 30 Sep 2014 18:05:37 +0800 Message-Id: <1412071538-19059-8-git-send-email-jike.song@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1412071538-19059-1-git-send-email-jike.song@intel.com> References: <1412071538-19059-1-git-send-email-jike.song@intel.com> Subject: [Intel-gfx] [RFC PATCH 7/8] drm/i915: vgt irq mediation - via a tasklet based mechanism X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP vgt owns the hardware interrupt of the GPU, to satisfy the interrupt requirement from both host side and guest side (e.g. host may have MI_USER_INTERRUPT disabled, while a VM may have it enabled). Sometimes vgt may also need to emulate a virtual interrupt to the host, w/o a hardware interrupt actually triggered. So we need to split the handling between physical interrupts to vgt and virtual interrupts to host i915. Regarding to above requirements, this patch registers a vgt interrupt handler when vgt is enabled, while letting original i915 interrupt handler instead carried in a tasklet. Whenever a virtual interrupt needs to be injected to host i915, tasklet_schedule gets called. Signed-off-by: Jike Song --- drivers/gpu/drm/i915/i915_drv.h | 6 ++++++ drivers/gpu/drm/i915/i915_irq.c | 35 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_vgt.h | 20 ++++++++++++++++++++ drivers/gpu/drm/i915/vgt/vgt.c | 22 ++++++++++++++++++++++ 4 files changed, 83 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 742fe8a..e33455a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1668,6 +1668,12 @@ struct drm_i915_private { struct vlv_s0ix_state vlv_s0ix_state; struct { + struct tasklet_struct host_irq_task; + irqreturn_t (*host_isr)(int, void *); + void (*host_irq_uninstall)(struct drm_device *); + } igvt; + + struct { /* * Raw watermark latency values: * in 0.1us units for WM0, diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 080981b..df7c868 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -36,6 +36,7 @@ #include "i915_drv.h" #include "i915_trace.h" #include "intel_drv.h" +#include "i915_vgt.h" static const u32 hpd_ibx[] = { [HPD_CRT] = SDE_CRT_HOTPLUG, @@ -4650,6 +4651,30 @@ static void intel_hpd_irq_reenable_work(struct work_struct *work) intel_runtime_pm_put(dev_priv); } +static void vgt_host_isr_wrapper(unsigned long data) +{ + struct drm_device *dev = (struct drm_device *)data; + struct drm_i915_private *dev_priv = dev->dev_private; + + dev_priv->igvt.host_isr(dev->pdev->irq, dev); +} + +void vgt_schedule_host_isr(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + tasklet_schedule(&dev_priv->igvt.host_irq_task); +} + +static void vgt_irq_uninstall(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + tasklet_kill(&dev_priv->igvt.host_irq_task); + dev_priv->igvt.host_irq_uninstall(dev); + vgt_fini_irq(dev->pdev); +} + void intel_irq_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -4756,6 +4781,16 @@ void intel_irq_init(struct drm_device *dev) dev->driver->enable_vblank = i915_enable_vblank; dev->driver->disable_vblank = i915_disable_vblank; } + + if (i915.enable_vgt) { + vgt_init_irq(dev->pdev, dev); + dev_priv->igvt.host_isr = dev->driver->irq_handler; + dev->driver->irq_handler = vgt_interrupt; + dev_priv->igvt.host_irq_uninstall = dev->driver->irq_uninstall; + dev->driver->irq_uninstall = vgt_irq_uninstall; + tasklet_init(&dev_priv->igvt.host_irq_task, + vgt_host_isr_wrapper, (unsigned long)dev); + } } void intel_hpd_init(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/i915_vgt.h b/drivers/gpu/drm/i915/i915_vgt.h index 03e7f00..553f920 100644 --- a/drivers/gpu/drm/i915/i915_vgt.h +++ b/drivers/gpu/drm/i915/i915_vgt.h @@ -1,6 +1,9 @@ #ifndef _I915_VGT_H_ #define _I915_VGT_H_ +#include + +struct drm_device; struct drm_i915_private; #ifdef CONFIG_I915_IGVT @@ -9,6 +12,10 @@ bool i915_start_vgt(struct pci_dev *); void i915_vgt_record_priv(struct drm_i915_private *); bool vgt_emulate_host_read(u32, void *, int, bool, bool); bool vgt_emulate_host_write(u32, void *, int, bool, bool); +void vgt_schedule_host_isr(struct drm_device *); +void vgt_init_irq(struct pci_dev *, struct drm_device *); +void vgt_fini_irq(struct pci_dev *); +irqreturn_t vgt_interrupt(int, void *); #else /* !CONFIG_I915_IGVT */ @@ -33,6 +40,19 @@ static inline bool vgt_emulate_host_write(u32 reg, void *val, int len, return false; } +static inline void vgt_init_irq(struct pci_dev *pdev, struct drm_device *dev) +{ +} + +static inline void vgt_fini_irq(struct pci_dev *pdev) +{ +} + +static inline irqreturn_t vgt_interrupt(int irq, void *data) +{ + return IRQ_NONE; +} + #endif /* CONFIG_I915_IGVT */ #endif diff --git a/drivers/gpu/drm/i915/vgt/vgt.c b/drivers/gpu/drm/i915/vgt/vgt.c index f33baf3..dab4bfc 100644 --- a/drivers/gpu/drm/i915/vgt/vgt.c +++ b/drivers/gpu/drm/i915/vgt/vgt.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "../i915_drv.h" #include "vgt.h" @@ -121,3 +122,24 @@ void i915_vgt_record_priv(struct drm_i915_private *priv) { dev_priv = priv; } + +static void vgt_host_irq(struct drm_device *dev) +{ + vgt_schedule_host_isr(dev); +} + +void vgt_init_irq(struct pci_dev *pdev, struct drm_device *dev) +{ + /* TODO: initialize vgt-specific irq handlings after vgt integration */ +} + +void vgt_fini_irq(struct pci_dev *pdev) +{ + /* TODO: cleanup vgt-specific irq handlings after vgt integration */ +} + +irqreturn_t vgt_interrupt(int irq, void *data) +{ + vgt_host_irq(data); + return IRQ_HANDLED; +}