Skip to content

Commit 9698084

Browse files
committed
Merge tag 'drm-intel-fixes-2017-12-07' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes
- Fix for fd.o bug #103997 CNL eDP + HDMI causing a machine hard hang (James) - Fix to allow suspending with a wedged GPU to hopefully unwedge it (Chris) - Fix for Gen2 vblank timestap/frame counter jumps (Ville) - Revert of a W/A for enabling FBC on CNL/GLK for certain images and sizes (Rodrigo) - Lockdep fix for i915 userptr code (Chris) gvt-fixes-2017-12-06 - Fix invalid hw reg read value for vGPU (Xiong) - Fix qemu warning on PCI ROM bar missing (Changbin) - Workaround preemption regression (Zhenyu) * tag 'drm-intel-fixes-2017-12-07' of git://anongit.freedesktop.org/drm/drm-intel: Revert "drm/i915: Display WA #1133 WaFbcSkipSegments:cnl, glk" drm/i915: Call i915_gem_init_userptr() before taking struct_mutex drm/i915/gvt: set max priority for gvt context drm/i915/gvt: Don't mark vgpu context as inactive when preempted drm/i915/gvt: Limit read hw reg to active vgpu drm/i915/gvt: Export intel_gvt_render_mmio_to_ring_id() drm/i915/gvt: Emulate PCI expansion ROM base address register drm/i915/cnl: Mask previous DDI - PLL mapping drm/i915: Fix vblank timestamp/frame counter jumps on gen2 drm/i915: Skip switch-to-kernel-context on suspend when wedged
2 parents c2ef3a6 + d85936a commit 9698084

File tree

9 files changed

+133
-58
lines changed

9 files changed

+133
-58
lines changed

drivers/gpu/drm/i915/gvt/cfg_space.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,20 @@ static int emulate_pci_command_write(struct intel_vgpu *vgpu,
208208
return 0;
209209
}
210210

211+
static int emulate_pci_rom_bar_write(struct intel_vgpu *vgpu,
212+
unsigned int offset, void *p_data, unsigned int bytes)
213+
{
214+
u32 *pval = (u32 *)(vgpu_cfg_space(vgpu) + offset);
215+
u32 new = *(u32 *)(p_data);
216+
217+
if ((new & PCI_ROM_ADDRESS_MASK) == PCI_ROM_ADDRESS_MASK)
218+
/* We don't have rom, return size of 0. */
219+
*pval = 0;
220+
else
221+
vgpu_pci_cfg_mem_write(vgpu, offset, p_data, bytes);
222+
return 0;
223+
}
224+
211225
static int emulate_pci_bar_write(struct intel_vgpu *vgpu, unsigned int offset,
212226
void *p_data, unsigned int bytes)
213227
{
@@ -300,6 +314,11 @@ int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset,
300314
}
301315

302316
switch (rounddown(offset, 4)) {
317+
case PCI_ROM_ADDRESS:
318+
if (WARN_ON(!IS_ALIGNED(offset, 4)))
319+
return -EINVAL;
320+
return emulate_pci_rom_bar_write(vgpu, offset, p_data, bytes);
321+
303322
case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_5:
304323
if (WARN_ON(!IS_ALIGNED(offset, 4)))
305324
return -EINVAL;
@@ -375,6 +394,8 @@ void intel_vgpu_init_cfg_space(struct intel_vgpu *vgpu,
375394
pci_resource_len(gvt->dev_priv->drm.pdev, 0);
376395
vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].size =
377396
pci_resource_len(gvt->dev_priv->drm.pdev, 2);
397+
398+
memset(vgpu_cfg_space(vgpu) + PCI_ROM_ADDRESS, 0, 4);
378399
}
379400

380401
/**

drivers/gpu/drm/i915/gvt/handlers.c

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -137,17 +137,26 @@ static int new_mmio_info(struct intel_gvt *gvt,
137137
return 0;
138138
}
139139

140-
static int render_mmio_to_ring_id(struct intel_gvt *gvt, unsigned int reg)
140+
/**
141+
* intel_gvt_render_mmio_to_ring_id - convert a mmio offset into ring id
142+
* @gvt: a GVT device
143+
* @offset: register offset
144+
*
145+
* Returns:
146+
* Ring ID on success, negative error code if failed.
147+
*/
148+
int intel_gvt_render_mmio_to_ring_id(struct intel_gvt *gvt,
149+
unsigned int offset)
141150
{
142151
enum intel_engine_id id;
143152
struct intel_engine_cs *engine;
144153

145-
reg &= ~GENMASK(11, 0);
154+
offset &= ~GENMASK(11, 0);
146155
for_each_engine(engine, gvt->dev_priv, id) {
147-
if (engine->mmio_base == reg)
156+
if (engine->mmio_base == offset)
148157
return id;
149158
}
150-
return -1;
159+
return -ENODEV;
151160
}
152161

