[Nouveau] [Bug 49142] New: [NV4A] OpengGL content corruption when width = 2048

2012-04-25 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=49142

 Bug #: 49142
   Summary: [NV4A] OpengGL content corruption when width = 2048
Classification: Unclassified
   Product: Mesa
   Version: git
  Platform: Other
OS/Version: All
Status: NEW
  Severity: normal
  Priority: medium
 Component: Drivers/DRI/nouveau
AssignedTo: nouveau@lists.freedesktop.org
ReportedBy: michel.herm...@gmail.com


When a window with opengl content with a width = 2048 the right part show
random memory. Was easy to discover for me due since I'm using dual head with
kwin opengl rendering. glxdemo produce the same corruption if enlarged enougth.
Thought I was not really able to test if the same kind of problem appends with
expending the height.
Note that this is a regression in nv30 from nvfx.

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [Bug 49148] New: nv20_state_fb.c:50: get_rt_format: Assertion `0' failed.

2012-04-25 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=49148

 Bug #: 49148
   Summary: nv20_state_fb.c:50: get_rt_format: Assertion `0'
failed.
Classification: Unclassified
   Product: xorg
   Version: unspecified
  Platform: x86 (IA32)
OS/Version: Linux (All)
Status: NEW
  Severity: normal
  Priority: medium
 Component: Driver/nouveau
AssignedTo: nouveau@lists.freedesktop.org
ReportedBy: johndo...@rambler.ru
 QAContact: xorg-t...@lists.x.org


Lubuntu 11.10

0.0 VGA compatible controller: nVidia Corporation NV25 [GeForce4 Ti 4400] (rev
a3)
X.Org version: 1.11.2.902
  dimensions:1024x768 pixels (270x203 millimeters)
  depth of root window:24 planes
direct rendering: Yes
server glx vendor string: SGI
server glx version string: 1.4
--
OpenGL vendor string: Nouveau
OpenGL renderer string: Mesa DRI nv25 x86/MMX/SSE2
OpenGL version string: 1.2 Mesa 8.0.2
Linux 3.1.3-030103-generic
xserver-xorg-video-nouveau
1:0.0.16+git20120328.ab7291d3-0ubuntu0sarvatt~oneiric

Start of some 3D applications. Example 

SweetHome3D-3.3$ ./SweetHome3D
JAVA 3D: OpenGL 1.2 detected; will run with reduced functionality
JAVA 3D: OpenGL 1.2 detected; will run with reduced functionality
java: nv20_state_fb.c:50: get_rt_format: Assertion `0' failed.

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [Bug 49148] nv20_state_fb.c:50: get_rt_format: Assertion `0' failed.

2012-04-25 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=49148

--- Comment #1 from Lucas Stach d...@lynxeye.de 2012-04-25 12:51:55 PDT ---
Created attachment 60588
  -- https://bugs.freedesktop.org/attachment.cgi?id=60588
proposed fix

Could you please try the attached patch? It's only compile tested, as I don't
have any vieux hardware and you have to compile mesa from git, but it should be
worth a try.

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [Bug 48890] dmesg full of DATA_ERROR SEMANTIC_PTSZ_OVER_LIMIT errors on nouveau driver

2012-04-25 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=48890

--- Comment #6 from Alen Skondro askon...@gmail.com 2012-04-25 14:04:48 PDT 
---
Confirmed, there are no error messages anymore.

Thank you!

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH v2 1/4] drm/nouveau: base fence timeout on time of emission

2012-04-25 Thread Marcin Slusarz
Wait loop can be interrupted by signal, so if signals are raised
periodically (e.g. SIGALRM) this loop may never finish. Use
emission time as a base for fence timeout.

Signed-off-by: Marcin Slusarz marcin.slus...@gmail.com
---
 drivers/gpu/drm/nouveau/nouveau_fence.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c 
