Home | History | Annotate | Line # | Download | only in gvt
      1  1.1  riastrad /*	$NetBSD: interrupt.c,v 1.2 2021/12/18 23:45:31 riastradh Exp $	*/
      2  1.1  riastrad 
      3  1.1  riastrad /*
      4  1.1  riastrad  * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
      5  1.1  riastrad  *
      6  1.1  riastrad  * Permission is hereby granted, free of charge, to any person obtaining a
      7  1.1  riastrad  * copy of this software and associated documentation files (the "Software"),
      8  1.1  riastrad  * to deal in the Software without restriction, including without limitation
      9  1.1  riastrad  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  1.1  riastrad  * and/or sell copies of the Software, and to permit persons to whom the
     11  1.1  riastrad  * Software is furnished to do so, subject to the following conditions:
     12  1.1  riastrad  *
     13  1.1  riastrad  * The above copyright notice and this permission notice (including the next
     14  1.1  riastrad  * paragraph) shall be included in all copies or substantial portions of the
     15  1.1  riastrad  * Software.
     16  1.1  riastrad  *
     17  1.1  riastrad  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  1.1  riastrad  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  1.1  riastrad  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  1.1  riastrad  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  1.1  riastrad  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     22  1.1  riastrad  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     23  1.1  riastrad  * SOFTWARE.
     24  1.1  riastrad  *
     25  1.1  riastrad  * Authors:
     26  1.1  riastrad  *    Kevin Tian <kevin.tian (at) intel.com>
     27  1.1  riastrad  *    Zhi Wang <zhi.a.wang (at) intel.com>
     28  1.1  riastrad  *
     29  1.1  riastrad  * Contributors:
     30  1.1  riastrad  *    Min he <min.he (at) intel.com>
     31  1.1  riastrad  *
     32  1.1  riastrad  */
     33  1.1  riastrad 
     34  1.1  riastrad #include <sys/cdefs.h>
     35  1.1  riastrad __KERNEL_RCSID(0, "$NetBSD: interrupt.c,v 1.2 2021/12/18 23:45:31 riastradh Exp $");
     36  1.1  riastrad 
     37  1.1  riastrad #include "i915_drv.h"
     38  1.1  riastrad #include "gvt.h"
     39  1.1  riastrad #include "trace.h"
     40  1.1  riastrad 
     41  1.1  riastrad /* common offset among interrupt control registers */
     42  1.1  riastrad #define regbase_to_isr(base)	(base)
     43  1.1  riastrad #define regbase_to_imr(base)	(base + 0x4)
     44  1.1  riastrad #define regbase_to_iir(base)	(base + 0x8)
     45  1.1  riastrad #define regbase_to_ier(base)	(base + 0xC)
     46  1.1  riastrad 
     47  1.1  riastrad #define iir_to_regbase(iir)    (iir - 0x8)
     48  1.1  riastrad #define ier_to_regbase(ier)    (ier - 0xC)
     49  1.1  riastrad 
     50  1.1  riastrad #define get_event_virt_handler(irq, e)	(irq->events[e].v_handler)
     51  1.1  riastrad #define get_irq_info(irq, e)		(irq->events[e].info)
     52  1.1  riastrad 
     53  1.1  riastrad #define irq_to_gvt(irq) \
     54  1.1  riastrad 	container_of(irq, struct intel_gvt, irq)
     55  1.1  riastrad 
     56  1.1  riastrad static void update_upstream_irq(struct intel_vgpu *vgpu,
     57  1.1  riastrad 		struct intel_gvt_irq_info *info);
     58  1.1  riastrad 
     59  1.1  riastrad static const char * const irq_name[INTEL_GVT_EVENT_MAX] = {
     60  1.1  riastrad 	[RCS_MI_USER_INTERRUPT] = "Render CS MI USER INTERRUPT",
     61  1.1  riastrad 	[RCS_DEBUG] = "Render EU debug from SVG",
     62  1.1  riastrad 	[RCS_MMIO_SYNC_FLUSH] = "Render MMIO sync flush status",
     63  1.1  riastrad 	[RCS_CMD_STREAMER_ERR] = "Render CS error interrupt",
     64  1.1  riastrad 	[RCS_PIPE_CONTROL] = "Render PIPE CONTROL notify",
     65  1.1  riastrad 	[RCS_WATCHDOG_EXCEEDED] = "Render CS Watchdog counter exceeded",
     66  1.1  riastrad 	[RCS_PAGE_DIRECTORY_FAULT] = "Render page directory faults",
     67  1.1  riastrad 	[RCS_AS_CONTEXT_SWITCH] = "Render AS Context Switch Interrupt",
     68  1.1  riastrad 
     69  1.1  riastrad 	[VCS_MI_USER_INTERRUPT] = "Video CS MI USER INTERRUPT",
     70  1.1  riastrad 	[VCS_MMIO_SYNC_FLUSH] = "Video MMIO sync flush status",
     71  1.1  riastrad 	[VCS_CMD_STREAMER_ERR] = "Video CS error interrupt",
     72  1.1  riastrad 	[VCS_MI_FLUSH_DW] = "Video MI FLUSH DW notify",
     73  1.1  riastrad 	[VCS_WATCHDOG_EXCEEDED] = "Video CS Watchdog counter exceeded",
     74  1.1  riastrad 	[VCS_PAGE_DIRECTORY_FAULT] = "Video page directory faults",
     75  1.1  riastrad 	[VCS_AS_CONTEXT_SWITCH] = "Video AS Context Switch Interrupt",
     76  1.1  riastrad 	[VCS2_MI_USER_INTERRUPT] = "VCS2 Video CS MI USER INTERRUPT",
     77  1.1  riastrad 	[VCS2_MI_FLUSH_DW] = "VCS2 Video MI FLUSH DW notify",
     78  1.1  riastrad 	[VCS2_AS_CONTEXT_SWITCH] = "VCS2 Context Switch Interrupt",
     79  1.1  riastrad 
     80  1.1  riastrad 	[BCS_MI_USER_INTERRUPT] = "Blitter CS MI USER INTERRUPT",
     81  1.1  riastrad 	[BCS_MMIO_SYNC_FLUSH] = "Billter MMIO sync flush status",
     82  1.1  riastrad 	[BCS_CMD_STREAMER_ERR] = "Blitter CS error interrupt",
     83  1.1  riastrad 	[BCS_MI_FLUSH_DW] = "Blitter MI FLUSH DW notify",
     84  1.1  riastrad 	[BCS_PAGE_DIRECTORY_FAULT] = "Blitter page directory faults",
     85  1.1  riastrad 	[BCS_AS_CONTEXT_SWITCH] = "Blitter AS Context Switch Interrupt",
     86  1.1  riastrad 
     87  1.1  riastrad 	[VECS_MI_FLUSH_DW] = "Video Enhanced Streamer MI FLUSH DW notify",
     88  1.1  riastrad 	[VECS_AS_CONTEXT_SWITCH] = "VECS Context Switch Interrupt",
     89  1.1  riastrad 
     90  1.1  riastrad 	[PIPE_A_FIFO_UNDERRUN] = "Pipe A FIFO underrun",
     91  1.1  riastrad 	[PIPE_A_CRC_ERR] = "Pipe A CRC error",
     92  1.1  riastrad 	[PIPE_A_CRC_DONE] = "Pipe A CRC done",
     93  1.1  riastrad 	[PIPE_A_VSYNC] = "Pipe A vsync",
     94  1.1  riastrad 	[PIPE_A_LINE_COMPARE] = "Pipe A line compare",
     95  1.1  riastrad 	[PIPE_A_ODD_FIELD] = "Pipe A odd field",
     96  1.1  riastrad 	[PIPE_A_EVEN_FIELD] = "Pipe A even field",
     97  1.1  riastrad 	[PIPE_A_VBLANK] = "Pipe A vblank",
     98  1.1  riastrad 	[PIPE_B_FIFO_UNDERRUN] = "Pipe B FIFO underrun",
     99  1.1  riastrad 	[PIPE_B_CRC_ERR] = "Pipe B CRC error",
    100  1.1  riastrad 	[PIPE_B_CRC_DONE] = "Pipe B CRC done",
    101  1.1  riastrad 	[PIPE_B_VSYNC] = "Pipe B vsync",
    102  1.1  riastrad 	[PIPE_B_LINE_COMPARE] = "Pipe B line compare",
    103  1.1  riastrad 	[PIPE_B_ODD_FIELD] = "Pipe B odd field",
    104  1.1  riastrad 	[PIPE_B_EVEN_FIELD] = "Pipe B even field",
    105  1.1  riastrad 	[PIPE_B_VBLANK] = "Pipe B vblank",
    106  1.1  riastrad 	[PIPE_C_VBLANK] = "Pipe C vblank",
    107  1.1  riastrad 	[DPST_PHASE_IN] = "DPST phase in event",
    108  1.1  riastrad 	[DPST_HISTOGRAM] = "DPST histogram event",
    109  1.1  riastrad 	[GSE] = "GSE",
    110  1.1  riastrad 	[DP_A_HOTPLUG] = "DP A Hotplug",
    111  1.1  riastrad 	[AUX_CHANNEL_A] = "AUX Channel A",
    112  1.1  riastrad 	[PERF_COUNTER] = "Performance counter",
    113  1.1  riastrad 	[POISON] = "Poison",
    114  1.1  riastrad 	[GTT_FAULT] = "GTT fault",
    115  1.1  riastrad 	[PRIMARY_A_FLIP_DONE] = "Primary Plane A flip done",
    116  1.1  riastrad 	[PRIMARY_B_FLIP_DONE] = "Primary Plane B flip done",
    117  1.1  riastrad 	[PRIMARY_C_FLIP_DONE] = "Primary Plane C flip done",
    118  1.1  riastrad 	[SPRITE_A_FLIP_DONE] = "Sprite Plane A flip done",
    119  1.1  riastrad 	[SPRITE_B_FLIP_DONE] = "Sprite Plane B flip done",
    120  1.1  riastrad 	[SPRITE_C_FLIP_DONE] = "Sprite Plane C flip done",
    121  1.1  riastrad 
    122  1.1  riastrad 	[PCU_THERMAL] = "PCU Thermal Event",
    123  1.1  riastrad 	[PCU_PCODE2DRIVER_MAILBOX] = "PCU pcode2driver mailbox event",
    124  1.1  riastrad 
    125  1.1  riastrad 	[FDI_RX_INTERRUPTS_TRANSCODER_A] = "FDI RX Interrupts Combined A",
    126  1.1  riastrad 	[AUDIO_CP_CHANGE_TRANSCODER_A] = "Audio CP Change Transcoder A",
    127  1.1  riastrad 	[AUDIO_CP_REQUEST_TRANSCODER_A] = "Audio CP Request Transcoder A",
    128  1.1  riastrad 	[FDI_RX_INTERRUPTS_TRANSCODER_B] = "FDI RX Interrupts Combined B",
    129  1.1  riastrad 	[AUDIO_CP_CHANGE_TRANSCODER_B] = "Audio CP Change Transcoder B",
    130  1.1  riastrad 	[AUDIO_CP_REQUEST_TRANSCODER_B] = "Audio CP Request Transcoder B",
    131  1.1  riastrad 	[FDI_RX_INTERRUPTS_TRANSCODER_C] = "FDI RX Interrupts Combined C",
    132  1.1  riastrad 	[AUDIO_CP_CHANGE_TRANSCODER_C] = "Audio CP Change Transcoder C",
    133  1.1  riastrad 	[AUDIO_CP_REQUEST_TRANSCODER_C] = "Audio CP Request Transcoder C",
    134  1.1  riastrad 	[ERR_AND_DBG] = "South Error and Debug Interrupts Combined",
    135  1.1  riastrad 	[GMBUS] = "Gmbus",
    136  1.1  riastrad 	[SDVO_B_HOTPLUG] = "SDVO B hotplug",
    137  1.1  riastrad 	[CRT_HOTPLUG] = "CRT Hotplug",
    138  1.1  riastrad 	[DP_B_HOTPLUG] = "DisplayPort/HDMI/DVI B Hotplug",
    139  1.1  riastrad 	[DP_C_HOTPLUG] = "DisplayPort/HDMI/DVI C Hotplug",
    140  1.1  riastrad 	[DP_D_HOTPLUG] = "DisplayPort/HDMI/DVI D Hotplug",
    141  1.1  riastrad 	[AUX_CHANNEL_B] = "AUX Channel B",
    142  1.1  riastrad 	[AUX_CHANNEL_C] = "AUX Channel C",
    143  1.1  riastrad 	[AUX_CHANNEL_D] = "AUX Channel D",
    144  1.1  riastrad 	[AUDIO_POWER_STATE_CHANGE_B] = "Audio Power State change Port B",
    145  1.1  riastrad 	[AUDIO_POWER_STATE_CHANGE_C] = "Audio Power State change Port C",
    146  1.1  riastrad 	[AUDIO_POWER_STATE_CHANGE_D] = "Audio Power State change Port D",
    147  1.1  riastrad 
    148  1.1  riastrad 	[INTEL_GVT_EVENT_RESERVED] = "RESERVED EVENTS!!!",
    149  1.1  riastrad };
    150  1.1  riastrad 
    151  1.1  riastrad static inline struct intel_gvt_irq_info *regbase_to_irq_info(
    152  1.1  riastrad 		struct intel_gvt *gvt,
    153  1.1  riastrad 		unsigned int reg)
    154  1.1  riastrad {
    155  1.1  riastrad 	struct intel_gvt_irq *irq = &gvt->irq;
    156  1.1  riastrad 	int i;
    157  1.1  riastrad 
    158  1.1  riastrad 	for_each_set_bit(i, irq->irq_info_bitmap, INTEL_GVT_IRQ_INFO_MAX) {
    159  1.1  riastrad 		if (i915_mmio_reg_offset(irq->info[i]->reg_base) == reg)
    160  1.1  riastrad 			return irq->info[i];
    161  1.1  riastrad 	}
    162  1.1  riastrad 
    163  1.1  riastrad 	return NULL;
    164  1.1  riastrad }
    165  1.1  riastrad 
    166  1.1  riastrad /**
    167  1.1  riastrad  * intel_vgpu_reg_imr_handler - Generic IMR register emulation write handler
    168  1.1  riastrad  * @vgpu: a vGPU
    169  1.1  riastrad  * @reg: register offset written by guest
    170  1.1  riastrad  * @p_data: register data written by guest
    171  1.1  riastrad  * @bytes: register data length
    172  1.1  riastrad  *
    173  1.1  riastrad  * This function is used to emulate the generic IMR register bit change
    174  1.1  riastrad  * behavior.
    175  1.1  riastrad  *
    176  1.1  riastrad  * Returns:
    177  1.1  riastrad  * Zero on success, negative error code if failed.
    178  1.1  riastrad  *
    179  1.1  riastrad  */
    180  1.1  riastrad int intel_vgpu_reg_imr_handler(struct intel_vgpu *vgpu,
    181  1.1  riastrad 	unsigned int reg, void *p_data, unsigned int bytes)
    182  1.1  riastrad {
    183  1.1  riastrad 	struct intel_gvt *gvt = vgpu->gvt;
    184  1.1  riastrad 	struct intel_gvt_irq_ops *ops = gvt->irq.ops;
    185  1.1  riastrad 	u32 imr = *(u32 *)p_data;
    186  1.1  riastrad 
    187  1.1  riastrad 	trace_write_ir(vgpu->id, "IMR", reg, imr, vgpu_vreg(vgpu, reg),
    188  1.1  riastrad 		       (vgpu_vreg(vgpu, reg) ^ imr));
    189  1.1  riastrad 
    190  1.1  riastrad 	vgpu_vreg(vgpu, reg) = imr;
    191  1.1  riastrad 
    192  1.1  riastrad 	ops->check_pending_irq(vgpu);
    193  1.1  riastrad 
    194  1.1  riastrad 	return 0;
    195  1.1  riastrad }
    196  1.1  riastrad 
    197  1.1  riastrad /**
    198  1.1  riastrad  * intel_vgpu_reg_master_irq_handler - master IRQ write emulation handler
    199  1.1  riastrad  * @vgpu: a vGPU
    200  1.1  riastrad  * @reg: register offset written by guest
    201  1.1  riastrad  * @p_data: register data written by guest
    202  1.1  riastrad  * @bytes: register data length
    203  1.1  riastrad  *
    204  1.1  riastrad  * This function is used to emulate the master IRQ register on gen8+.
    205  1.1  riastrad  *
    206  1.1  riastrad  * Returns:
    207  1.1  riastrad  * Zero on success, negative error code if failed.
    208  1.1  riastrad  *
    209  1.1  riastrad  */
    210  1.1  riastrad int intel_vgpu_reg_master_irq_handler(struct intel_vgpu *vgpu,
    211  1.1  riastrad 	unsigned int reg, void *p_data, unsigned int bytes)
    212  1.1  riastrad {
    213  1.1  riastrad 	struct intel_gvt *gvt = vgpu->gvt;
    214  1.1  riastrad 	struct intel_gvt_irq_ops *ops = gvt->irq.ops;
    215  1.1  riastrad 	u32 ier = *(u32 *)p_data;
    216  1.1  riastrad 	u32 virtual_ier = vgpu_vreg(vgpu, reg);
    217  1.1  riastrad 
    218  1.1  riastrad 	trace_write_ir(vgpu->id, "MASTER_IRQ", reg, ier, virtual_ier,
    219  1.1  riastrad 		       (virtual_ier ^ ier));
    220  1.1  riastrad 
    221  1.1  riastrad 	/*
    222  1.1  riastrad 	 * GEN8_MASTER_IRQ is a special irq register,
    223  1.1  riastrad 	 * only bit 31 is allowed to be modified
    224  1.1  riastrad 	 * and treated as an IER bit.
    225  1.1  riastrad 	 */
    226  1.1  riastrad 	ier &= GEN8_MASTER_IRQ_CONTROL;
    227  1.1  riastrad 	virtual_ier &= GEN8_MASTER_IRQ_CONTROL;
    228  1.1  riastrad 	vgpu_vreg(vgpu, reg) &= ~GEN8_MASTER_IRQ_CONTROL;
    229  1.1  riastrad 	vgpu_vreg(vgpu, reg) |= ier;
    230  1.1  riastrad 
    231  1.1  riastrad 	ops->check_pending_irq(vgpu);
    232  1.1  riastrad 
    233  1.1  riastrad 	return 0;
    234  1.1  riastrad }
    235  1.1  riastrad 
    236  1.1  riastrad /**
    237  1.1  riastrad  * intel_vgpu_reg_ier_handler - Generic IER write emulation handler
    238  1.1  riastrad  * @vgpu: a vGPU
    239  1.1  riastrad  * @reg: register offset written by guest
    240  1.1  riastrad  * @p_data: register data written by guest
    241  1.1  riastrad  * @bytes: register data length
    242  1.1  riastrad  *
    243  1.1  riastrad  * This function is used to emulate the generic IER register behavior.
    244  1.1  riastrad  *
    245  1.1  riastrad  * Returns:
    246  1.1  riastrad  * Zero on success, negative error code if failed.
    247  1.1  riastrad  *
    248  1.1  riastrad  */
    249  1.1  riastrad int intel_vgpu_reg_ier_handler(struct intel_vgpu *vgpu,
    250  1.1  riastrad 	unsigned int reg, void *p_data, unsigned int bytes)
    251  1.1  riastrad {
    252  1.1  riastrad 	struct intel_gvt *gvt = vgpu->gvt;
    253  1.1  riastrad 	struct intel_gvt_irq_ops *ops = gvt->irq.ops;
    254  1.1  riastrad 	struct intel_gvt_irq_info *info;
    255  1.1  riastrad 	u32 ier = *(u32 *)p_data;
    256  1.1  riastrad 
    257  1.1  riastrad 	trace_write_ir(vgpu->id, "IER", reg, ier, vgpu_vreg(vgpu, reg),
    258  1.1  riastrad 		       (vgpu_vreg(vgpu, reg) ^ ier));
    259  1.1  riastrad 
    260  1.1  riastrad 	vgpu_vreg(vgpu, reg) = ier;
    261  1.1  riastrad 
    262  1.1  riastrad 	info = regbase_to_irq_info(gvt, ier_to_regbase(reg));
    263  1.1  riastrad 	if (WARN_ON(!info))
    264  1.1  riastrad 		return -EINVAL;
    265  1.1  riastrad 
    266  1.1  riastrad 	if (info->has_upstream_irq)
    267  1.1  riastrad 		update_upstream_irq(vgpu, info);
    268  1.1  riastrad 
    269  1.1  riastrad 	ops->check_pending_irq(vgpu);
    270  1.1  riastrad 
    271  1.1  riastrad 	return 0;
    272  1.1  riastrad }
    273  1.1  riastrad 
    274  1.1  riastrad /**
    275  1.1  riastrad  * intel_vgpu_reg_iir_handler - Generic IIR write emulation handler
    276  1.1  riastrad  * @vgpu: a vGPU
    277  1.1  riastrad  * @reg: register offset written by guest
    278  1.1  riastrad  * @p_data: register data written by guest
    279  1.1  riastrad  * @bytes: register data length
    280  1.1  riastrad  *
    281  1.1  riastrad  * This function is used to emulate the generic IIR register behavior.
    282  1.1  riastrad  *
    283  1.1  riastrad  * Returns:
    284  1.1  riastrad  * Zero on success, negative error code if failed.
    285  1.1  riastrad  *
    286  1.1  riastrad  */
    287  1.1  riastrad int intel_vgpu_reg_iir_handler(struct intel_vgpu *vgpu, unsigned int reg,
    288  1.1  riastrad 	void *p_data, unsigned int bytes)
    289  1.1  riastrad {
    290  1.1  riastrad 	struct intel_gvt_irq_info *info = regbase_to_irq_info(vgpu->gvt,
    291  1.1  riastrad 		iir_to_regbase(reg));
    292  1.1  riastrad 	u32 iir = *(u32 *)p_data;
    293  1.1  riastrad 
    294  1.1  riastrad 	trace_write_ir(vgpu->id, "IIR", reg, iir, vgpu_vreg(vgpu, reg),
    295  1.1  riastrad 		       (vgpu_vreg(vgpu, reg) ^ iir));
    296  1.1  riastrad 
    297  1.1  riastrad 	if (WARN_ON(!info))
    298  1.1  riastrad 		return -EINVAL;
    299  1.1  riastrad 
    300  1.1  riastrad 	vgpu_vreg(vgpu, reg) &= ~iir;
    301  1.1  riastrad 
    302  1.1  riastrad 	if (info->has_upstream_irq)
    303  1.1  riastrad 		update_upstream_irq(vgpu, info);
    304  1.1  riastrad 	return 0;
    305  1.1  riastrad }
    306  1.1  riastrad 
    307  1.1  riastrad static struct intel_gvt_irq_map gen8_irq_map[] = {
    308  1.1  riastrad 	{ INTEL_GVT_IRQ_INFO_MASTER, 0, INTEL_GVT_IRQ_INFO_GT0, 0xffff },
    309  1.1  riastrad 	{ INTEL_GVT_IRQ_INFO_MASTER, 1, INTEL_GVT_IRQ_INFO_GT0, 0xffff0000 },
    310  1.1  riastrad 	{ INTEL_GVT_IRQ_INFO_MASTER, 2, INTEL_GVT_IRQ_INFO_GT1, 0xffff },
    311  1.1  riastrad 	{ INTEL_GVT_IRQ_INFO_MASTER, 3, INTEL_GVT_IRQ_INFO_GT1, 0xffff0000 },
    312  1.1  riastrad 	{ INTEL_GVT_IRQ_INFO_MASTER, 4, INTEL_GVT_IRQ_INFO_GT2, 0xffff },
    313  1.1  riastrad 	{ INTEL_GVT_IRQ_INFO_MASTER, 6, INTEL_GVT_IRQ_INFO_GT3, 0xffff },
    314  1.1  riastrad 	{ INTEL_GVT_IRQ_INFO_MASTER, 16, INTEL_GVT_IRQ_INFO_DE_PIPE_A, ~0 },
    315  1.1  riastrad 	{ INTEL_GVT_IRQ_INFO_MASTER, 17, INTEL_GVT_IRQ_INFO_DE_PIPE_B, ~0 },
    316  1.1  riastrad 	{ INTEL_GVT_IRQ_INFO_MASTER, 18, INTEL_GVT_IRQ_INFO_DE_PIPE_C, ~0 },
    317  1.1  riastrad 	{ INTEL_GVT_IRQ_INFO_MASTER, 20, INTEL_GVT_IRQ_INFO_DE_PORT, ~0 },
    318  1.1  riastrad 	{ INTEL_GVT_IRQ_INFO_MASTER, 22, INTEL_GVT_IRQ_INFO_DE_MISC, ~0 },
    319  1.1  riastrad 	{ INTEL_GVT_IRQ_INFO_MASTER, 23, INTEL_GVT_IRQ_INFO_PCH, ~0 },
    320  1.1  riastrad 	{ INTEL_GVT_IRQ_INFO_MASTER, 30, INTEL_GVT_IRQ_INFO_PCU, ~0 },
    321  1.1  riastrad 	{ -1, -1, ~0 },
    322  1.1  riastrad };
    323  1.1  riastrad 
    324  1.1  riastrad static void update_upstream_irq(struct intel_vgpu *vgpu,
    325  1.1  riastrad 		struct intel_gvt_irq_info *info)
    326  1.1  riastrad {
    327  1.1  riastrad 	struct intel_gvt_irq *irq = &vgpu->gvt->irq;
    328  1.1  riastrad 	struct intel_gvt_irq_map *map = irq->irq_map;
    329  1.1  riastrad 	struct intel_gvt_irq_info *up_irq_info = NULL;
    330  1.1  riastrad 	u32 set_bits = 0;
    331  1.1  riastrad 	u32 clear_bits = 0;
    332  1.1  riastrad 	int bit;
    333  1.1  riastrad 	u32 val = vgpu_vreg(vgpu,
    334  1.1  riastrad 			regbase_to_iir(i915_mmio_reg_offset(info->reg_base)))
    335  1.1  riastrad 		& vgpu_vreg(vgpu,
    336  1.1  riastrad 			regbase_to_ier(i915_mmio_reg_offset(info->reg_base)));
    337  1.1  riastrad 
    338  1.1  riastrad 	if (!info->has_upstream_irq)
    339  1.1  riastrad 		return;
    340  1.1  riastrad 
    341  1.1  riastrad 	for (map = irq->irq_map; map->up_irq_bit != -1; map++) {
    342  1.1  riastrad 		if (info->group != map->down_irq_group)
    343  1.1  riastrad 			continue;
    344  1.1  riastrad 
    345  1.1  riastrad 		if (!up_irq_info)
    346  1.1  riastrad 			up_irq_info = irq->info[map->up_irq_group];
    347  1.1  riastrad 		else
    348  1.1  riastrad 			WARN_ON(up_irq_info != irq->info[map->up_irq_group]);
    349  1.1  riastrad 
    350  1.1  riastrad 		bit = map->up_irq_bit;
    351  1.1  riastrad 
    352  1.1  riastrad 		if (val & map->down_irq_bitmask)
    353  1.1  riastrad 			set_bits |= (1 << bit);
    354  1.1  riastrad 		else
    355  1.1  riastrad 			clear_bits |= (1 << bit);
    356  1.1  riastrad 	}
    357  1.1  riastrad 
    358  1.1  riastrad 	if (WARN_ON(!up_irq_info))
    359  1.1  riastrad 		return;
    360  1.1  riastrad 
    361  1.1  riastrad 	if (up_irq_info->group == INTEL_GVT_IRQ_INFO_MASTER) {
    362  1.1  riastrad 		u32 isr = i915_mmio_reg_offset(up_irq_info->reg_base);
    363  1.1  riastrad 
    364  1.1  riastrad 		vgpu_vreg(vgpu, isr) &= ~clear_bits;
    365  1.1  riastrad 		vgpu_vreg(vgpu, isr) |= set_bits;
    366  1.1  riastrad 	} else {
    367  1.1  riastrad 		u32 iir = regbase_to_iir(
    368  1.1  riastrad 			i915_mmio_reg_offset(up_irq_info->reg_base));
    369  1.1  riastrad 		u32 imr = regbase_to_imr(
    370  1.1  riastrad 			i915_mmio_reg_offset(up_irq_info->reg_base));
    371  1.1  riastrad 
    372  1.1  riastrad 		vgpu_vreg(vgpu, iir) |= (set_bits & ~vgpu_vreg(vgpu, imr));
    373  1.1  riastrad 	}
    374  1.1  riastrad 
    375  1.1  riastrad 	if (up_irq_info->has_upstream_irq)
    376  1.1  riastrad 		update_upstream_irq(vgpu, up_irq_info);
    377  1.1  riastrad }
    378  1.1  riastrad 
    379  1.1  riastrad static void init_irq_map(struct intel_gvt_irq *irq)
    380  1.1  riastrad {
    381  1.1  riastrad 	struct intel_gvt_irq_map *map;
    382  1.1  riastrad 	struct intel_gvt_irq_info *up_info, *down_info;
    383  1.1  riastrad 	int up_bit;
    384  1.1  riastrad 
    385  1.1  riastrad 	for (map = irq->irq_map; map->up_irq_bit != -1; map++) {
    386  1.1  riastrad 		up_info = irq->info[map->up_irq_group];
    387  1.1  riastrad 		up_bit = map->up_irq_bit;
    388  1.1  riastrad 		down_info = irq->info[map->down_irq_group];
    389  1.1  riastrad 
    390  1.1  riastrad 		set_bit(up_bit, up_info->downstream_irq_bitmap);
    391  1.1  riastrad 		down_info->has_upstream_irq = true;
    392  1.1  riastrad 
    393  1.1  riastrad 		gvt_dbg_irq("[up] grp %d bit %d -> [down] grp %d bitmask %x\n",
    394  1.1  riastrad 			up_info->group, up_bit,
    395  1.1  riastrad 			down_info->group, map->down_irq_bitmask);
    396  1.1  riastrad 	}
    397  1.1  riastrad }
    398  1.1  riastrad 
    399  1.1  riastrad /* =======================vEvent injection===================== */
    400  1.1  riastrad static int inject_virtual_interrupt(struct intel_vgpu *vgpu)
    401  1.1  riastrad {
    402  1.1  riastrad 	return intel_gvt_hypervisor_inject_msi(vgpu);
    403  1.1  riastrad }
    404  1.1  riastrad 
    405  1.1  riastrad static void propagate_event(struct intel_gvt_irq *irq,
    406  1.1  riastrad 	enum intel_gvt_event_type event, struct intel_vgpu *vgpu)
    407  1.1  riastrad {
    408  1.1  riastrad 	struct intel_gvt_irq_info *info;
    409  1.1  riastrad 	unsigned int reg_base;
    410  1.1  riastrad 	int bit;
    411  1.1  riastrad 
    412  1.1  riastrad 	info = get_irq_info(irq, event);
    413  1.1  riastrad 	if (WARN_ON(!info))
    414  1.1  riastrad 		return;
    415  1.1  riastrad 
    416  1.1  riastrad 	reg_base = i915_mmio_reg_offset(info->reg_base);
    417  1.1  riastrad 	bit = irq->events[event].bit;
    418  1.1  riastrad 
    419  1.1  riastrad 	if (!test_bit(bit, (void *)&vgpu_vreg(vgpu,
    420  1.1  riastrad 					regbase_to_imr(reg_base)))) {
    421  1.1  riastrad 		trace_propagate_event(vgpu->id, irq_name[event], bit);
    422  1.1  riastrad 		set_bit(bit, (void *)&vgpu_vreg(vgpu,
    423  1.1  riastrad 					regbase_to_iir(reg_base)));
    424  1.1  riastrad 	}
    425  1.1  riastrad }
    426  1.1  riastrad 
    427  1.1  riastrad /* =======================vEvent Handlers===================== */
    428  1.1  riastrad static void handle_default_event_virt(struct intel_gvt_irq *irq,
    429  1.1  riastrad 	enum intel_gvt_event_type event, struct intel_vgpu *vgpu)
    430  1.1  riastrad {
    431  1.1  riastrad 	if (!vgpu->irq.irq_warn_once[event]) {
    432  1.1  riastrad 		gvt_dbg_core("vgpu%d: IRQ receive event %d (%s)\n",
    433  1.1  riastrad 			vgpu->id, event, irq_name[event]);
    434  1.1  riastrad 		vgpu->irq.irq_warn_once[event] = true;
    435  1.1  riastrad 	}
    436  1.1  riastrad 	propagate_event(irq, event, vgpu);
    437  1.1  riastrad }
    438  1.1  riastrad 
    439  1.1  riastrad /* =====================GEN specific logic======================= */
    440  1.1  riastrad /* GEN8 interrupt routines. */
    441  1.1  riastrad 
    442  1.1  riastrad #define DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(regname, regbase) \
    443  1.1  riastrad static struct intel_gvt_irq_info gen8_##regname##_info = { \
    444  1.1  riastrad 	.name = #regname"-IRQ", \
    445  1.1  riastrad 	.reg_base = (regbase), \
    446  1.1  riastrad 	.bit_to_event = {[0 ... INTEL_GVT_IRQ_BITWIDTH-1] = \
    447  1.1  riastrad 		INTEL_GVT_EVENT_RESERVED}, \
    448  1.1  riastrad }
    449  1.1  riastrad 
    450  1.1  riastrad DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(gt0, GEN8_GT_ISR(0));
    451  1.1  riastrad DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(gt1, GEN8_GT_ISR(1));
    452  1.1  riastrad DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(gt2, GEN8_GT_ISR(2));
    453  1.1  riastrad DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(gt3, GEN8_GT_ISR(3));
    454  1.1  riastrad DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(de_pipe_a, GEN8_DE_PIPE_ISR(PIPE_A));
    455  1.1  riastrad DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(de_pipe_b, GEN8_DE_PIPE_ISR(PIPE_B));
    456  1.1  riastrad DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(de_pipe_c, GEN8_DE_PIPE_ISR(PIPE_C));
    457  1.1  riastrad DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(de_port, GEN8_DE_PORT_ISR);
    458  1.1  riastrad DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(de_misc, GEN8_DE_MISC_ISR);
    459  1.1  riastrad DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(pcu, GEN8_PCU_ISR);
    460  1.1  riastrad DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(master, GEN8_MASTER_IRQ);
    461  1.1  riastrad 
    462  1.1  riastrad static struct intel_gvt_irq_info gvt_base_pch_info = {
    463  1.1  riastrad 	.name = "PCH-IRQ",
    464  1.1  riastrad 	.reg_base = SDEISR,
    465  1.1  riastrad 	.bit_to_event = {[0 ... INTEL_GVT_IRQ_BITWIDTH-1] =
    466  1.1  riastrad 		INTEL_GVT_EVENT_RESERVED},
    467  1.1  riastrad };
    468  1.1  riastrad 
    469  1.1  riastrad static void gen8_check_pending_irq(struct intel_vgpu *vgpu)
    470  1.1  riastrad {
    471  1.1  riastrad 	struct intel_gvt_irq *irq = &vgpu->gvt->irq;
    472  1.1  riastrad 	int i;
    473  1.1  riastrad 
    474  1.1  riastrad 	if (!(vgpu_vreg(vgpu, i915_mmio_reg_offset(GEN8_MASTER_IRQ)) &
    475  1.1  riastrad 				GEN8_MASTER_IRQ_CONTROL))
    476  1.1  riastrad 		return;
    477  1.1  riastrad 
    478  1.1  riastrad 	for_each_set_bit(i, irq->irq_info_bitmap, INTEL_GVT_IRQ_INFO_MAX) {
    479  1.1  riastrad 		struct intel_gvt_irq_info *info = irq->info[i];
    480  1.1  riastrad 		u32 reg_base;
    481  1.1  riastrad 
    482  1.1  riastrad 		if (!info->has_upstream_irq)
    483  1.1  riastrad 			continue;
    484  1.1  riastrad 
    485  1.1  riastrad 		reg_base = i915_mmio_reg_offset(info->reg_base);
    486  1.1  riastrad 		if ((vgpu_vreg(vgpu, regbase_to_iir(reg_base))
    487  1.1  riastrad 				& vgpu_vreg(vgpu, regbase_to_ier(reg_base))))
    488  1.1  riastrad 			update_upstream_irq(vgpu, info);
    489  1.1  riastrad 	}
    490  1.1  riastrad 
    491  1.1  riastrad 	if (vgpu_vreg(vgpu, i915_mmio_reg_offset(GEN8_MASTER_IRQ))
    492  1.1  riastrad 			& ~GEN8_MASTER_IRQ_CONTROL)
    493  1.1  riastrad 		inject_virtual_interrupt(vgpu);
    494  1.1  riastrad }
    495  1.1  riastrad 
    496  1.1  riastrad static void gen8_init_irq(
    497  1.1  riastrad 		struct intel_gvt_irq *irq)
    498  1.1  riastrad {
    499  1.1  riastrad 	struct intel_gvt *gvt = irq_to_gvt(irq);
    500  1.1  riastrad 
    501  1.1  riastrad #define SET_BIT_INFO(s, b, e, i)		\
    502  1.1  riastrad 	do {					\
    503  1.1  riastrad 		s->events[e].bit = b;		\
    504  1.1  riastrad 		s->events[e].info = s->info[i];	\
    505  1.1  riastrad 		s->info[i]->bit_to_event[b] = e;\
    506  1.1  riastrad 	} while (0)
    507  1.1  riastrad 
    508  1.1  riastrad #define SET_IRQ_GROUP(s, g, i) \
    509  1.1  riastrad 	do { \
    510  1.1  riastrad 		s->info[g] = i; \
    511  1.1  riastrad 		(i)->group = g; \
    512  1.1  riastrad 		set_bit(g, s->irq_info_bitmap); \
    513  1.1  riastrad 	} while (0)
    514  1.1  riastrad 
    515  1.1  riastrad 	SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_MASTER, &gen8_master_info);
    516  1.1  riastrad 	SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_GT0, &gen8_gt0_info);
    517  1.1  riastrad 	SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_GT1, &gen8_gt1_info);
    518  1.1  riastrad 	SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_GT2, &gen8_gt2_info);
    519  1.1  riastrad 	SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_GT3, &gen8_gt3_info);
    520  1.1  riastrad 	SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_DE_PIPE_A, &gen8_de_pipe_a_info);
    521  1.1  riastrad 	SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_DE_PIPE_B, &gen8_de_pipe_b_info);
    522  1.1  riastrad 	SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_DE_PIPE_C, &gen8_de_pipe_c_info);
    523  1.1  riastrad 	SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_DE_PORT, &gen8_de_port_info);
    524  1.1  riastrad 	SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_DE_MISC, &gen8_de_misc_info);
    525  1.1  riastrad 	SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_PCU, &gen8_pcu_info);
    526  1.1  riastrad 	SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_PCH, &gvt_base_pch_info);
    527  1.1  riastrad 
    528  1.1  riastrad 	/* GEN8 level 2 interrupts. */
    529  1.1  riastrad 
    530  1.1  riastrad 	/* GEN8 interrupt GT0 events */
    531  1.1  riastrad 	SET_BIT_INFO(irq, 0, RCS_MI_USER_INTERRUPT, INTEL_GVT_IRQ_INFO_GT0);
    532  1.1  riastrad 	SET_BIT_INFO(irq, 4, RCS_PIPE_CONTROL, INTEL_GVT_IRQ_INFO_GT0);
    533  1.1  riastrad 	SET_BIT_INFO(irq, 8, RCS_AS_CONTEXT_SWITCH, INTEL_GVT_IRQ_INFO_GT0);
    534  1.1  riastrad 
    535  1.1  riastrad 	SET_BIT_INFO(irq, 16, BCS_MI_USER_INTERRUPT, INTEL_GVT_IRQ_INFO_GT0);
    536  1.1  riastrad 	SET_BIT_INFO(irq, 20, BCS_MI_FLUSH_DW, INTEL_GVT_IRQ_INFO_GT0);
    537  1.1  riastrad 	SET_BIT_INFO(irq, 24, BCS_AS_CONTEXT_SWITCH, INTEL_GVT_IRQ_INFO_GT0);
    538  1.1  riastrad 
    539  1.1  riastrad 	/* GEN8 interrupt GT1 events */
    540  1.1  riastrad 	SET_BIT_INFO(irq, 0, VCS_MI_USER_INTERRUPT, INTEL_GVT_IRQ_INFO_GT1);
    541  1.1  riastrad 	SET_BIT_INFO(irq, 4, VCS_MI_FLUSH_DW, INTEL_GVT_IRQ_INFO_GT1);
    542  1.1  riastrad 	SET_BIT_INFO(irq, 8, VCS_AS_CONTEXT_SWITCH, INTEL_GVT_IRQ_INFO_GT1);
    543  1.1  riastrad 
    544  1.1  riastrad 	if (HAS_ENGINE(gvt->dev_priv, VCS1)) {
    545  1.1  riastrad 		SET_BIT_INFO(irq, 16, VCS2_MI_USER_INTERRUPT,
    546  1.1  riastrad 			INTEL_GVT_IRQ_INFO_GT1);
    547  1.1  riastrad 		SET_BIT_INFO(irq, 20, VCS2_MI_FLUSH_DW,
    548  1.1  riastrad 			INTEL_GVT_IRQ_INFO_GT1);
    549  1.1  riastrad 		SET_BIT_INFO(irq, 24, VCS2_AS_CONTEXT_SWITCH,
    550  1.1  riastrad 			INTEL_GVT_IRQ_INFO_GT1);
    551  1.1  riastrad 	}
    552  1.1  riastrad 
    553  1.1  riastrad 	/* GEN8 interrupt GT3 events */
    554  1.1  riastrad 	SET_BIT_INFO(irq, 0, VECS_MI_USER_INTERRUPT, INTEL_GVT_IRQ_INFO_GT3);
    555  1.1  riastrad 	SET_BIT_INFO(irq, 4, VECS_MI_FLUSH_DW, INTEL_GVT_IRQ_INFO_GT3);
    556  1.1  riastrad 	SET_BIT_INFO(irq, 8, VECS_AS_CONTEXT_SWITCH, INTEL_GVT_IRQ_INFO_GT3);
    557  1.1  riastrad 
    558  1.1  riastrad 	SET_BIT_INFO(irq, 0, PIPE_A_VBLANK, INTEL_GVT_IRQ_INFO_DE_PIPE_A);
    559  1.1  riastrad 	SET_BIT_INFO(irq, 0, PIPE_B_VBLANK, INTEL_GVT_IRQ_INFO_DE_PIPE_B);
    560  1.1  riastrad 	SET_BIT_INFO(irq, 0, PIPE_C_VBLANK, INTEL_GVT_IRQ_INFO_DE_PIPE_C);
    561  1.1  riastrad 
    562  1.1  riastrad 	/* GEN8 interrupt DE PORT events */
    563  1.1  riastrad 	SET_BIT_INFO(irq, 0, AUX_CHANNEL_A, INTEL_GVT_IRQ_INFO_DE_PORT);
    564  1.1  riastrad 	SET_BIT_INFO(irq, 3, DP_A_HOTPLUG, INTEL_GVT_IRQ_INFO_DE_PORT);
    565  1.1  riastrad 
    566  1.1  riastrad 	/* GEN8 interrupt DE MISC events */
    567  1.1  riastrad 	SET_BIT_INFO(irq, 0, GSE, INTEL_GVT_IRQ_INFO_DE_MISC);
    568  1.1  riastrad 
    569  1.1  riastrad 	/* PCH events */
    570  1.1  riastrad 	SET_BIT_INFO(irq, 17, GMBUS, INTEL_GVT_IRQ_INFO_PCH);
    571  1.1  riastrad 	SET_BIT_INFO(irq, 19, CRT_HOTPLUG, INTEL_GVT_IRQ_INFO_PCH);
    572  1.1  riastrad 	SET_BIT_INFO(irq, 21, DP_B_HOTPLUG, INTEL_GVT_IRQ_INFO_PCH);
    573  1.1  riastrad 	SET_BIT_INFO(irq, 22, DP_C_HOTPLUG, INTEL_GVT_IRQ_INFO_PCH);
    574  1.1  riastrad 	SET_BIT_INFO(irq, 23, DP_D_HOTPLUG, INTEL_GVT_IRQ_INFO_PCH);
    575  1.1  riastrad 
    576  1.1  riastrad 	if (IS_BROADWELL(gvt->dev_priv)) {
    577  1.1  riastrad 		SET_BIT_INFO(irq, 25, AUX_CHANNEL_B, INTEL_GVT_IRQ_INFO_PCH);
    578  1.1  riastrad 		SET_BIT_INFO(irq, 26, AUX_CHANNEL_C, INTEL_GVT_IRQ_INFO_PCH);
    579  1.1  riastrad 		SET_BIT_INFO(irq, 27, AUX_CHANNEL_D, INTEL_GVT_IRQ_INFO_PCH);
    580  1.1  riastrad 
    581  1.1  riastrad 		SET_BIT_INFO(irq, 4, PRIMARY_A_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_A);
    582  1.1  riastrad 		SET_BIT_INFO(irq, 5, SPRITE_A_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_A);
    583  1.1  riastrad 
    584  1.1  riastrad 		SET_BIT_INFO(irq, 4, PRIMARY_B_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_B);
    585  1.1  riastrad 		SET_BIT_INFO(irq, 5, SPRITE_B_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_B);
    586  1.1  riastrad 
    587  1.1  riastrad 		SET_BIT_INFO(irq, 4, PRIMARY_C_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_C);
    588  1.1  riastrad 		SET_BIT_INFO(irq, 5, SPRITE_C_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_C);
    589  1.1  riastrad 	} else if (INTEL_GEN(gvt->dev_priv) >= 9) {
    590  1.1  riastrad 		SET_BIT_INFO(irq, 25, AUX_CHANNEL_B, INTEL_GVT_IRQ_INFO_DE_PORT);
    591  1.1  riastrad 		SET_BIT_INFO(irq, 26, AUX_CHANNEL_C, INTEL_GVT_IRQ_INFO_DE_PORT);
    592  1.1  riastrad 		SET_BIT_INFO(irq, 27, AUX_CHANNEL_D, INTEL_GVT_IRQ_INFO_DE_PORT);
    593  1.1  riastrad 
    594  1.1  riastrad 		SET_BIT_INFO(irq, 3, PRIMARY_A_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_A);
    595  1.1  riastrad 		SET_BIT_INFO(irq, 3, PRIMARY_B_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_B);
    596  1.1  riastrad 		SET_BIT_INFO(irq, 3, PRIMARY_C_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_C);
    597  1.1  riastrad 
    598  1.1  riastrad 		SET_BIT_INFO(irq, 4, SPRITE_A_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_A);
    599  1.1  riastrad 		SET_BIT_INFO(irq, 4, SPRITE_B_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_B);
    600  1.1  riastrad 		SET_BIT_INFO(irq, 4, SPRITE_C_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_C);
    601  1.1  riastrad 	}
    602  1.1  riastrad 
    603  1.1  riastrad 	/* GEN8 interrupt PCU events */
    604  1.1  riastrad 	SET_BIT_INFO(irq, 24, PCU_THERMAL, INTEL_GVT_IRQ_INFO_PCU);
    605  1.1  riastrad 	SET_BIT_INFO(irq, 25, PCU_PCODE2DRIVER_MAILBOX, INTEL_GVT_IRQ_INFO_PCU);
    606  1.1  riastrad }
    607  1.1  riastrad 
    608  1.1  riastrad static struct intel_gvt_irq_ops gen8_irq_ops = {
    609  1.1  riastrad 	.init_irq = gen8_init_irq,
    610  1.1  riastrad 	.check_pending_irq = gen8_check_pending_irq,
    611  1.1  riastrad };
    612  1.1  riastrad 
    613  1.1  riastrad /**
    614  1.1  riastrad  * intel_vgpu_trigger_virtual_event - Trigger a virtual event for a vGPU
    615  1.1  riastrad  * @vgpu: a vGPU
    616  1.1  riastrad  * @event: interrupt event
    617  1.1  riastrad  *
    618  1.1  riastrad  * This function is used to trigger a virtual interrupt event for vGPU.
    619  1.1  riastrad  * The caller provides the event to be triggered, the framework itself
    620  1.1  riastrad  * will emulate the IRQ register bit change.
    621  1.1  riastrad  *
    622  1.1  riastrad  */
    623  1.1  riastrad void intel_vgpu_trigger_virtual_event(struct intel_vgpu *vgpu,
    624  1.1  riastrad 	enum intel_gvt_event_type event)
    625  1.1  riastrad {
    626  1.1  riastrad 	struct intel_gvt *gvt = vgpu->gvt;
    627  1.1  riastrad 	struct intel_gvt_irq *irq = &gvt->irq;
    628  1.1  riastrad 	gvt_event_virt_handler_t handler;
    629  1.1  riastrad 	struct intel_gvt_irq_ops *ops = gvt->irq.ops;
    630  1.1  riastrad 
    631  1.1  riastrad 	handler = get_event_virt_handler(irq, event);
    632  1.1  riastrad 	WARN_ON(!handler);
    633  1.1  riastrad 
    634  1.1  riastrad 	handler(irq, event, vgpu);
    635  1.1  riastrad 
    636  1.1  riastrad 	ops->check_pending_irq(vgpu);
    637  1.1  riastrad }
    638  1.1  riastrad 
    639  1.1  riastrad static void init_events(
    640  1.1  riastrad 	struct intel_gvt_irq *irq)
    641  1.1  riastrad {
    642  1.1  riastrad 	int i;
    643  1.1  riastrad 
    644  1.1  riastrad 	for (i = 0; i < INTEL_GVT_EVENT_MAX; i++) {
    645  1.1  riastrad 		irq->events[i].info = NULL;
    646  1.1  riastrad 		irq->events[i].v_handler = handle_default_event_virt;
    647  1.1  riastrad 	}
    648  1.1  riastrad }
    649  1.1  riastrad 
    650  1.1  riastrad static enum hrtimer_restart vblank_timer_fn(struct hrtimer *data)
    651  1.1  riastrad {
    652  1.1  riastrad 	struct intel_gvt_vblank_timer *vblank_timer;
    653  1.1  riastrad 	struct intel_gvt_irq *irq;
    654  1.1  riastrad 	struct intel_gvt *gvt;
    655  1.1  riastrad 
    656  1.1  riastrad 	vblank_timer = container_of(data, struct intel_gvt_vblank_timer, timer);
    657  1.1  riastrad 	irq = container_of(vblank_timer, struct intel_gvt_irq, vblank_timer);
    658  1.1  riastrad 	gvt = container_of(irq, struct intel_gvt, irq);
    659  1.1  riastrad 
    660  1.1  riastrad 	intel_gvt_request_service(gvt, INTEL_GVT_REQUEST_EMULATE_VBLANK);
    661  1.1  riastrad 	hrtimer_add_expires_ns(&vblank_timer->timer, vblank_timer->period);
    662  1.1  riastrad 	return HRTIMER_RESTART;
    663  1.1  riastrad }
    664  1.1  riastrad 
    665  1.1  riastrad /**
    666  1.1  riastrad  * intel_gvt_clean_irq - clean up GVT-g IRQ emulation subsystem
    667  1.1  riastrad  * @gvt: a GVT device
    668  1.1  riastrad  *
    669  1.1  riastrad  * This function is called at driver unloading stage, to clean up GVT-g IRQ
    670  1.1  riastrad  * emulation subsystem.
    671  1.1  riastrad  *
    672  1.1  riastrad  */
    673  1.1  riastrad void intel_gvt_clean_irq(struct intel_gvt *gvt)
    674  1.1  riastrad {
    675  1.1  riastrad 	struct intel_gvt_irq *irq = &gvt->irq;
    676  1.1  riastrad 
    677  1.1  riastrad 	hrtimer_cancel(&irq->vblank_timer.timer);
    678  1.1  riastrad }
    679  1.1  riastrad 
    680  1.1  riastrad #define VBLANK_TIMER_PERIOD 16000000
    681  1.1  riastrad 
    682  1.1  riastrad /**
    683  1.1  riastrad  * intel_gvt_init_irq - initialize GVT-g IRQ emulation subsystem
    684  1.1  riastrad  * @gvt: a GVT device
    685  1.1  riastrad  *
    686  1.1  riastrad  * This function is called at driver loading stage, to initialize the GVT-g IRQ
    687  1.1  riastrad  * emulation subsystem.
    688  1.1  riastrad  *
    689  1.1  riastrad  * Returns:
    690  1.1  riastrad  * Zero on success, negative error code if failed.
    691  1.1  riastrad  */
    692  1.1  riastrad int intel_gvt_init_irq(struct intel_gvt *gvt)
    693  1.1  riastrad {
    694  1.1  riastrad 	struct intel_gvt_irq *irq = &gvt->irq;
    695  1.1  riastrad 	struct intel_gvt_vblank_timer *vblank_timer = &irq->vblank_timer;
    696  1.1  riastrad 
    697  1.1  riastrad 	gvt_dbg_core("init irq framework\n");
    698  1.1  riastrad 
    699  1.1  riastrad 	irq->ops = &gen8_irq_ops;
    700  1.1  riastrad 	irq->irq_map = gen8_irq_map;
    701  1.1  riastrad 
    702  1.1  riastrad 	/* common event initialization */
    703  1.1  riastrad 	init_events(irq);
    704  1.1  riastrad 
    705  1.1  riastrad 	/* gen specific initialization */
    706  1.1  riastrad 	irq->ops->init_irq(irq);
    707  1.1  riastrad 
    708  1.1  riastrad 	init_irq_map(irq);
    709  1.1  riastrad 
    710  1.1  riastrad 	hrtimer_init(&vblank_timer->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
    711  1.1  riastrad 	vblank_timer->timer.function = vblank_timer_fn;
    712  1.1  riastrad 	vblank_timer->period = VBLANK_TIMER_PERIOD;
    713  1.1  riastrad 
    714  1.1  riastrad 	return 0;
    715  1.1  riastrad }
    716