Skip to content

Commit

Permalink
Merge tag 'drm-intel-fixes-2020-02-20' of git://anongit.freedesktop.o…
Browse files Browse the repository at this point in the history
…rg/drm/drm-intel into drm-fixes

drm/i915 fixes for v5.6-rc3:
- Workaround missing Display Stream Compression (DSC) state readout by
  forcing modeset when its enabled at probe
- Fix EHL port clock voltage level requirements
- Fix queuing retire workers on the virtual engine
- Fix use of partially initialized waiters
- Stop using drm_pci_alloc/drm_pci/free
- Fix rewind of RING_TAIL by forcing a context reload
- Fix locking on resetting ring->head
- Propagate our bug filing URL change to stable kernels

Signed-off-by: Dave Airlie <[email protected]>
From: Jani Nikula <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
  • Loading branch information
airlied committed Feb 21, 2020
2 parents c1368b3 + 15de9cb commit 97d9a4e
Show file tree
Hide file tree
Showing 19 changed files with 168 additions and 108 deletions.
2 changes: 1 addition & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -8392,7 +8392,7 @@ M: Joonas Lahtinen <[email protected]>
M: Rodrigo Vivi <[email protected]>
L: [email protected]
W: https://01.org/linuxgraphics/
B: https://01.org/linuxgraphics/documentation/how-report-bugs
B: https://gitlab.freedesktop.org/drm/intel/-/wikis/How-to-file-i915-bugs
C: irc://chat.freenode.net/intel-gfx
Q: http://patchwork.freedesktop.org/project/intel-gfx/
T: git git://anongit.freedesktop.org/drm-intel
Expand Down
5 changes: 2 additions & 3 deletions drivers/gpu/drm/i915/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,8 @@ config DRM_I915_CAPTURE_ERROR
help
This option enables capturing the GPU state when a hang is detected.
This information is vital for triaging hangs and assists in debugging.
Please report any hang to
https://bugs.freedesktop.org/enter_bug.cgi?product=DRI
for triaging.
Please report any hang for triaging according to:
https://gitlab.freedesktop.org/drm/intel/-/wikis/How-to-file-i915-bugs

If in doubt, say "Y".

Expand Down
4 changes: 3 additions & 1 deletion drivers/gpu/drm/i915/display/intel_ddi.c
Original file line number Diff line number Diff line change
Expand Up @@ -4251,7 +4251,9 @@ static bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv,
struct intel_crtc_state *crtc_state)
{
if (INTEL_GEN(dev_priv) >= 11 && crtc_state->port_clock > 594000)
if (IS_ELKHARTLAKE(dev_priv) && crtc_state->port_clock > 594000)
crtc_state->min_voltage_level = 3;
else if (INTEL_GEN(dev_priv) >= 11 && crtc_state->port_clock > 594000)
crtc_state->min_voltage_level = 1;
else if (IS_CANNONLAKE(dev_priv) && crtc_state->port_clock > 594000)
crtc_state->min_voltage_level = 2;
Expand Down
20 changes: 19 additions & 1 deletion drivers/gpu/drm/i915/display/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -11087,7 +11087,7 @@ static u32 intel_cursor_base(const struct intel_plane_state *plane_state)
u32 base;

if (INTEL_INFO(dev_priv)->display.cursor_needs_physical)
base = obj->phys_handle->busaddr;
base = sg_dma_address(obj->mm.pages->sgl);
else
base = intel_plane_ggtt_offset(plane_state);

Expand Down Expand Up @@ -17433,6 +17433,24 @@ static int intel_initial_commit(struct drm_device *dev)
* have readout for pipe gamma enable.
*/
crtc_state->uapi.color_mgmt_changed = true;

/*
* FIXME hack to force full modeset when DSC is being
* used.
*
* As long as we do not have full state readout and
* config comparison of crtc_state->dsc, we have no way
* to ensure reliable fastset. Remove once we have
* readout for DSC.
*/
if (crtc_state->dsc.compression_enable) {
ret = drm_atomic_add_affected_connectors(state,
&crtc->base);
if (ret)
goto out;
crtc_state->uapi.mode_changed = true;
drm_dbg_kms(dev, "Force full modeset for DSC\n");
}
}
}

Expand Down
16 changes: 16 additions & 0 deletions drivers/gpu/drm/i915/gem/i915_gem_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,22 @@ static int __context_set_persistence(struct i915_gem_context *ctx, bool state)
if (!(ctx->i915->caps.scheduler & I915_SCHEDULER_CAP_PREEMPTION))
return -ENODEV;

/*
* If the cancel fails, we then need to reset, cleanly!
*
* If the per-engine reset fails, all hope is lost! We resort
* to a full GPU reset in that unlikely case, but realistically
* if the engine could not reset, the full reset does not fare
* much better. The damage has been done.
*
* However, if we cannot reset an engine by itself, we cannot
* cleanup a hanging persistent context without causing
* colateral damage, and we should not pretend we can by
* exposing the interface.
*/
if (!intel_has_reset_engine(&ctx->i915->gt))
return -ENODEV;

i915_gem_context_clear_persistence(ctx);
}

Expand Down
3 changes: 0 additions & 3 deletions drivers/gpu/drm/i915/gem/i915_gem_object_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,6 @@ struct drm_i915_gem_object {

void *gvt_info;
};

/** for phys allocated objects */
struct drm_dma_handle *phys_handle;
};