b/drivers/gpu/drm/nouveau/nouveau_fence.c
index a22b9ad..41ee17d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -44,6 +44,7 @@ struct nouveau_fence {
 
uint32_t sequence;
bool signalled;
+   unsigned long timeout;
 
void (*work)(void *priv, bool signalled);
void *priv;
@@ -172,6 +173,7 @@ nouveau_fence_emit(struct nouveau_fence *fence)
}
OUT_RING (chan, fence-sequence);
FIRE_RING(chan);
+   fence-timeout = jiffies + 3 * DRM_HZ;
 
return 0;
 }
@@ -230,7 +232,8 @@ __nouveau_fence_signalled(void *sync_obj, void *sync_arg)
 int
 __nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr)
 {
-   unsigned long timeout = jiffies + (3 * DRM_HZ);
+   struct nouveau_fence *fence = nouveau_fence(sync_obj);
+   unsigned long timeout = fence-timeout;
unsigned long sleep_time = NSEC_PER_MSEC / 1000;
ktime_t t;
int ret = 0;
-- 
1.7.8.5

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH v2 2/4] drm/nouveau: propagate errors from vm flushes

2012-04-25 Thread Marcin Slusarz
We need this for lockup recovery.

Signed-off-by: Marcin Slusarz marcin.slus...@gmail.com
---
 drivers/gpu/drm/nouveau/nouveau_bo.c  |9 +++--
 drivers/gpu/drm/nouveau/nouveau_drv.h |6 +++---
 drivers/gpu/drm/nouveau/nouveau_vm.c  |   20 ++--
 drivers/gpu/drm/nouveau/nouveau_vm.h  |   18 +-
 drivers/gpu/drm/nouveau/nv50_fifo.c   |4 ++--
 drivers/gpu/drm/nouveau/nv50_graph.c  |   12 
 drivers/gpu/drm/nouveau/nv50_mpeg.c   |4 ++--
 drivers/gpu/drm/nouveau/nv50_vm.c |   30 --
 drivers/gpu/drm/nouveau/nv84_crypt.c  |4 ++--
 drivers/gpu/drm/nouveau/nva3_copy.c   |4 ++--
 drivers/gpu/drm/nouveau/nvc0_vm.c |3 ++-
 11 files changed, 67 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 638ae32..5b0dc50 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -1230,10 +1230,15 @@ nouveau_bo_vma_add(struct nouveau_bo *nvbo, struct 
nouveau_vm *vm,
return ret;
 
if (nvbo-bo.mem.mem_type == TTM_PL_VRAM)
-   nouveau_vm_map(vma, nvbo-bo.mem.mm_node);
+   ret = nouveau_vm_map(vma, nvbo-bo.mem.mm_node);
else
if (nvbo-bo.mem.mem_type == TTM_PL_TT)
-   nouveau_vm_map_sg(vma, 0, size, node);
+   ret = nouveau_vm_map_sg(vma, 0, size, node);
+
+   if (ret) {
+   nouveau_vm_put(vma);
+   return ret;
+   }
 
list_add_tail(vma-head, nvbo-vma_list);
vma-refcount = 1;
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h 
b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 2f8e80a..d120baf 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -320,7 +320,7 @@ struct nouveau_exec_engine {
int  (*object_new)(struct nouveau_channel *, int engine,
   u32 handle, u16 class);
void (*set_tile_region)(struct drm_device *dev, int i);
-   void (*tlb_flush)(struct drm_device *, int engine);
+   int (*tlb_flush)(struct drm_device *, int engine);
 };
 
 struct nouveau_instmem_engine {
@@ -387,7 +387,7 @@ struct nouveau_fifo_engine {
void (*destroy_context)(struct nouveau_channel *);
int  (*load_context)(struct nouveau_channel *);
int  (*unload_context)(struct drm_device *);
-   void (*tlb_flush)(struct drm_device *dev);
+   int  (*tlb_flush)(struct drm_device *dev);
 };
 
 struct nouveau_display_engine {
@@ -1246,7 +1246,7 @@ extern int  nv50_fifo_create_context(struct 
nouveau_channel *);
 extern void nv50_fifo_destroy_context(struct nouveau_channel *);
 extern int  nv50_fifo_load_context(struct nouveau_channel *);
 extern int  nv50_fifo_unload_context(struct drm_device *);
-extern void nv50_fifo_tlb_flush(struct drm_device *dev);
+extern int  nv50_fifo_tlb_flush(struct drm_device *dev);
 
 /* nvc0_fifo.c */
 extern int  nvc0_fifo_init(struct drm_device *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_vm.c 
b/drivers/gpu/drm/nouveau/nouveau_vm.c
index 2bf6c03..e2d4853 100644
--- a/drivers/gpu/drm/nouveau/nouveau_vm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_vm.c
@@ -27,7 +27,7 @@
 #include nouveau_mm.h
 #include nouveau_vm.h
 
-void
+int
 nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_mem *node)
 {
struct nouveau_vm *vm = vma-vm;
@@ -67,16 +67,16 @@ nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, 
struct nouveau_mem *node)
}
}
 
-   vm-flush(vm);
+   return vm-flush(vm);
 }
 