153162
#define offset_to_fence_num(offset) \
@@ -1398,18 +1407,36 @@ static int skl_lcpll_write(struct intel_vgpu *vgpu, unsigned int offset,
13981407
static int mmio_read_from_hw(struct intel_vgpu *vgpu,
13991408
unsigned int offset, void *p_data, unsigned int bytes)
14001409
{
1401-
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
1410+
struct intel_gvt *gvt = vgpu->gvt;
1411+
struct drm_i915_private *dev_priv = gvt->dev_priv;
1412+
int ring_id;
1413+
u32 ring_base;
1414+
1415+
ring_id = intel_gvt_render_mmio_to_ring_id(gvt, offset);
1416+
/**
1417+
* Read HW reg in following case
1418+
* a. the offset isn't a ring mmio
1419+
* b. the offset's ring is running on hw.
1420+
* c. the offset is ring time stamp mmio
1421+
*/
1422+
if (ring_id >= 0)
1423+
ring_base = dev_priv->engine[ring_id]->mmio_base;
1424+
1425+
if (ring_id < 0 || vgpu == gvt->scheduler.engine_owner[ring_id] ||
1426+
offset == i915_mmio_reg_offset(RING_TIMESTAMP(ring_base)) ||
1427+
offset == i915_mmio_reg_offset(RING_TIMESTAMP_UDW(ring_base))) {
1428+
mmio_hw_access_pre(dev_priv);
1429+
vgpu_vreg(vgpu, offset) = I915_READ(_MMIO(offset));
1430+
mmio_hw_access_post(dev_priv);
1431+
}
14021432

1403-
mmio_hw_access_pre(dev_priv);
1404-
vgpu_vreg(vgpu, offset) = I915_READ(_MMIO(offset));
1405-
mmio_hw_access_post(dev_priv);
14061433
return intel_vgpu_default_mmio_read(vgpu, offset, p_data, bytes);
14071434
}
14081435

14091436
static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
14101437
void *p_data, unsigned int bytes)
14111438
{
1412-
int ring_id = render_mmio_to_ring_id(vgpu->gvt, offset);
1439+
int ring_id = intel_gvt_render_mmio_to_ring_id(vgpu->gvt, offset);
14131440
struct intel_vgpu_execlist *execlist;
14141441
u32 data = *(u32 *)p_data;
14151442
int ret = 0;
@@ -1436,7 +1463,7 @@ static int ring_mode_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
14361463
void *p_data, unsigned int bytes)
14371464
{
14381465
u32 data = *(u32 *)p_data;
1439-
int ring_id = render_mmio_to_ring_id(vgpu->gvt, offset);
1466+
int ring_id = intel_gvt_render_mmio_to_ring_id(vgpu->gvt, offset);
14401467
bool enable_execlist;
14411468

14421469
write_vreg(vgpu, offset, p_data, bytes);

drivers/gpu/drm/i915/gvt/mmio.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ struct intel_gvt_mmio_info {
6565
struct hlist_node node;
6666
};
6767

68+
int intel_gvt_render_mmio_to_ring_id(struct intel_gvt *gvt,
69+
unsigned int reg);
6870
unsigned long intel_gvt_get_device_type(struct intel_gvt *gvt);
6971
bool intel_gvt_match_device(struct intel_gvt *gvt, unsigned long device);
7072

drivers/gpu/drm/i915/gvt/scheduler.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,20 @@ static inline bool is_gvt_request(struct drm_i915_gem_request *req)
131131
return i915_gem_context_force_single_submission(req->ctx);
132132
}
133133

