mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge tag 'drm-intel-testing-2017-04-03' of git://anongit.freedesktop.org/git/drm-intel into drm-next
Last 4.12 feature pile: GVT updates: - Add mdev attribute group for per-vgpu info - Time slice based vGPU scheduling QoS support (Gao Ping) - Initial KBL support for E3 server (Han Xu) - other misc. i915: - lots and lots of small fixes and improvements all over - refactor fw_domain code (Chris Wilson) - improve guc code (Oscar Mateo) - refactor cursor/sprite code, precompute more for less overhead in the critical path (Ville) - refactor guc/huc fw loading code a bit (Michal Wajdeczko) * tag 'drm-intel-testing-2017-04-03' of git://anongit.freedesktop.org/git/drm-intel: (121 commits) drm/i915: Update DRIVER_DATE to 20170403 drm/i915: Clear gt.active_requests before checking idle status drm/i915/uc: Drop use of MISSING_CASE on trivial enums drm/i915: make a few DDI functions static drm/i915: Combine reset_all_global_seqno() loops into one drm/i915: Remove redudant wait for each engine to idle from seqno wrap drm/i915: Wait for all engines to be idle as part of i915_gem_wait_for_idle() drm/i915: Move retire-requests into i915_gem_wait_for_idle() drm/i915/uc: Move fw path check to fetch_uc_fw() drm/i915/huc: Remove unused intel_huc_fini() drm/i915/uc: Add intel_uc_fw_fini() drm/i915/uc: Add intel_uc_fw_type_repr() drm/i915/uc: Move intel_uc_fw_status_repr() to intel_uc.h drivers: gpu: drm: i915L intel_lpe_audio: Fix kerneldoc comments drm/i915: Suppress busy status for engines if wedged drm/i915: Do request retirement before marking engines as wedged drm/i915: Drop verbose and archaic "ring" from our internal engine names drm/i915: Use a dummy timeline name for a signaled fence drm/i915: Ironlake do_idle_maps w/a may be called w/o struct_mutex drm/i915/guc: Take enable_guc_loading check out of GEM core code ...
This commit is contained in:
commit
2b2fc72aa5
60 files changed
+2633
-2029
No files matched your search
@@ -1215,7 +1215,7 @@ static int gen8_check_mi_display_flip(struct parser_exec_state *s,
|
||||
if (!info->async_flip)
|
||||
return 0;
|
||||
|
||||
if (IS_SKYLAKE(dev_priv)) {
|
||||
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
|
||||
stride = vgpu_vreg(s->vgpu, info->stride_reg) & GENMASK(9, 0);
|
||||
tile = (vgpu_vreg(s->vgpu, info->ctrl_reg) &
|
||||
GENMASK(12, 10)) >> 10;
|
||||
@@ -1243,7 +1243,7 @@ static int gen8_update_plane_mmio_from_mi_display_flip(
|
||||
|
||||
set_mask_bits(&vgpu_vreg(vgpu, info->surf_reg), GENMASK(31, 12),
|
||||
info->surf_val << 12);
|
||||
if (IS_SKYLAKE(dev_priv)) {
|
||||
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
|
||||
set_mask_bits(&vgpu_vreg(vgpu, info->stride_reg), GENMASK(9, 0),
|
||||
info->stride_val);
|
||||
set_mask_bits(&vgpu_vreg(vgpu, info->ctrl_reg), GENMASK(12, 10),
|
||||
@@ -1267,7 +1267,7 @@ static int decode_mi_display_flip(struct parser_exec_state *s,
|
||||
|
||||
if (IS_BROADWELL(dev_priv))
|
||||
return gen8_decode_mi_display_flip(s, info);
|
||||
if (IS_SKYLAKE(dev_priv))
|
||||
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
|
||||
return skl_decode_mi_display_flip(s, info);
|
||||
|
||||
return -ENODEV;
|
||||
@@ -1278,7 +1278,9 @@ static int check_mi_display_flip(struct parser_exec_state *s,
|
||||
{
|
||||
struct drm_i915_private *dev_priv = s->vgpu->gvt->dev_priv;
|
||||
|
||||
if (IS_BROADWELL(dev_priv) || IS_SKYLAKE(dev_priv))
|
||||
if (IS_BROADWELL(dev_priv)
|
||||
|| IS_SKYLAKE(dev_priv)
|
||||
|| IS_KABYLAKE(dev_priv))
|
||||
return gen8_check_mi_display_flip(s, info);
|
||||
return -ENODEV;
|
||||
}
|
||||
@@ -1289,7 +1291,9 @@ static int update_plane_mmio_from_mi_display_flip(
|
||||
{
|
||||
struct drm_i915_private *dev_priv = s->vgpu->gvt->dev_priv;
|
||||
|
||||
if (IS_BROADWELL(dev_priv) || IS_SKYLAKE(dev_priv))
|
||||
if (IS_BROADWELL(dev_priv)
|
||||
|| IS_SKYLAKE(dev_priv)
|
||||
|| IS_KABYLAKE(dev_priv))
|
||||
return gen8_update_plane_mmio_from_mi_display_flip(s, info);
|
||||
return -ENODEV;
|
||||
}
|
||||
@@ -1569,7 +1573,8 @@ static int batch_buffer_needs_scan(struct parser_exec_state *s)
|
||||
{
|
||||
struct intel_gvt *gvt = s->vgpu->gvt;
|
||||
|
||||
if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv)) {
|
||||
if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv)
|
||||
|| IS_KABYLAKE(gvt->dev_priv)) {
|
||||
/* BDW decides privilege based on address space */
|
||||
if (cmd_val(s, 0) & (1 << 8))
|
||||
return 0;
|
||||
@@ -2604,6 +2609,9 @@ static int scan_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
|
||||
unsigned long gma_head, gma_tail, gma_bottom, ring_size, ring_tail;
|
||||
struct parser_exec_state s;
|
||||
int ret = 0;
|
||||
struct intel_vgpu_workload *workload = container_of(wa_ctx,
|
||||
struct intel_vgpu_workload,
|
||||
wa_ctx);
|
||||
|
||||
/* ring base is page aligned */
|
||||
if (WARN_ON(!IS_ALIGNED(wa_ctx->indirect_ctx.guest_gma, GTT_PAGE_SIZE)))
|
||||
@@ -2618,14 +2626,14 @@ static int scan_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
|
||||
|
||||
s.buf_type = RING_BUFFER_INSTRUCTION;
|
||||
s.buf_addr_type = GTT_BUFFER;
|
||||
s.vgpu = wa_ctx->workload->vgpu;
|
||||
s.ring_id = wa_ctx->workload->ring_id;
|
||||
s.vgpu = workload->vgpu;
|
||||
s.ring_id = workload->ring_id;
|
||||
s.ring_start = wa_ctx->indirect_ctx.guest_gma;
|
||||
s.ring_size = ring_size;
|
||||
s.ring_head = gma_head;
|
||||
s.ring_tail = gma_tail;
|
||||
s.rb_va = wa_ctx->indirect_ctx.shadow_va;
|
||||
s.workload = wa_ctx->workload;
|
||||
s.workload = workload;
|
||||
|
||||
ret = ip_gma_set(&s, gma_head);
|
||||
if (ret)
|
||||
@@ -2708,12 +2716,15 @@ static int shadow_indirect_ctx(struct intel_shadow_wa_ctx *wa_ctx)
|
||||
{
|
||||
int ctx_size = wa_ctx->indirect_ctx.size;
|
||||
unsigned long guest_gma = wa_ctx->indirect_ctx.guest_gma;
|
||||
struct intel_vgpu *vgpu = wa_ctx->workload->vgpu;
|
||||
struct intel_vgpu_workload *workload = container_of(wa_ctx,
|
||||
struct intel_vgpu_workload,
|
||||
wa_ctx);
|
||||
struct intel_vgpu *vgpu = workload->vgpu;
|
||||
struct drm_i915_gem_object *obj;
|
||||
int ret = 0;
|
||||
void *map;
|
||||
|
||||
obj = i915_gem_object_create(wa_ctx->workload->vgpu->gvt->dev_priv,
|
||||
obj = i915_gem_object_create(workload->vgpu->gvt->dev_priv,
|
||||
roundup(ctx_size + CACHELINE_BYTES,
|
||||
PAGE_SIZE));
|
||||
if (IS_ERR(obj))
|
||||
@@ -2733,8 +2744,8 @@ static int shadow_indirect_ctx(struct intel_shadow_wa_ctx *wa_ctx)
|
||||
goto unmap_src;
|
||||
}
|
||||
|
||||
ret = copy_gma_to_hva(wa_ctx->workload->vgpu,
|
||||
wa_ctx->workload->vgpu->gtt.ggtt_mm,
|
||||
ret = copy_gma_to_hva(workload->vgpu,
|
||||
workload->vgpu->gtt.ggtt_mm,
|
||||
guest_gma, guest_gma + ctx_size,
|
||||
map);
|
||||
if (ret < 0) {
|
||||
@@ -2772,7 +2783,10 @@ static int combine_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
|
||||
int intel_gvt_scan_and_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
|
||||
{
|
||||
int ret;
|
||||
struct intel_vgpu *vgpu = wa_ctx->workload->vgpu;
|
||||
struct intel_vgpu_workload *workload = container_of(wa_ctx,
|
||||
struct intel_vgpu_workload,
|
||||
wa_ctx);
|
||||
struct intel_vgpu *vgpu = workload->vgpu;
|
||||
|
||||
if (wa_ctx->indirect_ctx.size == 0)
|
||||
return 0;
|
||||
|
||||
@@ -161,8 +161,9 @@ static unsigned char virtual_dp_monitor_edid[GVT_EDID_NUM][EDID_SIZE] = {
|
||||
|
||||
#define DPCD_HEADER_SIZE 0xb
|
||||
|
||||
/* let the virtual display supports DP1.2 */
|
||||
static u8 dpcd_fix_data[DPCD_HEADER_SIZE] = {
|
||||
0x11, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
0x12, 0x014, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
|
||||
@@ -172,9 +173,20 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
|
||||
SDE_PORTC_HOTPLUG_CPT |
|
||||
SDE_PORTD_HOTPLUG_CPT);
|
||||
|
||||
if (IS_SKYLAKE(dev_priv))
|
||||
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
|
||||
vgpu_vreg(vgpu, SDEISR) &= ~(SDE_PORTA_HOTPLUG_SPT |
|
||||
SDE_PORTE_HOTPLUG_SPT);
|
||||
vgpu_vreg(vgpu, SKL_FUSE_STATUS) |=
|
||||
SKL_FUSE_DOWNLOAD_STATUS |
|
||||
SKL_FUSE_PG0_DIST_STATUS |
|
||||
SKL_FUSE_PG1_DIST_STATUS |
|
||||
SKL_FUSE_PG2_DIST_STATUS;
|
||||
vgpu_vreg(vgpu, LCPLL1_CTL) |=
|
||||
LCPLL_PLL_ENABLE |
|
||||
LCPLL_PLL_LOCK;
|
||||
vgpu_vreg(vgpu, LCPLL2_CTL) |= LCPLL_PLL_ENABLE;
|
||||
|
||||
}
|
||||
|
||||
if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
|
||||
vgpu_vreg(vgpu, SDEISR) |= SDE_PORTB_HOTPLUG_CPT;
|
||||
@@ -191,7 +203,7 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
|
||||
vgpu_vreg(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDID_DETECTED;
|
||||
}
|
||||
|
||||
if (IS_SKYLAKE(dev_priv) &&
|
||||
if ((IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) &&
|
||||
intel_vgpu_has_monitor_on_port(vgpu, PORT_E)) {
|
||||
vgpu_vreg(vgpu, SDEISR) |= SDE_PORTE_HOTPLUG_SPT;
|
||||
}
|
||||
@@ -353,7 +365,7 @@ void intel_vgpu_clean_display(struct intel_vgpu *vgpu)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
|
||||
|
||||
if (IS_SKYLAKE(dev_priv))
|
||||
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
|
||||
clean_virtual_dp_monitor(vgpu, PORT_D);
|
||||
else
|
||||
clean_virtual_dp_monitor(vgpu, PORT_B);
|
||||
@@ -375,7 +387,7 @@ int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 resolution)
|
||||
|
||||
intel_vgpu_init_i2c_edid(vgpu);
|
||||
|
||||
if (IS_SKYLAKE(dev_priv))
|
||||
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
|
||||
return setup_virtual_dp_monitor(vgpu, PORT_D, GVT_DP_D,
|
||||
resolution);
|
||||
else
|
||||
|
||||
@@ -394,9 +394,11 @@ static void prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload)
|
||||
|
||||
static int update_wa_ctx_2_shadow_ctx(struct intel_shadow_wa_ctx *wa_ctx)
|
||||
{
|
||||
int ring_id = wa_ctx->workload->ring_id;
|
||||
struct i915_gem_context *shadow_ctx =
|
||||
wa_ctx->workload->vgpu->shadow_ctx;
|
||||
struct intel_vgpu_workload *workload = container_of(wa_ctx,
|
||||
struct intel_vgpu_workload,
|
||||
wa_ctx);
|
||||
int ring_id = workload->ring_id;
|
||||
struct i915_gem_context *shadow_ctx = workload->vgpu->shadow_ctx;
|
||||
struct drm_i915_gem_object *ctx_obj =
|
||||
shadow_ctx->engine[ring_id].state->obj;
|
||||
struct execlist_ring_context *shadow_ring_context;
|
||||
@@ -680,7 +682,6 @@ static int submit_context(struct intel_vgpu *vgpu, int ring_id,
|
||||
CACHELINE_BYTES;
|
||||
workload->wa_ctx.per_ctx.guest_gma =
|
||||
per_ctx & PER_CTX_ADDR_MASK;
|
||||
workload->wa_ctx.workload = workload;
|
||||
|
||||
WARN_ON(workload->wa_ctx.indirect_ctx.size && !(per_ctx & 0x1));
|
||||
}
|
||||
|
||||
@@ -2220,7 +2220,8 @@ int intel_gvt_init_gtt(struct intel_gvt *gvt)
|
||||
|
||||
gvt_dbg_core("init gtt\n");
|
||||
|
||||
if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv)) {
|
||||
if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv)
|
||||
|| IS_KABYLAKE(gvt->dev_priv)) {
|
||||
gvt->gtt.pte_ops = &gen8_gtt_pte_ops;
|
||||
gvt->gtt.gma_ops = &gen8_gtt_gma_ops;
|
||||
gvt->gtt.mm_alloc_page_table = gen8_mm_alloc_page_table;
|
||||
|
||||
@@ -106,7 +106,8 @@ static void init_device_info(struct intel_gvt *gvt)
|
||||
struct intel_gvt_device_info *info = &gvt->device_info;
|
||||
struct pci_dev *pdev = gvt->dev_priv->drm.pdev;
|
||||
|
||||
if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv)) {
|
||||
if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv)
|
||||
|| IS_KABYLAKE(gvt->dev_priv)) {
|
||||
info->max_support_vgpus = 8;
|
||||
info->cfg_space_size = 256;
|
||||
info->mmio_size = 2 * 1024 * 1024;
|
||||
@@ -143,6 +144,11 @@ static int gvt_service_thread(void *data)
|
||||
intel_gvt_emulate_vblank(gvt);
|
||||
mutex_unlock(&gvt->lock);
|
||||
}
|
||||
|
||||
if (test_and_clear_bit(INTEL_GVT_REQUEST_SCHED,
|
||||
(void *)&gvt->service_request)) {
|
||||
intel_gvt_schedule(gvt);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -196,6 +202,8 @@ void intel_gvt_clean_device(struct drm_i915_private *dev_priv)
|
||||
|
||||
idr_destroy(&gvt->vgpu_idr);
|
||||
|
||||
intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
|
||||
|
||||
kfree(dev_priv->gvt);
|
||||
dev_priv->gvt = NULL;
|
||||
}
|
||||
@@ -214,6 +222,7 @@ void intel_gvt_clean_device(struct drm_i915_private *dev_priv)
|
||||
int intel_gvt_init_device(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_gvt *gvt;
|
||||
struct intel_vgpu *vgpu;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
@@ -286,6 +295,14 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)
|
||||
goto out_clean_types;
|
||||
}
|
||||
|
||||
vgpu = intel_gvt_create_idle_vgpu(gvt);
|
||||
if (IS_ERR(vgpu)) {
|
||||
ret = PTR_ERR(vgpu);
|
||||
gvt_err("failed to create idle vgpu\n");
|
||||
goto out_clean_types;
|
||||
}
|
||||
gvt->idle_vgpu = vgpu;
|
||||
|
||||
gvt_dbg_core("gvt device initialization is done\n");
|
||||
dev_priv->gvt = gvt;
|
||||
return 0;
|
||||
|
||||
@@ -138,6 +138,10 @@ struct intel_vgpu_display {
|
||||
struct intel_vgpu_sbi sbi;
|
||||
};
|
||||
|
||||
struct vgpu_sched_ctl {
|
||||
int weight;
|
||||
};
|
||||
|
||||
struct intel_vgpu {
|
||||
struct intel_gvt *gvt;
|
||||
int id;
|
||||
@@ -147,6 +151,7 @@ struct intel_vgpu {
|
||||
bool failsafe;
|
||||
bool resetting;
|
||||
void *sched_data;
|
||||
struct vgpu_sched_ctl sched_ctl;
|
||||
|
||||
struct intel_vgpu_fence fence;
|
||||
struct intel_vgpu_gm gm;
|
||||
@@ -160,6 +165,7 @@ struct intel_vgpu {
|
||||
struct list_head workload_q_head[I915_NUM_ENGINES];
|
||||
struct kmem_cache *workloads;
|
||||
atomic_t running_workload_num;
|
||||
ktime_t last_ctx_submit_time;
|
||||
DECLARE_BITMAP(tlb_handle_pending, I915_NUM_ENGINES);
|
||||
struct i915_gem_context *shadow_ctx;
|
||||
|
||||
@@ -215,6 +221,7 @@ struct intel_vgpu_type {
|
||||
unsigned int low_gm_size;
|
||||
unsigned int high_gm_size;
|
||||
unsigned int fence;
|
||||
unsigned int weight;
|
||||
enum intel_vgpu_edid resolution;
|
||||
};
|
||||
|
||||
@@ -236,6 +243,7 @@ struct intel_gvt {
|
||||
DECLARE_HASHTABLE(cmd_table, GVT_CMD_HASH_BITS);
|
||||
struct intel_vgpu_type *types;
|
||||
unsigned int num_types;
|
||||
struct intel_vgpu *idle_vgpu;
|
||||
|
||||
struct task_struct *service_thread;
|
||||
wait_queue_head_t service_thread_wq;
|
||||
@@ -249,6 +257,7 @@ static inline struct intel_gvt *to_gvt(struct drm_i915_private *i915)
|
||||
|
||||
enum {
|
||||
INTEL_GVT_REQUEST_EMULATE_VBLANK = 0,
|
||||
INTEL_GVT_REQUEST_SCHED = 1,
|
||||
};
|
||||
|
||||
static inline void intel_gvt_request_service(struct intel_gvt *gvt,
|
||||
@@ -322,6 +331,8 @@ struct intel_vgpu_creation_params {
|
||||
__u64 resolution;
|
||||
__s32 primary;
|
||||
__u64 vgpu_id;
|
||||
|
||||
__u32 weight;
|
||||
};
|
||||
|
||||
int intel_vgpu_alloc_resource(struct intel_vgpu *vgpu,
|
||||
@@ -376,6 +387,8 @@ static inline void intel_vgpu_write_pci_bar(struct intel_vgpu *vgpu,
|
||||
int intel_gvt_init_vgpu_types(struct intel_gvt *gvt);
|
||||
void intel_gvt_clean_vgpu_types(struct intel_gvt *gvt);
|
||||
|
||||
struct intel_vgpu *intel_gvt_create_idle_vgpu(struct intel_gvt *gvt);
|
||||
void intel_gvt_destroy_idle_vgpu(struct intel_vgpu *vgpu);
|
||||
struct intel_vgpu *intel_gvt_create_vgpu(struct intel_gvt *gvt,
|
||||
struct intel_vgpu_type *type);
|
||||
void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu);
|
||||
|
||||
+191
-170
@@ -68,6 +68,8 @@ unsigned long intel_gvt_get_device_type(struct intel_gvt *gvt)
|
||||
return D_BDW;
|
||||
else if (IS_SKYLAKE(gvt->dev_priv))
|
||||
return D_SKL;
|
||||
else if (IS_KABYLAKE(gvt->dev_priv))
|
||||
return D_KBL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -234,7 +236,8 @@ static int mul_force_wake_write(struct intel_vgpu *vgpu,
|
||||
old = vgpu_vreg(vgpu, offset);
|
||||
new = CALC_MODE_MASK_REG(old, *(u32 *)p_data);
|
||||
|
||||
if (IS_SKYLAKE(vgpu->gvt->dev_priv)) {
|
||||
if (IS_SKYLAKE(vgpu->gvt->dev_priv)
|
||||
|| IS_KABYLAKE(vgpu->gvt->dev_priv)) {
|
||||
switch (offset) {
|
||||
case FORCEWAKE_RENDER_GEN9_REG:
|
||||
ack_reg_offset = FORCEWAKE_ACK_RENDER_GEN9_REG;
|
||||
@@ -823,8 +826,9 @@ static int dp_aux_ch_ctl_mmio_write(struct intel_vgpu *vgpu,
|
||||
write_vreg(vgpu, offset, p_data, bytes);
|
||||
data = vgpu_vreg(vgpu, offset);
|
||||
|
||||
if (IS_SKYLAKE(vgpu->gvt->dev_priv) &&
|
||||
offset != _REG_SKL_DP_AUX_CH_CTL(port_index)) {
|
||||
if ((IS_SKYLAKE(vgpu->gvt->dev_priv)
|
||||
|| IS_KABYLAKE(vgpu->gvt->dev_priv))
|
||||
&& offset != _REG_SKL_DP_AUX_CH_CTL(port_index)) {
|
||||
/* SKL DPB/C/D aux ctl register changed */
|
||||
return 0;
|
||||
} else if (IS_BROADWELL(vgpu->gvt->dev_priv) &&
|
||||
@@ -1303,7 +1307,8 @@ static int mailbox_write(struct intel_vgpu *vgpu, unsigned int offset,
|
||||
|
||||
switch (cmd) {
|
||||
case GEN9_PCODE_READ_MEM_LATENCY:
|
||||
if (IS_SKYLAKE(vgpu->gvt->dev_priv)) {
|
||||
if (IS_SKYLAKE(vgpu->gvt->dev_priv)
|
||||
|| IS_KABYLAKE(vgpu->gvt->dev_priv)) {
|
||||
/**
|
||||
* "Read memory latency" command on gen9.
|
||||
* Below memory latency values are read
|
||||
@@ -1316,7 +1321,8 @@ static int mailbox_write(struct intel_vgpu *vgpu, unsigned int offset,
|
||||
}
|
||||
break;
|
||||
case SKL_PCODE_CDCLK_CONTROL:
|
||||
if (IS_SKYLAKE(vgpu->gvt->dev_priv))
|
||||
if (IS_SKYLAKE(vgpu->gvt->dev_priv)
|
||||
|| IS_KABYLAKE(vgpu->gvt->dev_priv))
|
||||
*data0 = SKL_CDCLK_READY_FOR_CHANGE;
|
||||
break;
|
||||
case GEN6_PCODE_READ_RC6VIDS:
|
||||
@@ -1410,6 +1416,7 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
|
||||
|
||||
execlist->elsp_dwords.data[execlist->elsp_dwords.index] = data;
|
||||
if (execlist->elsp_dwords.index == 3) {
|
||||
vgpu->last_ctx_submit_time = ktime_get();
|
||||
ret = intel_vgpu_submit_execlist(vgpu, ring_id);
|
||||
if(ret)
|
||||
gvt_vgpu_err("fail submit workload on ring %d\n",
|
||||
@@ -2584,219 +2591,232 @@ static int init_skl_mmio_info(struct intel_gvt *gvt)
|
||||
MMIO_DH(FORCEWAKE_MEDIA_GEN9, D_SKL_PLUS, NULL, mul_force_wake_write);
|
||||
MMIO_DH(FORCEWAKE_ACK_MEDIA_GEN9, D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_F(_DPB_AUX_CH_CTL, 6 * 4, 0, 0, 0, D_SKL, NULL, dp_aux_ch_ctl_mmio_write);
|
||||
MMIO_F(_DPC_AUX_CH_CTL, 6 * 4, 0, 0, 0, D_SKL, NULL, dp_aux_ch_ctl_mmio_write);
|
||||
MMIO_F(_DPD_AUX_CH_CTL, 6 * 4, 0, 0, 0, D_SKL, NULL, dp_aux_ch_ctl_mmio_write);
|
||||
MMIO_F(_DPB_AUX_CH_CTL, 6 * 4, 0, 0, 0, D_SKL_PLUS, NULL,
|
||||
dp_aux_ch_ctl_mmio_write);
|
||||
MMIO_F(_DPC_AUX_CH_CTL, 6 * 4, 0, 0, 0, D_SKL_PLUS, NULL,
|
||||
dp_aux_ch_ctl_mmio_write);
|
||||
MMIO_F(_DPD_AUX_CH_CTL, 6 * 4, 0, 0, 0, D_SKL_PLUS, NULL,
|
||||
dp_aux_ch_ctl_mmio_write);
|
||||
|
||||
MMIO_D(HSW_PWR_WELL_BIOS, D_SKL);
|
||||
MMIO_DH(HSW_PWR_WELL_DRIVER, D_SKL, NULL, skl_power_well_ctl_write);
|
||||
MMIO_D(HSW_PWR_WELL_BIOS, D_SKL_PLUS);
|
||||
MMIO_DH(HSW_PWR_WELL_DRIVER, D_SKL_PLUS, NULL,
|
||||
skl_power_well_ctl_write);
|
||||
MMIO_DH(GEN6_PCODE_MAILBOX, D_SKL_PLUS, NULL, mailbox_write);
|
||||
|
||||
MMIO_D(0xa210, D_SKL_PLUS);
|
||||
MMIO_D(GEN9_MEDIA_PG_IDLE_HYSTERESIS, D_SKL_PLUS);
|
||||
MMIO_D(GEN9_RENDER_PG_IDLE_HYSTERESIS, D_SKL_PLUS);
|
||||
MMIO_DFH(GEN9_GAMT_ECO_REG_RW_IA, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
|
||||
MMIO_DH(0x4ddc, D_SKL, NULL, skl_misc_ctl_write);
|
||||
MMIO_DH(0x42080, D_SKL, NULL, skl_misc_ctl_write);
|
||||
MMIO_D(0x45504, D_SKL);
|
||||
MMIO_D(0x45520, D_SKL);
|
||||
MMIO_D(0x46000, D_SKL);
|
||||
MMIO_DH(0x46010, D_SKL, NULL, skl_lcpll_write);
|
||||
MMIO_DH(0x46014, D_SKL, NULL, skl_lcpll_write);
|
||||
MMIO_D(0x6C040, D_SKL);
|
||||
MMIO_D(0x6C048, D_SKL);
|
||||
MMIO_D(0x6C050, D_SKL);
|
||||
MMIO_D(0x6C044, D_SKL);
|
||||
MMIO_D(0x6C04C, D_SKL);
|
||||
MMIO_D(0x6C054, D_SKL);
|
||||
MMIO_D(0x6c058, D_SKL);
|
||||
MMIO_D(0x6c05c, D_SKL);
|
||||
MMIO_DH(0X6c060, D_SKL, dpll_status_read, NULL);
|
||||
MMIO_DH(0x4ddc, D_SKL_PLUS, NULL, skl_misc_ctl_write);
|
||||
MMIO_DH(0x42080, D_SKL_PLUS, NULL, skl_misc_ctl_write);
|
||||
MMIO_D(0x45504, D_SKL_PLUS);
|
||||
MMIO_D(0x45520, D_SKL_PLUS);
|
||||
MMIO_D(0x46000, D_SKL_PLUS);
|
||||
MMIO_DH(0x46010, D_SKL | D_KBL, NULL, skl_lcpll_write);
|
||||
MMIO_DH(0x46014, D_SKL | D_KBL, NULL, skl_lcpll_write);
|
||||
MMIO_D(0x6C040, D_SKL | D_KBL);
|
||||
MMIO_D(0x6C048, D_SKL | D_KBL);
|
||||
MMIO_D(0x6C050, D_SKL | D_KBL);
|
||||
MMIO_D(0x6C044, D_SKL | D_KBL);
|
||||
MMIO_D(0x6C04C, D_SKL | D_KBL);
|
||||
MMIO_D(0x6C054, D_SKL | D_KBL);
|
||||
MMIO_D(0x6c058, D_SKL | D_KBL);
|
||||
MMIO_D(0x6c05c, D_SKL | D_KBL);
|
||||
MMIO_DH(0X6c060, D_SKL | D_KBL, dpll_status_read, NULL);
|
||||
|
||||
MMIO_DH(SKL_PS_WIN_POS(PIPE_A, 0), D_SKL, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_POS(PIPE_A, 1), D_SKL, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_POS(PIPE_B, 0), D_SKL, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_POS(PIPE_B, 1), D_SKL, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_POS(PIPE_C, 0), D_SKL, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_POS(PIPE_C, 1), D_SKL, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_POS(PIPE_A, 0), D_SKL_PLUS, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_POS(PIPE_A, 1), D_SKL_PLUS, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_POS(PIPE_B, 0), D_SKL_PLUS, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_POS(PIPE_B, 1), D_SKL_PLUS, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_POS(PIPE_C, 0), D_SKL_PLUS, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_POS(PIPE_C, 1), D_SKL_PLUS, NULL, pf_write);
|
||||
|
||||
MMIO_DH(SKL_PS_WIN_SZ(PIPE_A, 0), D_SKL, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_SZ(PIPE_A, 1), D_SKL, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_SZ(PIPE_B, 0), D_SKL, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_SZ(PIPE_B, 1), D_SKL, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_SZ(PIPE_C, 0), D_SKL, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_SZ(PIPE_C, 1), D_SKL, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_SZ(PIPE_A, 0), D_SKL_PLUS, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_SZ(PIPE_A, 1), D_SKL_PLUS, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_SZ(PIPE_B, 0), D_SKL_PLUS, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_SZ(PIPE_B, 1), D_SKL_PLUS, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_SZ(PIPE_C, 0), D_SKL_PLUS, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_WIN_SZ(PIPE_C, 1), D_SKL_PLUS, NULL, pf_write);
|
||||
|
||||
MMIO_DH(SKL_PS_CTRL(PIPE_A, 0), D_SKL, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_CTRL(PIPE_A, 1), D_SKL, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_CTRL(PIPE_B, 0), D_SKL, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_CTRL(PIPE_B, 1), D_SKL, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_CTRL(PIPE_C, 0), D_SKL, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_CTRL(PIPE_C, 1), D_SKL, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_CTRL(PIPE_A, 0), D_SKL_PLUS, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_CTRL(PIPE_A, 1), D_SKL_PLUS, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_CTRL(PIPE_B, 0), D_SKL_PLUS, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_CTRL(PIPE_B, 1), D_SKL_PLUS, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_CTRL(PIPE_C, 0), D_SKL_PLUS, NULL, pf_write);
|
||||
MMIO_DH(SKL_PS_CTRL(PIPE_C, 1), D_SKL_PLUS, NULL, pf_write);
|
||||
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_A, 0), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_A, 1), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_A, 2), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_A, 3), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_A, 0), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_A, 1), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_A, 2), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_A, 3), D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_B, 0), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_B, 1), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_B, 2), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_B, 3), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_B, 0), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_B, 1), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_B, 2), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_B, 3), D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_C, 0), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_C, 1), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_C, 2), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_C, 3), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_C, 0), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_C, 1), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_C, 2), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_BUF_CFG(PIPE_C, 3), D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_DH(CUR_BUF_CFG(PIPE_A), D_SKL, NULL, NULL);
|
||||
MMIO_DH(CUR_BUF_CFG(PIPE_B), D_SKL, NULL, NULL);
|
||||
MMIO_DH(CUR_BUF_CFG(PIPE_C), D_SKL, NULL, NULL);
|
||||
MMIO_DH(CUR_BUF_CFG(PIPE_A), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(CUR_BUF_CFG(PIPE_B), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(CUR_BUF_CFG(PIPE_C), D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_F(PLANE_WM(PIPE_A, 0, 0), 4 * 8, 0, 0, 0, D_SKL, NULL, NULL);
|
||||
MMIO_F(PLANE_WM(PIPE_A, 1, 0), 4 * 8, 0, 0, 0, D_SKL, NULL, NULL);
|
||||
MMIO_F(PLANE_WM(PIPE_A, 2, 0), 4 * 8, 0, 0, 0, D_SKL, NULL, NULL);
|
||||
MMIO_F(PLANE_WM(PIPE_A, 0, 0), 4 * 8, 0, 0, 0, D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_F(PLANE_WM(PIPE_A, 1, 0), 4 * 8, 0, 0, 0, D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_F(PLANE_WM(PIPE_A, 2, 0), 4 * 8, 0, 0, 0, D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_F(PLANE_WM(PIPE_B, 0, 0), 4 * 8, 0, 0, 0, D_SKL, NULL, NULL);
|
||||
MMIO_F(PLANE_WM(PIPE_B, 1, 0), 4 * 8, 0, 0, 0, D_SKL, NULL, NULL);
|
||||
MMIO_F(PLANE_WM(PIPE_B, 2, 0), 4 * 8, 0, 0, 0, D_SKL, NULL, NULL);
|
||||
MMIO_F(PLANE_WM(PIPE_B, 0, 0), 4 * 8, 0, 0, 0, D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_F(PLANE_WM(PIPE_B, 1, 0), 4 * 8, 0, 0, 0, D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_F(PLANE_WM(PIPE_B, 2, 0), 4 * 8, 0, 0, 0, D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_F(PLANE_WM(PIPE_C, 0, 0), 4 * 8, 0, 0, 0, D_SKL, NULL, NULL);
|
||||
MMIO_F(PLANE_WM(PIPE_C, 1, 0), 4 * 8, 0, 0, 0, D_SKL, NULL, NULL);
|
||||
MMIO_F(PLANE_WM(PIPE_C, 2, 0), 4 * 8, 0, 0, 0, D_SKL, NULL, NULL);
|
||||
MMIO_F(PLANE_WM(PIPE_C, 0, 0), 4 * 8, 0, 0, 0, D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_F(PLANE_WM(PIPE_C, 1, 0), 4 * 8, 0, 0, 0, D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_F(PLANE_WM(PIPE_C, 2, 0), 4 * 8, 0, 0, 0, D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_F(CUR_WM(PIPE_A, 0), 4 * 8, 0, 0, 0, D_SKL, NULL, NULL);
|
||||
MMIO_F(CUR_WM(PIPE_B, 0), 4 * 8, 0, 0, 0, D_SKL, NULL, NULL);
|
||||
MMIO_F(CUR_WM(PIPE_C, 0), 4 * 8, 0, 0, 0, D_SKL, NULL, NULL);
|
||||
MMIO_F(CUR_WM(PIPE_A, 0), 4 * 8, 0, 0, 0, D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_F(CUR_WM(PIPE_B, 0), 4 * 8, 0, 0, 0, D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_F(CUR_WM(PIPE_C, 0), 4 * 8, 0, 0, 0, D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_DH(PLANE_WM_TRANS(PIPE_A, 0), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_WM_TRANS(PIPE_A, 1), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_WM_TRANS(PIPE_A, 2), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_WM_TRANS(PIPE_A, 0), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_WM_TRANS(PIPE_A, 1), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_WM_TRANS(PIPE_A, 2), D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_DH(PLANE_WM_TRANS(PIPE_B, 0), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_WM_TRANS(PIPE_B, 1), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_WM_TRANS(PIPE_B, 2), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_WM_TRANS(PIPE_B, 0), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_WM_TRANS(PIPE_B, 1), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_WM_TRANS(PIPE_B, 2), D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_DH(PLANE_WM_TRANS(PIPE_C, 0), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_WM_TRANS(PIPE_C, 1), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_WM_TRANS(PIPE_C, 2), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_WM_TRANS(PIPE_C, 0), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_WM_TRANS(PIPE_C, 1), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_WM_TRANS(PIPE_C, 2), D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_DH(CUR_WM_TRANS(PIPE_A), D_SKL, NULL, NULL);
|
||||
MMIO_DH(CUR_WM_TRANS(PIPE_B), D_SKL, NULL, NULL);
|
||||
MMIO_DH(CUR_WM_TRANS(PIPE_C), D_SKL, NULL, NULL);
|
||||
MMIO_DH(CUR_WM_TRANS(PIPE_A), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(CUR_WM_TRANS(PIPE_B), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(CUR_WM_TRANS(PIPE_C), D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_A, 0), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_A, 1), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_A, 2), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_A, 3), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_A, 0), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_A, 1), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_A, 2), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_A, 3), D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_B, 0), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_B, 1), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_B, 2), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_B, 3), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_B, 0), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_B, 1), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_B, 2), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_B, 3), D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_C, 0), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_C, 1), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_C, 2), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_C, 3), D_SKL, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_C, 0), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_C, 1), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_C, 2), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_C, 3), D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_DH(_REG_701C0(PIPE_A, 1), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_A, 2), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_A, 3), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_A, 4), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_A, 1), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_A, 2), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_A, 3), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_A, 4), D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_DH(_REG_701C0(PIPE_B, 1), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_B, 2), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_B, 3), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_B, 4), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_B, 1), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_B, 2), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_B, 3), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_B, 4), D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_DH(_REG_701C0(PIPE_C, 1), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_C, 2), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_C, 3), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_C, 4), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_C, 1), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_C, 2), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_C, 3), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(_REG_701C0(PIPE_C, 4), D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_DH(_REG_701C4(PIPE_A, 1), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_A, 2), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_A, 3), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_A, 4), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_A, 1), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_A, 2), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_A, 3), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_A, 4), D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_DH(_REG_701C4(PIPE_B, 1), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_B, 2), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_B, 3), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_B, 4), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_B, 1), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_B, 2), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_B, 3), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_B, 4), D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_DH(_REG_701C4(PIPE_C, 1), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_C, 2), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_C, 3), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_C, 4), D_SKL, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_C, 1), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_C, 2), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_C, 3), D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_DH(_REG_701C4(PIPE_C, 4), D_SKL_PLUS, NULL, NULL);
|
||||
|
||||
MMIO_D(0x70380, D_SKL);
|
||||
MMIO_D(0x71380, D_SKL);
|
||||
MMIO_D(0x72380, D_SKL);
|
||||
MMIO_D(0x7039c, D_SKL);
|
||||
MMIO_D(0x70380, D_SKL_PLUS);
|
||||
MMIO_D(0x71380, D_SKL_PLUS);
|
||||
MMIO_D(0x72380, D_SKL_PLUS);
|
||||
MMIO_D(0x7039c, D_SKL_PLUS);
|
||||
|
||||
MMIO_F(0x80000, 0x3000, 0, 0, 0, D_SKL, NULL, NULL);
|
||||
MMIO_D(0x8f074, D_SKL);
|
||||
MMIO_D(0x8f004, D_SKL);
|
||||
MMIO_D(0x8f034, D_SKL);
|
||||
MMIO_F(0x80000, 0x3000, 0, 0, 0, D_SKL_PLUS, NULL, NULL);
|
||||
MMIO_D(0x8f074, D_SKL | D_KBL);
|
||||
MMIO_D(0x8f004, D_SKL | D_KBL);
|
||||
MMIO_D(0x8f034, D_SKL | D_KBL);
|
||||
|
||||
MMIO_D(0xb11c, D_SKL);
|
||||
MMIO_D(0xb11c, D_SKL | D_KBL);
|
||||
|
||||
MMIO_D(0x51000, D_SKL);
|
||||
MMIO_D(0x6c00c, D_SKL);
|
||||
MMIO_D(0x51000, D_SKL | D_KBL);
|
||||
MMIO_D(0x6c00c, D_SKL_PLUS);
|
||||
|
||||
MMIO_F(0xc800, 0x7f8, F_CMD_ACCESS, 0, 0, D_SKL, NULL, NULL);
|
||||
MMIO_F(0xb020, 0x80, F_CMD_ACCESS, 0, 0, D_SKL, NULL, NULL);
|
||||
MMIO_F(0xc800, 0x7f8, F_CMD_ACCESS, 0, 0, D_SKL | D_KBL, NULL, NULL);
|
||||
MMIO_F(0xb020, 0x80, F_CMD_ACCESS, 0, 0, D_SKL | D_KBL, NULL, NULL);
|
||||
|
||||
MMIO_D(0xd08, D_SKL);
|
||||
MMIO_DFH(0x20e0, D_SKL, F_MODE_MASK, NULL, NULL);
|
||||
MMIO_DFH(0x20ec, D_SKL, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL);
|
||||
MMIO_D(0xd08, D_SKL_PLUS);
|
||||
MMIO_DFH(0x20e0, D_SKL_PLUS, F_MODE_MASK, NULL, NULL);
|
||||
MMIO_DFH(0x20ec, D_SKL_PLUS, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL);
|
||||
|
||||
/* TRTT */
|
||||
MMIO_DFH(0x4de0, D_SKL, F_CMD_ACCESS, NULL, NULL);
|
||||
MMIO_DFH(0x4de4, D_SKL, F_CMD_ACCESS, NULL, NULL);
|
||||
MMIO_DFH(0x4de8, D_SKL, F_CMD_ACCESS, NULL, NULL);
|
||||
MMIO_DFH(0x4dec, D_SKL, F_CMD_ACCESS, NULL, NULL);
|
||||
MMIO_DFH(0x4df0, D_SKL, F_CMD_ACCESS, NULL, NULL);
|
||||
MMIO_DFH(0x4df4, D_SKL, F_CMD_ACCESS, NULL, gen9_trtte_write);
|
||||
MMIO_DH(0x4dfc, D_SKL, NULL, gen9_trtt_chicken_write);
|
||||
MMIO_DFH(0x4de0, D_SKL | D_KBL, F_CMD_ACCESS, NULL, NULL);
|
||||
MMIO_DFH(0x4de4, D_SKL | D_KBL, F_CMD_ACCESS, NULL, NULL);
|
||||
MMIO_DFH(0x4de8, D_SKL | D_KBL, F_CMD_ACCESS, NULL, NULL);
|
||||
MMIO_DFH(0x4dec, D_SKL | D_KBL, F_CMD_ACCESS, NULL, NULL);
|
||||
MMIO_DFH(0x4df0, D_SKL | D_KBL, F_CMD_ACCESS, NULL, NULL);
|
||||
MMIO_DFH(0x4df4, D_SKL | D_KBL, F_CMD_ACCESS, NULL, gen9_trtte_write);
|
||||
MMIO_DH(0x4dfc, D_SKL | D_KBL, NULL, gen9_trtt_chicken_write);
|
||||
|
||||
MMIO_D(0x45008, D_SKL);
|
||||
MMIO_D(0x45008, D_SKL | D_KBL);
|
||||
|
||||
MMIO_D(0x46430, D_SKL);
|
||||
MMIO_D(0x46430, D_SKL | D_KBL);
|
||||
|
||||
MMIO_D(0x46520, D_SKL);
|
||||
MMIO_D(0x46520, D_SKL | D_KBL);
|
||||
|
||||
MMIO_D(0xc403c, D_SKL);
|
||||
MMIO_D(0xb004, D_SKL);
|
||||
MMIO_D(0xc403c, D_SKL | D_KBL);
|
||||
MMIO_D(0xb004, D_SKL_PLUS);
|
||||
MMIO_DH(DMA_CTRL, D_SKL_PLUS, NULL, dma_ctrl_write);
|
||||
|
||||
MMIO_D(0x65900, D_SKL);
|
||||
MMIO_D(0x1082c0, D_SKL);
|
||||
MMIO_D(0x4068, D_SKL);
|
||||
MMIO_D(0x67054, D_SKL);
|
||||
MMIO_D(0x6e560, D_SKL);
|
||||
MMIO_D(0x6e554, D_SKL);
|
||||
MMIO_D(0x2b20, D_SKL);
|
||||
MMIO_D(0x65f00, D_SKL);
|
||||
MMIO_D(0x65f08, D_SKL);
|
||||
MMIO_D(0x320f0, D_SKL);
|
||||
MMIO_D(0x65900, D_SKL_PLUS);
|
||||
MMIO_D(0x1082c0, D_SKL | D_KBL);
|
||||
MMIO_D(0x4068, D_SKL | D_KBL);
|
||||
MMIO_D(0x67054, D_SKL | D_KBL);
|
||||
MMIO_D(0x6e560, D_SKL | D_KBL);
|
||||
MMIO_D(0x6e554, D_SKL | D_KBL);
|
||||
MMIO_D(0x2b20, D_SKL | D_KBL);
|
||||
MMIO_D(0x65f00, D_SKL | D_KBL);
|
||||
MMIO_D(0x65f08, D_SKL | D_KBL);
|
||||
MMIO_D(0x320f0, D_SKL | D_KBL);
|
||||
|
||||
MMIO_DFH(_REG_VCS2_EXCC, D_SKL, F_CMD_ACCESS, NULL, NULL);
|
||||
MMIO_D(0x70034, D_SKL);
|
||||
MMIO_D(0x71034, D_SKL);
|
||||
MMIO_D(0x72034, D_SKL);
|
||||
MMIO_DFH(_REG_VCS2_EXCC, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
|
||||
MMIO_DFH(_REG_VECS_EXCC, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
|
||||
MMIO_D(0x70034, D_SKL_PLUS);
|
||||
MMIO_D(0x71034, D_SKL_PLUS);
|
||||
MMIO_D(0x72034, D_SKL_PLUS);
|
||||
|
||||
MMIO_D(_PLANE_KEYVAL_1(PIPE_A), D_SKL);
|
||||
MMIO_D(_PLANE_KEYVAL_1(PIPE_B), D_SKL);
|
||||
MMIO_D(_PLANE_KEYVAL_1(PIPE_C), D_SKL);
|
||||
MMIO_D(_PLANE_KEYMSK_1(PIPE_A), D_SKL);
|
||||
MMIO_D(_PLANE_KEYMSK_1(PIPE_B), D_SKL);
|
||||
MMIO_D(_PLANE_KEYMSK_1(PIPE_C), D_SKL);
|
||||
MMIO_D(_PLANE_KEYVAL_1(PIPE_A), D_SKL_PLUS);
|
||||
MMIO_D(_PLANE_KEYVAL_1(PIPE_B), D_SKL_PLUS);
|
||||
MMIO_D(_PLANE_KEYVAL_1(PIPE_C), D_SKL_PLUS);
|
||||
MMIO_D(_PLANE_KEYMSK_1(PIPE_A), D_SKL_PLUS);
|
||||
MMIO_D(_PLANE_KEYMSK_1(PIPE_B), D_SKL_PLUS);
|
||||
MMIO_D(_PLANE_KEYMSK_1(PIPE_C), D_SKL_PLUS);
|
||||
|
||||
MMIO_D(0x44500, D_SKL);
|
||||
MMIO_D(0x44500, D_SKL_PLUS);
|
||||
MMIO_DFH(GEN9_CSFE_CHICKEN1_RCS, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
|
||||
MMIO_DFH(GEN8_HDC_CHICKEN1, D_SKL, F_MODE_MASK | F_CMD_ACCESS,
|
||||
MMIO_DFH(GEN8_HDC_CHICKEN1, D_SKL | D_KBL, F_MODE_MASK | F_CMD_ACCESS,
|
||||
NULL, NULL);
|
||||
|
||||
MMIO_D(0x4ab8, D_KBL);
|
||||
MMIO_D(0x940c, D_SKL_PLUS);
|
||||
MMIO_D(0x2248, D_SKL_PLUS | D_KBL);
|
||||
MMIO_D(0x4ab0, D_SKL | D_KBL);
|
||||
MMIO_D(0x20d4, D_SKL | D_KBL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2873,7 +2893,8 @@ int intel_gvt_setup_mmio_info(struct intel_gvt *gvt)
|
||||
ret = init_broadwell_mmio_info(gvt);
|
||||
if (ret)
|
||||
goto err;
|
||||
} else if (IS_SKYLAKE(dev_priv)) {
|
||||
} else if (IS_SKYLAKE(dev_priv)
|
||||
|| IS_KABYLAKE(dev_priv)) {
|
||||
ret = init_broadwell_mmio_info(gvt);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
@@ -580,7 +580,7 @@ static void gen8_init_irq(
|
||||
|
||||
SET_BIT_INFO(irq, 4, PRIMARY_C_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_C);
|
||||
SET_BIT_INFO(irq, 5, SPRITE_C_FLIP_DONE, INTEL_GVT_IRQ_INFO_DE_PIPE_C);
|
||||
} else if (IS_SKYLAKE(gvt->dev_priv)) {
|
||||
} else if (IS_SKYLAKE(gvt->dev_priv) || IS_KABYLAKE(gvt->dev_priv)) {
|
||||
SET_BIT_INFO(irq, 25, AUX_CHANNEL_B, INTEL_GVT_IRQ_INFO_DE_PORT);
|
||||
SET_BIT_INFO(irq, 26, AUX_CHANNEL_C, INTEL_GVT_IRQ_INFO_DE_PORT);
|
||||
SET_BIT_INFO(irq, 27, AUX_CHANNEL_D, INTEL_GVT_IRQ_INFO_DE_PORT);
|
||||
@@ -690,7 +690,8 @@ int intel_gvt_init_irq(struct intel_gvt *gvt)
|
||||
|
||||
gvt_dbg_core("init irq framework\n");
|
||||
|
||||
if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv)) {
|
||||
if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv)
|
||||
|| IS_KABYLAKE(gvt->dev_priv)) {
|
||||
irq->ops = &gen8_irq_ops;
|
||||
irq->irq_map = gen8_irq_map;
|
||||
} else {
|
||||
|
||||
@@ -295,10 +295,12 @@ static ssize_t description_show(struct kobject *kobj, struct device *dev,
|
||||
return 0;
|
||||
|
||||
return sprintf(buf, "low_gm_size: %dMB\nhigh_gm_size: %dMB\n"
|
||||
"fence: %d\nresolution: %s\n",
|
||||
"fence: %d\nresolution: %s\n"
|
||||
"weight: %d\n",
|
||||
BYTES_TO_MB(type->low_gm_size),
|
||||
BYTES_TO_MB(type->high_gm_size),
|
||||
type->fence, vgpu_edid_str(type->resolution));
|
||||
type->fence, vgpu_edid_str(type->resolution),
|
||||
type->weight);
|
||||
}
|
||||
|
||||
static MDEV_TYPE_ATTR_RO(available_instances);
|
||||
@@ -1146,8 +1148,40 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
vgpu_id_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);
|
||||
return sprintf(buf, "%d\n", vgpu->id);
|
||||
}
|
||||
return sprintf(buf, "\n");
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(vgpu_id);
|
||||
|
||||
static struct attribute *intel_vgpu_attrs[] = {
|
||||
&dev_attr_vgpu_id.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct attribute_group intel_vgpu_group = {
|
||||
.name = "intel_vgpu",
|
||||
.attrs = intel_vgpu_attrs,
|
||||
};
|
||||
|
||||
static const struct attribute_group *intel_vgpu_groups[] = {
|
||||
&intel_vgpu_group,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct mdev_parent_ops intel_vgpu_ops = {
|
||||
.supported_type_groups = intel_vgpu_type_groups,
|
||||
.mdev_attr_groups = intel_vgpu_groups,
|
||||
.create = intel_vgpu_create,
|
||||
.remove = intel_vgpu_remove,
|
||||
|
||||
@@ -1339,13 +1373,6 @@ static int kvmgt_guest_init(struct mdev_device *mdev)
|
||||
|
||||
static bool kvmgt_guest_exit(struct kvmgt_guest_info *info)
|
||||
{
|
||||
struct intel_vgpu *vgpu = info->vgpu;
|
||||
|
||||
if (!info) {
|
||||
gvt_vgpu_err("kvmgt_guest_info invalid\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
kvm_page_track_unregister_notifier(info->kvm, &info->track_node);
|
||||
kvmgt_protect_table_destroy(info);
|
||||
gvt_cache_destroy(info->vgpu);
|
||||
|
||||
@@ -44,20 +44,21 @@ struct intel_vgpu;
|
||||
#define D_HSW (1 << 2)
|
||||
#define D_BDW (1 << 3)
|
||||
#define D_SKL (1 << 4)
|
||||
#define D_KBL (1 << 5)
|
||||
|
||||
#define D_GEN9PLUS (D_SKL)
|
||||
#define D_GEN8PLUS (D_BDW | D_SKL)
|
||||
#define D_GEN75PLUS (D_HSW | D_BDW | D_SKL)
|
||||
#define D_GEN7PLUS (D_IVB | D_HSW | D_BDW | D_SKL)
|
||||
#define D_GEN9PLUS (D_SKL | D_KBL)
|
||||
#define D_GEN8PLUS (D_BDW | D_SKL | D_KBL)
|
||||
#define D_GEN75PLUS (D_HSW | D_BDW | D_SKL | D_KBL)
|
||||
#define D_GEN7PLUS (D_IVB | D_HSW | D_BDW | D_SKL | D_KBL)
|
||||
|
||||
#define D_SKL_PLUS (D_SKL)
|
||||
#define D_BDW_PLUS (D_BDW | D_SKL)
|
||||
#define D_HSW_PLUS (D_HSW | D_BDW | D_SKL)
|
||||
#define D_IVB_PLUS (D_IVB | D_HSW | D_BDW | D_SKL)
|
||||
#define D_SKL_PLUS (D_SKL | D_KBL)
|
||||
#define D_BDW_PLUS (D_BDW | D_SKL | D_KBL)
|
||||
#define D_HSW_PLUS (D_HSW | D_BDW | D_SKL | D_KBL)
|
||||
#define D_IVB_PLUS (D_IVB | D_HSW | D_BDW | D_SKL | D_KBL)
|
||||
|
||||
#define D_PRE_BDW (D_SNB | D_IVB | D_HSW)
|
||||
#define D_PRE_SKL (D_SNB | D_IVB | D_HSW | D_BDW)
|
||||
#define D_ALL (D_SNB | D_IVB | D_HSW | D_BDW | D_SKL)
|
||||
#define D_ALL (D_SNB | D_IVB | D_HSW | D_BDW | D_SKL | D_KBL)
|
||||
|
||||
struct intel_gvt_mmio_info {
|
||||
u32 offset;
|
||||
|
||||
@@ -126,6 +126,18 @@ static struct render_mmio gen9_render_mmio_list[] = {
|
||||
{VCS2, _MMIO(0x1c028), 0xffff, false},
|
||||
|
||||
{VECS, _MMIO(0x1a028), 0xffff, false},
|
||||
|
||||
{RCS, _MMIO(0x7304), 0xffff, true},
|
||||
{RCS, _MMIO(0x2248), 0x0, false},
|
||||
{RCS, _MMIO(0x940c), 0x0, false},
|
||||
{RCS, _MMIO(0x4ab8), 0x0, false},
|
||||
|
||||
{RCS, _MMIO(0x4ab0), 0x0, false},
|
||||
{RCS, _MMIO(0x20d4), 0x0, false},
|
||||
|
||||
{RCS, _MMIO(0xb004), 0x0, false},
|
||||
{RCS, _MMIO(0x20a0), 0x0, false},
|
||||
{RCS, _MMIO(0x20e4), 0xffff, false},
|
||||
};
|
||||
|
||||
static u32 gen9_render_mocs[I915_NUM_ENGINES][64];
|
||||
@@ -159,7 +171,7 @@ static void handle_tlb_pending_event(struct intel_vgpu *vgpu, int ring_id)
|
||||
*/
|
||||
fw = intel_uncore_forcewake_for_reg(dev_priv, reg,
|
||||
FW_REG_READ | FW_REG_WRITE);
|
||||
if (ring_id == RCS && IS_SKYLAKE(dev_priv))
|
||||
if (ring_id == RCS && (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)))
|
||||
fw |= FORCEWAKE_RENDER;
|
||||
|
||||
intel_uncore_forcewake_get(dev_priv, fw);
|
||||
@@ -192,7 +204,7 @@ static void load_mocs(struct intel_vgpu *vgpu, int ring_id)
|
||||
if (WARN_ON(ring_id >= ARRAY_SIZE(regs)))
|
||||
return;
|
||||
|
||||
if (!IS_SKYLAKE(dev_priv))
|
||||
if (!(IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)))
|
||||
return;
|
||||
|
||||
offset.reg = regs[ring_id];
|
||||
@@ -230,7 +242,7 @@ static void restore_mocs(struct intel_vgpu *vgpu, int ring_id)
|
||||
if (WARN_ON(ring_id >= ARRAY_SIZE(regs)))
|
||||
return;
|
||||
|
||||
if (!IS_SKYLAKE(dev_priv))
|
||||
if (!(IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)))
|
||||
return;
|
||||
|
||||
offset.reg = regs[ring_id];
|
||||
@@ -265,7 +277,8 @@ void intel_gvt_load_render_mmio(struct intel_vgpu *vgpu, int ring_id)
|
||||
u32 inhibit_mask =
|
||||
_MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT);
|
||||
|
||||
if (IS_SKYLAKE(vgpu->gvt->dev_priv)) {
|
||||
if (IS_SKYLAKE(vgpu->gvt->dev_priv)
|
||||
|| IS_KABYLAKE(vgpu->gvt->dev_priv)) {
|
||||
mmio = gen9_render_mmio_list;
|
||||
array_size = ARRAY_SIZE(gen9_render_mmio_list);
|
||||
load_mocs(vgpu, ring_id);
|
||||
@@ -312,7 +325,7 @@ void intel_gvt_restore_render_mmio(struct intel_vgpu *vgpu, int ring_id)
|
||||
u32 v;
|
||||
int i, array_size;
|
||||
|
||||
if (IS_SKYLAKE(dev_priv)) {
|
||||
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
|
||||
mmio = gen9_render_mmio_list;
|
||||
array_size = ARRAY_SIZE(gen9_render_mmio_list);
|
||||
restore_mocs(vgpu, ring_id);
|
||||
|
||||
@@ -47,11 +47,87 @@ static bool vgpu_has_pending_workload(struct intel_vgpu *vgpu)
|
||||
return false;
|
||||
}
|
||||
|
||||
struct vgpu_sched_data {
|
||||
struct list_head lru_list;
|
||||
struct intel_vgpu *vgpu;
|
||||
|
||||
ktime_t sched_in_time;
|
||||
ktime_t sched_out_time;
|
||||
ktime_t sched_time;
|
||||
ktime_t left_ts;
|
||||
ktime_t allocated_ts;
|
||||
|
||||
struct vgpu_sched_ctl sched_ctl;
|
||||
};
|
||||
|
||||
struct gvt_sched_data {
|
||||
struct intel_gvt *gvt;
|
||||
struct hrtimer timer;
|
||||
unsigned long period;
|
||||
struct list_head lru_runq_head;
|
||||
};
|
||||
|
||||
static void vgpu_update_timeslice(struct intel_vgpu *pre_vgpu)
|
||||
{
|
||||
ktime_t delta_ts;
|
||||
struct vgpu_sched_data *vgpu_data = pre_vgpu->sched_data;
|
||||
|
||||
delta_ts = vgpu_data->sched_out_time - vgpu_data->sched_in_time;
|
||||
|
||||
vgpu_data->sched_time += delta_ts;
|
||||
vgpu_data->left_ts -= delta_ts;
|
||||
}
|
||||
|
||||
#define GVT_TS_BALANCE_PERIOD_MS 100
|
||||
#define GVT_TS_BALANCE_STAGE_NUM 10
|
||||
|
||||
static void gvt_balance_timeslice(struct gvt_sched_data *sched_data)
|
||||
{
|
||||
struct vgpu_sched_data *vgpu_data;
|
||||
struct list_head *pos;
|
||||
static uint64_t stage_check;
|
||||
int stage = stage_check++ % GVT_TS_BALANCE_STAGE_NUM;
|
||||
|
||||
/* The timeslice accumulation reset at stage 0, which is
|
||||
* allocated again without adding previous debt.
|
||||
*/
|
||||
if (stage == 0) {
|
||||
int total_weight = 0;
|
||||
ktime_t fair_timeslice;
|
||||
|
||||
list_for_each(pos, &sched_data->lru_runq_head) {
|
||||
vgpu_data = container_of(pos, struct vgpu_sched_data, lru_list);
|
||||
total_weight += vgpu_data->sched_ctl.weight;
|
||||
}
|
||||
|
||||
list_for_each(pos, &sched_data->lru_runq_head) {
|
||||
vgpu_data = container_of(pos, struct vgpu_sched_data, lru_list);
|
||||
fair_timeslice = ms_to_ktime(GVT_TS_BALANCE_PERIOD_MS) *
|
||||
vgpu_data->sched_ctl.weight /
|
||||
total_weight;
|
||||
|
||||
vgpu_data->allocated_ts = fair_timeslice;
|
||||
vgpu_data->left_ts = vgpu_data->allocated_ts;
|
||||
}
|
||||
} else {
|
||||
list_for_each(pos, &sched_data->lru_runq_head) {
|
||||
vgpu_data = container_of(pos, struct vgpu_sched_data, lru_list);
|
||||
|
||||
/* timeslice for next 100ms should add the left/debt
|
||||
* slice of previous stages.
|
||||
*/
|
||||
vgpu_data->left_ts += vgpu_data->allocated_ts;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void try_to_schedule_next_vgpu(struct intel_gvt *gvt)
|
||||
{
|
||||
struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
|
||||
enum intel_engine_id i;
|
||||
struct intel_engine_cs *engine;
|
||||
struct vgpu_sched_data *vgpu_data;
|
||||
ktime_t cur_time;
|
||||
|
||||
/* no target to schedule */
|
||||
if (!scheduler->next_vgpu)
|
||||
@@ -77,6 +153,15 @@ static void try_to_schedule_next_vgpu(struct intel_gvt *gvt)
|
||||
gvt_dbg_sched("switch to next vgpu %d\n",
|
||||
scheduler->next_vgpu->id);
|
||||
|
||||
cur_time = ktime_get();
|
||||
if (scheduler->current_vgpu) {
|
||||
vgpu_data = scheduler->current_vgpu->sched_data;
|
||||
vgpu_data->sched_out_time = cur_time;
|
||||
vgpu_update_timeslice(scheduler->current_vgpu);
|
||||
}
|
||||
vgpu_data = scheduler->next_vgpu->sched_data;
|
||||
vgpu_data->sched_in_time = cur_time;
|
||||
|
||||
/* switch current vgpu */
|
||||
scheduler->current_vgpu = scheduler->next_vgpu;
|
||||
scheduler->next_vgpu = NULL;
|
||||
@@ -88,62 +173,61 @@ static void try_to_schedule_next_vgpu(struct intel_gvt *gvt)
|
||||
wake_up(&scheduler->waitq[i]);
|
||||
}
|
||||
|
||||
struct tbs_vgpu_data {
|
||||
struct list_head list;
|
||||
struct intel_vgpu *vgpu;
|
||||
/* put some per-vgpu sched stats here */
|
||||
};
|
||||
|
||||
struct tbs_sched_data {
|
||||
struct intel_gvt *gvt;
|
||||
struct delayed_work work;
|
||||
unsigned long period;
|
||||
struct list_head runq_head;
|
||||
};
|
||||
|
||||
#define GVT_DEFAULT_TIME_SLICE (msecs_to_jiffies(1))
|
||||
|
||||
static void tbs_sched_func(struct work_struct *work)
|
||||
static struct intel_vgpu *find_busy_vgpu(struct gvt_sched_data *sched_data)
|
||||
{
|
||||
struct tbs_sched_data *sched_data = container_of(work,
|
||||
struct tbs_sched_data, work.work);
|
||||
struct tbs_vgpu_data *vgpu_data;
|
||||
|
||||
struct intel_gvt *gvt = sched_data->gvt;
|
||||
struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
|
||||
|
||||
struct vgpu_sched_data *vgpu_data;
|
||||
struct intel_vgpu *vgpu = NULL;
|
||||
struct list_head *pos, *head;
|
||||
|
||||
mutex_lock(&gvt->lock);
|
||||
|
||||
/* no vgpu or has already had a target */
|
||||
if (list_empty(&sched_data->runq_head) || scheduler->next_vgpu)
|
||||
goto out;
|
||||
|
||||
if (scheduler->current_vgpu) {
|
||||
vgpu_data = scheduler->current_vgpu->sched_data;
|
||||
head = &vgpu_data->list;
|
||||
} else {
|
||||
head = &sched_data->runq_head;
|
||||
}
|
||||
struct list_head *head = &sched_data->lru_runq_head;
|
||||
struct list_head *pos;
|
||||
|
||||
/* search a vgpu with pending workload */
|
||||
list_for_each(pos, head) {
|
||||
if (pos == &sched_data->runq_head)
|
||||
continue;
|
||||
|
||||
vgpu_data = container_of(pos, struct tbs_vgpu_data, list);
|
||||
vgpu_data = container_of(pos, struct vgpu_sched_data, lru_list);
|
||||
if (!vgpu_has_pending_workload(vgpu_data->vgpu))
|
||||
continue;
|
||||
|
||||
vgpu = vgpu_data->vgpu;
|
||||
break;
|
||||
/* Return the vGPU only if it has time slice left */
|
||||
if (vgpu_data->left_ts > 0) {
|
||||
vgpu = vgpu_data->vgpu;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return vgpu;
|
||||
}
|
||||
|
||||
/* in nanosecond */
|
||||
#define GVT_DEFAULT_TIME_SLICE 1000000
|
||||
|
||||
static void tbs_sched_func(struct gvt_sched_data *sched_data)
|
||||
{
|
||||
struct intel_gvt *gvt = sched_data->gvt;
|
||||
struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
|
||||
struct vgpu_sched_data *vgpu_data;
|
||||
struct intel_vgpu *vgpu = NULL;
|
||||
static uint64_t timer_check;
|
||||
|
||||
if (!(timer_check++ % GVT_TS_BALANCE_PERIOD_MS))
|
||||
gvt_balance_timeslice(sched_data);
|
||||
|
||||
/* no active vgpu or has already had a target */
|
||||
if (list_empty(&sched_data->lru_runq_head) || scheduler->next_vgpu)
|
||||
goto out;
|
||||
|
||||
vgpu = find_busy_vgpu(sched_data);
|
||||
if (vgpu) {
|
||||
scheduler->next_vgpu = vgpu;
|
||||
|
||||
/* Move the last used vGPU to the tail of lru_list */
|
||||
vgpu_data = vgpu->sched_data;
|
||||
list_del_init(&vgpu_data->lru_list);
|
||||
list_add_tail(&vgpu_data->lru_list,
|
||||
&sched_data->lru_runq_head);
|
||||
|
||||
gvt_dbg_sched("pick next vgpu %d\n", vgpu->id);
|
||||
} else {
|
||||
scheduler->next_vgpu = gvt->idle_vgpu;
|
||||
}
|
||||
out:
|
||||
if (scheduler->next_vgpu) {
|
||||
@@ -151,34 +235,49 @@ out:
|
||||
scheduler->next_vgpu->id);
|
||||
try_to_schedule_next_vgpu(gvt);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* still have vgpu on runq
|
||||
* or last schedule haven't finished due to running workload
|
||||
*/
|
||||
if (!list_empty(&sched_data->runq_head) || scheduler->next_vgpu)
|
||||
schedule_delayed_work(&sched_data->work, sched_data->period);
|
||||
void intel_gvt_schedule(struct intel_gvt *gvt)
|
||||
{
|
||||
struct gvt_sched_data *sched_data = gvt->scheduler.sched_data;
|
||||
|
||||
mutex_lock(&gvt->lock);
|
||||
tbs_sched_func(sched_data);
|
||||
mutex_unlock(&gvt->lock);
|
||||
}
|
||||
|
||||
static enum hrtimer_restart tbs_timer_fn(struct hrtimer *timer_data)
|
||||
{
|
||||
struct gvt_sched_data *data;
|
||||
|
||||
data = container_of(timer_data, struct gvt_sched_data, timer);
|
||||
|
||||
intel_gvt_request_service(data->gvt, INTEL_GVT_REQUEST_SCHED);
|
||||
|
||||
hrtimer_add_expires_ns(&data->timer, data->period);
|
||||
|
||||
return HRTIMER_RESTART;
|
||||
}
|
||||
|
||||
static int tbs_sched_init(struct intel_gvt *gvt)
|
||||
{
|
||||
struct intel_gvt_workload_scheduler *scheduler =
|
||||
&gvt->scheduler;
|
||||
|
||||
struct tbs_sched_data *data;
|
||||
struct gvt_sched_data *data;
|
||||
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_LIST_HEAD(&data->runq_head);
|
||||
INIT_DELAYED_WORK(&data->work, tbs_sched_func);
|
||||
INIT_LIST_HEAD(&data->lru_runq_head);
|
||||
hrtimer_init(&data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
|
||||
data->timer.function = tbs_timer_fn;
|
||||
data->period = GVT_DEFAULT_TIME_SLICE;
|
||||
data->gvt = gvt;
|
||||
|
||||
scheduler->sched_data = data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -186,25 +285,28 @@ static void tbs_sched_clean(struct intel_gvt *gvt)
|
||||
{
|
||||
struct intel_gvt_workload_scheduler *scheduler =
|
||||
&gvt->scheduler;
|
||||
struct tbs_sched_data *data = scheduler->sched_data;
|
||||
struct gvt_sched_data *data = scheduler->sched_data;
|
||||
|
||||
hrtimer_cancel(&data->timer);
|
||||
|
||||
cancel_delayed_work(&data->work);
|
||||
kfree(data);
|
||||
scheduler->sched_data = NULL;
|
||||
}
|
||||
|
||||
static int tbs_sched_init_vgpu(struct intel_vgpu *vgpu)
|
||||
{
|
||||
struct tbs_vgpu_data *data;
|
||||
struct vgpu_sched_data *data;
|
||||
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
data->sched_ctl.weight = vgpu->sched_ctl.weight;
|
||||
data->vgpu = vgpu;
|
||||
INIT_LIST_HEAD(&data->list);
|
||||
INIT_LIST_HEAD(&data->lru_list);
|
||||
|
||||
vgpu->sched_data = data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -216,21 +318,24 @@ static void tbs_sched_clean_vgpu(struct intel_vgpu *vgpu)
|
||||
|
||||
static void tbs_sched_start_schedule(struct intel_vgpu *vgpu)
|
||||
{
|
||||
struct tbs_sched_data *sched_data = vgpu->gvt->scheduler.sched_data;
|
||||
struct tbs_vgpu_data *vgpu_data = vgpu->sched_data;
|
||||
struct gvt_sched_data *sched_data = vgpu->gvt->scheduler.sched_data;
|
||||
struct vgpu_sched_data *vgpu_data = vgpu->sched_data;
|
||||
|
||||
if (!list_empty(&vgpu_data->list))
|
||||
if (!list_empty(&vgpu_data->lru_list))
|
||||
return;
|
||||
|
||||
list_add_tail(&vgpu_data->list, &sched_data->runq_head);
|
||||
schedule_delayed_work(&sched_data->work, 0);
|
||||
list_add_tail(&vgpu_data->lru_list, &sched_data->lru_runq_head);
|
||||
|
||||
if (!hrtimer_active(&sched_data->timer))
|
||||
hrtimer_start(&sched_data->timer, ktime_add_ns(ktime_get(),
|
||||
sched_data->period), HRTIMER_MODE_ABS);
|
||||
}
|
||||
|
||||
static void tbs_sched_stop_schedule(struct intel_vgpu *vgpu)
|
||||
{
|
||||
struct tbs_vgpu_data *vgpu_data = vgpu->sched_data;
|
||||
struct vgpu_sched_data *vgpu_data = vgpu->sched_data;
|
||||
|
||||
list_del_init(&vgpu_data->list);
|
||||
list_del_init(&vgpu_data->lru_list);
|
||||
}
|
||||
|
||||
static struct intel_gvt_sched_policy_ops tbs_schedule_ops = {
|
||||
|
||||
@@ -43,6 +43,8 @@ struct intel_gvt_sched_policy_ops {
|
||||
void (*stop_schedule)(struct intel_vgpu *vgpu);
|
||||
};
|
||||
|
||||
void intel_gvt_schedule(struct intel_gvt *gvt);
|
||||
|
||||
int intel_gvt_init_sched_policy(struct intel_gvt *gvt);
|
||||
|
||||
void intel_gvt_clean_sched_policy(struct intel_gvt *gvt);
|
||||
|
||||
@@ -448,7 +448,8 @@ static int workload_thread(void *priv)
|
||||
struct intel_vgpu_workload *workload = NULL;
|
||||
struct intel_vgpu *vgpu = NULL;
|
||||
int ret;
|
||||
bool need_force_wake = IS_SKYLAKE(gvt->dev_priv);
|
||||
bool need_force_wake = IS_SKYLAKE(gvt->dev_priv)
|
||||
|| IS_KABYLAKE(gvt->dev_priv);
|
||||
DEFINE_WAIT_FUNC(wait, woken_wake_function);
|
||||
|
||||
kfree(p);
|
||||
|
||||
@@ -67,7 +67,6 @@ struct shadow_per_ctx {
|
||||
};
|
||||
|
||||
struct intel_shadow_wa_ctx {
|
||||
struct intel_vgpu_workload *workload;
|
||||
struct shadow_indirect_ctx indirect_ctx;
|
||||
struct shadow_per_ctx per_ctx;
|
||||
|
||||
|
||||
@@ -64,18 +64,28 @@ void populate_pvinfo_page(struct intel_vgpu *vgpu)
|
||||
WARN_ON(sizeof(struct vgt_if) != VGT_PVINFO_SIZE);
|
||||
}
|
||||
|
||||
#define VGPU_MAX_WEIGHT 16
|
||||
#define VGPU_WEIGHT(vgpu_num) \
|
||||
(VGPU_MAX_WEIGHT / (vgpu_num))
|
||||
|
||||
static struct {
|
||||
unsigned int low_mm;
|
||||
unsigned int high_mm;
|
||||
unsigned int fence;
|
||||
|
||||
/* A vGPU with a weight of 8 will get twice as much GPU as a vGPU
|
||||
* with a weight of 4 on a contended host, different vGPU type has
|
||||
* different weight set. Legal weights range from 1 to 16.
|
||||
*/
|
||||
unsigned int weight;
|
||||
enum intel_vgpu_edid edid;
|
||||
char *name;
|
||||
} vgpu_types[] = {
|
||||
/* Fixed vGPU type table */
|
||||
{ MB_TO_BYTES(64), MB_TO_BYTES(512), 4, GVT_EDID_1024_768, "8" },
|
||||
{ MB_TO_BYTES(128), MB_TO_BYTES(512), 4, GVT_EDID_1920_1200, "4" },
|
||||
{ MB_TO_BYTES(256), MB_TO_BYTES(1024), 4, GVT_EDID_1920_1200, "2" },
|
||||
{ MB_TO_BYTES(512), MB_TO_BYTES(2048), 4, GVT_EDID_1920_1200, "1" },
|
||||
{ MB_TO_BYTES(64), MB_TO_BYTES(384), 4, VGPU_WEIGHT(8), GVT_EDID_1024_768, "8" },
|
||||
{ MB_TO_BYTES(128), MB_TO_BYTES(512), 4, VGPU_WEIGHT(4), GVT_EDID_1920_1200, "4" },
|
||||
{ MB_TO_BYTES(256), MB_TO_BYTES(1024), 4, VGPU_WEIGHT(2), GVT_EDID_1920_1200, "2" },
|
||||
{ MB_TO_BYTES(512), MB_TO_BYTES(2048), 4, VGPU_WEIGHT(1), GVT_EDID_1920_1200, "1" },
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -120,6 +130,12 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
|
||||
gvt->types[i].low_gm_size = vgpu_types[i].low_mm;
|
||||
gvt->types[i].high_gm_size = vgpu_types[i].high_mm;
|
||||
gvt->types[i].fence = vgpu_types[i].fence;
|
||||
|
||||
if (vgpu_types[i].weight < 1 ||
|
||||
vgpu_types[i].weight > VGPU_MAX_WEIGHT)
|
||||
return -EINVAL;
|
||||
|
||||
gvt->types[i].weight = vgpu_types[i].weight;
|
||||
gvt->types[i].resolution = vgpu_types[i].edid;
|
||||
gvt->types[i].avail_instance = min(low_avail / vgpu_types[i].low_mm,
|
||||
high_avail / vgpu_types[i].high_mm);
|
||||
@@ -131,11 +147,12 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
|
||||
sprintf(gvt->types[i].name, "GVTg_V5_%s",
|
||||
vgpu_types[i].name);
|
||||
|
||||
gvt_dbg_core("type[%d]: %s avail %u low %u high %u fence %u res %s\n",
|
||||
gvt_dbg_core("type[%d]: %s avail %u low %u high %u fence %u weight %u res %s\n",
|
||||
i, gvt->types[i].name,
|
||||
gvt->types[i].avail_instance,
|
||||
gvt->types[i].low_gm_size,
|
||||
gvt->types[i].high_gm_size, gvt->types[i].fence,
|
||||
gvt->types[i].weight,
|
||||
vgpu_edid_str(gvt->types[i].resolution));
|
||||
}
|
||||
|
||||
@@ -216,6 +233,59 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu)
|
||||
mutex_unlock(&gvt->lock);
|
||||
}
|
||||
|
||||
#define IDLE_VGPU_IDR 0
|
||||
|
||||
/**
|
||||
* intel_gvt_create_idle_vgpu - create an idle virtual GPU
|
||||
* @gvt: GVT device
|
||||
*
|
||||
* This function is called when user wants to create an idle virtual GPU.
|
||||
*
|
||||
* Returns:
|
||||
* pointer to intel_vgpu, error pointer if failed.
|
||||
*/
|
||||
struct intel_vgpu *intel_gvt_create_idle_vgpu(struct intel_gvt *gvt)
|
||||
{
|
||||
struct intel_vgpu *vgpu;
|
||||
enum intel_engine_id i;
|
||||
int ret;
|
||||
|
||||
vgpu = vzalloc(sizeof(*vgpu));
|
||||
if (!vgpu)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
vgpu->id = IDLE_VGPU_IDR;
|
||||
vgpu->gvt = gvt;
|
||||
|
||||
for (i = 0; i < I915_NUM_ENGINES; i++)
|
||||
INIT_LIST_HEAD(&vgpu->workload_q_head[i]);
|
||||
|
||||
ret = intel_vgpu_init_sched_policy(vgpu);
|
||||
if (ret)
|
||||
goto out_free_vgpu;
|
||||
|
||||
vgpu->active = false;
|
||||
|
||||
return vgpu;
|
||||
|
||||
out_free_vgpu:
|
||||
vfree(vgpu);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_gvt_destroy_vgpu - destroy an idle virtual GPU
|
||||
* @vgpu: virtual GPU
|
||||
*
|
||||
* This function is called when user wants to destroy an idle virtual GPU.
|
||||
*
|
||||
*/
|
||||
void intel_gvt_destroy_idle_vgpu(struct intel_vgpu *vgpu)
|
||||
{
|
||||
intel_vgpu_clean_sched_policy(vgpu);
|
||||
vfree(vgpu);
|
||||
}
|
||||
|
||||
static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
|
||||
struct intel_vgpu_creation_params *param)
|
||||
{
|
||||
@@ -232,13 +302,15 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
|
||||
|
||||
mutex_lock(&gvt->lock);
|
||||
|
||||
ret = idr_alloc(&gvt->vgpu_idr, vgpu, 1, GVT_MAX_VGPU, GFP_KERNEL);
|
||||
ret = idr_alloc(&gvt->vgpu_idr, vgpu, IDLE_VGPU_IDR + 1, GVT_MAX_VGPU,
|
||||
GFP_KERNEL);
|
||||
if (ret < 0)
|
||||
goto out_free_vgpu;
|
||||
|
||||
vgpu->id = ret;
|
||||
vgpu->handle = param->handle;
|
||||
vgpu->gvt = gvt;
|
||||
vgpu->sched_ctl.weight = param->weight;
|
||||
bitmap_zero(vgpu->tlb_handle_pending, I915_NUM_ENGINES);
|
||||
|
||||
intel_vgpu_init_cfg_space(vgpu, param->primary);
|
||||
@@ -325,6 +397,7 @@ struct intel_vgpu *intel_gvt_create_vgpu(struct intel_gvt *gvt,
|
||||
param.low_gm_sz = type->low_gm_size;
|
||||
param.high_gm_sz = type->high_gm_size;
|
||||
param.fence_sz = type->fence;
|
||||
param.weight = type->weight;
|
||||
param.resolution = type->resolution;
|
||||
|
||||
/* XXX current param based on MB */
|
||||
|
||||
@@ -1012,9 +1012,12 @@ static int gpu_state_release(struct inode *inode, struct file *file)
|
||||
|
||||
static int i915_gpu_info_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct drm_i915_private *i915 = inode->i_private;
|
||||
struct i915_gpu_state *gpu;
|
||||
|
||||
gpu = i915_capture_gpu_state(inode->i_private);
|
||||
intel_runtime_pm_get(i915);
|
||||
gpu = i915_capture_gpu_state(i915);
|
||||
intel_runtime_pm_put(i915);
|
||||
if (!gpu)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -1459,16 +1462,14 @@ static int ironlake_drpc_info(struct seq_file *m)
|
||||
|
||||
static int i915_forcewake_domains(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
struct drm_i915_private *i915 = node_to_i915(m->private);
|
||||
struct intel_uncore_forcewake_domain *fw_domain;
|
||||
unsigned int tmp;
|
||||
|
||||
spin_lock_irq(&dev_priv->uncore.lock);
|
||||
for_each_fw_domain(fw_domain, dev_priv) {
|
||||
for_each_fw_domain(fw_domain, i915, tmp)
|
||||
seq_printf(m, "%s.wake_count = %u\n",
|
||||
intel_uncore_forcewake_domain_to_str(fw_domain->id),
|
||||
fw_domain->wake_count);
|
||||
}
|
||||
spin_unlock_irq(&dev_priv->uncore.lock);
|
||||
READ_ONCE(fw_domain->wake_count));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1938,9 +1939,8 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
|
||||
|
||||
static void describe_ctx_ring(struct seq_file *m, struct intel_ring *ring)
|
||||
{
|
||||
seq_printf(m, " (ringbuffer, space: %d, head: %u, tail: %u, last head: %d)",
|
||||
ring->space, ring->head, ring->tail,
|
||||
ring->last_retired_head);
|
||||
seq_printf(m, " (ringbuffer, space: %d, head: %u, tail: %u)",
|
||||
ring->space, ring->head, ring->tail);
|
||||
}
|
||||
|
||||
static int i915_context_status(struct seq_file *m, void *unused)
|
||||
@@ -2474,9 +2474,9 @@ static void i915_guc_client_info(struct seq_file *m,
|
||||
enum intel_engine_id id;
|
||||
uint64_t tot = 0;
|
||||
|
||||
seq_printf(m, "\tPriority %d, GuC ctx index: %u, PD offset 0x%x\n",
|
||||
client->priority, client->ctx_index, client->proc_desc_offset);
|
||||
seq_printf(m, "\tDoorbell id %d, offset: 0x%x, cookie 0x%x\n",
|
||||
seq_printf(m, "\tPriority %d, GuC stage index: %u, PD offset 0x%x\n",
|
||||
client->priority, client->stage_id, client->proc_desc_offset);
|
||||
seq_printf(m, "\tDoorbell id %d, offset: 0x%lx, cookie 0x%x\n",
|
||||
client->doorbell_id, client->doorbell_offset, client->doorbell_cookie);
|
||||
seq_printf(m, "\tWQ size %d, offset: 0x%x, tail %d\n",
|
||||
client->wq_size, client->wq_offset, client->wq_tail);
|
||||
@@ -2511,7 +2511,7 @@ static int i915_guc_info(struct seq_file *m, void *data)
|
||||
}
|
||||
|
||||
seq_printf(m, "Doorbell map:\n");
|
||||
seq_printf(m, "\t%*pb\n", GUC_MAX_DOORBELLS, guc->doorbell_bitmap);
|
||||
seq_printf(m, "\t%*pb\n", GUC_NUM_DOORBELLS, guc->doorbell_bitmap);
|
||||
seq_printf(m, "Doorbell next cacheline: 0x%x\n\n", guc->db_cacheline);
|
||||
|
||||
seq_printf(m, "GuC total action count: %llu\n", guc->action_count);
|
||||
@@ -4129,7 +4129,9 @@ i915_wedged_get(void *data, u64 *val)
|
||||
static int
|
||||
i915_wedged_set(void *data, u64 val)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = data;
|
||||
struct drm_i915_private *i915 = data;
|
||||
struct intel_engine_cs *engine;
|
||||
unsigned int tmp;
|
||||
|
||||
/*
|
||||
* There is no safeguard against this debugfs entry colliding
|
||||
@@ -4139,13 +4141,17 @@ i915_wedged_set(void *data, u64 val)
|
||||
* while it is writing to 'i915_wedged'
|
||||
*/
|
||||
|
||||
if (i915_reset_backoff(&dev_priv->gpu_error))
|
||||
if (i915_reset_backoff(&i915->gpu_error))
|
||||
return -EAGAIN;
|
||||
|
||||
i915_handle_error(dev_priv, val,
|
||||
"Manually setting wedged to %llu", val);
|
||||
for_each_engine_masked(engine, i915, val, tmp) {
|
||||
engine->hangcheck.seqno = intel_engine_get_seqno(engine);
|
||||
engine->hangcheck.stalled = true;
|
||||
}
|
||||
|
||||
wait_on_bit(&dev_priv->gpu_error.flags,
|
||||
i915_handle_error(i915, val, "Manually setting wedged to %llu", val);
|
||||
|
||||
wait_on_bit(&i915->gpu_error.flags,
|
||||
I915_RESET_HANDOFF,
|
||||
TASK_UNINTERRUPTIBLE);
|
||||
|
||||
@@ -4173,10 +4179,6 @@ fault_irq_set(struct drm_i915_private *i915,
|
||||
if (err)
|
||||
goto err_unlock;
|
||||
|
||||
/* Retire to kick idle work */
|
||||
i915_gem_retire_requests(i915);
|
||||
GEM_BUG_ON(i915->gt.active_requests);
|
||||
|
||||
*irq = val;
|
||||
mutex_unlock(&i915->drm.struct_mutex);
|
||||
|
||||
@@ -4280,7 +4282,7 @@ i915_drop_caches_set(void *data, u64 val)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (val & (DROP_RETIRE | DROP_ACTIVE))
|
||||
if (val & DROP_RETIRE)
|
||||
i915_gem_retire_requests(dev_priv);
|
||||
|
||||
lockdep_set_current_reclaim_state(GFP_KERNEL);
|
||||
|
||||
@@ -549,6 +549,7 @@ static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {
|
||||
static void i915_gem_fini(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
mutex_lock(&dev_priv->drm.struct_mutex);
|
||||
intel_uc_fini_hw(dev_priv);
|
||||
i915_gem_cleanup_engines(dev_priv);
|
||||
i915_gem_context_fini(dev_priv);
|
||||
mutex_unlock(&dev_priv->drm.struct_mutex);
|
||||
@@ -609,7 +610,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
|
||||
|
||||
ret = i915_gem_init(dev_priv);
|
||||
if (ret)
|
||||
goto cleanup_irq;
|
||||
goto cleanup_uc;
|
||||
|
||||
intel_modeset_gem_init(dev);
|
||||
|
||||
@@ -631,9 +632,9 @@ cleanup_gem:
|
||||
if (i915_gem_suspend(dev_priv))
|
||||
DRM_ERROR("failed to idle hardware; continuing to unload!\n");
|
||||
i915_gem_fini(dev_priv);
|
||||
cleanup_uc:
|
||||
intel_uc_fini_fw(dev_priv);
|
||||
cleanup_irq:
|
||||
intel_guc_fini(dev_priv);
|
||||
intel_huc_fini(dev_priv);
|
||||
drm_irq_uninstall(dev);
|
||||
intel_teardown_gmbus(dev_priv);
|
||||
cleanup_csr:
|
||||
@@ -1351,9 +1352,8 @@ void i915_driver_unload(struct drm_device *dev)
|
||||
/* Flush any outstanding unpin_work. */
|
||||
drain_workqueue(dev_priv->wq);
|
||||
|
||||
intel_guc_fini(dev_priv);
|
||||
intel_huc_fini(dev_priv);
|
||||
i915_gem_fini(dev_priv);
|
||||
intel_uc_fini_fw(dev_priv);
|
||||
intel_fbc_cleanup_cfb(dev_priv);
|
||||
|
||||
intel_power_domains_fini(dev_priv);
|
||||
|
||||
@@ -79,26 +79,8 @@
|
||||
|
||||
#define DRIVER_NAME "i915"
|
||||
#define DRIVER_DESC "Intel Graphics"
|
||||
#define DRIVER_DATE "20170320"
|
||||
#define DRIVER_TIMESTAMP 1489994464
|
||||
|
||||
#undef WARN_ON
|
||||
/* Many gcc seem to no see through this and fall over :( */
|
||||
#if 0
|
||||
#define WARN_ON(x) ({ \
|
||||
bool __i915_warn_cond = (x); \
|
||||
if (__builtin_constant_p(__i915_warn_cond)) \
|
||||
BUILD_BUG_ON(__i915_warn_cond); \
|
||||
WARN(__i915_warn_cond, "WARN_ON(" #x ")"); })
|
||||
#else
|
||||
#define WARN_ON(x) WARN((x), "%s", "WARN_ON(" __stringify(x) ")")
|
||||
#endif
|
||||
|
||||
#undef WARN_ON_ONCE
|
||||
#define WARN_ON_ONCE(x) WARN_ONCE((x), "%s", "WARN_ON_ONCE(" __stringify(x) ")")
|
||||
|
||||
#define MISSING_CASE(x) WARN(1, "Missing switch case (%lu) in %s\n", \
|
||||
(long) (x), __func__);
|
||||
#define DRIVER_DATE "20170403"
|
||||
#define DRIVER_TIMESTAMP 1491198738
|
||||
|
||||
/* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and
|
||||
* WARN_ON()) for hw state sanity checks to check for unexpected conditions
|
||||
@@ -703,9 +685,9 @@ enum forcewake_domain_id {
|
||||
};
|
||||
|
||||
enum forcewake_domains {
|
||||
FORCEWAKE_RENDER = (1 << FW_DOMAIN_ID_RENDER),
|
||||
FORCEWAKE_BLITTER = (1 << FW_DOMAIN_ID_BLITTER),
|
||||
FORCEWAKE_MEDIA = (1 << FW_DOMAIN_ID_MEDIA),
|
||||
FORCEWAKE_RENDER = BIT(FW_DOMAIN_ID_RENDER),
|
||||
FORCEWAKE_BLITTER = BIT(FW_DOMAIN_ID_BLITTER),
|
||||
FORCEWAKE_MEDIA = BIT(FW_DOMAIN_ID_MEDIA),
|
||||
FORCEWAKE_ALL = (FORCEWAKE_RENDER |
|
||||
FORCEWAKE_BLITTER |
|
||||
FORCEWAKE_MEDIA)
|
||||
@@ -732,21 +714,25 @@ intel_uncore_forcewake_for_reg(struct drm_i915_private *dev_priv,
|
||||
|
||||
struct intel_uncore_funcs {
|
||||
void (*force_wake_get)(struct drm_i915_private *dev_priv,
|
||||
enum forcewake_domains domains);
|
||||
enum forcewake_domains domains);
|
||||
void (*force_wake_put)(struct drm_i915_private *dev_priv,
|
||||
enum forcewake_domains domains);
|
||||
enum forcewake_domains domains);
|
||||
|
||||
uint8_t (*mmio_readb)(struct drm_i915_private *dev_priv, i915_reg_t r, bool trace);
|
||||
uint16_t (*mmio_readw)(struct drm_i915_private *dev_priv, i915_reg_t r, bool trace);
|
||||
uint32_t (*mmio_readl)(struct drm_i915_private *dev_priv, i915_reg_t r, bool trace);
|
||||
uint64_t (*mmio_readq)(struct drm_i915_private *dev_priv, i915_reg_t r, bool trace);
|
||||
uint8_t (*mmio_readb)(struct drm_i915_private *dev_priv,
|
||||
i915_reg_t r, bool trace);
|
||||
uint16_t (*mmio_readw)(struct drm_i915_private *dev_priv,
|
||||
i915_reg_t r, bool trace);
|
||||
uint32_t (*mmio_readl)(struct drm_i915_private *dev_priv,
|
||||
i915_reg_t r, bool trace);
|
||||
uint64_t (*mmio_readq)(struct drm_i915_private *dev_priv,
|
||||
i915_reg_t r, bool trace);
|
||||
|
||||
void (*mmio_writeb)(struct drm_i915_private *dev_priv, i915_reg_t r,
|
||||
uint8_t val, bool trace);
|
||||
void (*mmio_writew)(struct drm_i915_private *dev_priv, i915_reg_t r,
|
||||
uint16_t val, bool trace);
|
||||
void (*mmio_writel)(struct drm_i915_private *dev_priv, i915_reg_t r,
|
||||
uint32_t val, bool trace);
|
||||
void (*mmio_writeb)(struct drm_i915_private *dev_priv,
|
||||
i915_reg_t r, uint8_t val, bool trace);
|
||||
void (*mmio_writew)(struct drm_i915_private *dev_priv,
|
||||
i915_reg_t r, uint16_t val, bool trace);
|
||||
void (*mmio_writel)(struct drm_i915_private *dev_priv,
|
||||
i915_reg_t r, uint32_t val, bool trace);
|
||||
};
|
||||
|
||||
struct intel_forcewake_range {
|
||||
@@ -770,32 +756,35 @@ struct intel_uncore {
|
||||
enum forcewake_domains fw_domains;
|
||||
enum forcewake_domains fw_domains_active;
|
||||
|
||||
u32 fw_set;
|
||||
u32 fw_clear;
|
||||
u32 fw_reset;
|
||||
|
||||
struct intel_uncore_forcewake_domain {
|
||||
struct drm_i915_private *i915;
|
||||
enum forcewake_domain_id id;
|
||||
enum forcewake_domains mask;
|
||||
unsigned wake_count;
|
||||
struct hrtimer timer;
|
||||
i915_reg_t reg_set;
|
||||
u32 val_set;
|
||||
u32 val_clear;
|
||||
i915_reg_t reg_ack;
|
||||
i915_reg_t reg_post;
|
||||
u32 val_reset;
|
||||
} fw_domain[FW_DOMAIN_ID_COUNT];
|
||||
|
||||
int unclaimed_mmio_check;
|
||||
};
|
||||
|
||||
/* Iterate over initialised fw domains */
|
||||
#define for_each_fw_domain_masked(domain__, mask__, dev_priv__) \
|
||||
for ((domain__) = &(dev_priv__)->uncore.fw_domain[0]; \
|
||||
(domain__) < &(dev_priv__)->uncore.fw_domain[FW_DOMAIN_ID_COUNT]; \
|
||||
(domain__)++) \
|
||||
for_each_if ((mask__) & (domain__)->mask)
|
||||
#define __mask_next_bit(mask) ({ \
|
||||
int __idx = ffs(mask) - 1; \
|
||||
mask &= ~BIT(__idx); \
|
||||
__idx; \
|
||||
})
|
||||
|
||||
#define for_each_fw_domain(domain__, dev_priv__) \
|
||||
for_each_fw_domain_masked(domain__, FORCEWAKE_ALL, dev_priv__)
|
||||
/* Iterate over initialised fw domains */
|
||||
#define for_each_fw_domain_masked(domain__, mask__, dev_priv__, tmp__) \
|
||||
for (tmp__ = (mask__); \
|
||||
tmp__ ? (domain__ = &(dev_priv__)->uncore.fw_domain[__mask_next_bit(tmp__)]), 1 : 0;)
|
||||
|
||||
#define for_each_fw_domain(domain__, dev_priv__, tmp__) \
|
||||
for_each_fw_domain_masked(domain__, (dev_priv__)->uncore.fw_domains, dev_priv__, tmp__)
|
||||
|
||||
#define CSR_VERSION(major, minor) ((major) << 16 | (minor))
|
||||
#define CSR_VERSION_MAJOR(version) ((version) >> 16)
|
||||
@@ -846,6 +835,7 @@ struct intel_csr {
|
||||
func(has_resource_streamer); \
|
||||
func(has_runtime_pm); \
|
||||
func(has_snoop); \
|
||||
func(unfenced_needs_alignment); \
|
||||
func(cursor_needs_physical); \
|
||||
func(hws_needs_physical); \
|
||||
func(overlay_needs_physical); \
|
||||
@@ -2578,12 +2568,6 @@ static inline struct drm_i915_private *huc_to_i915(struct intel_huc *huc)
|
||||
(id__)++) \
|
||||
for_each_if ((engine__) = (dev_priv__)->engine[(id__)])
|
||||
|
||||
#define __mask_next_bit(mask) ({ \
|
||||
int __idx = ffs(mask) - 1; \
|
||||
mask &= ~BIT(__idx); \
|
||||
__idx; \
|
||||
})
|
||||
|
||||
/* Iterator over subset of engines selected by mask */
|
||||
#define for_each_engine_masked(engine__, dev_priv__, mask__, tmp__) \
|
||||
for (tmp__ = mask__ & INTEL_INFO(dev_priv__)->ring_mask; \
|
||||
@@ -3956,14 +3940,14 @@ u64 intel_rc6_residency_us(struct drm_i915_private *dev_priv,
|
||||
#define POSTING_READ16(reg) (void)I915_READ16_NOTRACE(reg)
|
||||
|
||||
#define __raw_read(x, s) \
|
||||
static inline uint##x##_t __raw_i915_read##x(struct drm_i915_private *dev_priv, \
|
||||
static inline uint##x##_t __raw_i915_read##x(const struct drm_i915_private *dev_priv, \
|
||||
i915_reg_t reg) \
|
||||
{ \
|
||||
return read##s(dev_priv->regs + i915_mmio_reg_offset(reg)); \
|
||||
}
|
||||
|
||||
#define __raw_write(x, s) \
|
||||
static inline void __raw_i915_write##x(struct drm_i915_private *dev_priv, \
|
||||
static inline void __raw_i915_write##x(const struct drm_i915_private *dev_priv, \
|
||||
i915_reg_t reg, uint##x##_t val) \
|
||||
{ \
|
||||
write##s(val, dev_priv->regs + i915_mmio_reg_offset(reg)); \
|
||||
|
||||
@@ -2321,7 +2321,7 @@ rebuild_st:
|
||||
st->nents = 0;
|
||||
for (i = 0; i < page_count; i++) {
|
||||
page = shmem_read_mapping_page_gfp(mapping, i, gfp);
|
||||
if (IS_ERR(page)) {
|
||||
if (unlikely(IS_ERR(page))) {
|
||||
i915_gem_shrink(dev_priv,
|
||||
page_count,
|
||||
I915_SHRINK_BOUND |
|
||||
@@ -2329,12 +2329,21 @@ rebuild_st:
|
||||
I915_SHRINK_PURGEABLE);
|
||||
page = shmem_read_mapping_page_gfp(mapping, i, gfp);
|
||||
}
|
||||
if (IS_ERR(page)) {
|
||||
if (unlikely(IS_ERR(page))) {
|
||||
gfp_t reclaim;
|
||||
|
||||
/* We've tried hard to allocate the memory by reaping
|
||||
* our own buffer, now let the real VM do its job and
|
||||
* go down in flames if truly OOM.
|
||||
*
|
||||
* However, since graphics tend to be disposable,
|
||||
* defer the oom here by reporting the ENOMEM back
|
||||
* to userspace.
|
||||
*/
|
||||
page = shmem_read_mapping_page(mapping, i);
|
||||
reclaim = mapping_gfp_constraint(mapping, 0);
|
||||
reclaim |= __GFP_NORETRY; /* reclaim, but no oom */
|
||||
|
||||
page = shmem_read_mapping_page_gfp(mapping, i, reclaim);
|
||||
if (IS_ERR(page)) {
|
||||
ret = PTR_ERR(page);
|
||||
goto err_sg;
|
||||
@@ -2989,10 +2998,15 @@ void i915_gem_set_wedged(struct drm_i915_private *dev_priv)
|
||||
lockdep_assert_held(&dev_priv->drm.struct_mutex);
|
||||
set_bit(I915_WEDGED, &dev_priv->gpu_error.flags);
|
||||
|
||||
/* Retire completed requests first so the list of inflight/incomplete
|
||||
* requests is accurate and we don't try and mark successful requests
|
||||
* as in error during __i915_gem_set_wedged_BKL().
|
||||
*/
|
||||
i915_gem_retire_requests(dev_priv);
|
||||
|
||||
stop_machine(__i915_gem_set_wedged_BKL, dev_priv, NULL);
|
||||
|
||||
i915_gem_context_lost(dev_priv);
|
||||
i915_gem_retire_requests(dev_priv);
|
||||
|
||||
mod_delayed_work(dev_priv->wq, &dev_priv->gt.idle_work, 0);
|
||||
}
|
||||
@@ -3098,9 +3112,7 @@ i915_gem_idle_work_handler(struct work_struct *work)
|
||||
* Wait for last execlists context complete, but bail out in case a
|
||||
* new request is submitted.
|
||||
*/
|
||||
wait_for(READ_ONCE(dev_priv->gt.active_requests) ||
|
||||
intel_engines_are_idle(dev_priv),
|
||||
10);
|
||||
wait_for(intel_engines_are_idle(dev_priv), 10);
|
||||
if (READ_ONCE(dev_priv->gt.active_requests))
|
||||
return;
|
||||
|
||||
@@ -3259,6 +3271,29 @@ static int wait_for_timeline(struct i915_gem_timeline *tl, unsigned int flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wait_for_engine(struct intel_engine_cs *engine, int timeout_ms)
|
||||
{
|
||||
return wait_for(intel_engine_is_idle(engine), timeout_ms);
|
||||
}
|
||||
|
||||
static int wait_for_engines(struct drm_i915_private *i915)
|
||||
{
|
||||
struct intel_engine_cs *engine;
|
||||
enum intel_engine_id id;
|
||||
|
||||
for_each_engine(engine, i915, id) {
|
||||
if (GEM_WARN_ON(wait_for_engine(engine, 50))) {
|
||||
i915_gem_set_wedged(i915);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
GEM_BUG_ON(intel_engine_get_seqno(engine) !=
|
||||
intel_engine_last_submit(engine));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i915_gem_wait_for_idle(struct drm_i915_private *i915, unsigned int flags)
|
||||
{
|
||||
int ret;
|
||||
@@ -3273,13 +3308,16 @@ int i915_gem_wait_for_idle(struct drm_i915_private *i915, unsigned int flags)
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
i915_gem_retire_requests(i915);
|
||||
GEM_BUG_ON(i915->gt.active_requests);
|
||||
|
||||
ret = wait_for_engines(i915);
|
||||
} else {
|
||||
ret = wait_for_timeline(&i915->gt.global_timeline, flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Flushes the GTT write domain for the object if it's dirty. */
|
||||
@@ -3307,8 +3345,14 @@ i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj)
|
||||
* system agents we cannot reproduce this behaviour).
|
||||
*/
|
||||
wmb();
|
||||
if (INTEL_GEN(dev_priv) >= 6 && !HAS_LLC(dev_priv))
|
||||
POSTING_READ(RING_ACTHD(dev_priv->engine[RCS]->mmio_base));
|
||||
if (INTEL_GEN(dev_priv) >= 6 && !HAS_LLC(dev_priv)) {
|
||||
if (intel_runtime_pm_get_if_in_use(dev_priv)) {
|
||||
spin_lock_irq(&dev_priv->uncore.lock);
|
||||
POSTING_READ_FW(RING_ACTHD(dev_priv->engine[RCS]->mmio_base));
|
||||
spin_unlock_irq(&dev_priv->uncore.lock);
|
||||
intel_runtime_pm_put(dev_priv);
|
||||
}
|
||||
}
|
||||
|
||||
intel_fb_obj_flush(obj, write_origin(obj, I915_GEM_DOMAIN_GTT));
|
||||
|
||||
@@ -4408,9 +4452,6 @@ int i915_gem_suspend(struct drm_i915_private *dev_priv)
|
||||
if (ret)
|
||||
goto err_unlock;
|
||||
|
||||
i915_gem_retire_requests(dev_priv);
|
||||
GEM_BUG_ON(dev_priv->gt.active_requests);
|
||||
|
||||
assert_kernel_context_is_current(dev_priv);
|
||||
i915_gem_context_lost(dev_priv);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
Loaded 20 of 60 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user