static inline struct drm_i915_gem_object *
Expand Down
98 changes: 50 additions & 48 deletions drivers/gpu/drm/i915/gem/i915_gem_phys.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,88 +22,87 @@
static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
{
struct address_space *mapping = obj->base.filp->f_mapping;
struct drm_dma_handle *phys;
struct sg_table *st;
struct scatterlist *sg;
char *vaddr;
struct sg_table *st;
dma_addr_t dma;
void *vaddr;
void *dst;
int i;
int err;

if (WARN_ON(i915_gem_object_needs_bit17_swizzle(obj)))
return -EINVAL;

/* Always aligning to the object size, allows a single allocation
/*
* Always aligning to the object size, allows a single allocation
* to handle all possible callers, and given typical object sizes,
* the alignment of the buddy allocation will naturally match.
*/
phys = drm_pci_alloc(obj->base.dev,
roundup_pow_of_two(obj->base.size),
roundup_pow_of_two(obj->base.size));
if (!phys)
vaddr = dma_alloc_coherent(&obj->base.dev->pdev->dev,
roundup_pow_of_two(obj->base.size),
&dma, GFP_KERNEL);
if (!vaddr)
return -ENOMEM;

vaddr = phys->vaddr;
st = kmalloc(sizeof(*st), GFP_KERNEL);
if (!st)
goto err_pci;

if (sg_alloc_table(st, 1, GFP_KERNEL))
goto err_st;

sg = st->sgl;
sg->offset = 0;
sg->length = obj->base.size;

sg_assign_page(sg, (struct page *)vaddr);
sg_dma_address(sg) = dma;
sg_dma_len(sg) = obj->base.size;

dst = vaddr;
for (i = 0; i < obj->base.size / PAGE_SIZE; i++) {
struct page *page;
char *src;
void *src;

page = shmem_read_mapping_page(mapping, i);
if (IS_ERR(page)) {
err = PTR_ERR(page);
goto err_phys;
}
if (IS_ERR(page))
goto err_st;

src = kmap_atomic(page);
memcpy(vaddr, src, PAGE_SIZE);
drm_clflush_virt_range(vaddr, PAGE_SIZE);
memcpy(dst, src, PAGE_SIZE);
drm_clflush_virt_range(dst, PAGE_SIZE);
kunmap_atomic(src);

put_page(page);
vaddr += PAGE_SIZE;
dst += PAGE_SIZE;
}

intel_gt_chipset_flush(&to_i915(obj->base.dev)->gt);

st = kmalloc(sizeof(*st), GFP_KERNEL);
if (!st) {
err = -ENOMEM;
goto err_phys;
}

if (sg_alloc_table(st, 1, GFP_KERNEL)) {
kfree(st);
err = -ENOMEM;
goto err_phys;
}

sg = st->sgl;
sg->offset = 0;
sg->length = obj->base.size;

sg_dma_address(sg) = phys->busaddr;
sg_dma_len(sg) = obj->base.size;

obj->phys_handle = phys;

__i915_gem_object_set_pages(obj, st, sg->length);

return 0;

err_phys:
drm_pci_free(obj->base.dev, phys);

return err;
err_st:
kfree(st);
err_pci:
dma_free_coherent(&obj->base.dev->pdev->dev,
roundup_pow_of_two(obj->base.size),
vaddr, dma);
return -ENOMEM;
}

static void
i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj,
struct sg_table *pages)
{
dma_addr_t dma = sg_dma_address(pages->sgl);
void *vaddr = sg_page(pages->sgl);

__i915_gem_object_release_shmem(obj, pages, false);

if (obj->mm.dirty) {
struct address_space *mapping = obj->base.filp->f_mapping;
char *vaddr = obj->phys_handle->vaddr;
void *src = vaddr;
int i;

for (i = 0; i < obj->base.size / PAGE_SIZE; i++) {
Expand All @@ -115,23 +114,26 @@ i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj,
continue;

dst = kmap_atomic(page);
drm_clflush_virt_range(vaddr, PAGE_SIZE);
memcpy(dst, vaddr, PAGE_SIZE);
drm_clflush_virt_range(src, PAGE_SIZE);
memcpy(dst, src, PAGE_SIZE);
kunmap_atomic(dst);

set_page_dirty(page);
if (obj->mm.madv == I915_MADV_WILLNEED)
mark_page_accessed(page);
put_page(page);
vaddr += PAGE_SIZE;

src += PAGE_SIZE;
}
obj->mm.dirty = false;
}

sg_free_table(pages);
kfree(pages);

drm_pci_free(obj->base.dev, obj->phys_handle);
dma_free_coherent(&obj->base.dev->pdev->dev,
roundup_pow_of_two(obj->base.size),
vaddr, dma);
}

static void phys_release(struct drm_i915_gem_object *obj)
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ static void add_retire(struct intel_breadcrumbs *b, struct intel_timeline *tl)
struct intel_engine_cs *engine =
container_of(b, struct intel_engine_cs, breadcrumbs);

if (unlikely(intel_engine_is_virtual(engine)))
engine = intel_virtual_engine_get_sibling(engine, 0);

intel_engine_add_retire(engine, tl);
}

Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/i915/gt/intel_gt_requests.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ static bool add_retire(struct intel_engine_cs *engine,
void intel_engine_add_retire(struct intel_engine_cs *engine,
struct intel_timeline *tl)
{
/* We don't deal well with the engine disappearing beneath us */
GEM_BUG_ON(intel_engine_is_virtual(engine));

if (add_retire(engine, tl))
schedule_work(&engine->retire_work);
}
Expand Down
Loading

0 comments on commit 97d9a4e

Please sign in to comment.