134+
static void save_ring_hw_state(struct intel_vgpu *vgpu, int ring_id)
135+
{
136+
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
137+
u32 ring_base = dev_priv->engine[ring_id]->mmio_base;
138+
i915_reg_t reg;
139+
140+
reg = RING_INSTDONE(ring_base);
141+
vgpu_vreg(vgpu, i915_mmio_reg_offset(reg)) = I915_READ_FW(reg);
142+
reg = RING_ACTHD(ring_base);
143+
vgpu_vreg(vgpu, i915_mmio_reg_offset(reg)) = I915_READ_FW(reg);
144+
reg = RING_ACTHD_UDW(ring_base);
145+
vgpu_vreg(vgpu, i915_mmio_reg_offset(reg)) = I915_READ_FW(reg);
146+
}
147+
134148
static int shadow_context_status_change(struct notifier_block *nb,
135149
unsigned long action, void *data)
136150
{
@@ -175,9 +189,12 @@ static int shadow_context_status_change(struct notifier_block *nb,
175189
atomic_set(&workload->shadow_ctx_active, 1);
176190
break;
177191
case INTEL_CONTEXT_SCHEDULE_OUT:
178-
case INTEL_CONTEXT_SCHEDULE_PREEMPTED:
192+
save_ring_hw_state(workload->vgpu, ring_id);
179193
atomic_set(&workload->shadow_ctx_active, 0);
180194
break;
195+
case INTEL_CONTEXT_SCHEDULE_PREEMPTED:
196+
save_ring_hw_state(workload->vgpu, ring_id);
197+
break;
181198
default:
182199
WARN_ON(1);
183200
return NOTIFY_OK;
@@ -740,6 +757,9 @@ int intel_vgpu_init_gvt_context(struct intel_vgpu *vgpu)
740757
if (IS_ERR(vgpu->shadow_ctx))
741758
return PTR_ERR(vgpu->shadow_ctx);
742759

760+
if (INTEL_INFO(vgpu->gvt->dev_priv)->has_logical_ring_preemption)
761+
vgpu->shadow_ctx->priority = INT_MAX;
762+
743763
vgpu->shadow_ctx->engine[RCS].initialised = true;
744764

745765
bitmap_zero(vgpu->shadow_ctx_desc_updated, I915_NUM_ENGINES);

drivers/gpu/drm/i915/i915_gem.c

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4712,17 +4712,19 @@ int i915_gem_suspend(struct drm_i915_private *dev_priv)
47124712
* state. Fortunately, the kernel_context is disposable and we do
47134713
* not rely on its state.
47144714
*/
4715-
ret = i915_gem_switch_to_kernel_context(dev_priv);
4716-
if (ret)
4717-
goto err_unlock;
4715+
if (!i915_terminally_wedged(&dev_priv->gpu_error)) {
4716+
ret = i915_gem_switch_to_kernel_context(dev_priv);
4717+
if (ret)
4718+
goto err_unlock;
47184719

4719-
ret = i915_gem_wait_for_idle(dev_priv,
4720-
I915_WAIT_INTERRUPTIBLE |
4721-
I915_WAIT_LOCKED);
4722-
if (ret && ret != -EIO)
4723-
goto err_unlock;
4720+
ret = i915_gem_wait_for_idle(dev_priv,
4721+
I915_WAIT_INTERRUPTIBLE |
4722+
I915_WAIT_LOCKED);
4723+
if (ret && ret != -EIO)
4724+
goto err_unlock;
47244725

4725-
assert_kernel_context_is_current(dev_priv);
4726+
assert_kernel_context_is_current(dev_priv);
4727+
}
47264728
i915_gem_contexts_lost(dev_priv);
47274729
mutex_unlock(&dev->struct_mutex);
47284730

@@ -4946,8 +4948,6 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
49464948
{
49474949
int ret;
49484950

4949-
mutex_lock(&dev_priv->drm.struct_mutex);
4950-
49514951
/*
49524952
* We need to fallback to 4K pages since gvt gtt handling doesn't
49534953
* support huge page entries - we will need to check either hypervisor
@@ -4967,18 +4967,19 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
49674967
dev_priv->gt.cleanup_engine = intel_logical_ring_cleanup;
49684968
}
49694969

4970+
ret = i915_gem_init_userptr(dev_priv);
4971+
if (ret)
4972+
return ret;
4973+
49704974
/* This is just a security blanket to placate dragons.
49714975
* On some systems, we very sporadically observe that the first TLBs
49724976
* used by the CS may be stale, despite us poking the TLB reset. If
49734977
* we hold the forcewake during initialisation these problems
49744978
* just magically go away.
49754979
*/
4980+
mutex_lock(&dev_priv->drm.struct_mutex);
49764981
intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
49774982

4978-
ret = i915_gem_init_userptr(dev_priv);
4979-
if (ret)
4980-
goto out_unlock;
4981-
49824983
ret = i915_gem_init_ggtt(dev_priv);
49834984
if (ret)
49844985
goto out_unlock;

drivers/gpu/drm/i915/i915_reg.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2951,9 +2951,6 @@ enum i915_power_well_id {
29512951
#define ILK_DPFC_CHICKEN _MMIO(0x43224)
29522952
#define ILK_DPFC_DISABLE_DUMMY0 (1<<8)
29532953
#define ILK_DPFC_NUKE_ON_ANY_MODIFICATION (1<<23)
2954-
#define GLK_SKIP_SEG_EN (1<<12)
2955-
#define GLK_SKIP_SEG_COUNT_MASK (3<<10)
2956-
#define GLK_SKIP_SEG_COUNT(x) ((x)<<10)
29572954
#define ILK_FBC_RT_BASE _MMIO(0x2128)
29582955
#define ILK_FBC_RT_VALID (1<<0)
29592956
#define SNB_FBC_FRONT_BUFFER (1<<1)

drivers/gpu/drm/i915/intel_ddi.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,6 +2131,7 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder,
21312131
if (IS_CANNONLAKE(dev_priv)) {
21322132
/* Configure DPCLKA_CFGCR0 to map the DPLL to the DDI. */
21332133
val = I915_READ(DPCLKA_CFGCR0);
2134+
val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port);
21342135
val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->id, port);
21352136
I915_WRITE(DPCLKA_CFGCR0, val);
21362137

drivers/gpu/drm/i915/intel_display.c

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,7 +1000,8 @@ enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
10001000
return crtc->config->cpu_transcoder;
10011001
}
10021002

1003-
static bool pipe_dsl_stopped(struct drm_i915_private *dev_priv, enum pipe pipe)
1003+
static bool pipe_scanline_is_moving(struct drm_i915_private *dev_priv,
1004+
enum pipe pipe)
10041005
{
10051006
i915_reg_t reg = PIPEDSL(pipe);
10061007
u32 line1, line2;
@@ -1015,7 +1016,28 @@ static bool pipe_dsl_stopped(struct drm_i915_private *dev_priv, enum pipe pipe)
10151016
msleep(5);
10161017
line2 = I915_READ(reg) & line_mask;
10171018

1018-
return line1 == line2;
1019+
return line1 != line2;
1020+
}
1021+
1022+
static void wait_for_pipe_scanline_moving(struct intel_crtc *crtc, bool state)
1023+
{
1024+
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1025+
enum pipe pipe = crtc->pipe;
1026+
1027+
/* Wait for the display line to settle/start moving */
1028+
if (wait_for(pipe_scanline_is_moving(dev_priv, pipe) == state, 100))
1029+
DRM_ERROR("pipe %c scanline %s wait timed out\n",
1030+
pipe_name(pipe), onoff(state));
1031+
}
1032+
1033+
static void intel_wait_for_pipe_scanline_stopped(struct intel_crtc *crtc)
1034+
{
1035+
wait_for_pipe_scanline_moving(crtc, false);
1036+
}
1037+
1038+
static void intel_wait_for_pipe_scanline_moving(struct intel_crtc *crtc)
1039+
{
1040+
wait_for_pipe_scanline_moving(crtc, true);
10191041
}
10201042

10211043
/*
@@ -1038,7 +1060,6 @@ static void intel_wait_for_pipe_off(struct intel_crtc *crtc)
10381060
{
10391061
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
10401062
enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
1041-
enum pipe pipe = crtc->pipe;
10421063

10431064
if (INTEL_GEN(dev_priv) >= 4) {
10441065
i915_reg_t reg = PIPECONF(cpu_transcoder);
@@ -1049,9 +1070,7 @@ static void intel_wait_for_pipe_off(struct intel_crtc *crtc)
10491070
100))
10501071
WARN(1, "pipe_off wait timed out\n");
10511072
} else {
1052-
/* Wait for the display line to settle */
1053-
if (wait_for(pipe_dsl_stopped(dev_priv, pipe), 100))
1054-
WARN(1, "pipe_off wait timed out\n");
1073+
intel_wait_for_pipe_scanline_stopped(crtc);
10551074
}
10561075
}
10571076