-void
+int
 nouveau_vm_map(struct nouveau_vma *vma, struct nouveau_mem *node)
 {
-   nouveau_vm_map_at(vma, 0, node);
+   return nouveau_vm_map_at(vma, 0, node);
 }
 
-void
+int
 nouveau_vm_map_sg(struct nouveau_vma *vma, u64 delta, u64 length,
  struct nouveau_mem *mem)
 {
@@ -110,10 +110,10 @@ nouveau_vm_map_sg(struct nouveau_vma *vma, u64 delta, u64 
length,
}
}
 
-   vm-flush(vm);
+   return vm-flush(vm);
 }
 
-void
+int
 nouveau_vm_unmap_at(struct nouveau_vma *vma, u64 delta, u64 length)
 {
struct nouveau_vm *vm = vma-vm;
@@ -144,13 +144,13 @@ nouveau_vm_unmap_at(struct nouveau_vma *vma, u64 delta, 
u64 length)
}
}
 
-   vm-flush(vm);
+   return vm-flush(vm);
 }
 
-void
+int
 nouveau_vm_unmap(struct nouveau_vma *vma)
 {
-   nouveau_vm_unmap_at(vma, 0, (u64)vma-node-length  12);
+   return nouveau_vm_unmap_at(vma, 0, (u64)vma-node-length  12);
 }
 
 static void
diff --git a/drivers/gpu/drm/nouveau/nouveau_vm.h 
b/drivers/gpu/drm/nouveau/nouveau_vm.h
index 4fb6e72..59dc206 100644
--- a/drivers/gpu/drm/nouveau/nouveau_vm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_vm.h
@@ -73,7 +73,7 @@ struct nouveau_vm {
void (*map_sg)(struct nouveau_vma *, struct nouveau_gpuobj *,
   struct nouveau_mem *, u32 pte, u32 cnt, 

[Nouveau] [PATCH v2 3/4] drm/nv50: let applications hanging on vm flush to be killed

2012-04-25 Thread Marcin Slusarz
Signed-off-by: Marcin Slusarz marcin.slus...@gmail.com
---
 drivers/gpu/drm/nouveau/nv50_graph.c |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c 
b/drivers/gpu/drm/nouveau/nv50_graph.c
index 6899547..a61853f 100644
--- a/drivers/gpu/drm/nouveau/nv50_graph.c
+++ b/drivers/gpu/drm/nouveau/nv50_graph.c
@@ -435,6 +435,11 @@ nv84_graph_tlb_flush(struct drm_device *dev, int engine)
if ((tmp  7) == 1)
idle = false;
}
+
+   if (fatal_signal_pending(current)) {
+   ret = -ERESTARTSYS;
+   break;
+   }
} while (!idle  !(timeout = ptimer-read(dev) - start  20));
 
