Re: [Intel-gfx] regression after: drm/i915: Warn if we run out of FIFO space for a mode
On Di, 2010-08-03 at 17:15 +0200, Alexey Fisher wrote: On Mo, 2010-08-02 at 20:42 +0100, Chris Wilson wrote: On Mon, 02 Aug 2010 12:16:16 +0200, Alexey Fisher bug-tr...@fisher-privat.net wrote: Hallo all, i have regression coused by this patch: commit b9421ae8f30958deea98d71477b4a77a066856b4 Author: Chris Wilson ch...@chris-wilson.co.uk Date: Mon Jul 19 21:46:08 2010 +0100 drm/i915: Warn if we run out of FIFO space for a mode Weird as all that patch should do is add a DRM_ERROR() with no other side-effect. How confident are you in your analysis? Did you at least see the error in dmesg? No error in dmesg, i doing recheck now. It seems to have some false negative. To be sure i run noncrash kernel extra long. I still can't get good results. Too many false negatives. If you have some tips, bench tools or test where i can reproduce this bug, it will be great. Regards, Alexey ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Remove useless message when disabling Big FIFO on PineView
As we already have appropriate debug and warnings when we activate and deactivate the self-refresh FIFO, having a further INFO is just annoying. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c | 11 +++ 1 files changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ae17185..3ae8474 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2831,13 +2831,9 @@ static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int is_ddr3, static void pineview_disable_cxsr(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev-dev_private; - u32 reg; /* deactivate cxsr */ - reg = I915_READ(DSPFW3); - reg = ~(PINEVIEW_SELF_REFRESH_EN); - I915_WRITE(DSPFW3, reg); - DRM_INFO(Big FIFO is disabled\n); + I915_WRITE(DSPFW3, I915_READ(DSPFW3) ~PINEVIEW_SELF_REFRESH_EN); } /* @@ -2976,9 +2972,8 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, DRM_DEBUG_KMS(DSPFW3 register is %x\n, reg); /* activate cxsr */ - reg = I915_READ(DSPFW3); - reg |= PINEVIEW_SELF_REFRESH_EN; - I915_WRITE(DSPFW3, reg); + I915_WRITE(DSPFW3, + I915_READ(DSPFW3) | PINEVIEW_SELF_REFRESH_EN); DRM_DEBUG_KMS(Self-refresh is enabled\n); } else { pineview_disable_cxsr(dev); -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Do not clobber the contents of TRANS_DP_CTL when enabling.
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_reg.h |1 + drivers/gpu/drm/i915/intel_display.c |7 --- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 281db6e..97a35a4 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2928,6 +2928,7 @@ #define TRANS_DP_VSYNC_ACTIVE_LOW 0 #define TRANS_DP_HSYNC_ACTIVE_HIGH(13) #define TRANS_DP_HSYNC_ACTIVE_LOW 0 +#define TRANS_DP_SYNC_MASK(33) /* SNB eDP training params */ /* SNB A-stepping */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3ae8474..5946c88 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1998,9 +1998,10 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) int reg; reg = I915_READ(trans_dp_ctl); - reg = ~TRANS_DP_PORT_SEL_MASK; - reg = TRANS_DP_OUTPUT_ENABLE | - TRANS_DP_ENH_FRAMING; + reg = ~(TRANS_DP_PORT_SEL_MASK | +TRANS_DP_SYNC_MASK); + reg |= (TRANS_DP_OUTPUT_ENABLE | + TRANS_DP_ENH_FRAMING); if (crtc-mode.flags DRM_MODE_FLAG_PHSYNC) reg |= TRANS_DP_HSYNC_ACTIVE_HIGH; -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] Fair eviction patchset.
The fair-eviction patches rebased upon drm-(core|intel)-next. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/5] drm/i915: Use a common seqno for all rings.
This will be used by the eviction logic to maintain fairness between the rings. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h |3 +- drivers/gpu/drm/i915/i915_gem.c |2 + drivers/gpu/drm/i915/intel_ringbuffer.c | 46 +- drivers/gpu/drm/i915/intel_ringbuffer.h |1 - 4 files changed, 29 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 906663b..09ec8d5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -242,6 +242,7 @@ typedef struct drm_i915_private { struct pci_dev *bridge_dev; struct intel_ring_buffer render_ring; struct intel_ring_buffer bsd_ring; + uint32_t next_seqno; drm_dma_handle_t *status_page_dmah; void *seqno_page; @@ -568,8 +569,6 @@ typedef struct drm_i915_private { */ struct delayed_work retire_work; - uint32_t next_gem_seqno; - /** * Waiting sequence number, if any */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 408be72..e115236 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4694,6 +4694,8 @@ i915_gem_init_ringbuffer(struct drm_device *dev) goto cleanup_render_ring; } + dev_priv-next_seqno = 1; + return 0; cleanup_render_ring: diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 26362f8..f914c42 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -33,18 +33,35 @@ #include i915_drm.h #include i915_trace.h +static u32 i915_gem_get_seqno(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev-dev_private; + u32 seqno; + + seqno = dev_priv-next_seqno; + + /* reserve 0 for non-seqno */ + if (++dev_priv-next_seqno == 0) + dev_priv-next_seqno = 1; + + return seqno; +} + static void render_ring_flush(struct drm_device *dev, struct intel_ring_buffer *ring, u32 invalidate_domains, u32 flush_domains) { + drm_i915_private_t *dev_priv = dev-dev_private; + u32 cmd; + #if WATCH_EXEC DRM_INFO(%s: invalidate %08x flush %08x\n, __func__, invalidate_domains, flush_domains); #endif - u32 cmd; - trace_i915_gem_request_flush(dev, ring-next_seqno, + + trace_i915_gem_request_flush(dev, dev_priv-next_seqno, invalidate_domains, flush_domains); if ((invalidate_domains | flush_domains) I915_GEM_GPU_DOMAINS) { @@ -233,9 +250,10 @@ render_ring_add_request(struct drm_device *dev, struct drm_file *file_priv, u32 flush_domains) { - u32 seqno; drm_i915_private_t *dev_priv = dev-dev_private; - seqno = intel_ring_get_seqno(dev, ring); + u32 seqno; + + seqno = i915_gem_get_seqno(dev); if (IS_GEN6(dev)) { BEGIN_LP_RING(6); @@ -405,7 +423,9 @@ bsd_ring_add_request(struct drm_device *dev, u32 flush_domains) { u32 seqno; - seqno = intel_ring_get_seqno(dev, ring); + + seqno = i915_gem_get_seqno(dev); + intel_ring_begin(dev, ring, 4); intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX); intel_ring_emit(dev, ring, @@ -479,7 +499,7 @@ render_ring_dispatch_gem_execbuffer(struct drm_device *dev, exec_start = (uint32_t) exec_offset + exec-batch_start_offset; exec_len = (uint32_t) exec-batch_len; - trace_i915_gem_request_submit(dev, dev_priv-mm.next_gem_seqno + 1); + trace_i915_gem_request_submit(dev, dev_priv-next_seqno + 1); count = nbox ? nbox : 1; @@ -762,18 +782,6 @@ void intel_fill_struct(struct drm_device *dev, intel_ring_advance(dev, ring); } -u32 intel_ring_get_seqno(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - u32 seqno; - seqno = ring-next_seqno; - - /* reserve 0 for non-seqno */ - if (++ring-next_seqno == 0) - ring-next_seqno = 1; - return seqno; -} - struct intel_ring_buffer render_ring = { .name = render ring, .regs = { @@ -791,7 +799,6 @@ struct intel_ring_buffer render_ring = { .head = 0, .tail = 0, .space = 0, - .next_seqno = 1, .user_irq_refcount = 0, .irq_gem_seqno = 0, .waiting_gem_seqno = 0, @@ -830,7 +837,6 @@ struct intel_ring_buffer bsd_ring = { .head = 0, .tail = 0, .space = 0, -
[Intel-gfx] [PATCH 1/5] drm/i915: prepare for fair lru eviction
From: Daniel Vetter daniel.vet...@ffwll.ch This does two little changes: - Add an alignment parameter for evict_something. It's not really great to whack a carefully sized hole into the gtt with the wrong alignment. Especially since the fallback path is a full evict. - With the inactive scan stuff we need to evict more that one object, so move the unbind call into the helper function that scans for the object to be evicted, too. And adjust its name. No functional changes in this patch, just preparation. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 67 --- 1 files changed, 41 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4efd4fd..408be72 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -35,6 +35,7 @@ #include linux/swap.h #include linux/pci.h +static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj); static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); @@ -48,7 +49,8 @@ static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment); static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); -static int i915_gem_evict_something(struct drm_device *dev, int min_size); +static int i915_gem_evict_something(struct drm_device *dev, int min_size, + unsigned alignment); static int i915_gem_evict_from_inactive_list(struct drm_device *dev); static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, @@ -313,7 +315,8 @@ i915_gem_object_get_pages_or_evict(struct drm_gem_object *obj) if (ret == -ENOMEM) { struct drm_device *dev = obj-dev; - ret = i915_gem_evict_something(dev, obj-size); + ret = i915_gem_evict_something(dev, obj-size, + i915_gem_get_gtt_alignment(obj)); if (ret) return ret; @@ -2010,10 +2013,12 @@ i915_gem_object_unbind(struct drm_gem_object *obj) return ret; } -static struct drm_gem_object * -i915_gem_find_inactive_object(struct drm_device *dev, int min_size) +static int +i915_gem_scan_inactive_list_and_evict(struct drm_device *dev, int min_size, + unsigned alignment, int *found) { drm_i915_private_t *dev_priv = dev-dev_private; + struct drm_gem_object *obj; struct drm_i915_gem_object *obj_priv; struct drm_gem_object *best = NULL; struct drm_gem_object *first = NULL; @@ -2027,14 +2032,31 @@ i915_gem_find_inactive_object(struct drm_device *dev, int min_size) (!best || obj-size best-size)) { best = obj; if (best-size == min_size) - return best; + break; } if (!first) first = obj; } } - return best ? best : first; + obj = best ? best : first; + + if (!obj) { + *found = 0; + return 0; + } + + *found = 1; + +#if WATCH_LRU + DRM_INFO(%s: evicting %p\n, __func__, obj); +#endif + obj_priv = to_intel_bo(obj); + BUG_ON(obj_priv-pin_count != 0); + BUG_ON(obj_priv-active); + + /* Wait on the rendering and unbind the buffer. */ + return i915_gem_object_unbind(obj); } static int @@ -2120,11 +2142,11 @@ i915_gem_evict_everything(struct drm_device *dev) } static int -i915_gem_evict_something(struct drm_device *dev, int min_size) +i915_gem_evict_something(struct drm_device *dev, +int min_size, unsigned alignment) { drm_i915_private_t *dev_priv = dev-dev_private; - struct drm_gem_object *obj; - int ret; + int ret, found; struct intel_ring_buffer *render_ring = dev_priv-render_ring; struct intel_ring_buffer *bsd_ring = dev_priv-bsd_ring; @@ -2134,20 +2156,11 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) /* If there's an inactive buffer available now, grab it * and be done. */ - obj = i915_gem_find_inactive_object(dev, min_size); - if (obj) { - struct drm_i915_gem_object *obj_priv; - -#if WATCH_LRU -
[Intel-gfx] [PATCH 3/5] drm/i915: Move the eviction logic to its own file.
The eviction code is the gnarly underbelly of memory management, and is clearer if kept separated from the normal domain management in GEM. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/Makefile |1 + drivers/gpu/drm/i915/i915_drv.h |6 + drivers/gpu/drm/i915/i915_gem.c | 231 +- drivers/gpu/drm/i915/i915_gem_evict.c | 260 + 4 files changed, 269 insertions(+), 229 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_gem_evict.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index da78f2c..384fd45 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -8,6 +8,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ i915_suspend.o \ i915_gem.o \ i915_gem_debug.o \ + i915_gem_evict.o \ i915_gem_tiling.o \ i915_trace_points.o \ intel_display.o \ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 09ec8d5..75fe397 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -977,6 +977,7 @@ int i915_gem_init_ringbuffer(struct drm_device *dev); void i915_gem_cleanup_ringbuffer(struct drm_device *dev); int i915_gem_do_init(struct drm_device *dev, unsigned long start, unsigned long end); +int i915_gpu_idle(struct drm_device *dev); int i915_gem_idle(struct drm_device *dev); uint32_t i915_add_request(struct drm_device *dev, struct drm_file *file_priv, @@ -1002,6 +1003,11 @@ int i915_gem_object_flush_write_domain(struct drm_gem_object *obj); void i915_gem_shrinker_init(void); void i915_gem_shrinker_exit(void); +/* i915_gem_evict.c */ +int i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment); +int i915_gem_evict_everything(struct drm_device *dev); +int i915_gem_evict_inactive(struct drm_device *dev); + /* i915_gem_tiling.c */ void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e115236..ecc447f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -49,9 +49,6 @@ static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment); static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); -static int i915_gem_evict_something(struct drm_device *dev, int min_size, - unsigned alignment); -static int i915_gem_evict_from_inactive_list(struct drm_device *dev); static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, struct drm_file *file_priv); @@ -1890,19 +1887,6 @@ i915_gem_flush(struct drm_device *dev, flush_domains); } -static void -i915_gem_flush_ring(struct drm_device *dev, - uint32_t invalidate_domains, - uint32_t flush_domains, - struct intel_ring_buffer *ring) -{ - if (flush_domains I915_GEM_DOMAIN_CPU) - drm_agp_chipset_flush(dev); - ring-flush(dev, ring, - invalidate_domains, - flush_domains); -} - /** * Ensures that all rendering to the object has completed and the object is * safe to unbind from the GTT or access from the CPU. @@ -2013,53 +1997,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) return ret; } -static int -i915_gem_scan_inactive_list_and_evict(struct drm_device *dev, int min_size, - unsigned alignment, int *found) -{ - drm_i915_private_t *dev_priv = dev-dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - struct drm_gem_object *best = NULL; - struct drm_gem_object *first = NULL; - - /* Try to find the smallest clean object */ - list_for_each_entry(obj_priv, dev_priv-mm.inactive_list, list) { - struct drm_gem_object *obj = obj_priv-base; - if (obj-size = min_size) { - if ((!obj_priv-dirty || -i915_gem_object_is_purgeable(obj_priv)) - (!best || obj-size best-size)) { - best = obj; - if (best-size == min_size) - break; - } - if (!first) - first = obj; - } - } - - obj = best ? best : first; - - if (!obj) { - *found = 0; -
[Intel-gfx] [PATCH 5/5] drm/i915: Maintain LRU order of inactive objects upon access by CPU
In order to reduce the penalty of fallbacks under memory pressure and to avoid a potential immediate ping-pong of evicting a mmaped buffer, we move the object to the tail of the inactive list when a page is freshly faulted or the object is moved into the CPU domain. We choose not to protect the CPU objects from casual eviction, preferring to keep the GPU active for as long as possible. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c |7 +++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index ecc447f..b09def9 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1036,6 +1036,10 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); } + /* Maintain LRU order of inactive objects */ + if (ret == 0 obj_priv-gtt_space !obj_priv-active) + list_move_tail(obj_priv-list, dev_priv-mm.inactive_list); + drm_gem_object_unreference(obj); mutex_unlock(dev-struct_mutex); return ret; @@ -1169,6 +1173,9 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) goto unlock; } + if (!obj_priv-active) + list_move_tail(obj_priv-list, dev_priv-mm.inactive_list); + pfn = ((dev-agp-base + obj_priv-gtt_offset) PAGE_SHIFT) + page_offset; -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Emit a backtrace if we attempt to rebind a pinned buffer
This debugging trace was useful for finding the fbcon regression on i965, and it may prove useful again in future. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b09def9..b2ff908 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4010,6 +4010,10 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) if (alignment == 0) alignment = i915_gem_get_gtt_alignment(obj); if (obj_priv-gtt_offset (alignment - 1)) { + WARN(obj_priv-pin_count, +bo is already pinned with incorrect alignment: + offset=%x, req.alignment=%x\n, +obj_priv-gtt_offset, alignment); ret = i915_gem_object_unbind(obj); if (ret) return ret; -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] SVDO properties patchset
This patchset touches virtually all of i915/intel*.c simply to subclass encoders and connectors, then cleans up intel_sdvo in order to add a few more TV properties. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 7/7] drm/i915/sdvo: Add dot crawl property
This property is slightly unusual in that it is a boolean and so has no GET_MAX command. Reference: Bug 28636 - missing TV parameter Dot Crawl freeze https://bugs.freedesktop.org/show_bug.cgi?id=28636 Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_sdvo.c | 24 1 files changed, 24 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 0e13b95..ccf6574 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -161,6 +161,7 @@ struct intel_sdvo_connector { struct drm_property *flicker_filter_2d; struct drm_property *tv_chroma_filter; struct drm_property *tv_luma_filter; + struct drm_property *dot_crawl; /* add the property for the SDVO-TV/LVDS */ struct drm_property *brightness; @@ -182,6 +183,7 @@ struct intel_sdvo_connector { u32 cur_flicker_filter_2d, max_flicker_filter_2d; u32 cur_tv_chroma_filter, max_tv_chroma_filter; u32 cur_tv_luma_filter, max_tv_luma_filter; + u32 cur_dot_crawl, max_dot_crawl; }; static struct intel_sdvo *enc_to_intel_sdvo(struct drm_encoder *encoder) @@ -1751,6 +1753,8 @@ intel_sdvo_destroy_enhance_property(struct drm_connector *connector) drm_property_destroy(dev, intel_sdvo_connector-tv_luma_filter); if (intel_sdvo_connector-tv_chroma_filter) drm_property_destroy(dev, intel_sdvo_connector-tv_chroma_filter); + if (intel_sdvo_connector-dot_crawl) + drm_property_destroy(dev, intel_sdvo_connector-dot_crawl); if (intel_sdvo_connector-brightness) drm_property_destroy(dev, intel_sdvo_connector-brightness); } @@ -1867,6 +1871,7 @@ intel_sdvo_set_property(struct drm_connector *connector, CHECK_PROPERTY(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE) CHECK_PROPERTY(tv_chroma_filter, TV_CHROMA_FILTER) CHECK_PROPERTY(tv_luma_filter, TV_LUMA_FILTER) + CHECK_PROPERTY(dot_crawl, DOT_CRAWL) } return -EINVAL; /* unknown property */ @@ -2439,6 +2444,25 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, ENHANCEMENT(tv_chroma_filter, TV_CHROMA_FILTER); ENHANCEMENT(tv_luma_filter, TV_LUMA_FILTER); + if (enhancements.dot_crawl) { + if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_DOT_CRAWL, response, 2)) + return false; + + intel_sdvo_connector-max_dot_crawl = 1; + intel_sdvo_connector-cur_dot_crawl = response 0x1; + intel_sdvo_connector-dot_crawl = + drm_property_create(dev, DRM_MODE_PROP_RANGE, dot_crawl, 2); + if (!intel_sdvo_connector-dot_crawl) + return false; + + intel_sdvo_connector-dot_crawl-values[0] = 0; + intel_sdvo_connector-dot_crawl-values[1] = 1; + drm_connector_attach_property(connector, + intel_sdvo_connector-dot_crawl, + intel_sdvo_connector-cur_dot_crawl); + DRM_DEBUG_KMS(dot crawl: current %d\n, response); + } + return true; } -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/7] drm/i915: Subclass intel_connector.
Make the code that tiny bit clearer by reducing the pointer dance. 2 files changed, 130 insertions(+), 147 deletions(-) Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_drv.h |1 - drivers/gpu/drm/i915/intel_sdvo.c | 276 +--- 2 files changed, 130 insertions(+), 147 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 0e8c5a8..a44b8cb 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -109,7 +109,6 @@ struct intel_encoder { struct intel_connector { struct drm_connector base; - void *dev_priv; }; struct intel_crtc; diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index b4a1900..5d1277e 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -134,6 +134,8 @@ struct intel_sdvo { }; struct intel_sdvo_connector { + struct intel_connector base; + /* Mark the type of connector */ uint16_t output_flag; @@ -180,6 +182,11 @@ static struct intel_sdvo *enc_to_intel_sdvo(struct drm_encoder *encoder) return container_of(enc_to_intel_encoder(encoder), struct intel_sdvo, base); } +static struct intel_sdvo_connector *to_intel_sdvo_connector(struct drm_connector *connector) +{ + return container_of(to_intel_connector(connector), struct intel_sdvo_connector, base); +} + static bool intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags); static void @@ -1502,8 +1509,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) { struct drm_encoder *encoder = intel_attached_encoder(connector); struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); - struct intel_connector *intel_connector = to_intel_connector(connector); - struct intel_sdvo_connector *sdvo_connector = intel_connector-dev_priv; + struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); enum drm_connector_status status = connector_status_connected; struct edid *edid = NULL; @@ -1543,7 +1549,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) if (edid != NULL) { bool is_digital = !!(edid-input DRM_EDID_INPUT_DIGITAL); - bool need_digital = !!(sdvo_connector-output_flag SDVO_TMDS_MASK); + bool need_digital = !!(intel_sdvo_connector-output_flag SDVO_TMDS_MASK); /* DDC bus is shared, match EDID to connector type */ if (is_digital need_digital) @@ -1566,8 +1572,7 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect u8 status; struct drm_encoder *encoder = intel_attached_encoder(connector); struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); - struct intel_connector *intel_connector = to_intel_connector(connector); - struct intel_sdvo_connector *sdvo_connector = intel_connector-dev_priv; + struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); enum drm_connector_status ret; intel_sdvo_write_cmd(intel_sdvo, @@ -1588,7 +1593,7 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect intel_sdvo-attached_output = response; - if ((sdvo_connector-output_flag response) == 0) + if ((intel_sdvo_connector-output_flag response) == 0) ret = connector_status_disconnected; else if (response SDVO_TMDS_MASK) ret = intel_sdvo_hdmi_sink_detect(connector); @@ -1784,12 +1789,11 @@ end: static int intel_sdvo_get_modes(struct drm_connector *connector) { - struct intel_connector *intel_connector = to_intel_connector(connector); - struct intel_sdvo_connector *sdvo_connector = intel_connector-dev_priv; + struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); - if (IS_TV(sdvo_connector)) + if (IS_TV(intel_sdvo_connector)) intel_sdvo_get_tv_modes(connector); - else if (IS_LVDS(sdvo_connector)) + else if (IS_LVDS(intel_sdvo_connector)) intel_sdvo_get_lvds_modes(connector); else intel_sdvo_get_ddc_modes(connector); @@ -1802,48 +1806,46 @@ static int intel_sdvo_get_modes(struct drm_connector *connector) static void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) { - struct intel_connector *intel_connector = to_intel_connector(connector); - struct intel_sdvo_connector *intel_sdvo = intel_connector-dev_priv; + struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); struct drm_device *dev = connector-dev; - if (IS_TV(intel_sdvo)) { - if (intel_sdvo-left_property) - drm_property_destroy(dev,
[Intel-gfx] [PATCH 5/7] drm/i915/sdvo: Check for allocation failure when constructing properties
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_sdvo.c | 40 +++- 1 files changed, 38 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 0e03f40..c668010 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1687,8 +1687,8 @@ static int intel_sdvo_get_modes(struct drm_connector *connector) return !list_empty(connector-probed_modes); } -static -void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) +static void +intel_sdvo_destroy_enhance_property(struct drm_connector *connector) { struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); struct drm_device *dev = connector-dev; @@ -2104,6 +2104,7 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) return true; err: + intel_sdvo_destroy_enhance_property(connector); kfree(intel_sdvo_connector); return false; } @@ -2178,6 +2179,7 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) return true; err: + intel_sdvo_destroy_enhance_property(connector); kfree(intel_sdvo_connector); return false; } @@ -2269,6 +2271,8 @@ static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, intel_sdvo_connector-tv_format_property = drm_property_create(dev, DRM_MODE_PROP_ENUM, mode, intel_sdvo_connector-format_supported_num); + if (!intel_sdvo_connector-tv_format_property) + return false; for (i = 0; i intel_sdvo_connector-format_supported_num; i++) drm_property_add_enum( @@ -2321,14 +2325,21 @@ static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, intel_sdvo_connector-left_property = drm_property_create(dev, DRM_MODE_PROP_RANGE, left_margin, 2); + if (!intel_sdvo_connector-left_property) + return false; + intel_sdvo_connector-left_property-values[0] = 0; intel_sdvo_connector-left_property-values[1] = data_value[0]; drm_connector_attach_property(connector, intel_sdvo_connector-left_property, intel_sdvo_connector-left_margin); + intel_sdvo_connector-right_property = drm_property_create(dev, DRM_MODE_PROP_RANGE, right_margin, 2); + if (!intel_sdvo_connector-right_property) + return false; + intel_sdvo_connector-right_property-values[0] = 0; intel_sdvo_connector-right_property-values[1] = data_value[0]; drm_connector_attach_property(connector, @@ -2355,14 +2366,21 @@ static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, intel_sdvo_connector-top_property = drm_property_create(dev, DRM_MODE_PROP_RANGE, top_margin, 2); + if (!intel_sdvo_connector-top_property) + return false; + intel_sdvo_connector-top_property-values[0] = 0; intel_sdvo_connector-top_property-values[1] = data_value[0]; drm_connector_attach_property(connector, intel_sdvo_connector-top_property, intel_sdvo_connector-top_margin); + intel_sdvo_connector-bottom_property = drm_property_create(dev, DRM_MODE_PROP_RANGE, bottom_margin, 2); + if (!intel_sdvo_connector-bottom_property) + return false; + intel_sdvo_connector-bottom_property-values[0] = 0; intel_sdvo_connector-bottom_property-values[1] = data_value[0]; drm_connector_attach_property(connector, @@ -2388,6 +2406,9 @@ static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, intel_sdvo_connector-hpos_property = drm_property_create(dev, DRM_MODE_PROP_RANGE, hpos, 2); + if (!intel_sdvo_connector-hpos_property) + return false; +
[Intel-gfx] [PATCH 4/7] drm/i915/sdvo: Use an integer mapping for supported tv format modes
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_sdvo.c | 34 +++--- 1 files changed, 11 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 5cc83e5..0e03f40 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -98,7 +98,7 @@ struct intel_sdvo { bool is_tv; /* This is for current tv format name */ - char *tv_format_name; + int tv_format_index; /** * This is set if we treat the device as HDMI, instead of DVI. @@ -141,7 +141,7 @@ struct intel_sdvo_connector { uint16_t output_flag; /* This contains all current supported TV format */ - char *tv_format_supported[TV_FORMAT_NUM]; + u8 tv_format_supported[TV_FORMAT_NUM]; int format_supported_num; struct drm_property *tv_format_property; struct drm_property *tv_format_name_property[TV_FORMAT_NUM]; @@ -958,13 +958,9 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo, static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) { struct intel_sdvo_tv_format format; - uint32_t format_map, i; - - for (i = 0; i TV_FORMAT_NUM; i++) - if (tv_format_names[i] == intel_sdvo-tv_format_name) - break; + uint32_t format_map; - format_map = 1 i; + format_map = 1 intel_sdvo-tv_format_index; memset(format, 0, sizeof(format)); memcpy(format, format_map, min(sizeof(format), sizeof(format_map))); @@ -1614,11 +1610,7 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) /* Read the list of supported input resolutions for the selected TV * format. */ - for (i = 0; i TV_FORMAT_NUM; i++) - if (tv_format_names[i] == intel_sdvo-tv_format_name) - break; - - format_map = (1 i); + format_map = 1 intel_sdvo-tv_format_index; memcpy(tv_res, format_map, min(sizeof(format_map), sizeof(struct intel_sdvo_sdtv_resolution_request))); @@ -1640,7 +1632,6 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) if (nmode) drm_mode_probed_add(connector, nmode); } - } static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) @@ -1768,11 +1759,11 @@ intel_sdvo_set_property(struct drm_connector *connector, if (val = TV_FORMAT_NUM) return -EINVAL; - if (intel_sdvo-tv_format_name == + if (intel_sdvo-tv_format_index == intel_sdvo_connector-tv_format_supported[val]) return 0; - intel_sdvo-tv_format_name = intel_sdvo_connector-tv_format_supported[val]; + intel_sdvo-tv_format_index = intel_sdvo_connector-tv_format_supported[val]; changed = true; } else if (IS_TV_OR_LVDS(intel_sdvo_connector)) { cmd = 0; @@ -2271,11 +2262,8 @@ static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, intel_sdvo_connector-format_supported_num = 0; for (i = 0 ; i TV_FORMAT_NUM; i++) - if (format_map (1 i)) { - intel_sdvo_connector-tv_format_supported - [intel_sdvo_connector-format_supported_num++] = - tv_format_names[i]; - } + if (format_map (1 i)) + intel_sdvo_connector-tv_format_supported[intel_sdvo_connector-format_supported_num++] = i; intel_sdvo_connector-tv_format_property = @@ -2285,9 +2273,9 @@ static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, for (i = 0; i intel_sdvo_connector-format_supported_num; i++) drm_property_add_enum( intel_sdvo_connector-tv_format_property, i, - i, intel_sdvo_connector-tv_format_supported[i]); + i, tv_format_names[intel_sdvo_connector-tv_format_supported[i]]); - intel_sdvo-tv_format_name = intel_sdvo_connector-tv_format_supported[0]; + intel_sdvo-tv_format_index = intel_sdvo_connector-tv_format_supported[0]; drm_connector_attach_property(intel_sdvo_connector-base.base, intel_sdvo_connector-tv_format_property, 0); return true; -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Only emit flushes on active rings.
This avoids the excess flush and requests on idle rings (and spamming the debug log ;-) Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h |3 +++ drivers/gpu/drm/i915/i915_gem.c | 26 -- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 61a8c90..844d10e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -286,6 +286,9 @@ typedef struct drm_i915_private { unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; int vblank_pipe; int num_pipe; + u32 flush_rings; +#define FLUSH_RENDER_RING 0x1 +#define FLUSH_BSD_RING 0x2 /* For hangcheck timer */ #define DRM_I915_HANGCHECK_PERIOD 75 /* in jiffies */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b2ff908..36d7e93 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2936,6 +2936,7 @@ static void i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) { struct drm_device *dev = obj-dev; + drm_i915_private_t *dev_priv = dev-dev_private; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); uint32_tinvalidate_domains = 0; uint32_tflush_domains = 0; @@ -2998,6 +2999,13 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) obj-pending_write_domain = obj-write_domain; obj-read_domains = obj-pending_read_domains; + if (flush_domains I915_GEM_GPU_DOMAINS) { + if (obj_priv-ring == dev_priv-render_ring) + dev_priv-flush_rings |= FLUSH_RENDER_RING; + else if (obj_priv-ring == dev_priv-bsd_ring) + dev_priv-flush_rings |= FLUSH_BSD_RING; + } + dev-invalidate_domains |= invalidate_domains; dev-flush_domains |= flush_domains; #if WATCH_BUF @@ -3536,7 +3544,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, ring = dev_priv-render_ring; } - if (args-buffer_count 1) { DRM_ERROR(execbuf with %d buffers\n, args-buffer_count); return -EINVAL; @@ -3710,6 +3717,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, */ dev-invalidate_domains = 0; dev-flush_domains = 0; + dev_priv-flush_rings = 0; for (i = 0; i args-buffer_count; i++) { struct drm_gem_object *obj = object_list[i]; @@ -3730,16 +3738,14 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, i915_gem_flush(dev, dev-invalidate_domains, dev-flush_domains); - if (dev-flush_domains I915_GEM_GPU_DOMAINS) { + if (dev_priv-flush_rings FLUSH_RENDER_RING) (void)i915_add_request(dev, file_priv, - dev-flush_domains, - dev_priv-render_ring); - - if (HAS_BSD(dev)) - (void)i915_add_request(dev, file_priv, - dev-flush_domains, - dev_priv-bsd_ring); - } + dev-flush_domains, + dev_priv-render_ring); + if (dev_priv-flush_rings FLUSH_BSD_RING) + (void)i915_add_request(dev, file_priv, + dev-flush_domains, + dev_priv-bsd_ring); } for (i = 0; i args-buffer_count; i++) { -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Kill the active list spinlock
This spinlock only served debugging purposes in a time when we could not be sure of the mutex ever being released upon a GPU hang. As we now should be able rely on hangcheck to do the job for us (and that error reporting should not itself require the struct mutex) we can kill the incomplete and misleading attempt at protection. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 58 +--- drivers/gpu/drm/i915/i915_drv.h |2 - drivers/gpu/drm/i915/i915_gem.c | 35 +-- drivers/gpu/drm/i915/i915_gem_evict.c |5 --- 4 files changed, 47 insertions(+), 53 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 9214119..08f279b 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -71,12 +71,10 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) struct drm_device *dev = node-minor-dev; drm_i915_private_t *dev_priv = dev-dev_private; struct drm_i915_gem_object *obj_priv; - spinlock_t *lock = NULL; switch (list) { case ACTIVE_LIST: seq_printf(m, Active:\n); - lock = dev_priv-mm.active_list_lock; head = dev_priv-render_ring.active_list; break; case INACTIVE_LIST: @@ -89,11 +87,12 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) break; default: DRM_INFO(Ooops, unexpected list\n); - return 0; + return -EINVAL; } - if (lock) - spin_lock(lock); + if (!mutex_trylock(dev-struct_mutex)) + return -EBUSY; + list_for_each_entry(obj_priv, head, list) { seq_printf(m, %p: %s %8zd %08x %08x %d%s%s, @@ -116,8 +115,8 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) seq_printf(m, \n); } - if (lock) - spin_unlock(lock); + mutex_unlock(dev-struct_mutex); + return 0; } @@ -128,6 +127,9 @@ static int i915_gem_request_info(struct seq_file *m, void *data) drm_i915_private_t *dev_priv = dev-dev_private; struct drm_i915_gem_request *gem_request; + if (!mutex_trylock(dev-struct_mutex)) + return -EBUSY; + seq_printf(m, Request:\n); list_for_each_entry(gem_request, dev_priv-render_ring.request_list, list) { @@ -135,6 +137,9 @@ static int i915_gem_request_info(struct seq_file *m, void *data) gem_request-seqno, (int) (jiffies - gem_request-emitted_jiffies)); } + + mutex_unlock(dev-struct_mutex); + return 0; } @@ -144,6 +149,9 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data) struct drm_device *dev = node-minor-dev; drm_i915_private_t *dev_priv = dev-dev_private; + if (!mutex_trylock(dev-struct_mutex)) + return -EBUSY; + if (dev_priv-render_ring.status_page.page_addr != NULL) { seq_printf(m, Current sequence: %d\n, i915_get_gem_seqno(dev, dev_priv-render_ring)); @@ -153,6 +161,9 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data) seq_printf(m, Waiter sequence: %d\n, dev_priv-mm.waiting_gem_seqno); seq_printf(m, IRQ sequence: %d\n, dev_priv-mm.irq_gem_seqno); + + mutex_unlock(dev-struct_mutex); + return 0; } @@ -216,6 +227,9 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data) drm_i915_private_t *dev_priv = dev-dev_private; int i; + if (!mutex_trylock(dev-struct_mutex)) + return -EBUSY; + seq_printf(m, Reserved fences = %d\n, dev_priv-fence_reg_start); seq_printf(m, Total fences = %d\n, dev_priv-num_fence_regs); for (i = 0; i dev_priv-num_fence_regs; i++) { @@ -241,6 +255,8 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data) } } + mutex_unlock(dev-struct_mutex); + return 0; } @@ -284,9 +300,10 @@ static int i915_batchbuffer_info(struct seq_file *m, void *data) drm_i915_private_t *dev_priv = dev-dev_private; struct drm_gem_object *obj; struct drm_i915_gem_object *obj_priv; - int ret; + int ret = 0; - spin_lock(dev_priv-mm.active_list_lock); + if (!mutex_trylock(dev-struct_mutex)) + return -EBUSY; list_for_each_entry(obj_priv, dev_priv-render_ring.active_list, list) { @@ -295,8 +312,7 @@ static int i915_batchbuffer_info(struct seq_file *m, void *data) ret = i915_gem_object_get_pages(obj, 0); if (ret) {
[Intel-gfx] [PATCH] drm: Use ENOENT consistently for the error return for an unmatched handle.
This is consistent with trying to access a filename that not exist within a directory which is a good analogy here. The main reason for the change is that it is easy to confuse the error code of EBADF as an performing an ioctl on an invalid file descriptor (rather than an unknown object). Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/drm_gem.c |2 +- drivers/gpu/drm/i915/i915_gem.c| 26 +- drivers/gpu/drm/i915/i915_gem_tiling.c |4 ++-- drivers/gpu/drm/nouveau/nouveau_gem.c |8 drivers/gpu/drm/nouveau/nv04_crtc.c|2 +- drivers/gpu/drm/nouveau/nv50_crtc.c|2 +- drivers/gpu/drm/radeon/radeon_cs.c |2 +- drivers/gpu/drm/radeon/radeon_cursor.c |2 +- drivers/gpu/drm/radeon/radeon_gem.c| 12 ++-- 9 files changed, 30 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 4f1b867..bf92d07 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -322,7 +322,7 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args-handle); if (obj == NULL) - return -EBADF; + return -ENOENT; again: if (idr_pre_get(dev-object_name_idr, GFP_KERNEL) == 0) { diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0f0c387..862ce34 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -456,7 +456,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args-handle); if (obj == NULL) - return -EBADF; + return -ENOENT; obj_priv = to_intel_bo(obj); /* Bounds check source. @@ -919,7 +919,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args-handle); if (obj == NULL) - return -EBADF; + return -ENOENT; obj_priv = to_intel_bo(obj); /* Bounds check destination. @@ -1002,7 +1002,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args-handle); if (obj == NULL) - return -EBADF; + return -ENOENT; obj_priv = to_intel_bo(obj); mutex_lock(dev-struct_mutex); @@ -1064,7 +1064,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args-handle); if (obj == NULL) { mutex_unlock(dev-struct_mutex); - return -EBADF; + return -ENOENT; } #if WATCH_BUF @@ -1103,7 +1103,7 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args-handle); if (obj == NULL) - return -EBADF; + return -ENOENT; offset = args-offset; @@ -1380,7 +1380,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args-handle); if (obj == NULL) - return -EBADF; + return -ENOENT; mutex_lock(dev-struct_mutex); @@ -3165,7 +3165,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, reloc-target_handle); if (target_obj == NULL) { i915_gem_object_unpin(obj); - return -EBADF; + return -ENOENT; } target_obj_priv = to_intel_bo(target_obj); @@ -3580,7 +3580,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, exec_list[i].handle, i); /* prevent error path from reading uninitialized data */ args-buffer_count = i + 1; - ret = -EBADF; + ret = -ENOENT; goto err; } @@ -3590,7 +3590,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, object_list[i]); /* prevent error path from reading uninitialized data */ args-buffer_count = i + 1; - ret = -EBADF; + ret = -EINVAL; goto err; } obj_priv-in_execbuffer = true; @@ -4067,7 +4067,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, DRM_ERROR(Bad handle in i915_gem_pin_ioctl(): %d\n, args-handle); mutex_unlock(dev-struct_mutex); - return -EBADF; + return -ENOENT; } obj_priv = to_intel_bo(obj); @@ -4123,7 +4123,7 @@ i915_gem_unpin_ioctl(struct
[Intel-gfx] [PATCH 2/2] drm/i915: Record error batch buffers using iomem
Directly read the GTT mapping for the contents of the batch buffers rather than relying on possibly stale CPU caches. Also for completeness scan the flushing/inactive lists for the current buffers - we are collecting error state after all. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_irq.c | 64 ++ 1 files changed, 57 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 85785a8..8aed608 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -425,9 +425,11 @@ static struct drm_i915_error_object * i915_error_object_create(struct drm_device *dev, struct drm_gem_object *src) { + drm_i915_private_t *dev_priv = dev-dev_private; struct drm_i915_error_object *dst; struct drm_i915_gem_object *src_priv; int page, page_count; + u32 reloc_offset; if (src == NULL) return NULL; @@ -442,18 +444,27 @@ i915_error_object_create(struct drm_device *dev, if (dst == NULL) return NULL; + reloc_offset = src_priv-gtt_offset; for (page = 0; page page_count; page++) { - void *s, *d = kmalloc(PAGE_SIZE, GFP_ATOMIC); unsigned long flags; + void __iomem *s; + void *d; + d = kmalloc(PAGE_SIZE, GFP_ATOMIC); if (d == NULL) goto unwind; + local_irq_save(flags); - s = kmap_atomic(src_priv-pages[page], KM_IRQ0); - memcpy(d, s, PAGE_SIZE); - kunmap_atomic(s, KM_IRQ0); + s = io_mapping_map_atomic_wc(dev_priv-mm.gtt_mapping, +reloc_offset, +KM_IRQ0); + memcpy_fromio(d, s, PAGE_SIZE); + io_mapping_unmap_atomic(s, KM_IRQ0); local_irq_restore(flags); + dst-pages[page] = d; + + reloc_offset += PAGE_SIZE; } dst-page_count = page_count; dst-gtt_offset = src_priv-gtt_offset; @@ -612,18 +623,57 @@ static void i915_capture_error_state(struct drm_device *dev) if (batchbuffer[1] == NULL error-acthd = obj_priv-gtt_offset - error-acthd obj_priv-gtt_offset + obj-size - batchbuffer[0] != obj) + error-acthd obj_priv-gtt_offset + obj-size) batchbuffer[1] = obj; count++; } + /* Scan the other lists for completeness for those bizarre errors. */ + if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { + list_for_each_entry(obj_priv, dev_priv-mm.flushing_list, list) { + struct drm_gem_object *obj = obj_priv-base; + + if (batchbuffer[0] == NULL + bbaddr = obj_priv-gtt_offset + bbaddr obj_priv-gtt_offset + obj-size) + batchbuffer[0] = obj; + + if (batchbuffer[1] == NULL + error-acthd = obj_priv-gtt_offset + error-acthd obj_priv-gtt_offset + obj-size) + batchbuffer[1] = obj; + + if (batchbuffer[0] batchbuffer[1]) + break; + } + } + if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { + list_for_each_entry(obj_priv, dev_priv-mm.inactive_list, list) { + struct drm_gem_object *obj = obj_priv-base; + + if (batchbuffer[0] == NULL + bbaddr = obj_priv-gtt_offset + bbaddr obj_priv-gtt_offset + obj-size) + batchbuffer[0] = obj; + + if (batchbuffer[1] == NULL + error-acthd = obj_priv-gtt_offset + error-acthd obj_priv-gtt_offset + obj-size) + batchbuffer[1] = obj; + + if (batchbuffer[0] batchbuffer[1]) + break; + } + } /* We need to copy these to an anonymous buffer as the simplest * method to avoid being overwritten by userpace. */ error-batchbuffer[0] = i915_error_object_create(dev, batchbuffer[0]); - error-batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); + if (batchbuffer[1] != batchbuffer[0]) + error-batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); + else + error-batchbuffer[1] = NULL; /* Record the ringbuffer */ error-ringbuffer = i915_error_object_create(dev, -- 1.7.1
[Intel-gfx] [PATCH 1/2] drm, io-mapping: Specify slot to use for atomic mappings
This is required should we ever attempt to use an io-mapping where KM_USER0 is verboten, such as inside an IRQ context. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: Eric Anholt e...@anholt.net --- drivers/gpu/drm/i915/i915_gem.c|9 + drivers/gpu/drm/i915/intel_overlay.c |5 +++-- drivers/gpu/drm/nouveau/nouveau_bios.c |8 include/linux/io-mapping.h | 16 ++-- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 862ce34..4cf2789 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -496,10 +496,10 @@ fast_user_write(struct io_mapping *mapping, char *vaddr_atomic; unsigned long unwritten; - vaddr_atomic = io_mapping_map_atomic_wc(mapping, page_base); + vaddr_atomic = io_mapping_map_atomic_wc(mapping, page_base, KM_USER0); unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + page_offset, user_data, length); - io_mapping_unmap_atomic(vaddr_atomic); + io_mapping_unmap_atomic(vaddr_atomic, KM_USER0); if (unwritten) return -EFAULT; return 0; @@ -3288,7 +3288,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, reloc_offset = obj_priv-gtt_offset + reloc-offset; reloc_page = io_mapping_map_atomic_wc(dev_priv-mm.gtt_mapping, (reloc_offset - ~(PAGE_SIZE - 1))); + ~(PAGE_SIZE - 1)), + KM_USER0); reloc_entry = (uint32_t __iomem *)(reloc_page + (reloc_offset (PAGE_SIZE - 1))); reloc_val = target_obj_priv-gtt_offset + reloc-delta; @@ -3299,7 +3300,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, readl(reloc_entry), reloc_val); #endif writel(reloc_val, reloc_entry); - io_mapping_unmap_atomic(reloc_page); + io_mapping_unmap_atomic(reloc_page, KM_USER0); /* The updated presumed offset for this entry will be * copied back out to the user. diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index f26ec2f..d39aea2 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -185,7 +185,8 @@ static struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_over if (OVERLAY_NONPHYSICAL(overlay-dev)) { regs = io_mapping_map_atomic_wc(dev_priv-mm.gtt_mapping, - overlay-reg_bo-gtt_offset); + overlay-reg_bo-gtt_offset, + KM_USER0); if (!regs) { DRM_ERROR(failed to map overlay regs in GTT\n); @@ -200,7 +201,7 @@ static struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_over static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay) { if (OVERLAY_NONPHYSICAL(overlay-dev)) - io_mapping_unmap_atomic(overlay-virt_addr); + io_mapping_unmap_atomic(overlay-virt_addr, KM_USER0); overlay-virt_addr = NULL; diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index b59f348..7369b5e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -2083,11 +2083,11 @@ peek_fb(struct drm_device *dev, struct io_mapping *fb, uint32_t val = 0; if (off pci_resource_len(dev-pdev, 1)) { - uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off); + uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off, KM_USER0); val = ioread32(p); - io_mapping_unmap_atomic(p); + io_mapping_unmap_atomic(p, KM_USER0); } return val; @@ -2098,12 +2098,12 @@ poke_fb(struct drm_device *dev, struct io_mapping *fb, uint32_t off, uint32_t val) { if (off pci_resource_len(dev-pdev, 1)) { - uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off); + uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off, KM_USER0); iowrite32(val, p); wmb(); - io_mapping_unmap_atomic(p); + io_mapping_unmap_atomic(p, KM_USER0); } } diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h index 25085dd..e0ea40f 100644 --- a/include/linux/io-mapping.h +++ b/include/linux/io-mapping.h @@ -79,7 +79,9 @@ io_mapping_free(struct io_mapping
[Intel-gfx] [PATCH] drm/i915/sdvo: Markup a few constant strings.
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_sdvo.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index ccf6574..234c856 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -50,7 +50,7 @@ #define IS_TV_OR_LVDS(c) (c-output_flag (SDVO_TV_MASK | SDVO_LVDS_MASK)) -static char *tv_format_names[] = { +static const char *tv_format_names[] = { NTSC_M , NTSC_J , NTSC_443, PAL_B, PAL_D , PAL_G , PAL_H, PAL_I , PAL_M , @@ -292,7 +292,7 @@ static bool intel_sdvo_write_byte(struct intel_sdvo *intel_sdvo, int addr, u8 ch /** Mapping of command numbers to names, for debug output */ static const struct _sdvo_cmd_name { u8 cmd; - char *name; + const char *name; } sdvo_cmd_names[] = { SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET), SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS), -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Enable aspect/centering panel fitting for Ironlake.
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h |2 + drivers/gpu/drm/i915/intel_display.c | 16 +++ drivers/gpu/drm/i915/intel_lvds.c| 70 -- 3 files changed, 75 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ad8dab5..6da15d8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -610,6 +610,8 @@ typedef struct drm_i915_private { struct sdvo_device_mapping sdvo_mappings[2]; /* indicate whether the LVDS_BORDER should be enabled or not */ unsigned int lvds_border_bits; + /* Panel fitter placement and size for Ironlake+ */ + u32 pch_pf_pos, pch_pf_size; struct drm_crtc *plane_to_crtc_mapping[2]; struct drm_crtc *pipe_to_crtc_mapping[2]; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 07f893f..9b5fab4 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1914,15 +1914,13 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) /* Enable panel fitting for LVDS */ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) || HAS_eDP || intel_pch_has_edp(crtc)) { - temp = I915_READ(pf_ctl_reg); - I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); - - /* currently full aspect */ - I915_WRITE(pf_win_pos, 0); - - I915_WRITE(pf_win_size, - (dev_priv-panel_fixed_mode-hdisplay 16) | - (dev_priv-panel_fixed_mode-vdisplay)); + if (dev_priv-pch_pf_size) { + temp = I915_READ(pf_ctl_reg); + I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); + I915_WRITE(pf_win_pos, dev_priv-pch_pf_pos); + I915_WRITE(pf_win_size, dev_priv-pch_pf_size); + } else + I915_WRITE(pf_ctl_reg, temp ~PF_ENABLE); } /* Enable CPU pipe */ diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 312ac30..abbe32e 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -218,6 +218,68 @@ static inline u32 panel_fitter_scaling(u32 source, u32 target) return (FACTOR * ratio + FACTOR/2) / FACTOR; } +static bool +intel_pch_lvds_mode_fixup(struct intel_lvds *intel_lvds, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct drm_device *dev = intel_lvds-base.enc.dev; + struct drm_i915_private *dev_priv = dev-dev_private; + struct drm_display_mode *fixed_mode = dev_priv-panel_fixed_mode; + int x, y, width, height; + + x = y = width = height = 0; + + /* Native modes don't need fitting */ + if (adjusted_mode-hdisplay == mode-hdisplay + adjusted_mode-vdisplay == mode-vdisplay) + goto done; + + switch (intel_lvds-fitting_mode) { + case DRM_MODE_SCALE_CENTER: + width = mode-hdisplay; + height = mode-vdisplay; + x = (fixed_mode-hdisplay - width + 1)/2; + y = (fixed_mode-vdisplay - height + 1)/2; + break; + + case DRM_MODE_SCALE_ASPECT: + /* Scale but preserve the aspect ratio */ + { + u32 scaled_width = fixed_mode-hdisplay * mode-vdisplay; + u32 scaled_height = mode-hdisplay * fixed_mode-vdisplay; + if (scaled_width scaled_height) { /* pillar */ + width = scaled_height / mode-vdisplay; + x = (fixed_mode-hdisplay - width + 1) / 2; + y = 0; + height = fixed_mode-vdisplay; + } else if (scaled_width scaled_height) { /* letter */ + height = scaled_width / mode-hdisplay; + y = (fixed_mode-vdisplay - height + 1) / 2; + x = 0; + width = fixed_mode-hdisplay; + } else { + x = y = 0; + width = fixed_mode-hdisplay; + height = fixed_mode-vdisplay; + } + } + break; + + default: + case DRM_MODE_SCALE_FULLSCREEN: + x = y = 0; + width = fixed_mode-hdisplay; + height = fixed_mode-vdisplay; +
[Intel-gfx] Small ringbuffer cleanup
The goal here is to simplify the ringbuffer emission so that we can avoid the function call overhead when writing into the ringbuffer. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 3/4] drm/i915: Inline ringbuffer_emit()
As the function has been reduced to a store plus increment, the body is now smaller than the call so inline it. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_ringbuffer.c |8 drivers/gpu/drm/i915/intel_ringbuffer.h | 12 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index c153d4e..3a02425 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -755,14 +755,6 @@ void intel_ring_begin(struct drm_device *dev, ring-space -= n; } -void intel_ring_emit(struct drm_device *dev, - struct intel_ring_buffer *ring, unsigned int data) -{ - unsigned int *virt = ring-virtual_start + ring-tail; - *virt = data; - ring-tail += 4; -} - void intel_ring_advance(struct drm_device *dev, struct intel_ring_buffer *ring) { diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index a242bcb..525e7d3 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -105,8 +105,16 @@ int intel_wrap_ring_buffer(struct drm_device *dev, struct intel_ring_buffer *ring); void intel_ring_begin(struct drm_device *dev, struct intel_ring_buffer *ring, int n); -void intel_ring_emit(struct drm_device *dev, - struct intel_ring_buffer *ring, u32 data); + +static inline void intel_ring_emit(struct drm_device *dev, + struct intel_ring_buffer *ring, + unsigned int data) +{ + unsigned int *virt = ring-virtual_start + ring-tail; + *virt = data; + ring-tail += 4; +} + void intel_fill_struct(struct drm_device *dev, struct intel_ring_buffer *ring, void *data, -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 4/4] drm/i915: Use an uncommon name for the local dev_priv in macros
Using dev_priv__ avoids sparse complaining about shadowed variables in the *LP_RING() macros. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 14 +++--- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6da15d8..392dcb8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1102,26 +1102,26 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); #define I915_VERBOSE 0 #define BEGIN_LP_RING(n) do { \ - drm_i915_private_t *dev_priv = dev-dev_private;\ + drm_i915_private_t *dev_priv__ = dev-dev_private;\ if (I915_VERBOSE) \ DRM_DEBUG( BEGIN_LP_RING %x\n, (int)(n)); \ - intel_ring_begin(dev, dev_priv-render_ring, (n)); \ + intel_ring_begin(dev, dev_priv__-render_ring, (n)); \ } while (0) #define OUT_RING(x) do { \ - drm_i915_private_t *dev_priv = dev-dev_private;\ + drm_i915_private_t *dev_priv__ = dev-dev_private; \ if (I915_VERBOSE) \ DRM_DEBUG( OUT_RING %x\n, (int)(x));\ - intel_ring_emit(dev, dev_priv-render_ring, x);\ + intel_ring_emit(dev, dev_priv__-render_ring, x); \ } while (0) #define ADVANCE_LP_RING() do { \ - drm_i915_private_t *dev_priv = dev-dev_private;\ + drm_i915_private_t *dev_priv__ = dev-dev_private;\ if (I915_VERBOSE) \ DRM_DEBUG(ADVANCE_LP_RING %x\n, \ - dev_priv-render_ring.tail);\ - intel_ring_advance(dev, dev_priv-render_ring);\ + dev_priv__-render_ring.tail); \ + intel_ring_advance(dev, dev_priv__-render_ring); \ } while(0) /** -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/4] drm/i915: Unroll wrapping of the ringbuffer.
The tail is quadword aligned, so we can add two MI_NOOP as a time. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_ringbuffer.c |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index f914c42..b5ccee5 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -702,9 +702,11 @@ int intel_wrap_ring_buffer(struct drm_device *dev, } virt = (unsigned int *)(ring-virtual_start + ring-tail); - rem /= 4; - while (rem--) + rem /= 8; + while (rem--) { *virt++ = MI_NOOP; + *virt++ = MI_NOOP; + } ring-tail = 0; ring-space = ring-head - 8; -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Write to display base last.
Writing to the DSPBASE register triggers the double-buffered update to all the control registers, so always write it last in the update sequence. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c |6 ++ 1 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9b5fab4..f9d88c2 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1486,15 +1486,13 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, Start, Offset, x, y, crtc-fb-pitch); I915_WRITE(dspstride, crtc-fb-pitch); if (IS_I965G(dev)) { - I915_WRITE(dspbase, Offset); - I915_READ(dspbase); I915_WRITE(dspsurf, Start); - I915_READ(dspsurf); I915_WRITE(dsptileoff, (y 16) | x); + I915_WRITE(dspbase, Offset); } else { I915_WRITE(dspbase, Start + Offset); - I915_READ(dspbase); } + POSTING_READ(dspbase); if ((IS_I965G(dev) || plane == 0)) intel_update_fbc(crtc, crtc-mode); -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: report all active objects as busy
Incorporates a similar patch by Daniel Vetter, the alteration being to report the current busy state after retiring. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc : Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_gem.c | 40 +- 1 files changed, 26 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f599d77..909e727 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4163,22 +4163,34 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, } mutex_lock(dev-struct_mutex); - /* Update the active list for the hardware's current position. -* Otherwise this only updates on a delayed timer or when irqs are -* actually unmasked, and our working set ends up being larger than -* required. -*/ - i915_gem_retire_requests(dev); - obj_priv = to_intel_bo(obj); - /* Don't count being on the flushing list against the object being -* done. Otherwise, a buffer left on the flushing list but not getting -* flushed (because nobody's flushing that domain) won't ever return -* unbusy and get reused by libdrm's bo cache. The other expected -* consumer of this interface, OpenGL's occlusion queries, also specs -* that the objects get unbusy eventually without any interference. + /* Count all active objects as busy, even if they are currently not used +* by the gpu. Users of this interface expect objects to eventually +* become non-busy without any further actions, therefore emit any +* necessary flushes here. */ - args-busy = obj_priv-active obj_priv-last_rendering_seqno != 0; + obj_priv = to_intel_bo(obj); + args-busy = obj_priv-active; + if (args-busy) { + /* Unconditionally flush objects, even when the gpu still uses this +* object. Userspace calling this function indicates that it wants to +* use this buffer rather sooner than later, so issuing the required +* flush earlier is beneficial. +*/ + if (obj-write_domain) { + i915_gem_flush(dev, 0, obj-write_domain); + (void)i915_add_request(dev, file_priv, obj-write_domain, obj_priv-ring); + } + + /* Update the active list for the hardware's current position. +* Otherwise this only updates on a delayed timer or when irqs +* are actually unmasked, and our working set ends up being +* larger than required. +*/ + i915_gem_retire_requests_ring(dev, obj_priv-ring); + + args-busy = obj_priv-active; + } drm_gem_object_unreference(obj); mutex_unlock(dev-struct_mutex); -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Capture the overlay status upon a GPU hang.
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c |3 + drivers/gpu/drm/i915/i915_drv.h | 10 +++- drivers/gpu/drm/i915/i915_irq.c |3 + drivers/gpu/drm/i915/intel_overlay.c | 85 ++ 4 files changed, 99 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 08f279b..8e09931 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -488,6 +488,9 @@ static int i915_error_state(struct seq_file *m, void *unused) } } + if (error-overlay) + intel_overlay_print_error_state(m, error-overlay); + out: spin_unlock_irqrestore(dev_priv-error_lock, flags); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 392dcb8..1787e06 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -113,6 +113,9 @@ struct intel_opregion { int enabled; }; +struct intel_overlay; +struct intel_overlay_error_state; + struct drm_i915_master_private { drm_local_map_t *sarea; struct _drm_i915_sarea *sarea_priv; @@ -166,6 +169,7 @@ struct drm_i915_error_state { u32 purgeable:1; } *active_bo; u32 active_bo_count; + struct intel_overlay_error_state *overlay; }; struct drm_i915_display_funcs { @@ -186,8 +190,6 @@ struct drm_i915_display_funcs { /* clock gating init */ }; -struct intel_overlay; - struct intel_device_info { u8 is_mobile : 1; u8 is_i8xx : 1; @@ -1076,6 +1078,10 @@ extern bool ironlake_set_drps(struct drm_device *dev, u8 val); extern void intel_detect_pch (struct drm_device *dev); extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); +/* overlay */ +extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); +extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error); + /** * Lock test for when it's just for synchronization of ring access. * diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 8aed608..5161cea 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -500,6 +500,7 @@ i915_error_state_free(struct drm_device *dev, i915_error_object_free(error-batchbuffer[1]); i915_error_object_free(error-ringbuffer); kfree(error-active_bo); + kfree(error-overlay); kfree(error); } @@ -717,6 +718,8 @@ static void i915_capture_error_state(struct drm_device *dev) do_gettimeofday(error-time); + error-overlay = intel_overlay_capture_error_state(dev); + spin_lock_irqsave(dev_priv-error_lock, flags); if (dev_priv-first_error == NULL) { dev_priv-first_error = error; diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index d39aea2..f11ea5c 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -1416,3 +1416,88 @@ void intel_cleanup_overlay(struct drm_device *dev) kfree(dev_priv-overlay); } } + +struct intel_overlay_error_state { + struct overlay_registers regs; + u32 status; +}; + +struct intel_overlay_error_state * +intel_overlay_capture_error_state(struct drm_device *dev) +{ +drm_i915_private_t *dev_priv = dev-dev_private; + struct intel_overlay_error_state *error; + struct overlay_registers __iomem *regs; + + if (!dev_priv-overlay || !dev_priv-overlay-active) + return NULL; + + error = kmalloc(sizeof(*error), GFP_ATOMIC); + if (error == NULL) + return NULL; + + error-status = I915_READ(DOVSTA); + + regs = intel_overlay_map_regs_atomic(dev_priv-overlay); + if (!regs) + goto err; + + memcpy_fromio(error-regs, regs, sizeof(struct overlay_registers)); + intel_overlay_unmap_regs_atomic(dev_priv-overlay); + + return error; + +err: + kfree(error); + return NULL; +} + +void +intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error) +{ + seq_printf(m, Overlay, status: 0x%08x\n, error-status); + +#define P(x) seq_printf(m,#x : 0x%08x\n, error-regs.x) + P(OBUF_0Y); + P(OBUF_1Y); + P(OBUF_0U); + P(OBUF_0V); + P(OBUF_1U); + P(OBUF_1V); + P(OSTRIDE); + P(YRGB_VPH); + P(UV_VPH); + P(HORZ_PH); + P(INIT_PHS); + P(DWINPOS); + P(DWINSZ); + P(SWIDTH); + P(SWIDTHSW); + P(SHEIGHT); + P(YRGBSCALE); + P(UVSCALE); + P(OCLRC0); + P(OCLRC1); + P(DCLRKV); + P(DCLRKM); + P(SCLRKVH); + P(SCLRKVL); + P(SCLRKEN); + P(OCONFIG); + P(OCMD); + P(OSTART_0Y); +
[Intel-gfx] [PATCH] drm/i915: Truncate the inode as well as the backing pages on purge
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4cf2789..f599d77 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1497,6 +1497,7 @@ i915_gem_object_truncate(struct drm_gem_object *obj) struct inode *inode; inode = obj-filp-f_path.dentry-d_inode; + truncate_inode_pages(inode-i_mapping, 0); if (inode-i_op-truncate) inode-i_op-truncate (inode); -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: report all active objects as busy
On Wed, Aug 04, 2010 at 08:57:26PM +0200, Daniel Vetter wrote: On Wed, Aug 04, 2010 at 03:36:30PM +0100, Chris Wilson wrote: Incorporates a similar patch by Daniel Vetter, the alteration being to report the current busy state after retiring. Woot, nice idea to exactly preserve the semantics of the old implementation. /me bangs the head against the wall for not coming up with this myself Reviewed-by: Daniel Vetter daniel.vet...@ffwll.ch Chris thought that given how much his patch looks like mine, a s-o-b is more appropriated: Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/2] drm/i915: fixup pageflip ringbuffer commands for i8xx
Add a new path for 2nd gen chips that uses the commands for i81x chips (where public docs do exist) augmented with the plane bits from i915. It seems to work and doesn't result in a black screen like before. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Cc: sta...@kernel.org --- drivers/gpu/drm/i915/intel_display.c |8 +++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8359c50..8135ee0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4933,12 +4933,18 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, OUT_RING(obj_priv-gtt_offset | obj_priv-tiling_mode); pipesrc = I915_READ(pipesrc_reg); OUT_RING(pipesrc 0x0fff0fff); - } else { + } else if (IS_GEN3(dev)) { OUT_RING(MI_DISPLAY_FLIP_I915 | MI_DISPLAY_FLIP_PLANE(intel_crtc-plane)); OUT_RING(fb-pitch); OUT_RING(obj_priv-gtt_offset); OUT_RING(MI_NOOP); + } else { + OUT_RING(MI_DISPLAY_FLIP | +MI_DISPLAY_FLIP_PLANE(intel_crtc-plane)); + OUT_RING(fb-pitch); + OUT_RING(obj_priv-gtt_offset); + OUT_RING(MI_NOOP); } ADVANCE_LP_RING(); -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Capture the overlay status upon a GPU hang.
On Wed, Aug 04, 2010 at 08:26:07PM +0100, Chris Wilson wrote: v2: Add the interrupt status and address. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Daniel Vetter daniel.vet...@ffwll.ch -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 1/2] drm/i915: fixup pageflip ringbuffer commands for i8xx
On Wed, 4 Aug 2010 21:22:09 +0200 Daniel Vetter daniel.vet...@ffwll.ch wrote: Add a new path for 2nd gen chips that uses the commands for i81x chips (where public docs do exist) augmented with the plane bits from i915. It seems to work and doesn't result in a black screen like before. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Cc: sta...@kernel.org --- drivers/gpu/drm/i915/intel_display.c |8 +++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8359c50..8135ee0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4933,12 +4933,18 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, OUT_RING(obj_priv-gtt_offset | obj_priv-tiling_mode); pipesrc = I915_READ(pipesrc_reg); OUT_RING(pipesrc 0x0fff0fff); - } else { + } else if (IS_GEN3(dev)) { OUT_RING(MI_DISPLAY_FLIP_I915 | MI_DISPLAY_FLIP_PLANE(intel_crtc-plane)); OUT_RING(fb-pitch); OUT_RING(obj_priv-gtt_offset); OUT_RING(MI_NOOP); + } else { + OUT_RING(MI_DISPLAY_FLIP | + MI_DISPLAY_FLIP_PLANE(intel_crtc-plane)); + OUT_RING(fb-pitch); + OUT_RING(obj_priv-gtt_offset); + OUT_RING(MI_NOOP); } ADVANCE_LP_RING(); Yep, looks fine. Reviewed-by: Jesse Barnes jbar...@virtuousgeek.org -- Jesse Barnes, 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 2/2] drm/i915: i8xx also doesn't like multiple oustanding pageflips
On Wed, 4 Aug 2010 21:22:10 +0200 Daniel Vetter daniel.vet...@ffwll.ch wrote: My i855GM suffers from a 80k/s interrupt storm without this. So add 2nd gen to the list of things that don't like more than one outstanding pageflip request. Furthermore I've changed the busy loop into a ringbuffer wait. Busy-loops that don't check whether the chip died are simply evil. And performance should actually improve, because there's usually a decent amount of rendering queued on the gpu, hopefully rendering that MI_WAIT into a noop by the time it's executed. The current code holds dev-struct_mutex while executing this loop, hence stalling all other gem activity anyway. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Cc: sta...@kernel.org --- drivers/gpu/drm/i915/intel_display.c | 13 - 1 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8135ee0..7b6035e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4916,14 +4916,17 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, work-pending_flip_obj = obj; if (intel_crtc-plane) - flip_mask = I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; + flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; else - flip_mask = I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT; + flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; /* Wait for any previous flip to finish */ - if (IS_GEN3(dev)) - while (I915_READ(ISR) flip_mask) - ; + if (IS_GEN3(dev) || IS_GEN2(dev)) { + BEGIN_LP_RING(2); + OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); + OUT_RING(0); + ADVANCE_LP_RING(); + } BEGIN_LP_RING(4); if (IS_I965G(dev)) { This looks nicer than what was there before. Hope it still works on 9xx... Reviewed-by: Jesse Barnes jbar...@virtuousgeek.org -- Jesse Barnes, 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 4/5] drm/i915: Implement fair lru eviction across both rings.
On Wed, Aug 04, 2010 at 12:20:36PM +0100, Chris Wilson wrote: Based in a large part upon Daniel Vetter's implementation and adapted for handling multiple rings in a single pass. I've thought some more about this and I'm not sold on the idea that your One Scan to Rule Them All is any fairer than simply looping through all outstanding requests, like this: 1. (Re-)scan the inactive list and return the hole if found. 2. If there are any outstanding requests, wait for one to finish (on any ring), then go back to 1. 3. If there are no more outstanding requests issue a full gpu flush and wait, then go back to 2. 4. All hope is lost (and even evict_everything shouldn't be able to pull of miracles), return NULL. This way active buffers are scanned in retiring order, whereas your code scans them in issuing order. IMHO the former is the fairer approach for eviction when both rings are busy. I also think the code would look slightly less scary ;) Of course, this way we scan the inactive lru list completely for every outstanding request. But I don't think that's a problem because a) the current code does it, too, and b) we're stalling already, so there should be enough cpu power available. -Daniel -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 2/2] drm/i915: i8xx also does not like multiple oustanding pageflips
On Wed, Aug 04, 2010 at 09:06:46PM +0100, Chris Wilson wrote: If you move the if(intel_crtc-plane) inside the gen2/3 block, then I'll test it on my netbooks. :) I believe the compiler will happily do that for you ;) Starting to look like intel_overlay.c ;-) Well, that's actually one of the things on my idea for drm/i915 projects: To unify the overlay/display plane pageflip support code. -Daniel -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 2/2] drm/i915: i8xx also doesn't like multiple oustanding pageflips
On 4 August 2010 20:49, Jesse Barnes jbar...@virtuousgeek.org wrote: On Wed, 4 Aug 2010 21:22:10 +0200 Daniel Vetter daniel.vet...@ffwll.ch wrote: My i855GM suffers from a 80k/s interrupt storm without this. So add 2nd gen to the list of things that don't like more than one outstanding pageflip request. Furthermore I've changed the busy loop into a ringbuffer wait. Busy-loops that don't check whether the chip died are simply evil. And performance should actually improve, because there's usually a decent amount of rendering queued on the gpu, hopefully rendering that MI_WAIT into a noop by the time it's executed. The current code holds dev-struct_mutex while executing this loop, hence stalling all other gem activity anyway. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Cc: sta...@kernel.org --- drivers/gpu/drm/i915/intel_display.c | 13 - 1 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8135ee0..7b6035e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4916,14 +4916,17 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, work-pending_flip_obj = obj; if (intel_crtc-plane) - flip_mask = I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; + flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; else - flip_mask = I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT; + flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; /* Wait for any previous flip to finish */ - if (IS_GEN3(dev)) - while (I915_READ(ISR) flip_mask) - ; + if (IS_GEN3(dev) || IS_GEN2(dev)) { + BEGIN_LP_RING(2); + OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); + OUT_RING(0); + ADVANCE_LP_RING(); + } BEGIN_LP_RING(4); if (IS_I965G(dev)) { This looks nicer than what was there before. Hope it still works on 9xx... Reviewed-by: Jesse Barnes jbar...@virtuousgeek.org -- Jesse Barnes, Intel Open Source Technology Center ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx Just to warn: you sent the patch to the wrong address (sta...@kernel.org instead of sta...@kernel.org). Regards, Pedro ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 4/5] drm/i915: Implement fair lru eviction across both rings.
On Wed, 4 Aug 2010 22:16:58 +0200, Daniel Vetter dan...@ffwll.ch wrote: This way active buffers are scanned in retiring order, whereas your code scans them in issuing order. IMHO the former is the fairer approach for eviction when both rings are busy. I also think the code would look slightly less scary ;) Hmm, I was aiming for retiring order, I may have missed. But yes, the true goal is for this to be clear from the code, and here my preference was for unrolling the loop so that the order was apparent. Obviously I have failed on one or both accounts. -- 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] drm/i915: Enable aspect/centering panel fitting for Ironlake.
On 2010.08.04 15:04:01 +0100, Chris Wilson wrote: Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h |2 + drivers/gpu/drm/i915/intel_display.c | 16 +++ drivers/gpu/drm/i915/intel_lvds.c| 70 -- 3 files changed, 75 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ad8dab5..6da15d8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -610,6 +610,8 @@ typedef struct drm_i915_private { struct sdvo_device_mapping sdvo_mappings[2]; /* indicate whether the LVDS_BORDER should be enabled or not */ unsigned int lvds_border_bits; + /* Panel fitter placement and size for Ironlake+ */ + u32 pch_pf_pos, pch_pf_size; struct drm_crtc *plane_to_crtc_mapping[2]; struct drm_crtc *pipe_to_crtc_mapping[2]; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 07f893f..9b5fab4 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1914,15 +1914,13 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) /* Enable panel fitting for LVDS */ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) || HAS_eDP || intel_pch_has_edp(crtc)) { - temp = I915_READ(pf_ctl_reg); - I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); - - /* currently full aspect */ - I915_WRITE(pf_win_pos, 0); - - I915_WRITE(pf_win_size, -(dev_priv-panel_fixed_mode-hdisplay 16) | -(dev_priv-panel_fixed_mode-vdisplay)); + if (dev_priv-pch_pf_size) { + temp = I915_READ(pf_ctl_reg); + I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); + I915_WRITE(pf_win_pos, dev_priv-pch_pf_pos); + I915_WRITE(pf_win_size, dev_priv-pch_pf_size); + } else + I915_WRITE(pf_ctl_reg, temp ~PF_ENABLE); } So this breaks panel fitting setting on eDP... -- Open Source Technology Center, Intel ltd. $gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827 signature.asc Description: Digital signature ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] hotplug CRT detection
So I've been reviewing the i915/ironlake CRT detect code and am a bit confused. I though on the i945 and above that we had proper CRT hotplug detection with an IRQ, that didn't require any polling. Now looking at the code when we do a CRT detect, the first thing we do is try the hotplug method, however on ILK/SNB this is crap and requires powering off the ADPA, which turns off the monitor, if that fails we fallback to DDC probing which is pretty non-destructive. I get the feeling the whole hotplug detect code is pointless if the hardware is already meant to send us an IRQ when something happens, or at least I think the DDC probe should be than the hotplug probe if the hotplug probe is too remain destructive. Dave. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx