.. | .. |
---|
56 | 56 | |
---|
57 | 57 | /** |
---|
58 | 58 | * vgpu_pci_cfg_mem_write - write virtual cfg space memory |
---|
| 59 | + * @vgpu: target vgpu |
---|
| 60 | + * @off: offset |
---|
| 61 | + * @src: src ptr to write |
---|
| 62 | + * @bytes: number of bytes |
---|
59 | 63 | * |
---|
60 | 64 | * Use this function to write virtual cfg space memory. |
---|
61 | 65 | * For standard cfg space, only RW bits can be changed, |
---|
.. | .. |
---|
66 | 70 | { |
---|
67 | 71 | u8 *cfg_base = vgpu_cfg_space(vgpu); |
---|
68 | 72 | u8 mask, new, old; |
---|
| 73 | + pci_power_t pwr; |
---|
69 | 74 | int i = 0; |
---|
70 | 75 | |
---|
71 | 76 | for (; i < bytes && (off + i < sizeof(pci_cfg_space_rw_bmp)); i++) { |
---|
.. | .. |
---|
87 | 92 | /* For other configuration space directly copy as it is. */ |
---|
88 | 93 | if (i < bytes) |
---|
89 | 94 | memcpy(cfg_base + off + i, src + i, bytes - i); |
---|
| 95 | + |
---|
| 96 | + if (off == vgpu->cfg_space.pmcsr_off && vgpu->cfg_space.pmcsr_off) { |
---|
| 97 | + pwr = (pci_power_t __force)(*(u16*)(&vgpu_cfg_space(vgpu)[off]) |
---|
| 98 | + & PCI_PM_CTRL_STATE_MASK); |
---|
| 99 | + if (pwr == PCI_D3hot) |
---|
| 100 | + vgpu->d3_entered = true; |
---|
| 101 | + gvt_dbg_core("vgpu-%d power status changed to %d\n", |
---|
| 102 | + vgpu->id, pwr); |
---|
| 103 | + } |
---|
90 | 104 | } |
---|
91 | 105 | |
---|
92 | 106 | /** |
---|
93 | 107 | * intel_vgpu_emulate_cfg_read - emulate vGPU configuration space read |
---|
| 108 | + * @vgpu: target vgpu |
---|
| 109 | + * @offset: offset |
---|
| 110 | + * @p_data: return data ptr |
---|
| 111 | + * @bytes: number of bytes to read |
---|
94 | 112 | * |
---|
95 | 113 | * Returns: |
---|
96 | 114 | * Zero on success, negative error code if failed. |
---|
.. | .. |
---|
98 | 116 | int intel_vgpu_emulate_cfg_read(struct intel_vgpu *vgpu, unsigned int offset, |
---|
99 | 117 | void *p_data, unsigned int bytes) |
---|
100 | 118 | { |
---|
101 | | - if (WARN_ON(bytes > 4)) |
---|
| 119 | + struct drm_i915_private *i915 = vgpu->gvt->gt->i915; |
---|
| 120 | + |
---|
| 121 | + if (drm_WARN_ON(&i915->drm, bytes > 4)) |
---|
102 | 122 | return -EINVAL; |
---|
103 | 123 | |
---|
104 | | - if (WARN_ON(offset + bytes > vgpu->gvt->device_info.cfg_space_size)) |
---|
| 124 | + if (drm_WARN_ON(&i915->drm, |
---|
| 125 | + offset + bytes > vgpu->gvt->device_info.cfg_space_size)) |
---|
105 | 126 | return -EINVAL; |
---|
106 | 127 | |
---|
107 | 128 | memcpy(p_data, vgpu_cfg_space(vgpu) + offset, bytes); |
---|
.. | .. |
---|
278 | 299 | |
---|
279 | 300 | /** |
---|
280 | 301 | * intel_vgpu_emulate_cfg_read - emulate vGPU configuration space write |
---|
| 302 | + * @vgpu: target vgpu |
---|
| 303 | + * @offset: offset |
---|
| 304 | + * @p_data: write data ptr |
---|
| 305 | + * @bytes: number of bytes to write |
---|
281 | 306 | * |
---|
282 | 307 | * Returns: |
---|
283 | 308 | * Zero on success, negative error code if failed. |
---|
.. | .. |
---|
285 | 310 | int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset, |
---|
286 | 311 | void *p_data, unsigned int bytes) |
---|
287 | 312 | { |
---|
| 313 | + struct drm_i915_private *i915 = vgpu->gvt->gt->i915; |
---|
288 | 314 | int ret; |
---|
289 | 315 | |
---|
290 | | - if (WARN_ON(bytes > 4)) |
---|
| 316 | + if (drm_WARN_ON(&i915->drm, bytes > 4)) |
---|
291 | 317 | return -EINVAL; |
---|
292 | 318 | |
---|
293 | | - if (WARN_ON(offset + bytes > vgpu->gvt->device_info.cfg_space_size)) |
---|
| 319 | + if (drm_WARN_ON(&i915->drm, |
---|
| 320 | + offset + bytes > vgpu->gvt->device_info.cfg_space_size)) |
---|
294 | 321 | return -EINVAL; |
---|
295 | 322 | |
---|
296 | 323 | /* First check if it's PCI_COMMAND */ |
---|
297 | 324 | if (IS_ALIGNED(offset, 2) && offset == PCI_COMMAND) { |
---|
298 | | - if (WARN_ON(bytes > 2)) |
---|
| 325 | + if (drm_WARN_ON(&i915->drm, bytes > 2)) |
---|
299 | 326 | return -EINVAL; |
---|
300 | 327 | return emulate_pci_command_write(vgpu, offset, p_data, bytes); |
---|
301 | 328 | } |
---|
302 | 329 | |
---|
303 | 330 | switch (rounddown(offset, 4)) { |
---|
304 | 331 | case PCI_ROM_ADDRESS: |
---|
305 | | - if (WARN_ON(!IS_ALIGNED(offset, 4))) |
---|
| 332 | + if (drm_WARN_ON(&i915->drm, !IS_ALIGNED(offset, 4))) |
---|
306 | 333 | return -EINVAL; |
---|
307 | 334 | return emulate_pci_rom_bar_write(vgpu, offset, p_data, bytes); |
---|
308 | 335 | |
---|
309 | 336 | case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_5: |
---|
310 | | - if (WARN_ON(!IS_ALIGNED(offset, 4))) |
---|
| 337 | + if (drm_WARN_ON(&i915->drm, !IS_ALIGNED(offset, 4))) |
---|
311 | 338 | return -EINVAL; |
---|
312 | 339 | return emulate_pci_bar_write(vgpu, offset, p_data, bytes); |
---|
313 | 340 | |
---|
314 | 341 | case INTEL_GVT_PCI_SWSCI: |
---|
315 | | - if (WARN_ON(!IS_ALIGNED(offset, 4))) |
---|
| 342 | + if (drm_WARN_ON(&i915->drm, !IS_ALIGNED(offset, 4))) |
---|
316 | 343 | return -EINVAL; |
---|
317 | 344 | ret = intel_vgpu_emulate_opregion_request(vgpu, *(u32 *)p_data); |
---|
318 | 345 | if (ret) |
---|
.. | .. |
---|
320 | 347 | break; |
---|
321 | 348 | |
---|
322 | 349 | case INTEL_GVT_PCI_OPREGION: |
---|
323 | | - if (WARN_ON(!IS_ALIGNED(offset, 4))) |
---|
| 350 | + if (drm_WARN_ON(&i915->drm, !IS_ALIGNED(offset, 4))) |
---|
324 | 351 | return -EINVAL; |
---|
325 | 352 | ret = intel_vgpu_opregion_base_write_handler(vgpu, |
---|
326 | 353 | *(u32 *)p_data); |
---|
.. | .. |
---|
349 | 376 | struct intel_gvt *gvt = vgpu->gvt; |
---|
350 | 377 | const struct intel_gvt_device_info *info = &gvt->device_info; |
---|
351 | 378 | u16 *gmch_ctl; |
---|
| 379 | + u8 next; |
---|
352 | 380 | |
---|
353 | 381 | memcpy(vgpu_cfg_space(vgpu), gvt->firmware.cfg_space, |
---|
354 | 382 | info->cfg_space_size); |
---|
.. | .. |
---|
379 | 407 | memset(vgpu_cfg_space(vgpu) + INTEL_GVT_PCI_OPREGION, 0, 4); |
---|
380 | 408 | |
---|
381 | 409 | vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_GTTMMIO].size = |
---|
382 | | - pci_resource_len(gvt->dev_priv->drm.pdev, 0); |
---|
| 410 | + pci_resource_len(gvt->gt->i915->drm.pdev, 0); |
---|
383 | 411 | vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].size = |
---|
384 | | - pci_resource_len(gvt->dev_priv->drm.pdev, 2); |
---|
| 412 | + pci_resource_len(gvt->gt->i915->drm.pdev, 2); |
---|
385 | 413 | |
---|
386 | 414 | memset(vgpu_cfg_space(vgpu) + PCI_ROM_ADDRESS, 0, 4); |
---|
| 415 | + |
---|
| 416 | + /* PM Support */ |
---|
| 417 | + vgpu->cfg_space.pmcsr_off = 0; |
---|
| 418 | + if (vgpu_cfg_space(vgpu)[PCI_STATUS] & PCI_STATUS_CAP_LIST) { |
---|
| 419 | + next = vgpu_cfg_space(vgpu)[PCI_CAPABILITY_LIST]; |
---|
| 420 | + do { |
---|
| 421 | + if (vgpu_cfg_space(vgpu)[next + PCI_CAP_LIST_ID] == PCI_CAP_ID_PM) { |
---|
| 422 | + vgpu->cfg_space.pmcsr_off = next + PCI_PM_CTRL; |
---|
| 423 | + break; |
---|
| 424 | + } |
---|
| 425 | + next = vgpu_cfg_space(vgpu)[next + PCI_CAP_LIST_NEXT]; |
---|
| 426 | + } while (next); |
---|
| 427 | + } |
---|
387 | 428 | } |
---|
388 | 429 | |
---|
389 | 430 | /** |
---|