if (timeout) {
-- 
1.7.8.5

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH v2 4/4] drm/nouveau: gpu lockup recovery

2012-04-25 Thread Marcin Slusarz
Overall idea:
Detect lockups by watching for timeouts (vm flush / fence), return -EIOs,
handle them at ioctl level, reset the GPU and repeat last ioctl.

GPU reset is done by doing suspend / resume cycle with few tweaks:
- CPU-only bo eviction
- ignoring vm flush / fence timeouts
- shortening waits

Signed-off-by: Marcin Slusarz marcin.slus...@gmail.com
---
 drivers/gpu/drm/nouveau/Makefile   |2 +-
 drivers/gpu/drm/nouveau/nouveau_bo.c   |2 +-
 drivers/gpu/drm/nouveau/nouveau_channel.c  |5 +-
 drivers/gpu/drm/nouveau/nouveau_drv.c  |   56 ++-
 drivers/gpu/drm/nouveau/nouveau_drv.h  |   45 -
 drivers/gpu/drm/nouveau/nouveau_fence.c|7 +-
 drivers/gpu/drm/nouveau/nouveau_gem.c  |   14 +++-
 drivers/gpu/drm/nouveau/nouveau_notifier.c |3 +
 drivers/gpu/drm/nouveau/nouveau_object.c   |6 +
 drivers/gpu/drm/nouveau/nouveau_reset.c|  148 
 drivers/gpu/drm/nouveau/nouveau_state.c|6 +
 drivers/gpu/drm/nouveau/nv50_graph.c   |   11 +-
 12 files changed, 290 insertions(+), 15 deletions(-)
 create mode 100644 drivers/gpu/drm/nouveau/nouveau_reset.c

diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
index 03860f5..77d0c33 100644
--- a/drivers/gpu/drm/nouveau/Makefile
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -9,7 +9,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o 
nouveau_mem.o \
  nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \
  nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \
  nouveau_display.o nouveau_connector.o nouveau_fbcon.o \
- nouveau_hdmi.o nouveau_dp.o nouveau_ramht.o \
+ nouveau_hdmi.o nouveau_dp.o nouveau_ramht.o nouveau_reset.o \
 nouveau_pm.o nouveau_volt.o nouveau_perf.o nouveau_temp.o \
 nouveau_mm.o nouveau_vm.o nouveau_mxm.o nouveau_gpio.o \
  nv04_timer.o \
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 5b0dc50..7de6cad 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -936,7 +936,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, 
bool intr,
}
 
/* Software copy if the card isn't up and running yet. */
-   if (!dev_priv-channel) {
+   if (!dev_priv-channel || nouveau_gpu_reset_in_progress(dev_priv-dev)) 
{
ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, 
no_wait_gpu, new_mem);
goto out;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c 
b/drivers/gpu/drm/nouveau/nouveau_channel.c
index 846afb0..c0fa5a7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_channel.c
+++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
@@ -420,7 +420,7 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
init-fb_ctxdma_handle,
init-tt_ctxdma_handle);
if (ret)
-   return ret;
+   goto out;
init-channel  = chan-id;
 
if (nouveau_vram_pushbuf == 0) {
@@ -450,6 +450,9 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
if (ret == 0)
atomic_inc(chan-users); /* userspace reference */
nouveau_channel_put(chan);
+out:
+   if (ret == -EIO)
+   ret = nouveau_reset_device(dev);
return ret;
 }
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c 
b/drivers/gpu/drm/nouveau/nouveau_drv.c
index 090fff6..261e1f5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
@@ -237,7 +237,7 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t 
pm_state)
if (!dev_priv-eng[e])
continue;
 