@@ -1936,15 +1955,14 @@ static void intel_enable_pipe(struct intel_crtc *crtc)
19361955
POSTING_READ(reg);
19371956

19381957
/*
1939-
* Until the pipe starts DSL will read as 0, which would cause
1940-
* an apparent vblank timestamp jump, which messes up also the
1941-
* frame count when it's derived from the timestamps. So let's
1942-
* wait for the pipe to start properly before we call
1943-
* drm_crtc_vblank_on()
1958+
* Until the pipe starts PIPEDSL reads will return a stale value,
1959+
* which causes an apparent vblank timestamp jump when PIPEDSL
1960+
* resets to its proper value. That also messes up the frame count
1961+
* when it's derived from the timestamps. So let's wait for the
1962+
* pipe to start properly before we call drm_crtc_vblank_on()
19441963
*/
1945-
if (dev->max_vblank_count == 0 &&
1946-
wait_for(intel_get_crtc_scanline(crtc) != crtc->scanline_offset, 50))
1947-
DRM_ERROR("pipe %c didn't start\n", pipe_name(pipe));
1964+
if (dev->max_vblank_count == 0)
1965+
intel_wait_for_pipe_scanline_moving(crtc);
19481966
}
19491967

19501968
/**
@@ -14643,6 +14661,8 @@ void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
1464314661

1464414662
void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
1464514663
{
14664+
struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
14665+
1464614666
DRM_DEBUG_KMS("disabling pipe %c due to force quirk\n",
1464714667
pipe_name(pipe));
1464814668

@@ -14652,8 +14672,7 @@ void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
1465214672
I915_WRITE(PIPECONF(pipe), 0);
1465314673
POSTING_READ(PIPECONF(pipe));
1465414674

14655-
if (wait_for(pipe_dsl_stopped(dev_priv, pipe), 100))
14656-
DRM_ERROR("pipe %c off wait timed out\n", pipe_name(pipe));
14675+
intel_wait_for_pipe_scanline_stopped(crtc);
1465714676

1465814677
I915_WRITE(DPLL(pipe), DPLL_VGA_MODE_DIS);
1465914678
POSTING_READ(DPLL(pipe));

drivers/gpu/drm/i915/intel_pm.c

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ static void bxt_init_clock_gating(struct drm_i915_private *dev_priv)
124124

125125
static void glk_init_clock_gating(struct drm_i915_private *dev_priv)
126126
{
127-
u32 val;
128127
gen9_init_clock_gating(dev_priv);
129128

130129
/*
@@ -144,11 +143,6 @@ static void glk_init_clock_gating(struct drm_i915_private *dev_priv)
144143
I915_WRITE(CHICKEN_MISC_2, val);
145144
}
146145

147-
/* Display WA #1133: WaFbcSkipSegments:glk */
148-
val = I915_READ(ILK_DPFC_CHICKEN);
149-
val &= ~GLK_SKIP_SEG_COUNT_MASK;
150-
val |= GLK_SKIP_SEG_EN | GLK_SKIP_SEG_COUNT(1);
151-
I915_WRITE(ILK_DPFC_CHICKEN, val);
152146
}
153147

