Re: [Intel-gfx] [PATCH] drm/i915: fix tiling limits for i915 class hw

2010-04-15 Thread Chris Wilson
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.

2010-04-22 Thread Chris Wilson
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

2010-04-22 Thread Chris Wilson
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.

2010-05-09 Thread Chris Wilson
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.

2010-05-11 Thread Chris Wilson
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.

2010-05-11 Thread Chris Wilson
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

2010-05-17 Thread Chris Wilson
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

2010-05-19 Thread Chris Wilson
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

2010-05-25 Thread Chris Wilson
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()

2010-05-26 Thread Chris Wilson
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

2010-05-27 Thread Chris Wilson
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

2010-05-27 Thread Chris Wilson
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.

2010-05-27 Thread Chris Wilson
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.

2010-05-27 Thread Chris Wilson
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.

2010-05-27 Thread Chris Wilson
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

2010-05-27 Thread Chris Wilson
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

2010-05-27 Thread Chris Wilson
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()

2010-05-27 Thread Chris Wilson
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

2010-06-06 Thread Chris Wilson
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.

2010-06-06 Thread Chris Wilson
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.

2010-06-07 Thread Chris Wilson
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

2010-06-12 Thread Chris Wilson
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

2010-06-16 Thread Chris Wilson
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

2010-06-23 Thread Chris Wilson
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

2010-06-30 Thread Chris Wilson
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

2010-07-01 Thread Chris Wilson
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.

2010-07-02 Thread Chris Wilson
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.

2010-07-02 Thread Chris Wilson
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

2010-07-02 Thread Chris Wilson
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

2010-07-02 Thread Chris Wilson
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

2010-07-02 Thread Chris Wilson
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.

2010-07-02 Thread Chris Wilson
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

2010-07-02 Thread Chris Wilson
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.

2010-07-02 Thread Chris Wilson
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

2010-07-05 Thread Chris Wilson
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)

2010-07-05 Thread Chris Wilson
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.

2010-07-05 Thread Chris Wilson
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.

2010-07-05 Thread Chris Wilson
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.

2010-07-10 Thread Chris Wilson
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.

2010-07-13 Thread Chris Wilson
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

2010-07-17 Thread Chris Wilson
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.

2010-07-17 Thread Chris Wilson
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()

2010-07-17 Thread Chris Wilson
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????

2010-07-18 Thread Chris Wilson
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

2010-07-19 Thread Chris Wilson
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

2010-07-19 Thread Chris Wilson
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

2010-07-19 Thread Chris Wilson
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.

2010-07-21 Thread Chris Wilson
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?

2010-07-23 Thread Chris Wilson
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

2010-07-23 Thread Chris Wilson
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)

2010-07-23 Thread Chris Wilson
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)

2010-07-23 Thread Chris Wilson
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)

2010-07-23 Thread Chris Wilson
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)

2010-07-23 Thread Chris Wilson
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

2010-07-23 Thread Chris Wilson
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

2010-07-24 Thread Chris Wilson
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

2010-07-25 Thread Chris Wilson
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

2010-07-28 Thread Chris Wilson
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

2010-07-29 Thread Chris Wilson
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

2010-07-30 Thread Chris Wilson
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

2010-08-02 Thread Chris Wilson
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

2010-08-04 Thread Chris Wilson
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.

2010-08-04 Thread Chris Wilson
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.

2010-08-04 Thread Chris Wilson
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.

2010-08-04 Thread Chris Wilson
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

2010-08-04 Thread Chris Wilson
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.

2010-08-04 Thread Chris Wilson
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

2010-08-04 Thread Chris Wilson
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

2010-08-04 Thread Chris Wilson
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

2010-08-04 Thread Chris Wilson
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

2010-08-04 Thread Chris Wilson
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.

2010-08-04 Thread Chris Wilson
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

2010-08-04 Thread Chris Wilson
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

2010-08-04 Thread Chris Wilson
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.

2010-08-04 Thread Chris Wilson
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

2010-08-04 Thread Chris Wilson
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.

2010-08-04 Thread Chris Wilson
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

2010-08-04 Thread Chris Wilson
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

2010-08-04 Thread Chris Wilson
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.

2010-08-04 Thread Chris Wilson
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.

2010-08-04 Thread Chris Wilson
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

2010-08-04 Thread Chris Wilson
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()

2010-08-04 Thread Chris Wilson
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

2010-08-04 Thread Chris Wilson
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.

2010-08-04 Thread Chris Wilson
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.

2010-08-04 Thread Chris Wilson
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

2010-08-04 Thread Chris Wilson
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.

2010-08-04 Thread Chris Wilson
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

2010-08-04 Thread Chris Wilson
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.

2010-08-04 Thread Chris Wilson
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.

2010-08-05 Thread Chris Wilson
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

2010-08-05 Thread Chris Wilson
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

2010-08-06 Thread Chris Wilson
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)

2010-08-06 Thread Chris Wilson
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

2010-08-06 Thread Chris Wilson
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.

2010-08-06 Thread Chris Wilson
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()

2010-08-06 Thread Chris Wilson
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)

2010-08-06 Thread Chris Wilson
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.

2010-08-06 Thread Chris Wilson
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.

2010-08-06 Thread Chris Wilson
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


  1   2   3   4   5   6   7   8   9   10   >