[Intel-gfx] Updated drm-intel-testing
Hi all, New -testing cycle with cool stuff: - Accurate frontbuffer tracking and frontbuffer rendering invalidate, flush and flip events. This is prep work for proper PSR support and should also be useful for DRRSfbc. - Runtime suspend hardware on system suspend to support the new SOix sleep states, from Jesse. - PSR updates for broadwell (Rodrigo) - Universal plane support for cursors (Matt Roper), including core drm patches. - Prefault gtt mappings (Chris) - baytrail write-enable pte bit support (Akash Goel) - mmio based flips (Sourab Gupta) instead of blitter ring flips - interrupt handling race fixes (Oscar Mateo) And old, not yet merged features from the previous round: - rps/turbo support for chv (Deepak) - some other straggling chv patches (Ville) - proper universal plane conversion for the primary plane (Matt Roper) - ppgtt on vlv from Jesse - pile of cleanups, little fixes for insane corner cases and improved debug support all over Happy testing! Cheers, Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [RFC][PATCH] gpu:drm:i915:intel_detect_pch: back to check devfn instead of check class type
Just ping, any comments? Thanks Tiejun On 2014/6/19 17:53, Tiejun Chen wrote: Originally the reason to probe ISA bridge instead of Dev31:Fun0 is to make graphics device passthrough work easy for VMM, that only need to expose ISA bridge to let driver know the real hardware underneath. This is a requirement from virtualization team. Especially in that virtualized environments, XEN, there is irrelevant ISA bridge in the system with that legacy qemu version specific to xen, qemu-xen-traditional. So to work reliably, we should scan through all the ISA bridge devices and check for the first match, instead of only checking the first one. But actually, qemu-xen-traditional, is always enumerated with Dev31:Fun0, 00:1f.0 as follows: hw/pt-graphics.c: intel_pch_init() | + pci_isa_bridge_init(bus, PCI_DEVFN(0x1f, 0), ...); so this mean that isa bridge is still represented with Dev31:Func0 like the native OS. Furthermore, currently we're pushing VGA passthrough support into qemu upstream, and with some discussion, we wouldn't set the bridge class type and just expose this devfn. So we just go back to check devfn to make life normal. Signed-off-by: Tiejun Chen tiejun.c...@intel.com --- drivers/gpu/drm/i915/i915_drv.c | 19 +++ 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 651e65e..cb2526e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -417,18 +417,8 @@ void intel_detect_pch(struct drm_device *dev) return; } - /* -* The reason to probe ISA bridge instead of Dev31:Fun0 is to -* make graphics device passthrough work easy for VMM, that only -* need to expose ISA bridge to let driver know the real hardware -* underneath. This is a requirement from virtualization team. -* -* In some virtualized environments (e.g. XEN), there is irrelevant -* ISA bridge in the system. To work reliably, we should scan trhough -* all the ISA bridge devices and check for the first match, instead -* of only checking the first one. -*/ - while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA 8, pch))) { + pch = pci_get_bus_and_slot(0, PCI_DEVFN(0x1f, 0)); + if (pch) { if (pch-vendor == PCI_VENDOR_ID_INTEL) { unsigned short id = pch-device INTEL_PCH_DEVICE_ID_MASK; dev_priv-pch_id = id; @@ -462,10 +452,7 @@ void intel_detect_pch(struct drm_device *dev) DRM_DEBUG_KMS(Found LynxPoint LP PCH\n); WARN_ON(!IS_HASWELL(dev)); WARN_ON(!IS_ULT(dev)); - } else - continue; - - break; + } } } if (!pch) ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/4] drm/i915: Clearing buffer objects via blitter engine
From: Chris Wilson ch...@chris-wilson.co.uk This patch adds support for clearing buffer objects via blitter engines. This is particularly useful for clearing out the memory from stolen region. testcase: igt/gem_create2 Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/Makefile| 1 + drivers/gpu/drm/i915/i915_drv.h | 3 + drivers/gpu/drm/i915/i915_gem_exec.c | 120 +++ 3 files changed, 124 insertions(+) create mode 100644 drivers/gpu/drm/i915/i915_gem_exec.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index cad1683..a18f7e5 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -22,6 +22,7 @@ i915-y += i915_cmd_parser.o \ i915_gem_debug.o \ i915_gem_dmabuf.o \ i915_gem_evict.o \ + i915_gem_exec.o \ i915_gem_execbuffer.o \ i915_gem_gtt.o \ i915_gem.o \ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8cea596..4470105 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2480,6 +2480,9 @@ int __must_check i915_gem_evict_something(struct drm_device *dev, int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle); int i915_gem_evict_everything(struct drm_device *dev); +/* i915_gem_exec.c */ +int i915_gem_exec_clear_object(struct drm_i915_gem_object *obj); + /* belongs in i915_gem_gtt.h */ static inline void i915_gem_chipset_flush(struct drm_device *dev) { diff --git a/drivers/gpu/drm/i915/i915_gem_exec.c b/drivers/gpu/drm/i915/i915_gem_exec.c new file mode 100644 index 000..374f1e1 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gem_exec.c @@ -0,0 +1,120 @@ +/* + * Copyright © 2013 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the Software), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + *Chris Wilson ch...@chris-wilson.co.uk + * + */ + +#include drm/drmP.h +#include drm/i915_drm.h +#include i915_drv.h + +#define COLOR_BLT_CMD (229 | 0x4022) +#define BLT_WRITE_ALPHA (121) +#define BLT_WRITE_RGB (120) +#define BLT_WRITE_RGBA (BLT_WRITE_RGB|BLT_WRITE_ALPHA) + +#define BPP_8 0 +#define BPP_16 (124) +#define BPP_32 (125 | 124) + +#define ROP_FILL_COPY (0xf0 16) + +static int i915_gem_exec_flush_object(struct drm_i915_gem_object *obj, + struct intel_engine_cs *ring) +{ + int ret; + + ret = i915_gem_object_sync(obj, ring); + if (ret) + return ret; + + if (obj-base.write_domain I915_GEM_DOMAIN_CPU) { + if (i915_gem_clflush_object(obj, false)) + i915_gem_chipset_flush(obj-base.dev); + obj-base.write_domain = ~I915_GEM_DOMAIN_CPU; + } + if (obj-base.write_domain I915_GEM_DOMAIN_GTT) { + wmb(); + obj-base.write_domain = ~I915_GEM_DOMAIN_GTT; + } + + return intel_ring_invalidate_all_caches(ring); +} + +static void i915_gem_exec_dirty_object(struct drm_i915_gem_object *obj, + struct intel_engine_cs *ring) +{ + obj-fenced_gpu_access = false; + obj-base.read_domains = I915_GEM_DOMAIN_RENDER; + obj-base.write_domain = I915_GEM_DOMAIN_RENDER; + i915_vma_move_to_active(i915_gem_obj_to_ggtt(obj), ring); + obj-last_write_seqno = intel_ring_get_seqno(ring); + obj-dirty = 1; + + ring-gpu_caches_dirty = true; +} + +int i915_gem_exec_clear_object(struct drm_i915_gem_object *obj) +{ + struct drm_device *dev = obj-base.dev; + struct drm_i915_private *dev_priv = dev-dev_private; + struct intel_engine_cs *ring; + int ret; + + lockdep_assert_held(dev-struct_mutex); + + ring = dev_priv-ring[HAS_BLT(dev) ? BCS : RCS]; + + ret = i915_gem_obj_ggtt_pin(obj, 0, 0); + if (ret) + return ret; + +
[Intel-gfx] [PATCH v2 4/4] drm/i915: Add support for stealing purgable stolen pages
From: Chris Wilson ch...@chris-wilson.co.uk If we run out of stolen memory when trying to allocate an object, see if we can reap enough purgeable objects to free up enough contiguous free space for the allocation. This is in principle very much like evicting objects to free up enough contiguous space in the vma when binding a new object - and you will be forgiven for thinking that the code looks very similar. At the moment, we do not allow userspace to allocate objects in stolen, so there is neither the memory pressure to trigger stolen eviction nor any purgeable objects inside the stolen arena. However, this will change in the near future, and so better management and defragmentation of stolen memory will become a real issue. v2: Remember to remove the drm_mm_node. testcase: igt/gem_create2 Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: Gupta, Sourab sourab.gu...@intel.com Cc: Goel, Akash akash.g...@intel.com --- drivers/gpu/drm/i915/i915_gem_stolen.c | 121 ++--- 1 file changed, 110 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index 6441178..042ae61 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -340,18 +340,29 @@ cleanup: return NULL; } -struct drm_i915_gem_object * -i915_gem_object_create_stolen(struct drm_device *dev, u32 size) +static bool mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind) +{ + if (obj-stolen == NULL) + return false; + + if (obj-madv != I915_MADV_DONTNEED) + return false; + + if (i915_gem_obj_is_pinned(obj)) + return false; + + list_add(obj-obj_exec_link, unwind); + return drm_mm_scan_add_block(obj-stolen); +} + +static struct drm_mm_node * +stolen_alloc(struct drm_i915_private *dev_priv, u32 size) { - struct drm_i915_private *dev_priv = dev-dev_private; - struct drm_i915_gem_object *obj; struct drm_mm_node *stolen; + struct drm_i915_gem_object *obj; + struct list_head unwind, evict; int ret; - if (!drm_mm_initialized(dev_priv-mm.stolen)) - return NULL; - - DRM_DEBUG_KMS(creating stolen object: size=%x\n, size); if (size == 0) return NULL; @@ -361,11 +372,99 @@ i915_gem_object_create_stolen(struct drm_device *dev, u32 size) ret = drm_mm_insert_node(dev_priv-mm.stolen, stolen, size, 4096, DRM_MM_SEARCH_DEFAULT); - if (ret) { - kfree(stolen); - return NULL; + if (ret == 0) + return stolen; + + /* No more stolen memory available, or too fragmented. +* Try evicting purgeable objects and search again. +*/ + + drm_mm_init_scan(dev_priv-mm.stolen, size, 4096, 0); + INIT_LIST_HEAD(unwind); + + list_for_each_entry(obj, dev_priv-mm.unbound_list, global_list) + if (mark_free(obj, unwind)) + goto found; + + list_for_each_entry(obj, dev_priv-mm.bound_list, global_list) + if (mark_free(obj, unwind)) + goto found; + +found: + INIT_LIST_HEAD(evict); + while (!list_empty(unwind)) { + obj = list_first_entry(unwind, + struct drm_i915_gem_object, + obj_exec_link); + list_del_init(obj-obj_exec_link); + + if (drm_mm_scan_remove_block(obj-stolen)) { + list_add(obj-obj_exec_link, evict); + drm_gem_object_reference(obj-base); + } } + ret = 0; + while (!list_empty(evict)) { + obj = list_first_entry(evict, + struct drm_i915_gem_object, + obj_exec_link); + list_del_init(obj-obj_exec_link); + + if (ret == 0) { + struct i915_vma *vma, *vma_next; + + list_for_each_entry_safe(vma, vma_next, +obj-vma_list, +vma_link) + if (i915_vma_unbind(vma)) + break; + + /* Stolen pins its pages to prevent the +* normal shrinker from processing stolen +* objects. +*/ + i915_gem_object_unpin_pages(obj); + + ret = i915_gem_object_put_pages(obj); + if (ret == 0) { + i915_gem_object_release_stolen(obj); + obj-madv = __I915_MADV_PURGED; + } else +
[Intel-gfx] [PATCH 2/4] drm/i915: Clearing buffer objects via blitter engine for Gen8
From: Deepak S deepa...@linux.intel.com On Gen8, COLOR BLT commands are different. Add gen8 specific command to clearing buffer objects via blitter engines. Signed-off-by: Deepak S deepa...@linux.intel.com --- drivers/gpu/drm/i915/i915_gem_exec.c | 39 +++- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_exec.c b/drivers/gpu/drm/i915/i915_gem_exec.c index 374f1e1..fc9e454 100644 --- a/drivers/gpu/drm/i915/i915_gem_exec.c +++ b/drivers/gpu/drm/i915/i915_gem_exec.c @@ -29,6 +29,8 @@ #include drm/i915_drm.h #include i915_drv.h +#define GEN8_COLOR_BLT_CMD (229 | 0x5022) + #define COLOR_BLT_CMD (229 | 0x4022) #define BLT_WRITE_ALPHA (121) #define BLT_WRITE_RGB (120) @@ -100,18 +102,35 @@ int i915_gem_exec_clear_object(struct drm_i915_gem_object *obj) if (ret) goto unpin; - ret = intel_ring_begin(ring, 6); - if (ret) - goto unpin; + if (IS_GEN8(dev)) { + ret = intel_ring_begin(ring, 8); + if (ret) + goto unpin; - intel_ring_emit(ring, COLOR_BLT_CMD | BLT_WRITE_RGBA | (5-2)); - intel_ring_emit(ring, BPP_32 | ROP_FILL_COPY | PAGE_SIZE); - intel_ring_emit(ring, obj-base.size PAGE_SHIFT 16 | PAGE_SIZE); - intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj)); - intel_ring_emit(ring, 0); - intel_ring_emit(ring, MI_NOOP); + intel_ring_emit(ring, GEN8_COLOR_BLT_CMD | BLT_WRITE_RGBA | (7-2)); + intel_ring_emit(ring, BPP_32 | ROP_FILL_COPY | PAGE_SIZE); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, obj-base.size PAGE_SHIFT 16 | PAGE_SIZE / 4); + intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj)); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, MI_NOOP); + + __intel_ring_advance(ring); + } else { + ret = intel_ring_begin(ring, 6); + if (ret) + goto unpin; - __intel_ring_advance(ring); + intel_ring_emit(ring, COLOR_BLT_CMD | BLT_WRITE_RGBA | (5-2)); + intel_ring_emit(ring, BPP_32 | ROP_FILL_COPY | PAGE_SIZE); + intel_ring_emit(ring, obj-base.size PAGE_SHIFT 16 | PAGE_SIZE); + intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj)); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, MI_NOOP); + + __intel_ring_advance(ring); + } i915_gem_exec_dirty_object(obj, ring); unpin: -- 1.8.5.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v4 3/4] drm/i915: Introduce a new create ioctl for user specified placement
From: Chris Wilson ch...@chris-wilson.co.uk Despite being a unified memory architecture (UMA) some bits of memory are more equal than others. In particular we have the thorny issue of stolen memory, memory stolen from the system by the BIOS and reserved for igfx use. Stolen memory is required for some functions of the GPU and display engine, but in general it goes wasted. Whilst we cannot return it back to the system, we need to find some other method for utilising it. As we do not support direct access to the physical address in the stolen region, it behaves like a different class of memory, closer in kin to local GPU memory. This strongly suggests that we need a placement model like TTM if we are to fully utilize these discrete chunks of differing memory. This new create ioctl therefore exists to allow the user to create these second class buffer objects from stolen memory. At the moment direct access by the CPU through mmaps and pread/pwrite are verboten on the objects, and so the user must be aware of the limitations of the objects created. Yet, those limitations rarely reduce the desired functionality in many use cases and so the user should be able to easily fill the stolen memory and so help to reduce overall memory pressure. The most obvious use case for stolen memory is for the creation of objects for the display engine which already have very similar restrictions on access. However, we want a reasonably general ioctl in order to cater for diverse scenarios beyond the author's imagination. v2: Expand the struct slightly to include cache domains, and ensure that all memory allocated by the kernel for userspace is zeroed. v3: Ben suggested the idea of binding the object at a known offset into the target context upon creation. v4: Revert the removal of DRM_AUTH from some ioctls, which got squashed in by mistake (Damien) testcase: igt/gem_create2 Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_dma.c| 5 +- drivers/gpu/drm/i915/i915_drv.h| 15 ++- drivers/gpu/drm/i915/i915_gem.c| 208 ++--- drivers/gpu/drm/i915/i915_gem_tiling.c | 106 + include/uapi/drm/i915_drm.h| 107 + 5 files changed, 370 insertions(+), 71 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 5e583a1..0ab390a 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -2010,8 +2010,8 @@ const struct drm_ioctl_desc i915_ioctls[] = { DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED|DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, DRM_UNLOCKED), DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), @@ -2025,6 +2025,7 @@ const struct drm_ioctl_desc i915_ioctls[] = { DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_GET_RESET_STATS, i915_get_reset_stats_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_GEM_USERPTR, i915_gem_userptr_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_CREATE2, i915_gem_create2_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), }; int i915_max_ioctl = ARRAY_SIZE(i915_ioctls); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4470105..78f64fd 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2157,6 +2157,8 @@ int i915_gem_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +int i915_gem_create2_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); int i915_gem_pread_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, @@ -2191,10 +2193,10 @@ int i915_gem_entervt_ioctl(struct drm_device *dev, void *data, struct
[Intel-gfx] [PATCH 0/4] Introduce a new create ioctl for user specified
From: Sourab Gupta sourab.gu...@intel.com This patch series introduces a new gem create ioctl for user specified placement. Despite being a unified memory architecture (UMA) some bits of memory are more equal than others. In particular we have the thorny issue of stolen memory, memory stolen from the system by the BIOS and reserved for igfx use. Stolen memory is required for some functions of the GPU and display engine, but in general it goes wasted. Whilst we cannot return it back to the system, we need to find some other method for utilising it. As we do not support direct access to the physical address in the stolen region, it behaves like a different class of memory, closer in kin to local GPU memory. This strongly suggests that we need a placement model like TTM if we are to fully utilize these discrete chunks of differing memory. This new create ioctl therefore exists to allow the user to create these second class buffer objects from stolen memory. At the moment direct access by the CPU through mmaps and pread/pwrite are verboten on the objects, and so the user must be aware of the limitations of the objects created. Yet, those limitations rarely reduce the desired functionality in many use cases and so the user should be able to easily fill the stolen memory and so help to reduce overall memory pressure. The most obvious use case for stolen memory is for the creation of objects for the display engine which already have very similar restrictions on access. However, we want a reasonably general ioctl in order to cater for diverse scenarios beyond the author's imagination. Chris Wilson (3): drm/i915: Clearing buffer objects via blitter engine drm/i915: Introduce a new create ioctl for user specified placement drm/i915: Add support for stealing purgable stolen pages Deepak S (1): drm/i915: Clearing buffer objects via blitter engine for Gen8 drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/i915_dma.c| 5 +- drivers/gpu/drm/i915/i915_drv.h| 18 ++- drivers/gpu/drm/i915/i915_gem.c| 208 ++--- drivers/gpu/drm/i915/i915_gem_exec.c | 139 ++ drivers/gpu/drm/i915/i915_gem_stolen.c | 121 +-- drivers/gpu/drm/i915/i915_gem_tiling.c | 106 + include/uapi/drm/i915_drm.h| 107 + 8 files changed, 623 insertions(+), 82 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_gem_exec.c -- 1.8.5.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] intel-gpu-tools: add igt_core init func calls to some tests
From: Tim Gore tim.g...@intel.com igt-core.h/c provides some macros and initialisation functions to support the tests but some of the single tests do not use these. Modifying these tests to use the igt_simple_main macro and igt_simple_init function is the first step towards a consistent command line across all tests. Signed-off-by: Tim Gore tim.g...@intel.com --- tests/gem_bad_address.c | 4 +--- tests/gem_bad_batch.c| 4 +--- tests/gem_bad_blit.c | 4 +--- tests/gem_hang.c | 2 ++ tests/gem_non_secure_batch.c | 4 +--- tests/gem_stress.c | 2 ++ 6 files changed, 8 insertions(+), 12 deletions(-) diff --git a/tests/gem_bad_address.c b/tests/gem_bad_address.c index f8fda90..e7a9587 100644 --- a/tests/gem_bad_address.c +++ b/tests/gem_bad_address.c @@ -60,7 +60,7 @@ bad_store(void) intel_batchbuffer_flush(batch); } -int main(int argc, char **argv) +igt_simple_main { int fd; @@ -76,6 +76,4 @@ int main(int argc, char **argv) drm_intel_bufmgr_destroy(bufmgr); close(fd); - - return 0; } diff --git a/tests/gem_bad_batch.c b/tests/gem_bad_batch.c index 33b3241..7f92a93 100644 --- a/tests/gem_bad_batch.c +++ b/tests/gem_bad_batch.c @@ -56,7 +56,7 @@ bad_batch(void) intel_batchbuffer_flush(batch); } -int main(int argc, char **argv) +igt_simple_main { int fd; @@ -72,6 +72,4 @@ int main(int argc, char **argv) drm_intel_bufmgr_destroy(bufmgr); close(fd); - - return 0; } diff --git a/tests/gem_bad_blit.c b/tests/gem_bad_blit.c index 9c03117..71a9f78 100644 --- a/tests/gem_bad_blit.c +++ b/tests/gem_bad_blit.c @@ -95,7 +95,7 @@ bad_blit(drm_intel_bo *src_bo, uint32_t devid) intel_batchbuffer_flush(batch); } -int main(int argc, char **argv) +igt_simple_main { drm_intel_bo *src; int fd; @@ -114,6 +114,4 @@ int main(int argc, char **argv) drm_intel_bufmgr_destroy(bufmgr); close(fd); - - return 0; } diff --git a/tests/gem_hang.c b/tests/gem_hang.c index 8ebf606..6248244 100644 --- a/tests/gem_hang.c +++ b/tests/gem_hang.c @@ -72,6 +72,8 @@ int main(int argc, char **argv) { int fd; + igt_simple_init(); + igt_assert_f(argc == 2, usage: %s disabled pipe number\n, argv[0]); diff --git a/tests/gem_non_secure_batch.c b/tests/gem_non_secure_batch.c index 9acfda4..01101e9 100644 --- a/tests/gem_non_secure_batch.c +++ b/tests/gem_non_secure_batch.c @@ -77,7 +77,7 @@ mi_lri_loop(void) } } -int main(int argc, char **argv) +igt_simple_main { int fd; int devid; @@ -108,6 +108,4 @@ int main(int argc, char **argv) drm_intel_bufmgr_destroy(bufmgr); close(fd); - - return 0; } diff --git a/tests/gem_stress.c b/tests/gem_stress.c index d46c643..2ccb6fc 100644 --- a/tests/gem_stress.c +++ b/tests/gem_stress.c @@ -865,6 +865,8 @@ int main(int argc, char **argv) int i, j; unsigned *current_permutation, *tmp_permutation; + igt_simple_init(); + drm_fd = drm_open_any(); devid = intel_get_drm_devid(drm_fd); -- 1.9.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] mmu_notifier and i915_gem_userptr.c
On Thu, Jun 19, 2014 at 05:02:57PM +0100, Chris Wilson wrote: Maybe it should hook the invalidate_page notifier. I picked invalidate_range() as it seemed to be called first and seemed to cover all operations that affected an mm's addr range. The invalidate_page seemed to be only called during writeback, which aiui will not affect gup. Should we be hooking more notifiers? For what you are interested in the invalidate_range_start notifier should be sufficient. Invalidate_page is only called for page-aging and swapping (and xip, but that doesn't matter either). The problem with invalidate_range_start/end is that its semantics make it somewhat expensive to implement. So it would be good to reduce the call-sites and get rid of it at least around the change_pte calls in a first step. I am not familiar with the i915 hardware and the driver implementation details, so I wanted to ask whether the driver 1) Cares about the change_pte event? I don't think so... If I understand correctly, change_pte only gets called when the PTE is updated, not the physical page itself. If that is true, then the dma mapping of the page is unaffected, and so the GPU view of the page is not affected either. So, as long as the GPU maintains a remapped address of a page that is associated by a process address, we don't need to change anything. Change_pte is also called when the underlying page of an address changes in the kernel which would matter for DMA. But that can only happen in KSM and uprobes code which is probably not of interest for the i915 driver. The other case where I think it matters is the do_wp_page() path for COW. The code works by calling invalidate_range_start - change_pte - invalidate_range_end. Your driver would react to this by unbinding the vma from itself internally (after a fork for example). But I have to check whether this really matters here. If need be, start with overkill. I'd rather drop everything and rebuild it through the layers of mappings we have, as this is a new area for us and we want some solid foundations before trying to be smart. The main problem I have seen so far is the mutex taken in the invalidate_range_start call-back. That can't be used in a change_pte function because change_pte is not preemptible. Joerg ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [RFC][PATCH] gpu:drm:i915:intel_detect_pch: back to check devfn instead of check class type
Well I have no clue about forwarding the intel gpu to virtualized hosts and also no idea who could review this really. There's been a bit a discussion around the iommu mapping forwarding and similar topics though. So I really wonder how well our driver works in this use case ... -Daniel On Fri, Jun 20, 2014 at 11:40 AM, Chen, Tiejun tiejun.c...@intel.com wrote: Just ping, any comments? Thanks Tiejun On 2014/6/19 17:53, Tiejun Chen wrote: Originally the reason to probe ISA bridge instead of Dev31:Fun0 is to make graphics device passthrough work easy for VMM, that only need to expose ISA bridge to let driver know the real hardware underneath. This is a requirement from virtualization team. Especially in that virtualized environments, XEN, there is irrelevant ISA bridge in the system with that legacy qemu version specific to xen, qemu-xen-traditional. So to work reliably, we should scan through all the ISA bridge devices and check for the first match, instead of only checking the first one. But actually, qemu-xen-traditional, is always enumerated with Dev31:Fun0, 00:1f.0 as follows: hw/pt-graphics.c: intel_pch_init() | + pci_isa_bridge_init(bus, PCI_DEVFN(0x1f, 0), ...); so this mean that isa bridge is still represented with Dev31:Func0 like the native OS. Furthermore, currently we're pushing VGA passthrough support into qemu upstream, and with some discussion, we wouldn't set the bridge class type and just expose this devfn. So we just go back to check devfn to make life normal. Signed-off-by: Tiejun Chen tiejun.c...@intel.com --- drivers/gpu/drm/i915/i915_drv.c | 19 +++ 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 651e65e..cb2526e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -417,18 +417,8 @@ void intel_detect_pch(struct drm_device *dev) return; } - /* -* The reason to probe ISA bridge instead of Dev31:Fun0 is to -* make graphics device passthrough work easy for VMM, that only -* need to expose ISA bridge to let driver know the real hardware -* underneath. This is a requirement from virtualization team. -* -* In some virtualized environments (e.g. XEN), there is irrelevant -* ISA bridge in the system. To work reliably, we should scan trhough -* all the ISA bridge devices and check for the first match, instead -* of only checking the first one. -*/ - while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA 8, pch))) { + pch = pci_get_bus_and_slot(0, PCI_DEVFN(0x1f, 0)); + if (pch) { if (pch-vendor == PCI_VENDOR_ID_INTEL) { unsigned short id = pch-device INTEL_PCH_DEVICE_ID_MASK; dev_priv-pch_id = id; @@ -462,10 +452,7 @@ void intel_detect_pch(struct drm_device *dev) DRM_DEBUG_KMS(Found LynxPoint LP PCH\n); WARN_ON(!IS_HASWELL(dev)); WARN_ON(!IS_ULT(dev)); - } else - continue; - - break; + } } } if (!pch) -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [RFC][PATCH] gpu:drm:i915:intel_detect_pch: back to check devfn instead of check class type
Il 19/06/2014 11:53, Tiejun Chen ha scritto: so this mean that isa bridge is still represented with Dev31:Func0 like the native OS. Furthermore, currently we're pushing VGA passthrough support into qemu upstream, and with some discussion, we wouldn't set the bridge class type and just expose this devfn. Even this is not really optimal. It just happens to work just because QEMU's machine is currently a PCI machine with the ISA bridge on 00:01.0. As soon as you'll try doing integrated graphics passthrough on a PCIe machine type (such as QEMU's -M q35) things will break down just as badly. Paolo ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [RFC 1/4] drm/i915: Implement a framework for batch buffer pools
On 06/19/2014 06:35 PM, Volkin, Bradley D wrote: On Thu, Jun 19, 2014 at 02:48:29AM -0700, Tvrtko Ursulin wrote: Hi Brad, On 06/18/2014 05:36 PM, bradley.d.vol...@intel.com wrote: From: Brad Volkin bradley.d.vol...@intel.com This adds a small module for managing a pool of batch buffers. The only current use case is for the command parser, as described in the kerneldoc in the patch. The code is simple, but separating it out makes it easier to change the underlying algorithms and to extend to future use cases should they arise. The interface is simple: alloc to create an empty pool, free to clean it up; get to obtain a new buffer, put to return it to the pool. Note that all buffers must be returned to the pool before freeing it. The pool has a maximum number of buffers allowed due to some tests (e.g. gem_exec_nop) creating a very large number of buffers (e.g. ___). Buffers are purgeable while in the pool, but not explicitly truncated in order to avoid overhead during execbuf. Locking is currently based on the caller holding the struct_mutex. We already do that in the places where we will use the batch pool for the command parser. Signed-off-by: Brad Volkin bradley.d.vol...@intel.com --- r.e. pool capacity My original testing showed something like thousands of buffers in the pool after a gem_exec_nop run. But when I reran with the max check disabled just now to get an actual number for the commit message, the number was more like 130. I developed and tested the changes incrementally, and suspect that the original run was before I implemented the actual copy operation. So I'm inclined to remove or at least increase the cap in the final version. Thoughts? Some random thoughts: Is it strictly necessary to cap the pool size? I ask because it seems to be introducing a limit where so far there wasn't an explicit one. No, I only added it because there were a huge number of buffers in the pool at one point. But that seems to have been an artifact of my development process, so unless someone says they really want to keep the cap, I'm going to drop it in the next rev. Cap or no cap (I am for no cap), but the pool is still grow only at the moment, no? So one allocation storm and objects on the pool inactive list end up wasting memory forever. Unless my novice eyes are missing something hidden? But it can't be since then there would have to be a mechanism letting the pool know that some objects got expired. Regards, Tvrtko ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 3/3] drm/i915: New drm crtc property for varying the size of borders
From: Akash Goel akash.g...@intel.com This patch adds a new drm crtc property for varying the size of the horizontal vertical borers of the output/display window. This will control the output of Panel fitter. There are actually 4 separate properties so as to allow a control on the size of each border left/top/bottom/right Testcase: igt/kms_panel_fitter_test Signed-off-by: Akash Goel akash.g...@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 10 ++ drivers/gpu/drm/i915/intel_display.c | 118 ++- drivers/gpu/drm/i915/intel_drv.h | 12 ++ drivers/gpu/drm/i915/intel_panel.c | 219 --- 4 files changed, 344 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0640071..b1d94d3 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1515,6 +1515,16 @@ struct drm_i915_private { struct drm_property *broadcast_rgb_property; struct drm_property *force_audio_property; + /* +* Properties to dynamically vary the size of the +* borders. This will indirectly control the size +* of the display window i.e Panel fitter output +*/ + struct drm_property *left_border_property; + struct drm_property *right_border_property; + struct drm_property *top_border_property; + struct drm_property *bottom_border_property; + uint32_t hw_context_size; struct list_head context_list; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d95afb6..cf0b67f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11064,12 +11064,124 @@ out_config: return ret; } +static void intel_create_crtc_properties(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc-dev; + struct drm_i915_private *dev_priv = dev-dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + /* Create properties*/ + if (!dev_priv-left_border_property) + dev_priv-left_border_property = + drm_property_create_range(dev, 0, left border, + 0, (uint64_t)MAX_BORDER_VALUE); + + if (!dev_priv-right_border_property) + dev_priv-right_border_property = + drm_property_create_range(dev, 0, right border, + 0, (uint64_t)MAX_BORDER_VALUE); + + if (!dev_priv-top_border_property) + dev_priv-top_border_property = + drm_property_create_range(dev, 0, top border, + 0, (uint64_t)MAX_BORDER_VALUE); + + if (!dev_priv-bottom_border_property) + dev_priv-bottom_border_property = + drm_property_create_range(dev, 0, bottom border, + 0, (uint64_t)MAX_BORDER_VALUE); + + /* Attach to properties*/ + if (dev_priv-left_border_property) + drm_object_attach_property(intel_crtc-base.base, + dev_priv-left_border_property, + 0); + + if (dev_priv-right_border_property) + drm_object_attach_property(intel_crtc-base.base, + dev_priv-right_border_property, + 0); + + if (dev_priv-top_border_property) + drm_object_attach_property(intel_crtc-base.base, + dev_priv-top_border_property, + 0); + + if (dev_priv-bottom_border_property) + drm_object_attach_property(intel_crtc-base.base, + dev_priv-bottom_border_property, + 0); +} + static int intel_crtc_set_property(struct drm_crtc *crtc, struct drm_property *property, uint64_t val) { - int ret = -ENOENT; + struct drm_device *dev = crtc-dev; + struct drm_i915_private *dev_priv = dev-dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - return ret; + if (property == dev_priv-left_border_property) { + if (val == (uint64_t)intel_crtc-border[PANEL_BORDER_LEFT]) + return 0; + if (val 1) { + DRM_ERROR(Odd border value not supported\n); + return -EINVAL; + } + + intel_crtc-border[PANEL_BORDER_LEFT] = (uint32_t)val; + goto done; + } + + if (property == dev_priv-right_border_property) { + if (val == (uint64_t)intel_crtc-border[PANEL_BORDER_RIGHT]) + return 0; + if (val 1) { +
[Intel-gfx] [PATCH 1/3] drm/i915: Added a return type for panel fitter config functions
From: Akash Goel akash.g...@intel.com This patch changes the return type of panel fitter configuration functions from 'void', so that an error could be returned back to User space, either during the modeset time or when the 'border' property is being set, if the configuation is not valid. Signed-off-by: Akash Goel akash.g...@intel.com --- drivers/gpu/drm/i915/intel_display.c | 5 +++-- drivers/gpu/drm/i915/intel_dp.c | 17 ++--- drivers/gpu/drm/i915/intel_drv.h | 6 +++--- drivers/gpu/drm/i915/intel_hdmi.c| 2 +- drivers/gpu/drm/i915/intel_lvds.c| 13 +++-- drivers/gpu/drm/i915/intel_panel.c | 10 ++ drivers/gpu/drm/i915/intel_sdvo.c| 2 +- drivers/gpu/drm/i915/intel_tv.c | 2 +- 8 files changed, 32 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5e8e711..f764b74 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10631,9 +10631,10 @@ static int intel_set_mode(struct drm_crtc *crtc, return ret; } -void intel_crtc_restore_mode(struct drm_crtc *crtc) +int intel_crtc_restore_mode(struct drm_crtc *crtc) { - intel_set_mode(crtc, crtc-mode, crtc-x, crtc-y, crtc-primary-fb); + return intel_set_mode(crtc, crtc-mode, crtc-x, crtc-y, + crtc-primary-fb); } #undef for_each_intel_crtc_masked diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 912e9c4..6117639 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -824,12 +824,15 @@ intel_dp_compute_config(struct intel_encoder *encoder, if (is_edp(intel_dp) intel_connector-panel.fixed_mode) { intel_fixed_panel_mode(intel_connector-panel.fixed_mode, adjusted_mode); - if (!HAS_PCH_SPLIT(dev)) - intel_gmch_panel_fitting(intel_crtc, pipe_config, - intel_connector-panel.fitting_mode); - else - intel_pch_panel_fitting(intel_crtc, pipe_config, - intel_connector-panel.fitting_mode); + if (!HAS_PCH_SPLIT(dev)) { + if (!intel_gmch_panel_fitting(intel_crtc, pipe_config, + intel_connector-panel.fitting_mode)) + return false; + } else { + if (!intel_pch_panel_fitting(intel_crtc, pipe_config, + intel_connector-panel.fitting_mode)) + return false; + } } if (adjusted_mode-flags DRM_MODE_FLAG_DBLCLK) @@ -3782,7 +3785,7 @@ intel_dp_set_property(struct drm_connector *connector, done: if (intel_encoder-base.crtc) - intel_crtc_restore_mode(intel_encoder-base.crtc); + return intel_crtc_restore_mode(intel_encoder-base.crtc); return 0; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index ab5962b..860d531 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -727,7 +727,7 @@ void intel_mark_busy(struct drm_device *dev); void intel_mark_fb_busy(struct drm_i915_gem_object *obj, struct intel_engine_cs *ring); void intel_mark_idle(struct drm_device *dev); -void intel_crtc_restore_mode(struct drm_crtc *crtc); +int intel_crtc_restore_mode(struct drm_crtc *crtc); void intel_crtc_update_dpms(struct drm_crtc *crtc); void intel_encoder_destroy(struct drm_encoder *encoder); void intel_connector_dpms(struct drm_connector *, int mode); @@ -918,10 +918,10 @@ int intel_panel_init(struct intel_panel *panel, void intel_panel_fini(struct intel_panel *panel); void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, struct drm_display_mode *adjusted_mode); -void intel_pch_panel_fitting(struct intel_crtc *crtc, +bool intel_pch_panel_fitting(struct intel_crtc *crtc, struct intel_crtc_config *pipe_config, int fitting_mode); -void intel_gmch_panel_fitting(struct intel_crtc *crtc, +bool intel_gmch_panel_fitting(struct intel_crtc *crtc, struct intel_crtc_config *pipe_config, int fitting_mode); void intel_panel_set_backlight(struct intel_connector *connector, u32 level, diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 318b150..2551b62 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1128,7 +1128,7 @@ intel_hdmi_set_property(struct drm_connector *connector, done: if (intel_dig_port-base.base.crtc) -
[Intel-gfx] [PATCH 2/3] drm/i915: Initialized 'set_property' fn pointer field of intel_crtc_funcs structure
From: Akash Goel akash.g...@intel.com This patch defines a new function assigns that to the 'set_property' function pointer field of the 'intel_crtc_funcs' structure. Signed-off-by: Akash Goel akash.g...@intel.com --- drivers/gpu/drm/i915/intel_display.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f764b74..d95afb6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11064,11 +11064,20 @@ out_config: return ret; } +static int intel_crtc_set_property(struct drm_crtc *crtc, + struct drm_property *property, uint64_t val) +{ + int ret = -ENOENT; + + return ret; +} + static const struct drm_crtc_funcs intel_crtc_funcs = { .gamma_set = intel_crtc_gamma_set, .set_config = intel_crtc_set_config, .destroy = intel_crtc_destroy, .page_flip = intel_crtc_page_flip, + .set_property = intel_crtc_set_property, }; static void intel_cpu_pll_init(struct drm_device *dev) -- 1.9.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 0/3] New drm crtc properties
From: Akash Goel akash.g...@intel.com Added new drm crtc properties which provides control to vary the size of horizontal vertical borders. With this the size of the Panel fitter output or display window can be controlled. Also added a return type to panel fitter config functions, so that an error could be returned to User space for an invalid configuration. Akash Goel (3): drm/i915: Added a return type for panel fitter config functions drm/i915: Initialized 'set_property' fn pointer field of intel_crtc_funcs structure drm/i915: New drm crtc property for varying the size of borders drivers/gpu/drm/i915/i915_drv.h | 10 ++ drivers/gpu/drm/i915/intel_display.c | 128 +++- drivers/gpu/drm/i915/intel_dp.c | 17 +-- drivers/gpu/drm/i915/intel_drv.h | 18 ++- drivers/gpu/drm/i915/intel_hdmi.c| 2 +- drivers/gpu/drm/i915/intel_lvds.c| 13 +- drivers/gpu/drm/i915/intel_panel.c | 229 --- drivers/gpu/drm/i915/intel_sdvo.c| 2 +- drivers/gpu/drm/i915/intel_tv.c | 2 +- 9 files changed, 383 insertions(+), 38 deletions(-) -- 1.9.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 1/3] drm/i915: Added a return type for panel fitter config functions
On Fri, Jun 20, 2014 at 07:25:52PM +0530, akash.g...@intel.com wrote: diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 912e9c4..6117639 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -824,12 +824,15 @@ intel_dp_compute_config(struct intel_encoder *encoder, if (is_edp(intel_dp) intel_connector-panel.fixed_mode) { intel_fixed_panel_mode(intel_connector-panel.fixed_mode, adjusted_mode); - if (!HAS_PCH_SPLIT(dev)) - intel_gmch_panel_fitting(intel_crtc, pipe_config, - intel_connector-panel.fitting_mode); - else - intel_pch_panel_fitting(intel_crtc, pipe_config, - intel_connector-panel.fitting_mode); + if (!HAS_PCH_SPLIT(dev)) { + if (!intel_gmch_panel_fitting(intel_crtc, pipe_config, + intel_connector-panel.fitting_mode)) + return false; + } else { + if (!intel_pch_panel_fitting(intel_crtc, pipe_config, + intel_connector-panel.fitting_mode)) + return false; + } } if (adjusted_mode-flags DRM_MODE_FLAG_DBLCLK) @@ -3782,7 +3785,7 @@ intel_dp_set_property(struct drm_connector *connector, done: if (intel_encoder-base.crtc) - intel_crtc_restore_mode(intel_encoder-base.crtc); + return intel_crtc_restore_mode(intel_encoder-base.crtc); But you don't unwind the property change after failure. return 0; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index ab5962b..860d531 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -727,7 +727,7 @@ void intel_mark_busy(struct drm_device *dev); void intel_mark_fb_busy(struct drm_i915_gem_object *obj, struct intel_engine_cs *ring); void intel_mark_idle(struct drm_device *dev); -void intel_crtc_restore_mode(struct drm_crtc *crtc); +int intel_crtc_restore_mode(struct drm_crtc *crtc); void intel_crtc_update_dpms(struct drm_crtc *crtc); void intel_encoder_destroy(struct drm_encoder *encoder); void intel_connector_dpms(struct drm_connector *, int mode); @@ -918,10 +918,10 @@ int intel_panel_init(struct intel_panel *panel, void intel_panel_fini(struct intel_panel *panel); void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, struct drm_display_mode *adjusted_mode); -void intel_pch_panel_fitting(struct intel_crtc *crtc, +bool intel_pch_panel_fitting(struct intel_crtc *crtc, struct intel_crtc_config *pipe_config, int fitting_mode); -void intel_gmch_panel_fitting(struct intel_crtc *crtc, +bool intel_gmch_panel_fitting(struct intel_crtc *crtc, struct intel_crtc_config *pipe_config, int fitting_mode); Only make significnt changes like this to one interface at a time. -Chris -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 0/3] New drm crtc properties
On Fri, Jun 20, 2014 at 07:25:51PM +0530, akash.g...@intel.com wrote: From: Akash Goel akash.g...@intel.com Added new drm crtc properties which provides control to vary the size of horizontal vertical borders. With this the size of the Panel fitter output or display window can be controlled. Also added a return type to panel fitter config functions, so that an error could be returned to User space for an invalid configuration. Akash Goel (3): drm/i915: Added a return type for panel fitter config functions drm/i915: Initialized 'set_property' fn pointer field of intel_crtc_funcs structure drm/i915: New drm crtc property for varying the size of borders As an aside, you're missing the new property documentation in Documentation/DocBook/drm.tmpl. -- Damien ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] intel-gpu-tools: add igt_core init func calls to some tests
On 20 Jun 2014 11:28, tim.g...@intel.com wrote: From: Tim Gore tim.g...@intel.com igt-core.h/c provides some macros and initialisation functions to support the tests but some of the single tests do not use these. Modifying these tests to use the igt_simple_main macro and igt_simple_init function is the first step towards a consistent command line across all tests. This also helps add support for other common functionality such as setting the debug level. Patch has been merged, thanks. Signed-off-by: Tim Gore tim.g...@intel.com --- tests/gem_bad_address.c | 4 +--- tests/gem_bad_batch.c| 4 +--- tests/gem_bad_blit.c | 4 +--- tests/gem_hang.c | 2 ++ tests/gem_non_secure_batch.c | 4 +--- tests/gem_stress.c | 2 ++ 6 files changed, 8 insertions(+), 12 deletions(-) diff --git a/tests/gem_bad_address.c b/tests/gem_bad_address.c index f8fda90..e7a9587 100644 --- a/tests/gem_bad_address.c +++ b/tests/gem_bad_address.c @@ -60,7 +60,7 @@ bad_store(void) intel_batchbuffer_flush(batch); } -int main(int argc, char **argv) +igt_simple_main { int fd; @@ -76,6 +76,4 @@ int main(int argc, char **argv) drm_intel_bufmgr_destroy(bufmgr); close(fd); - - return 0; } diff --git a/tests/gem_bad_batch.c b/tests/gem_bad_batch.c index 33b3241..7f92a93 100644 --- a/tests/gem_bad_batch.c +++ b/tests/gem_bad_batch.c @@ -56,7 +56,7 @@ bad_batch(void) intel_batchbuffer_flush(batch); } -int main(int argc, char **argv) +igt_simple_main { int fd; @@ -72,6 +72,4 @@ int main(int argc, char **argv) drm_intel_bufmgr_destroy(bufmgr); close(fd); - - return 0; } diff --git a/tests/gem_bad_blit.c b/tests/gem_bad_blit.c index 9c03117..71a9f78 100644 --- a/tests/gem_bad_blit.c +++ b/tests/gem_bad_blit.c @@ -95,7 +95,7 @@ bad_blit(drm_intel_bo *src_bo, uint32_t devid) intel_batchbuffer_flush(batch); } -int main(int argc, char **argv) +igt_simple_main { drm_intel_bo *src; int fd; @@ -114,6 +114,4 @@ int main(int argc, char **argv) drm_intel_bufmgr_destroy(bufmgr); close(fd); - - return 0; } diff --git a/tests/gem_hang.c b/tests/gem_hang.c index 8ebf606..6248244 100644 --- a/tests/gem_hang.c +++ b/tests/gem_hang.c @@ -72,6 +72,8 @@ int main(int argc, char **argv) { int fd; + igt_simple_init(); + igt_assert_f(argc == 2, usage: %s disabled pipe number\n, argv[0]); diff --git a/tests/gem_non_secure_batch.c b/tests/gem_non_secure_batch.c index 9acfda4..01101e9 100644 --- a/tests/gem_non_secure_batch.c +++ b/tests/gem_non_secure_batch.c @@ -77,7 +77,7 @@ mi_lri_loop(void) } } -int main(int argc, char **argv) +igt_simple_main { int fd; int devid; @@ -108,6 +108,4 @@ int main(int argc, char **argv) drm_intel_bufmgr_destroy(bufmgr); close(fd); - - return 0; } diff --git a/tests/gem_stress.c b/tests/gem_stress.c index d46c643..2ccb6fc 100644 --- a/tests/gem_stress.c +++ b/tests/gem_stress.c @@ -865,6 +865,8 @@ int main(int argc, char **argv) int i, j; unsigned *current_permutation, *tmp_permutation; + igt_simple_init(); + drm_fd = drm_open_any(); devid = intel_get_drm_devid(drm_fd); -- 1.9.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [RFC 1/4] drm/i915: Implement a framework for batch buffer pools
On Fri, Jun 20, 2014 at 06:25:56AM -0700, Tvrtko Ursulin wrote: On 06/19/2014 06:35 PM, Volkin, Bradley D wrote: On Thu, Jun 19, 2014 at 02:48:29AM -0700, Tvrtko Ursulin wrote: Hi Brad, On 06/18/2014 05:36 PM, bradley.d.vol...@intel.com wrote: From: Brad Volkin bradley.d.vol...@intel.com This adds a small module for managing a pool of batch buffers. The only current use case is for the command parser, as described in the kerneldoc in the patch. The code is simple, but separating it out makes it easier to change the underlying algorithms and to extend to future use cases should they arise. The interface is simple: alloc to create an empty pool, free to clean it up; get to obtain a new buffer, put to return it to the pool. Note that all buffers must be returned to the pool before freeing it. The pool has a maximum number of buffers allowed due to some tests (e.g. gem_exec_nop) creating a very large number of buffers (e.g. ___). Buffers are purgeable while in the pool, but not explicitly truncated in order to avoid overhead during execbuf. Locking is currently based on the caller holding the struct_mutex. We already do that in the places where we will use the batch pool for the command parser. Signed-off-by: Brad Volkin bradley.d.vol...@intel.com --- r.e. pool capacity My original testing showed something like thousands of buffers in the pool after a gem_exec_nop run. But when I reran with the max check disabled just now to get an actual number for the commit message, the number was more like 130. I developed and tested the changes incrementally, and suspect that the original run was before I implemented the actual copy operation. So I'm inclined to remove or at least increase the cap in the final version. Thoughts? Some random thoughts: Is it strictly necessary to cap the pool size? I ask because it seems to be introducing a limit where so far there wasn't an explicit one. No, I only added it because there were a huge number of buffers in the pool at one point. But that seems to have been an artifact of my development process, so unless someone says they really want to keep the cap, I'm going to drop it in the next rev. Cap or no cap (I am for no cap), but the pool is still grow only at the moment, no? So one allocation storm and objects on the pool inactive list end up wasting memory forever. Oh, so what happens is that when you put() an object back in the pool, we set obj-madv = I915_MADV_DONTNEED, which should tell the shrinker that it can drop the backing storage for the object if we need space. When you get() an object, we set obj-madv = I915_MADV_WILLNEED and get new backing pages. So the number of objects grows (capped or not), but the memory used can be controlled. Brad Unless my novice eyes are missing something hidden? But it can't be since then there would have to be a mechanism letting the pool know that some objects got expired. Regards, Tvrtko ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [RFC 1/4] drm/i915: Implement a framework for batch buffer pools
On 06/20/2014 04:30 PM, Volkin, Bradley D wrote: On Fri, Jun 20, 2014 at 06:25:56AM -0700, Tvrtko Ursulin wrote: On 06/19/2014 06:35 PM, Volkin, Bradley D wrote: On Thu, Jun 19, 2014 at 02:48:29AM -0700, Tvrtko Ursulin wrote: Hi Brad, On 06/18/2014 05:36 PM, bradley.d.vol...@intel.com wrote: From: Brad Volkin bradley.d.vol...@intel.com This adds a small module for managing a pool of batch buffers. The only current use case is for the command parser, as described in the kerneldoc in the patch. The code is simple, but separating it out makes it easier to change the underlying algorithms and to extend to future use cases should they arise. The interface is simple: alloc to create an empty pool, free to clean it up; get to obtain a new buffer, put to return it to the pool. Note that all buffers must be returned to the pool before freeing it. The pool has a maximum number of buffers allowed due to some tests (e.g. gem_exec_nop) creating a very large number of buffers (e.g. ___). Buffers are purgeable while in the pool, but not explicitly truncated in order to avoid overhead during execbuf. Locking is currently based on the caller holding the struct_mutex. We already do that in the places where we will use the batch pool for the command parser. Signed-off-by: Brad Volkin bradley.d.vol...@intel.com --- r.e. pool capacity My original testing showed something like thousands of buffers in the pool after a gem_exec_nop run. But when I reran with the max check disabled just now to get an actual number for the commit message, the number was more like 130. I developed and tested the changes incrementally, and suspect that the original run was before I implemented the actual copy operation. So I'm inclined to remove or at least increase the cap in the final version. Thoughts? Some random thoughts: Is it strictly necessary to cap the pool size? I ask because it seems to be introducing a limit where so far there wasn't an explicit one. No, I only added it because there were a huge number of buffers in the pool at one point. But that seems to have been an artifact of my development process, so unless someone says they really want to keep the cap, I'm going to drop it in the next rev. Cap or no cap (I am for no cap), but the pool is still grow only at the moment, no? So one allocation storm and objects on the pool inactive list end up wasting memory forever. Oh, so what happens is that when you put() an object back in the pool, we set obj-madv = I915_MADV_DONTNEED, which should tell the shrinker that it can drop the backing storage for the object if we need space. When you get() an object, we set obj-madv = I915_MADV_WILLNEED and get new backing pages. So the number of objects grows (capped or not), but the memory used can be controlled. Education time for me I see. :) So the object is in pool-inactive_list _and_ in some other list so shrinker can find it? Thanks, Tvrtko ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 3/4] drm/i915: Try harder to get FBC
You give me too much credit. I just gave you an explanation of what the hardware does, then you ran with it. On Thu, Jun 19, 2014 at 12:06:13PM -0700, Ben Widawsky wrote: + DRM_INFO(Reducing the compressed framebuffer size. This may lead to increased power. Try to increase stolen memory size if available in BIOS.\n); I prefer This may lead to less power savings than a non-reduced size. since FBC is still going to save power. dpfc_ctl = DPFC_CTL_PLANE(intel_crtc-plane); if (drm_format_plane_cpp(fb-pixel_format, 0) == 2) + dev_priv-fbc.threshold++; + + switch (dev_priv-fbc.threshold) { + case 4: + dpfc_ctl |= DPFC_CTL_LIMIT_4X; + break; + case 2: dpfc_ctl |= DPFC_CTL_LIMIT_2X; - else + break; + case 1: dpfc_ctl |= DPFC_CTL_LIMIT_1X; + break; + } I Am Not A Coder, but at a glance it looks like the ++ could lead to undefined case 3 when you want case 4. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [RFC 1/4] drm/i915: Implement a framework for batch buffer pools
On Fri, Jun 20, 2014 at 08:41:08AM -0700, Tvrtko Ursulin wrote: On 06/20/2014 04:30 PM, Volkin, Bradley D wrote: On Fri, Jun 20, 2014 at 06:25:56AM -0700, Tvrtko Ursulin wrote: On 06/19/2014 06:35 PM, Volkin, Bradley D wrote: On Thu, Jun 19, 2014 at 02:48:29AM -0700, Tvrtko Ursulin wrote: Hi Brad, On 06/18/2014 05:36 PM, bradley.d.vol...@intel.com wrote: Cap or no cap (I am for no cap), but the pool is still grow only at the moment, no? So one allocation storm and objects on the pool inactive list end up wasting memory forever. Oh, so what happens is that when you put() an object back in the pool, we set obj-madv = I915_MADV_DONTNEED, which should tell the shrinker that it can drop the backing storage for the object if we need space. When you get() an object, we set obj-madv = I915_MADV_WILLNEED and get new backing pages. So the number of objects grows (capped or not), but the memory used can be controlled. Education time for me I see. :) So the object is in pool-inactive_list _and_ in some other list so shrinker can find it? Yes. In fact, they are on several other lists. Here's my understanding: The dev_priv-mm struct has bound_list and unbound_list, which track which objects are or are not bound in some gtt. The shrinker operates on these lists to drop backing storage when we need physical space. The pool objects are added to these lists when we explicitly call ggtt_pin() and when the object eventually gets an unbind(). The ring structs have an active_list, which track objects that are used by work still in progress on that ring. The i915_address_space structs have an inactive_list, which contains vmas that are bound in that address space but are not used by work still in progress. The driver uses these to evict objects in a given gtt/ppgtt when we need GPU virtual address space. We explicitly put a pool object's vma on the active_list with a move_to_active() call at the end of do_execbuffer(). Retiring requests moves it to the appropriate i915_address_space inactive_list. Brad Thanks, Tvrtko ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 3/4] drm/i915: drop runtime PM get/put pair around DP detect
We're taking the right power well refs now, so this shouldn't be needed. Reported-by: Imre Deak imre.d...@intel.com Signed-off-by: Jesse Barnes jbar...@virtuousgeek.org --- drivers/gpu/drm/i915/intel_dp.c | 4 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 912e9c4..ed6f00c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3596,8 +3596,6 @@ intel_dp_detect(struct drm_connector *connector, bool force) enum intel_display_power_domain power_domain; struct edid *edid = NULL; - intel_runtime_pm_get(dev_priv); - power_domain = intel_display_port_power_domain(intel_encoder); intel_display_power_get(dev_priv, power_domain); @@ -3633,8 +3631,6 @@ intel_dp_detect(struct drm_connector *connector, bool force) out: intel_display_power_put(dev_priv, power_domain); - intel_runtime_pm_put(dev_priv); - return status; } -- 1.8.3.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/4] drm/i915: add helper for checking whether IRQs are enabled
Now that we use the runtime IRQ enable/disable functions in our suspend path, we can simply check the pm._irqs_disabled flag everywhere. So rename it to catch the users, and add an inline for it to make the checks clear everywhere. Signed-off-by: Jesse Barnes jbar...@virtuousgeek.org --- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/i915/i915_irq.c | 16 drivers/gpu/drm/i915/intel_display.c | 2 +- drivers/gpu/drm/i915/intel_drv.h | 9 - drivers/gpu/drm/i915/intel_pm.c | 6 +++--- 7 files changed, 23 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 76c2572..f3c0482 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2076,7 +2076,7 @@ static int i915_pc8_status(struct seq_file *m, void *unused) seq_printf(m, GPU idle: %s\n, yesno(!dev_priv-mm.busy)); seq_printf(m, IRQs disabled: %s\n, - yesno(dev_priv-pm.irqs_disabled)); + yesno(!intel_irqs_enabled(dev_priv))); return 0; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0640071..d12e9b7 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1298,7 +1298,7 @@ struct ilk_wm_values { */ struct i915_runtime_pm { bool suspended; - bool irqs_disabled; + bool _irqs_disabled; }; enum intel_pipe_crc_source { diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d857f58..2f1815e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1161,7 +1161,7 @@ static int __wait_seqno(struct intel_engine_cs *ring, u32 seqno, unsigned long timeout_expire; int ret; - WARN(dev_priv-pm.irqs_disabled, IRQs disabled\n); + WARN(!intel_irqs_enabled(dev_priv), IRQs disabled); if (i915_seqno_passed(ring-get_seqno(ring, true), seqno)) return 0; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index fe3b309..bc953cc 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -136,7 +136,7 @@ ironlake_enable_display_irq(struct drm_i915_private *dev_priv, u32 mask) { assert_spin_locked(dev_priv-irq_lock); - if (WARN_ON(dev_priv-pm.irqs_disabled)) + if (WARN_ON(!intel_irqs_enabled(dev_priv))) return; if ((dev_priv-irq_mask mask) != 0) { @@ -151,7 +151,7 @@ ironlake_disable_display_irq(struct drm_i915_private *dev_priv, u32 mask) { assert_spin_locked(dev_priv-irq_lock); - if (dev_priv-pm.irqs_disabled) + if (!intel_irqs_enabled(dev_priv)) return; if ((dev_priv-irq_mask mask) != mask) { @@ -173,7 +173,7 @@ static void ilk_update_gt_irq(struct drm_i915_private *dev_priv, { assert_spin_locked(dev_priv-irq_lock); - if (WARN_ON(dev_priv-pm.irqs_disabled)) + if (WARN_ON(!intel_irqs_enabled(dev_priv))) return; dev_priv-gt_irq_mask = ~interrupt_mask; @@ -206,7 +206,7 @@ static void snb_update_pm_irq(struct drm_i915_private *dev_priv, assert_spin_locked(dev_priv-irq_lock); - if (WARN_ON(dev_priv-pm.irqs_disabled)) + if (WARN_ON(!intel_irqs_enabled(dev_priv))) return; new_val = dev_priv-pm_irq_mask; @@ -264,7 +264,7 @@ static void bdw_update_pm_irq(struct drm_i915_private *dev_priv, assert_spin_locked(dev_priv-irq_lock); - if (WARN_ON(dev_priv-pm.irqs_disabled)) + if (WARN_ON(!intel_irqs_enabled(dev_priv))) return; new_val = dev_priv-pm_irq_mask; @@ -420,7 +420,7 @@ static void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, assert_spin_locked(dev_priv-irq_lock); - if (WARN_ON(dev_priv-pm.irqs_disabled)) + if (WARN_ON(!intel_irqs_enabled(dev_priv))) return; I915_WRITE(SDEIMR, sdeimr); @@ -4478,7 +4478,7 @@ void intel_runtime_pm_disable_interrupts(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; dev-driver-irq_uninstall(dev); - dev_priv-pm.irqs_disabled = true; + dev_priv-pm._irqs_disabled = true; } /* Restore interrupts so we can recover from runtime PM. */ @@ -4486,7 +4486,7 @@ void intel_runtime_pm_restore_interrupts(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev-dev_private; - dev_priv-pm.irqs_disabled = false; + dev_priv-pm._irqs_disabled = false; dev-driver-irq_preinstall(dev); dev-driver-irq_postinstall(dev); } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5e8e711..d993b69 100644 ---
[Intel-gfx] [PATCH 1/4] drm/i915: don't warn if IRQs are disabled when shutting down display IRQs
This was always the case on our suspend path, but it was recently exposed by the change to use our runtime IRQ disable routine rather than the full DRM IRQ disable. Keep the warning on the enable side, as that really would indicate a bug. Signed-off-by: Jesse Barnes jbar...@virtuousgeek.org --- drivers/gpu/drm/i915/i915_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 1c1ec22..fe3b309 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -151,7 +151,7 @@ ironlake_disable_display_irq(struct drm_i915_private *dev_priv, u32 mask) { assert_spin_locked(dev_priv-irq_lock); - if (WARN_ON(dev_priv-pm.irqs_disabled)) + if (dev_priv-pm.irqs_disabled) return; if ((dev_priv-irq_mask mask) != mask) { -- 1.8.3.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 3/4] drm/i915: Try harder to get FBC
Rodrigo, when you're ready, can you pull in Art's requests? On Fri, Jun 20, 2014 at 03:56:08PM +, Runyan, Arthur J wrote: You give me too much credit. I just gave you an explanation of what the hardware does, then you ran with it. On Thu, Jun 19, 2014 at 12:06:13PM -0700, Ben Widawsky wrote: + DRM_INFO(Reducing the compressed framebuffer size. This may lead to increased power. Try to increase stolen memory size if available in BIOS.\n); I prefer This may lead to less power savings than a non-reduced size. since FBC is still going to save power. Got it. dpfc_ctl = DPFC_CTL_PLANE(intel_crtc-plane); if (drm_format_plane_cpp(fb-pixel_format, 0) == 2) + dev_priv-fbc.threshold++; + + switch (dev_priv-fbc.threshold) { + case 4: + dpfc_ctl |= DPFC_CTL_LIMIT_4X; + break; + case 2: dpfc_ctl |= DPFC_CTL_LIMIT_2X; - else + break; + case 1: dpfc_ctl |= DPFC_CTL_LIMIT_1X; + break; + } I Am Not A Coder, but at a glance it looks like the ++ could lead to undefined case 3 when you want case 4. Thanks for your feedback. 3 is an invalid value, but a default case should be added here. I'd do a BUG_ON, but that's strictly forbidden. -- Ben Widawsky, Intel Open Source Technology Center ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v2 9/9] drm/i915: Leave interrupts enabled while disabling crtcs during suspend
On Mon, May 26, 2014 at 02:46:32PM +0300, ville.syrj...@linux.intel.com wrote: From: Ville Syrjälä ville.syrj...@linux.intel.com The new watermaek update mechanism requires interrupts to work s/watermaek/watermark/ correctly. Because of this we need interrupts while disabling crtcs during suspend. So move the irq disable to happen a bit later. I'm not super familiar with this code, so I might be missing something, but won't this cause us to call drm_irq_uninstall() and then potentially dev-driver-get_vblank_counter() while the pipe is disabled (which will result in get_vblank_counter() returning 0)? Also, does it cause any problems if if our interrupt handler races with intel_disable_pipe()? Matt This also avoid clobbering the vblank.last count in case the vblank interrupt was already disabled earlier by the timer. In that case drm_vblank_off() will need .last to be correct so that it can update the user visible vblank counter value approapriately. v2: Note vblank counter in commit message Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 4619c9e..21554a0 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -524,7 +524,6 @@ static int i915_drm_freeze(struct drm_device *dev) return error; } - drm_irq_uninstall(dev); dev_priv-enable_hotplug_processing = false; intel_disable_gt_powersave(dev); @@ -541,6 +540,8 @@ static int i915_drm_freeze(struct drm_device *dev) } mutex_unlock(dev-mode_config.mutex); + drm_irq_uninstall(dev); + intel_modeset_suspend_hw(dev); } -- 1.8.5.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Matt Roper Graphics Software Engineer IoTG Platform Enabling Development Intel Corporation (916) 356-2795 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 14/9] drm: Kick start vblank interrupts at drm_vblank_on()
On Mon, Jun 02, 2014 at 11:15:51AM +0300, ville.syrj...@linux.intel.com wrote: From: Ville Syrjälä ville.syrj...@linux.intel.com If the user is interested in getting accurate vblank sequence numbers all the time they may disable the vblank disable timer entirely. In that case it seems appropriate to kick start the vblank interrupts already from drm_vblank_on(). Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/drm_irq.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 82a039a..6376d96 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -1126,9 +1126,12 @@ void drm_vblank_on(struct drm_device *dev, int crtc) vblank-last = (dev-driver-get_vblank_counter(dev, crtc) - 1) dev-max_vblank_count; - - /* re-enable interrupts if there's are users left */ - if (atomic_read(vblank-refcount) != 0) + /* + * re-enable interrupts if there are users left, or the + * user wishes vblank interrupts to be enabled all the time. + */ + if (atomic_read(vblank-refcount) != 0 || + (!dev-vblank_disable_immediate drm_vblank_offdelay 0)) As noted on patch 10, wouldn't it make sense for the user-provided module parameter override the driver ability to disable immediately in this case where they've specifically asked for never disable? Otherwise, patches 12-14 are Reviewed-by: Matt Roper matthew.d.ro...@intel.com WARN_ON(drm_vblank_enable(dev, crtc)); spin_unlock_irqrestore(dev-vbl_lock, irqflags); } -- 1.8.5.5 ___ dri-devel mailing list dri-de...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel -- Matt Roper Graphics Software Engineer IoTG Platform Enabling Development Intel Corporation (916) 356-2795 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: mark IRQs as disabled on unload
To avoid more spew with the new warnings. Signed-off-by: Jesse Barnes jbar...@virtuousgeek.org --- drivers/gpu/drm/i915/intel_display.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d993b69..7288d1d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12778,6 +12778,8 @@ void intel_modeset_cleanup(struct drm_device *dev) */ drm_irq_uninstall(dev); cancel_work_sync(dev_priv-hotplug_work); + dev_priv-pm._irqs_disabled = true; + /* * Due to the hpd irq storm handling the hotplug work can re-arm the * poll handlers. Hence disable polling after hpd handling is shut down. -- 1.8.3.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915/bdw: Use timeout mode for RC6 on bdw
From: Ben Widawsky [mailto:b...@bwidawsk.net] Sent: Friday, June 20, 2014 9:43 AM On Wed, Apr 09, 2014 at 11:44:06AM -0700, Tom O'Rourke wrote: Higher RC6 residency is observed using timeout mode instead of EI mode. This applies to Broadwell only. The difference is particularly noticeable with video playback. Issue: VIZ-3778 Change-Id: I62bb12e21caf19651034826b45cde7f73a80938d Signed-off-by: Tom O'Rourke Tom.O'rou...@intel.com Now that CHV is out, does it apply there too? Reviewed-by: Ben Widawsky b...@bwidawsk.net [snip] -- Ben Widawsky, Intel Open Source Technology Center [TOR:] For CHV, we expect timeout mode will provide benefit on some pre-production steppings and no benefit on the production stepping. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 23/53] drm/i915: Generalize intel_ring_get_tail
On Fri, Jun 13, 2014 at 08:37:41AM -0700, oscar.ma...@intel.com wrote: From: Oscar Mateo oscar.ma...@intel.com Reusing stuff, a penny at a time. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_gem.c | 4 ++-- drivers/gpu/drm/i915/intel_ringbuffer.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c5c06c9..dcdffab 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2320,7 +2320,7 @@ int __i915_add_request(struct intel_engine_cs *ring, u32 request_ring_position, request_start; int ret; - request_start = intel_ring_get_tail(ring); + request_start = intel_ring_get_tail(ring-buffer); /* * Emit any outstanding flushes - execbuf can fail to emit the flush * after having emitted the batchbuffer command. Hence we need to fix @@ -2341,7 +2341,7 @@ int __i915_add_request(struct intel_engine_cs *ring, * GPU processing the request, we never over-estimate the * position of the head. */ - request_ring_position = intel_ring_get_tail(ring); + request_ring_position = intel_ring_get_tail(ring-buffer); ret = ring-add_request(ring); if (ret) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index dc944fe..1558afa 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -334,9 +334,9 @@ void intel_destroy_ring_buffer(struct intel_ringbuffer *ringbuf); int intel_allocate_ring_buffer(struct drm_device *dev, struct intel_ringbuffer *ringbuf); -static inline u32 intel_ring_get_tail(struct intel_engine_cs *ring) +static inline u32 intel_ring_get_tail(struct intel_ringbuffer *ringbuf) { - return ring-buffer-tail; + return ringbuf-tail; } Another naming bikeshed, for this and the previous patch: It might be unexpected to have all of the intel_ring_ functions except for two take a struct intel_engine_cs and then have this and intel_ring_space take a struct intel_ringbuffer. So maybe intel_ringbuffer_ or similar for those two. Brad static inline u32 intel_ring_get_seqno(struct intel_engine_cs *ring) -- 1.9.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 25/53] drm/i915/bdw: GEN-specific logical ring submit context (somewhat)
On Fri, Jun 13, 2014 at 08:37:43AM -0700, oscar.ma...@intel.com wrote: From: Oscar Mateo oscar.ma...@intel.com For the moment, just mark the place (we still need to do a lot of preparation before execlists are ready to start submitting things). Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/intel_lrc.c| 11 +++ drivers/gpu/drm/i915/intel_ringbuffer.h | 6 ++ 2 files changed, 17 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 6c62ae5..02fc3d0 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -139,6 +139,12 @@ static void gen8_set_seqno(struct intel_engine_cs *ring, u32 seqno) intel_write_status_page(ring, I915_GEM_HWS_INDEX, seqno); } +static void gen8_submit_ctx(struct intel_engine_cs *ring, + struct intel_context *ctx, u32 value) +{ + DRM_ERROR(Execlists still not ready!\n); +} + void intel_logical_ring_cleanup(struct intel_engine_cs *ring) { if (!intel_ring_initialized(ring)) @@ -213,6 +219,7 @@ static int logical_render_ring_init(struct drm_device *dev) ring-cleanup = intel_fini_pipe_control; ring-get_seqno = gen8_get_seqno; ring-set_seqno = gen8_set_seqno; + ring-submit_ctx = gen8_submit_ctx; return logical_ring_init(dev, ring); } @@ -231,6 +238,7 @@ static int logical_bsd_ring_init(struct drm_device *dev) ring-init = gen8_init_common_ring; ring-get_seqno = gen8_get_seqno; ring-set_seqno = gen8_set_seqno; + ring-submit_ctx = gen8_submit_ctx; return logical_ring_init(dev, ring); } @@ -249,6 +257,7 @@ static int logical_bsd2_ring_init(struct drm_device *dev) ring-init = gen8_init_common_ring; ring-get_seqno = gen8_get_seqno; ring-set_seqno = gen8_set_seqno; + ring-submit_ctx = gen8_submit_ctx; return logical_ring_init(dev, ring); } @@ -267,6 +276,7 @@ static int logical_blt_ring_init(struct drm_device *dev) ring-init = gen8_init_common_ring; ring-get_seqno = gen8_get_seqno; ring-set_seqno = gen8_set_seqno; + ring-submit_ctx = gen8_submit_ctx; return logical_ring_init(dev, ring); } @@ -285,6 +295,7 @@ static int logical_vebox_ring_init(struct drm_device *dev) ring-init = gen8_init_common_ring; ring-get_seqno = gen8_get_seqno; ring-set_seqno = gen8_set_seqno; + ring-submit_ctx = gen8_submit_ctx; return logical_ring_init(dev, ring); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index ff8753c..1a6df42 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -79,6 +79,8 @@ struct intel_ringbuffer { u32 last_retired_head; }; +struct intel_context; + struct intel_engine_cs { const char *name; enum intel_ring_id { @@ -146,6 +148,10 @@ struct intel_engine_cs { unsigned int num_dwords); } semaphore; + /* Execlists */ + void(*submit_ctx)(struct intel_engine_cs *ring, + struct intel_context *ctx, u32 value); + Is it worth making this a vfunc in the refactored codebase? It ends up as the same function for all engines...called in one place...the implementation of which is a single call to another function that takes the same arguments. Previously this was an implementation of the write_tail vfunc, so it made sense. I'm not so sure now. Brad /** * List of objects currently involved in rendering from the * ringbuffer. -- 1.9.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Introduce FBC False Color for debug purposes.
With this bit enabled, HW changes the color when compressing frames for debug purposes. ALthough the simple way to enable a single bit is over intel_reg_write, this value is overwriten on next update_fbc so depending on the workload it is not possible to set this bit with intel-gpu-tools. So this patch introduces a persistent way to enable false color over debugfs. Signed-off-by: Rodrigo Vivi rodrigo.v...@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 70 + drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 6 4 files changed, 79 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 6b7b32b..c2019a6 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1508,6 +1508,75 @@ static int i915_fbc_status(struct seq_file *m, void *unused) return 0; } +static int i915_fbc_fc_show(struct seq_file *m, void *data) +{ + struct drm_device *dev = m-private; + struct drm_i915_private *dev_priv = dev-dev_private; + + drm_modeset_lock_all(dev); + seq_printf(m, False Color: %s\n, yesno(dev_priv-fbc.false_color)); + drm_modeset_unlock_all(dev); + + return 0; +} + +static int i915_fbc_fc_open(struct inode *inode, struct file *file) +{ + struct drm_device *dev = inode-i_private; + + if (INTEL_INFO(dev)-gen 5) + return -ENODEV; + + return single_open(file, i915_fbc_fc_show, dev); +} + +static ssize_t i915_fbc_fc_write(struct file *file, const char __user *ubuf, + size_t len, loff_t *offp) +{ + struct seq_file *m = file-private_data; + struct drm_device *dev = m-private; + struct drm_i915_private *dev_priv = dev-dev_private; + int ret; + char tmp[2]; + int false_color; + u32 val; + + if (len 2) + return -EINVAL; + + if (copy_from_user(tmp, ubuf, len)) + return -EFAULT; + + tmp[1] = '\0'; + + ret = sscanf(tmp, %d, false_color); + if (ret != 1) + return -EINVAL; + + drm_modeset_lock_all(dev); + + val = I915_READ(ILK_DPFC_CONTROL); + dev_priv-fbc.false_color = false_color; + + I915_WRITE(ILK_DPFC_CONTROL, false_color ? + (val | FBC_CTL_FALSE_COLOR) : + (val ~FBC_CTL_FALSE_COLOR)); + + drm_modeset_unlock_all(dev); + + return len; +} + +static const struct file_operations i915_fbc_fops = { + .release = single_release, + .owner = THIS_MODULE, + .read = seq_read, + .open = i915_fbc_fc_open, + .llseek = seq_lseek, + .release = single_release, + .write = i915_fbc_fc_write, +}; + static int i915_ips_status(struct seq_file *m, void *unused) { struct drm_info_node *node = m-private; @@ -3858,6 +3927,7 @@ static const struct i915_debugfs_files { {i915_pri_wm_latency, i915_pri_wm_latency_fops}, {i915_spr_wm_latency, i915_spr_wm_latency_fops}, {i915_cur_wm_latency, i915_cur_wm_latency_fops}, + {i915_fbc_false_color, i915_fbc_fops}, }; void intel_display_crc_init(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8cea596..ec24b15 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -607,6 +607,8 @@ struct i915_fbc { struct drm_mm_node *compressed_fb; struct drm_mm_node *compressed_llb; + bool false_color; + struct intel_fbc_work { struct delayed_work work; struct drm_crtc *crtc; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 3488567..c70df22 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1495,6 +1495,7 @@ enum punit_power_well { /* Framebuffer compression for Ironlake */ #define ILK_DPFC_CB_BASE 0x43200 #define ILK_DPFC_CONTROL 0x43208 +#define FBC_CTL_FALSE_COLOR (110) /* The bit 28-8 is reserved */ #define DPFC_RESERVED(0x1F00) #define ILK_DPFC_RECOMP_CTL0x4320c diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index d771e82..216cb19 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -236,6 +236,9 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc) if (IS_GEN5(dev)) dpfc_ctl |= obj-fence_reg; + if (dev_priv-fbc.false_color) + dpfc_ctl |= FBC_CTL_FALSE_COLOR; + I915_WRITE(ILK_DPFC_FENCE_YOFF, crtc-y); I915_WRITE(ILK_FBC_RT_BASE, i915_gem_obj_ggtt_offset(obj) | ILK_FBC_RT_VALID); /* enable it... */ @@ -290,6 +293,9 @@ static void gen7_enable_fbc(struct drm_crtc *crtc) dpfc_ctl |= DPFC_CTL_LIMIT_1X; dpfc_ctl |=
Re: [Intel-gfx] [PATCH 28/53] drm/i915/bdw: GEN-specific logical ring emit flush
On Fri, Jun 13, 2014 at 08:37:46AM -0700, oscar.ma...@intel.com wrote: From: Oscar Mateo oscar.ma...@intel.com Notice that the BSD invalidate bit is no longer present in GEN8, so Hmm. As far as I can tell, it is still present for VCS on gen8. As to whether we need to set it, I don't know. we can consolidate the blt and bsd ring flushes into one. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/intel_lrc.c| 80 + drivers/gpu/drm/i915/intel_ringbuffer.c | 7 --- drivers/gpu/drm/i915/intel_ringbuffer.h | 11 + 3 files changed, 91 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 3debe8b..3d7fcd6 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -343,6 +343,81 @@ static int gen8_init_render_ring(struct intel_engine_cs *ring) return ret; } +static int gen8_emit_flush(struct intel_engine_cs *ring, +struct intel_context *ctx, +u32 invalidate_domains, +u32 unused) +{ + struct intel_ringbuffer *ringbuf = logical_ringbuf_get(ring, ctx); + uint32_t cmd; + int ret; + + ret = intel_logical_ring_begin(ring, ctx, 4); + if (ret) + return ret; + + cmd = MI_FLUSH_DW + 1; + + /* + * Bspec vol 1c.3 - blitter engine command streamer: + * If ENABLED, all TLBs will be invalidated once the flush + * operation is complete. This bit is only valid when the + * Post-Sync Operation field is a value of 1h or 3h. + */ + if (invalidate_domains I915_GEM_DOMAIN_RENDER) + cmd |= MI_INVALIDATE_TLB | MI_FLUSH_DW_STORE_INDEX | + MI_FLUSH_DW_OP_STOREDW; + intel_logical_ring_emit(ringbuf, cmd); + intel_logical_ring_emit(ringbuf, I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT); + intel_logical_ring_emit(ringbuf, 0); /* upper addr */ + intel_logical_ring_emit(ringbuf, 0); /* value */ + intel_logical_ring_advance(ringbuf); + + return 0; +} + +static int gen8_emit_flush_render(struct intel_engine_cs *ring, + struct intel_context *ctx, + u32 invalidate_domains, + u32 flush_domains) +{ + struct intel_ringbuffer *ringbuf = logical_ringbuf_get(ring, ctx); + u32 flags = 0; + u32 scratch_addr = ring-scratch.gtt_offset + 2 * CACHELINE_BYTES; + int ret; + + flags |= PIPE_CONTROL_CS_STALL; + + if (flush_domains) { + flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; + flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; + } + if (invalidate_domains) { + flags |= PIPE_CONTROL_TLB_INVALIDATE; + flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_QW_WRITE; + flags |= PIPE_CONTROL_GLOBAL_GTT_IVB; + } + + ret = intel_logical_ring_begin(ring, ctx, 6); + if (ret) + return ret; + + intel_logical_ring_emit(ringbuf, GFX_OP_PIPE_CONTROL(6)); + intel_logical_ring_emit(ringbuf, flags); + intel_logical_ring_emit(ringbuf, scratch_addr); + intel_logical_ring_emit(ringbuf, 0); + intel_logical_ring_emit(ringbuf, 0); + intel_logical_ring_emit(ringbuf, 0); + intel_logical_ring_advance(ringbuf); + + return 0; +} + static u32 gen8_get_seqno(struct intel_engine_cs *ring, bool lazy_coherency) { return intel_read_status_page(ring, I915_GEM_HWS_INDEX); @@ -491,6 +566,7 @@ static int logical_render_ring_init(struct drm_device *dev) ring-set_seqno = gen8_set_seqno; ring-submit_ctx = gen8_submit_ctx; ring-emit_request = gen8_emit_request_render; + ring-emit_flush = gen8_emit_flush_render; return logical_ring_init(dev, ring); } @@ -511,6 +587,7 @@ static int logical_bsd_ring_init(struct drm_device *dev) ring-set_seqno = gen8_set_seqno; ring-submit_ctx = gen8_submit_ctx; ring-emit_request = gen8_emit_request; + ring-emit_flush = gen8_emit_flush; return logical_ring_init(dev, ring); } @@ -531,6 +608,7 @@ static int logical_bsd2_ring_init(struct drm_device *dev) ring-set_seqno = gen8_set_seqno; ring-submit_ctx = gen8_submit_ctx; ring-emit_request = gen8_emit_request; + ring-emit_flush = gen8_emit_flush; return logical_ring_init(dev, ring); } @@ -551,6 +629,7 @@ static int logical_blt_ring_init(struct drm_device *dev) ring-set_seqno = gen8_set_seqno; ring-submit_ctx =