0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #include <linux/eventfd.h>
0033
0034 #include "i915_drv.h"
0035 #include "i915_reg.h"
0036 #include "gvt.h"
0037 #include "trace.h"
0038
0039
0040 #define regbase_to_isr(base) (base)
0041 #define regbase_to_imr(base) (base + 0x4)
0042 #define regbase_to_iir(base) (base + 0x8)
0043 #define regbase_to_ier(base) (base + 0xC)
0044
0045 #define iir_to_regbase(iir) (iir - 0x8)
0046 #define ier_to_regbase(ier) (ier - 0xC)
0047
0048 #define get_event_virt_handler(irq, e) (irq->events[e].v_handler)
0049 #define get_irq_info(irq, e) (irq->events[e].info)
0050
0051 #define irq_to_gvt(irq) \
0052 container_of(irq, struct intel_gvt, irq)
0053
0054 static void update_upstream_irq(struct intel_vgpu *vgpu,
0055 struct intel_gvt_irq_info *info);
0056
0057 static const char * const irq_name[INTEL_GVT_EVENT_MAX] = {
0058 [RCS_MI_USER_INTERRUPT] = "Render CS MI USER INTERRUPT",
0059 [RCS_DEBUG] = "Render EU debug from SVG",
0060 [RCS_MMIO_SYNC_FLUSH] = "Render MMIO sync flush status",
0061 [RCS_CMD_STREAMER_ERR] = "Render CS error interrupt",
0062 [RCS_PIPE_CONTROL] = "Render PIPE CONTROL notify",
0063 [RCS_WATCHDOG_EXCEEDED] = "Render CS Watchdog counter exceeded",
0064 [RCS_PAGE_DIRECTORY_FAULT] = "Render page directory faults",
0065 [RCS_AS_CONTEXT_SWITCH] = "Render AS Context Switch Interrupt",
0066
0067 [VCS_MI_USER_INTERRUPT] = "Video CS MI USER INTERRUPT",
0068 [VCS_MMIO_SYNC_FLUSH] = "Video MMIO sync flush status",
0069 [VCS_CMD_STREAMER_ERR] = "Video CS error interrupt",
0070 [VCS_MI_FLUSH_DW] = "Video MI FLUSH DW notify",
0071 [VCS_WATCHDOG_EXCEEDED] = "Video CS Watchdog counter exceeded",
0072 [VCS_PAGE_DIRECTORY_FAULT] = "Video page directory faults",
0073 [VCS_AS_CONTEXT_SWITCH] = "Video AS Context Switch Interrupt",
0074 [VCS2_MI_USER_INTERRUPT] = "VCS2 Video CS MI USER INTERRUPT",
0075 [VCS2_MI_FLUSH_DW] = "VCS2 Video MI FLUSH DW notify",
0076 [VCS2_AS_CONTEXT_SWITCH] = "VCS2 Context Switch Interrupt",
0077
0078 [BCS_MI_USER_INTERRUPT] = "Blitter CS MI USER INTERRUPT",
0079 [BCS_MMIO_SYNC_FLUSH] = "Billter MMIO sync flush status",
0080 [BCS_CMD_STREAMER_ERR] = "Blitter CS error interrupt",
0081 [BCS_MI_FLUSH_DW] = "Blitter MI FLUSH DW notify",
0082 [BCS_PAGE_DIRECTORY_FAULT] = "Blitter page directory faults",
0083 [BCS_AS_CONTEXT_SWITCH] = "Blitter AS Context Switch Interrupt",
0084
0085 [VECS_MI_FLUSH_DW] = "Video Enhanced Streamer MI FLUSH DW notify",
0086 [VECS_AS_CONTEXT_SWITCH] = "VECS Context Switch Interrupt",
0087
0088 [PIPE_A_FIFO_UNDERRUN] = "Pipe A FIFO underrun",
0089 [PIPE_A_CRC_ERR] = "Pipe A CRC error",
0090 [PIPE_A_CRC_DONE] = "Pipe A CRC done",
0091 [PIPE_A_VSYNC] = "Pipe A vsync",
0092 [PIPE_A_LINE_COMPARE] = "Pipe A line compare",
0093 [PIPE_A_ODD_FIELD] = "Pipe A odd field",
0094 [PIPE_A_EVEN_FIELD] = "Pipe A even field",
0095 [PIPE_A_VBLANK] = "Pipe A vblank",
0096 [PIPE_B_FIFO_UNDERRUN] = "Pipe B FIFO underrun",
0097 [PIPE_B_CRC_ERR] = "Pipe B CRC error",
0098 [PIPE_B_CRC_DONE] = "Pipe B CRC done",
0099 [PIPE_B_VSYNC] = "Pipe B vsync",
0100 [PIPE_B_LINE_COMPARE] = "Pipe B line compare",
0101 [PIPE_B_ODD_FIELD] = "Pipe B odd field",
0102 [PIPE_B_EVEN_FIELD] = "Pipe B even field",
0103 [PIPE_B_VBLANK] = "Pipe B vblank",
0104 [PIPE_C_VBLANK] = "Pipe C vblank",
0105 [DPST_PHASE_IN] = "DPST phase in event",
0106 [DPST_HISTOGRAM] = "DPST histogram event",
0107 [GSE] = "GSE",
0108 [DP_A_HOTPLUG] = "DP A Hotplug",
0109 [AUX_CHANNEL_A] = "AUX Channel A",
0110 [PERF_COUNTER] = "Performance counter",
0111 [POISON] = "Poison",
0112 [GTT_FAULT] = "GTT fault",
0113 [PRIMARY_A_FLIP_DONE] = "Primary Plane A flip done",
0114 [PRIMARY_B_FLIP_DONE] = "Primary Plane B flip done",
0115 [PRIMARY_C_FLIP_DONE] = "Primary Plane C flip done",
0116 [SPRITE_A_FLIP_DONE] = "Sprite Plane A flip done",
0117 [SPRITE_B_FLIP_DONE] = "Sprite Plane B flip done",
0118 [SPRITE_C_FLIP_DONE] = "Sprite Plane C flip done",
0119
0120 [PCU_THERMAL] = "PCU Thermal Event",
0121 [PCU_PCODE2DRIVER_MAILBOX] = "PCU pcode2driver mailbox event",
0122
0123 [FDI_RX_INTERRUPTS_TRANSCODER_A] = "FDI RX Interrupts Combined A",
0124 [AUDIO_CP_CHANGE_TRANSCODER_A] = "Audio CP Change Transcoder A",
0125 [AUDIO_CP_REQUEST_TRANSCODER_A] = "Audio CP Request Transcoder A",
0126 [FDI_RX_INTERRUPTS_TRANSCODER_B] = "FDI RX Interrupts Combined B",
0127 [AUDIO_CP_CHANGE_TRANSCODER_B] = "Audio CP Change Transcoder B",
0128 [AUDIO_CP_REQUEST_TRANSCODER_B] = "Audio CP Request Transcoder B",
0129 [FDI_RX_INTERRUPTS_TRANSCODER_C] = "FDI RX Interrupts Combined C",
0130 [AUDIO_CP_CHANGE_TRANSCODER_C] = "Audio CP Change Transcoder C",
0131 [AUDIO_CP_REQUEST_TRANSCODER_C] = "Audio CP Request Transcoder C",
0132 [ERR_AND_DBG] = "South Error and Debug Interrupts Combined",
0133 [GMBUS] = "Gmbus",
0134 [SDVO_B_HOTPLUG] = "SDVO B hotplug",
0135 [CRT_HOTPLUG] = "CRT Hotplug",
0136 [DP_B_HOTPLUG] = "DisplayPort/HDMI/DVI B Hotplug",
0137 [DP_C_HOTPLUG] = "DisplayPort/HDMI/DVI C Hotplug",
0138 [DP_D_HOTPLUG] = "DisplayPort/HDMI/DVI D Hotplug",
0139 [AUX_CHANNEL_B] = "AUX Channel B",
0140 [AUX_CHANNEL_C] = "AUX Channel C",
0141 [AUX_CHANNEL_D] = "AUX Channel D",
0142 [AUDIO_POWER_STATE_CHANGE_B] = "Audio Power State change Port B",
0143 [AUDIO_POWER_STATE_CHANGE_C] = "Audio Power State change Port C",
0144 [AUDIO_POWER_STATE_CHANGE_D] = "Audio Power State change Port D",
0145
0146 [INTEL_GVT_EVENT_RESERVED] = "RESERVED EVENTS!!!",
0147 };
0148
0149 static inline struct intel_gvt_irq_info *regbase_to_irq_info(
0150 struct intel_gvt *gvt,
0151 unsigned int reg)
0152 {
0153 struct intel_gvt_irq *irq = &gvt->irq;
0154 int i;
0155
0156 for_each_set_bit(i, irq->irq_info_bitmap, INTEL_GVT_IRQ_INFO_MAX) {
0157 if (i915_mmio_reg_offset(irq->info[i]->reg_base) == reg)
0158 return irq->info[i];
0159 }
0160
0161 return NULL;
0162 }
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178 int intel_vgpu_reg_imr_handler(struct intel_vgpu *vgpu,
0179 unsigned int reg, void *p_data, unsigned int bytes)
0180 {
0181 struct intel_gvt *gvt = vgpu->gvt;
0182 const struct intel_gvt_irq_ops *ops = gvt->irq.ops;
0183 u32 imr = *(u32 *)p_data;
0184
0185 trace_write_ir(vgpu->id, "IMR", reg, imr, vgpu_vreg(vgpu, reg),
0186 (vgpu_vreg(vgpu, reg) ^ imr));
0187
0188 vgpu_vreg(vgpu, reg) = imr;
0189
0190 ops->check_pending_irq(vgpu);
0191
0192 return 0;
0193 }
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208 int intel_vgpu_reg_master_irq_handler(struct intel_vgpu *vgpu,
0209 unsigned int reg, void *p_data, unsigned int bytes)
0210 {
0211 struct intel_gvt *gvt = vgpu->gvt;
0212 const struct intel_gvt_irq_ops *ops = gvt->irq.ops;
0213 u32 ier = *(u32 *)p_data;
0214 u32 virtual_ier = vgpu_vreg(vgpu, reg);
0215
0216 trace_write_ir(vgpu->id, "MASTER_IRQ", reg, ier, virtual_ier,
0217 (virtual_ier ^ ier));
0218
0219
0220
0221
0222
0223
0224 ier &= GEN8_MASTER_IRQ_CONTROL;
0225 virtual_ier &= GEN8_MASTER_IRQ_CONTROL;
0226 vgpu_vreg(vgpu, reg) &= ~GEN8_MASTER_IRQ_CONTROL;
0227 vgpu_vreg(vgpu, reg) |= ier;
0228
0229 ops->check_pending_irq(vgpu);
0230
0231 return 0;
0232 }
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247 int intel_vgpu_reg_ier_handler(struct intel_vgpu *vgpu,
0248 unsigned int reg, void *p_data, unsigned int bytes)
0249 {
0250 struct intel_gvt *gvt = vgpu->gvt;
0251 struct drm_i915_private *i915 = gvt->gt->i915;
0252 const struct intel_gvt_irq_ops *ops = gvt->irq.ops;
0253 struct intel_gvt_irq_info *info;
0254 u32 ier = *(u32 *)p_data;
0255
0256 trace_write_ir(vgpu->id, "IER", reg, ier, vgpu_vreg(vgpu, reg),
0257 (vgpu_vreg(vgpu, reg) ^ ier));
0258
0259 vgpu_vreg(vgpu, reg) = ier;
0260
0261 info = regbase_to_irq_info(gvt, ier_to_regbase(reg));
0262 if (drm_WARN_ON(&i915->drm, !info))
0263 return -EINVAL;
0264
0265 if (info->has_upstream_irq)
0266 update_upstream_irq(vgpu, info);
0267
0268 ops->check_pending_irq(vgpu);
0269
0270 return 0;
0271 }
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286 int intel_vgpu_reg_iir_handler(struct intel_vgpu *vgpu, unsigned int reg,
0287 void *p_data, unsigned int bytes)
0288 {
0289 struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
0290 struct intel_gvt_irq_info *info = regbase_to_irq_info(vgpu->gvt,
0291 iir_to_regbase(reg));
0292 u32 iir = *(u32 *)p_data;
0293
0294 trace_write_ir(vgpu->id, "IIR", reg, iir, vgpu_vreg(vgpu, reg),
0295 (vgpu_vreg(vgpu, reg) ^ iir));
0296
0297 if (drm_WARN_ON(&i915->drm, !info))
0298 return -EINVAL;
0299
0300 vgpu_vreg(vgpu, reg) &= ~iir;
0301
0302 if (info->has_upstream_irq)
0303 update_upstream_irq(vgpu, info);
0304 return 0;
0305 }
0306
0307 static struct intel_gvt_irq_map gen8_irq_map[] = {
0308 { INTEL_GVT_IRQ_INFO_MASTER, 0, INTEL_GVT_IRQ_INFO_GT0, 0xffff },
0309 { INTEL_GVT_IRQ_INFO_MASTER, 1, INTEL_GVT_IRQ_INFO_GT0, 0xffff0000 },
0310 { INTEL_GVT_IRQ_INFO_MASTER, 2, INTEL_GVT_IRQ_INFO_GT1, 0xffff },
0311 { INTEL_GVT_IRQ_INFO_MASTER, 3, INTEL_GVT_IRQ_INFO_GT1, 0xffff0000 },
0312 { INTEL_GVT_IRQ_INFO_MASTER, 4, INTEL_GVT_IRQ_INFO_GT2, 0xffff },
0313 { INTEL_GVT_IRQ_INFO_MASTER, 6, INTEL_GVT_IRQ_INFO_GT3, 0xffff },
0314 { INTEL_GVT_IRQ_INFO_MASTER, 16, INTEL_GVT_IRQ_INFO_DE_PIPE_A, ~0 },
0315 { INTEL_GVT_IRQ_INFO_MASTER, 17, INTEL_GVT_IRQ_INFO_DE_PIPE_B, ~0 },
0316 { INTEL_GVT_IRQ_INFO_MASTER, 18, INTEL_GVT_IRQ_INFO_DE_PIPE_C, ~0 },
0317 { INTEL_GVT_IRQ_INFO_MASTER, 20, INTEL_GVT_IRQ_INFO_DE_PORT, ~0 },
0318 { INTEL_GVT_IRQ_INFO_MASTER, 22, INTEL_GVT_IRQ_INFO_DE_MISC, ~0 },
0319 { INTEL_GVT_IRQ_INFO_MASTER, 23, INTEL_GVT_IRQ_INFO_PCH, ~0 },
0320 { INTEL_GVT_IRQ_INFO_MASTER, 30, INTEL_GVT_IRQ_INFO_PCU, ~0 },
0321 { -1, -1, ~0 },
0322 };
0323
0324 static void update_upstream_irq(struct intel_vgpu *vgpu,
0325 struct intel_gvt_irq_info *info)
0326 {
0327 struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
0328 struct intel_gvt_irq *irq = &vgpu->gvt->irq;
0329 struct intel_gvt_irq_map *map = irq->irq_map;
0330 struct intel_gvt_irq_info *up_irq_info = NULL;
0331 u32 set_bits = 0;
0332 u32 clear_bits = 0;
0333 int bit;
0334 u32 val = vgpu_vreg(vgpu,
0335 regbase_to_iir(i915_mmio_reg_offset(info->reg_base)))
0336 & vgpu_vreg(vgpu,
0337 regbase_to_ier(i915_mmio_reg_offset(info->reg_base)));
0338
0339 if (!info->has_upstream_irq)
0340 return;
0341
0342 for (map = irq->irq_map; map->up_irq_bit != -1; map++) {
0343 if (info->group != map->down_irq_group)
0344 continue;
0345
0346 if (!up_irq_info)
0347 up_irq_info = irq->info[map->up_irq_group];
0348 else
0349 drm_WARN_ON(&i915->drm, up_irq_info !=
0350 irq->info[map->up_irq_group]);
0351
0352 bit = map->up_irq_bit;
0353
0354 if (val & map->down_irq_bitmask)
0355 set_bits |= (1 << bit);
0356 else
0357 clear_bits |= (1 << bit);
0358 }
0359
0360 if (drm_WARN_ON(&i915->drm, !up_irq_info))
0361 return;
0362
0363 if (up_irq_info->group == INTEL_GVT_IRQ_INFO_MASTER) {
0364 u32 isr = i915_mmio_reg_offset(up_irq_info->reg_base);
0365
0366 vgpu_vreg(vgpu, isr) &= ~clear_bits;
0367 vgpu_vreg(vgpu, isr) |= set_bits;
0368 } else {
0369 u32 iir = regbase_to_iir(
0370 i915_mmio_reg_offset(up_irq_info->reg_base));
0371 u32 imr = regbase_to_imr(
0372 i915_mmio_reg_offset(up_irq_info->reg_base));
0373
0374 vgpu_vreg(vgpu, iir) |= (set_bits & ~vgpu_vreg(vgpu, imr));
0375 }
0376
0377 if (up_irq_info->has_upstream_irq)
0378 update_upstream_irq(vgpu, up_irq_info);
0379 }
0380
0381 static void init_irq_map(struct intel_gvt_irq *irq)
0382 {
0383 struct intel_gvt_irq_map *map;
0384 struct intel_gvt_irq_info *up_info, *down_info;
0385 int up_bit;
0386
0387 for (map = irq->irq_map; map->up_irq_bit != -1; map++) {
0388 up_info = irq->info[map->up_irq_group];
0389 up_bit = map->up_irq_bit;
0390 down_info = irq->info[map->down_irq_group];
0391
0392 set_bit(up_bit, up_info->downstream_irq_bitmap);
0393 down_info->has_upstream_irq = true;
0394
0395 gvt_dbg_irq("[up] grp %d bit %d -> [down] grp %d bitmask %x\n",
0396 up_info->group, up_bit,
0397 down_info->group, map->down_irq_bitmask);
0398 }
0399 }
0400
0401
0402
0403 #define MSI_CAP_CONTROL(offset) (offset + 2)
0404 #define MSI_CAP_ADDRESS(offset) (offset + 4)
0405 #define MSI_CAP_DATA(offset) (offset + 8)
0406 #define MSI_CAP_EN 0x1
0407
0408 static int inject_virtual_interrupt(struct intel_vgpu *vgpu)
0409 {
0410 unsigned long offset = vgpu->gvt->device_info.msi_cap_offset;
0411 u16 control, data;
0412 u32 addr;
0413
0414 control = *(u16 *)(vgpu_cfg_space(vgpu) + MSI_CAP_CONTROL(offset));
0415 addr = *(u32 *)(vgpu_cfg_space(vgpu) + MSI_CAP_ADDRESS(offset));
0416 data = *(u16 *)(vgpu_cfg_space(vgpu) + MSI_CAP_DATA(offset));
0417
0418
0419 if (!(control & MSI_CAP_EN))
0420 return 0;
0421
0422 if (WARN(control & GENMASK(15, 1), "only support one MSI format\n"))
0423 return -EINVAL;
0424
0425 trace_inject_msi(vgpu->id, addr, data);
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436 if (!vgpu->attached)
0437 return -ESRCH;
0438 if (vgpu->msi_trigger && eventfd_signal(vgpu->msi_trigger, 1) != 1)
0439 return -EFAULT;
0440 return 0;
0441 }
0442
0443 static void propagate_event(struct intel_gvt_irq *irq,
0444 enum intel_gvt_event_type event, struct intel_vgpu *vgpu)
0445 {
0446 struct intel_gvt_irq_info *info;
0447 unsigned int reg_base;
0448 int bit;
0449
0450 info = get_irq_info(irq, event);
0451 if (WARN_ON(!info))
0452 return;
0453
0454 reg_base = i915_mmio_reg_offset(info->reg_base);
0455 bit = irq->events[event].bit;
0456
0457 if (!test_bit(bit, (void *)&vgpu_vreg(vgpu,
0458 regbase_to_imr(reg_base)))) {
0459 trace_propagate_event(vgpu->id, irq_name[event], bit);
0460 set_bit(bit, (void *)&vgpu_vreg(vgpu,
0461 regbase_to_iir(reg_base)));
0462 }
0463 }
0464
0465
0466 static void handle_default_event_virt(struct intel_gvt_irq *irq,
0467 enum intel_gvt_event_type event, struct intel_vgpu *vgpu)
0468 {
0469 if (!vgpu->irq.irq_warn_once[event]) {
0470 gvt_dbg_core("vgpu%d: IRQ receive event %d (%s)\n",
0471 vgpu->id, event, irq_name[event]);
0472 vgpu->irq.irq_warn_once[event] = true;
0473 }
0474 propagate_event(irq, event, vgpu);
0475 }
0476
0477
0478
0479
0480 #define DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(regname, regbase) \
0481 static struct intel_gvt_irq_info gen8_##regname##_info = { \
0482 .name = #regname"-IRQ", \
0483 .reg_base = (regbase), \
0484 .bit_to_event = {[0 ... INTEL_GVT_IRQ_BITWIDTH-1] = \
0485 INTEL_GVT_EVENT_RESERVED}, \
0486 }
0487
0488 DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(gt0, GEN8_GT_ISR(0));
0489 DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(gt1, GEN8_GT_ISR(1));
0490 DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(gt2, GEN8_GT_ISR(2));
0491 DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(gt3, GEN8_GT_ISR(3));
0492 DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(de_pipe_a, GEN8_DE_PIPE_ISR(PIPE_A));
0493 DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(de_pipe_b, GEN8_DE_PIPE_ISR(PIPE_B));
0494 DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(de_pipe_c, GEN8_DE_PIPE_ISR(PIPE_C));
0495 DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(de_port, GEN8_DE_PORT_ISR);
0496 DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(de_misc, GEN8_DE_MISC_ISR);
0497 DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(pcu, GEN8_PCU_ISR);
0498 DEFINE_GVT_GEN8_INTEL_GVT_IRQ_INFO(master, GEN8_MASTER_IRQ);
0499
0500 static struct intel_gvt_irq_info gvt_base_pch_info = {
0501 .name = "PCH-IRQ",
0502 .reg_base = SDEISR,
0503 .bit_to_event = {[0 ... INTEL_GVT_IRQ_BITWIDTH-1] =
0504 INTEL_GVT_EVENT_RESERVED},
0505 };
0506
0507 static void gen8_check_pending_irq(struct intel_vgpu *vgpu)
0508 {
0509 struct intel_gvt_irq *irq = &vgpu->gvt->irq;
0510 int i;
0511
0512 if (!(vgpu_vreg(vgpu, i915_mmio_reg_offset(GEN8_MASTER_IRQ)) &
0513 GEN8_MASTER_IRQ_CONTROL))
0514 return;
0515
0516 for_each_set_bit(i, irq->irq_info_bitmap, INTEL_GVT_IRQ_INFO_MAX) {
0517 struct intel_gvt_irq_info *info = irq->info[i];
0518 u32 reg_base;
0519
0520 if (!info->has_upstream_irq)
0521 continue;
0522
0523 reg_base = i915_mmio_reg_offset(info->reg_base);
0524 if ((vgpu_vreg(vgpu, regbase_to_iir(reg_base))
0525 & vgpu_vreg(vgpu, regbase_to_ier(reg_base))))
0526 update_upstream_irq(vgpu, info);
0527 }
0528
0529 if (vgpu_vreg(vgpu, i915_mmio_reg_offset(GEN8_MASTER_IRQ))
0530 & ~GEN8_MASTER_IRQ_CONTROL)
0531 inject_virtual_interrupt(vgpu);
0532 }
0533
0534 static void gen8_init_irq(
0535 struct intel_gvt_irq *irq)
0536 {
0537 struct intel_gvt *gvt = irq_to_gvt(irq);
0538
0539 #define SET_BIT_INFO(s, b, e, i) \
0540 do { \
0541 s->events[e].bit = b; \
0542 s->events[e].info = s->info[i]; \
0543 s->info[i]->bit_to_event[b] = e;\
0544 } while (0)
0545
0546 #define SET_IRQ_GROUP(s, g, i) \
0547 do { \
0548 s->info[g] = i; \
0549 (i)->group = g; \
0550 set_bit(g, s->irq_info_bitmap); \
0551 } while (0)
0552
0553 SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_MASTER, &gen8_master_info);
0554 SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_GT0, &gen8_gt0_info);
0555 SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_GT1, &gen8_gt1_info);
0556 SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_GT2, &gen8_gt2_info);
0557 SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_GT3, &gen8_gt3_info);
0558 SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_DE_PIPE_A, &gen8_de_pipe_a_info);
0559 SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_DE_PIPE_B, &gen8_de_pipe_b_info);
0560 SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_DE_PIPE_C, &gen8_de_pipe_c_info);
0561 SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_DE_PORT, &gen8_de_port_info);
0562 SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_DE_MISC, &gen8_de_misc_info);
0563 SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_PCU, &gen8_pcu_info);
0564 SET_IRQ_GROUP(irq, INTEL_GVT_IRQ_INFO_PCH, &gvt_base_pch_info);
0565
0566
0567
0568
0569 SET_BIT_INFO(irq, 0, RCS_MI_USER_INTERRUPT, INTEL_GVT_IRQ_INFO_GT0);
0570 SET_BIT_INFO(irq, 4, RCS_PIPE_CONTROL, INTEL_GVT_IRQ_INFO_GT0);
0571 SET_BIT_INFO(irq, 8, RCS_AS_CONTEXT_SWITCH, INTEL_GVT_IRQ_INFO_GT0);
0572
0573 SET_BIT_INFO(irq, 16, BCS_MI_USER_INTERRUPT, INTEL_GVT_IRQ_INFO_GT0);
0574 SET_BIT_INFO(irq, 20, BCS_MI_FLUSH_DW, INTEL_GVT_IRQ_INFO_GT0);
0575 SET_BIT_INFO(irq, 24, BCS_AS_CONTEXT_SWITCH, INTEL_GVT_IRQ_INFO_GT0);
0576
0577
0578 SET_BIT_INFO(irq, 0, VCS_MI_USER_INTERRUPT, INTEL_GVT_IRQ_INFO_GT1);
0579 SET_BIT_INFO(irq, 4, VCS_MI_FLUSH_DW, INTEL_GVT_IRQ_INFO_GT1);
0580 SET_BIT_INFO(irq, 8, VCS_AS_CONTEXT_SWITCH, INTEL_GVT_IRQ_INFO_GT1);
0581
0582 if (HAS_ENGINE(gvt->gt, VCS1)) {
0583 SET_BIT_INFO(irq, 16, VCS2_MI_USER_INTERRUPT,
0584 INTEL_GVT_IRQ_INFO_GT1);
0585 SET_BIT_INFO(irq, 20, VCS2_MI_FLUSH_DW,
0586 INTEL_GVT_IRQ_INFO_GT1);
0587 SET_BIT_INFO(irq, 24, VCS2_AS_CONTEXT_SWITCH,
0588 INTEL_GVT_IRQ_INFO_GT1);
0589 }
0590
0591
0592 SET_BIT_INFO(irq, 0, VECS_MI_USER_INTERRUPT, INTEL_GVT_IRQ_INFO_GT3);
0593 SET_BIT_INFO(irq, 4, VECS_MI_FLUSH_DW, INTEL_GVT_IRQ_INFO_GT3);
0594 SET_BIT_INFO(irq, 8, VECS_AS_CONTEXT_SWITCH, INTEL_GVT_IRQ_INFO_GT3);
0595
0596 SET_BIT_INFO(irq, 0, PIPE_A_VBLANK, INTEL_GVT_IRQ_INFO_DE_PIPE_A);
0597 SET_BIT_INFO(irq, 0, PIPE_B_VBLANK, INTEL_GVT_IRQ_INFO_DE_PIPE_B);
0598 SET_BIT_INFO(irq, 0, PIPE_C_VBLANK, INTEL_GVT_IRQ_INFO_DE_PIPE_C);
0599
0600
0601 SET_BIT_INFO(irq, 0, AUX_CHANNEL_A, INTEL_GVT_IRQ_INFO_DE_PORT);
0602 SET_BIT_INFO(irq, 3, DP_A_HOTPLUG, INTEL_GVT_IRQ_INFO_DE_PORT);
0603
0604
0605 SET_BIT_INFO(irq, 0, GSE, INTEL_GVT_IRQ_INFO_DE_MISC);
0606
0607
0608 SET_BIT_INFO(irq, 17, GMBUS, INTEL_GVT_IRQ_INFO_PCH);
0609 SET_BIT_INFO(irq, 19, CRT_HOTPLUG, INTEL_GVT_IRQ_INFO_PCH);
0610 SET_BIT_INFO(irq, 21, DP_B_HOTPLUG, INTEL_GVT_IRQ_INFO_PCH);
0611 SET_BIT_INFO(irq, 22, DP_C_HOTPLUG, INTEL_GVT_IRQ_INFO_PCH);
0612 SET_BIT_INFO(irq, 23, DP_D_HOTPLUG, INTEL_GVT_IRQ_INFO_PCH);
0613
0614 if (IS_BROADWELL(gvt->gt->i915)) {
0615 SET_BIT_INFO(irq, 25, AUX_CHANNEL_B, INTEL_GVT_IRQ_INFO_PCH);
0616 SET_BIT_INFO(irq, 26, AUX_CHANNEL_C, INTEL_GVT_IRQ_INFO_PCH);
0617 SET_BIT_INFO(irq, 27, AUX_CHANNEL_D, INTEL_GVT_IRQ_INFO_PCH);
0618
0619 SET_BIT_INFO(irq, 4, PRIMARY_A_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_A);
0620 SET_BIT_INFO(irq, 5, SPRITE_A_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_A);
0621
0622 SET_BIT_INFO(irq, 4, PRIMARY_B_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_B);
0623 SET_BIT_INFO(irq, 5, SPRITE_B_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_B);
0624
0625 SET_BIT_INFO(irq, 4, PRIMARY_C_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_C);
0626 SET_BIT_INFO(irq, 5, SPRITE_C_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_C);
0627 } else if (GRAPHICS_VER(gvt->gt->i915) >= 9) {
0628 SET_BIT_INFO(irq, 25, AUX_CHANNEL_B, INTEL_GVT_IRQ_INFO_DE_PORT);
0629 SET_BIT_INFO(irq, 26, AUX_CHANNEL_C, INTEL_GVT_IRQ_INFO_DE_PORT);
0630 SET_BIT_INFO(irq, 27, AUX_CHANNEL_D, INTEL_GVT_IRQ_INFO_DE_PORT);
0631
0632 SET_BIT_INFO(irq, 3, PRIMARY_A_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_A);
0633 SET_BIT_INFO(irq, 3, PRIMARY_B_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_B);
0634 SET_BIT_INFO(irq, 3, PRIMARY_C_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_C);
0635
0636 SET_BIT_INFO(irq, 4, SPRITE_A_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_A);
0637 SET_BIT_INFO(irq, 4, SPRITE_B_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_B);
0638 SET_BIT_INFO(irq, 4, SPRITE_C_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_C);
0639 }
0640
0641
0642 SET_BIT_INFO(irq, 24, PCU_THERMAL, INTEL_GVT_IRQ_INFO_PCU);
0643 SET_BIT_INFO(irq, 25, PCU_PCODE2DRIVER_MAILBOX, INTEL_GVT_IRQ_INFO_PCU);
0644 }
0645
0646 static const struct intel_gvt_irq_ops gen8_irq_ops = {
0647 .init_irq = gen8_init_irq,
0648 .check_pending_irq = gen8_check_pending_irq,
0649 };
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661 void intel_vgpu_trigger_virtual_event(struct intel_vgpu *vgpu,
0662 enum intel_gvt_event_type event)
0663 {
0664 struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
0665 struct intel_gvt *gvt = vgpu->gvt;
0666 struct intel_gvt_irq *irq = &gvt->irq;
0667 gvt_event_virt_handler_t handler;
0668 const struct intel_gvt_irq_ops *ops = gvt->irq.ops;
0669
0670 handler = get_event_virt_handler(irq, event);
0671 drm_WARN_ON(&i915->drm, !handler);
0672
0673 handler(irq, event, vgpu);
0674
0675 ops->check_pending_irq(vgpu);
0676 }
0677
0678 static void init_events(
0679 struct intel_gvt_irq *irq)
0680 {
0681 int i;
0682
0683 for (i = 0; i < INTEL_GVT_EVENT_MAX; i++) {
0684 irq->events[i].info = NULL;
0685 irq->events[i].v_handler = handle_default_event_virt;
0686 }
0687 }
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699 int intel_gvt_init_irq(struct intel_gvt *gvt)
0700 {
0701 struct intel_gvt_irq *irq = &gvt->irq;
0702
0703 gvt_dbg_core("init irq framework\n");
0704
0705 irq->ops = &gen8_irq_ops;
0706 irq->irq_map = gen8_irq_map;
0707
0708
0709 init_events(irq);
0710
0711
0712 irq->ops->init_irq(irq);
0713
0714 init_irq_map(irq);
0715
0716 return 0;
0717 }