154148
static void i915_pineview_get_mem_freq(struct drm_i915_private *dev_priv)
@@ -8517,7 +8511,6 @@ static void cnp_init_clock_gating(struct drm_i915_private *dev_priv)
85178511

85188512
static void cnl_init_clock_gating(struct drm_i915_private *dev_priv)
85198513
{
8520-
u32 val;
85218514
cnp_init_clock_gating(dev_priv);
85228515

85238516
/* This is not an Wa. Enable for better image quality */
@@ -8537,12 +8530,6 @@ static void cnl_init_clock_gating(struct drm_i915_private *dev_priv)
85378530
I915_WRITE(SLICE_UNIT_LEVEL_CLKGATE,
85388531
I915_READ(SLICE_UNIT_LEVEL_CLKGATE) |
85398532
SARBUNIT_CLKGATE_DIS);
8540-
8541-
/* Display WA #1133: WaFbcSkipSegments:cnl */
8542-
val = I915_READ(ILK_DPFC_CHICKEN);
8543-
val &= ~GLK_SKIP_SEG_COUNT_MASK;
8544-
val |= GLK_SKIP_SEG_EN | GLK_SKIP_SEG_COUNT(1);
8545-
I915_WRITE(ILK_DPFC_CHICKEN, val);
85468533
}
85478534

85488535
static void cfl_init_clock_gating(struct drm_i915_private *dev_priv)

0 commit comments

Comments
 (0)