-   ret = dev_priv-eng[e]-fini(dev, e, true);
+   ret = dev_priv-eng[e]-fini(dev, e, 
!nouveau_gpu_reset_in_progress(dev));
if (ret) {
NV_ERROR(dev, ... engine %d failed: %d\n, e, ret);
goto out_abort;
@@ -443,11 +443,63 @@ nouveau_pci_resume(struct pci_dev *pdev)
return 0;
 }
 
+void intr_rwsem_init(struct intr_rwsem *r)
+{
+   init_rwsem(r-rwsem);
+   mutex_init(r-mutex);
+}
+
+int intr_rwsem_down_read_interruptible(struct intr_rwsem *r)
+{
+   while (down_read_trylock(r-rwsem) == 0) {
+   int ret = mutex_lock_interruptible(r-mutex);
+   if (ret)
+   return ret;
+   mutex_unlock(r-mutex);
+   }
+   return 0;
+}
+
+void intr_rwsem_up_read(struct intr_rwsem *r)
+{
+   up_read(r-rwsem);
+}
+
+void intr_rwsem_down_write(struct intr_rwsem *r)
+{
+   mutex_lock(r-mutex);
+   down_write(r-rwsem);
+}
+
+void intr_rwsem_up_write(struct intr_rwsem *r)
+{
+   up_write(r-rwsem);
+   mutex_unlock(r-mutex);
+}
+
+static long nouveau_ioctl(struct file *filp,
+  

[Nouveau] [Bug 48890] dmesg full of DATA_ERROR SEMANTIC_PTSZ_OVER_LIMIT errors on nouveau driver

2012-04-25 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=48890

Lucas Stach d...@lynxeye.de changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution||FIXED

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH v2 4/4] drm/nouveau: gpu lockup recovery

2012-04-25 Thread Marcin Slusarz
On Wed, Apr 25, 2012 at 11:20:36PM +0200, Marcin Slusarz wrote:
 Overall idea:
 Detect lockups by watching for timeouts (vm flush / fence), return -EIOs,
 handle them at ioctl level, reset the GPU and repeat last ioctl.
 
 GPU reset is done by doing suspend / resume cycle with few tweaks:
 - CPU-only bo eviction
 - ignoring vm flush / fence timeouts
 - shortening waits
 
 Signed-off-by: Marcin Slusarz marcin.slus...@gmail.com
 ---

What changed from v1:
- moved ioctl locking from drm core to nouveau
- made down_reads interruptible
- fixed build bug on 32-bit systems
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 1/2] drm/nouveau: Use drm_vblank_count_and_time() for pageflip completion events.

2012-04-25 Thread Lucas Stach
From: Mario Kleiner mario.klei...@tuebingen.mpg.de

Emit kms pageflip completion events with proper vblank count
and timestamp for the vblank interval in which the pageflip
completed. This makes the timestamps and counts consistent with
what the OML_sync_control spec defines.

v2 Lucas Stach: rebased on top of nouveau tree and resolved trivial
conflict.

Signed-off-by: Mario Kleiner mario.klei...@tuebingen.mpg.de

Conflicts:

drivers/gpu/drm/nouveau/nouveau_display.c
---
 drivers/gpu/drm/nouveau/nouveau_display.c |   29 +++--
 drivers/gpu/drm/nouveau/nouveau_drv.h |1 +
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c 
b/drivers/gpu/drm/nouveau/nouveau_display.c
index 71379f8..2c0f415 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -504,7 +504,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct 
drm_framebuffer *fb,
*s = (struct nouveau_page_flip_state)
{ { }, event, nouveau_crtc(crtc)-index,
  fb-bits_per_pixel, fb-pitches[0], crtc-x, crtc-y,
- new_bo-bo.offset };
+ new_bo-bo.offset, crtc-framedur_ns };
 
/* Choose the channel the flip will be handled in */
chan = nouveau_fence_channel(new_bo-bo.sync_obj);
@@ -550,6 +550,9 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
struct drm_device *dev = chan-dev;
struct nouveau_page_flip_state *s;
unsigned long flags;
+   struct timeval tnow, tvbl;
+
+   do_gettimeofday(tnow);
 
spin_lock_irqsave(dev-event_lock, flags);
 
@@ -563,12 +566,26 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
 struct nouveau_page_flip_state, head);
if (s-event) {
struct drm_pending_vblank_event *e = s-event;
-   struct timeval now;
 
-   do_gettimeofday(now);
-   e-event.sequence = 0;
-   e-event.tv_sec = now.tv_sec;
-   e-event.tv_usec = now.tv_usec;
+   e-event.sequence = drm_vblank_count_and_time(dev, s-crtc, 
tvbl);
+
+   /* Called before vblank count and timestamp have
+* been updated for the vblank interval of flip
+* completion? If so, need to increment vblank count and
+* add one videorefresh duration to returned timestamp
+* to account for this. We assume this happened if we
+* get called over 0.9 frame durations after the last
+* timestamped vblank.
+*/
+   if (10 * (timeval_to_ns(tnow) - timeval_to_ns(tvbl)) 
+9 * s-framedur_ns) {
+   e-event.sequence++;
+   tvbl = ns_to_timeval(timeval_to_ns(tvbl) +
+   s-framedur_ns);
+   }
+
+   e-event.tv_sec = tvbl.tv_sec;
+   e-event.tv_usec = tvbl.tv_usec;
list_add_tail(e-base.link, e-base.file_priv-event_list);
wake_up_interruptible(e-base.file_priv-event_wait);
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h 
b/drivers/gpu/drm/nouveau/nouveau_drv.h
index ab9f9e0..ba10ad7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -203,6 +203,7 @@ struct nouveau_page_flip_state {
struct drm_pending_vblank_event *event;
int crtc, bpp, pitch, x, y;
uint64_t offset;
+   s64 framedur_ns;
 };
 
 enum nouveau_channel_mutex_class {
-- 
1.7.10

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 2/2] drm/nouveau: implement precise vblank timestamping

2012-04-25 Thread Lucas Stach
This patch implements the driver hooks needed for precise vblank
timestamping. This is a complementary patch to Mario Kleiner's
patches to improve swap scheduling. With the complete
patchset applied nouveau will be able to provide correct and
precise pageflip timestamps (compliant to OML_sync_control spec)

v2: - Rebase on top of nouveau tree and update to reflect Ben's
  review feedback.

v3: - Split nv04+ and nv50+ paths into separate functions.
- Do not advertise precise vblank timestamping on nvd9+,
  as it's not confirmed to work and the nv50 codepath may
  not work due to moved regs.

Kudos to Mario for his many helpful comments and testing.

Signed-off-by: Lucas Stach d...@lynxeye.de
Reviewed-by: Mario Kleiner mario.klei...@tuebingen.mpg.de
Tested-by: Mario Kleiner mario.klei...@tuebingen.mpg.de
---
 drivers/gpu/drm/nouveau/nouveau_display.c |   25 ++
 drivers/gpu/drm/nouveau/nouveau_reg.h |9 +++-
 drivers/gpu/drm/nouveau/nv04_display.c|   55 ++
 drivers/gpu/drm/nouveau/nv50_crtc.c   |   19 
 drivers/gpu/drm/nouveau/nv50_display.c|   71 +
 drivers/gpu/drm/nouveau/nvreg.h   |1 +
 6 files changed, 179 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c 
b/drivers/gpu/drm/nouveau/nouveau_display.c
index 2c0f415..810ba72 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -258,6 +258,27 @@ nouveau_display_fini(struct drm_device *dev)
 }
 
 int
+nouveau_get_vblank_timestamp(struct drm_device *dev, int crtc,
+int *max_error, struct timeval *vblank_time,
+unsigned flags)
+{
+   struct drm_crtc *drmcrtc;
+
+   if (crtc  0 || crtc = dev-num_crtcs) {
+   DRM_ERROR(Invalid crtc %d\n, crtc);
+   return -EINVAL;
+   }
+
+   list_for_each_entry(drmcrtc, dev-mode_config.crtc_list, head) {
+   if(nouveau_crtc(drmcrtc)-index == crtc)
+   break;
+   }
+
+   return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error,
+   vblank_time, flags, drmcrtc);
+}
+
+int
 nouveau_display_create(struct drm_device *dev)
 {
struct drm_nouveau_private *dev_priv = dev-dev_private;
@@ -327,6 +348,10 @@ nouveau_display_create(struct drm_device *dev)
if (ret)
goto disp_create_err;
 
+   if (dev-driver-get_scanout_position)
+   dev-driver-get_vblank_timestamp =
+   nouveau_get_vblank_timestamp;
+
if (dev-mode_config.num_crtc) {
ret = drm_vblank_init(dev, dev-mode_config.num_crtc);
if (ret)
diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h 
b/drivers/gpu/drm/nouveau/nouveau_reg.h
index 43a96b9..0ec1945 100644
--- a/drivers/gpu/drm/nouveau/nouveau_reg.h
+++ b/drivers/gpu/drm/nouveau/nouveau_reg.h
@@ -762,7 +762,7 @@
 #define NV50_PDISPLAY_CRTC_CLOCK 0x00610ad0
 #define NV50_PDISPLAY_CRTC_COLOR_CTRL0x00610ae0
 #define NV50_PDISPLAY_CRTC_SYNC_START_TO_BLANK_END   0x00610ae8
-#define NV50_PDISPLAY_CRTC_MODE_UNK1 0x00610af0
+#define NV50_PDISPLAY_CRTC_VBL_START 0x00610af0
 #define NV50_PDISPLAY_CRTC_DISPLAY_TOTAL 0x00610af8
 #define NV50_PDISPLAY_CRTC_SYNC_DURATION 0x00610b00
 #define NV50_PDISPLAY_CRTC_MODE_UNK2 0x00610b08
@@ -800,6 +800,13 @@
 #define NV50_PDISPLAY_SOR_CLK0x00614000
 #define NV50_PDISPLAY_SOR_CLK_CTRL2(i)  ((i) * 0x800 + 
0x614300)
 
+#define NV50_PDISPLAY_CRTC_STAT_VERT(i0)  (0x00616340 + 
0x800*(i0))
+#define NV50_PDISPLAY_CRTC_STAT_VERT_VLINE__MASK   0x
+#define NV50_PDISPLAY_CRTC_STAT_VERT_VBLANK_COUNT__MASK
0x
+#define NV50_PDISPLAY_CRTC_STAT_VERT_VBLANK_COUNT__SHIFT   16
+#define NV50_PDISPLAY_CRTC_STAT_HORZ(i0)  (0x00616344 + 
0x800*(i0))
+#define NV50_PDISPLAY_CRTC_STAT_HORZ_HLINE__MASK   0x
+
 #define NV50_PDISPLAY_VGACRTC(r)((r) + 
0x619400)
 
 #define NV50_PDISPLAY_DAC0x0061a000
diff --git a/drivers/gpu/drm/nouveau/nv04_display.c 
b/drivers/gpu/drm/nouveau/nv04_display.c
index 7047d37..2622953 100644
--- a/drivers/gpu/drm/nouveau/nv04_display.c
+++ b/drivers/gpu/drm/nouveau/nv04_display.c
@@ -26,6 +26,7 @@
 #include drm.h
 #include drm_crtc_helper.h
 
+#include nouveau_crtc.h
 #include nouveau_drv.h
 #include nouveau_fb.h
 #include nouveau_hw.h
@@ -35,6 +36,58 @@
 static void nv04_vblank_crtc0_isr(struct drm_device *);
 static void nv04_vblank_crtc1_isr(struct drm_device *);
 
+int