Re: [Intel-gfx] [PATCH] drm/i915: fix tiling limits for i915 class hw
On Thu, 15 Apr 2010 09:08:16 +0200, Daniel Vetter daniel.vet...@ffwll.ch wrote: Current code is definitely crap: Largest pitch allowed spills into the TILING_Y bit of the fence registers ... :( I've rewritten the limits check under the assumption that 3rd gen hw has a 3d pitch limit of 8kb (like 2nd gen). This is supported by an otherwise totally misleading XXX comment. Good catch Daniel! Hopefully we must be soon running out of tiling bugs. It does - the fence pitch limit is 8KiB for both 512- and 128-wide tiles. In the 128 byte case the max pitch value is 64, and correspondingly the max pitch value is 16 for 512 byte wide tiles. -ickle -- 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 1/2] drm/i915: check execbuffer for validity earlier to save on work.
On Thu, 22 Apr 2010 22:38:41 +0100, Owain G. Ainsworth zer...@googlemail.com wrote: Before, we were waiting until we knew the batch object's gtt offset before we checked for validity. However, since this is purely an alignment check (it is impossible for the batch object to get to execbuffer stage without being pinned and bound) we can check alignment before we do any other expensive work. Additionally, check that batch_start_offset + batch_len is = the size of the batchbuffer object. And that batch_len and batch_start_offset do not overflow a u_int32_t. Signed-off-by: Owain G. Ainsworth o...@openbsd.org Minor comment inline. Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 42 ++ 1 files changed, 16 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b85727c..a9da182 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3656,23 +3656,6 @@ err: return ret; } -static int -i915_gem_check_execbuffer (struct drm_i915_gem_execbuffer2 *exec, -uint64_t exec_offset) -{ - uint32_t exec_start, exec_len; - - exec_start = (uint32_t) exec_offset + exec-batch_start_offset; - exec_len = (uint32_t) exec-batch_len; - - if ((exec_start | exec_len) 0x7) - return -EINVAL; - - if (!exec_start) - return -EINVAL; - - return 0; -} static int i915_gem_wait_for_pending_flip(struct drm_device *dev, @@ -3722,7 +3705,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, struct drm_clip_rect *cliprects = NULL; struct drm_i915_gem_relocation_entry *relocs = NULL; int ret = 0, ret2, i, pinned = 0; - uint64_t exec_offset; uint32_t seqno, flush_domains, reloc_index; int pin_tries, flips; @@ -3730,6 +3712,16 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, DRM_INFO(buffers_ptr %d buffer_count %d len %08x\n, (int) args-buffers_ptr, args-buffer_count, args-batch_len); #endif + /* + * check for valid execbuffer offset. We can do this early because + * bound objects are always page aligned, so only the start offset + * matters. Also check for overflow. + */ + if ((args-batch_start_offset | args-batch_len) 0x7 || + args-batch_start_offset + args-batch_len args-batch_len || + args-batch_start_offset + args-batch_len + args-batch_start_offset) + return -EINVAL; A minor critique, can we move this predicate into an inline for the sake of the reader? i915_gem_check_execbuffer_offset(args) perhaps? -ickle -- 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 2/2] drm/i915: Remove the bind in mmap_gtt_ioctl
On Thu, 22 Apr 2010 22:38:42 +0100, Owain G. Ainsworth zer...@googlemail.com wrote: It really won't affect faulting speed at all, and in rare cases may do more than we needed in the first place. If we do need to map and we aren't bound it will take *just as long* when the mmap happens as it would on the ioctl being called. Discussed with danvet and jbarnes. Signed-Off-By: Owain G. Ainsworth o...@openbsd.org Acked-by: Chris Wilson ch...@chris-wilson.co.uk -ickle -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Mark the object as dirty when setting to the CPU write domain.
Or else we may not write back the written pages upon unbind. For example the contents of a batch buffer written using a simple mmap or using shmmem pwrite may be discarded if we are forced to evict everything whilst pinning the objects for execbuffer. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: sta...@kernel.org --- 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 f04612f..5d60c3b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3076,6 +3076,7 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write) if (write) { obj-read_domains = I915_GEM_DOMAIN_CPU; obj-write_domain = I915_GEM_DOMAIN_CPU; + obj_priv-dirty = 1; } trace_i915_gem_object_change_domain(obj, -- 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: Protect mmaped buffers from casual eviction.
By keeping buffers that are in use by the CPU, having been mmapped and moved to the CPU or GTT domain since their last rendering on a separate inactive list, prevents the first-pass eviction process from unbinding one of these buffers. Those buffers are evicted as normal during evict-everything so that the memory can be recovered under high pressure or a forced idle. References: Bug 20152 - [G45/GM965 UXA] cannot view JPG in firefox when running UXA https://bugs.freedesktop.org/show_bug.cgi?id=20152 Bug 24369 - Hang when scrolling firefox page with window in front https://bugs.freedesktop.org/show_bug.cgi?id=24369 Bug 15911 - Intermittent X crash (freeze) https://bugzilla.kernel.org/show_bug.cgi?id=15911 Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Tested-by: Christian von Schultz ker...@vonschultz.se --- drivers/gpu/drm/i915/i915_drv.h | 13 +++ drivers/gpu/drm/i915/i915_gem.c | 71 ++ 2 files changed, 76 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 317c9bf..f99936f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -557,6 +557,19 @@ typedef struct drm_i915_private { */ struct list_head inactive_list; + /** +* LRU list of objects which are not in the ringbuffer and +* are ready to unbind, but are still in the GTT and currently +* mapped and in use by the CPU. +* +* last_rendering_seqno is 0 while an object is in this list. +* +* A reference is not held on the buffer while on this list, +* as merely being GTT-bound shouldn't prevent its being +* freed, and we'll pull it off the list in the free path. +*/ + struct list_head mmap_list; + /** LRU list of objects with fence regs on them. */ struct list_head fence_list; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 229354e..9a73b20 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -52,6 +52,7 @@ static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, 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_from_inactive_list(struct drm_device *dev); +static int i915_gem_evict_from_mmap_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); @@ -1064,6 +1065,9 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); } + if (ret == 0 obj_priv-gtt_space !obj_priv-active) + list_move_tail(obj_priv-list, dev_priv-mm.mmap_list); + drm_gem_object_unreference(obj); mutex_unlock(dev-struct_mutex); return ret; @@ -1197,6 +1201,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.mmap_list); + pfn = ((dev-agp-base + obj_priv-gtt_offset) PAGE_SHIFT) + page_offset; @@ -2162,7 +2169,8 @@ i915_gem_evict_everything(struct drm_device *dev) bool lists_empty; spin_lock(dev_priv-mm.active_list_lock); - lists_empty = (list_empty(dev_priv-mm.inactive_list) + lists_empty = (list_empty(dev_priv-mm.mmap_list) + list_empty(dev_priv-mm.inactive_list) list_empty(dev_priv-mm.flushing_list) list_empty(dev_priv-mm.active_list)); spin_unlock(dev_priv-mm.active_list_lock); @@ -2177,12 +2185,17 @@ i915_gem_evict_everything(struct drm_device *dev) BUG_ON(!list_empty(dev_priv-mm.flushing_list)); + ret = i915_gem_evict_from_mmap_list(dev); + if (ret) + return ret; + ret = i915_gem_evict_from_inactive_list(dev); if (ret) return ret; spin_lock(dev_priv-mm.active_list_lock); - lists_empty = (list_empty(dev_priv-mm.inactive_list) + lists_empty = (list_empty(dev_priv-mm.mmap_list) + list_empty(dev_priv-mm.inactive_list) list_empty(dev_priv-mm.flushing_list) list_empty(dev_priv-mm.active_list)); spin_unlock(dev_priv-mm.active_list_lock); @@ -4624,17 +4637,15 @@ void i915_gem_free_object(struct drm_gem_object *obj) kfree(obj-driver_private); } -/** Unbinds all inactive objects. */ static
Re: [Intel-gfx] [PATCH] drm/i915: Protect mmaped buffers from casual eviction.
On Tue, 11 May 2010 09:38:36 -0700, Eric Anholt e...@anholt.net wrote: Couldn't this be more easily handled by the times where you would move to the tail of mmap, just move to the tail of inactive? Since inactive is obj_priv-gtt_space !obj_priv-active already. The real issue is the inactive list is no longer evicted in LRU, otherwise just moving to the end of inactive list would be ideal. In benchmarks it is faster to evict the appropriately sized object rather than iterate over the inactive list until enough contiguous space has been freed. The consequence is that the page-fault-of-doom is reintroduced unless some measure is taken to avoid it. I don't have any figures to suggest what the average size of the mmap_list will be. As an object is only on the list until it is used or evict-everything, then the list should be kept quite short. As our drivers improve, the frequency at which we have to mmap buffers should reduce as well... -ickle -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Fail to load driver if KMS request without GEM
The i915's implementation of KMS requires GEM in order to manage the memory and execution domains of the framebuffer and associated resources. By the point at which we detect broken a BIOS and need to disable GEM, we have already registered ourselves as a KMS driver with several subsystems. Rather than introducing a fragile unwind and attempt to continue with UMS, spit out an error and unload the driver. References: [Bug 15754] IP: [a0207589] drm_mm_search_free+0x49/0x90 [drm] BUG: unable to handle kernel NULL pointer dereference at (null) https://bugzilla.kernel.org/show_bug.cgi?id=15754 [drm:i915_driver_load] *ERROR* Detected broken video BIOS with 262140/262144kB of video memory stolen. [drm:i915_driver_load] *ERROR* Disabling GEM. (try reducing stolen memory or updating the BIOS to fix). i915 :00:02.0: irq 30 for MSI/MSI-X [drm] set up 255M of stolen space BUG: unable to handle kernel NULL pointer dereference at (null) IP: [a0207589] drm_mm_search_free+0x49/0x90 [drm] PGD 69719067 PUD 69dda067 PMD 0 Oops: [#1] PREEMPT SMP last sysfs file: /sys/module/snd_seq_oss/initstate CPU 1 Pid: 867, comm: modprobe Not tainted 2.6.33-ARCH #1 G43Twins-FullHD/To Be Filled By O.E.M. RIP: 0010:[a0207589] [a0207589] drm_mm_search_free+0x49/0x90 [drm] RSP: 0018:8800699f3af8 EFLAGS: 00010246 RAX: RBX: RCX: RDX: 1000 RSI: 1000 RDI: 8800693d0f78 RBP: 8800699f3b18 R08: 1000 R09: R10: R11: R12: 880068de70c0 R13: 1000 R14: R15: 8800689cb000 FS: 7fa93f4e5700() GS:88000188() knlGS: CS: 0010 DS: ES: CR0: 80050033 CR2: CR3: 695a CR4: 000406e0 DR0: DR1: DR2: DR3: DR6: 0ff0 DR7: 0400 Process modprobe (pid: 867, threadinfo 8800699f2000, task 8800694f4740) Stack: 880068de73c0 880068de70c0 8800689cb000 1000 0 8800699f3b68 a0299f63 8800693d0f78 120068de70c0 0 8800689cb000 880068de73c0 880068de70c0 8800689cb000 Call Trace: [a0299f63] i915_gem_object_bind_to_gtt+0x83/0x360 [i915] [a029a2e5] i915_gem_object_pin+0xa5/0xb0 [i915] [a029a3c5] i915_gem_init_ringbuffer+0xd5/0x510 [i915] [a028dbee] i915_driver_load+0x4ce/0xd00 [i915] [a0205d37] ? drm_sysfs_device_add+0x87/0xb0 [drm] [a0203363] ? drm_get_minor+0x1d3/0x330 [drm] [a02037e6] drm_get_dev+0x326/0x580 [drm] [a02bc0a5] i915_pci_probe+0x10/0xd0 [i915] [811e98a2] local_pci_probe+0x12/0x20 [811ea8e0] pci_device_probe+0x80/0xb0 [8127b12a] ? driver_sysfs_add+0x5a/0x90 [8127b273] driver_probe_device+0x93/0x1a0 [8127b413] __driver_attach+0x93/0xa0 [8127b380] ? __driver_attach+0x0/0xa0 [8127a8f8] bus_for_each_dev+0x68/0x90 [8127b0c9] driver_attach+0x19/0x20 [8127a0ad] bus_add_driver+0xcd/0x2d0 [8127b718] driver_register+0x78/0x140 [811eab91] __pci_register_driver+0x51/0xd0 [a02d6000] ? i915_init+0x0/0x52 [i915] [a01fdc31] drm_init+0x111/0x120 [drm] [810eb0cd] ? register_shrinker+0x4d/0x60 [a02d6000] ? i915_init+0x0/0x52 [i915] [a02d6050] i915_init+0x50/0x52 [i915] [81002047] do_one_initcall+0x37/0x1a0 [8108ed17] sys_init_module+0xd7/0x250 [81009fc2] system_call_fastpath+0x16/0x1b Code: eb 29 49 8b 41 28 31 d2 49 f7 f5 85 d2 74 39 44 89 c0 29 d0 48 89 c2 48 01 f2 49 39 d2 73 29 0f 1f 00 49 89 da 4c 89 d3 4d 89 d9 4d 8b 19 49 39 f9 41 0f 18 0b 74 2b 4d 8b 51 30 4d 89 cc 49 39 RIP [a0207589] drm_mm_search_free+0x49/0x90 [drm] RSP 8800699f3af8 CR2: Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_dma.c |7 +++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 851a2f8..39a685e 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1672,6 +1672,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev_priv-has_gem = 0; } + if (dev_priv-has_gem == 0 + drm_core_check_feature(dev, DRIVER_MODESET)) { + DRM_ERROR(kernel modesetting requires GEM, disabling driver.\n); + ret = -ENODEV; + goto out_iomapfree; + } + dev-driver-get_vblank_counter = i915_get_vblank_counter; dev-max_vblank_count = 0xff; /* only 24 bits of frame count */ if (IS_G4X(dev) || IS_IRONLAKE(dev) || IS_GEN6(dev)) { -- 1.7.1
Re: [Intel-gfx] [PATCH 0/9] [RFC] fair-lru eviction
On Tue, 18 May 2010 23:11:42 +0200, Daniel Vetter daniel.vet...@ffwll.ch wrote: Hi all, This patch series implements the fair-lru eviction Chris Wilson already posted with a twist. It's essentially the same idea algorithm. Differnences versus his patch: - Doesn't do any allocations while scanning. - Implemented in drm_mm.c In other words, this should also be usable by ttm. The idea is simple: Scan through the lru, marking objects as evictable until there is a large area of memory free/free-able. Then walk through all the scanned objects in reverse, checking which ones fall into this hole. Finally evicting them. Comments, ideas highly welcome. The next adaptation I did was to clean up evict_something to add objects from the inactive, active!pinned!write, flushing!pinned, active!pinnedwrite lists. This reduces the logic in evict_something to a single scan over the available objects in LRU order. We still need the move-to-inactive-tail upon access by the CPU, and I think it is acceptable to maintain our preference of the GPU over the CPU. Recovering memory from the CPU is comparatively cheap. Comparing 'while :; do yes /tmp/yes; done cairo-perf-trace', there is no significant delta between the fair LRU and current. I'll rebase my evict_something() on top of your drm_mm, and rerun the tests. -- 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] 945gm: xrandr crashes X
On Tue, 25 May 2010 10:38:51 +0300, Vasily Khoruzhick anars...@gmail.com wrote: Hi, after upgrade to 2.6.34 kernel I'm unable to configure external VGA monitor anymore, any attempt to use xrandr results in X crash with following message: X: intel_bufmgr_gem.c:900: drm_intel_gem_bo_unreference_locked_timed: Assertion `((bo_gem-refcount)-atomic) 0' failed. There's a bug entry in gentoo bugzilla, however they blame xorg-server, but xorg-server-1.8.x works for me with 2.6.33.x kernel: http://bugs.gentoo.org/show_bug.cgi?id=318743 Is it known/fixed issue, or should I file a new bug on fd.o bugzilla? commit 9f54107f866a25cf670f81f7c52b8c108728c6a5 Author: Chris Wilson ch...@chris-wilson.co.uk Date: Tue May 11 14:55:16 2010 +0100 dri2: Handle reference counting across page flipping 1. Instead of swapping bos, swap the entire private structure. 2. If we update the pixmap bo for the Screen, make sure we update the reference inside intel-front_buffer so that xrandr still functions. Fixes: Bug 27922 - i965: Rapidly resizing OpenGL window causes GPU to hang. https://bugs.freedesktop.org/show_bug.cgi?id=27922 -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Return the error code from init_hws()
Otherwise we indicate success in the event of failure and this will lead to an eventual OOPS. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index aacd798..e0e29ae 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4640,7 +4640,7 @@ err_unpin: err_unref: drm_gem_object_unreference(obj); err: - return 0; + return ret; } static void -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 01/11] drm/i915: Only print an message if there was an error
Only report an error if the GPU has actually detected one, otherwise we are just hung. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_irq.c | 38 -- 1 files changed, 24 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b5dba47..2479be0 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -692,24 +692,13 @@ void i915_destroy_error_state(struct drm_device *dev) i915_error_state_free(dev, error); } -/** - * i915_handle_error - handle an error interrupt - * @dev: drm device - * - * Do some basic checking of regsiter state at error interrupt time and - * dump it to the syslog. Also call i915_capture_error_state() to make - * sure we get a record and make it available in debugfs. Fire a uevent - * so userspace knows something bad happened (should trigger collection - * of a ring dump etc.). - */ -static void i915_handle_error(struct drm_device *dev, bool wedged) +static void i915_report_and_clear_eir(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev-dev_private; u32 eir = I915_READ(EIR); - u32 pipea_stats = I915_READ(PIPEASTAT); - u32 pipeb_stats = I915_READ(PIPEBSTAT); - i915_capture_error_state(dev); + if (!eir) + return; printk(KERN_ERR render error detected, EIR: 0x%08x\n, eir); @@ -755,6 +744,9 @@ static void i915_handle_error(struct drm_device *dev, bool wedged) } if (eir I915_ERROR_MEMORY_REFRESH) { + u32 pipea_stats = I915_READ(PIPEASTAT); + u32 pipeb_stats = I915_READ(PIPEBSTAT); + printk(KERN_ERR memory refresh error\n); printk(KERN_ERR PIPEASTAT: 0x%08x\n, pipea_stats); @@ -811,6 +803,24 @@ static void i915_handle_error(struct drm_device *dev, bool wedged) I915_WRITE(EMR, I915_READ(EMR) | eir); I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); } +} + +/** + * i915_handle_error - handle an error interrupt + * @dev: drm device + * + * Do some basic checking of regsiter state at error interrupt time and + * dump it to the syslog. Also call i915_capture_error_state() to make + * sure we get a record and make it available in debugfs. Fire a uevent + * so userspace knows something bad happened (should trigger collection + * of a ring dump etc.). + */ +static void i915_handle_error(struct drm_device *dev, bool wedged) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + + i915_capture_error_state(dev); + i915_report_and_clear_eir(dev); if (wedged) { atomic_set(dev_priv-mm.wedged, 1); -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 02/11] drm/i915: Hold the spinlock whilst resetting unpin_work along error path
Delay taking the mutex until we need to and ensure that we hold the spinlock when resetting unpin_work on the error path. Also defer the debugging print messages until after we have released the spinlock. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: Jesse Barnes jbar...@virtuousgeek.org Cc: Kristian Høgsberg k...@bitplanet.net --- drivers/gpu/drm/i915/intel_display.c | 20 1 files changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cfac4dd..1845a06 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4667,8 +4667,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, if (work == NULL) return -ENOMEM; - mutex_lock(dev-struct_mutex); - work-event = event; work-dev = crtc-dev; intel_fb = to_intel_framebuffer(crtc-fb); @@ -4678,10 +4676,10 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, /* We borrow the event spin lock for protecting unpin_work */ spin_lock_irqsave(dev-event_lock, flags); if (intel_crtc-unpin_work) { - DRM_DEBUG_DRIVER(flip queue: crtc already busy\n); spin_unlock_irqrestore(dev-event_lock, flags); kfree(work); - mutex_unlock(dev-struct_mutex); + + DRM_DEBUG_DRIVER(flip queue: crtc already busy\n); return -EBUSY; } intel_crtc-unpin_work = work; @@ -4690,13 +4688,19 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, intel_fb = to_intel_framebuffer(fb); obj = intel_fb-obj; + mutex_lock(dev-struct_mutex); ret = intel_pin_and_fence_fb_obj(dev, obj); if (ret != 0) { - DRM_DEBUG_DRIVER(flip queue: %p pin fence failed\n, - to_intel_bo(obj)); - kfree(work); - intel_crtc-unpin_work = NULL; mutex_unlock(dev-struct_mutex); + + spin_lock_irqsave(dev-event_lock, flags); + intel_crtc-unpin_work = NULL; + spin_unlock_irqrestore(dev-event_lock, flags); + + kfree(work); + + DRM_DEBUG_DRIVER(flip queue: %p pin fence failed\n, +to_intel_bo(obj)); return ret; } -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 05/11] drm/i915: Only print nothing to do debug message as required.
If the FBC is already disabled, then we do not even attempt to disable FBC and so there is no point emitting a debug statement at that point, having already emitted one saying why we are disabling FBC. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c |5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1845a06..e504fdb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1248,10 +1248,11 @@ static void intel_update_fbc(struct drm_crtc *crtc, return; out_disable: - DRM_DEBUG_KMS(unsupported config, disabling FBC\n); /* Multiple disables should be harmless */ - if (intel_fbc_enabled(dev)) + if (intel_fbc_enabled(dev)) { + DRM_DEBUG_KMS(unsupported config, disabling FBC\n); intel_disable_fbc(dev); + } } static int -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 07/11] drm/i915: Rebind bo if currently bound with incorrect alignment.
Whilst pinning the buffer, check that that its current alignment matches the requested alignment. If it does not, rebind. This should clear up any final render errors whilst resuming, for reference: Bug 27070 - [i915] Page table errors with empty ringbuffer https://bugs.freedesktop.org/show_bug.cgi?id=27070 Bug 15502 - render error detected, EIR: 0x0010 https://bugzilla.kernel.org/show_bug.cgi?id=15502 Bug 13844 - i915 error: render error detected https://bugzilla.kernel.org/show_bug.cgi?id=13844 Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: sta...@kernel.org --- drivers/gpu/drm/i915/i915_gem.c | 11 +++ 1 files changed, 11 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6425c2a..a5ca959 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4164,6 +4164,17 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) BUG_ON(obj_priv-pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT); i915_verify_inactive(dev, __FILE__, __LINE__); + + if (obj_priv-gtt_space != NULL) { + if (alignment == 0) + alignment = i915_gem_get_gtt_alignment(obj); + if (obj_priv-gtt_offset (alignment - 1)) { + ret = i915_gem_object_unbind(obj); + if (ret) + return ret; + } + } + if (obj_priv-gtt_space == NULL) { ret = i915_gem_object_bind_to_gtt(obj, alignment); if (ret) -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 09/11] drm/i915: Check error code whilst moving buffer to GTT domain.
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_fb.c |6 +- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 6f53cf7..f8c76e6 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -105,7 +105,11 @@ static int intelfb_create(struct intel_fbdev *ifbdev, } /* Flush everything out, we'll be doing GTT only from now on */ - i915_gem_object_set_to_gtt_domain(fbo, 1); + ret = i915_gem_object_set_to_gtt_domain(fbo, 1); + if (ret) { + DRM_ERROR(failed to bind fb: %d.\n, ret); + goto out_unpin; + } info = framebuffer_alloc(0, device); if (!info) { -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 10/11] drm/i915: Reject bind_to_gtt() early if object aperture
If the object is bigger than the entire aperture, reject it early before evicting everything in a vain attempt to find space. v2: Use E2BIG as suggested by Owain G. Ainsworth. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: sta...@kernel.org --- drivers/gpu/drm/i915/i915_gem.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b87945d..f84c8e9 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2648,6 +2648,14 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) return -EINVAL; } + /* If the object is bigger than the entire aperture, reject it early +* before evicting everything in a vain attempt to find space. +*/ + if (obj-size dev-gtt_total) { + DRM_ERROR(Attempting to bind an object larger than the aperture\n); + return -E2BIG; + } + search_free: free_space = drm_mm_search_free(dev_priv-mm.gtt_space, obj-size, alignment, 0); -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 11/11] drm/i915: Cleanup after failed initialization of ringbuffers
The callers expect us to cleanup any partially initialised structures before reporting the error. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 19 ++- 1 files changed, 18 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f84c8e9..42866c0 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4632,23 +4632,40 @@ i915_gem_init_ringbuffer(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev-dev_private; int ret; + dev_priv-render_ring = render_ring; + if (!I915_NEED_GFX_HWS(dev)) { dev_priv-render_ring.status_page.page_addr = dev_priv-status_page_dmah-vaddr; memset(dev_priv-render_ring.status_page.page_addr, 0, PAGE_SIZE); } + if (HAS_PIPE_CONTROL(dev)) { ret = i915_gem_init_pipe_control(dev); if (ret) return ret; } + ret = intel_init_ring_buffer(dev, dev_priv-render_ring); - if (!ret HAS_BSD(dev)) { + if (ret) + goto cleanup_pipe_control; + + if (HAS_BSD(dev)) { dev_priv-bsd_ring = bsd_ring; ret = intel_init_ring_buffer(dev, dev_priv-bsd_ring); + if (ret) + goto cleanup_render_ring; } + + return 0; + +cleanup_render_ring: + intel_cleanup_ring_buffer(dev, dev_priv-render_ring); +cleanup_pipe_control: + if (HAS_PIPE_CONTROL(dev)) + i915_gem_cleanup_pipe_control(dev); return ret; } -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/2] drm/i915: Fix up address spaces in slow_kernel_write()
Since we now get_user_pages() outside of the mutex prior to performing the copy, we kmap() the page inside the copy routine and so need to perform an ordinary memcpy() and not copy_from_user(). Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 42 +++--- 1 files changed, 17 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6769fab..528ff7d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -509,25 +509,24 @@ fast_user_write(struct io_mapping *mapping, * page faults */ -static inline int +static inline void slow_kernel_write(struct io_mapping *mapping, loff_t gtt_base, int gtt_offset, struct page *user_page, int user_offset, int length) { - char *src_vaddr, *dst_vaddr; - unsigned long unwritten; + char __iomem *dst_vaddr; + char *src_vaddr; - dst_vaddr = io_mapping_map_atomic_wc(mapping, gtt_base); - src_vaddr = kmap_atomic(user_page, KM_USER1); - unwritten = __copy_from_user_inatomic_nocache(dst_vaddr + gtt_offset, - src_vaddr + user_offset, - length); - kunmap_atomic(src_vaddr, KM_USER1); - io_mapping_unmap_atomic(dst_vaddr); - if (unwritten) - return -EFAULT; - return 0; + dst_vaddr = io_mapping_map_wc(mapping, gtt_base); + src_vaddr = kmap(user_page); + + memcpy_toio(dst_vaddr + gtt_offset, + src_vaddr + user_offset, + length); + + kunmap(user_page); + io_mapping_unmap(dst_vaddr); } static inline int @@ -700,18 +699,11 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, if ((data_page_offset + page_length) PAGE_SIZE) page_length = PAGE_SIZE - data_page_offset; - ret = slow_kernel_write(dev_priv-mm.gtt_mapping, - gtt_page_base, gtt_page_offset, - user_pages[data_page_index], - data_page_offset, - page_length); - - /* If we get a fault while copying data, then (presumably) our -* source page isn't available. Return the error and we'll -* retry in the slow path. -*/ - if (ret) - goto out_unpin_object; + slow_kernel_write(dev_priv-mm.gtt_mapping, + gtt_page_base, gtt_page_offset, + user_pages[data_page_index], + data_page_offset, + page_length); remain -= page_length; offset += page_length; -- 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: Include instdone[1] in hangcheck
References: Bug 26691 - Spurious hangcheck whilst executing a long shader over a large vertex buffer https://bugs.freedesktop.org/show_bug.cgi?id=26691 Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h |2 ++ drivers/gpu/drm/i915/i915_irq.c | 38 +++--- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2765831..27900cd 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -285,6 +285,8 @@ typedef struct drm_i915_private { struct timer_list hangcheck_timer; int hangcheck_count; uint32_t last_acthd; + uint32_t last_instdone; + uint32_t last_instdone1; struct drm_mm vram; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 2479be0..4f2a85d 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1225,16 +1225,21 @@ void i915_hangcheck_elapsed(unsigned long data) { struct drm_device *dev = (struct drm_device *)data; drm_i915_private_t *dev_priv = dev-dev_private; - uint32_t acthd; + uint32_t acthd, instdone, instdone1; /* No reset support on this chip yet. */ if (IS_GEN6(dev)) return; - if (!IS_I965G(dev)) + if (!IS_I965G(dev)) { acthd = I915_READ(ACTHD); - else + instdone = I915_READ(INSTDONE); + instdone1 = 0; + } else { acthd = I915_READ(ACTHD_I965); + instdone = I915_READ(INSTDONE_I965); + instdone1 = I915_READ(INSTDONE1); + } /* If all work is done then ACTHD clearly hasn't advanced. */ if (list_empty(dev_priv-render_ring.request_list) || @@ -1245,21 +1250,24 @@ void i915_hangcheck_elapsed(unsigned long data) return; } - if (dev_priv-last_acthd == acthd dev_priv-hangcheck_count 0) { - DRM_ERROR(Hangcheck timer elapsed... GPU hung\n); - i915_handle_error(dev, true); - return; - } + if (dev_priv-last_acthd == acthd + dev_priv-last_instdone == instdone + dev_priv-last_instdone1 == instdone1) { + if (dev_priv-hangcheck_count++ 1) { + DRM_ERROR(Hangcheck timer elapsed... GPU hung\n); + i915_handle_error(dev, true); + return; + } + } else { + dev_priv-hangcheck_count = 0; + + dev_priv-last_acthd = acthd; + dev_priv-last_instdone = instdone; + dev_priv-last_instdone1 = instdone1; + } /* Reset timer case chip hangs without another request being added */ mod_timer(dev_priv-hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); - - if (acthd != dev_priv-last_acthd) - dev_priv-hangcheck_count = 0; - else - dev_priv-hangcheck_count++; - - dev_priv-last_acthd = acthd; } /* drm_dma.h hooks -- 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: Remove the WARN when failing to set tiling.
We generally issue an error message at the point of failure, and so this warning with a fairly pointless stacktrace is superfluous and ugly. Needless to say, the common trigger for this WARN happens to be EIO where this is pure noise. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_tiling.c |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 4b7c49d..155719e 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -333,8 +333,6 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, i915_gem_release_mmap(obj); if (ret != 0) { - WARN(ret != -ERESTARTSYS, -failed to reset object for tiling switch); args-tiling_mode = obj_priv-tiling_mode; args-stride = obj_priv-stride; goto err; -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] Allocate a correctly sized framebuffer when tiling by using libdrm support.
On Sun, 6 Jun 2010 23:49:09 -0700, Eric Anholt e...@anholt.net wrote: When I made libdrm stop overallocating so much memory for the purpose of bo caching, things started scribbling on the bottom of my frontbuffer (and vice versa, leading to GPU hangs). We had the usual mistake of size = tiled_pitch * height instead of size = tiled_pitch * tile_aligned_height. Hmm, something is fishy after applying the patch. The framebuffer pitch for the 1920x1080 external display looks to be off by 2. -ickle -- 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 1/7 resend] drm/i915: Add the support of eDP on DP-D for Ibex/CPT
On Sat, 12 Jun 2010 14:32:21 +0800, Zhenyu Wang zhen...@linux.intel.com wrote: From: Zhao Yakui yakui.z...@intel.com This one adds support for eDP that connected on PCH DP-D port instead of CPU DP-A port, and only DP-D port could be used for eDP. https://bugs.freedesktop.org/show_bug.cgi?id=27220 Signed-off-by: Zhao Yakui yakui.z...@intel.com Tested-by: Jan-Hendrik Zab j...@jhz.name Tested-by: Templar temp...@rshc.de Signed-off-by: Zhenyu Wang zhen...@linux.intel.com --- [snip] static void -intel_dp_compute_m_n(int bytes_per_pixel, +intel_dp_compute_m_n(int bpp, int nlanes, int pixel_clock, int link_clock, struct intel_dp_m_n *m_n) { m_n-tu = 64; - m_n-gmch_m = pixel_clock * bytes_per_pixel; + m_n-gmch_m = (pixel_clock * bpp) 3; m_n-gmch_n = link_clock * nlanes; intel_reduce_ratio(m_n-gmch_m, m_n-gmch_n); m_n-link_m = pixel_clock; This rounds the gmch_m down. Is this correct? And how close to overflow is pixel_clock today? -ickle -- 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] [ANNOUNCE] xf86-video-intel 2.11.901
On Wed, 16 Jun 2010 15:10:35 +0200, Marc Deop i Argemà damnsh...@gmail.com wrote: On Wednesday June 16 2010 10:45:34 Marc Deop i Argemà wrote: Anyway, I will try to bisect today and report back :) Well, I tried. Does this message: Bisecting: 0 revisions left to test after this (roughly 0 steps) [29ba8a84f7cf5c29a5f38688a1ac0ccf41d8e4ec] XvMC: everyone's using execbuffer! mean I finished the process? One more step. Test that commit and tell git bisect (good|bad) and it will print a slightly more verbose statement of which commit is triggering the freeze. Thanks, -ickle -- 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] CUDA port for intel graphics
Hi Gregory, I think most of your questions can be answered by reading the [interface] design document for GEM - the Graphics Execution Manager. http://lwn.net/Articles/283798/ That will give you a better idea of the separation of the execution and memory management which is performed by the kernel and how it is controlled by userspace. All userspace clients are [more or less] equal and submit batch buffers to the kernel to be scheduled for execution. Each batch is a list of buffers [your textures, command streams, vertex buffers etc] which the kernel then maps into the graphics aperture and performs relocations upon the command streams. As such the GPU is then shared between multiple independent clients. If you want to perform a privileged operation such as modifying the ring buffer or registers prior to the execution of your batch, you will need to extend the GEM interface to allow you to do so. Hope this helps, and you have a lot of fun programming with the GPU directly. -- 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: Selectively enable self-reclaim
On Wed, 30 Jun 2010 16:54:07 +1000, Dave Airlie airl...@gmail.com wrote: Chris's patch has been reported to cause a regression in hibernate, Reviewing the patch again, we no longer set the default gfpmask on the inode to contain NORETRY and instead add the NORETRY at the one spot in the code where we are trying to do a large allocation and our shrinker would be prevented from running (due to contention on struct_mutex). I do not know how this causes memory corruption across hibernate and would appreciate any insights. -- 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] System freeze with 2.12 + 2.6.34
On Thu, 1 Jul 2010 16:55:28 +0200, Clemens Eisserer linuxhi...@gmail.com wrote: During the 2.6.11.901 testing phase a few people reported system freezes. What was the result of that discussion? I still experience those freezes with kernel-2.6.34 + intel 2.12, quite frequently when watching high resolution flash videos. Any idea what the problem could be? All depends upon the system. Jesse is working on a couple of patches that address the change in handling of the vblank interrupt in some revisions of the i945/i965 chipsets. That's the known failure mode... -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Explosion following OOM in do_execbuffer.
Oops, when merging the extra details following an OOM, I missed that driver_private is now NULL and the correct way to convert from the drm_gem_object into the drm_i915_gem_object is to use to_intel_bo(). BUG: unable to handle kernel NULL pointer dereference at 0069 IP: [c11a4a02] i915_gem_do_execbuffer+0x71f/0xbb6 *pde = Oops: [#1] SMP last sysfs file: /sys/devices/virtual/vc/vcsa3/uevent Pid: 10993, comm: X Not tainted 2.6.35-rc2+ #67 / EIP: 0060:[c11a4a02] EFLAGS: 00213202 CPU: 0 EIP is at i915_gem_do_execbuffer+0x71f/0xbb6 EAX: f647e8a8 EBX: ECX: 0003 EDX: ESI: 00424000 EDI: EBP: f6508e48 ESP: f6508dd4 DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 Process X (pid: 10993, ti=f6508000 task=f6432880 task.ti=f6508000) Stack: f6508de0 f713 0001 f647e8a8 f64f8480 0 f7974414 0006 f6578000 0008 0006 0 f6797880 0040 ffe4 f7974400 00d0 00d0 01c0 Call Trace: [c11a4f3a] ? i915_gem_execbuffer2+0xa1/0xe7 [c118ab96] ? drm_ioctl+0x22c/0x2fa [c11a4e99] ? i915_gem_execbuffer2+0x0/0xe7 [c107e88c] ? do_sync_read+0x8f/0xca [c1088cbd] ? vfs_ioctl+0x2c/0x96 [c118a96a] ? drm_ioctl+0x0/0x2fa [c10891f4] ? do_vfs_ioctl+0x429/0x45a [c107e5c9] ? fsnotify_access+0x54/0x5f [c107ee1c] ? vfs_read+0x9a/0xae [c1089258] ? sys_ioctl+0x33/0x4d [c1002610] ? sysenter_do_call+0x12/0x26 Code: d0 89 4d c4 31 c9 89 45 d8 eb 44 8b 45 cc 8b 14 88 8b 42 50 89 45 bc 8b 45 a0 8b 52 38 89 55 d0 31 d2 f6 40 20 01 74 0d 8b 55 bc f6 42 69 30 0f 95 c2 0f b6 d2 8b 45 d0 c7 45 d4 00 00 00 00 89 EIP: [c11a4a02] i915_gem_do_execbuffer+0x71f/0xbb6 SS:ESP 0068:f6508dd4 CR2: 0069 ---[ end trace 3f1d514b34d39381 ]--- Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0cf9584..781bd09 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3665,6 +3665,7 @@ i915_gem_wait_for_pending_flip(struct drm_device *dev, return ret; } + int i915_gem_do_execbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv, @@ -3812,7 +3813,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, unsigned long long total_size = 0; int num_fences = 0; for (i = 0; i args-buffer_count; i++) { - obj_priv = object_list[i]-driver_private; + obj_priv = to_intel_bo(object_list[i]); total_size += object_list[i]-size; num_fences += -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] Destroy screen pixmap on screen close.
On Thu, 1 Jul 2010 09:56:40 -0400, Keith Packard kei...@keithp.com wrote: This avoids a memory leak on server reset. Signed-off-by: Keith Packard kei...@keithp.com --- uxa/uxa.c |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/uxa/uxa.c b/uxa/uxa.c index a9a705c..dcfaaa9 100644 --- a/uxa/uxa.c +++ b/uxa/uxa.c @@ -1,7 +1,7 @@ /* - * Copyright © 2001 Keith Packard + * Copyright © 2001 Keith Packard * - * Partly based on code that is Copyright © The XFree86 Project Inc. + * Partly based on code that is Copyright © The XFree86 Project Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -381,6 +381,8 @@ static Bool uxa_close_screen(int i, ScreenPtr pScreen) uxa_glyphs_fini(pScreen); + (void) (*pScreen-DestroyPixmap) (pScreen-devPrivate); + pScreen-devPrivate = NULL; This looks like the responsibility of miCloseScreen(). Are we failing to chain up properly? Currently we have uxa_close_screen - PictureCloseScreen - fbCloseScreen and fbCloseScreen supersedes miCloseScreen. So should it not be fbCloseScreen that calls miCloseScreen, since fb has taken over the management of the mi interface? -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 01/11] drm: use list_for_each_entry in drm_mm.c
From: Daniel Vetter daniel.vet...@ffwll.ch Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Acked-by: Thomas Hellstrom thellst...@vmwgfx.com --- drivers/gpu/drm/drm_mm.c |8 ++-- 1 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 2ac074c..b75eb55 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -332,7 +332,6 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, unsigned long size, unsigned alignment, int best_match) { - struct list_head *list; const struct list_head *free_stack = mm-fl_entry; struct drm_mm_node *entry; struct drm_mm_node *best; @@ -342,8 +341,7 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, best = NULL; best_size = ~0UL; - list_for_each(list, free_stack) { - entry = list_entry(list, struct drm_mm_node, fl_entry); + list_for_each_entry(entry, free_stack, fl_entry) { wasted = 0; if (entry-size size) @@ -376,7 +374,6 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, unsigned long end, int best_match) { - struct list_head *list; const struct list_head *free_stack = mm-fl_entry; struct drm_mm_node *entry; struct drm_mm_node *best; @@ -386,8 +383,7 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, best = NULL; best_size = ~0UL; - list_for_each(list, free_stack) { - entry = list_entry(list, struct drm_mm_node, fl_entry); + list_for_each_entry(entry, free_stack, fl_entry) { wasted = 0; if (entry-size size) -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 03/11] drm: kill dead code in drm_mm.c
From: Daniel Vetter daniel.vet...@ffwll.ch Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Acked-by: Thomas Hellstrom thellst...@vmwgfx.com Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/drm_mm.c | 45 - 1 files changed, 0 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index b75eb55..a5a7a16 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -48,36 +48,6 @@ #define MM_UNUSED_TARGET 4 -unsigned long drm_mm_tail_space(struct drm_mm *mm) -{ - struct list_head *tail_node; - struct drm_mm_node *entry; - - tail_node = mm-ml_entry.prev; - entry = list_entry(tail_node, struct drm_mm_node, ml_entry); - if (!entry-free) - return 0; - - return entry-size; -} - -int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size) -{ - struct list_head *tail_node; - struct drm_mm_node *entry; - - tail_node = mm-ml_entry.prev; - entry = list_entry(tail_node, struct drm_mm_node, ml_entry); - if (!entry-free) - return -ENOMEM; - - if (entry-size = size) - return -ENOMEM; - - entry-size -= size; - return 0; -} - static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) { struct drm_mm_node *child; @@ -152,21 +122,6 @@ static int drm_mm_create_tail_node(struct drm_mm *mm, return 0; } -int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size, int atomic) -{ - struct list_head *tail_node; - struct drm_mm_node *entry; - - tail_node = mm-ml_entry.prev; - entry = list_entry(tail_node, struct drm_mm_node, ml_entry); - if (!entry-free) { - return drm_mm_create_tail_node(mm, entry-start + entry-size, - size, atomic); - } - entry-size += size; - return 0; -} - static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent, unsigned long size, int atomic) -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 07/11] 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 --- 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 bfc7269..d4bcf71 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_fence_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_fence_alignment(obj)); if (ret) return ret; @@ -1988,10 +1991,12 @@ i915_gem_object_unbind(struct drm_gem_object *obj) return 0; } -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; @@ -2005,14 +2010,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 @@ -2098,11 +2120,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; @@ -2115,20 +2137,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 - DRM_INFO(%s: evicting %p\n, __func__, obj);
[Intel-gfx] [PATCH 09/11] 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 | 234 +- drivers/gpu/drm/i915/i915_gem_evict.c | 263 + 4 files changed, 272 insertions(+), 232 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 65cf336..b6a0bd0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -964,6 +964,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, @@ -989,6 +990,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 1b867c4..bb7d6a9 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); @@ -1869,19 +1866,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. @@ -1991,53 +1975,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) return 0; } -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; - return
[Intel-gfx] [PATCH 11/11] 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 bb7d6a9..26d0345 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
Re: [Intel-gfx] [PATCH] Destroy screen pixmap on screen close.
On Fri, 02 Jul 2010 11:54:44 -0400, Keith Packard kei...@keithp.com wrote: On Fri, 02 Jul 2010 09:24:07 +0100, Chris Wilson ch...@chris-wilson.co.uk wrote: This looks like the responsibility of miCloseScreen(). Are we failing to chain up properly? I don't think miCloseScreen (or fbCloseScreen) can do this -- before we're called, rendering may not have been finished, after we're called, the acceleration code is shut down and pixmaps cannot be freed. That sounds true, and deserves a comment in the code. It doesn't explain why fbCloseScreen() calls free(screen-devPrivate) instead of miCloseScreen() and causing the leak in the first place... :) -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Use 128k alignment for untiled display surface on i965
The original i965 requires an alignment of 128K for the display surface with linear memory, so increase the requirement from 64k for these chipsets. For the later chipsets in the i965 family, only a 4k alignment is required. (So long as we do not start performing asynchronous flips.) Note the impact of this should be slight as on i965 we should be using a tiled frontbuffer for anything up to a 4096x4096 display. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: Jesse Barnes jbar...@virtuousgeek.org --- drivers/gpu/drm/i915/i915_drv.c |4 ++-- drivers/gpu/drm/i915/i915_drv.h |4 drivers/gpu/drm/i915/intel_display.c |7 ++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 5462d1d..57e003b 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -96,11 +96,11 @@ static const struct intel_device_info intel_i945gm_info = { }; static const struct intel_device_info intel_i965g_info = { - .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1, + .is_broadwater = 1, .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1, }; static const struct intel_device_info intel_i965gm_info = { - .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1, + .is_crestline = 1, .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1, }; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ef81c5b..c6efb80 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -200,6 +200,8 @@ struct intel_device_info { u8 need_gfx_hws : 1; u8 is_g4x : 1; u8 is_pineview : 1; + u8 is_broadwater : 1; + u8 is_crestline : 1; u8 is_ironlake : 1; u8 is_gen6 : 1; u8 has_fbc : 1; @@ -1139,6 +1141,8 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); #define IS_I945GM(dev) (INTEL_INFO(dev)-is_i945gm) #define IS_I965G(dev) (INTEL_INFO(dev)-is_i965g) #define IS_I965GM(dev) (INTEL_INFO(dev)-is_i965gm) +#define IS_BROADWATER(dev) (INTEL_INFO(dev)-is_broadwater) +#define IS_CRESTLINE(dev) (INTEL_INFO(dev)-is_crestline) #define IS_GM45(dev) ((dev)-pci_device == 0x2A42) #define IS_G4X(dev)(INTEL_INFO(dev)-is_g4x) #define IS_PINEVIEW_G(dev) ((dev)-pci_device == 0xa001) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a2d4110..86a9306 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1264,7 +1264,12 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj) switch (obj_priv-tiling_mode) { case I915_TILING_NONE: - alignment = 64 * 1024; + if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) + alignment = 128 * 1024; + else if (IS_I965(dev)) + alignment = 4 * 1024; + else + alignment = 64 * 1024; break; case I915_TILING_X: /* pin() will align the object as required by fence */ -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/2] drm/i915: Use 128k alignment for untiled display surface on i965 (v2)
The original i965, including the revised G35 and Q35, requires an alignment of 128K for the display surface with linear memory, so increase the requirement from 64k for these chipsets. For the later chipsets in the i965 family, only a 4k alignment is required. (So long as we do not start performing asynchronous flips.) Note the impact of this should be slight as on i965 we should be using a tiled frontbuffer for anything up to a 4096x4096 display. v2: compilation fixes and note that the docs do not exclude the G35 from the extra alignment. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: Jesse Barnes jbar...@virtuousgeek.org --- drivers/gpu/drm/i915/i915_drv.c |4 ++-- drivers/gpu/drm/i915/i915_drv.h |4 drivers/gpu/drm/i915/intel_display.c |7 ++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 5462d1d..57e003b 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -96,11 +96,11 @@ static const struct intel_device_info intel_i945gm_info = { }; static const struct intel_device_info intel_i965g_info = { - .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1, + .is_broadwater = 1, .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1, }; static const struct intel_device_info intel_i965gm_info = { - .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1, + .is_crestline = 1, .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1, }; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ef81c5b..c6efb80 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -200,6 +200,8 @@ struct intel_device_info { u8 need_gfx_hws : 1; u8 is_g4x : 1; u8 is_pineview : 1; + u8 is_broadwater : 1; + u8 is_crestline : 1; u8 is_ironlake : 1; u8 is_gen6 : 1; u8 has_fbc : 1; @@ -1139,6 +1141,8 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); #define IS_I945GM(dev) (INTEL_INFO(dev)-is_i945gm) #define IS_I965G(dev) (INTEL_INFO(dev)-is_i965g) #define IS_I965GM(dev) (INTEL_INFO(dev)-is_i965gm) +#define IS_BROADWATER(dev) (INTEL_INFO(dev)-is_broadwater) +#define IS_CRESTLINE(dev) (INTEL_INFO(dev)-is_crestline) #define IS_GM45(dev) ((dev)-pci_device == 0x2A42) #define IS_G4X(dev)(INTEL_INFO(dev)-is_g4x) #define IS_PINEVIEW_G(dev) ((dev)-pci_device == 0xa001) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a2d4110..99c0b4f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1264,7 +1264,12 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj) switch (obj_priv-tiling_mode) { case I915_TILING_NONE: - alignment = 64 * 1024; + if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) + alignment = 128 * 1024; + else if (IS_I965G(dev)) + alignment = 4 * 1024; + else + alignment = 64 * 1024; break; case I915_TILING_X: /* pin() will align the object as required by fence */ -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/2] drm/i915: Include any alternate names by which the device is known.
When trying to keep track of features between the kernel, the 2D driver, mesa and the specs, it helps to list any other name by which the device is referred to. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.c | 52 +++--- 1 files changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 57e003b..d0ab92b 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -151,33 +151,33 @@ static const struct intel_device_info intel_sandybridge_m_info = { .has_hotplug = 1, .is_gen6 = 1, }; -static const struct pci_device_id pciidlist[] = { - INTEL_VGA_DEVICE(0x3577, intel_i830_info), - INTEL_VGA_DEVICE(0x2562, intel_845g_info), - INTEL_VGA_DEVICE(0x3582, intel_i85x_info), +static const struct pci_device_id pciidlist[] = { /* aka */ + INTEL_VGA_DEVICE(0x3577, intel_i830_info), /* I830_M */ + INTEL_VGA_DEVICE(0x2562, intel_845g_info), /* 845_G */ + INTEL_VGA_DEVICE(0x3582, intel_i85x_info), /* I855_GM */ INTEL_VGA_DEVICE(0x358e, intel_i85x_info), - INTEL_VGA_DEVICE(0x2572, intel_i865g_info), - INTEL_VGA_DEVICE(0x2582, intel_i915g_info), - INTEL_VGA_DEVICE(0x258a, intel_i915g_info), - INTEL_VGA_DEVICE(0x2592, intel_i915gm_info), - INTEL_VGA_DEVICE(0x2772, intel_i945g_info), - INTEL_VGA_DEVICE(0x27a2, intel_i945gm_info), - INTEL_VGA_DEVICE(0x27ae, intel_i945gm_info), - INTEL_VGA_DEVICE(0x2972, intel_i965g_info), - INTEL_VGA_DEVICE(0x2982, intel_i965g_info), - INTEL_VGA_DEVICE(0x2992, intel_i965g_info), - INTEL_VGA_DEVICE(0x29a2, intel_i965g_info), - INTEL_VGA_DEVICE(0x29b2, intel_g33_info), - INTEL_VGA_DEVICE(0x29c2, intel_g33_info), - INTEL_VGA_DEVICE(0x29d2, intel_g33_info), - INTEL_VGA_DEVICE(0x2a02, intel_i965gm_info), - INTEL_VGA_DEVICE(0x2a12, intel_i965gm_info), - INTEL_VGA_DEVICE(0x2a42, intel_gm45_info), - INTEL_VGA_DEVICE(0x2e02, intel_g45_info), - INTEL_VGA_DEVICE(0x2e12, intel_g45_info), - INTEL_VGA_DEVICE(0x2e22, intel_g45_info), - INTEL_VGA_DEVICE(0x2e32, intel_g45_info), - INTEL_VGA_DEVICE(0x2e42, intel_g45_info), + INTEL_VGA_DEVICE(0x2572, intel_i865g_info),/* I865_G */ + INTEL_VGA_DEVICE(0x2582, intel_i915g_info),/* I915_G */ + INTEL_VGA_DEVICE(0x258a, intel_i915g_info),/* E7221_G */ + INTEL_VGA_DEVICE(0x2592, intel_i915gm_info), /* I915_GM */ + INTEL_VGA_DEVICE(0x2772, intel_i945g_info),/* I945_G */ + INTEL_VGA_DEVICE(0x27a2, intel_i945gm_info), /* I945_GM */ + INTEL_VGA_DEVICE(0x27ae, intel_i945gm_info), /* I945_GME */ + INTEL_VGA_DEVICE(0x2972, intel_i965g_info),/* I946_GZ */ + INTEL_VGA_DEVICE(0x2982, intel_i965g_info),/* G35_G */ + INTEL_VGA_DEVICE(0x2992, intel_i965g_info),/* I965_Q */ + INTEL_VGA_DEVICE(0x29a2, intel_i965g_info),/* I965_G */ + INTEL_VGA_DEVICE(0x29b2, intel_g33_info), /* Q35_G */ + INTEL_VGA_DEVICE(0x29c2, intel_g33_info), /* G33_G */ + INTEL_VGA_DEVICE(0x29d2, intel_g33_info), /* Q33_G */ + INTEL_VGA_DEVICE(0x2a02, intel_i965gm_info), /* I965_GM */ + INTEL_VGA_DEVICE(0x2a12, intel_i965gm_info), /* I965_GME */ + INTEL_VGA_DEVICE(0x2a42, intel_gm45_info), /* GM45_G */ + INTEL_VGA_DEVICE(0x2e02, intel_g45_info), /* IGD_E_G */ + INTEL_VGA_DEVICE(0x2e12, intel_g45_info), /* Q45_G */ + INTEL_VGA_DEVICE(0x2e22, intel_g45_info), /* G45_G */ + INTEL_VGA_DEVICE(0x2e32, intel_g45_info), /* G41_G */ + INTEL_VGA_DEVICE(0x2e42, intel_g45_info), /* B43_G */ INTEL_VGA_DEVICE(0xa001, intel_pineview_info), INTEL_VGA_DEVICE(0xa011, intel_pineview_info), INTEL_VGA_DEVICE(0x0042, intel_ironlake_d_info), -- 1.7.1 ___ 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: Include any alternate names by which the device is known.
On Mon, 5 Jul 2010 18:01:47 +0100, Chris Wilson ch...@chris-wilson.co.uk wrote: When trying to keep track of features between the kernel, the 2D driver, mesa and the specs, it helps to list any other name by which the device is referred to. In adding this list it became apparent that the 2D code is lagging a bit in its device names. In particular, it is unaware of 0x358e and still uses IGD. Is it ok to change these based on drm/i915? -ickle -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Unset mmap_offset on failure path.
If we fail to correctly setup the mapping for an object, make sure that we nullify the pointer within the object after tearing down. Otherwise, we may later attempt to reuse the invalid pointer... Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: sta...@kernel.org --- 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 52643dd..ed2803f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1261,6 +1261,7 @@ out_free_mm: drm_mm_put_block(list-file_offset_node); out_free_list: kfree(list-map); + list-map = NULL; return ret; } -- 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: Typo in (unused) register mask for overlay.
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_overlay.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 88a9ee8..5ba3b48 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -65,7 +65,7 @@ #define OCMD_YUV_410_PLANAR(0xe10) /* also 411 */ #define OCMD_TVSYNCFLIP_PARITY (0x19) #define OCMD_TVSYNCFLIP_ENABLE (0x17) -#define OCMD_BUF_TYPE_MASK (Ox15) +#define OCMD_BUF_TYPE_MASK (0x15) #define OCMD_BUF_TYPE_FRAME(0x05) #define OCMD_BUF_TYPE_FIELD(0x15) #define OCMD_TEST_MODE (0x14) -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/2] drm/i915: Remove the redundant check for a fixed_panel_mode
We already checked just a couple of lines above that we have found a fixed_panel_mode for the LVDS, so remove the surplus check. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_lvds.c | 32 +++- 1 files changed, 15 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 0eab8df..6ef9388 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -200,27 +200,25 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, if (dev_priv-panel_fixed_mode == NULL) return true; /* -* If we have timings from the BIOS for the panel, put them in +* We have timings from the BIOS for the panel, put them in * to the adjusted mode. The CRTC will be set up for this mode, * with the panel scaling set up to source from the H/VDisplay * of the original mode. */ - if (dev_priv-panel_fixed_mode != NULL) { - adjusted_mode-hdisplay = dev_priv-panel_fixed_mode-hdisplay; - adjusted_mode-hsync_start = - dev_priv-panel_fixed_mode-hsync_start; - adjusted_mode-hsync_end = - dev_priv-panel_fixed_mode-hsync_end; - adjusted_mode-htotal = dev_priv-panel_fixed_mode-htotal; - adjusted_mode-vdisplay = dev_priv-panel_fixed_mode-vdisplay; - adjusted_mode-vsync_start = - dev_priv-panel_fixed_mode-vsync_start; - adjusted_mode-vsync_end = - dev_priv-panel_fixed_mode-vsync_end; - adjusted_mode-vtotal = dev_priv-panel_fixed_mode-vtotal; - adjusted_mode-clock = dev_priv-panel_fixed_mode-clock; - drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); - } + adjusted_mode-hdisplay = dev_priv-panel_fixed_mode-hdisplay; + adjusted_mode-hsync_start = + dev_priv-panel_fixed_mode-hsync_start; + adjusted_mode-hsync_end = + dev_priv-panel_fixed_mode-hsync_end; + adjusted_mode-htotal = dev_priv-panel_fixed_mode-htotal; + adjusted_mode-vdisplay = dev_priv-panel_fixed_mode-vdisplay; + adjusted_mode-vsync_start = + dev_priv-panel_fixed_mode-vsync_start; + adjusted_mode-vsync_end = + dev_priv-panel_fixed_mode-vsync_end; + adjusted_mode-vtotal = dev_priv-panel_fixed_mode-vtotal; + adjusted_mode-clock = dev_priv-panel_fixed_mode-clock; + drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); /* Make sure pre-965s set dither correctly */ if (!IS_I965G(dev)) { -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/2] drm/i915: Refactor panel fitting on the LVDS.
Move the common routines into separate functions to not only increase readability, but also throwaway surplus code. In doing so, we review the calculation of the aspect preserving scaling and avoid the use of fixed-point until we need to calculate the accurate scale factor. 1 files changed, 128 insertions(+), 194 deletions(-) Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: Jesse Barnes jbar...@virtuousgeek.org --- drivers/gpu/drm/i915/intel_lvds.c | 322 +++-- 1 files changed, 128 insertions(+), 194 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 6ef9388..eab6a3a 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -156,31 +156,92 @@ static int intel_lvds_mode_valid(struct drm_connector *connector, return MODE_OK; } +static void +centre_horizontally(struct drm_display_mode *mode, + int width) +{ + u32 border, sync_pos, blank_width, sync_width; + + sync_width = mode-crtc_hsync_end - mode-crtc_hsync_start; + blank_width = mode-crtc_hblank_end - mode-crtc_hblank_start; + + border = (mode-hdisplay - width) / 2; + + if (mode-hdisplay 1) /* odd resolutions */ + border++; + + /* keep the border be even */ + if (border 1) + border++; + + mode-crtc_hdisplay = width; + mode-crtc_hblank_start = width + border; + /* keep the hblank width constant */ + mode-crtc_hblank_end = + mode-crtc_hblank_start + blank_width; + + /* get the hsync start pos relative to hblank start */ + sync_pos = (blank_width - sync_width) / 2; + /* keep the hsync_pos be even */ + if (sync_pos 1) + sync_pos++; + + /* keep hsync width constant */ + mode-crtc_hsync_start = mode-crtc_hblank_start + sync_pos; + mode-crtc_hsync_end = mode-crtc_hsync_start + sync_width; +} + +static void +centre_vertically(struct drm_display_mode *mode, + int height) +{ + u32 border, sync_pos, blank_width, sync_width; + + sync_width = mode-crtc_vsync_end - mode-crtc_vsync_start; + blank_width = mode-crtc_vblank_end - mode-crtc_vblank_start; + + border = (mode-vdisplay - height) / 2; + + if (mode-vdisplay 1) + border++; + + mode-crtc_vdisplay = height; + mode-crtc_vblank_start = height + border; + /* keep the vblank width constant */ + mode-crtc_vblank_end = mode-crtc_vblank_start + blank_width; + + /* get the vsync start pos relative to vblank start */ + sync_pos = (blank_width - sync_width) / 2; + + /* keep the vsync width constant */ + mode-crtc_vsync_start = mode-crtc_vblank_start + sync_pos; + mode-crtc_vsync_end = mode-crtc_vsync_start + sync_width; +} + +static inline u32 panel_fitter_scaling(u32 source, u32 target) +{ + /* +* Floating point operation is not supported. So the FACTOR +* is defined, which can avoid the floating point computation +* when calculating the panel ratio. +*/ +#define ACCURACY 12 +#define FACTOR (1 ACCURACY) + u32 ratio = source * FACTOR / target; + return (FACTOR * (ratio + FACTOR/2)) / FACTOR; +} + static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - /* -* float point operation is not supported . So the PANEL_RATIO_FACTOR -* is defined, which can avoid the float point computation when -* calculating the panel ratio. -*/ -#define PANEL_RATIO_FACTOR 8192 struct drm_device *dev = encoder-dev; struct drm_i915_private *dev_priv = dev-dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder-crtc); struct drm_encoder *tmp_encoder; struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); struct intel_lvds_priv *lvds_priv = intel_encoder-dev_priv; - u32 pfit_control = 0, pfit_pgm_ratios = 0; - int left_border = 0, right_border = 0, top_border = 0; - int bottom_border = 0; - bool border = 0; - int panel_ratio, desired_ratio, vert_scale, horiz_scale; - int horiz_ratio, vert_ratio; - u32 hsync_width, vsync_width; - u32 hblank_width, vblank_width; - u32 hsync_pos, vsync_pos; + u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; /* Should never happen!! */ if (!IS_I965G(dev) intel_crtc-pipe == 0) { @@ -228,11 +289,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, /* Native modes don't need fitting */ if (adjusted_mode-hdisplay == mode-hdisplay - adjusted_mode-vdisplay == mode-vdisplay) { - pfit_pgm_ratios = 0; - border = 0
[Intel-gfx] [PATCH 2/2] drm/i915: Remove extraneous variables from intel_crtc_page_flip()
Reduce the number of variables used and improve readability by scoping. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c | 31 +++ 1 files changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b3b5ff0..bb3941e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4879,15 +4879,12 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, { struct drm_device *dev = crtc-dev; struct drm_i915_private *dev_priv = dev-dev_private; - struct intel_framebuffer *intel_fb; struct drm_i915_gem_object *obj_priv; struct drm_gem_object *obj; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_unpin_work *work; unsigned long flags; - int pipesrc_reg = (intel_crtc-pipe == 0) ? PIPEASRC : PIPEBSRC; - int ret, pipesrc; - u32 flip_mask; + int ret; work = kzalloc(sizeof *work, GFP_KERNEL); if (work == NULL) @@ -4895,8 +4892,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, work-event = event; work-dev = crtc-dev; - intel_fb = to_intel_framebuffer(crtc-fb); - work-old_fb_obj = intel_fb-obj; + work-old_fb_obj = to_intel_framebuffer(crtc-fb)-obj; INIT_WORK(work-work, intel_unpin_work_fn); /* We borrow the event spin lock for protecting unpin_work */ @@ -4911,8 +4907,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, intel_crtc-unpin_work = work; spin_unlock_irqrestore(dev-event_lock, flags); - intel_fb = to_intel_framebuffer(fb); - obj = intel_fb-obj; + obj = to_intel_framebuffer(fb)-obj; mutex_lock(dev-struct_mutex); ret = intel_pin_and_fence_fb_obj(dev, obj); @@ -4936,24 +4931,28 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, atomic_inc(obj_priv-pending_flip); work-pending_flip_obj = obj; - if (intel_crtc-plane) - flip_mask = I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; - else - flip_mask = I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT; + if (IS_GEN3(dev)) { + u32 flip_mask; + + if (intel_crtc-plane) + flip_mask = I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; + else + flip_mask = I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT; - /* Wait for any previous flip to finish */ - if (IS_GEN3(dev)) + /* Wait for any previous flip to finish */ while (I915_READ(ISR) flip_mask) ; + } BEGIN_LP_RING(4); if (IS_I965G(dev)) { + int pipesrc_reg = (intel_crtc-pipe == 0) ? PIPEASRC : PIPEBSRC; + OUT_RING(MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc-plane)); OUT_RING(fb-pitch); OUT_RING(obj_priv-gtt_offset | obj_priv-tiling_mode); - pipesrc = I915_READ(pipesrc_reg); - OUT_RING(pipesrc 0x0fff0fff); + OUT_RING(I915_READ(pipesrc_reg) 0x0fff0fff); } else { OUT_RING(MI_DISPLAY_FLIP_I915 | MI_DISPLAY_FLIP_PLANE(intel_crtc-plane)); -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] KMS broken from 2.6.33 up to 2.6.35-rc5????
On Sun, 18 Jul 2010 14:29:34 +0200, Massimo Maggi mass...@.it wrote: I've set up a very minimal kernel config (the resulting kernel is not useful for anything except showing the problem), and built versions: 2.6.32.16 2.6.33.6 2.6.34.1 2.6.35-rc5 Only 2.6.32.16 is able to correctly initialize the framebuffer. Excellent, as you have managed to reproduce this with a minimal kernel, can you do a bisect between 2.6.33.16 and 2.6.33.6 and see which patch causes the regression? It should only take a couple of hours. My bet is one of the Arrandale enabling patches... -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/4] drm/i915: Add fixed panel mode parsed from EDID for eDP without fixed mode in VBT
From: Zhao Yakui yakui.z...@intel.com Signed-off-by: Zhao Yakui yakui.z...@intel.com Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Cc: sta...@kernel.org --- drivers/gpu/drm/i915/intel_dp.c | 16 +++- 1 files changed, 15 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index b4f0282..74d026c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1325,8 +1325,22 @@ static int intel_dp_get_modes(struct drm_connector *connector) */ ret = intel_ddc_get_modes(connector, intel_encoder-ddc_bus); - if (ret) + if (ret) { + if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) + !dev_priv-panel_fixed_mode) { + struct drm_display_mode *newmode; + list_for_each_entry(newmode, connector-probed_modes, + head) { + if (newmode-type DRM_MODE_TYPE_PREFERRED) { + dev_priv-panel_fixed_mode = + drm_mode_duplicate(dev, newmode); + break; + } + } + } + return ret; + } /* if eDP has no EDID, try to use fixed panel mode from VBT */ if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[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 ba50755..a30d751 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))); @@ -1612,11 +1608,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))); @@ -1638,7 +1630,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) @@ -1766,11 +1757,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; @@ -2269,11 +2260,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 = @@ -2283,9 +2271,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 6/7] drm/i915/sdvo: Add missing TV filters
Reference: Bug 28634 - missing TV parameter Flicker Filter https://bugs.freedesktop.org/show_bug.cgi?id=28634 Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_sdvo.c | 644 ++-- drivers/gpu/drm/i915/intel_sdvo_regs.h | 48 ++-- 2 files changed, 308 insertions(+), 384 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d5f1b27..39ef9ce 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -143,31 +143,31 @@ struct intel_sdvo_connector { /* This contains all current supported TV format */ 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]; - - /** -* Returned SDTV resolutions allowed for the current format, if the -* device reported it. -*/ - struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions; + struct drm_property *tv_format; /* add the property for the SDVO-TV */ - struct drm_property *left_property; - struct drm_property *right_property; - struct drm_property *top_property; - struct drm_property *bottom_property; - struct drm_property *hpos_property; - struct drm_property *vpos_property; + struct drm_property *left; + struct drm_property *right; + struct drm_property *top; + struct drm_property *bottom; + struct drm_property *hpos; + struct drm_property *vpos; + struct drm_property *contrast; + struct drm_property *saturation; + struct drm_property *hue; + struct drm_property *sharpness; + struct drm_property *flicker_filter; + struct drm_property *flicker_filter_adaptive; + struct drm_property *flicker_filter_2d; + struct drm_property *tv_chroma_filter; + struct drm_property *tv_luma_filter; /* add the property for the SDVO-TV/LVDS */ - struct drm_property *brightness_property; - struct drm_property *contrast_property; - struct drm_property *saturation_property; - struct drm_property *hue_property; + struct drm_property *brightness; /* Add variable to record current setting for the above property */ u32 left_margin, right_margin, top_margin, bottom_margin; + /* this is to get the range of margin.*/ u32 max_hscan, max_vscan; u32 max_hpos, cur_hpos; @@ -176,6 +176,12 @@ struct intel_sdvo_connector { u32 cur_contrast, max_contrast; u32 cur_saturation, max_saturation; u32 cur_hue,max_hue; + u32 cur_sharpness, max_sharpness; + u32 cur_flicker_filter, max_flicker_filter; + u32 cur_flicker_filter_adaptive,max_flicker_filter_adaptive; + 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; }; static struct intel_sdvo *enc_to_intel_sdvo(struct drm_encoder *encoder) @@ -329,13 +335,14 @@ static const struct _sdvo_cmd_name { SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT), SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT), SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS), + /* Add the op code for SDVO enhancements */ -SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_POSITION_H), -SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POSITION_H), -SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_POSITION_H), -SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_POSITION_V), -SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POSITION_V), -SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_POSITION_V), +SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HPOS), +SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HPOS), +SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HPOS), +SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_VPOS), +SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_VPOS), +SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_VPOS), SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SATURATION), SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SATURATION), SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SATURATION), @@ -354,6 +361,27 @@ static const struct _sdvo_cmd_name { SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_V), SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_V), SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_V), +SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER), +SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER), +SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER), +SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE), +SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE), +SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE), +SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_2D), +SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_2D
[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 57d24f8..0e7bf85 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -599,6 +599,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 d56184c..d476752 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1918,15 +1918,13 @@ static int ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) /* Enable panel fitting for LVDS */ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { - 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 6b399e0..56d233d 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -215,6 +215,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; + break; + } + +done: + dev_priv-pch_pf_pos
Re: [Intel-gfx] Fwd: State of 10 bits/channel?
On Thu, 22 Jul 2010 17:34:09 -0400, Andrew Lutomirski l...@mit.edu wrote: [resend b/c I used the wrong from address last time] I have a 10 bit/channel monitor (DisplayPort) which works quite nicely in 8 bit mode. Â I saw some patches from Peter Clifton related to 10 bit support go in awhile ago. [snip] What is the hardware capable of, and what is the state of affairs right now? AIUI, all the intel chips are capable of driving 30-bit displays. The later generations are more flexible and faster with greater bit depth for LUTs etc. The output driver support should (in theory) be complete, but it hasn't been well tested due to scarcity of suitable displays. Â I'm running 2.6.35-rc4+ with a hacked up xf86-video-intel with this patch: Please submit this as a format-patch to the list for inclusion. With that patch and DefaultDepth 30, I get a mostly working system, but there's no direct rendering (seems to be disabled because DRI is disabled because it runs only at depths 16 and 24) title bars on gnome-terminal draw incorrectly. Hmm, the render paths should work on 10bpc surfaces. Please do file bugs for the failures. -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Repeat unbinding during free if interrupted
If during the freeing of an object the unbind is interrupted a system call, which is quite possible if we have outstanding GPU writes that must be flused, the unbind is silently aborted. This still leaves the AGP region and backing pages allocated, and perhaps more importantly, the object remains upon the various lists exposing us to memory corruption. I think this is the cause behind the use-after-free, such as Bug 15664 - Graphics hang and kernel backtrace when starting Azureus with Compiz enabled https://bugzilla.kernel.org/show_bug.cgi?id=15664 Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: sta...@kernel.org --- drivers/gpu/drm/i915/i915_gem.c |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 3c7c0f7..a4c0b44 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4292,6 +4292,7 @@ void i915_gem_free_object(struct drm_gem_object *obj) { struct drm_device *dev = obj-dev; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + int ret; trace_i915_gem_object_destroy(obj); @@ -4301,7 +4302,9 @@ void i915_gem_free_object(struct drm_gem_object *obj) if (obj_priv-phys_obj) i915_gem_detach_phys_object(dev, obj); - i915_gem_object_unbind(obj); + do { + ret = i915_gem_object_unbind(obj); + } while (ret == -ERESTARTSYS); if (obj_priv-mmap_offset) i915_gem_free_mmap_offset(obj); -- 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: Repeat unbinding during free if interrupted (v2)
If during the freeing of an object the unbind is interrupted by a system call, which is quite possible if we have outstanding GPU writes that must be flushed, the unbind is silently aborted. This still leaves the AGP region and backing pages allocated, and perhaps more importantly, the object remains upon the various lists exposing us to memory corruption. I think this is the cause behind the use-after-free, such as Bug 15664 - Graphics hang and kernel backtrace when starting Azureus with Compiz enabled https://bugzilla.kernel.org/show_bug.cgi?id=15664 v2: Daniel Vetter reminded me that kernel space programming is never easy. We cannot simply spin to clear the pending signal and so must deferred the freeing of the object until later. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: sta...@kernel.org --- drivers/gpu/drm/i915/i915_drv.h |8 + drivers/gpu/drm/i915/i915_gem.c | 56 -- 2 files changed, 49 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0e7bf85..a66503c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -551,6 +551,14 @@ typedef struct drm_i915_private { struct list_head fence_list; /** +* List of objects currently pending being freed. +* +* These objects are no longer in use, but due to a signal +* we were prevented from freeing them at the appointed time. +*/ + struct list_head deferred_free_list; + + /** * We leave the user IRQ off as much as possible, * but this means that requests will finish and never * be retired once the system goes idle. Set a timer to diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 3c7c0f7..28a71e4 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -52,6 +52,7 @@ static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); 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); +static void i915_gem_free_object_tail(struct drm_gem_object *obj); static LIST_HEAD(shrink_list); static DEFINE_SPINLOCK(shrink_list_lock); @@ -1707,6 +1708,15 @@ i915_gem_retire_requests_ring(struct drm_device *dev, drm_i915_private_t *dev_priv = dev-dev_private; uint32_t seqno; + if (!list_empty(dev_priv-mm.deferred_free_list)) { + struct drm_i915_gem_object *obj_priv, *tmp; + + list_for_each_entry_safe(obj_priv, tmp, +dev_priv-mm.deferred_free_list, +list) + i915_gem_free_object_tail(obj_priv-base); + } + if (!ring-status_page.page_addr || list_empty(ring-request_list)) return; @@ -1929,11 +1939,12 @@ i915_gem_object_unbind(struct drm_gem_object *obj) * before we unbind. */ ret = i915_gem_object_set_to_cpu_domain(obj, 1); - if (ret) { - if (ret != -ERESTARTSYS) - DRM_ERROR(set_domain failed: %d\n, ret); + if (ret == -ERESTARTSYS) return ret; - } + /* Continue on if we fail due to EIO, the GPU is hung so we +* should be safe and we need to cleanup or else we might +* cause memory corruption through use-after-free. +*/ BUG_ON(obj_priv-active); @@ -1967,7 +1978,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) trace_i915_gem_object_unbind(obj); - return 0; + return ret; } int @@ -4288,20 +4299,19 @@ int i915_gem_init_object(struct drm_gem_object *obj) return 0; } -void i915_gem_free_object(struct drm_gem_object *obj) +static void i915_gem_free_object_tail(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); + int ret; - trace_i915_gem_object_destroy(obj); - - while (obj_priv-pin_count 0) - i915_gem_object_unpin(obj); - - if (obj_priv-phys_obj) - i915_gem_detach_phys_object(dev, obj); - - i915_gem_object_unbind(obj); + ret = i915_gem_object_unbind(obj); + if (ret == -ERESTARTSYS) { + list_move_tail(obj_priv-list, + dev_priv-mm.deferred_free_list); + return; + } if (obj_priv-mmap_offset) i915_gem_free_mmap_offset(obj); @@ -4313,6 +4323,22 @@ void i915_gem_free_object(struct drm_gem_object *obj) kfree(obj_priv); } +void
[Intel-gfx] [PATCH] drm/i915: Repeat unbinding during free if interrupted (v3)
If during the freeing of an object the unbind is interrupted by a system call, which is quite possible if we have outstanding GPU writes that must be flushed, the unbind is silently aborted. This still leaves the AGP region and backing pages allocated, and perhaps more importantly, the object remains upon the various lists exposing us to memory corruption. I think this is the cause behind the use-after-free, such as Bug 15664 - Graphics hang and kernel backtrace when starting Azureus with Compiz enabled https://bugzilla.kernel.org/show_bug.cgi?id=15664 v2: Daniel Vetter reminded me that kernel space programming is never easy. We cannot simply spin to clear the pending signal and so must deferred the freeing of the object until later. v3: Run from the top level retire requests. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: sta...@kernel.org --- drivers/gpu/drm/i915/i915_drv.h |8 + drivers/gpu/drm/i915/i915_gem.c | 56 -- 2 files changed, 49 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0e7bf85..a66503c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -551,6 +551,14 @@ typedef struct drm_i915_private { struct list_head fence_list; /** +* List of objects currently pending being freed. +* +* These objects are no longer in use, but due to a signal +* we were prevented from freeing them at the appointed time. +*/ + struct list_head deferred_free_list; + + /** * We leave the user IRQ off as much as possible, * but this means that requests will finish and never * be retired once the system goes idle. Set a timer to diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 3c7c0f7..1f2c5f5 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -52,6 +52,7 @@ static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); 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); +static void i915_gem_free_object_tail(struct drm_gem_object *obj); static LIST_HEAD(shrink_list); static DEFINE_SPINLOCK(shrink_list_lock); @@ -1746,6 +1747,15 @@ i915_gem_retire_requests(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev-dev_private; + if (!list_empty(dev_priv-mm.deferred_free_list)) { + struct drm_i915_gem_object *obj_priv, *tmp; + + list_for_each_entry_safe(obj_priv, tmp, +dev_priv-mm.deferred_free_list, +list) + i915_gem_free_object_tail(obj_priv-base); + } + i915_gem_retire_requests_ring(dev, dev_priv-render_ring); if (HAS_BSD(dev)) i915_gem_retire_requests_ring(dev, dev_priv-bsd_ring); @@ -1929,11 +1939,12 @@ i915_gem_object_unbind(struct drm_gem_object *obj) * before we unbind. */ ret = i915_gem_object_set_to_cpu_domain(obj, 1); - if (ret) { - if (ret != -ERESTARTSYS) - DRM_ERROR(set_domain failed: %d\n, ret); + if (ret == -ERESTARTSYS) return ret; - } + /* Continue on if we fail due to EIO, the GPU is hung so we +* should be safe and we need to cleanup or else we might +* cause memory corruption through use-after-free. +*/ BUG_ON(obj_priv-active); @@ -1967,7 +1978,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) trace_i915_gem_object_unbind(obj); - return 0; + return ret; } int @@ -4288,20 +4299,19 @@ int i915_gem_init_object(struct drm_gem_object *obj) return 0; } -void i915_gem_free_object(struct drm_gem_object *obj) +static void i915_gem_free_object_tail(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); + int ret; - trace_i915_gem_object_destroy(obj); - - while (obj_priv-pin_count 0) - i915_gem_object_unpin(obj); - - if (obj_priv-phys_obj) - i915_gem_detach_phys_object(dev, obj); - - i915_gem_object_unbind(obj); + ret = i915_gem_object_unbind(obj); + if (ret == -ERESTARTSYS) { + list_move_tail(obj_priv-list, + dev_priv-mm.deferred_free_list); + return; + } if (obj_priv-mmap_offset) i915_gem_free_mmap_offset(obj); @@ -4313,6 +4323,22 @@ void i915_gem_free_object(struct
[Intel-gfx] [PATCH] drm/i915: Repeat unbinding during free if interrupted (v4)
If during the freeing of an object the unbind is interrupted by a system call, which is quite possible if we have outstanding GPU writes that must be flushed, the unbind is silently aborted. This still leaves the AGP region and backing pages allocated, and perhaps more importantly, the object remains upon the various lists exposing us to memory corruption. I think this is the cause behind the use-after-free, such as Bug 15664 - Graphics hang and kernel backtrace when starting Azureus with Compiz enabled https://bugzilla.kernel.org/show_bug.cgi?id=15664 v2: Daniel Vetter reminded me that kernel space programming is never easy. We cannot simply spin to clear the pending signal and so must deferred the freeing of the object until later. v3: Run from the top level retire requests. v4: Tested with P(return -ERESTARTSYS)=.5 from i915_gem_do_wait_request() Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: sta...@kernel.org Reviewed-by: Daniel Vetter dan...@ffwll.ch --- drivers/gpu/drm/i915/i915_drv.h |8 + drivers/gpu/drm/i915/i915_gem.c | 57 -- 2 files changed, 50 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0e7bf85..a66503c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -551,6 +551,14 @@ typedef struct drm_i915_private { struct list_head fence_list; /** +* List of objects currently pending being freed. +* +* These objects are no longer in use, but due to a signal +* we were prevented from freeing them at the appointed time. +*/ + struct list_head deferred_free_list; + + /** * We leave the user IRQ off as much as possible, * but this means that requests will finish and never * be retired once the system goes idle. Set a timer to diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 78835f8..9424d9b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -52,6 +52,7 @@ static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); 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); +static void i915_gem_free_object_tail(struct drm_gem_object *obj); static LIST_HEAD(shrink_list); static DEFINE_SPINLOCK(shrink_list_lock); @@ -1746,6 +1747,15 @@ i915_gem_retire_requests(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev-dev_private; + if (!list_empty(dev_priv-mm.deferred_free_list)) { + struct drm_i915_gem_object *obj_priv, *tmp; + + list_for_each_entry_safe(obj_priv, tmp, +dev_priv-mm.deferred_free_list, +list) + i915_gem_free_object_tail(obj_priv-base); + } + i915_gem_retire_requests_ring(dev, dev_priv-render_ring); if (HAS_BSD(dev)) i915_gem_retire_requests_ring(dev, dev_priv-bsd_ring); @@ -1929,11 +1939,12 @@ i915_gem_object_unbind(struct drm_gem_object *obj) * before we unbind. */ ret = i915_gem_object_set_to_cpu_domain(obj, 1); - if (ret) { - if (ret != -ERESTARTSYS) - DRM_ERROR(set_domain failed: %d\n, ret); + if (ret == -ERESTARTSYS) return ret; - } + /* Continue on if we fail due to EIO, the GPU is hung so we +* should be safe and we need to cleanup or else we might +* cause memory corruption through use-after-free. +*/ BUG_ON(obj_priv-active); @@ -1967,7 +1978,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) trace_i915_gem_object_unbind(obj); - return 0; + return ret; } int @@ -4292,20 +4303,19 @@ int i915_gem_init_object(struct drm_gem_object *obj) return 0; } -void i915_gem_free_object(struct drm_gem_object *obj) +static void i915_gem_free_object_tail(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); + int ret; - trace_i915_gem_object_destroy(obj); - - while (obj_priv-pin_count 0) - i915_gem_object_unpin(obj); - - if (obj_priv-phys_obj) - i915_gem_detach_phys_object(dev, obj); - - i915_gem_object_unbind(obj); + ret = i915_gem_object_unbind(obj); + if (ret == -ERESTARTSYS) { + list_move_tail(obj_priv-list, + dev_priv-mm.deferred_free_list); + return; + } if (obj_priv
[Intel-gfx] [PATCH] drm/i915: Repeat unbinding during free if interrupted (v5)
If during the freeing of an object the unbind is interrupted by a system call, which is quite possible if we have outstanding GPU writes that must be flushed, the unbind is silently aborted. This still leaves the AGP region and backing pages allocated, and perhaps more importantly, the object remains upon the various lists exposing us to memory corruption. I think this is the cause behind the use-after-free, such as Bug 15664 - Graphics hang and kernel backtrace when starting Azureus with Compiz enabled https://bugzilla.kernel.org/show_bug.cgi?id=15664 v2: Daniel Vetter reminded me that kernel space programming is never easy. We cannot simply spin to clear the pending signal and so must deferred the freeing of the object until later. v3: Run from the top level retire requests. v4: Tested with P(return -ERESTARTSYS)=.5 from i915_gem_do_wait_request() v5: Rebase against Eric's for-linus tree. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: sta...@kernel.org Cc: Daniel Vetter dan...@ffwll.ch --- drivers/gpu/drm/i915/i915_drv.c |2 +- drivers/gpu/drm/i915/i915_drv.h | 11 - drivers/gpu/drm/i915/i915_gem.c | 96 --- 3 files changed, 70 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 119692f..5044f65 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -340,7 +340,7 @@ int i965_reset(struct drm_device *dev, u8 flags) /* * Clear request list */ - i915_gem_retire_requests(dev, dev_priv-render_ring); + i915_gem_retire_requests(dev); if (need_display) i915_save_display(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5a0100e..e3ff35e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -547,6 +547,14 @@ typedef struct drm_i915_private { struct list_head fence_list; /** +* List of objects currently pending being freed. +* +* These objects are no longer in use, but due to a signal +* we were prevented from freeing them at the appointed time. +*/ + struct list_head deferred_free_list; + + /** * We leave the user IRQ off as much as possible, * but this means that requests will finish and never * be retired once the system goes idle. Set a timer to @@ -955,8 +963,7 @@ uint32_t i915_get_gem_seqno(struct drm_device *dev, bool i915_seqno_passed(uint32_t seq1, uint32_t seq2); int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); int i915_gem_object_put_fence_reg(struct drm_gem_object *obj); -void i915_gem_retire_requests(struct drm_device *dev, -struct intel_ring_buffer *ring); +void i915_gem_retire_requests(struct drm_device *dev); void i915_gem_retire_work_handler(struct work_struct *work); void i915_gem_clflush_object(struct drm_gem_object *obj); int i915_gem_object_set_domain(struct drm_gem_object *obj, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 2d0e109..6a371e3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -53,6 +53,7 @@ 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); +static void i915_gem_free_object_tail(struct drm_gem_object *obj); static LIST_HEAD(shrink_list); static DEFINE_SPINLOCK(shrink_list_lock); @@ -1709,9 +1710,9 @@ i915_get_gem_seqno(struct drm_device *dev, /** * This function clears the request list as sequence numbers are passed. */ -void -i915_gem_retire_requests(struct drm_device *dev, - struct intel_ring_buffer *ring) +static void +i915_gem_retire_requests_ring(struct drm_device *dev, + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev-dev_private; uint32_t seqno; @@ -1751,6 +1752,25 @@ i915_gem_retire_requests(struct drm_device *dev, } void +i915_gem_retire_requests(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev-dev_private; + + if (!list_empty(dev_priv-mm.deferred_free_list)) { + struct drm_i915_gem_object *obj_priv, *tmp; + + list_for_each_entry_safe(obj_priv, tmp, +dev_priv-mm.deferred_free_list, +list) + i915_gem_free_object_tail(obj_priv-base); + } + + i915_gem_retire_requests_ring(dev, dev_priv-render_ring); + if (HAS_BSD(dev)) + i915_gem_retire_requests_ring(dev, dev_priv-bsd_ring); +} + +void
[Intel-gfx] [PATCH 3/3] drm/i915: Attempt to uncouple object after catastrophic failure in unbind
If we fail to flush outstanding GPU writes but return the memory to the system, we risk corrupting memory should the GPU recovery and complete those writes. On the other hand, if we bail early and free the object then we have a definite use-after-free and real memory corruption. Choose the lesser of two evils, since in order to recover from the hung GPU we need to completely reset it, those pending writes should never happen. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 11 ++- 1 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4a21053..56fd9e2 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1967,11 +1967,12 @@ i915_gem_object_unbind(struct drm_gem_object *obj) * before we unbind. */ ret = i915_gem_object_set_to_cpu_domain(obj, 1); - if (ret) { - if (ret != -ERESTARTSYS) - DRM_ERROR(set_domain failed: %d\n, ret); + if (ret == -ERESTARTSYS) return ret; - } + /* Continue on if we fail due to EIO, the GPU is hung so we +* should be safe and we need to cleanup or else we might +* cause memory corruption through use-after-free. +*/ BUG_ON(obj_priv-active); @@ -2007,7 +2008,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) trace_i915_gem_object_unbind(obj); - return 0; + return ret; } static struct drm_gem_object * -- 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: Unreference object not handle on creation
When creating an object, we create the handle by which it is known to the process and which own the reference to the object. That reference to the new handle is what we want to transfer to the process, not the lost reference to the object; so free the local object reference *not* the process's handle reference. This brings i915_gem_object_create_ioctl() into line with drm_gem_open_ioctl() Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c |3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6c856e9..d0fa44c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -127,8 +127,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, return -ENOMEM; ret = drm_gem_handle_create(file_priv, obj, handle); - drm_gem_object_handle_unreference_unlocked(obj); - + drm_gem_object_unreference_unlocked(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] [PATCH] drm/i915: Clear any existing dither mode prior to enabling spatial dithering
We cannot the initial configuration set by the BIOS not to have a dither mode enabled which conflicts with our enabling the Spatial Temporal 1 dither mode for PCH. In particular, the BIOS may either enable temporal dithering or the Spatial Temporal 2 with the result that we enable pure temporal dithering. Temporal dithering looks bad and is perceived as a flicker. Fixes: Bug 29248 - [Arrandale] Annoying flicker on internal panel, goes away after suspend to RAM https://bugs.freedesktop.org/show_bug.cgi?id=29248 Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7133436..fb6568b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3925,6 +3925,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, if (dev_priv-lvds_dither) { if (HAS_PCH_SPLIT(dev)) { pipeconf |= PIPE_ENABLE_DITHER; + pipeconf = ~PIPE_DITHER_TYPE_MASK; pipeconf |= PIPE_DITHER_TYPE_ST01; } else lvds |= LVDS_ENABLE_DITHER; -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] xf86-video-intel: configure.ac
On Tue, 27 Jul 2010 09:34:01 -0700, Jesse Barnes jbar...@virtuousgeek.org wrote: and glproto is missing a dep on GL: arjan In file included from i810.h:60:0, arjan from i810_accel.c:41: arjan /usr/include/GL/glxint.h:36:19: fatal error: GL/gl.h: No such file or directory From memory, I think this is just a bit of idiocacy in the driver inappropriately using a GL type, i.e. for a variable unconnected with any of the GL interfaces. -- 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 2/4] drm/i915: Enable panel fitting for eDP
On Thu, 29 Jul 2010 10:58:53 +1000, Dave Airlie airl...@gmail.com wrote: did this patch go anywhere? We haven't forgotten it. It has been successfully tested by the bug reporter to have fixed the issue on his machine. When Eric did his last sweep of patches for Linus, we realised that it was based on drm-intel-next and so not ready to be pushed. -- 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] [Blacklisted][PATCH] Submit batch buffers from flush callback chain
On Thu, 29 Jul 2010 18:34:19 -0400, Kristian Høgsberg k...@bitplanet.net wrote: There are a few cases where the server will flush client output buffers but our block handler only catches the most common (before going into select). If the server flushes client buffers before we submit our batch buffer, the client may receive a damage event for rendering that hasn't happened yet. Instead, we can hook into the flush callback chain, which the server will invoke just before flushing output. This lets us submit batch buffers before sending out events, preserving ordering. Fixes 28438: [bisected] incorrect character in gnome-terminal under compiz https://bugs.freedesktop.org/show_bug.cgi?id=28438 Signed-off-by: Kristian Høgsberg k...@bitplanet.net A flush callback makes more sense than a block handler. Is there a guide to the various hooks the xserver uses for io and the meaning of those barriers between clients? Do we have an idea of the impact this has in non-damage situations, does it impact aa10text? ;-) In intel_dri.c we manually flush the batchbuffer, should this be better expressed in terms of a call to a general flush func? For what's it is worth, I approve of this change. :) -- 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] regression after: drm/i915: Warn if we run out of FIFO space for a mode
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? -- Chris Wilson, Intel Open Source Technology Centre ___ 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_sdvo
[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_sdvo_connector
[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 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
[Intel-gfx] [PATCH] drm/i915: Enable aspect/centering panel fitting for Ironlake.
v2: Hook in DP paths to keep FULLSCREEN panel fitting on eDP. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: Zhenyu Wang zhen...@linux.intel.com --- drivers/gpu/drm/i915/Makefile|1 + drivers/gpu/drm/i915/i915_drv.h |2 + drivers/gpu/drm/i915/intel_display.c | 16 ++--- drivers/gpu/drm/i915/intel_dp.c | 20 ++- drivers/gpu/drm/i915/intel_drv.h |7 ++ drivers/gpu/drm/i915/intel_lvds.c| 32 +++--- drivers/gpu/drm/i915/intel_panel.c | 111 ++ 7 files changed, 143 insertions(+), 46 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_panel.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 384fd45..5c8e534 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -19,6 +19,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ intel_hdmi.o \ intel_sdvo.o \ intel_modes.o \ + intel_panel.o \ intel_i2c.o \ intel_fb.o \ intel_tv.o \ 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_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c4c5868..cee5d9c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -523,21 +523,9 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) dev_priv-panel_fixed_mode) { - struct drm_display_mode *fixed_mode = dev_priv-panel_fixed_mode; - - adjusted_mode-hdisplay = fixed_mode-hdisplay; - adjusted_mode-hsync_start = fixed_mode-hsync_start; - adjusted_mode-hsync_end = fixed_mode-hsync_end; - adjusted_mode-htotal = fixed_mode-htotal; - - adjusted_mode-vdisplay = fixed_mode-vdisplay; - adjusted_mode-vsync_start = fixed_mode-vsync_start; - adjusted_mode-vsync_end = fixed_mode-vsync_end; - adjusted_mode-vtotal = fixed_mode-vtotal; - - adjusted_mode-clock = fixed_mode-clock; - drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); - + intel_fixed_panel_mode(dev_priv-panel_fixed_mode, adjusted_mode); + intel_pch_panel_fitting(dev, DRM_MODE_SCALE_FULLSCREEN, + mode, adjusted_mode); /* * the mode-clock is used to calculate the DataLink M/N * of the pipe. For the eDP the fixed clock should be used. @@ -572,8 +560,10 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, count %d clock %d\n, intel_dp-link_bw, intel_dp-lane_count, adjusted_mode-clock); + return true; } + return false; } diff --git a/drivers/gpu/drm
[Intel-gfx] [PATCH] drm/i915/opregion: Use ASLE response codes defined in 0.1
Within i915_opregion.c there are two blocks of semantically identical ASLE response codes defined. Only one of those matches the ACPI IGD OpRegion Specification 0.1, use those. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: Matthew Garrett mj...@srcf.ucam.org --- drivers/gpu/drm/i915/i915_opregion.c | 10 +++--- 1 files changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c index 8fcc75c..ce402b2 100644 --- a/drivers/gpu/drm/i915/i915_opregion.c +++ b/drivers/gpu/drm/i915/i915_opregion.c @@ -114,10 +114,6 @@ struct opregion_asle { #define ASLE_REQ_MSK 0xf /* response bits of ASLE irq request */ -#define ASLE_ALS_ILLUM_FAIL(210) -#define ASLE_BACKLIGHT_FAIL(212) -#define ASLE_PFIT_FAIL (214) -#define ASLE_PWM_FREQ_FAIL (216) #define ASLE_ALS_ILLUM_FAILED (110) #define ASLE_BACKLIGHT_FAILED (112) #define ASLE_PFIT_FAILED (114) @@ -155,11 +151,11 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) u32 max_backlight, level, shift; if (!(bclp ASLE_BCLP_VALID)) - return ASLE_BACKLIGHT_FAIL; + return ASLE_BACKLIGHT_FAILED; bclp = ASLE_BCLP_MSK; if (bclp 0 || bclp 255) - return ASLE_BACKLIGHT_FAIL; + return ASLE_BACKLIGHT_FAILED; blc_pwm_ctl = I915_READ(BLC_PWM_CTL); blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2); @@ -211,7 +207,7 @@ static u32 asle_set_pfit(struct drm_device *dev, u32 pfit) /* Panel fitting is currently controlled by the X code, so this is a noop until modesetting support works fully */ if (!(pfit ASLE_PFIT_VALID)) - return ASLE_PFIT_FAIL; + return ASLE_PFIT_FAILED; return 0; } -- 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/ringbuffer: Set ring-gem_buffer = NULL on init unwind
The cleanup path for early abort failed to nullify the gem_buffer. The likely consequence of this is zero, since a failure here should mean aborting the module load. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_ringbuffer.c | 31 +-- 1 files changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 3a02425..7823b96 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -608,9 +608,10 @@ err: int intel_init_ring_buffer(struct drm_device *dev, struct intel_ring_buffer *ring) { - int ret; struct drm_i915_gem_object *obj_priv; struct drm_gem_object *obj; + int ret; + ring-dev = dev; if (I915_NEED_GFX_HWS(dev)) { @@ -623,16 +624,14 @@ int intel_init_ring_buffer(struct drm_device *dev, if (obj == NULL) { DRM_ERROR(Failed to allocate ringbuffer\n); ret = -ENOMEM; - goto cleanup; + goto err_hws; } ring-gem_object = obj; ret = i915_gem_object_pin(obj, ring-alignment); - if (ret != 0) { - drm_gem_object_unreference(obj); - goto cleanup; - } + if (ret) + goto err_unref; obj_priv = to_intel_bo(obj); ring-map.size = ring-size; @@ -644,18 +643,14 @@ int intel_init_ring_buffer(struct drm_device *dev, drm_core_ioremap_wc(ring-map, dev); if (ring-map.handle == NULL) { DRM_ERROR(Failed to map ringbuffer.\n); - i915_gem_object_unpin(obj); - drm_gem_object_unreference(obj); ret = -EINVAL; - goto cleanup; + goto err_unpin; } ring-virtual_start = ring-map.handle; ret = ring-init(dev, ring); - if (ret != 0) { - intel_cleanup_ring_buffer(dev, ring); - return ret; - } + if (ret) + goto err_unmap; if (!drm_core_check_feature(dev, DRIVER_MODESET)) i915_kernel_lost_context(dev); @@ -669,7 +664,15 @@ int intel_init_ring_buffer(struct drm_device *dev, INIT_LIST_HEAD(ring-active_list); INIT_LIST_HEAD(ring-request_list); return ret; -cleanup: + +err_unmap: + drm_core_ioremapfree(ring-map, dev); +err_unpin: + i915_gem_object_unpin(obj); +err_unref: + drm_gem_object_unreference(obj); + ring-gem_object = NULL; +err_hws: cleanup_status_page(dev, ring); return ret; } -- 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: Implement fair lru eviction across both rings. (v2)
Based in a large part upon Daniel Vetter's implementation and adapted for handling multiple rings in a single pass. This should lead to better gtt usage and fixes the page-fault-of-doom triggered. The fairness is provided by scanning through the GTT space amalgamating space in rendering order. As soon as we have a contiguous space in the GTT large enough for the new object (and its alignment), evict any object which lies within that space. This should keep more objects resident in the GTT. Doing throughput testing on a PineView machine with cairo-perf-trace indicates that there is very little difference with the new LRU scan, perhaps a small improvement... Except oddly for the poppler trace. Reference: Bug 15911 - Intermittent X crash (freeze) https://bugzilla.kernel.org/show_bug.cgi?id=15911 Bug 20152 - cannot view JPG in firefox when running UXA https://bugs.freedesktop.org/show_bug.cgi?id=20152 Bug 24369 - Hang when scrolling firefox page with window in front https://bugs.freedesktop.org/show_bug.cgi?id=24369 Bug 28478 - Intermittent graphics lockups due to overflow/loop https://bugs.freedesktop.org/show_bug.cgi?id=28478 v2: Attempt to clarify the logic and order of eviction through the use of comments and macros. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: Daniel Vetter dan...@ffwll.ch --- drivers/gpu/drm/i915/i915_drv.h |2 + drivers/gpu/drm/i915/i915_gem_evict.c | 276 + 2 files changed, 144 insertions(+), 134 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 75fe397..61a8c90 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -668,6 +668,8 @@ struct drm_i915_gem_object { struct list_head list; /** This object's place on GPU write list */ struct list_head gpu_write_list; + /** This object's place on eviction list */ + struct list_head evict_list; /** * This is set if the object is on the active or flushing lists diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index 479e450..17ec91f 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c @@ -31,167 +31,175 @@ #include i915_drv.h #include i915_drm.h -static inline int -i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj_priv) -{ - return obj_priv-madv == I915_MADV_DONTNEED; -} - -static int -i915_gem_scan_inactive_list_and_evict(struct drm_device *dev, int min_size, - unsigned alignment, int *found) +static struct drm_i915_gem_object * +i915_gem_next_active_object(struct drm_device *dev, + struct list_head **render_iter, + struct list_head **bsd_iter) { 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; - } - } + struct drm_i915_gem_object *render_obj = NULL, *bsd_obj = NULL; - obj = best ? best : first; + if (*render_iter != dev_priv-render_ring.active_list) + render_obj = list_entry(*render_iter, + struct drm_i915_gem_object, + list); - if (!obj) { - *found = 0; - return 0; - } + if (HAS_BSD(dev)) { + if (*bsd_iter != dev_priv-bsd_ring.active_list) + bsd_obj = list_entry(*bsd_iter, +struct drm_i915_gem_object, +list); - *found = 1; + if (render_obj == NULL) { + *bsd_iter = (*bsd_iter)-next; + return bsd_obj; + } -#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); + if (bsd_obj == NULL) { + *render_iter = (*render_iter)-next; + return render_obj
[Intel-gfx] [PATCH] drm/i915/edp: Flush the write before waiting for PLLs
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9814182..5cae58a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1570,6 +1570,7 @@ static void ironlake_enable_pll_edp (struct drm_crtc *crtc) dpa_ctl = I915_READ(DP_A); dpa_ctl |= DP_PLL_ENABLE; I915_WRITE(DP_A, dpa_ctl); + POSTING_READ(DP_A); udelay(200); } -- 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: Ensure that while(INREG()) are bounded.
Add a new macro, wait_for, to simplify the act of waiting on a register to change state. wait_for() takes three arguments, the condition to inspect on every loop, the maximum amount of time to wait and whether to yield the cpu for a length of time after each check. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_crt.c | 17 -- drivers/gpu/drm/i915/intel_display.c | 54 +++--- drivers/gpu/drm/i915/intel_dp.c | 25 +-- drivers/gpu/drm/i915/intel_drv.h | 14 + drivers/gpu/drm/i915/intel_lvds.c| 12 +++ 5 files changed, 46 insertions(+), 76 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index d4d0c1c..45e043c 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -187,8 +187,9 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) DRM_DEBUG_KMS(pch crt adpa 0x%x, adpa); I915_WRITE(PCH_ADPA, adpa); - while ((I915_READ(PCH_ADPA) ADPA_CRT_HOTPLUG_FORCE_TRIGGER) != 0) - ; + if (wait_for((I915_READ(PCH_ADPA) ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, +1000, 1)) + DRM_DEBUG_DRIVER(timed out waiting for FORCE_TRIGGER); if (HAS_PCH_CPT(dev)) { I915_WRITE(PCH_ADPA, temp); @@ -239,17 +240,13 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; for (i = 0; i tries ; i++) { - unsigned long timeout; /* turn on the FORCE_DETECT */ I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); - timeout = jiffies + msecs_to_jiffies(1000); /* wait for FORCE_DETECT to go off */ - do { - if (!(I915_READ(PORT_HOTPLUG_EN) - CRT_HOTPLUG_FORCE_DETECT)) - break; - msleep(1); - } while (time_after(timeout, jiffies)); + if (wait_for((I915_READ(PORT_HOTPLUG_EN) + CRT_HOTPLUG_FORCE_DETECT) == 0, +1000, 1)) + DRM_DEBUG_DRIVER(timed out waiting for FORCE_DETECT to go off); } stat = I915_READ(PORT_HOTPLUG_STAT); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5cae58a..958d9aa 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1034,7 +1034,6 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) void i8xx_disable_fbc(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev-dev_private; - unsigned long timeout = jiffies + msecs_to_jiffies(1); u32 fbc_ctl; if (!I915_HAS_FBC(dev)) @@ -1049,12 +1048,9 @@ void i8xx_disable_fbc(struct drm_device *dev) I915_WRITE(FBC_CONTROL, fbc_ctl); /* Wait for compressing bit to clear */ - while (I915_READ(FBC_STATUS) FBC_STAT_COMPRESSING) { - if (time_after(jiffies, timeout)) { - DRM_DEBUG_DRIVER(FBC idle timed out\n); - break; - } - ; /* do nothing */ + if (wait_for((I915_READ(FBC_STATUS) FBC_STAT_COMPRESSING) == 0, 10, 0)) { + DRM_DEBUG_KMS(FBC idle timed out\n); + return; } intel_wait_for_vblank(dev); @@ -1845,7 +1841,6 @@ static int ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; int trans_dpll_sel = (pipe == 0) ? 0 : 1; u32 temp; - int n; u32 pipe_bpc; temp = I915_READ(pipeconf_reg); @@ -2040,9 +2035,8 @@ static int ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) temp |= pipe_bpc; I915_WRITE(transconf_reg, temp | TRANS_ENABLE); - while ((I915_READ(transconf_reg) TRANS_STATE_ENABLE) == 0) - ; - + if (wait_for(I915_READ(transconf_reg) TRANS_STATE_ENABLE, 10, 0)) + DRM_DEBUG_KMS(failed to enable transcoder\n); } intel_crtc_load_lut(crtc); @@ -2074,19 +2068,9 @@ static int ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) if (temp PIPEACONF_ENABLE) { I915_WRITE(pipeconf_reg, temp ~PIPEACONF_ENABLE); - n = 0; /* wait for cpu pipe off, pipe state */ - while (I915_READ(pipeconf_reg) I965_PIPECONF_ACTIVE) { - n++; - if (n 60) { - udelay(500
[Intel-gfx] [PATCH] drm/i915: FBC is updated within set_base() so remove second call in mode_set()
The FBC is dependent upon a few details of the framebuffer so it is required to be updated within set_base(), so remove the redundant call from mode_set(). Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c |3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 958d9aa..c920508 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4041,9 +4041,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, /* Flush the plane changes */ ret = intel_pipe_set_base(crtc, x, y, old_fb); - if ((IS_I965G(dev) || plane == 0)) - intel_update_fbc(crtc, crtc-mode); - intel_update_watermarks(dev); drm_vblank_post_modeset(dev, pipe); -- 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: Implement fair lru eviction across both rings. (v2)
On Fri, 6 Aug 2010 20:58:30 +0200, Daniel Vetter dan...@ffwll.ch wrote: On Fri, Aug 06, 2010 at 12:25:45PM +0100, Chris Wilson wrote: + return i915_gem_evict_everything(dev); I think this should be equivalent to return -ENOMEM; Yes, we could return -ENOSPC and then do_execbuffer() would unpin and call i915_gem_evict_everything() before retrying. I'm happy for anybody to paint it a completely different colour just as soon as it is heading upstream. :) -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Append the object onto the inactive list on binding.
In order to properly track bound objects, they need to exist on one of the inactive/active lists or be pinned. As this is a requirement, do the work inside i915_gem_bind_to_gtt() rather than dotted around the callsites. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c |9 - 1 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 63251c9..69753bd 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1159,8 +1159,6 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) if (ret) goto unlock; - list_add_tail(obj_priv-list, dev_priv-mm.inactive_list); - ret = i915_gem_object_set_to_gtt_domain(obj, write); if (ret) goto unlock; @@ -1416,7 +1414,6 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, mutex_unlock(dev-struct_mutex); return ret; } - list_add_tail(obj_priv-list, dev_priv-mm.inactive_list); } drm_gem_object_unreference(obj); @@ -2517,6 +2514,9 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) atomic_inc(dev-gtt_count); atomic_add(obj-size, dev-gtt_memory); + /* keep track of bounds object by adding it to the inactive list */ + list_add_tail(obj_priv-list, dev_priv-mm.inactive_list); + /* Assert that the object is not currently in any GPU domain. As it * wasn't in the GTT, there shouldn't be any way it could have been in * a GPU cache @@ -4017,8 +4017,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) atomic_inc(dev-pin_count); atomic_add(obj-size, dev-pin_memory); if (!obj_priv-active - (obj-write_domain I915_GEM_GPU_DOMAINS) == 0 - !list_empty(obj_priv-list)) + (obj-write_domain I915_GEM_GPU_DOMAINS) == 0) list_del_init(obj_priv-list); } i915_verify_inactive(dev, __FILE__, __LINE__); -- 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: Disable FDI link before retraining.
On Fri, 06 Aug 2010 14:21:59 -0700, Eric Anholt e...@anholt.net wrote: On Tue, 3 Aug 2010 08:12:12 +0100, Chris Wilson ch...@chris-wilson.co.uk wrote: At the moment, we have a habit of occasionally performing a double dpms on. This confuses the FDI link training performed on a dpms on as we can only adjust the settings whilst the link is disabled and the second attempt at training fails. A simple defensive workaround is to always disable the link prior to adjustment and re-enabling on dpms on. With the drm fix to not re-dpms the crtc, is this one still needed? No. I had to disable both this and Dave Airlie's double dpms defense, but with the drm crtc dpms fix this patch is no longer required. -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx