Re: Mesa shader compiling/optimizing process is too slow

2012-07-09 Thread Chris Forbes
Presumably there needs to be a api-level mechanism to wait for the
background optimization to finish, so that piglit etc can validate the
behavior of the optimized shader?

-- Chris

On Tue, Jul 10, 2012 at 5:17 AM, Eric Anholt  wrote:
> Tiziano Bacocco  writes:
>
>> I've done benchmarks and comparison between proprietary drivers and
>> Mesa, Mesa seems to be up to 200x slower compiling the same shader,
>> since i understand optimizing such part of code may take months or even
>> more, i have thought to solve it this way:
>>
>> Upon calling glLinkProgram , an unoptimized version of the shader (
>> compiles much much faster ) is uploaded to the GPU
>> Then a separate thread is launched that will optimize the shader and as
>> soon it is done, on the next call to glUseProgram it will upload
>> optimized version in place of unoptimized one.
>>
>> This will solve many performance issues and temporary freezes with games
>> that load/unload content while running, while not reducing performance
>> once the background optimization is done
>
> Yeah, we've thought of this, and it would take some work.  Sounds like a
> fun project for someone.
>
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[REGRESSION] nouveau: Memory corruption using nva3 engine for 0xaf

2012-07-09 Thread Henrik Rydberg
On Mon, Jul 09, 2012 at 03:13:25PM +0200, Henrik Rydberg wrote:
> On Thu, Jul 05, 2012 at 10:34:10AM +0200, Henrik Rydberg wrote:
> > On Thu, Jul 05, 2012 at 08:54:46AM +0200, Henrik Rydberg wrote:
> > > > Thanks for tracking down the source of this corruption.  I don't have
> > > > any such hardware, so until someone can figure it out, I think we
> > > > should apply this patch.
> > > 
> > > In that case, I would have to massage the patch a bit first; it
> > > creates a problem with suspend/resume. Might be something with
> > > nva3_pm.c, who knows. I am really stabbing in the dark here. :-)
> > 
> > It seems the suspend/resume problem is unrelated (bad systemd update),
> > so I am fine with applying this as is. Obviously not the best
> > solution, and if I have time I will continue to look for problems in
> > the nva3 copy code, but for now,
> > 
> > Signed-off-by: Henrik Rydberg 
> 
> I have not encountered the problem in a long while, and I do not have
> the patch applied. It is entirely possible that this was fixed by
> something else. Unless you have already applied the patch, I would
> suggest holding on to it to see if the problem reappears.
> 
> Sorry for the churn.

... and there it was again, hours after giving up on it. Oh well.

What makes this bug particularly difficult is that as soon as the
patch is applied, the problem disappears and does not show itself
again - with or without the patch applied. Sounds very much like the
problem is a failure state that does not get reset by current
mainline, but somehow gets reset with the patch applied.

I also learnt that the problem is not in the nva3_copy code itself; I
reverted nva3_copy.c and nva3_pm.c back to v3.4, but the problem persisted.

A DMA problem elsewhere, in the drm code or in the pci layer, seems
more likely than this particular hardware having problems with this
particular copy engine. As it stands, though, applying the patch is
the only thing known to work.

Thanks,
Henrik


Mesa shader compiling/optimizing process is too slow

2012-07-09 Thread Tiziano Bacocco
I've done benchmarks and comparison between proprietary drivers and 
Mesa, Mesa seems to be up to 200x slower compiling the same shader, 
since i understand optimizing such part of code may take months or even 
more, i have thought to solve it this way:

Upon calling glLinkProgram , an unoptimized version of the shader ( 
compiles much much faster ) is uploaded to the GPU
Then a separate thread is launched that will optimize the shader and as 
soon it is done, on the next call to glUseProgram it will upload 
optimized version in place of unoptimized one.

This will solve many performance issues and temporary freezes with games 
that load/unload content while running, while not reducing performance 
once the background optimization is done


[Bug 33309] [855GM] GPU freeze due to overlay hang

2012-07-09 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=33309

Chris Wilson  changed:

   What|Removed |Added

 Status|NEEDINFO|RESOLVED
 Resolution||NOTOURBUG

--- Comment #31 from Chris Wilson  2012-07-09 
11:37:34 PDT ---
Ok, I'm just as surprised; be wary of a surprise attack. In the meantime, have
fun!

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


[Bug 33309] [855GM] GPU freeze due to overlay hang

2012-07-09 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=33309

--- Comment #30 from stefan  2012-07-09 11:18:52 PDT 
---
Hi Daniel,
(In reply to comment #29)
> (In reply to comment #28)
> > are there any news on this issue?
> > The 3.4 and 3.5-rc series seem stable wrt this issue,
> > but unfortunately something broke resume from s2ram badly,
> > the backlight stays off and the machine does not respond
> > even to SysRq and I need to do a hard power-off.
> 
> That's good&bad news. Can you try to bisect the backlight regression that has
> been introduce in 3.4 and open a new bug report? That usually helps in fixing
> it ...

It turns out to be an ACPICA regression not related to graphics at all.

As for this issue, I did not observe any more hangs with v3.4 or 3.5-rc, *yet*.
It is hard to tell for sure since it usually takes a while (sometimes hours)
for it to occure. Which makes it also almost impossible to bisect and to find
the commit that might have fixed it.

Cheers,
Stefan.

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


[RFC] drm/radeon: restoring ring commands in case of a lockup

2012-07-09 Thread Michel Dänzer
On Mon, 2012-07-09 at 12:41 +0200, Christian K?nig wrote: 
> Hi,
> 
> The following patchset tries to save and restore the not yet processed 
> commands
> from the rings in case of a lockup and with that should make a userspace
> problem with a single application far less problematic.
> 
> The first four patches are just stuff this patchset is based upon, followed by
> four patches which fix various bugs found while working on this feature.
> 
> Followed by patches which change the way how memory is saved/restored on
> suspend/resume, basically before we have unpinned most of the buffer objects 
> so
> it could be move from vram into system memory. But that is mostly unnecessary
> cause the buffer object either are already in system memory or their content
> can be easily reinitialized.
> 
> The last three patches implement the actual tracking and restoring of commands
> in case of a lockup. Please take a look and review.

Patches 3, 5 and 14 are

Reviewed-by: Michel D?nzer 


-- 
Earthling Michel D?nzer   |   http://www.amd.com
Libre software enthusiast |  Debian, X and DRI developer


[Bug 51870] r600_streamout=1 nothing change

2012-07-09 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=51870

Marek Ol??k  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution||NOTABUG

--- Comment #1 from Marek Ol??k  2012-07-09 10:50:59 PDT 
---
Those environment variables aren't required anymore. GLSL 1.3 and streamout are
enabled by default. The only thing missing is MSAA and there is no way to
enable it at the moment. Closing.

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


[PATCH 15/16] drm/radeon: implement ring commit tracking

2012-07-09 Thread Christian König
On 09.07.2012 17:36, Jerome Glisse wrote:
> On Mon, Jul 9, 2012 at 6:42 AM, Christian K?nig  
> wrote:
>> Signed-off-by: Christian K?nig 
> Bit too complex to my taste, what about attached patch, it's lot
> simpler. (Haven't tested
> the patch but it should work)
Cool idea! Depending on the writeback mechanism might not be the best 
part of it, but in general speaking all rings should have more than 
enough scratch registers for that!!!

Going to change it.

Thanks,
Christian.

>
> Cheers,
> Jerome
>
>> ---
>>   drivers/gpu/drm/radeon/radeon.h  |3 +++
>>   drivers/gpu/drm/radeon/radeon_ring.c |   39 
>> --
>>   2 files changed, 40 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/radeon/radeon.h 
>> b/drivers/gpu/drm/radeon/radeon.h
>> index fef4257..9c11be8 100644
>> --- a/drivers/gpu/drm/radeon/radeon.h
>> +++ b/drivers/gpu/drm/radeon/radeon.h
>> @@ -637,6 +637,9 @@ struct radeon_ring {
>>  u32 ptr_reg_shift;
>>  u32 ptr_reg_mask;
>>  u32 nop;
>> +   unsigned*track_back;
>> +   unsignedtrack_ptr;
>> +   unsignedtrack_mask;
>>   };
>>
>>   /*
>> diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
>> b/drivers/gpu/drm/radeon/radeon_ring.c
>> index d9b2e45..994c98c 100644
>> --- a/drivers/gpu/drm/radeon/radeon_ring.c
>> +++ b/drivers/gpu/drm/radeon/radeon_ring.c
>> @@ -276,6 +276,8 @@ void radeon_ring_commit(struct radeon_device *rdev, 
>> struct radeon_ring *ring)
>>  DRM_MEMORYBARRIER();
>>  WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & 
>> ring->ptr_reg_mask);
>>  (void)RREG32(ring->wptr_reg);
>> +   ring->track_back[ring->track_ptr++] = ring->wptr_old;
>> +   ring->track_ptr &= ring->track_mask;
>>   }
>>
>>   void radeon_ring_unlock_commit(struct radeon_device *rdev, struct 
>> radeon_ring *ring)
>> @@ -362,6 +364,27 @@ bool radeon_ring_test_lockup(struct radeon_device 
>> *rdev, struct radeon_ring *rin
>>  return false;
>>   }
>>
>> +static unsigned radeon_ring_first_valid_commit(struct radeon_ring *ring)
>> +{
>> +   unsigned i, c, result = ring->track_ptr;
>> +   i = ring->track_ptr - 1;
>> +   while (i != ring->track_ptr) {
>> +   i &= ring->track_mask;
>> +   c = ring->track_back[i];
>> +
>> +   if (ring->wptr >= ring->rptr) {
>> +   if (c < ring->rptr || c >= ring->wptr)
>> +   break;
>> +   } else {
>> +   if (c < ring->rptr && c >= ring->wptr)
>> +   break;
>> +   }
>> +
>> +   result = i--;
>> +   }
>> +   return result;
>> +}
>> +
>>   int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring,
>>   unsigned ring_size, unsigned align,
>>   unsigned rptr_offs, unsigned rptr_reg, unsigned 
>> wptr_reg,
>> @@ -403,6 +426,10 @@ int radeon_ring_init(struct radeon_device *rdev, struct 
>> radeon_ring *ring,
>>  dev_err(rdev->dev, "(%d) ring map failed\n", r);
>>  return r;
>>  }
>> +   ring->track_back = kmalloc(ring_size / align, GFP_KERNEL);
>> +   memset(ring->track_back, 0, ring_size / align);
>> +   ring->track_ptr = 0;
>> +   ring->track_mask = ((ring->ring_size / 4) / align) - 1;
>>  }
>>  ring->ptr_mask = (ring->ring_size / 4) - 1;
>>  ring->ring_free_dw = ring->ring_size / 4;
>> @@ -422,6 +449,7 @@ void radeon_ring_fini(struct radeon_device *rdev, struct 
>> radeon_ring *ring)
>>  ring->ready = false;
>>  ring->ring = NULL;
>>  ring->ring_obj = NULL;
>> +   kfree(ring->track_back);
>>  mutex_unlock(&rdev->ring_lock);
>>
>>  if (ring_obj) {
>> @@ -447,7 +475,7 @@ static int radeon_debugfs_ring_info(struct seq_file *m, 
>> void *data)
>>  struct radeon_device *rdev = dev->dev_private;
>>  int ridx = *(int*)node->info_ent->data;
>>  struct radeon_ring *ring = &rdev->ring[ridx];
>> -   unsigned count, i, j;
>> +   unsigned count, i, j, commit;
>>
>>  radeon_ring_free_size(rdev, ring);
>>  count = (ring->ring_size / 4) - ring->ring_free_dw;
>> @@ -457,9 +485,16 @@ static int radeon_debugfs_ring_info(struct seq_file *m, 
>> void *data)
>>  seq_printf(m, "driver's copy of the rptr: 0x%08x\n", ring->rptr);
>>  seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw);
>>  seq_printf(m, "%u dwords in ring\n", count);
>> +   commit = radeon_ring_first_valid_commit(ring);
>>  i = ring->rptr;
>>  for (j = 0; j <= count; j++) {
>> -   seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]);
>> +   seq_printf(m, "r[%04x]=0x%08

[PATCH 13/16] drm/radeon: move radeon_ib_ring_tests out of chipset code

2012-07-09 Thread Michel Dänzer
On Mon, 2012-07-09 at 17:22 +0200, Christian K?nig wrote: 
> On 09.07.2012 17:06, Michel D?nzer wrote:
> > On Mon, 2012-07-09 at 12:42 +0200, Christian K?nig wrote:
> >> Making it easier to controlwhen it is executed.
> >>
> >> Signed-off-by: Christian K?nig 
> > [...]
> >> diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
> >> b/drivers/gpu/drm/radeon/radeon_device.c
> >> index 254fdb4..bbd0971 100644
> >> --- a/drivers/gpu/drm/radeon/radeon_device.c
> >> +++ b/drivers/gpu/drm/radeon/radeon_device.c
> >> @@ -822,6 +822,10 @@ int radeon_device_init(struct radeon_device *rdev,
> >>if (r)
> >>return r;
> >>   
> >> +  r = radeon_ib_ring_tests(rdev);
> >> +  if (r)
> >> +  DRM_ERROR("ib ring test failed (%d).\n", r);
> >> +
> >>if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) {
> >>/* Acceleration not working on AGP card try again
> >> * with fallback to PCI or PCIE GART
> > I think this needs to set rdev->accel_working = false on failure, so the
> > AGP -> PCI(e) fallback can kick in.
> 
> See the implementation of radeon_ib_ring_tests, it is already handling 
> that internally.

Oops, I actually did check this when writing the above, but somehow I
failed to see what I was looking for. :}


-- 
Earthling Michel D?nzer   |   http://www.amd.com
Libre software enthusiast |  Debian, X and DRI developer


[Bug 45018] [bisected] rendering regression since added support for virtual address space on cayman v11

2012-07-09 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=45018

--- Comment #65 from Alexandre Demers  2012-07-10 
00:23:46 PDT ---
Created attachment 64053
  --> https://bugs.freedesktop.org/attachment.cgi?id=64053
xsession with drm-next

.xsession with drm-next branch

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


[Bug 45018] [bisected] rendering regression since added support for virtual address space on cayman v11

2012-07-09 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=45018

--- Comment #64 from Alexandre Demers  2012-07-10 
00:22:55 PDT ---
Created attachment 64052
  --> https://bugs.freedesktop.org/attachment.cgi?id=64052
dmesg drm-next

dmesg with latest drm-next branch

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


[PATCH 16/16] drm/radeon: implement ring saving on reset

2012-07-09 Thread Christian König
On 09.07.2012 17:06, Michel D?nzer wrote:
> On Mon, 2012-07-09 at 12:42 +0200, Christian K?nig wrote:
>> Try to save whatever is on the rings when
>> we encounter an lockup.
>>
>> Signed-off-by: Christian K?nig 
> [...]
>> @@ -1005,20 +1010,43 @@ int radeon_gpu_reset(struct radeon_device *rdev)
>>  resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
>>  radeon_suspend(rdev);
>>   
>> +for (i = 0; i < RADEON_NUM_RINGS; ++i) {
>> +ring_sizes[i] = radeon_ring_backup(rdev, &rdev->ring[i],
>> +   &ring_data[i]);
>> +if (ring_sizes[i]) {
>> +saved = true;
>> +dev_info(rdev->dev, "Saved %d dwords of commands "
>> + "on ring %d.\n", ring_sizes[i], i);
>> +}
>> +}
>> +
>> +retry:
>>  r = radeon_asic_reset(rdev);
>>  if (!r) {
>> -dev_info(rdev->dev, "GPU reset succeed\n");
>> +dev_info(rdev->dev, "GPU reset succeed trying to resume\n");
> Could fix the spelling of 'succeeded' while you're at it. :)
Akk, fixed it.
>
>
>>  radeon_resume(rdev);
>> +}
>>   
>> -r = radeon_ib_ring_tests(rdev);
>> -if (r)
>> -DRM_ERROR("ib ring test failed (%d).\n", r);
>> +radeon_restore_bios_scratch_regs(rdev);
>> +drm_helper_resume_force_mode(rdev->ddev);
>> +
>> +if (!r) {
>> +for (i = 0; i < RADEON_NUM_RINGS; ++i) {
>> +radeon_ring_restore(rdev, &rdev->ring[i],
>> +ring_sizes[i], ring_data[i]);
>> +}
> If radeon_asic_reset fails, this leaks the memory referenced by
> ring_data, doesn't it?
Oh yes indeed, going to fix that.

> Also, the added functions aren't documented as mandated by the rules
> Alex proposed.
>
True, also going to fix that.

Christian.



[Bug 45018] [bisected] rendering regression since added support for virtual address space on cayman v11

2012-07-09 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=45018

--- Comment #63 from Alexandre Demers  2012-07-10 
00:21:56 PDT ---
Now running latest drm-next just in case. Always the same error, but with a
little something new: with regular kernel, once the GPU crashed, it stays this
way. With the drm-next branch, it loops. Attaching some files in a moment.

I just started Gnome Shell, then opened a terminal window and launched piglit
r600 tests.

I'm pretty sure (dmesg):
[   66.238981] radeon :01:00.0: bo 88020f46bc00 va 0x0183B000 conflict
with (bo 88021b65d000 0x0183B000 0x0183C000)
[   66.271373] radeon :01:00.0: bo 880222cc9400 va 0x01814000 conflict
with (bo 880221a50800 0x01814000 0x01815000)
[   66.334540] radeon :01:00.0: bo 880222b7 va 0x01809000 conflict
with (bo 8802230a9000 0x01809000 0x0180A000)

corresponds to (.xsession-error):

radeon: Failed to allocate a buffer:
radeon:size  : 256 bytes
radeon:alignment : 256 bytes
radeon:domains   : 2
EE r600_texture.c:869 r600_texture_get_transfer - failed to create temporary
texture to hold untiled copy
Mesa: User error: GL_OUT_OF_MEMORY in glTexSubImage
radeon: Failed to allocate a buffer:
radeon:size  : 256 bytes
radeon:alignment : 256 bytes
radeon:domains   : 2
EE r600_texture.c:869 r600_texture_get_transfer - failed to create temporary
texture to hold untiled copy
radeon: Failed to allocate a buffer:
radeon:size  : 256 bytes
radeon:alignment : 256 bytes
radeon:domains   : 2
EE r600_texture.c:869 r600_texture_get_transfer - failed to create temporary
texture to hold untiled copy

Then (dmesg):

[  196.710933] radeon :01:00.0: GPU lockup CP stall for more than 1msec
[  196.710946] radeon :01:00.0: GPU lockup (waiting for 0x0675
last fence id 0x066c)
[  196.711129] radeon :01:00.0: couldn't schedule ib
[  196.711239] radeon :01:00.0: couldn't schedule ib
[  196.711805] radeon :01:00.0: couldn't schedule ib
[  196.715732] radeon :01:00.0: couldn't schedule ib
[  196.715975] radeon :01:00.0: couldn't schedule ib
[  196.716362] radeon :01:00.0: couldn't schedule ib
[  196.716627] radeon :01:00.0: couldn't schedule ib
[  196.718012] radeon :01:00.0: couldn't schedule ib
[  196.718262] radeon :01:00.0: couldn't schedule ib
[  196.718480] radeon :01:00.0: couldn't schedule ib
[  196.718985] radeon :01:00.0: couldn't schedule ib
[  196.920396] radeon :01:00.0: couldn't schedule ib
[  196.920703] radeon :01:00.0: couldn't schedule ib
[  196.921084] radeon :01:00.0: couldn't schedule ib
[  196.921318] radeon :01:00.0: couldn't schedule ib
[  196.921558] radeon :01:00.0: couldn't schedule ib
[  196.921898] radeon :01:00.0: couldn't schedule ib
[  196.952350] radeon :01:00.0: couldn't schedule ib
[  196.952386] [drm:radeon_cs_ib_chunk] *ERROR* Failed to schedule IB !
[  196.952439] BUG: unable to handle kernel NULL pointer dereference at
0008
[  196.952494] IP: [] radeon_fence_ref+0xd/0x40 [radeon]
[  196.952531] PGD 221dc4067 PUD 2228ff067 PMD 0 
[  196.952556] Oops:  [#1] PREEMPT SMP 
[  196.952579] CPU 1 
[  196.952617] Modules linked in: fuse snd_usb_audio snd_usbmidi_lib
snd_rawmidi powernow_k8 snd_seq_device radeon ttm joydev snd_hda_codec_hdmi
ppdev evdev pwc snd_hda_codec_realtek r8712u(C) r8169 mperf parport_pc parport
sp5100_tco usb_storage uas drm_kms_helper drm videobuf2_vmalloc
videobuf2_memops hid_logitech_dj pcspkr processor snd_hda_intel snd_hda_codec
i2c_algo_bit mii hid_generic videobuf2_core videodev media wmi kvm_amd
snd_hwdep snd_pcm snd_page_alloc snd_timer psmouse i2c_piix4 usbhid
firewire_ohci hid serio_raw i2c_core firewire_core k10temp kvm microcode
crc_itu_t snd edac_core button soundcore edac_mce_amd ext4 crc16 jbd2 mbcache
pata_acpi sr_mod sd_mod cdrom pata_atiixp ata_generic ohci_hcd ahci libahci
libata ehci_hcd usbcore scsi_mod usb_common
[  196.952957] 
[  196.952969] Pid: 715, comm: Xorg Tainted: G C  
3.5.0-rc4-VANILLA-46957-g74da01d #1 Gigabyte Technology Co., Ltd.
GA-MA78GM-S2H/GA-MA78GM-S2H
[  196.953044] RIP: 0010:[]  []
radeon_fence_ref+0xd/0x40 [radeon]
[  196.953092] RSP: 0018:8802230e9b48  EFLAGS: 00010286
...


and it loops.

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


[PATCH 13/16] drm/radeon: move radeon_ib_ring_tests out of chipset code

2012-07-09 Thread Christian König
On 09.07.2012 17:06, Michel D?nzer wrote:
> On Mon, 2012-07-09 at 12:42 +0200, Christian K?nig wrote:
>> Making it easier to controlwhen it is executed.
>>
>> Signed-off-by: Christian K?nig 
> [...]
>> diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
>> b/drivers/gpu/drm/radeon/radeon_device.c
>> index 254fdb4..bbd0971 100644
>> --- a/drivers/gpu/drm/radeon/radeon_device.c
>> +++ b/drivers/gpu/drm/radeon/radeon_device.c
>> @@ -822,6 +822,10 @@ int radeon_device_init(struct radeon_device *rdev,
>>  if (r)
>>  return r;
>>   
>> +r = radeon_ib_ring_tests(rdev);
>> +if (r)
>> +DRM_ERROR("ib ring test failed (%d).\n", r);
>> +
>>  if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) {
>>  /* Acceleration not working on AGP card try again
>>   * with fallback to PCI or PCIE GART
> I think this needs to set rdev->accel_working = false on failure, so the
> AGP -> PCI(e) fallback can kick in.

See the implementation of radeon_ib_ring_tests, it is already handling 
that internally.

> Not sure about the other places where you're adding
> radeon_ib_ring_tests() calls, might need more error handling as well.
radeon_ib_ring_tests is already handling most errors internally, e. g. 
it sets the accel_working and the ring->ready flags to false if anything 
goes wrong. The return value is mostly for the case where we want to try 
the reset a second time if restoring the ring commands leads to another 
lockup. I just doesn't want to ignore the result completely, so the 
additional error message.

Christian.



[PATCH 09/16] drm/radeon: make cp init on cayman more robust

2012-07-09 Thread Christian König
On 09.07.2012 16:43, Jerome Glisse wrote:
> On Mon, Jul 9, 2012 at 6:41 AM, Christian K?nig  
> wrote:
>> It's not critical, but the current code isn't
>> 100% correct.
>>
>> Signed-off-by: Christian K?nig 
>> ---
>>   drivers/gpu/drm/radeon/ni.c |  133 
>> ++-
>>   1 file changed, 56 insertions(+), 77 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
>> index 32a6082..8b1df33 100644
>> --- a/drivers/gpu/drm/radeon/ni.c
>> +++ b/drivers/gpu/drm/radeon/ni.c
>> @@ -987,10 +987,33 @@ static void cayman_cp_fini(struct radeon_device *rdev)
>>
>>   int cayman_cp_resume(struct radeon_device *rdev)
>>   {
>> +   static const int ridx[] = {
>> +   RADEON_RING_TYPE_GFX_INDEX,
>> +   CAYMAN_RING_TYPE_CP1_INDEX,
>> +   CAYMAN_RING_TYPE_CP2_INDEX
>> +   };
>> +   static const unsigned cp_rb_cntl[] = {
>> +   CP_RB0_CNTL,
>> +   CP_RB1_CNTL,
>> +   CP_RB2_CNTL,
>> +   };
>> +   static const unsigned cp_rb_rptr_addr[] = {
>> +   CP_RB0_RPTR_ADDR,
>> +   CP_RB1_RPTR_ADDR,
>> +   CP_RB2_RPTR_ADDR
>> +   };
>> +   static const unsigned cp_rb_rptr_addr_hi[] = {
>> +   CP_RB0_RPTR_ADDR_HI,
>> +   CP_RB1_RPTR_ADDR_HI,
>> +   CP_RB2_RPTR_ADDR_HI
>> +   };
>> +   static const unsigned cp_rb_base[] = {
>> +   CP_RB0_BASE,
>> +   CP_RB1_BASE,
>> +   CP_RB2_BASE
>> +   };
>>  struct radeon_ring *ring;
>> -   u32 tmp;
>> -   u32 rb_bufsz;
>> -   int r;
>> +   int i, r;
>>
>>  /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset 
>> */
>>  WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP |
>> @@ -1012,91 +1035,47 @@ int cayman_cp_resume(struct radeon_device *rdev)
>>
>>  WREG32(CP_DEBUG, (1 << 27));
>>
>> -   /* ring 0 - compute and gfx */
>> -   /* Set ring buffer size */
>> -   ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
>> -   rb_bufsz = drm_order(ring->ring_size / 8);
>> -   tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
>> -#ifdef __BIG_ENDIAN
>> -   tmp |= BUF_SWAP_32BIT;
>> -#endif
>> -   WREG32(CP_RB0_CNTL, tmp);
>> -
>> -   /* Initialize the ring buffer's read and write pointers */
>> -   WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA);
>> -   ring->wptr = 0;
>> -   WREG32(CP_RB0_WPTR, ring->wptr);
>> -
>>  /* set the wb address wether it's enabled or not */
>> -   WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + 
>> RADEON_WB_CP_RPTR_OFFSET) & 0xFFFC);
>> -   WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + 
>> RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
>>  WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + 
>> RADEON_WB_SCRATCH_OFFSET) >> 8) & 0x);
>> +   WREG32(SCRATCH_UMSK, 0xff);
> This looks wrong you set the mask unconditionaly even if writeback is 
> disabled.
writeback is always enabled for NI and APUs, but the register docs say 
that this feature isn't validated for NI and shouldn't be used so I'm 
not sure if enabling it is the right thing to do.

Anyway, it doesn't matter at all since we don't use the scratch register 
writeback anymore and use EOP instead.

Christian.


>
>
>> -   if (rdev->wb.enabled)
>> -   WREG32(SCRATCH_UMSK, 0xff);
>> -   else {
>> -   tmp |= RB_NO_UPDATE;
>> -   WREG32(SCRATCH_UMSK, 0);
>> -   }
>> -
>> -   mdelay(1);
>> -   WREG32(CP_RB0_CNTL, tmp);
>> -
>> -   WREG32(CP_RB0_BASE, ring->gpu_addr >> 8);
>> -
>> -   ring->rptr = RREG32(CP_RB0_RPTR);
>> +   for (i = 0; i < 3; ++i) {
>> +   uint32_t rb_cntl;
>> +   uint64_t addr;
>>
>> -   /* ring1  - compute only */
>> -   /* Set ring buffer size */
>> -   ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
>> -   rb_bufsz = drm_order(ring->ring_size / 8);
>> -   tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
>> +   /* Set ring buffer size */
>> +   ring = &rdev->ring[ridx[i]];
>> +   rb_cntl = drm_order(ring->ring_size / 8);
>> +   rb_cntl |= drm_order(RADEON_GPU_PAGE_SIZE/8) << 8;
>>   #ifdef __BIG_ENDIAN
>> -   tmp |= BUF_SWAP_32BIT;
>> +   rb_cntl |= BUF_SWAP_32BIT;
>>   #endif
>> -   WREG32(CP_RB1_CNTL, tmp);
>> +   WREG32(cp_rb_cntl[i], rb_cntl);
>>
>> -   /* Initialize the ring buffer's read and write pointers */
>> -   WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA);
>> -   ring->wptr = 0;
>> -   WREG32(CP_RB1_WPTR, ring->wptr);
>> -
>> -   /* set the wb address wether it's enabled or not */
>> -   WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + 
>> RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFC);
>> -   WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + 
>> RADEON_WB_CP1_RPTR_OFFS

[PATCH] drm/exynos: Add exynos drm specific fb_mmap function

2012-07-09 Thread Prathyush K
This patch adds a exynos drm specific implementation of fb_mmap
which supports mapping a non-contiguous buffer to user space.
This new function does not assume that the frame buffer is contiguous
and calls dma_mmap_writecombine for mapping the buffer to user space.
dma_mmap_writecombine will be able to map a contiguous buffer as well
as non-contig buffer depending on whether an IOMMU mapping is created
for drm or not.

Signed-off-by: Prathyush K 
---
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |   16 
 1 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c 
b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index d5586cc..b53e638 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -46,8 +46,24 @@ struct exynos_drm_fbdev {
struct exynos_drm_gem_obj   *exynos_gem_obj;
 };

+static int exynos_drm_fb_mmap(struct fb_info *info,
+ struct vm_area_struct *vma)
+{
+   if ((vma->vm_end - vma->vm_start) > info->fix.smem_len)
+   return -EINVAL;
+
+   vma->vm_pgoff = 0;
+   vma->vm_flags |= VM_IO | VM_RESERVED;
+   if (dma_mmap_writecombine(info->device, vma, info->screen_base,
+   info->fix.smem_start, vma->vm_end - vma->vm_start))
+   return -EAGAIN;
+
+   return 0;
+}
+
 static struct fb_ops exynos_drm_fb_ops = {
.owner  = THIS_MODULE,
+   .fb_mmap= exynos_drm_fb_mmap,
.fb_fillrect= cfb_fillrect,
.fb_copyarea= cfb_copyarea,
.fb_imageblit   = cfb_imageblit,
-- 
1.7.0.4



[PATCH 13/16] drm/radeon: move radeon_ib_ring_tests out of chipset code

2012-07-09 Thread Michel Dänzer
On Mon, 2012-07-09 at 12:42 +0200, Christian K?nig wrote: 
> Making it easier to controlwhen it is executed.
> 
> Signed-off-by: Christian K?nig 
[...] 
> diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
> b/drivers/gpu/drm/radeon/radeon_device.c
> index 254fdb4..bbd0971 100644
> --- a/drivers/gpu/drm/radeon/radeon_device.c
> +++ b/drivers/gpu/drm/radeon/radeon_device.c
> @@ -822,6 +822,10 @@ int radeon_device_init(struct radeon_device *rdev,
>   if (r)
>   return r;
>  
> + r = radeon_ib_ring_tests(rdev);
> + if (r)
> + DRM_ERROR("ib ring test failed (%d).\n", r);
> +
>   if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) {
>   /* Acceleration not working on AGP card try again
>* with fallback to PCI or PCIE GART

I think this needs to set rdev->accel_working = false on failure, so the
AGP -> PCI(e) fallback can kick in.

Not sure about the other places where you're adding
radeon_ib_ring_tests() calls, might need more error handling as well.


-- 
Earthling Michel D?nzer   |   http://www.amd.com
Libre software enthusiast |  Debian, X and DRI developer


[PATCH 16/16] drm/radeon: implement ring saving on reset

2012-07-09 Thread Michel Dänzer
On Mon, 2012-07-09 at 12:42 +0200, Christian K?nig wrote: 
> Try to save whatever is on the rings when
> we encounter an lockup.
> 
> Signed-off-by: Christian K?nig 
[...] 
> @@ -1005,20 +1010,43 @@ int radeon_gpu_reset(struct radeon_device *rdev)
>   resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
>   radeon_suspend(rdev);
>  
> + for (i = 0; i < RADEON_NUM_RINGS; ++i) {
> + ring_sizes[i] = radeon_ring_backup(rdev, &rdev->ring[i],
> +&ring_data[i]);
> + if (ring_sizes[i]) {
> + saved = true;
> + dev_info(rdev->dev, "Saved %d dwords of commands "
> +  "on ring %d.\n", ring_sizes[i], i);
> + }
> + }
> +
> +retry:
>   r = radeon_asic_reset(rdev);
>   if (!r) {
> - dev_info(rdev->dev, "GPU reset succeed\n");
> + dev_info(rdev->dev, "GPU reset succeed trying to resume\n");

Could fix the spelling of 'succeeded' while you're at it. :)


>   radeon_resume(rdev);
> + }
>  
> - r = radeon_ib_ring_tests(rdev);
> - if (r)
> - DRM_ERROR("ib ring test failed (%d).\n", r);
> + radeon_restore_bios_scratch_regs(rdev);
> + drm_helper_resume_force_mode(rdev->ddev);
> +
> + if (!r) {
> + for (i = 0; i < RADEON_NUM_RINGS; ++i) {
> + radeon_ring_restore(rdev, &rdev->ring[i],
> + ring_sizes[i], ring_data[i]);
> + }

If radeon_asic_reset fails, this leaks the memory referenced by
ring_data, doesn't it?


Also, the added functions aren't documented as mandated by the rules
Alex proposed.


-- 
Earthling Michel D?nzer   |   http://www.amd.com
Libre software enthusiast |  Debian, X and DRI developer


[PATCH v3] drm/exynos: use __free_page() to deallocate memory

2012-07-09 Thread Inki Dae
this patch uses __free_page() to deallocate the pages allocated
by alloc_page() and the pages doesn't need set_parge_dirty()
and mark_page_accessed() because they aren't from page cache so
removes them.

this patch has a pair with previous patch below,
http://www.spinics.net/lists/dri-devel/msg24382.html

Changelog v2:
remove unnecessary arguments.

Changelog v3:
fix npages type.
- npages can have negative value.

Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c |   21 ++---
 1 files changed, 6 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index dceb69f..3ccda0c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -126,23 +126,14 @@ fail:
 }

 static void exynos_gem_put_pages(struct drm_gem_object *obj,
-   struct page **pages,
-   bool dirty, bool accessed)
+   struct page **pages)
 {
-   int i, npages;
+   int npages;

npages = obj->size >> PAGE_SHIFT;

-   for (i = 0; i < npages; i++) {
-   if (dirty)
-   set_page_dirty(pages[i]);
-
-   if (accessed)
-   mark_page_accessed(pages[i]);
-
-   /* Undo the reference we took when populating the table */
-   page_cache_release(pages[i]);
-   }
+   while (--npages >= 0)
+   __free_page(pages[npages]);

drm_free_large(pages);
 }
@@ -222,7 +213,7 @@ err1:
kfree(buf->sgt);
buf->sgt = NULL;
 err:
-   exynos_gem_put_pages(obj, pages, true, false);
+   exynos_gem_put_pages(obj, pages);
return ret;

 }
@@ -240,7 +231,7 @@ static void exynos_drm_gem_put_pages(struct drm_gem_object 
*obj)
kfree(buf->sgt);
buf->sgt = NULL;

-   exynos_gem_put_pages(obj, buf->pages, true, false);
+   exynos_gem_put_pages(obj, buf->pages);
buf->pages = NULL;

/* add some codes for UNCACHED type here. TODO */
-- 
1.7.4.1



[PATCH v2] drm/exynos: use __free_page() to deallocate memory

2012-07-09 Thread Inki Dae
this patch uses __free_page() to deallocate the pages allocated
by alloc_page() and the pages doesn't need set_parge_dirty()
and mark_page_accessed() because they aren't from page cache so
removes them.

this patch has a pair with previous patch below,
http://www.spinics.net/lists/dri-devel/msg24382.html

Changelog v2:
remove unnecessary arguments.

Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c |   21 ++---
 1 files changed, 6 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index dceb69f..e6ca2b3 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -126,23 +126,14 @@ fail:
 }

 static void exynos_gem_put_pages(struct drm_gem_object *obj,
-   struct page **pages,
-   bool dirty, bool accessed)
+   struct page **pages)
 {
-   int i, npages;
+   unsigned int npages;

npages = obj->size >> PAGE_SHIFT;

-   for (i = 0; i < npages; i++) {
-   if (dirty)
-   set_page_dirty(pages[i]);
-
-   if (accessed)
-   mark_page_accessed(pages[i]);
-
-   /* Undo the reference we took when populating the table */
-   page_cache_release(pages[i]);
-   }
+   while (--npages >= 0)
+   __free_page(pages[npages]);

drm_free_large(pages);
 }
@@ -222,7 +213,7 @@ err1:
kfree(buf->sgt);
buf->sgt = NULL;
 err:
-   exynos_gem_put_pages(obj, pages, true, false);
+   exynos_gem_put_pages(obj, pages);
return ret;

 }
@@ -240,7 +231,7 @@ static void exynos_drm_gem_put_pages(struct drm_gem_object 
*obj)
kfree(buf->sgt);
buf->sgt = NULL;

-   exynos_gem_put_pages(obj, buf->pages, true, false);
+   exynos_gem_put_pages(obj, buf->pages);
buf->pages = NULL;

/* add some codes for UNCACHED type here. TODO */
-- 
1.7.4.1



[PATCH 2/2] drm/exynos: fixed exception to page allocation failure

2012-07-09 Thread Inki Dae
this patch corrects to deallocate the pages allocated already
at alloc_page failure.

Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 4b8b988..d0b3059 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -118,7 +118,7 @@ struct page **exynos_gem_get_pages(struct drm_gem_object 
*obj,
return pages;

 fail:
-   while (i--)
+   while (--i)
__free_page(pages[i]);

drm_free_large(pages);
-- 
1.7.4.1



[PATCH 1/2] drm/exynos: use __free_page() to deallocate memory

2012-07-09 Thread Inki Dae
this patch uses __free_page() to deallocate the pages allocated
by alloc_page() and the pages doesn't need set_parge_dirty()
and mark_page_accessed() because they aren't from page cache so
removes them.

this patch has a pair with previous patch below,
http://www.spinics.net/lists/dri-devel/msg24382.html

Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c |   14 +++---
 1 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index dceb69f..4b8b988 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -129,20 +129,12 @@ static void exynos_gem_put_pages(struct drm_gem_object 
*obj,
struct page **pages,
bool dirty, bool accessed)
 {
-   int i, npages;
+   unsigned int npages;

npages = obj->size >> PAGE_SHIFT;

-   for (i = 0; i < npages; i++) {
-   if (dirty)
-   set_page_dirty(pages[i]);
-
-   if (accessed)
-   mark_page_accessed(pages[i]);
-
-   /* Undo the reference we took when populating the table */
-   page_cache_release(pages[i]);
-   }
+   while (--npages >= 0)
+   __free_page(pages[npages]);

drm_free_large(pages);
 }
-- 
1.7.4.1



[PATCH 0/2] fix memory deallocation and exception

2012-07-09 Thread Inki Dae
this patch corrects to deallocate the pages allocated by alloc_page()
and fixes exception to page allocation failure.

Thanks.

Inki Dae (2):
  drm/exynos: use __free_page() to deallocate memory
  drm/exynos: fixed exception to page allocation failure

 drivers/gpu/drm/exynos/exynos_drm_gem.c |   16 
 1 files changed, 4 insertions(+), 12 deletions(-)

-- 
1.7.4.1



[REGRESSION] nouveau: Memory corruption using nva3 engine for 0xaf

2012-07-09 Thread Henrik Rydberg
On Thu, Jul 05, 2012 at 10:34:10AM +0200, Henrik Rydberg wrote:
> On Thu, Jul 05, 2012 at 08:54:46AM +0200, Henrik Rydberg wrote:
> > > Thanks for tracking down the source of this corruption.  I don't have
> > > any such hardware, so until someone can figure it out, I think we
> > > should apply this patch.
> > 
> > In that case, I would have to massage the patch a bit first; it
> > creates a problem with suspend/resume. Might be something with
> > nva3_pm.c, who knows. I am really stabbing in the dark here. :-)
> 
> It seems the suspend/resume problem is unrelated (bad systemd update),
> so I am fine with applying this as is. Obviously not the best
> solution, and if I have time I will continue to look for problems in
> the nva3 copy code, but for now,
> 
> Signed-off-by: Henrik Rydberg 

I have not encountered the problem in a long while, and I do not have
the patch applied. It is entirely possible that this was fixed by
something else. Unless you have already applied the patch, I would
suggest holding on to it to see if the problem reappears.

Sorry for the churn.

Thanks,
Henrik


[Bug 51870] r600_streamout=1 nothing change

2012-07-09 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=51870

Michel D?nzer  changed:

   What|Removed |Added

 AssignedTo|xorg-driver-ati at lists.x.org |dri-devel at 
lists.freedesktop
   ||.org
  QAContact|xorg-team at lists.x.org   |
Product|xorg|Mesa
Version|7.4 (2008.09)   |git
  Component|Driver/Radeon   |Drivers/Gallium/r600

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


3.5-rc5: radeon acceleration regression on Transmeta system

2012-07-09 Thread Meelis Roos
> > > In 3.4, radeon worked with a glitch - window titles were see-throug (not
> > > drawn). In 3.5-rc5, radeon driver seems to be more careful and disables
> > > acceleration on this system at all. Full dmesg below.
> > 
> > Does it always do it the same? got the dmesg from 3.4 and/or 2.6.32?
> 
> That was a good question. I did some more tries, and it was not 
> repeatable. Sometimes it worked like 3.4 did - rv100 initialized fine, 
> no borders except when maximized, otherwise worked.

Re-tested 3.4.0-rc7 that I had availble from 3.4 times, it worked 4 out 
of 4 times.

> Initial windows border problem seems to have been introduced between 
> 2.6.37 and 2.6.38, bisect is slow.

It's actually more complicated than that. Old kernel images started 
misbehaving from around 2.6.35-rc5 and any kernel older than that was 
OK. When I recompiled the older kernels with squeeze gcc (migh have been 
lenny gcc before, or different answers to make oldconfig), anything from 
current git down to 2.6.33 is broken with radeon.modeset=1 and works (I 
get window titles) with radeon.modeset=0.

2.6.32 works and has kernel modesetting enabled from dmesg but I think I 
did not notice screen going fbcon during boot... maybe it only used the 
modesetting when X started.

So there are 2 different problems (maybe related), the new one above and 
the old one of not seeing some window borders when modesetting and 
acceleration are in use. Maximized windows do have borders.

-- 
Meelis Roos (mroos at linux.ee)


[PATCH v2] drm/exynos: check if framebuffer and gem size are valid or not.

2012-07-09 Thread Inki Dae
with addfb request by user, wrong framebuffer or gem size could be sent
to kernel side so this could induce invalid memory access by dma of a device.
this patch checks if framebuffer and gem size are valid or not to avoid
this issue.

Changelog v2:
use fb->pitches instead of caculating it with fb->width and fb->bpp
as line size.

Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_fb.c |   47 ++-
 1 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c 
b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index 4ccfe43..f1b1008 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -48,6 +48,44 @@ struct exynos_drm_fb {
struct exynos_drm_gem_obj   *exynos_gem_obj[MAX_FB_BUFFER];
 };

+static int check_fb_gem_size(struct drm_device *drm_dev,
+   struct drm_framebuffer *fb,
+   unsigned int nr)
+{
+   unsigned long fb_size;
+   struct drm_gem_object *obj;
+   struct exynos_drm_gem_obj *exynos_gem_obj;
+   struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
+
+   /* in case of RGB format, only one plane is used. */
+   if (nr < 2) {
+   exynos_gem_obj = exynos_fb->exynos_gem_obj[0];
+   obj = &exynos_gem_obj->base;
+   fb_size = fb->pitches[0] * fb->height;
+
+   if (fb_size != exynos_gem_obj->packed_size) {
+   DRM_ERROR("invalid fb or gem size.\n");
+   return -EINVAL;
+   }
+   /* in case of NV12MT, YUV420M and so on, two and three planes. */
+   } else {
+   unsigned int i;
+
+   for (i = 0; i < nr; i++) {
+   exynos_gem_obj = exynos_fb->exynos_gem_obj[i];
+   obj = &exynos_gem_obj->base;
+   fb_size = fb->pitches[i] * fb->height;
+
+   if (fb_size != exynos_gem_obj->packed_size) {
+   DRM_ERROR("invalid fb or gem size.\n");
+   return -EINVAL;
+   }
+   }
+   }
+
+   return 0;
+}
+
 static void exynos_drm_fb_destroy(struct drm_framebuffer *fb)
 {
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
@@ -134,8 +172,7 @@ exynos_user_fb_create(struct drm_device *dev, struct 
drm_file *file_priv,
struct drm_gem_object *obj;
struct drm_framebuffer *fb;
struct exynos_drm_fb *exynos_fb;
-   int nr;
-   int i;
+   int nr, i, ret;

DRM_DEBUG_KMS("%s\n", __FILE__);

@@ -166,6 +203,12 @@ exynos_user_fb_create(struct drm_device *dev, struct 
drm_file *file_priv,
exynos_fb->exynos_gem_obj[i] = to_exynos_gem_obj(obj);
}

+   ret = check_fb_gem_size(dev, fb, nr);
+   if (ret < 0) {
+   exynos_drm_fb_destroy(fb);
+   return ERR_PTR(ret);
+   }
+
return fb;
 }

-- 
1.7.4.1



[git pull] drm/exynos: updated exynos-drm-fixes

2012-07-09 Thread Inki Dae
Hi Dave,

Please pull from
git://git.infradead.org/users/kmpark/linux-samsung exynos-drm-fixes

these patch sets below had already been posted several weeks ago for review
and include some fixes and exceptions.

thes patch sets are based on git repository below:
git://people.freedesktop.org/~airlied/linux.git drm-fixes
commit-id: 9f846a16d213523fbe6daea17e20df6b8ac5a1e5

Thanks.

Cooper Yuan (1):
  drm/exynos: fix buffer pitch calculation

Inki Dae (11):
  drm/exynos: removed unnecessary declaration.
  drm/exynos: set edid fake data only for test.
  drm/exynos: check if raw edid data is fake or not for test
  drm/exynos: fixed edid data setting at vidi connection request
  drm/exynos: fixed build warning.
  drm/exynos: use alloc_page() to allocate pages.
  drm/exynos: set buffer type from exporter.
  drm/exynos: do not release memory region from exporter.
  drm/exynos: removed unnecessary variable
  drm/exynos: fixed a comment to gem size.
  drm/exynos: add packed_size not aligned in page unit.

Sachin Kamat (4):
  drm/exynos: Add missing static storage class specifier
  drm/exynos: Use devm_* functions in exynos_drm_fimd.c
  drm/exynos: Use devm_* functions in exynos_hdmi.c
  drm/exynos: Use devm_* functions in exynos_mixer.c

Subash Patel (2):
  drm/exynos: return NULL if exynos_pages_to_sg fails
  drm/exynos: check for null in return value of
dma_buf_map_attachment()

 drivers/gpu/drm/exynos/exynos_drm_connector.c |3 +-
 drivers/gpu/drm/exynos/exynos_drm_core.c  |5 --
 drivers/gpu/drm/exynos/exynos_drm_dmabuf.c|   33 
 drivers/gpu/drm/exynos/exynos_drm_fimd.c  |   40 ---
 drivers/gpu/drm/exynos/exynos_drm_gem.c   |   28 +++--
 drivers/gpu/drm/exynos/exynos_drm_gem.h   |6 ++-
 drivers/gpu/drm/exynos/exynos_drm_vidi.c  |   53 +++--
 drivers/gpu/drm/exynos/exynos_hdmi.c  |   36 +++-
 drivers/gpu/drm/exynos/exynos_mixer.c |   48 +++
 9 files changed, 118 insertions(+), 134 deletions(-)

-- 
1.7.4.1



[PATCH 16/16] drm/radeon: implement ring saving on reset

2012-07-09 Thread Christian König
Try to save whatever is on the rings when
we encounter an lockup.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon.h|4 ++
 drivers/gpu/drm/radeon/radeon_device.c |   44 
 drivers/gpu/drm/radeon/radeon_ring.c   |   69 
 3 files changed, 109 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 9c11be8..1265840 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -770,6 +770,10 @@ int radeon_ring_test(struct radeon_device *rdev, struct 
radeon_ring *cp);
 void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring 
*ring);
 void radeon_ring_lockup_update(struct radeon_ring *ring);
 bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring 
*ring);
+unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring 
*ring,
+   uint32_t **data);
+int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring,
+   unsigned size, uint32_t *data);
 int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp,
 unsigned ring_size, unsigned align,
 unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg,
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index bbd0971..97696e5 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -996,7 +996,12 @@ int radeon_resume_kms(struct drm_device *dev)

 int radeon_gpu_reset(struct radeon_device *rdev)
 {
-   int r;
+   unsigned ring_sizes[RADEON_NUM_RINGS];
+   uint32_t *ring_data[RADEON_NUM_RINGS];
+
+   bool saved = false;
+
+   int i, r;
int resched;

down_write(&rdev->exclusive_lock);
@@ -1005,20 +1010,43 @@ int radeon_gpu_reset(struct radeon_device *rdev)
resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
radeon_suspend(rdev);

+   for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+   ring_sizes[i] = radeon_ring_backup(rdev, &rdev->ring[i],
+  &ring_data[i]);
+   if (ring_sizes[i]) {
+   saved = true;
+   dev_info(rdev->dev, "Saved %d dwords of commands "
+"on ring %d.\n", ring_sizes[i], i);
+   }
+   }
+
+retry:
r = radeon_asic_reset(rdev);
if (!r) {
-   dev_info(rdev->dev, "GPU reset succeed\n");
+   dev_info(rdev->dev, "GPU reset succeed trying to resume\n");
radeon_resume(rdev);
+   }

-   r = radeon_ib_ring_tests(rdev);
-   if (r)
-   DRM_ERROR("ib ring test failed (%d).\n", r);
+   radeon_restore_bios_scratch_regs(rdev);
+   drm_helper_resume_force_mode(rdev->ddev);
+
+   if (!r) {
+   for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+   radeon_ring_restore(rdev, &rdev->ring[i],
+   ring_sizes[i], ring_data[i]);
+   }

-   radeon_restore_bios_scratch_regs(rdev);
-   drm_helper_resume_force_mode(rdev->ddev);
-   ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
+   r = radeon_ib_ring_tests(rdev);
+   if (r) {
+   dev_err(rdev->dev, "ib ring test failed (%d).\n", r);
+   if (saved) {
+   radeon_suspend(rdev);
+   goto retry;
+   }
+   }
}

+   ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
if (r) {
/* bad news, how to tell it to userspace ? */
dev_info(rdev->dev, "GPU reset failed\n");
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index 994c98c..6ce51d6 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -385,6 +385,75 @@ static unsigned radeon_ring_first_valid_commit(struct 
radeon_ring *ring)
return result;
 }

+unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring 
*ring,
+   uint32_t **data)
+{
+   unsigned size, ptr, i;
+   int commit;
+
+   /* just in case lock the ring */
+   mutex_lock(&rdev->ring_lock);
+   *data = NULL;
+
+   if (ring->ring_obj == NULL) {
+   mutex_unlock(&rdev->ring_lock);
+   return 0;
+   }
+
+   /* first of all update the rptr directly from the hw */
+   ring->rptr = (RREG32(ring->rptr_reg) & ring->ptr_reg_mask)
+>> ring->ptr_reg_shift;
+
+   /* find the first commit not processed so far */
+   commit = radeon_ring_first_valid_commit(ring);
+ 

[PATCH 15/16] drm/radeon: implement ring commit tracking

2012-07-09 Thread Christian König
Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon.h  |3 +++
 drivers/gpu/drm/radeon/radeon_ring.c |   39 --
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index fef4257..9c11be8 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -637,6 +637,9 @@ struct radeon_ring {
u32 ptr_reg_shift;
u32 ptr_reg_mask;
u32 nop;
+   unsigned*track_back;
+   unsignedtrack_ptr;
+   unsignedtrack_mask;
 };

 /*
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index d9b2e45..994c98c 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -276,6 +276,8 @@ void radeon_ring_commit(struct radeon_device *rdev, struct 
radeon_ring *ring)
DRM_MEMORYBARRIER();
WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & 
ring->ptr_reg_mask);
(void)RREG32(ring->wptr_reg);
+   ring->track_back[ring->track_ptr++] = ring->wptr_old;
+   ring->track_ptr &= ring->track_mask;
 }

 void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring 
*ring)
@@ -362,6 +364,27 @@ bool radeon_ring_test_lockup(struct radeon_device *rdev, 
struct radeon_ring *rin
return false;
 }

+static unsigned radeon_ring_first_valid_commit(struct radeon_ring *ring)
+{
+   unsigned i, c, result = ring->track_ptr;
+   i = ring->track_ptr - 1;
+   while (i != ring->track_ptr) {
+   i &= ring->track_mask;
+   c = ring->track_back[i];
+
+   if (ring->wptr >= ring->rptr) {
+   if (c < ring->rptr || c >= ring->wptr)
+   break;
+   } else {
+   if (c < ring->rptr && c >= ring->wptr)
+   break;
+   }
+
+   result = i--;
+   }
+   return result;
+}
+
 int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring,
 unsigned ring_size, unsigned align,
 unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg,
@@ -403,6 +426,10 @@ int radeon_ring_init(struct radeon_device *rdev, struct 
radeon_ring *ring,
dev_err(rdev->dev, "(%d) ring map failed\n", r);
return r;
}
+   ring->track_back = kmalloc(ring_size / align, GFP_KERNEL);
+   memset(ring->track_back, 0, ring_size / align);
+   ring->track_ptr = 0;
+   ring->track_mask = ((ring->ring_size / 4) / align) - 1;
}
ring->ptr_mask = (ring->ring_size / 4) - 1;
ring->ring_free_dw = ring->ring_size / 4;
@@ -422,6 +449,7 @@ void radeon_ring_fini(struct radeon_device *rdev, struct 
radeon_ring *ring)
ring->ready = false;
ring->ring = NULL;
ring->ring_obj = NULL;
+   kfree(ring->track_back);
mutex_unlock(&rdev->ring_lock);

if (ring_obj) {
@@ -447,7 +475,7 @@ static int radeon_debugfs_ring_info(struct seq_file *m, 
void *data)
struct radeon_device *rdev = dev->dev_private;
int ridx = *(int*)node->info_ent->data;
struct radeon_ring *ring = &rdev->ring[ridx];
-   unsigned count, i, j;
+   unsigned count, i, j, commit;

radeon_ring_free_size(rdev, ring);
count = (ring->ring_size / 4) - ring->ring_free_dw;
@@ -457,9 +485,16 @@ static int radeon_debugfs_ring_info(struct seq_file *m, 
void *data)
seq_printf(m, "driver's copy of the rptr: 0x%08x\n", ring->rptr);
seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw);
seq_printf(m, "%u dwords in ring\n", count);
+   commit = radeon_ring_first_valid_commit(ring);
i = ring->rptr;
for (j = 0; j <= count; j++) {
-   seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]);
+   seq_printf(m, "r[%04x]=0x%08x", i, ring->ring[i]);
+   if (commit != ring->track_ptr && ring->track_back[commit] == i) 
{
+   seq_printf(m, " <-");
+   ++commit;
+   commit &= ring->track_mask;
+   }
+   seq_printf(m, "\n");
i = (i + 1) & ring->ptr_mask;
}
return 0;
-- 
1.7.9.5



[PATCH 14/16] drm/radeon: make align a ring_init parameter

2012-07-09 Thread Christian König
Instead of setting it directly from the chipset code.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/evergreen.c   |3 ++-
 drivers/gpu/drm/radeon/ni.c  |3 ++-
 drivers/gpu/drm/radeon/r100.c|3 +--
 drivers/gpu/drm/radeon/r600.c|3 +--
 drivers/gpu/drm/radeon/radeon.h  |3 ++-
 drivers/gpu/drm/radeon/radeon_ring.c |4 +++-
 drivers/gpu/drm/radeon/rv770.c   |3 ++-
 drivers/gpu/drm/radeon/si.c  |9 ++---
 8 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index f39b900..f0bbbe1 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3075,7 +3075,8 @@ static int evergreen_startup(struct radeon_device *rdev)
}
evergreen_irq_set(rdev);

-   r = radeon_ring_init(rdev, ring, ring->ring_size, 
RADEON_WB_CP_RPTR_OFFSET,
+   r = radeon_ring_init(rdev, ring, ring->ring_size, 16,
+RADEON_WB_CP_RPTR_OFFSET,
 R600_CP_RB_RPTR, R600_CP_RB_WPTR,
 0, 0xf, RADEON_CP_PACKET2);
if (r)
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index f2afefb..c69cebc 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1258,7 +1258,8 @@ static int cayman_startup(struct radeon_device *rdev)
}
evergreen_irq_set(rdev);

-   r = radeon_ring_init(rdev, ring, ring->ring_size, 
RADEON_WB_CP_RPTR_OFFSET,
+   r = radeon_ring_init(rdev, ring, ring->ring_size, 16,
+RADEON_WB_CP_RPTR_OFFSET,
 CP_RB0_RPTR, CP_RB0_WPTR,
 0, 0xf, RADEON_CP_PACKET2);
if (r)
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index e0f5ae8..116432f 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -977,7 +977,7 @@ int r100_cp_init(struct radeon_device *rdev, unsigned 
ring_size)
rb_bufsz = drm_order(ring_size / 8);
ring_size = (1 << (rb_bufsz + 1)) * 4;
r100_cp_load_microcode(rdev);
-   r = radeon_ring_init(rdev, ring, ring_size, RADEON_WB_CP_RPTR_OFFSET,
+   r = radeon_ring_init(rdev, ring, ring_size, 16, 
RADEON_WB_CP_RPTR_OFFSET,
 RADEON_CP_RB_RPTR, RADEON_CP_RB_WPTR,
 0, 0x7f, RADEON_CP_PACKET2);
if (r) {
@@ -988,7 +988,6 @@ int r100_cp_init(struct radeon_device *rdev, unsigned 
ring_size)
rb_blksz = 9;
/* cp will read 128bytes at a time (4 dwords) */
max_fetch = 1;
-   ring->align_mask = 16 - 1;
/* Write to CP_RB_WPTR will be delayed for pre_write_timer clocks */
pre_write_timer = 64;
/* Force CP_RB_WPTR write if written more than one time before the
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index c808fa9..7d15490 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2160,7 +2160,6 @@ void r600_ring_init(struct radeon_device *rdev, struct 
radeon_ring *ring, unsign
rb_bufsz = drm_order(ring_size / 8);
ring_size = (1 << (rb_bufsz + 1)) * 4;
ring->ring_size = ring_size;
-   ring->align_mask = 16 - 1;
 }

 void r600_cp_fini(struct radeon_device *rdev)
@@ -2376,7 +2375,7 @@ int r600_startup(struct radeon_device *rdev)
}
r600_irq_set(rdev);

-   r = radeon_ring_init(rdev, ring, ring->ring_size, 
RADEON_WB_CP_RPTR_OFFSET,
+   r = radeon_ring_init(rdev, ring, ring->ring_size, 16, 
RADEON_WB_CP_RPTR_OFFSET,
 R600_CP_RB_RPTR, R600_CP_RB_WPTR,
 0, 0xf, RADEON_CP_PACKET2);

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 872270c..fef4257 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -767,7 +767,8 @@ int radeon_ring_test(struct radeon_device *rdev, struct 
radeon_ring *cp);
 void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring 
*ring);
 void radeon_ring_lockup_update(struct radeon_ring *ring);
 bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring 
*ring);
-int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, 
unsigned ring_size,
+int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp,
+unsigned ring_size, unsigned align,
 unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg,
 u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop);
 void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *cp);
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index 0873834..d9b2e45 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring

[PATCH 13/16] drm/radeon: move radeon_ib_ring_tests out of chipset code

2012-07-09 Thread Christian König
Making it easier to controlwhen it is executed.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/evergreen.c |4 
 drivers/gpu/drm/radeon/ni.c|4 
 drivers/gpu/drm/radeon/r100.c  |4 
 drivers/gpu/drm/radeon/r300.c  |4 
 drivers/gpu/drm/radeon/r420.c  |4 
 drivers/gpu/drm/radeon/r520.c  |4 
 drivers/gpu/drm/radeon/r600.c  |4 
 drivers/gpu/drm/radeon/radeon_device.c |   15 +++
 drivers/gpu/drm/radeon/rs400.c |4 
 drivers/gpu/drm/radeon/rs600.c |4 
 drivers/gpu/drm/radeon/rs690.c |4 
 drivers/gpu/drm/radeon/rv515.c |4 
 drivers/gpu/drm/radeon/rv770.c |4 
 drivers/gpu/drm/radeon/si.c|   21 -
 14 files changed, 15 insertions(+), 69 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index 82f7aea..f39b900 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3093,10 +3093,6 @@ static int evergreen_startup(struct radeon_device *rdev)
return r;
}

-   r = radeon_ib_ring_tests(rdev);
-   if (r)
-   return r;
-
r = r600_audio_init(rdev);
if (r) {
DRM_ERROR("radeon: audio init failed\n");
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index ec5307c..f2afefb 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1276,10 +1276,6 @@ static int cayman_startup(struct radeon_device *rdev)
return r;
}

-   r = radeon_ib_ring_tests(rdev);
-   if (r)
-   return r;
-
r = radeon_vm_manager_init(rdev);
if (r) {
dev_err(rdev->dev, "vm manager initialization failed (%d).\n", 
r);
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 9524bd4..e0f5ae8 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -3887,10 +3887,6 @@ static int r100_startup(struct radeon_device *rdev)
return r;
}

-   r = radeon_ib_ring_tests(rdev);
-   if (r)
-   return r;
-
return 0;
 }

diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index b396e34..646a192 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -1397,10 +1397,6 @@ static int r300_startup(struct radeon_device *rdev)
return r;
}

-   r = radeon_ib_ring_tests(rdev);
-   if (r)
-   return r;
-
return 0;
 }

diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c
index 0062938..f2f5bf6 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -281,10 +281,6 @@ static int r420_startup(struct radeon_device *rdev)
return r;
}

-   r = radeon_ib_ring_tests(rdev);
-   if (r)
-   return r;
-
return 0;
 }

diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c
index 6df3e51..079d3c5 100644
--- a/drivers/gpu/drm/radeon/r520.c
+++ b/drivers/gpu/drm/radeon/r520.c
@@ -209,10 +209,6 @@ static int r520_startup(struct radeon_device *rdev)
return r;
}

-   r = radeon_ib_ring_tests(rdev);
-   if (r)
-   return r;
-
return 0;
 }

diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index af2f74a..c808fa9 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2395,10 +2395,6 @@ int r600_startup(struct radeon_device *rdev)
return r;
}

-   r = radeon_ib_ring_tests(rdev);
-   if (r)
-   return r;
-
r = r600_audio_init(rdev);
if (r) {
DRM_ERROR("radeon: audio init failed\n");
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 254fdb4..bbd0971 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -822,6 +822,10 @@ int radeon_device_init(struct radeon_device *rdev,
if (r)
return r;

+   r = radeon_ib_ring_tests(rdev);
+   if (r)
+   DRM_ERROR("ib ring test failed (%d).\n", r);
+
if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) {
/* Acceleration not working on AGP card try again
 * with fallback to PCI or PCIE GART
@@ -946,6 +950,7 @@ int radeon_resume_kms(struct drm_device *dev)
 {
struct drm_connector *connector;
struct radeon_device *rdev = dev->dev_private;
+   int r;

if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
return 0;
@@ -960,6 +965,11 @@ int radeon_resume_kms(struct drm_device *dev)
/* resume AGP if in use */
radeon_agp_resume(rdev);
 

[PATCH 12/16] drm/radeon: remove vm_manager start/suspend

2012-07-09 Thread Christian König
Just restore the page table instead. Addressing three
problem with this change:

1. Calling vm_manager_suspend in the suspend path is
   problematic cause it wants to wait for the VM use
   to end, which in case of a lockup never happens.

2. In case of a locked up memory controller
   unbinding the VM seems to make it even more
   unstable, creating an unrecoverable lockup
   in the end.

3. If we want to backup/restore the leftover ring
   content we must not unbind VMs in between.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/ni.c  |   12 ++---
 drivers/gpu/drm/radeon/radeon.h  |2 -
 drivers/gpu/drm/radeon/radeon_gart.c |   83 +-
 drivers/gpu/drm/radeon/si.c  |   12 ++---
 4 files changed, 59 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 4004376..ec5307c 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1280,9 +1280,11 @@ static int cayman_startup(struct radeon_device *rdev)
if (r)
return r;

-   r = radeon_vm_manager_start(rdev);
-   if (r)
+   r = radeon_vm_manager_init(rdev);
+   if (r) {
+   dev_err(rdev->dev, "vm manager initialization failed (%d).\n", 
r);
return r;
+   }

r = r600_audio_init(rdev);
if (r)
@@ -1315,7 +1317,6 @@ int cayman_resume(struct radeon_device *rdev)
 int cayman_suspend(struct radeon_device *rdev)
 {
r600_audio_fini(rdev);
-   radeon_vm_manager_suspend(rdev);
cayman_cp_enable(rdev, false);
rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
evergreen_irq_suspend(rdev);
@@ -1392,11 +1393,6 @@ int cayman_init(struct radeon_device *rdev)
return r;

rdev->accel_working = true;
-   r = radeon_vm_manager_init(rdev);
-   if (r) {
-   dev_err(rdev->dev, "vm manager initialization failed (%d).\n", 
r);
-   }
-
r = cayman_startup(rdev);
if (r) {
dev_err(rdev->dev, "disabling GPU acceleration\n");
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 8a8c3f8..872270c 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1759,8 +1759,6 @@ extern void radeon_ttm_set_active_vram_size(struct 
radeon_device *rdev, u64 size
  */
 int radeon_vm_manager_init(struct radeon_device *rdev);
 void radeon_vm_manager_fini(struct radeon_device *rdev);
-int radeon_vm_manager_start(struct radeon_device *rdev);
-int radeon_vm_manager_suspend(struct radeon_device *rdev);
 int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm);
 void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm);
 int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm);
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index ee11c50..56752da 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -282,27 +282,58 @@ void radeon_gart_fini(struct radeon_device *rdev)
  *
  * TODO bind a default page at vm initialization for default address
  */
+
 int radeon_vm_manager_init(struct radeon_device *rdev)
 {
+   struct radeon_vm *vm;
+   struct radeon_bo_va *bo_va;
int r;

-   rdev->vm_manager.enabled = false;
+   if (!rdev->vm_manager.enabled) {
+   /* mark first vm as always in use, it's the system one */
+   r = radeon_sa_bo_manager_init(rdev, 
&rdev->vm_manager.sa_manager,
+ rdev->vm_manager.max_pfn * 8,
+ RADEON_GEM_DOMAIN_VRAM);
+   if (r) {
+   dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n",
+   (rdev->vm_manager.max_pfn * 8) >> 10);
+   return r;
+   }

-   /* mark first vm as always in use, it's the system one */
-   r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager,
- rdev->vm_manager.max_pfn * 8,
- RADEON_GEM_DOMAIN_VRAM);
-   if (r) {
-   dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n",
-   (rdev->vm_manager.max_pfn * 8) >> 10);
-   return r;
+   r = rdev->vm_manager.funcs->init(rdev);
+   if (r)
+   return r;
+   
+   rdev->vm_manager.enabled = true;
+
+   r = radeon_sa_bo_manager_start(rdev, 
&rdev->vm_manager.sa_manager);
+   if (r)
+   return r;
}

-   r = rdev->vm_manager.funcs->init(rdev);
-   if (r == 0)
-   rdev->vm_manager.enabled = true;
+   /* restore page table */
+   list_for_each_entry(vm, &rdev->vm_manager.lru_vm, list) {
+   if (vm->id == -1)

[PATCH 11/16] drm/radeon: remove r600_blit_suspend

2012-07-09 Thread Christian König
Just reinitialize the shader content on resume instead.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/evergreen.c  |1 -
 drivers/gpu/drm/radeon/evergreen_blit_kms.c |   40 +--
 drivers/gpu/drm/radeon/ni.c |1 -
 drivers/gpu/drm/radeon/r600.c   |   15 --
 drivers/gpu/drm/radeon/r600_blit_kms.c  |   40 +--
 drivers/gpu/drm/radeon/radeon.h |2 --
 drivers/gpu/drm/radeon/rv770.c  |1 -
 drivers/gpu/drm/radeon/si.c |3 --
 8 files changed, 40 insertions(+), 63 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index 64e06e6..82f7aea 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3139,7 +3139,6 @@ int evergreen_suspend(struct radeon_device *rdev)
struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];

r600_audio_fini(rdev);
-   r600_blit_suspend(rdev);
r700_cp_stop(rdev);
ring->ready = false;
evergreen_irq_suspend(rdev);
diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c 
b/drivers/gpu/drm/radeon/evergreen_blit_kms.c
index e512560..89cb9fe 100644
--- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c
+++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c
@@ -634,10 +634,6 @@ int evergreen_blit_init(struct radeon_device *rdev)

rdev->r600_blit.max_dim = 16384;

-   /* pin copy shader into vram if already initialized */
-   if (rdev->r600_blit.shader_obj)
-   goto done;
-
rdev->r600_blit.state_offset = 0;

if (rdev->family < CHIP_CAYMAN)
@@ -668,11 +664,26 @@ int evergreen_blit_init(struct radeon_device *rdev)
obj_size += cayman_ps_size * 4;
obj_size = ALIGN(obj_size, 256);

-   r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true, 
RADEON_GEM_DOMAIN_VRAM,
-NULL, &rdev->r600_blit.shader_obj);
-   if (r) {
-   DRM_ERROR("evergreen failed to allocate shader\n");
-   return r;
+   /* pin copy shader into vram if not already initialized */
+   if (!rdev->r600_blit.shader_obj) {
+   r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true,
+RADEON_GEM_DOMAIN_VRAM,
+NULL, &rdev->r600_blit.shader_obj);
+   if (r) {
+   DRM_ERROR("evergreen failed to allocate shader\n");
+   return r;
+   }
+
+   r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
+   if (unlikely(r != 0))
+   return r;
+   r = radeon_bo_pin(rdev->r600_blit.shader_obj, 
RADEON_GEM_DOMAIN_VRAM,
+ &rdev->r600_blit.shader_gpu_addr);
+   radeon_bo_unreserve(rdev->r600_blit.shader_obj);
+   if (r) {
+   dev_err(rdev->dev, "(%d) pin blit object failed\n", r);
+   return r;
+   }
}

DRM_DEBUG("evergreen blit allocated bo %08x vs %08x ps %08x\n",
@@ -714,17 +725,6 @@ int evergreen_blit_init(struct radeon_device *rdev)
radeon_bo_kunmap(rdev->r600_blit.shader_obj);
radeon_bo_unreserve(rdev->r600_blit.shader_obj);

-done:
-   r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
-   if (unlikely(r != 0))
-   return r;
-   r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
- &rdev->r600_blit.shader_gpu_addr);
-   radeon_bo_unreserve(rdev->r600_blit.shader_obj);
-   if (r) {
-   dev_err(rdev->dev, "(%d) pin blit object failed\n", r);
-   return r;
-   }
radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
return 0;
 }
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index fe55310..4004376 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1316,7 +1316,6 @@ int cayman_suspend(struct radeon_device *rdev)
 {
r600_audio_fini(rdev);
radeon_vm_manager_suspend(rdev);
-   r600_blit_suspend(rdev);
cayman_cp_enable(rdev, false);
rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
evergreen_irq_suspend(rdev);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 9750f53..af2f74a 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2307,20 +2307,6 @@ int r600_copy_blit(struct radeon_device *rdev,
return 0;
 }

-void r600_blit_suspend(struct radeon_device *rdev)
-{
-   int r;
-
-   /* unpin shaders bo */
-   if (rdev->r600_blit.shader_obj) {
-   r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
-   if (!r) {
-   radeon_bo_unpin(rdev->r600_blit.sha

[PATCH 10/16] drm/radeon: remove ip_pool start/suspend

2012-07-09 Thread Christian König
The IB pool is in gart memory, so it is completely
superfluous to unpin / repin it on suspend / resume.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/evergreen.c   |   17 ++---
 drivers/gpu/drm/radeon/ni.c  |   16 ++--
 drivers/gpu/drm/radeon/r100.c|   23 ++-
 drivers/gpu/drm/radeon/r300.c|   17 ++---
 drivers/gpu/drm/radeon/r420.c|   17 ++---
 drivers/gpu/drm/radeon/r520.c|   14 +-
 drivers/gpu/drm/radeon/r600.c|   17 ++---
 drivers/gpu/drm/radeon/radeon.h  |2 --
 drivers/gpu/drm/radeon/radeon_asic.h |1 -
 drivers/gpu/drm/radeon/radeon_ring.c |   17 +++--
 drivers/gpu/drm/radeon/rs400.c   |   17 ++---
 drivers/gpu/drm/radeon/rs600.c   |   17 ++---
 drivers/gpu/drm/radeon/rs690.c   |   17 ++---
 drivers/gpu/drm/radeon/rv515.c   |   16 ++--
 drivers/gpu/drm/radeon/rv770.c   |   17 ++---
 drivers/gpu/drm/radeon/si.c  |   16 ++--
 16 files changed, 84 insertions(+), 157 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index eb9a71a..64e06e6 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3087,9 +3087,11 @@ static int evergreen_startup(struct radeon_device *rdev)
if (r)
return r;

-   r = radeon_ib_pool_start(rdev);
-   if (r)
+   r = radeon_ib_pool_init(rdev);
+   if (r) {
+   dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
return r;
+   }

r = radeon_ib_ring_tests(rdev);
if (r)
@@ -3137,7 +3139,6 @@ int evergreen_suspend(struct radeon_device *rdev)
struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];

r600_audio_fini(rdev);
-   radeon_ib_pool_suspend(rdev);
r600_blit_suspend(rdev);
r700_cp_stop(rdev);
ring->ready = false;
@@ -3224,20 +3225,14 @@ int evergreen_init(struct radeon_device *rdev)
if (r)
return r;

-   r = radeon_ib_pool_init(rdev);
rdev->accel_working = true;
-   if (r) {
-   dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
-   rdev->accel_working = false;
-   }
-
r = evergreen_startup(rdev);
if (r) {
dev_err(rdev->dev, "disabling GPU acceleration\n");
r700_cp_fini(rdev);
r600_irq_fini(rdev);
radeon_wb_fini(rdev);
-   r100_ib_fini(rdev);
+   radeon_ib_pool_fini(rdev);
radeon_irq_kms_fini(rdev);
evergreen_pcie_gart_fini(rdev);
rdev->accel_working = false;
@@ -3264,7 +3259,7 @@ void evergreen_fini(struct radeon_device *rdev)
r700_cp_fini(rdev);
r600_irq_fini(rdev);
radeon_wb_fini(rdev);
-   r100_ib_fini(rdev);
+   radeon_ib_pool_fini(rdev);
radeon_irq_kms_fini(rdev);
evergreen_pcie_gart_fini(rdev);
r600_vram_scratch_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 8b1df33..fe55310 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1270,9 +1270,11 @@ static int cayman_startup(struct radeon_device *rdev)
if (r)
return r;

-   r = radeon_ib_pool_start(rdev);
-   if (r)
+   r = radeon_ib_pool_init(rdev);
+   if (r) {
+   dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
return r;
+   }

r = radeon_ib_ring_tests(rdev);
if (r)
@@ -1313,7 +1315,6 @@ int cayman_resume(struct radeon_device *rdev)
 int cayman_suspend(struct radeon_device *rdev)
 {
r600_audio_fini(rdev);
-   radeon_ib_pool_suspend(rdev);
radeon_vm_manager_suspend(rdev);
r600_blit_suspend(rdev);
cayman_cp_enable(rdev, false);
@@ -1391,12 +1392,7 @@ int cayman_init(struct radeon_device *rdev)
if (r)
return r;

-   r = radeon_ib_pool_init(rdev);
rdev->accel_working = true;
-   if (r) {
-   dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
-   rdev->accel_working = false;
-   }
r = radeon_vm_manager_init(rdev);
if (r) {
dev_err(rdev->dev, "vm manager initialization failed (%d).\n", 
r);
@@ -1410,7 +1406,7 @@ int cayman_init(struct radeon_device *rdev)
if (rdev->flags & RADEON_IS_IGP)
si_rlc_fini(rdev);
radeon_wb_fini(rdev);
-   r100_ib_fini(rdev);
+   radeon_ib_pool_fini(rdev);
radeon_vm_manager_fini(rdev);
radeon_irq_kms_fini(rdev);
cayman_pcie_gart_fini(rdev);
@@ -1441,7 +1437,7 @@ void cayman_fini(struct radeon

[PATCH 09/16] drm/radeon: make cp init on cayman more robust

2012-07-09 Thread Christian König
It's not critical, but the current code isn't
100% correct.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/ni.c |  133 ++-
 1 file changed, 56 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 32a6082..8b1df33 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -987,10 +987,33 @@ static void cayman_cp_fini(struct radeon_device *rdev)

 int cayman_cp_resume(struct radeon_device *rdev)
 {
+   static const int ridx[] = {
+   RADEON_RING_TYPE_GFX_INDEX,
+   CAYMAN_RING_TYPE_CP1_INDEX,
+   CAYMAN_RING_TYPE_CP2_INDEX
+   };
+   static const unsigned cp_rb_cntl[] = {
+   CP_RB0_CNTL,
+   CP_RB1_CNTL,
+   CP_RB2_CNTL,
+   };
+   static const unsigned cp_rb_rptr_addr[] = {
+   CP_RB0_RPTR_ADDR,
+   CP_RB1_RPTR_ADDR,
+   CP_RB2_RPTR_ADDR
+   };
+   static const unsigned cp_rb_rptr_addr_hi[] = {
+   CP_RB0_RPTR_ADDR_HI,
+   CP_RB1_RPTR_ADDR_HI,
+   CP_RB2_RPTR_ADDR_HI
+   };
+   static const unsigned cp_rb_base[] = {
+   CP_RB0_BASE,
+   CP_RB1_BASE,
+   CP_RB2_BASE
+   };
struct radeon_ring *ring;
-   u32 tmp;
-   u32 rb_bufsz;
-   int r;
+   int i, r;

/* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */
WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP |
@@ -1012,91 +1035,47 @@ int cayman_cp_resume(struct radeon_device *rdev)

WREG32(CP_DEBUG, (1 << 27));

-   /* ring 0 - compute and gfx */
-   /* Set ring buffer size */
-   ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
-   rb_bufsz = drm_order(ring->ring_size / 8);
-   tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
-#ifdef __BIG_ENDIAN
-   tmp |= BUF_SWAP_32BIT;
-#endif
-   WREG32(CP_RB0_CNTL, tmp);
-
-   /* Initialize the ring buffer's read and write pointers */
-   WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA);
-   ring->wptr = 0;
-   WREG32(CP_RB0_WPTR, ring->wptr);
-
/* set the wb address wether it's enabled or not */
-   WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) 
& 0xFFFC);
-   WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + 
RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 
8) & 0x);
+   WREG32(SCRATCH_UMSK, 0xff);

-   if (rdev->wb.enabled)
-   WREG32(SCRATCH_UMSK, 0xff);
-   else {
-   tmp |= RB_NO_UPDATE;
-   WREG32(SCRATCH_UMSK, 0);
-   }
-
-   mdelay(1);
-   WREG32(CP_RB0_CNTL, tmp);
-
-   WREG32(CP_RB0_BASE, ring->gpu_addr >> 8);
-
-   ring->rptr = RREG32(CP_RB0_RPTR);
+   for (i = 0; i < 3; ++i) {
+   uint32_t rb_cntl;
+   uint64_t addr;

-   /* ring1  - compute only */
-   /* Set ring buffer size */
-   ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
-   rb_bufsz = drm_order(ring->ring_size / 8);
-   tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
+   /* Set ring buffer size */
+   ring = &rdev->ring[ridx[i]];
+   rb_cntl = drm_order(ring->ring_size / 8);
+   rb_cntl |= drm_order(RADEON_GPU_PAGE_SIZE/8) << 8;
 #ifdef __BIG_ENDIAN
-   tmp |= BUF_SWAP_32BIT;
+   rb_cntl |= BUF_SWAP_32BIT;
 #endif
-   WREG32(CP_RB1_CNTL, tmp);
+   WREG32(cp_rb_cntl[i], rb_cntl);

-   /* Initialize the ring buffer's read and write pointers */
-   WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA);
-   ring->wptr = 0;
-   WREG32(CP_RB1_WPTR, ring->wptr);
-
-   /* set the wb address wether it's enabled or not */
-   WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + 
RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFC);
-   WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + 
RADEON_WB_CP1_RPTR_OFFSET) & 0xFF);
-
-   mdelay(1);
-   WREG32(CP_RB1_CNTL, tmp);
-
-   WREG32(CP_RB1_BASE, ring->gpu_addr >> 8);
-
-   ring->rptr = RREG32(CP_RB1_RPTR);
-
-   /* ring2 - compute only */
-   /* Set ring buffer size */
-   ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
-   rb_bufsz = drm_order(ring->ring_size / 8);
-   tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
-#ifdef __BIG_ENDIAN
-   tmp |= BUF_SWAP_32BIT;
-#endif
-   WREG32(CP_RB2_CNTL, tmp);
-
-   /* Initialize the ring buffer's read and write pointers */
-   WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA);
-   ring->wptr = 0;
-   WREG32(CP_RB2_WPTR, ring->wptr);
+   /* set the wb address wether it's enabled or not */
+   addr = rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET;
+   WREG32(cp_rb_rptr_addr[i], addr & 0xFFF

[PATCH 08/16] drm/radeon: remove FIXME comment from chipset suspend

2012-07-09 Thread Christian König
For a normal suspend/resume we allready wait for
the rings to be empty, and for a suspend/reasume
in case of a lockup we REALLY don't want to wait
for anything.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/evergreen.c |1 -
 drivers/gpu/drm/radeon/ni.c|1 -
 drivers/gpu/drm/radeon/r600.c  |1 -
 drivers/gpu/drm/radeon/rv770.c |1 -
 drivers/gpu/drm/radeon/si.c|1 -
 5 files changed, 5 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index f716e08..eb9a71a 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3137,7 +3137,6 @@ int evergreen_suspend(struct radeon_device *rdev)
struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];

r600_audio_fini(rdev);
-   /* FIXME: we should wait for ring to be empty */
radeon_ib_pool_suspend(rdev);
r600_blit_suspend(rdev);
r700_cp_stop(rdev);
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 2366be3..32a6082 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1334,7 +1334,6 @@ int cayman_resume(struct radeon_device *rdev)
 int cayman_suspend(struct radeon_device *rdev)
 {
r600_audio_fini(rdev);
-   /* FIXME: we should wait for ring to be empty */
radeon_ib_pool_suspend(rdev);
radeon_vm_manager_suspend(rdev);
r600_blit_suspend(rdev);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 43d0c41..de4de2d 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2461,7 +2461,6 @@ int r600_suspend(struct radeon_device *rdev)
r600_audio_fini(rdev);
radeon_ib_pool_suspend(rdev);
r600_blit_suspend(rdev);
-   /* FIXME: we should wait for ring to be empty */
r600_cp_stop(rdev);
rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
r600_irq_suspend(rdev);
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index b4f51c5..7e230f6 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -996,7 +996,6 @@ int rv770_suspend(struct radeon_device *rdev)
r600_audio_fini(rdev);
radeon_ib_pool_suspend(rdev);
r600_blit_suspend(rdev);
-   /* FIXME: we should wait for ring to be empty */
r700_cp_stop(rdev);
rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
r600_irq_suspend(rdev);
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 34603b3c8..78c790f 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -3807,7 +3807,6 @@ int si_resume(struct radeon_device *rdev)

 int si_suspend(struct radeon_device *rdev)
 {
-   /* FIXME: we should wait for ring to be empty */
radeon_ib_pool_suspend(rdev);
radeon_vm_manager_suspend(rdev);
 #if 0
-- 
1.7.9.5



[PATCH 07/16] drm/radeon: fix fence init after resume

2012-07-09 Thread Christian König
Start with last signaled fence number instead
of last emitted one.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon_fence.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index a194a14..76c5b22 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -578,7 +578,7 @@ int radeon_fence_driver_start_ring(struct radeon_device 
*rdev, int ring)
}
rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4];
rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr + index;
-   radeon_fence_write(rdev, rdev->fence_drv[ring].sync_seq[ring], ring);
+   radeon_fence_write(rdev, 
atomic64_read(&rdev->fence_drv[ring].last_seq), ring);
rdev->fence_drv[ring].initialized = true;
dev_info(rdev->dev, "fence driver on ring %d use gpu addr 0x%016llx and 
cpu addr 0x%p\n",
 ring, rdev->fence_drv[ring].gpu_addr, 
rdev->fence_drv[ring].cpu_addr);
-- 
1.7.9.5



[PATCH 06/16] drm/radeon: fix fence value access

2012-07-09 Thread Christian König
It is possible that radeon_fence_process is called
after writeback is disabled for suspend, leading
to an invalid read of register 0x0.

This fixes a problem for me where the fence value
is temporary incremented by 0x1 on
suspend/resume.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon_fence.c |   14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index be4e4f3..a194a14 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -42,21 +42,23 @@

 static void radeon_fence_write(struct radeon_device *rdev, u32 seq, int ring)
 {
-   if (rdev->wb.enabled) {
-   *rdev->fence_drv[ring].cpu_addr = cpu_to_le32(seq);
+   struct radeon_fence_driver *drv = &rdev->fence_drv[ring];
+   if (likely(rdev->wb.enabled || !drv->scratch_reg)) {
+   *drv->cpu_addr = cpu_to_le32(seq);
} else {
-   WREG32(rdev->fence_drv[ring].scratch_reg, seq);
+   WREG32(drv->scratch_reg, seq);
}
 }

 static u32 radeon_fence_read(struct radeon_device *rdev, int ring)
 {
+   struct radeon_fence_driver *drv = &rdev->fence_drv[ring];
u32 seq = 0;

-   if (rdev->wb.enabled) {
-   seq = le32_to_cpu(*rdev->fence_drv[ring].cpu_addr);
+   if (likely(rdev->wb.enabled || !drv->scratch_reg)) {
+   seq = le32_to_cpu(*drv->cpu_addr);
} else {
-   seq = RREG32(rdev->fence_drv[ring].scratch_reg);
+   seq = RREG32(drv->scratch_reg);
}
return seq;
 }
-- 
1.7.9.5



[PATCH 05/16] drm/radeon: fix ring commit padding

2012-07-09 Thread Christian König
We don't need to pad anything if the number of dwords
written to the ring already matches the requirements.

Fixes some "writting more dword to ring than expected"
warnings.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon_ring.c |7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index 0826e77..674aaba 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -272,13 +272,8 @@ int radeon_ring_lock(struct radeon_device *rdev, struct 
radeon_ring *ring, unsig

 void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring)
 {
-   unsigned count_dw_pad;
-   unsigned i;
-
/* We pad to match fetch size */
-   count_dw_pad = (ring->align_mask + 1) -
-  (ring->wptr & ring->align_mask);
-   for (i = 0; i < count_dw_pad; i++) {
+   while (ring->wptr & ring->align_mask) {
radeon_ring_write(ring, ring->nop);
}
DRM_MEMORYBARRIER();
-- 
1.7.9.5



[PATCH 04/16] drm/radeon: add an exclusive lock for GPU reset v2

2012-07-09 Thread Christian König
From: Jerome Glisse 

GPU reset need to be exclusive, one happening at a time. For this
add a rw semaphore so that any path that trigger GPU activities
have to take the semaphore as a reader thus allowing concurency.

The GPU reset path take the semaphore as a writer ensuring that
no concurrent reset take place.

v2: init rw semaphore

Signed-off-by: Jerome Glisse 
---
 drivers/gpu/drm/radeon/radeon.h|1 +
 drivers/gpu/drm/radeon/radeon_cs.c |5 +
 drivers/gpu/drm/radeon/radeon_device.c |3 +++
 drivers/gpu/drm/radeon/radeon_gem.c|8 
 4 files changed, 17 insertions(+)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 5861ec8..4487873 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1446,6 +1446,7 @@ struct radeon_device {
struct device   *dev;
struct drm_device   *ddev;
struct pci_dev  *pdev;
+   struct rw_semaphore exclusive_lock;
/* ASIC */
union radeon_asic_configconfig;
enum radeon_family  family;
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
b/drivers/gpu/drm/radeon/radeon_cs.c
index d5aec09..553da67 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -499,7 +499,9 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
struct radeon_cs_parser parser;
int r;

+   down_read(&rdev->exclusive_lock);
if (!rdev->accel_working) {
+   up_read(&rdev->exclusive_lock);
return -EBUSY;
}
/* initialize parser */
@@ -512,6 +514,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
if (r) {
DRM_ERROR("Failed to initialize parser !\n");
radeon_cs_parser_fini(&parser, r);
+   up_read(&rdev->exclusive_lock);
r = radeon_cs_handle_lockup(rdev, r);
return r;
}
@@ -520,6 +523,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
if (r != -ERESTARTSYS)
DRM_ERROR("Failed to parse relocation %d!\n", r);
radeon_cs_parser_fini(&parser, r);
+   up_read(&rdev->exclusive_lock);
r = radeon_cs_handle_lockup(rdev, r);
return r;
}
@@ -533,6 +537,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
}
 out:
radeon_cs_parser_fini(&parser, r);
+   up_read(&rdev->exclusive_lock);
r = radeon_cs_handle_lockup(rdev, r);
return r;
 }
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index f654ba8..254fdb4 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -734,6 +734,7 @@ int radeon_device_init(struct radeon_device *rdev,
mutex_init(&rdev->gem.mutex);
mutex_init(&rdev->pm.mutex);
init_rwsem(&rdev->pm.mclk_lock);
+   init_rwsem(&rdev->exclusive_lock);
init_waitqueue_head(&rdev->irq.vblank_queue);
init_waitqueue_head(&rdev->irq.idle_queue);
r = radeon_gem_init(rdev);
@@ -988,6 +989,7 @@ int radeon_gpu_reset(struct radeon_device *rdev)
int r;
int resched;

+   down_write(&rdev->exclusive_lock);
radeon_save_bios_scratch_regs(rdev);
/* block TTM */
resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
@@ -1007,6 +1009,7 @@ int radeon_gpu_reset(struct radeon_device *rdev)
dev_info(rdev->dev, "GPU reset failed\n");
}

+   up_write(&rdev->exclusive_lock);
return r;
 }

diff --git a/drivers/gpu/drm/radeon/radeon_gem.c 
b/drivers/gpu/drm/radeon/radeon_gem.c
index d9b0809..b0be9c4 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -215,12 +215,14 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void 
*data,
uint32_t handle;
int r;

+   down_read(&rdev->exclusive_lock);
/* create a gem object to contain this object in */
args->size = roundup(args->size, PAGE_SIZE);
r = radeon_gem_object_create(rdev, args->size, args->alignment,
args->initial_domain, false,
false, &gobj);
if (r) {
+   up_read(&rdev->exclusive_lock);
r = radeon_gem_handle_lockup(rdev, r);
return r;
}
@@ -228,10 +230,12 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void 
*data,
/* drop reference from allocate - handle holds it now */
drm_gem_object_unreference_unlocked(gobj);
if (r) {
+   up_read(&rdev->exclusive_lock);
r = radeon_gem_handle_lockup(rdev, r);
re

[PATCH 03/16] drm/radeon: fix fence related segfault in CS

2012-07-09 Thread Christian König
Don't return success if scheduling the IB fails, otherwise
we end up with an oops in ttm_eu_fence_buffer_objects.

Signed-off-by: Christian K?nig 
Cc: stable at vger.kernel.org
---
 drivers/gpu/drm/radeon/radeon_cs.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
b/drivers/gpu/drm/radeon/radeon_cs.c
index f1b7527..d5aec09 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -358,7 +358,7 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev,
if (r) {
DRM_ERROR("Failed to schedule IB !\n");
}
-   return 0;
+   return r;
 }

 static int radeon_bo_vm_update_pte(struct radeon_cs_parser *parser,
-- 
1.7.9.5



[PATCH 02/16] drm/radeon: add error handling to radeon_vm_unbind_locked

2012-07-09 Thread Christian König
Waiting for a fence can fail for different reasons,
the most common is a deadlock.

Signed-off-by: Christian K?nig 
Reviewed-by: Michel D?nzer 
---
 drivers/gpu/drm/radeon/radeon_gart.c |   17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index 2b34c1a..ee11c50 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -316,10 +316,21 @@ static void radeon_vm_unbind_locked(struct radeon_device 
*rdev,
}

/* wait for vm use to end */
-   if (vm->fence) {
-   radeon_fence_wait(vm->fence, false);
-   radeon_fence_unref(&vm->fence);
+   while (vm->fence) {
+   int r;
+   r = radeon_fence_wait(vm->fence, false);
+   if (r)
+   DRM_ERROR("error while waiting for fence: %d\n", r);
+   if (r == -EDEADLK) {
+   mutex_unlock(&rdev->vm_manager.lock);
+   r = radeon_gpu_reset(rdev);
+   mutex_lock(&rdev->vm_manager.lock);
+   if (!r)
+   continue;
+   }
+   break;
}
+   radeon_fence_unref(&vm->fence);

/* hw unbind */
rdev->vm_manager.funcs->unbind(rdev, vm);
-- 
1.7.9.5



[PATCH 01/16] drm/radeon: add error handling to fence_wait_empty_locked

2012-07-09 Thread Christian König
Instead of returning the error handle it directly
and while at it fix the comments about the ring lock.

Signed-off-by: Christian K?nig 
Reviewed-by: Michel D?nzer 
---
 drivers/gpu/drm/radeon/radeon.h   |2 +-
 drivers/gpu/drm/radeon/radeon_fence.c |   33 +
 2 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 77b4519b..5861ec8 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -239,7 +239,7 @@ void radeon_fence_process(struct radeon_device *rdev, int 
ring);
 bool radeon_fence_signaled(struct radeon_fence *fence);
 int radeon_fence_wait(struct radeon_fence *fence, bool interruptible);
 int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring);
-int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring);
+void radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring);
 int radeon_fence_wait_any(struct radeon_device *rdev,
  struct radeon_fence **fences,
  bool intr);
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 7b55625..be4e4f3 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -440,14 +440,11 @@ int radeon_fence_wait_any(struct radeon_device *rdev,
return 0;
 }

+/* caller must hold ring lock */
 int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring)
 {
uint64_t seq;

-   /* We are not protected by ring lock when reading current seq but
-* it's ok as worst case is we return to early while we could have
-* wait.
-*/
seq = atomic64_read(&rdev->fence_drv[ring].last_seq) + 1ULL;
if (seq >= rdev->fence_drv[ring].sync_seq[ring]) {
/* nothing to wait for, last_seq is
@@ -457,15 +454,27 @@ int radeon_fence_wait_next_locked(struct radeon_device 
*rdev, int ring)
return radeon_fence_wait_seq(rdev, seq, ring, false, false);
 }

-int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring)
+/* caller must hold ring lock */
+void radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring)
 {
-   /* We are not protected by ring lock when reading current seq
-* but it's ok as wait empty is call from place where no more
-* activity can be scheduled so there won't be concurrent access
-* to seq value.
-*/
-   return radeon_fence_wait_seq(rdev, rdev->fence_drv[ring].sync_seq[ring],
-ring, false, false);
+   uint64_t seq = rdev->fence_drv[ring].sync_seq[ring];
+
+   while(1) {
+   int r;
+   r = radeon_fence_wait_seq(rdev, seq, ring, false, false);
+   if (r == -EDEADLK) {
+   mutex_unlock(&rdev->ring_lock);
+   r = radeon_gpu_reset(rdev);
+   mutex_lock(&rdev->ring_lock);
+   if (!r)
+   continue;
+   }
+   if (r) {
+   dev_err(rdev->dev, "error waiting for ring to become"
+   " idle (%d)\n", r);
+   }
+   return;
+   }
 }

 struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence)
-- 
1.7.9.5



[RFC] drm/radeon: restoring ring commands in case of a lockup

2012-07-09 Thread Christian König
Hi,

The following patchset tries to save and restore the not yet processed commands
from the rings in case of a lockup and with that should make a userspace
problem with a single application far less problematic.

The first four patches are just stuff this patchset is based upon, followed by
four patches which fix various bugs found while working on this feature.

Followed by patches which change the way how memory is saved/restored on
suspend/resume, basically before we have unpinned most of the buffer objects so
it could be move from vram into system memory. But that is mostly unnecessary
cause the buffer object either are already in system memory or their content
can be easily reinitialized.

The last three patches implement the actual tracking and restoring of commands
in case of a lockup. Please take a look and review.

Cheers,
Christian.



[PATCH 15/16] drm/radeon: implement ring commit tracking

2012-07-09 Thread Jerome Glisse
On Mon, Jul 9, 2012 at 11:48 AM, Christian K?nig
 wrote:
> On 09.07.2012 17:36, Jerome Glisse wrote:
>>
>> On Mon, Jul 9, 2012 at 6:42 AM, Christian K?nig 
>> wrote:
>>>
>>> Signed-off-by: Christian K?nig 
>>
>> Bit too complex to my taste, what about attached patch, it's lot
>> simpler. (Haven't tested
>> the patch but it should work)
>
> Cool idea! Depending on the writeback mechanism might not be the best part
> of it, but in general speaking all rings should have more than enough
> scratch registers for that!!!
>
> Going to change it.
>
> Thanks,
> Christian.
>

Note that i haven't included the fence emit intentionally idea being
if you resume ring you fence to emit the last fence as soon as
possible and just pretend that the faulty ib succeeded.

Cheers,
Jerome


[RFC] drm/radeon: restoring ring commands in case of a lockup

2012-07-09 Thread Jerome Glisse
On Mon, Jul 9, 2012 at 11:59 AM, Michel D?nzer  wrote:
> On Mon, 2012-07-09 at 12:41 +0200, Christian K?nig wrote:
>> Hi,
>>
>> The following patchset tries to save and restore the not yet processed 
>> commands
>> from the rings in case of a lockup and with that should make a userspace
>> problem with a single application far less problematic.
>>
>> The first four patches are just stuff this patchset is based upon, followed 
>> by
>> four patches which fix various bugs found while working on this feature.
>>
>> Followed by patches which change the way how memory is saved/restored on
>> suspend/resume, basically before we have unpinned most of the buffer objects 
>> so
>> it could be move from vram into system memory. But that is mostly unnecessary
>> cause the buffer object either are already in system memory or their content
>> can be easily reinitialized.
>>
>> The last three patches implement the actual tracking and restoring of 
>> commands
>> in case of a lockup. Please take a look and review.
>
> Patches 3, 5 and 14 are
>
> Reviewed-by: Michel D?nzer 
>

Patch 1-9 are
Reviewed-by: Jerome Glisse 

Other looks good but i want to test them too and spend a bit more time
to double check few things. Will try to do that tomorrow.

Cheers,
Jerome


[PATCH 15/16] drm/radeon: implement ring commit tracking

2012-07-09 Thread Jerome Glisse
for (j = 0; j <= count; j++) {
> -   seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]);
> +   seq_printf(m, "r[%04x]=0x%08x", i, ring->ring[i]);
> +   if (commit != ring->track_ptr && ring->track_back[commit] == 
> i) {
> +   seq_printf(m, " <-");
> +   ++commit;
> +   commit &= ring->track_mask;
> +   }
> +   seq_printf(m, "\n");
> i = (i + 1) & ring->ptr_mask;
> }
> return 0;
> --
> 1.7.9.5
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
-- next part --
A non-text attachment was scrubbed...
Name: 0001-drm-radeon-record-what-is-next-valid-wptr-for-each-r.patch
Type: application/octet-stream
Size: 7152 bytes
Desc: not available
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20120709/f0d368f6/attachment.obj>


[Bug 51870] r600_streamout=1 nothing change

2012-07-09 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=51870

--- Comment #2 from ErikAlesund  2012-07-09 11:13:09 
UTC ---
(In reply to comment #1)
> Those environment variables aren't required anymore. GLSL 1.3 and streamout 
> are
> enabled by default. The only thing missing is MSAA and there is no way to
> enable it at the moment. Closing.

If would be nice to avoid confusion remove this:

10 Requires env var R600_STREAMOUT=1

in the radeon's feature page:


http://www.x.org/wiki/RadeonFeature/


Thanks

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


[PATCH 09/16] drm/radeon: make cp init on cayman more robust

2012-07-09 Thread Jerome Glisse
On Mon, Jul 9, 2012 at 6:41 AM, Christian K?nig  
wrote:
> It's not critical, but the current code isn't
> 100% correct.
>
> Signed-off-by: Christian K?nig 
> ---
>  drivers/gpu/drm/radeon/ni.c |  133 
> ++-
>  1 file changed, 56 insertions(+), 77 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
> index 32a6082..8b1df33 100644
> --- a/drivers/gpu/drm/radeon/ni.c
> +++ b/drivers/gpu/drm/radeon/ni.c
> @@ -987,10 +987,33 @@ static void cayman_cp_fini(struct radeon_device *rdev)
>
>  int cayman_cp_resume(struct radeon_device *rdev)
>  {
> +   static const int ridx[] = {
> +   RADEON_RING_TYPE_GFX_INDEX,
> +   CAYMAN_RING_TYPE_CP1_INDEX,
> +   CAYMAN_RING_TYPE_CP2_INDEX
> +   };
> +   static const unsigned cp_rb_cntl[] = {
> +   CP_RB0_CNTL,
> +   CP_RB1_CNTL,
> +   CP_RB2_CNTL,
> +   };
> +   static const unsigned cp_rb_rptr_addr[] = {
> +   CP_RB0_RPTR_ADDR,
> +   CP_RB1_RPTR_ADDR,
> +   CP_RB2_RPTR_ADDR
> +   };
> +   static const unsigned cp_rb_rptr_addr_hi[] = {
> +   CP_RB0_RPTR_ADDR_HI,
> +   CP_RB1_RPTR_ADDR_HI,
> +   CP_RB2_RPTR_ADDR_HI
> +   };
> +   static const unsigned cp_rb_base[] = {
> +   CP_RB0_BASE,
> +   CP_RB1_BASE,
> +   CP_RB2_BASE
> +   };
> struct radeon_ring *ring;
> -   u32 tmp;
> -   u32 rb_bufsz;
> -   int r;
> +   int i, r;
>
> /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */
> WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP |
> @@ -1012,91 +1035,47 @@ int cayman_cp_resume(struct radeon_device *rdev)
>
> WREG32(CP_DEBUG, (1 << 27));
>
> -   /* ring 0 - compute and gfx */
> -   /* Set ring buffer size */
> -   ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
> -   rb_bufsz = drm_order(ring->ring_size / 8);
> -   tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
> -#ifdef __BIG_ENDIAN
> -   tmp |= BUF_SWAP_32BIT;
> -#endif
> -   WREG32(CP_RB0_CNTL, tmp);
> -
> -   /* Initialize the ring buffer's read and write pointers */
> -   WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA);
> -   ring->wptr = 0;
> -   WREG32(CP_RB0_WPTR, ring->wptr);
> -
> /* set the wb address wether it's enabled or not */
> -   WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + 
> RADEON_WB_CP_RPTR_OFFSET) & 0xFFFC);
> -   WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + 
> RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
> WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) 
> >> 8) & 0x);
> +   WREG32(SCRATCH_UMSK, 0xff);

This looks wrong you set the mask unconditionaly even if writeback is disabled.


> -   if (rdev->wb.enabled)
> -   WREG32(SCRATCH_UMSK, 0xff);
> -   else {
> -   tmp |= RB_NO_UPDATE;
> -   WREG32(SCRATCH_UMSK, 0);
> -   }
> -
> -   mdelay(1);
> -   WREG32(CP_RB0_CNTL, tmp);
> -
> -   WREG32(CP_RB0_BASE, ring->gpu_addr >> 8);
> -
> -   ring->rptr = RREG32(CP_RB0_RPTR);
> +   for (i = 0; i < 3; ++i) {
> +   uint32_t rb_cntl;
> +   uint64_t addr;
>
> -   /* ring1  - compute only */
> -   /* Set ring buffer size */
> -   ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
> -   rb_bufsz = drm_order(ring->ring_size / 8);
> -   tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
> +   /* Set ring buffer size */
> +   ring = &rdev->ring[ridx[i]];
> +   rb_cntl = drm_order(ring->ring_size / 8);
> +   rb_cntl |= drm_order(RADEON_GPU_PAGE_SIZE/8) << 8;
>  #ifdef __BIG_ENDIAN
> -   tmp |= BUF_SWAP_32BIT;
> +   rb_cntl |= BUF_SWAP_32BIT;
>  #endif
> -   WREG32(CP_RB1_CNTL, tmp);
> +   WREG32(cp_rb_cntl[i], rb_cntl);
>
> -   /* Initialize the ring buffer's read and write pointers */
> -   WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA);
> -   ring->wptr = 0;
> -   WREG32(CP_RB1_WPTR, ring->wptr);
> -
> -   /* set the wb address wether it's enabled or not */
> -   WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + 
> RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFC);
> -   WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + 
> RADEON_WB_CP1_RPTR_OFFSET) & 0xFF);
> -
> -   mdelay(1);
> -   WREG32(CP_RB1_CNTL, tmp);
> -
> -   WREG32(CP_RB1_BASE, ring->gpu_addr >> 8);
> -
> -   ring->rptr = RREG32(CP_RB1_RPTR);
> -
> -   /* ring2 - compute only */
> -   /* Set ring buffer size */
> -   ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
> -   rb_bufsz = drm_order(ring->ring_size / 8);
> -   tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
> -#ifdef __BIG_ENDIAN
> -   tmp |= BUF_SWAP_32BIT;
> -#endif
> -

[PATCH, RFC] i.MX DRM support

2012-07-09 Thread Sascha Hauer
On Sun, Jul 08, 2012 at 08:35:55AM +0100, Dave Airlie wrote:
> On Fri, Jul 6, 2012 at 11:58 PM, Greg Kroah-Hartman
>  wrote:
> > On Mon, Jul 02, 2012 at 12:05:06PM +0200, Sascha Hauer wrote:
> >> On Thu, Jun 14, 2012 at 03:43:22PM +0200, Sascha Hauer wrote:
> >> > Hi All,
> >> >
> >> > The following is the state-of-the-art i.MX IPU (Image Processing Unit)
> >> > DRM support.
> >> >
> >> > This code is around for quite some time now and has been posted several
> >> > times with different APIs, first with plain old framebuffer support, now
> >> > DRM, first platform device binding, now devicetree. Unfortunately there's
> >> > quite much code needed to get something useful out of the IPU, so these
> >> > patches haven't received a lot of attention from people not involved in
> >> > i.MX. I think we have now come to a point where this code needs more 
> >> > public
> >> > exposure and where it's easier to talk in incremental changes instead of
> >> > blobs. Therefore I request this to go to staging for some cycles.
> >>
> >> Dave, Greg,
> >>
> >> Comments to this one? I addressed the comments I received so far and am
> >> about to respin this series. Is it ok to put this to staging? If yes,
> >> should I move the whole stuff into drivers/staging/ or should it stay
> >> in drivers/gpu/drm with just a Kconfig dependency on STAGING?
> >
> > That's up to the DRM subsystem maintainer to choose.
> 
> Sorry guys been out of the loop on arm drivers due to other things,
> but probably should go in staging proper for now, until I can at least
> spend time reviewing it.

Right now we have dependencies on:

http://www.mail-archive.com/dri-devel at lists.freedesktop.org/msg24409.html
http://www.mail-archive.com/dri-devel at lists.freedesktop.org/msg24224.html

We could move these two helpers into staging, but they are needed by
other drivers from Laurent Pinchart and Lars-Peter Clausen aswell. So
it would be good to have them available for them aswell. Could you have
a look on these and consider applying?

Thanks,
  Sascha

-- 
Pengutronix e.K.   | |
Industrial Linux Solutions | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0|
Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |


Re: Mesa shader compiling/optimizing process is too slow

2012-07-09 Thread Eric Anholt
Tiziano Bacocco  writes:

> I've done benchmarks and comparison between proprietary drivers and 
> Mesa, Mesa seems to be up to 200x slower compiling the same shader, 
> since i understand optimizing such part of code may take months or even 
> more, i have thought to solve it this way:
>
> Upon calling glLinkProgram , an unoptimized version of the shader ( 
> compiles much much faster ) is uploaded to the GPU
> Then a separate thread is launched that will optimize the shader and as 
> soon it is done, on the next call to glUseProgram it will upload 
> optimized version in place of unoptimized one.
>
> This will solve many performance issues and temporary freezes with games 
> that load/unload content while running, while not reducing performance 
> once the background optimization is done

Yeah, we've thought of this, and it would take some work.  Sounds like a
fun project for someone.


pgpkHIemNwJ9w.pgp
Description: PGP signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Mesa shader compiling/optimizing process is too slow

2012-07-09 Thread Eric Anholt
Tiziano Bacocco  writes:

> I've done benchmarks and comparison between proprietary drivers and 
> Mesa, Mesa seems to be up to 200x slower compiling the same shader, 
> since i understand optimizing such part of code may take months or even 
> more, i have thought to solve it this way:
>
> Upon calling glLinkProgram , an unoptimized version of the shader ( 
> compiles much much faster ) is uploaded to the GPU
> Then a separate thread is launched that will optimize the shader and as 
> soon it is done, on the next call to glUseProgram it will upload 
> optimized version in place of unoptimized one.
>
> This will solve many performance issues and temporary freezes with games 
> that load/unload content while running, while not reducing performance 
> once the background optimization is done

Yeah, we've thought of this, and it would take some work.  Sounds like a
fun project for someone.
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20120709/0b21e4c7/attachment.pgp>


Mesa shader compiling/optimizing process is too slow

2012-07-09 Thread Tiziano Bacocco
I've done benchmarks and comparison between proprietary drivers and 
Mesa, Mesa seems to be up to 200x slower compiling the same shader, 
since i understand optimizing such part of code may take months or even 
more, i have thought to solve it this way:


Upon calling glLinkProgram , an unoptimized version of the shader ( 
compiles much much faster ) is uploaded to the GPU
Then a separate thread is launched that will optimize the shader and as 
soon it is done, on the next call to glUseProgram it will upload 
optimized version in place of unoptimized one.


This will solve many performance issues and temporary freezes with games 
that load/unload content while running, while not reducing performance 
once the background optimization is done

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 15/16] drm/radeon: implement ring commit tracking

2012-07-09 Thread Jerome Glisse
On Mon, Jul 9, 2012 at 11:48 AM, Christian König
 wrote:
> On 09.07.2012 17:36, Jerome Glisse wrote:
>>
>> On Mon, Jul 9, 2012 at 6:42 AM, Christian König 
>> wrote:
>>>
>>> Signed-off-by: Christian König 
>>
>> Bit too complex to my taste, what about attached patch, it's lot
>> simpler. (Haven't tested
>> the patch but it should work)
>
> Cool idea! Depending on the writeback mechanism might not be the best part
> of it, but in general speaking all rings should have more than enough
> scratch registers for that!!!
>
> Going to change it.
>
> Thanks,
> Christian.
>

Note that i haven't included the fence emit intentionally idea being
if you resume ring you fence to emit the last fence as soon as
possible and just pretend that the faulty ib succeeded.

Cheers,
Jerome
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC] drm/radeon: restoring ring commands in case of a lockup

2012-07-09 Thread Jerome Glisse
On Mon, Jul 9, 2012 at 11:59 AM, Michel Dänzer  wrote:
> On Mon, 2012-07-09 at 12:41 +0200, Christian König wrote:
>> Hi,
>>
>> The following patchset tries to save and restore the not yet processed 
>> commands
>> from the rings in case of a lockup and with that should make a userspace
>> problem with a single application far less problematic.
>>
>> The first four patches are just stuff this patchset is based upon, followed 
>> by
>> four patches which fix various bugs found while working on this feature.
>>
>> Followed by patches which change the way how memory is saved/restored on
>> suspend/resume, basically before we have unpinned most of the buffer objects 
>> so
>> it could be move from vram into system memory. But that is mostly unnecessary
>> cause the buffer object either are already in system memory or their content
>> can be easily reinitialized.
>>
>> The last three patches implement the actual tracking and restoring of 
>> commands
>> in case of a lockup. Please take a look and review.
>
> Patches 3, 5 and 14 are
>
> Reviewed-by: Michel Dänzer 
>

Patch 1-9 are
Reviewed-by: Jerome Glisse 

Other looks good but i want to test them too and spend a bit more time
to double check few things. Will try to do that tomorrow.

Cheers,
Jerome
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC] drm/radeon: restoring ring commands in case of a lockup

2012-07-09 Thread Michel Dänzer
On Mon, 2012-07-09 at 12:41 +0200, Christian König wrote: 
> Hi,
> 
> The following patchset tries to save and restore the not yet processed 
> commands
> from the rings in case of a lockup and with that should make a userspace
> problem with a single application far less problematic.
> 
> The first four patches are just stuff this patchset is based upon, followed by
> four patches which fix various bugs found while working on this feature.
> 
> Followed by patches which change the way how memory is saved/restored on
> suspend/resume, basically before we have unpinned most of the buffer objects 
> so
> it could be move from vram into system memory. But that is mostly unnecessary
> cause the buffer object either are already in system memory or their content
> can be easily reinitialized.
> 
> The last three patches implement the actual tracking and restoring of commands
> in case of a lockup. Please take a look and review.

Patches 3, 5 and 14 are

Reviewed-by: Michel Dänzer 


-- 
Earthling Michel Dänzer   |   http://www.amd.com
Libre software enthusiast |  Debian, X and DRI developer
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 15/16] drm/radeon: implement ring commit tracking

2012-07-09 Thread Christian König

On 09.07.2012 17:36, Jerome Glisse wrote:

On Mon, Jul 9, 2012 at 6:42 AM, Christian König  wrote:

Signed-off-by: Christian König 

Bit too complex to my taste, what about attached patch, it's lot
simpler. (Haven't tested
the patch but it should work)
Cool idea! Depending on the writeback mechanism might not be the best 
part of it, but in general speaking all rings should have more than 
enough scratch registers for that!!!


Going to change it.

Thanks,
Christian.



Cheers,
Jerome


---
  drivers/gpu/drm/radeon/radeon.h  |3 +++
  drivers/gpu/drm/radeon/radeon_ring.c |   39 --
  2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index fef4257..9c11be8 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -637,6 +637,9 @@ struct radeon_ring {
 u32 ptr_reg_shift;
 u32 ptr_reg_mask;
 u32 nop;
+   unsigned*track_back;
+   unsignedtrack_ptr;
+   unsignedtrack_mask;
  };

  /*
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index d9b2e45..994c98c 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -276,6 +276,8 @@ void radeon_ring_commit(struct radeon_device *rdev, struct 
radeon_ring *ring)
 DRM_MEMORYBARRIER();
 WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & 
ring->ptr_reg_mask);
 (void)RREG32(ring->wptr_reg);
+   ring->track_back[ring->track_ptr++] = ring->wptr_old;
+   ring->track_ptr &= ring->track_mask;
  }

  void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring 
*ring)
@@ -362,6 +364,27 @@ bool radeon_ring_test_lockup(struct radeon_device *rdev, 
struct radeon_ring *rin
 return false;
  }

+static unsigned radeon_ring_first_valid_commit(struct radeon_ring *ring)
+{
+   unsigned i, c, result = ring->track_ptr;
+   i = ring->track_ptr - 1;
+   while (i != ring->track_ptr) {
+   i &= ring->track_mask;
+   c = ring->track_back[i];
+
+   if (ring->wptr >= ring->rptr) {
+   if (c < ring->rptr || c >= ring->wptr)
+   break;
+   } else {
+   if (c < ring->rptr && c >= ring->wptr)
+   break;
+   }
+
+   result = i--;
+   }
+   return result;
+}
+
  int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring,
  unsigned ring_size, unsigned align,
  unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg,
@@ -403,6 +426,10 @@ int radeon_ring_init(struct radeon_device *rdev, struct 
radeon_ring *ring,
 dev_err(rdev->dev, "(%d) ring map failed\n", r);
 return r;
 }
+   ring->track_back = kmalloc(ring_size / align, GFP_KERNEL);
+   memset(ring->track_back, 0, ring_size / align);
+   ring->track_ptr = 0;
+   ring->track_mask = ((ring->ring_size / 4) / align) - 1;
 }
 ring->ptr_mask = (ring->ring_size / 4) - 1;
 ring->ring_free_dw = ring->ring_size / 4;
@@ -422,6 +449,7 @@ void radeon_ring_fini(struct radeon_device *rdev, struct 
radeon_ring *ring)
 ring->ready = false;
 ring->ring = NULL;
 ring->ring_obj = NULL;
+   kfree(ring->track_back);
 mutex_unlock(&rdev->ring_lock);

 if (ring_obj) {
@@ -447,7 +475,7 @@ static int radeon_debugfs_ring_info(struct seq_file *m, 
void *data)
 struct radeon_device *rdev = dev->dev_private;
 int ridx = *(int*)node->info_ent->data;
 struct radeon_ring *ring = &rdev->ring[ridx];
-   unsigned count, i, j;
+   unsigned count, i, j, commit;

 radeon_ring_free_size(rdev, ring);
 count = (ring->ring_size / 4) - ring->ring_free_dw;
@@ -457,9 +485,16 @@ static int radeon_debugfs_ring_info(struct seq_file *m, 
void *data)
 seq_printf(m, "driver's copy of the rptr: 0x%08x\n", ring->rptr);
 seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw);
 seq_printf(m, "%u dwords in ring\n", count);
+   commit = radeon_ring_first_valid_commit(ring);
 i = ring->rptr;
 for (j = 0; j <= count; j++) {
-   seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]);
+   seq_printf(m, "r[%04x]=0x%08x", i, ring->ring[i]);
+   if (commit != ring->track_ptr && ring->track_back[commit] == i) 
{
+   seq_printf(m, " <-");
+   ++commit;
+   commit &= ring->track_mask;
+   }
+   seq_printf(m, "\n");
 i = (i + 1) & ring->ptr_mas

[Bug 44341] Radeon HD6990M: HDMI audio output works now! Kernel gives new warning

2012-07-09 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=44341


Christopher Fr?mmel  changed:

   What|Removed |Added

  Attachment #75061|application/octet-stream|text/plain
  mime type||




-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.


[Bug 44341] Radeon HD6990M: HDMI audio output works now! Kernel gives new warning

2012-07-09 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=44341


Christopher Fr?mmel  changed:

   What|Removed |Added

  Attachment #75121|application/octet-stream|text/plain
  mime type||




-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.


[Bug 44341] Radeon HD6990M: HDMI audio output works now! Kernel gives new warning

2012-07-09 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=44341


Christopher Fr?mmel  changed:

   What|Removed |Added

  Attachment #75091|application/octet-stream|text/plain
  mime type||




-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.


[Bug 44341] Radeon HD6990M: HDMI audio output works now! Kernel gives new warning

2012-07-09 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=44341


Christopher Fr?mmel  changed:

   What|Removed |Added

  Attachment #75071|application/octet-stream|text/plain
  mime type||




-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.


[Bug 44341] Radeon HD6990M: HDMI audio output works now! Kernel gives new warning

2012-07-09 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=44341


Christopher Fr?mmel  changed:

   What|Removed |Added

  Attachment #75081|application/octet-stream|text/plain
  mime type||




-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.


Re: [PATCH 13/16] drm/radeon: move radeon_ib_ring_tests out of chipset code

2012-07-09 Thread Michel Dänzer
On Mon, 2012-07-09 at 17:22 +0200, Christian König wrote: 
> On 09.07.2012 17:06, Michel Dänzer wrote:
> > On Mon, 2012-07-09 at 12:42 +0200, Christian König wrote:
> >> Making it easier to controlwhen it is executed.
> >>
> >> Signed-off-by: Christian König 
> > [...]
> >> diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
> >> b/drivers/gpu/drm/radeon/radeon_device.c
> >> index 254fdb4..bbd0971 100644
> >> --- a/drivers/gpu/drm/radeon/radeon_device.c
> >> +++ b/drivers/gpu/drm/radeon/radeon_device.c
> >> @@ -822,6 +822,10 @@ int radeon_device_init(struct radeon_device *rdev,
> >>if (r)
> >>return r;
> >>   
> >> +  r = radeon_ib_ring_tests(rdev);
> >> +  if (r)
> >> +  DRM_ERROR("ib ring test failed (%d).\n", r);
> >> +
> >>if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) {
> >>/* Acceleration not working on AGP card try again
> >> * with fallback to PCI or PCIE GART
> > I think this needs to set rdev->accel_working = false on failure, so the
> > AGP -> PCI(e) fallback can kick in.
> 
> See the implementation of radeon_ib_ring_tests, it is already handling 
> that internally.

Oops, I actually did check this when writing the above, but somehow I
failed to see what I was looking for. :}


-- 
Earthling Michel Dänzer   |   http://www.amd.com
Libre software enthusiast |  Debian, X and DRI developer
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 15/16] drm/radeon: implement ring commit tracking

2012-07-09 Thread Jerome Glisse
On Mon, Jul 9, 2012 at 6:42 AM, Christian König  wrote:
> Signed-off-by: Christian König 

Bit too complex to my taste, what about attached patch, it's lot
simpler. (Haven't tested
the patch but it should work)

Cheers,
Jerome

> ---
>  drivers/gpu/drm/radeon/radeon.h  |3 +++
>  drivers/gpu/drm/radeon/radeon_ring.c |   39 
> --
>  2 files changed, 40 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index fef4257..9c11be8 100644
> --- a/drivers/gpu/drm/radeon/radeon.h
> +++ b/drivers/gpu/drm/radeon/radeon.h
> @@ -637,6 +637,9 @@ struct radeon_ring {
> u32 ptr_reg_shift;
> u32 ptr_reg_mask;
> u32 nop;
> +   unsigned*track_back;
> +   unsignedtrack_ptr;
> +   unsignedtrack_mask;
>  };
>
>  /*
> diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
> b/drivers/gpu/drm/radeon/radeon_ring.c
> index d9b2e45..994c98c 100644
> --- a/drivers/gpu/drm/radeon/radeon_ring.c
> +++ b/drivers/gpu/drm/radeon/radeon_ring.c
> @@ -276,6 +276,8 @@ void radeon_ring_commit(struct radeon_device *rdev, 
> struct radeon_ring *ring)
> DRM_MEMORYBARRIER();
> WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & 
> ring->ptr_reg_mask);
> (void)RREG32(ring->wptr_reg);
> +   ring->track_back[ring->track_ptr++] = ring->wptr_old;
> +   ring->track_ptr &= ring->track_mask;
>  }
>
>  void radeon_ring_unlock_commit(struct radeon_device *rdev, struct 
> radeon_ring *ring)
> @@ -362,6 +364,27 @@ bool radeon_ring_test_lockup(struct radeon_device *rdev, 
> struct radeon_ring *rin
> return false;
>  }
>
> +static unsigned radeon_ring_first_valid_commit(struct radeon_ring *ring)
> +{
> +   unsigned i, c, result = ring->track_ptr;
> +   i = ring->track_ptr - 1;
> +   while (i != ring->track_ptr) {
> +   i &= ring->track_mask;
> +   c = ring->track_back[i];
> +
> +   if (ring->wptr >= ring->rptr) {
> +   if (c < ring->rptr || c >= ring->wptr)
> +   break;
> +   } else {
> +   if (c < ring->rptr && c >= ring->wptr)
> +   break;
> +   }
> +
> +   result = i--;
> +   }
> +   return result;
> +}
> +
>  int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring,
>  unsigned ring_size, unsigned align,
>  unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg,
> @@ -403,6 +426,10 @@ int radeon_ring_init(struct radeon_device *rdev, struct 
> radeon_ring *ring,
> dev_err(rdev->dev, "(%d) ring map failed\n", r);
> return r;
> }
> +   ring->track_back = kmalloc(ring_size / align, GFP_KERNEL);
> +   memset(ring->track_back, 0, ring_size / align);
> +   ring->track_ptr = 0;
> +   ring->track_mask = ((ring->ring_size / 4) / align) - 1;
> }
> ring->ptr_mask = (ring->ring_size / 4) - 1;
> ring->ring_free_dw = ring->ring_size / 4;
> @@ -422,6 +449,7 @@ void radeon_ring_fini(struct radeon_device *rdev, struct 
> radeon_ring *ring)
> ring->ready = false;
> ring->ring = NULL;
> ring->ring_obj = NULL;
> +   kfree(ring->track_back);
> mutex_unlock(&rdev->ring_lock);
>
> if (ring_obj) {
> @@ -447,7 +475,7 @@ static int radeon_debugfs_ring_info(struct seq_file *m, 
> void *data)
> struct radeon_device *rdev = dev->dev_private;
> int ridx = *(int*)node->info_ent->data;
> struct radeon_ring *ring = &rdev->ring[ridx];
> -   unsigned count, i, j;
> +   unsigned count, i, j, commit;
>
> radeon_ring_free_size(rdev, ring);
> count = (ring->ring_size / 4) - ring->ring_free_dw;
> @@ -457,9 +485,16 @@ static int radeon_debugfs_ring_info(struct seq_file *m, 
> void *data)
> seq_printf(m, "driver's copy of the rptr: 0x%08x\n", ring->rptr);
> seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw);
> seq_printf(m, "%u dwords in ring\n", count);
> +   commit = radeon_ring_first_valid_commit(ring);
> i = ring->rptr;
> for (j = 0; j <= count; j++) {
> -   seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]);
> +   seq_printf(m, "r[%04x]=0x%08x", i, ring->ring[i]);
> +   if (commit != ring->track_ptr && ring->track_back[commit] == 
> i) {
> +   seq_printf(m, " <-");
> +   ++commit;
> +   commit &= ring->track_mask;
> +   }
> +   seq_printf(m, "\n");
> i = (i + 1) & ring->ptr_mask;
> }
> return 0;
> --
> 1.7.9.5
>
> __

[Bug 42984] scrabled video with nouveau drivers on mac mini (320m)

2012-07-09 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=42984


m.b.lankhorst at gmail.com  changed:

   What|Removed |Added

 CC||m.b.lankhorst at gmail.com




--- Comment #15 from m.b.lankhorst at gmail.com   
2012-07-09 08:33:00 ---
This bug is fixed with commit a6a17859f1b and can be closed. It's backported to
3.2 stable and 3.4 with confirmation on 3.2.27

-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.


Re: [PATCH 16/16] drm/radeon: implement ring saving on reset

2012-07-09 Thread Christian König

On 09.07.2012 17:06, Michel Dänzer wrote:

On Mon, 2012-07-09 at 12:42 +0200, Christian König wrote:

Try to save whatever is on the rings when
we encounter an lockup.

Signed-off-by: Christian König 

[...]

@@ -1005,20 +1010,43 @@ int radeon_gpu_reset(struct radeon_device *rdev)
resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
radeon_suspend(rdev);
  
+	for (i = 0; i < RADEON_NUM_RINGS; ++i) {

+   ring_sizes[i] = radeon_ring_backup(rdev, &rdev->ring[i],
+  &ring_data[i]);
+   if (ring_sizes[i]) {
+   saved = true;
+   dev_info(rdev->dev, "Saved %d dwords of commands "
+"on ring %d.\n", ring_sizes[i], i);
+   }
+   }
+
+retry:
r = radeon_asic_reset(rdev);
if (!r) {
-   dev_info(rdev->dev, "GPU reset succeed\n");
+   dev_info(rdev->dev, "GPU reset succeed trying to resume\n");

Could fix the spelling of 'succeeded' while you're at it. :)

Akk, fixed it.




radeon_resume(rdev);
+   }
  
-		r = radeon_ib_ring_tests(rdev);

-   if (r)
-   DRM_ERROR("ib ring test failed (%d).\n", r);
+   radeon_restore_bios_scratch_regs(rdev);
+   drm_helper_resume_force_mode(rdev->ddev);
+
+   if (!r) {
+   for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+   radeon_ring_restore(rdev, &rdev->ring[i],
+   ring_sizes[i], ring_data[i]);
+   }

If radeon_asic_reset fails, this leaks the memory referenced by
ring_data, doesn't it?

Oh yes indeed, going to fix that.


Also, the added functions aren't documented as mandated by the rules
Alex proposed.


True, also going to fix that.

Christian.

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 13/16] drm/radeon: move radeon_ib_ring_tests out of chipset code

2012-07-09 Thread Christian König

On 09.07.2012 17:06, Michel Dänzer wrote:

On Mon, 2012-07-09 at 12:42 +0200, Christian König wrote:

Making it easier to controlwhen it is executed.

Signed-off-by: Christian König 

[...]

diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 254fdb4..bbd0971 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -822,6 +822,10 @@ int radeon_device_init(struct radeon_device *rdev,
if (r)
return r;
  
+	r = radeon_ib_ring_tests(rdev);

+   if (r)
+   DRM_ERROR("ib ring test failed (%d).\n", r);
+
if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) {
/* Acceleration not working on AGP card try again
 * with fallback to PCI or PCIE GART

I think this needs to set rdev->accel_working = false on failure, so the
AGP -> PCI(e) fallback can kick in.


See the implementation of radeon_ib_ring_tests, it is already handling 
that internally.



Not sure about the other places where you're adding
radeon_ib_ring_tests() calls, might need more error handling as well.
radeon_ib_ring_tests is already handling most errors internally, e. g. 
it sets the accel_working and the ring->ready flags to false if anything 
goes wrong. The return value is mostly for the case where we want to try 
the reset a second time if restoring the ring commands leads to another 
lockup. I just doesn't want to ignore the result completely, so the 
additional error message.


Christian.

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 09/16] drm/radeon: make cp init on cayman more robust

2012-07-09 Thread Christian König

On 09.07.2012 16:43, Jerome Glisse wrote:

On Mon, Jul 9, 2012 at 6:41 AM, Christian König  wrote:

It's not critical, but the current code isn't
100% correct.

Signed-off-by: Christian König 
---
  drivers/gpu/drm/radeon/ni.c |  133 ++-
  1 file changed, 56 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 32a6082..8b1df33 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -987,10 +987,33 @@ static void cayman_cp_fini(struct radeon_device *rdev)

  int cayman_cp_resume(struct radeon_device *rdev)
  {
+   static const int ridx[] = {
+   RADEON_RING_TYPE_GFX_INDEX,
+   CAYMAN_RING_TYPE_CP1_INDEX,
+   CAYMAN_RING_TYPE_CP2_INDEX
+   };
+   static const unsigned cp_rb_cntl[] = {
+   CP_RB0_CNTL,
+   CP_RB1_CNTL,
+   CP_RB2_CNTL,
+   };
+   static const unsigned cp_rb_rptr_addr[] = {
+   CP_RB0_RPTR_ADDR,
+   CP_RB1_RPTR_ADDR,
+   CP_RB2_RPTR_ADDR
+   };
+   static const unsigned cp_rb_rptr_addr_hi[] = {
+   CP_RB0_RPTR_ADDR_HI,
+   CP_RB1_RPTR_ADDR_HI,
+   CP_RB2_RPTR_ADDR_HI
+   };
+   static const unsigned cp_rb_base[] = {
+   CP_RB0_BASE,
+   CP_RB1_BASE,
+   CP_RB2_BASE
+   };
 struct radeon_ring *ring;
-   u32 tmp;
-   u32 rb_bufsz;
-   int r;
+   int i, r;

 /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */
 WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP |
@@ -1012,91 +1035,47 @@ int cayman_cp_resume(struct radeon_device *rdev)

 WREG32(CP_DEBUG, (1 << 27));

-   /* ring 0 - compute and gfx */
-   /* Set ring buffer size */
-   ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
-   rb_bufsz = drm_order(ring->ring_size / 8);
-   tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
-#ifdef __BIG_ENDIAN
-   tmp |= BUF_SWAP_32BIT;
-#endif
-   WREG32(CP_RB0_CNTL, tmp);
-
-   /* Initialize the ring buffer's read and write pointers */
-   WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA);
-   ring->wptr = 0;
-   WREG32(CP_RB0_WPTR, ring->wptr);
-
 /* set the wb address wether it's enabled or not */
-   WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) 
& 0xFFFC);
-   WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + 
RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
 WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) 
& 0x);
+   WREG32(SCRATCH_UMSK, 0xff);

This looks wrong you set the mask unconditionaly even if writeback is disabled.
writeback is always enabled for NI and APUs, but the register docs say 
that this feature isn't validated for NI and shouldn't be used so I'm 
not sure if enabling it is the right thing to do.


Anyway, it doesn't matter at all since we don't use the scratch register 
writeback anymore and use EOP instead.


Christian.






-   if (rdev->wb.enabled)
-   WREG32(SCRATCH_UMSK, 0xff);
-   else {
-   tmp |= RB_NO_UPDATE;
-   WREG32(SCRATCH_UMSK, 0);
-   }
-
-   mdelay(1);
-   WREG32(CP_RB0_CNTL, tmp);
-
-   WREG32(CP_RB0_BASE, ring->gpu_addr >> 8);
-
-   ring->rptr = RREG32(CP_RB0_RPTR);
+   for (i = 0; i < 3; ++i) {
+   uint32_t rb_cntl;
+   uint64_t addr;

-   /* ring1  - compute only */
-   /* Set ring buffer size */
-   ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
-   rb_bufsz = drm_order(ring->ring_size / 8);
-   tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
+   /* Set ring buffer size */
+   ring = &rdev->ring[ridx[i]];
+   rb_cntl = drm_order(ring->ring_size / 8);
+   rb_cntl |= drm_order(RADEON_GPU_PAGE_SIZE/8) << 8;
  #ifdef __BIG_ENDIAN
-   tmp |= BUF_SWAP_32BIT;
+   rb_cntl |= BUF_SWAP_32BIT;
  #endif
-   WREG32(CP_RB1_CNTL, tmp);
+   WREG32(cp_rb_cntl[i], rb_cntl);

-   /* Initialize the ring buffer's read and write pointers */
-   WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA);
-   ring->wptr = 0;
-   WREG32(CP_RB1_WPTR, ring->wptr);
-
-   /* set the wb address wether it's enabled or not */
-   WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) 
& 0xFFFC);
-   WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + 
RADEON_WB_CP1_RPTR_OFFSET) & 0xFF);
-
-   mdelay(1);
-   WREG32(CP_RB1_CNTL, tmp);
-
-   WREG32(CP_RB1_BASE, ring->gpu_addr >> 8);
-
-   ring->rptr = RREG32(CP_RB1_RPTR);
-
-   /* ring2 - compute only */
-   /* Set ring buffer size */
-   ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
-   rb_bufsz = drm_order(ring->ring_size / 8);
-   tmp = (drm

Re: [PATCH 13/16] drm/radeon: move radeon_ib_ring_tests out of chipset code

2012-07-09 Thread Michel Dänzer
On Mon, 2012-07-09 at 12:42 +0200, Christian König wrote: 
> Making it easier to controlwhen it is executed.
> 
> Signed-off-by: Christian König 
[...] 
> diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
> b/drivers/gpu/drm/radeon/radeon_device.c
> index 254fdb4..bbd0971 100644
> --- a/drivers/gpu/drm/radeon/radeon_device.c
> +++ b/drivers/gpu/drm/radeon/radeon_device.c
> @@ -822,6 +822,10 @@ int radeon_device_init(struct radeon_device *rdev,
>   if (r)
>   return r;
>  
> + r = radeon_ib_ring_tests(rdev);
> + if (r)
> + DRM_ERROR("ib ring test failed (%d).\n", r);
> +
>   if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) {
>   /* Acceleration not working on AGP card try again
>* with fallback to PCI or PCIE GART

I think this needs to set rdev->accel_working = false on failure, so the
AGP -> PCI(e) fallback can kick in.

Not sure about the other places where you're adding
radeon_ib_ring_tests() calls, might need more error handling as well.


-- 
Earthling Michel Dänzer   |   http://www.amd.com
Libre software enthusiast |  Debian, X and DRI developer
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 16/16] drm/radeon: implement ring saving on reset

2012-07-09 Thread Michel Dänzer
On Mon, 2012-07-09 at 12:42 +0200, Christian König wrote: 
> Try to save whatever is on the rings when
> we encounter an lockup.
> 
> Signed-off-by: Christian König 
[...] 
> @@ -1005,20 +1010,43 @@ int radeon_gpu_reset(struct radeon_device *rdev)
>   resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
>   radeon_suspend(rdev);
>  
> + for (i = 0; i < RADEON_NUM_RINGS; ++i) {
> + ring_sizes[i] = radeon_ring_backup(rdev, &rdev->ring[i],
> +&ring_data[i]);
> + if (ring_sizes[i]) {
> + saved = true;
> + dev_info(rdev->dev, "Saved %d dwords of commands "
> +  "on ring %d.\n", ring_sizes[i], i);
> + }
> + }
> +
> +retry:
>   r = radeon_asic_reset(rdev);
>   if (!r) {
> - dev_info(rdev->dev, "GPU reset succeed\n");
> + dev_info(rdev->dev, "GPU reset succeed trying to resume\n");

Could fix the spelling of 'succeeded' while you're at it. :)


>   radeon_resume(rdev);
> + }
>  
> - r = radeon_ib_ring_tests(rdev);
> - if (r)
> - DRM_ERROR("ib ring test failed (%d).\n", r);
> + radeon_restore_bios_scratch_regs(rdev);
> + drm_helper_resume_force_mode(rdev->ddev);
> +
> + if (!r) {
> + for (i = 0; i < RADEON_NUM_RINGS; ++i) {
> + radeon_ring_restore(rdev, &rdev->ring[i],
> + ring_sizes[i], ring_data[i]);
> + }

If radeon_asic_reset fails, this leaks the memory referenced by
ring_data, doesn't it?


Also, the added functions aren't documented as mandated by the rules
Alex proposed.


-- 
Earthling Michel Dänzer   |   http://www.amd.com
Libre software enthusiast |  Debian, X and DRI developer
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 09/16] drm/radeon: make cp init on cayman more robust

2012-07-09 Thread Jerome Glisse
On Mon, Jul 9, 2012 at 6:41 AM, Christian König  wrote:
> It's not critical, but the current code isn't
> 100% correct.
>
> Signed-off-by: Christian König 
> ---
>  drivers/gpu/drm/radeon/ni.c |  133 
> ++-
>  1 file changed, 56 insertions(+), 77 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
> index 32a6082..8b1df33 100644
> --- a/drivers/gpu/drm/radeon/ni.c
> +++ b/drivers/gpu/drm/radeon/ni.c
> @@ -987,10 +987,33 @@ static void cayman_cp_fini(struct radeon_device *rdev)
>
>  int cayman_cp_resume(struct radeon_device *rdev)
>  {
> +   static const int ridx[] = {
> +   RADEON_RING_TYPE_GFX_INDEX,
> +   CAYMAN_RING_TYPE_CP1_INDEX,
> +   CAYMAN_RING_TYPE_CP2_INDEX
> +   };
> +   static const unsigned cp_rb_cntl[] = {
> +   CP_RB0_CNTL,
> +   CP_RB1_CNTL,
> +   CP_RB2_CNTL,
> +   };
> +   static const unsigned cp_rb_rptr_addr[] = {
> +   CP_RB0_RPTR_ADDR,
> +   CP_RB1_RPTR_ADDR,
> +   CP_RB2_RPTR_ADDR
> +   };
> +   static const unsigned cp_rb_rptr_addr_hi[] = {
> +   CP_RB0_RPTR_ADDR_HI,
> +   CP_RB1_RPTR_ADDR_HI,
> +   CP_RB2_RPTR_ADDR_HI
> +   };
> +   static const unsigned cp_rb_base[] = {
> +   CP_RB0_BASE,
> +   CP_RB1_BASE,
> +   CP_RB2_BASE
> +   };
> struct radeon_ring *ring;
> -   u32 tmp;
> -   u32 rb_bufsz;
> -   int r;
> +   int i, r;
>
> /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */
> WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP |
> @@ -1012,91 +1035,47 @@ int cayman_cp_resume(struct radeon_device *rdev)
>
> WREG32(CP_DEBUG, (1 << 27));
>
> -   /* ring 0 - compute and gfx */
> -   /* Set ring buffer size */
> -   ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
> -   rb_bufsz = drm_order(ring->ring_size / 8);
> -   tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
> -#ifdef __BIG_ENDIAN
> -   tmp |= BUF_SWAP_32BIT;
> -#endif
> -   WREG32(CP_RB0_CNTL, tmp);
> -
> -   /* Initialize the ring buffer's read and write pointers */
> -   WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA);
> -   ring->wptr = 0;
> -   WREG32(CP_RB0_WPTR, ring->wptr);
> -
> /* set the wb address wether it's enabled or not */
> -   WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + 
> RADEON_WB_CP_RPTR_OFFSET) & 0xFFFC);
> -   WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + 
> RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
> WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) 
> >> 8) & 0x);
> +   WREG32(SCRATCH_UMSK, 0xff);

This looks wrong you set the mask unconditionaly even if writeback is disabled.


> -   if (rdev->wb.enabled)
> -   WREG32(SCRATCH_UMSK, 0xff);
> -   else {
> -   tmp |= RB_NO_UPDATE;
> -   WREG32(SCRATCH_UMSK, 0);
> -   }
> -
> -   mdelay(1);
> -   WREG32(CP_RB0_CNTL, tmp);
> -
> -   WREG32(CP_RB0_BASE, ring->gpu_addr >> 8);
> -
> -   ring->rptr = RREG32(CP_RB0_RPTR);
> +   for (i = 0; i < 3; ++i) {
> +   uint32_t rb_cntl;
> +   uint64_t addr;
>
> -   /* ring1  - compute only */
> -   /* Set ring buffer size */
> -   ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
> -   rb_bufsz = drm_order(ring->ring_size / 8);
> -   tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
> +   /* Set ring buffer size */
> +   ring = &rdev->ring[ridx[i]];
> +   rb_cntl = drm_order(ring->ring_size / 8);
> +   rb_cntl |= drm_order(RADEON_GPU_PAGE_SIZE/8) << 8;
>  #ifdef __BIG_ENDIAN
> -   tmp |= BUF_SWAP_32BIT;
> +   rb_cntl |= BUF_SWAP_32BIT;
>  #endif
> -   WREG32(CP_RB1_CNTL, tmp);
> +   WREG32(cp_rb_cntl[i], rb_cntl);
>
> -   /* Initialize the ring buffer's read and write pointers */
> -   WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA);
> -   ring->wptr = 0;
> -   WREG32(CP_RB1_WPTR, ring->wptr);
> -
> -   /* set the wb address wether it's enabled or not */
> -   WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + 
> RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFC);
> -   WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + 
> RADEON_WB_CP1_RPTR_OFFSET) & 0xFF);
> -
> -   mdelay(1);
> -   WREG32(CP_RB1_CNTL, tmp);
> -
> -   WREG32(CP_RB1_BASE, ring->gpu_addr >> 8);
> -
> -   ring->rptr = RREG32(CP_RB1_RPTR);
> -
> -   /* ring2 - compute only */
> -   /* Set ring buffer size */
> -   ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
> -   rb_bufsz = drm_order(ring->ring_size / 8);
> -   tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
> -#ifdef __BIG_ENDIAN
> -   tmp |= BUF_SWAP_32BIT;
> -#endif
> - 

question about drivers/gpu/drm/gma500/oaktrail_lvds.c

2012-07-09 Thread Julia Lawall
On Mon, 9 Jul 2012, Patrik Jakobsson wrote:

> On Sun, Jul 8, 2012 at 10:16 PM, Alan Cox  wrote:
>> On Sun, 8 Jul 2012 10:39:43 +0200 (CEST)
>> Julia Lawall  wrote:
>>
>>> In the function oaktrail_lvds_mode_set, I don't think that the following
>>> code makes any sense:
>>>
>>>  /* Find the connector we're trying to set up */
>>>  list_for_each_entry(connector, &mode_config->connector_list, head) 
>>> {
>>>  if (!connector->encoder || connector->encoder->crtc != 
>>> crtc)
>>>  continue;
>>>  }
>>>
>>>  if (!connector) {
>>>  DRM_ERROR("Couldn't find connector when setting mode");
>>>  return;
>>>  }
>>>
>>>  drm_connector_property_get_value(
>>>  connector,
>>>  dev->mode_config.scaling_mode_property,
>>>  &v);
>>>
>>> The initial loop is a no-op, because it always continues.  The test
>>> !connector can never be true, because at the end of a list_for_each_entry
>>> connector points to the list head, and calling
>>> drm_connector_property_get_value on the list head probably does not make
>>> sense.
>>
>> We test !connector->encoder rather than !connector ?
>
> It seems we should break on :
> if (connector->encoder && connector->encoder == encoder)
>
> Then do a check after list iteration:
> if (!connector || connector->encoder != encoder)
>DRM_ERROR("Couldn't find connector when setting mode");

Possible.  The !connector is still not needed, but the overall logic seems 
better.

julia


Re: [REGRESSION] nouveau: Memory corruption using nva3 engine for 0xaf

2012-07-09 Thread Henrik Rydberg
On Thu, Jul 05, 2012 at 10:34:10AM +0200, Henrik Rydberg wrote:
> On Thu, Jul 05, 2012 at 08:54:46AM +0200, Henrik Rydberg wrote:
> > > Thanks for tracking down the source of this corruption.  I don't have
> > > any such hardware, so until someone can figure it out, I think we
> > > should apply this patch.
> > 
> > In that case, I would have to massage the patch a bit first; it
> > creates a problem with suspend/resume. Might be something with
> > nva3_pm.c, who knows. I am really stabbing in the dark here. :-)
> 
> It seems the suspend/resume problem is unrelated (bad systemd update),
> so I am fine with applying this as is. Obviously not the best
> solution, and if I have time I will continue to look for problems in
> the nva3 copy code, but for now,
> 
> Signed-off-by: Henrik Rydberg 

I have not encountered the problem in a long while, and I do not have
the patch applied. It is entirely possible that this was fixed by
something else. Unless you have already applied the patch, I would
suggest holding on to it to see if the problem reappears.

Sorry for the churn.

Thanks,
Henrik
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 33309] [855GM] GPU freeze due to overlay hang

2012-07-09 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=33309

Chris Wilson  changed:

   What|Removed |Added

 Status|NEEDINFO|RESOLVED
 Resolution||NOTOURBUG

--- Comment #31 from Chris Wilson  2012-07-09 
11:37:34 PDT ---
Ok, I'm just as surprised; be wary of a surprise attack. In the meantime, have
fun!

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


Re: 3.5-rc5: radeon acceleration regression on Transmeta system

2012-07-09 Thread Meelis Roos
> > > In 3.4, radeon worked with a glitch - window titles were see-throug (not
> > > drawn). In 3.5-rc5, radeon driver seems to be more careful and disables
> > > acceleration on this system at all. Full dmesg below.
> > 
> > Does it always do it the same? got the dmesg from 3.4 and/or 2.6.32?
> 
> That was a good question. I did some more tries, and it was not 
> repeatable. Sometimes it worked like 3.4 did - rv100 initialized fine, 
> no borders except when maximized, otherwise worked.

Re-tested 3.4.0-rc7 that I had availble from 3.4 times, it worked 4 out 
of 4 times.

> Initial windows border problem seems to have been introduced between 
> 2.6.37 and 2.6.38, bisect is slow.

It's actually more complicated than that. Old kernel images started 
misbehaving from around 2.6.35-rc5 and any kernel older than that was 
OK. When I recompiled the older kernels with squeeze gcc (migh have been 
lenny gcc before, or different answers to make oldconfig), anything from 
current git down to 2.6.33 is broken with radeon.modeset=1 and works (I 
get window titles) with radeon.modeset=0.

2.6.32 works and has kernel modesetting enabled from dmesg but I think I 
did not notice screen going fbcon during boot... maybe it only used the 
modesetting when X started.

So there are 2 different problems (maybe related), the new one above and 
the old one of not seeing some window borders when modesetting and 
acceleration are in use. Maximized windows do have borders.

-- 
Meelis Roos (mr...@linux.ee)
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 33309] [855GM] GPU freeze due to overlay hang

2012-07-09 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=33309

--- Comment #30 from stefan  2012-07-09 11:18:52 PDT ---
Hi Daniel,
(In reply to comment #29)
> (In reply to comment #28)
> > are there any news on this issue?
> > The 3.4 and 3.5-rc series seem stable wrt this issue,
> > but unfortunately something broke resume from s2ram badly,
> > the backlight stays off and the machine does not respond
> > even to SysRq and I need to do a hard power-off.
> 
> That's good&bad news. Can you try to bisect the backlight regression that has
> been introduce in 3.4 and open a new bug report? That usually helps in fixing
> it ...

It turns out to be an ACPICA regression not related to graphics at all.

As for this issue, I did not observe any more hangs with v3.4 or 3.5-rc, *yet*.
It is hard to tell for sure since it usually takes a while (sometimes hours)
for it to occure. Which makes it also almost impossible to bisect and to find
the commit that might have fixed it.

Cheers,
Stefan.

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


[Bug 51870] r600_streamout=1 nothing change

2012-07-09 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=51870

--- Comment #2 from ErikAlesund  2012-07-09 11:13:09 
UTC ---
(In reply to comment #1)
> Those environment variables aren't required anymore. GLSL 1.3 and streamout 
> are
> enabled by default. The only thing missing is MSAA and there is no way to
> enable it at the moment. Closing.

If would be nice to avoid confusion remove this:

10 Requires env var R600_STREAMOUT=1

in the radeon's feature page:


http://www.x.org/wiki/RadeonFeature/


Thanks

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


[Bug 51870] r600_streamout=1 nothing change

2012-07-09 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=51870

Marek Olšák  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution||NOTABUG

--- Comment #1 from Marek Olšák  2012-07-09 10:50:59 PDT ---
Those environment variables aren't required anymore. GLSL 1.3 and streamout are
enabled by default. The only thing missing is MSAA and there is no way to
enable it at the moment. Closing.

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


[PATCH 16/16] drm/radeon: implement ring saving on reset

2012-07-09 Thread Christian König
Try to save whatever is on the rings when
we encounter an lockup.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/radeon.h|4 ++
 drivers/gpu/drm/radeon/radeon_device.c |   44 
 drivers/gpu/drm/radeon/radeon_ring.c   |   69 
 3 files changed, 109 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 9c11be8..1265840 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -770,6 +770,10 @@ int radeon_ring_test(struct radeon_device *rdev, struct 
radeon_ring *cp);
 void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring 
*ring);
 void radeon_ring_lockup_update(struct radeon_ring *ring);
 bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring 
*ring);
+unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring 
*ring,
+   uint32_t **data);
+int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring,
+   unsigned size, uint32_t *data);
 int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp,
 unsigned ring_size, unsigned align,
 unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg,
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index bbd0971..97696e5 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -996,7 +996,12 @@ int radeon_resume_kms(struct drm_device *dev)
 
 int radeon_gpu_reset(struct radeon_device *rdev)
 {
-   int r;
+   unsigned ring_sizes[RADEON_NUM_RINGS];
+   uint32_t *ring_data[RADEON_NUM_RINGS];
+
+   bool saved = false;
+
+   int i, r;
int resched;
 
down_write(&rdev->exclusive_lock);
@@ -1005,20 +1010,43 @@ int radeon_gpu_reset(struct radeon_device *rdev)
resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
radeon_suspend(rdev);
 
+   for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+   ring_sizes[i] = radeon_ring_backup(rdev, &rdev->ring[i],
+  &ring_data[i]);
+   if (ring_sizes[i]) {
+   saved = true;
+   dev_info(rdev->dev, "Saved %d dwords of commands "
+"on ring %d.\n", ring_sizes[i], i);
+   }
+   }
+
+retry:
r = radeon_asic_reset(rdev);
if (!r) {
-   dev_info(rdev->dev, "GPU reset succeed\n");
+   dev_info(rdev->dev, "GPU reset succeed trying to resume\n");
radeon_resume(rdev);
+   }
 
-   r = radeon_ib_ring_tests(rdev);
-   if (r)
-   DRM_ERROR("ib ring test failed (%d).\n", r);
+   radeon_restore_bios_scratch_regs(rdev);
+   drm_helper_resume_force_mode(rdev->ddev);
+
+   if (!r) {
+   for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+   radeon_ring_restore(rdev, &rdev->ring[i],
+   ring_sizes[i], ring_data[i]);
+   }
 
-   radeon_restore_bios_scratch_regs(rdev);
-   drm_helper_resume_force_mode(rdev->ddev);
-   ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
+   r = radeon_ib_ring_tests(rdev);
+   if (r) {
+   dev_err(rdev->dev, "ib ring test failed (%d).\n", r);
+   if (saved) {
+   radeon_suspend(rdev);
+   goto retry;
+   }
+   }
}
 
+   ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
if (r) {
/* bad news, how to tell it to userspace ? */
dev_info(rdev->dev, "GPU reset failed\n");
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index 994c98c..6ce51d6 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -385,6 +385,75 @@ static unsigned radeon_ring_first_valid_commit(struct 
radeon_ring *ring)
return result;
 }
 
+unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring 
*ring,
+   uint32_t **data)
+{
+   unsigned size, ptr, i;
+   int commit;
+
+   /* just in case lock the ring */
+   mutex_lock(&rdev->ring_lock);
+   *data = NULL;
+
+   if (ring->ring_obj == NULL) {
+   mutex_unlock(&rdev->ring_lock);
+   return 0;
+   }
+
+   /* first of all update the rptr directly from the hw */
+   ring->rptr = (RREG32(ring->rptr_reg) & ring->ptr_reg_mask)
+>> ring->ptr_reg_shift;
+
+   /* find the first commit not processed so far */
+   commit = radeon_ring_first_valid_commit(ri

[PATCH 15/16] drm/radeon: implement ring commit tracking

2012-07-09 Thread Christian König
Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/radeon.h  |3 +++
 drivers/gpu/drm/radeon/radeon_ring.c |   39 --
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index fef4257..9c11be8 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -637,6 +637,9 @@ struct radeon_ring {
u32 ptr_reg_shift;
u32 ptr_reg_mask;
u32 nop;
+   unsigned*track_back;
+   unsignedtrack_ptr;
+   unsignedtrack_mask;
 };
 
 /*
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index d9b2e45..994c98c 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -276,6 +276,8 @@ void radeon_ring_commit(struct radeon_device *rdev, struct 
radeon_ring *ring)
DRM_MEMORYBARRIER();
WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & 
ring->ptr_reg_mask);
(void)RREG32(ring->wptr_reg);
+   ring->track_back[ring->track_ptr++] = ring->wptr_old;
+   ring->track_ptr &= ring->track_mask;
 }
 
 void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring 
*ring)
@@ -362,6 +364,27 @@ bool radeon_ring_test_lockup(struct radeon_device *rdev, 
struct radeon_ring *rin
return false;
 }
 
+static unsigned radeon_ring_first_valid_commit(struct radeon_ring *ring)
+{
+   unsigned i, c, result = ring->track_ptr;
+   i = ring->track_ptr - 1;
+   while (i != ring->track_ptr) {
+   i &= ring->track_mask;
+   c = ring->track_back[i];
+
+   if (ring->wptr >= ring->rptr) {
+   if (c < ring->rptr || c >= ring->wptr)
+   break;
+   } else {
+   if (c < ring->rptr && c >= ring->wptr)
+   break;
+   }
+
+   result = i--;
+   }
+   return result;
+}
+
 int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring,
 unsigned ring_size, unsigned align,
 unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg,
@@ -403,6 +426,10 @@ int radeon_ring_init(struct radeon_device *rdev, struct 
radeon_ring *ring,
dev_err(rdev->dev, "(%d) ring map failed\n", r);
return r;
}
+   ring->track_back = kmalloc(ring_size / align, GFP_KERNEL);
+   memset(ring->track_back, 0, ring_size / align);
+   ring->track_ptr = 0;
+   ring->track_mask = ((ring->ring_size / 4) / align) - 1;
}
ring->ptr_mask = (ring->ring_size / 4) - 1;
ring->ring_free_dw = ring->ring_size / 4;
@@ -422,6 +449,7 @@ void radeon_ring_fini(struct radeon_device *rdev, struct 
radeon_ring *ring)
ring->ready = false;
ring->ring = NULL;
ring->ring_obj = NULL;
+   kfree(ring->track_back);
mutex_unlock(&rdev->ring_lock);
 
if (ring_obj) {
@@ -447,7 +475,7 @@ static int radeon_debugfs_ring_info(struct seq_file *m, 
void *data)
struct radeon_device *rdev = dev->dev_private;
int ridx = *(int*)node->info_ent->data;
struct radeon_ring *ring = &rdev->ring[ridx];
-   unsigned count, i, j;
+   unsigned count, i, j, commit;
 
radeon_ring_free_size(rdev, ring);
count = (ring->ring_size / 4) - ring->ring_free_dw;
@@ -457,9 +485,16 @@ static int radeon_debugfs_ring_info(struct seq_file *m, 
void *data)
seq_printf(m, "driver's copy of the rptr: 0x%08x\n", ring->rptr);
seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw);
seq_printf(m, "%u dwords in ring\n", count);
+   commit = radeon_ring_first_valid_commit(ring);
i = ring->rptr;
for (j = 0; j <= count; j++) {
-   seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]);
+   seq_printf(m, "r[%04x]=0x%08x", i, ring->ring[i]);
+   if (commit != ring->track_ptr && ring->track_back[commit] == i) 
{
+   seq_printf(m, " <-");
+   ++commit;
+   commit &= ring->track_mask;
+   }
+   seq_printf(m, "\n");
i = (i + 1) & ring->ptr_mask;
}
return 0;
-- 
1.7.9.5

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 14/16] drm/radeon: make align a ring_init parameter

2012-07-09 Thread Christian König
Instead of setting it directly from the chipset code.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/evergreen.c   |3 ++-
 drivers/gpu/drm/radeon/ni.c  |3 ++-
 drivers/gpu/drm/radeon/r100.c|3 +--
 drivers/gpu/drm/radeon/r600.c|3 +--
 drivers/gpu/drm/radeon/radeon.h  |3 ++-
 drivers/gpu/drm/radeon/radeon_ring.c |4 +++-
 drivers/gpu/drm/radeon/rv770.c   |3 ++-
 drivers/gpu/drm/radeon/si.c  |9 ++---
 8 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index f39b900..f0bbbe1 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3075,7 +3075,8 @@ static int evergreen_startup(struct radeon_device *rdev)
}
evergreen_irq_set(rdev);
 
-   r = radeon_ring_init(rdev, ring, ring->ring_size, 
RADEON_WB_CP_RPTR_OFFSET,
+   r = radeon_ring_init(rdev, ring, ring->ring_size, 16,
+RADEON_WB_CP_RPTR_OFFSET,
 R600_CP_RB_RPTR, R600_CP_RB_WPTR,
 0, 0xf, RADEON_CP_PACKET2);
if (r)
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index f2afefb..c69cebc 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1258,7 +1258,8 @@ static int cayman_startup(struct radeon_device *rdev)
}
evergreen_irq_set(rdev);
 
-   r = radeon_ring_init(rdev, ring, ring->ring_size, 
RADEON_WB_CP_RPTR_OFFSET,
+   r = radeon_ring_init(rdev, ring, ring->ring_size, 16,
+RADEON_WB_CP_RPTR_OFFSET,
 CP_RB0_RPTR, CP_RB0_WPTR,
 0, 0xf, RADEON_CP_PACKET2);
if (r)
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index e0f5ae8..116432f 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -977,7 +977,7 @@ int r100_cp_init(struct radeon_device *rdev, unsigned 
ring_size)
rb_bufsz = drm_order(ring_size / 8);
ring_size = (1 << (rb_bufsz + 1)) * 4;
r100_cp_load_microcode(rdev);
-   r = radeon_ring_init(rdev, ring, ring_size, RADEON_WB_CP_RPTR_OFFSET,
+   r = radeon_ring_init(rdev, ring, ring_size, 16, 
RADEON_WB_CP_RPTR_OFFSET,
 RADEON_CP_RB_RPTR, RADEON_CP_RB_WPTR,
 0, 0x7f, RADEON_CP_PACKET2);
if (r) {
@@ -988,7 +988,6 @@ int r100_cp_init(struct radeon_device *rdev, unsigned 
ring_size)
rb_blksz = 9;
/* cp will read 128bytes at a time (4 dwords) */
max_fetch = 1;
-   ring->align_mask = 16 - 1;
/* Write to CP_RB_WPTR will be delayed for pre_write_timer clocks */
pre_write_timer = 64;
/* Force CP_RB_WPTR write if written more than one time before the
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index c808fa9..7d15490 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2160,7 +2160,6 @@ void r600_ring_init(struct radeon_device *rdev, struct 
radeon_ring *ring, unsign
rb_bufsz = drm_order(ring_size / 8);
ring_size = (1 << (rb_bufsz + 1)) * 4;
ring->ring_size = ring_size;
-   ring->align_mask = 16 - 1;
 }
 
 void r600_cp_fini(struct radeon_device *rdev)
@@ -2376,7 +2375,7 @@ int r600_startup(struct radeon_device *rdev)
}
r600_irq_set(rdev);
 
-   r = radeon_ring_init(rdev, ring, ring->ring_size, 
RADEON_WB_CP_RPTR_OFFSET,
+   r = radeon_ring_init(rdev, ring, ring->ring_size, 16, 
RADEON_WB_CP_RPTR_OFFSET,
 R600_CP_RB_RPTR, R600_CP_RB_WPTR,
 0, 0xf, RADEON_CP_PACKET2);
 
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 872270c..fef4257 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -767,7 +767,8 @@ int radeon_ring_test(struct radeon_device *rdev, struct 
radeon_ring *cp);
 void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring 
*ring);
 void radeon_ring_lockup_update(struct radeon_ring *ring);
 bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring 
*ring);
-int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, 
unsigned ring_size,
+int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp,
+unsigned ring_size, unsigned align,
 unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg,
 u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop);
 void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *cp);
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index 0873834..d9b2e45 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon

[PATCH 12/16] drm/radeon: remove vm_manager start/suspend

2012-07-09 Thread Christian König
Just restore the page table instead. Addressing three
problem with this change:

1. Calling vm_manager_suspend in the suspend path is
   problematic cause it wants to wait for the VM use
   to end, which in case of a lockup never happens.

2. In case of a locked up memory controller
   unbinding the VM seems to make it even more
   unstable, creating an unrecoverable lockup
   in the end.

3. If we want to backup/restore the leftover ring
   content we must not unbind VMs in between.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/ni.c  |   12 ++---
 drivers/gpu/drm/radeon/radeon.h  |2 -
 drivers/gpu/drm/radeon/radeon_gart.c |   83 +-
 drivers/gpu/drm/radeon/si.c  |   12 ++---
 4 files changed, 59 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 4004376..ec5307c 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1280,9 +1280,11 @@ static int cayman_startup(struct radeon_device *rdev)
if (r)
return r;
 
-   r = radeon_vm_manager_start(rdev);
-   if (r)
+   r = radeon_vm_manager_init(rdev);
+   if (r) {
+   dev_err(rdev->dev, "vm manager initialization failed (%d).\n", 
r);
return r;
+   }
 
r = r600_audio_init(rdev);
if (r)
@@ -1315,7 +1317,6 @@ int cayman_resume(struct radeon_device *rdev)
 int cayman_suspend(struct radeon_device *rdev)
 {
r600_audio_fini(rdev);
-   radeon_vm_manager_suspend(rdev);
cayman_cp_enable(rdev, false);
rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
evergreen_irq_suspend(rdev);
@@ -1392,11 +1393,6 @@ int cayman_init(struct radeon_device *rdev)
return r;
 
rdev->accel_working = true;
-   r = radeon_vm_manager_init(rdev);
-   if (r) {
-   dev_err(rdev->dev, "vm manager initialization failed (%d).\n", 
r);
-   }
-
r = cayman_startup(rdev);
if (r) {
dev_err(rdev->dev, "disabling GPU acceleration\n");
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 8a8c3f8..872270c 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1759,8 +1759,6 @@ extern void radeon_ttm_set_active_vram_size(struct 
radeon_device *rdev, u64 size
  */
 int radeon_vm_manager_init(struct radeon_device *rdev);
 void radeon_vm_manager_fini(struct radeon_device *rdev);
-int radeon_vm_manager_start(struct radeon_device *rdev);
-int radeon_vm_manager_suspend(struct radeon_device *rdev);
 int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm);
 void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm);
 int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm);
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index ee11c50..56752da 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -282,27 +282,58 @@ void radeon_gart_fini(struct radeon_device *rdev)
  *
  * TODO bind a default page at vm initialization for default address
  */
+
 int radeon_vm_manager_init(struct radeon_device *rdev)
 {
+   struct radeon_vm *vm;
+   struct radeon_bo_va *bo_va;
int r;
 
-   rdev->vm_manager.enabled = false;
+   if (!rdev->vm_manager.enabled) {
+   /* mark first vm as always in use, it's the system one */
+   r = radeon_sa_bo_manager_init(rdev, 
&rdev->vm_manager.sa_manager,
+ rdev->vm_manager.max_pfn * 8,
+ RADEON_GEM_DOMAIN_VRAM);
+   if (r) {
+   dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n",
+   (rdev->vm_manager.max_pfn * 8) >> 10);
+   return r;
+   }
 
-   /* mark first vm as always in use, it's the system one */
-   r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager,
- rdev->vm_manager.max_pfn * 8,
- RADEON_GEM_DOMAIN_VRAM);
-   if (r) {
-   dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n",
-   (rdev->vm_manager.max_pfn * 8) >> 10);
-   return r;
+   r = rdev->vm_manager.funcs->init(rdev);
+   if (r)
+   return r;
+   
+   rdev->vm_manager.enabled = true;
+
+   r = radeon_sa_bo_manager_start(rdev, 
&rdev->vm_manager.sa_manager);
+   if (r)
+   return r;
}
 
-   r = rdev->vm_manager.funcs->init(rdev);
-   if (r == 0)
-   rdev->vm_manager.enabled = true;
+   /* restore page table */
+   list_for_each_entry(vm, &rdev->vm_manager.lru_vm, list) {
+   if (vm->id =

[PATCH 13/16] drm/radeon: move radeon_ib_ring_tests out of chipset code

2012-07-09 Thread Christian König
Making it easier to controlwhen it is executed.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/evergreen.c |4 
 drivers/gpu/drm/radeon/ni.c|4 
 drivers/gpu/drm/radeon/r100.c  |4 
 drivers/gpu/drm/radeon/r300.c  |4 
 drivers/gpu/drm/radeon/r420.c  |4 
 drivers/gpu/drm/radeon/r520.c  |4 
 drivers/gpu/drm/radeon/r600.c  |4 
 drivers/gpu/drm/radeon/radeon_device.c |   15 +++
 drivers/gpu/drm/radeon/rs400.c |4 
 drivers/gpu/drm/radeon/rs600.c |4 
 drivers/gpu/drm/radeon/rs690.c |4 
 drivers/gpu/drm/radeon/rv515.c |4 
 drivers/gpu/drm/radeon/rv770.c |4 
 drivers/gpu/drm/radeon/si.c|   21 -
 14 files changed, 15 insertions(+), 69 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index 82f7aea..f39b900 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3093,10 +3093,6 @@ static int evergreen_startup(struct radeon_device *rdev)
return r;
}
 
-   r = radeon_ib_ring_tests(rdev);
-   if (r)
-   return r;
-
r = r600_audio_init(rdev);
if (r) {
DRM_ERROR("radeon: audio init failed\n");
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index ec5307c..f2afefb 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1276,10 +1276,6 @@ static int cayman_startup(struct radeon_device *rdev)
return r;
}
 
-   r = radeon_ib_ring_tests(rdev);
-   if (r)
-   return r;
-
r = radeon_vm_manager_init(rdev);
if (r) {
dev_err(rdev->dev, "vm manager initialization failed (%d).\n", 
r);
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 9524bd4..e0f5ae8 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -3887,10 +3887,6 @@ static int r100_startup(struct radeon_device *rdev)
return r;
}
 
-   r = radeon_ib_ring_tests(rdev);
-   if (r)
-   return r;
-
return 0;
 }
 
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index b396e34..646a192 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -1397,10 +1397,6 @@ static int r300_startup(struct radeon_device *rdev)
return r;
}
 
-   r = radeon_ib_ring_tests(rdev);
-   if (r)
-   return r;
-
return 0;
 }
 
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c
index 0062938..f2f5bf6 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -281,10 +281,6 @@ static int r420_startup(struct radeon_device *rdev)
return r;
}
 
-   r = radeon_ib_ring_tests(rdev);
-   if (r)
-   return r;
-
return 0;
 }
 
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c
index 6df3e51..079d3c5 100644
--- a/drivers/gpu/drm/radeon/r520.c
+++ b/drivers/gpu/drm/radeon/r520.c
@@ -209,10 +209,6 @@ static int r520_startup(struct radeon_device *rdev)
return r;
}
 
-   r = radeon_ib_ring_tests(rdev);
-   if (r)
-   return r;
-
return 0;
 }
 
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index af2f74a..c808fa9 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2395,10 +2395,6 @@ int r600_startup(struct radeon_device *rdev)
return r;
}
 
-   r = radeon_ib_ring_tests(rdev);
-   if (r)
-   return r;
-
r = r600_audio_init(rdev);
if (r) {
DRM_ERROR("radeon: audio init failed\n");
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 254fdb4..bbd0971 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -822,6 +822,10 @@ int radeon_device_init(struct radeon_device *rdev,
if (r)
return r;
 
+   r = radeon_ib_ring_tests(rdev);
+   if (r)
+   DRM_ERROR("ib ring test failed (%d).\n", r);
+
if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) {
/* Acceleration not working on AGP card try again
 * with fallback to PCI or PCIE GART
@@ -946,6 +950,7 @@ int radeon_resume_kms(struct drm_device *dev)
 {
struct drm_connector *connector;
struct radeon_device *rdev = dev->dev_private;
+   int r;
 
if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
return 0;
@@ -960,6 +965,11 @@ int radeon_resume_kms(struct drm_device *dev)
/* resume AGP if in use */
radeon_agp_resume

[PATCH 04/16] drm/radeon: add an exclusive lock for GPU reset v2

2012-07-09 Thread Christian König
From: Jerome Glisse 

GPU reset need to be exclusive, one happening at a time. For this
add a rw semaphore so that any path that trigger GPU activities
have to take the semaphore as a reader thus allowing concurency.

The GPU reset path take the semaphore as a writer ensuring that
no concurrent reset take place.

v2: init rw semaphore

Signed-off-by: Jerome Glisse 
---
 drivers/gpu/drm/radeon/radeon.h|1 +
 drivers/gpu/drm/radeon/radeon_cs.c |5 +
 drivers/gpu/drm/radeon/radeon_device.c |3 +++
 drivers/gpu/drm/radeon/radeon_gem.c|8 
 4 files changed, 17 insertions(+)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 5861ec8..4487873 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1446,6 +1446,7 @@ struct radeon_device {
struct device   *dev;
struct drm_device   *ddev;
struct pci_dev  *pdev;
+   struct rw_semaphore exclusive_lock;
/* ASIC */
union radeon_asic_configconfig;
enum radeon_family  family;
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
b/drivers/gpu/drm/radeon/radeon_cs.c
index d5aec09..553da67 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -499,7 +499,9 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
struct radeon_cs_parser parser;
int r;
 
+   down_read(&rdev->exclusive_lock);
if (!rdev->accel_working) {
+   up_read(&rdev->exclusive_lock);
return -EBUSY;
}
/* initialize parser */
@@ -512,6 +514,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
if (r) {
DRM_ERROR("Failed to initialize parser !\n");
radeon_cs_parser_fini(&parser, r);
+   up_read(&rdev->exclusive_lock);
r = radeon_cs_handle_lockup(rdev, r);
return r;
}
@@ -520,6 +523,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
if (r != -ERESTARTSYS)
DRM_ERROR("Failed to parse relocation %d!\n", r);
radeon_cs_parser_fini(&parser, r);
+   up_read(&rdev->exclusive_lock);
r = radeon_cs_handle_lockup(rdev, r);
return r;
}
@@ -533,6 +537,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
}
 out:
radeon_cs_parser_fini(&parser, r);
+   up_read(&rdev->exclusive_lock);
r = radeon_cs_handle_lockup(rdev, r);
return r;
 }
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index f654ba8..254fdb4 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -734,6 +734,7 @@ int radeon_device_init(struct radeon_device *rdev,
mutex_init(&rdev->gem.mutex);
mutex_init(&rdev->pm.mutex);
init_rwsem(&rdev->pm.mclk_lock);
+   init_rwsem(&rdev->exclusive_lock);
init_waitqueue_head(&rdev->irq.vblank_queue);
init_waitqueue_head(&rdev->irq.idle_queue);
r = radeon_gem_init(rdev);
@@ -988,6 +989,7 @@ int radeon_gpu_reset(struct radeon_device *rdev)
int r;
int resched;
 
+   down_write(&rdev->exclusive_lock);
radeon_save_bios_scratch_regs(rdev);
/* block TTM */
resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
@@ -1007,6 +1009,7 @@ int radeon_gpu_reset(struct radeon_device *rdev)
dev_info(rdev->dev, "GPU reset failed\n");
}
 
+   up_write(&rdev->exclusive_lock);
return r;
 }
 
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c 
b/drivers/gpu/drm/radeon/radeon_gem.c
index d9b0809..b0be9c4 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -215,12 +215,14 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void 
*data,
uint32_t handle;
int r;
 
+   down_read(&rdev->exclusive_lock);
/* create a gem object to contain this object in */
args->size = roundup(args->size, PAGE_SIZE);
r = radeon_gem_object_create(rdev, args->size, args->alignment,
args->initial_domain, false,
false, &gobj);
if (r) {
+   up_read(&rdev->exclusive_lock);
r = radeon_gem_handle_lockup(rdev, r);
return r;
}
@@ -228,10 +230,12 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void 
*data,
/* drop reference from allocate - handle holds it now */
drm_gem_object_unreference_unlocked(gobj);
if (r) {
+   up_read(&rdev->exclusive_lock);
r = radeon_gem_handle_lockup(rdev, r);
 

[PATCH 11/16] drm/radeon: remove r600_blit_suspend

2012-07-09 Thread Christian König
Just reinitialize the shader content on resume instead.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/evergreen.c  |1 -
 drivers/gpu/drm/radeon/evergreen_blit_kms.c |   40 +--
 drivers/gpu/drm/radeon/ni.c |1 -
 drivers/gpu/drm/radeon/r600.c   |   15 --
 drivers/gpu/drm/radeon/r600_blit_kms.c  |   40 +--
 drivers/gpu/drm/radeon/radeon.h |2 --
 drivers/gpu/drm/radeon/rv770.c  |1 -
 drivers/gpu/drm/radeon/si.c |3 --
 8 files changed, 40 insertions(+), 63 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index 64e06e6..82f7aea 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3139,7 +3139,6 @@ int evergreen_suspend(struct radeon_device *rdev)
struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
 
r600_audio_fini(rdev);
-   r600_blit_suspend(rdev);
r700_cp_stop(rdev);
ring->ready = false;
evergreen_irq_suspend(rdev);
diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c 
b/drivers/gpu/drm/radeon/evergreen_blit_kms.c
index e512560..89cb9fe 100644
--- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c
+++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c
@@ -634,10 +634,6 @@ int evergreen_blit_init(struct radeon_device *rdev)
 
rdev->r600_blit.max_dim = 16384;
 
-   /* pin copy shader into vram if already initialized */
-   if (rdev->r600_blit.shader_obj)
-   goto done;
-
rdev->r600_blit.state_offset = 0;
 
if (rdev->family < CHIP_CAYMAN)
@@ -668,11 +664,26 @@ int evergreen_blit_init(struct radeon_device *rdev)
obj_size += cayman_ps_size * 4;
obj_size = ALIGN(obj_size, 256);
 
-   r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true, 
RADEON_GEM_DOMAIN_VRAM,
-NULL, &rdev->r600_blit.shader_obj);
-   if (r) {
-   DRM_ERROR("evergreen failed to allocate shader\n");
-   return r;
+   /* pin copy shader into vram if not already initialized */
+   if (!rdev->r600_blit.shader_obj) {
+   r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true,
+RADEON_GEM_DOMAIN_VRAM,
+NULL, &rdev->r600_blit.shader_obj);
+   if (r) {
+   DRM_ERROR("evergreen failed to allocate shader\n");
+   return r;
+   }
+
+   r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
+   if (unlikely(r != 0))
+   return r;
+   r = radeon_bo_pin(rdev->r600_blit.shader_obj, 
RADEON_GEM_DOMAIN_VRAM,
+ &rdev->r600_blit.shader_gpu_addr);
+   radeon_bo_unreserve(rdev->r600_blit.shader_obj);
+   if (r) {
+   dev_err(rdev->dev, "(%d) pin blit object failed\n", r);
+   return r;
+   }
}
 
DRM_DEBUG("evergreen blit allocated bo %08x vs %08x ps %08x\n",
@@ -714,17 +725,6 @@ int evergreen_blit_init(struct radeon_device *rdev)
radeon_bo_kunmap(rdev->r600_blit.shader_obj);
radeon_bo_unreserve(rdev->r600_blit.shader_obj);
 
-done:
-   r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
-   if (unlikely(r != 0))
-   return r;
-   r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
- &rdev->r600_blit.shader_gpu_addr);
-   radeon_bo_unreserve(rdev->r600_blit.shader_obj);
-   if (r) {
-   dev_err(rdev->dev, "(%d) pin blit object failed\n", r);
-   return r;
-   }
radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
return 0;
 }
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index fe55310..4004376 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1316,7 +1316,6 @@ int cayman_suspend(struct radeon_device *rdev)
 {
r600_audio_fini(rdev);
radeon_vm_manager_suspend(rdev);
-   r600_blit_suspend(rdev);
cayman_cp_enable(rdev, false);
rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
evergreen_irq_suspend(rdev);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 9750f53..af2f74a 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2307,20 +2307,6 @@ int r600_copy_blit(struct radeon_device *rdev,
return 0;
 }
 
-void r600_blit_suspend(struct radeon_device *rdev)
-{
-   int r;
-
-   /* unpin shaders bo */
-   if (rdev->r600_blit.shader_obj) {
-   r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
-   if (!r) {
-   radeon_bo_unpin(rdev->r600_

[PATCH 10/16] drm/radeon: remove ip_pool start/suspend

2012-07-09 Thread Christian König
The IB pool is in gart memory, so it is completely
superfluous to unpin / repin it on suspend / resume.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/evergreen.c   |   17 ++---
 drivers/gpu/drm/radeon/ni.c  |   16 ++--
 drivers/gpu/drm/radeon/r100.c|   23 ++-
 drivers/gpu/drm/radeon/r300.c|   17 ++---
 drivers/gpu/drm/radeon/r420.c|   17 ++---
 drivers/gpu/drm/radeon/r520.c|   14 +-
 drivers/gpu/drm/radeon/r600.c|   17 ++---
 drivers/gpu/drm/radeon/radeon.h  |2 --
 drivers/gpu/drm/radeon/radeon_asic.h |1 -
 drivers/gpu/drm/radeon/radeon_ring.c |   17 +++--
 drivers/gpu/drm/radeon/rs400.c   |   17 ++---
 drivers/gpu/drm/radeon/rs600.c   |   17 ++---
 drivers/gpu/drm/radeon/rs690.c   |   17 ++---
 drivers/gpu/drm/radeon/rv515.c   |   16 ++--
 drivers/gpu/drm/radeon/rv770.c   |   17 ++---
 drivers/gpu/drm/radeon/si.c  |   16 ++--
 16 files changed, 84 insertions(+), 157 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index eb9a71a..64e06e6 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3087,9 +3087,11 @@ static int evergreen_startup(struct radeon_device *rdev)
if (r)
return r;
 
-   r = radeon_ib_pool_start(rdev);
-   if (r)
+   r = radeon_ib_pool_init(rdev);
+   if (r) {
+   dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
return r;
+   }
 
r = radeon_ib_ring_tests(rdev);
if (r)
@@ -3137,7 +3139,6 @@ int evergreen_suspend(struct radeon_device *rdev)
struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
 
r600_audio_fini(rdev);
-   radeon_ib_pool_suspend(rdev);
r600_blit_suspend(rdev);
r700_cp_stop(rdev);
ring->ready = false;
@@ -3224,20 +3225,14 @@ int evergreen_init(struct radeon_device *rdev)
if (r)
return r;
 
-   r = radeon_ib_pool_init(rdev);
rdev->accel_working = true;
-   if (r) {
-   dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
-   rdev->accel_working = false;
-   }
-
r = evergreen_startup(rdev);
if (r) {
dev_err(rdev->dev, "disabling GPU acceleration\n");
r700_cp_fini(rdev);
r600_irq_fini(rdev);
radeon_wb_fini(rdev);
-   r100_ib_fini(rdev);
+   radeon_ib_pool_fini(rdev);
radeon_irq_kms_fini(rdev);
evergreen_pcie_gart_fini(rdev);
rdev->accel_working = false;
@@ -3264,7 +3259,7 @@ void evergreen_fini(struct radeon_device *rdev)
r700_cp_fini(rdev);
r600_irq_fini(rdev);
radeon_wb_fini(rdev);
-   r100_ib_fini(rdev);
+   radeon_ib_pool_fini(rdev);
radeon_irq_kms_fini(rdev);
evergreen_pcie_gart_fini(rdev);
r600_vram_scratch_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 8b1df33..fe55310 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1270,9 +1270,11 @@ static int cayman_startup(struct radeon_device *rdev)
if (r)
return r;
 
-   r = radeon_ib_pool_start(rdev);
-   if (r)
+   r = radeon_ib_pool_init(rdev);
+   if (r) {
+   dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
return r;
+   }
 
r = radeon_ib_ring_tests(rdev);
if (r)
@@ -1313,7 +1315,6 @@ int cayman_resume(struct radeon_device *rdev)
 int cayman_suspend(struct radeon_device *rdev)
 {
r600_audio_fini(rdev);
-   radeon_ib_pool_suspend(rdev);
radeon_vm_manager_suspend(rdev);
r600_blit_suspend(rdev);
cayman_cp_enable(rdev, false);
@@ -1391,12 +1392,7 @@ int cayman_init(struct radeon_device *rdev)
if (r)
return r;
 
-   r = radeon_ib_pool_init(rdev);
rdev->accel_working = true;
-   if (r) {
-   dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
-   rdev->accel_working = false;
-   }
r = radeon_vm_manager_init(rdev);
if (r) {
dev_err(rdev->dev, "vm manager initialization failed (%d).\n", 
r);
@@ -1410,7 +1406,7 @@ int cayman_init(struct radeon_device *rdev)
if (rdev->flags & RADEON_IS_IGP)
si_rlc_fini(rdev);
radeon_wb_fini(rdev);
-   r100_ib_fini(rdev);
+   radeon_ib_pool_fini(rdev);
radeon_vm_manager_fini(rdev);
radeon_irq_kms_fini(rdev);
cayman_pcie_gart_fini(rdev);
@@ -1441,7 +1437,7 @@ void cayman_fini(struct

[PATCH 08/16] drm/radeon: remove FIXME comment from chipset suspend

2012-07-09 Thread Christian König
For a normal suspend/resume we allready wait for
the rings to be empty, and for a suspend/reasume
in case of a lockup we REALLY don't want to wait
for anything.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/evergreen.c |1 -
 drivers/gpu/drm/radeon/ni.c|1 -
 drivers/gpu/drm/radeon/r600.c  |1 -
 drivers/gpu/drm/radeon/rv770.c |1 -
 drivers/gpu/drm/radeon/si.c|1 -
 5 files changed, 5 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index f716e08..eb9a71a 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3137,7 +3137,6 @@ int evergreen_suspend(struct radeon_device *rdev)
struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
 
r600_audio_fini(rdev);
-   /* FIXME: we should wait for ring to be empty */
radeon_ib_pool_suspend(rdev);
r600_blit_suspend(rdev);
r700_cp_stop(rdev);
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 2366be3..32a6082 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1334,7 +1334,6 @@ int cayman_resume(struct radeon_device *rdev)
 int cayman_suspend(struct radeon_device *rdev)
 {
r600_audio_fini(rdev);
-   /* FIXME: we should wait for ring to be empty */
radeon_ib_pool_suspend(rdev);
radeon_vm_manager_suspend(rdev);
r600_blit_suspend(rdev);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 43d0c41..de4de2d 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2461,7 +2461,6 @@ int r600_suspend(struct radeon_device *rdev)
r600_audio_fini(rdev);
radeon_ib_pool_suspend(rdev);
r600_blit_suspend(rdev);
-   /* FIXME: we should wait for ring to be empty */
r600_cp_stop(rdev);
rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
r600_irq_suspend(rdev);
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index b4f51c5..7e230f6 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -996,7 +996,6 @@ int rv770_suspend(struct radeon_device *rdev)
r600_audio_fini(rdev);
radeon_ib_pool_suspend(rdev);
r600_blit_suspend(rdev);
-   /* FIXME: we should wait for ring to be empty */
r700_cp_stop(rdev);
rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
r600_irq_suspend(rdev);
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 34603b3c8..78c790f 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -3807,7 +3807,6 @@ int si_resume(struct radeon_device *rdev)
 
 int si_suspend(struct radeon_device *rdev)
 {
-   /* FIXME: we should wait for ring to be empty */
radeon_ib_pool_suspend(rdev);
radeon_vm_manager_suspend(rdev);
 #if 0
-- 
1.7.9.5

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 09/16] drm/radeon: make cp init on cayman more robust

2012-07-09 Thread Christian König
It's not critical, but the current code isn't
100% correct.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/ni.c |  133 ++-
 1 file changed, 56 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 32a6082..8b1df33 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -987,10 +987,33 @@ static void cayman_cp_fini(struct radeon_device *rdev)
 
 int cayman_cp_resume(struct radeon_device *rdev)
 {
+   static const int ridx[] = {
+   RADEON_RING_TYPE_GFX_INDEX,
+   CAYMAN_RING_TYPE_CP1_INDEX,
+   CAYMAN_RING_TYPE_CP2_INDEX
+   };
+   static const unsigned cp_rb_cntl[] = {
+   CP_RB0_CNTL,
+   CP_RB1_CNTL,
+   CP_RB2_CNTL,
+   };
+   static const unsigned cp_rb_rptr_addr[] = {
+   CP_RB0_RPTR_ADDR,
+   CP_RB1_RPTR_ADDR,
+   CP_RB2_RPTR_ADDR
+   };
+   static const unsigned cp_rb_rptr_addr_hi[] = {
+   CP_RB0_RPTR_ADDR_HI,
+   CP_RB1_RPTR_ADDR_HI,
+   CP_RB2_RPTR_ADDR_HI
+   };
+   static const unsigned cp_rb_base[] = {
+   CP_RB0_BASE,
+   CP_RB1_BASE,
+   CP_RB2_BASE
+   };
struct radeon_ring *ring;
-   u32 tmp;
-   u32 rb_bufsz;
-   int r;
+   int i, r;
 
/* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */
WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP |
@@ -1012,91 +1035,47 @@ int cayman_cp_resume(struct radeon_device *rdev)
 
WREG32(CP_DEBUG, (1 << 27));
 
-   /* ring 0 - compute and gfx */
-   /* Set ring buffer size */
-   ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
-   rb_bufsz = drm_order(ring->ring_size / 8);
-   tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
-#ifdef __BIG_ENDIAN
-   tmp |= BUF_SWAP_32BIT;
-#endif
-   WREG32(CP_RB0_CNTL, tmp);
-
-   /* Initialize the ring buffer's read and write pointers */
-   WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA);
-   ring->wptr = 0;
-   WREG32(CP_RB0_WPTR, ring->wptr);
-
/* set the wb address wether it's enabled or not */
-   WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) 
& 0xFFFC);
-   WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + 
RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 
8) & 0x);
+   WREG32(SCRATCH_UMSK, 0xff);
 
-   if (rdev->wb.enabled)
-   WREG32(SCRATCH_UMSK, 0xff);
-   else {
-   tmp |= RB_NO_UPDATE;
-   WREG32(SCRATCH_UMSK, 0);
-   }
-
-   mdelay(1);
-   WREG32(CP_RB0_CNTL, tmp);
-
-   WREG32(CP_RB0_BASE, ring->gpu_addr >> 8);
-
-   ring->rptr = RREG32(CP_RB0_RPTR);
+   for (i = 0; i < 3; ++i) {
+   uint32_t rb_cntl;
+   uint64_t addr;
 
-   /* ring1  - compute only */
-   /* Set ring buffer size */
-   ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
-   rb_bufsz = drm_order(ring->ring_size / 8);
-   tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
+   /* Set ring buffer size */
+   ring = &rdev->ring[ridx[i]];
+   rb_cntl = drm_order(ring->ring_size / 8);
+   rb_cntl |= drm_order(RADEON_GPU_PAGE_SIZE/8) << 8;
 #ifdef __BIG_ENDIAN
-   tmp |= BUF_SWAP_32BIT;
+   rb_cntl |= BUF_SWAP_32BIT;
 #endif
-   WREG32(CP_RB1_CNTL, tmp);
+   WREG32(cp_rb_cntl[i], rb_cntl);
 
-   /* Initialize the ring buffer's read and write pointers */
-   WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA);
-   ring->wptr = 0;
-   WREG32(CP_RB1_WPTR, ring->wptr);
-
-   /* set the wb address wether it's enabled or not */
-   WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + 
RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFC);
-   WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + 
RADEON_WB_CP1_RPTR_OFFSET) & 0xFF);
-
-   mdelay(1);
-   WREG32(CP_RB1_CNTL, tmp);
-
-   WREG32(CP_RB1_BASE, ring->gpu_addr >> 8);
-
-   ring->rptr = RREG32(CP_RB1_RPTR);
-
-   /* ring2 - compute only */
-   /* Set ring buffer size */
-   ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
-   rb_bufsz = drm_order(ring->ring_size / 8);
-   tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
-#ifdef __BIG_ENDIAN
-   tmp |= BUF_SWAP_32BIT;
-#endif
-   WREG32(CP_RB2_CNTL, tmp);
-
-   /* Initialize the ring buffer's read and write pointers */
-   WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA);
-   ring->wptr = 0;
-   WREG32(CP_RB2_WPTR, ring->wptr);
+   /* set the wb address wether it's enabled or not */
+   addr = rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET;
+   WREG32(cp_rb_rptr_addr[i], addr 

[PATCH 07/16] drm/radeon: fix fence init after resume

2012-07-09 Thread Christian König
Start with last signaled fence number instead
of last emitted one.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/radeon_fence.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index a194a14..76c5b22 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -578,7 +578,7 @@ int radeon_fence_driver_start_ring(struct radeon_device 
*rdev, int ring)
}
rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4];
rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr + index;
-   radeon_fence_write(rdev, rdev->fence_drv[ring].sync_seq[ring], ring);
+   radeon_fence_write(rdev, 
atomic64_read(&rdev->fence_drv[ring].last_seq), ring);
rdev->fence_drv[ring].initialized = true;
dev_info(rdev->dev, "fence driver on ring %d use gpu addr 0x%016llx and 
cpu addr 0x%p\n",
 ring, rdev->fence_drv[ring].gpu_addr, 
rdev->fence_drv[ring].cpu_addr);
-- 
1.7.9.5

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 06/16] drm/radeon: fix fence value access

2012-07-09 Thread Christian König
It is possible that radeon_fence_process is called
after writeback is disabled for suspend, leading
to an invalid read of register 0x0.

This fixes a problem for me where the fence value
is temporary incremented by 0x1 on
suspend/resume.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/radeon_fence.c |   14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index be4e4f3..a194a14 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -42,21 +42,23 @@
 
 static void radeon_fence_write(struct radeon_device *rdev, u32 seq, int ring)
 {
-   if (rdev->wb.enabled) {
-   *rdev->fence_drv[ring].cpu_addr = cpu_to_le32(seq);
+   struct radeon_fence_driver *drv = &rdev->fence_drv[ring];
+   if (likely(rdev->wb.enabled || !drv->scratch_reg)) {
+   *drv->cpu_addr = cpu_to_le32(seq);
} else {
-   WREG32(rdev->fence_drv[ring].scratch_reg, seq);
+   WREG32(drv->scratch_reg, seq);
}
 }
 
 static u32 radeon_fence_read(struct radeon_device *rdev, int ring)
 {
+   struct radeon_fence_driver *drv = &rdev->fence_drv[ring];
u32 seq = 0;
 
-   if (rdev->wb.enabled) {
-   seq = le32_to_cpu(*rdev->fence_drv[ring].cpu_addr);
+   if (likely(rdev->wb.enabled || !drv->scratch_reg)) {
+   seq = le32_to_cpu(*drv->cpu_addr);
} else {
-   seq = RREG32(rdev->fence_drv[ring].scratch_reg);
+   seq = RREG32(drv->scratch_reg);
}
return seq;
 }
-- 
1.7.9.5

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 05/16] drm/radeon: fix ring commit padding

2012-07-09 Thread Christian König
We don't need to pad anything if the number of dwords
written to the ring already matches the requirements.

Fixes some "writting more dword to ring than expected"
warnings.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/radeon_ring.c |7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index 0826e77..674aaba 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -272,13 +272,8 @@ int radeon_ring_lock(struct radeon_device *rdev, struct 
radeon_ring *ring, unsig
 
 void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring)
 {
-   unsigned count_dw_pad;
-   unsigned i;
-
/* We pad to match fetch size */
-   count_dw_pad = (ring->align_mask + 1) -
-  (ring->wptr & ring->align_mask);
-   for (i = 0; i < count_dw_pad; i++) {
+   while (ring->wptr & ring->align_mask) {
radeon_ring_write(ring, ring->nop);
}
DRM_MEMORYBARRIER();
-- 
1.7.9.5

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 01/16] drm/radeon: add error handling to fence_wait_empty_locked

2012-07-09 Thread Christian König
Instead of returning the error handle it directly
and while at it fix the comments about the ring lock.

Signed-off-by: Christian König 
Reviewed-by: Michel Dänzer 
---
 drivers/gpu/drm/radeon/radeon.h   |2 +-
 drivers/gpu/drm/radeon/radeon_fence.c |   33 +
 2 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 77b4519b..5861ec8 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -239,7 +239,7 @@ void radeon_fence_process(struct radeon_device *rdev, int 
ring);
 bool radeon_fence_signaled(struct radeon_fence *fence);
 int radeon_fence_wait(struct radeon_fence *fence, bool interruptible);
 int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring);
-int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring);
+void radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring);
 int radeon_fence_wait_any(struct radeon_device *rdev,
  struct radeon_fence **fences,
  bool intr);
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 7b55625..be4e4f3 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -440,14 +440,11 @@ int radeon_fence_wait_any(struct radeon_device *rdev,
return 0;
 }
 
+/* caller must hold ring lock */
 int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring)
 {
uint64_t seq;
 
-   /* We are not protected by ring lock when reading current seq but
-* it's ok as worst case is we return to early while we could have
-* wait.
-*/
seq = atomic64_read(&rdev->fence_drv[ring].last_seq) + 1ULL;
if (seq >= rdev->fence_drv[ring].sync_seq[ring]) {
/* nothing to wait for, last_seq is
@@ -457,15 +454,27 @@ int radeon_fence_wait_next_locked(struct radeon_device 
*rdev, int ring)
return radeon_fence_wait_seq(rdev, seq, ring, false, false);
 }
 
-int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring)
+/* caller must hold ring lock */
+void radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring)
 {
-   /* We are not protected by ring lock when reading current seq
-* but it's ok as wait empty is call from place where no more
-* activity can be scheduled so there won't be concurrent access
-* to seq value.
-*/
-   return radeon_fence_wait_seq(rdev, rdev->fence_drv[ring].sync_seq[ring],
-ring, false, false);
+   uint64_t seq = rdev->fence_drv[ring].sync_seq[ring];
+
+   while(1) {
+   int r;
+   r = radeon_fence_wait_seq(rdev, seq, ring, false, false);
+   if (r == -EDEADLK) {
+   mutex_unlock(&rdev->ring_lock);
+   r = radeon_gpu_reset(rdev);
+   mutex_lock(&rdev->ring_lock);
+   if (!r)
+   continue;
+   }
+   if (r) {
+   dev_err(rdev->dev, "error waiting for ring to become"
+   " idle (%d)\n", r);
+   }
+   return;
+   }
 }
 
 struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence)
-- 
1.7.9.5

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 03/16] drm/radeon: fix fence related segfault in CS

2012-07-09 Thread Christian König
Don't return success if scheduling the IB fails, otherwise
we end up with an oops in ttm_eu_fence_buffer_objects.

Signed-off-by: Christian König 
Cc: sta...@vger.kernel.org
---
 drivers/gpu/drm/radeon/radeon_cs.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
b/drivers/gpu/drm/radeon/radeon_cs.c
index f1b7527..d5aec09 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -358,7 +358,7 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev,
if (r) {
DRM_ERROR("Failed to schedule IB !\n");
}
-   return 0;
+   return r;
 }
 
 static int radeon_bo_vm_update_pte(struct radeon_cs_parser *parser,
-- 
1.7.9.5

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[RFC] drm/radeon: restoring ring commands in case of a lockup

2012-07-09 Thread Christian König
Hi,

The following patchset tries to save and restore the not yet processed commands
from the rings in case of a lockup and with that should make a userspace
problem with a single application far less problematic.

The first four patches are just stuff this patchset is based upon, followed by
four patches which fix various bugs found while working on this feature.

Followed by patches which change the way how memory is saved/restored on
suspend/resume, basically before we have unpinned most of the buffer objects so
it could be move from vram into system memory. But that is mostly unnecessary
cause the buffer object either are already in system memory or their content
can be easily reinitialized.

The last three patches implement the actual tracking and restoring of commands
in case of a lockup. Please take a look and review.

Cheers,
Christian.

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 02/16] drm/radeon: add error handling to radeon_vm_unbind_locked

2012-07-09 Thread Christian König
Waiting for a fence can fail for different reasons,
the most common is a deadlock.

Signed-off-by: Christian König 
Reviewed-by: Michel Dänzer 
---
 drivers/gpu/drm/radeon/radeon_gart.c |   17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index 2b34c1a..ee11c50 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -316,10 +316,21 @@ static void radeon_vm_unbind_locked(struct radeon_device 
*rdev,
}
 
/* wait for vm use to end */
-   if (vm->fence) {
-   radeon_fence_wait(vm->fence, false);
-   radeon_fence_unref(&vm->fence);
+   while (vm->fence) {
+   int r;
+   r = radeon_fence_wait(vm->fence, false);
+   if (r)
+   DRM_ERROR("error while waiting for fence: %d\n", r);
+   if (r == -EDEADLK) {
+   mutex_unlock(&rdev->vm_manager.lock);
+   r = radeon_gpu_reset(rdev);
+   mutex_lock(&rdev->vm_manager.lock);
+   if (!r)
+   continue;
+   }
+   break;
}
+   radeon_fence_unref(&vm->fence);
 
/* hw unbind */
rdev->vm_manager.funcs->unbind(rdev, vm);
-- 
1.7.9.5

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH, RFC] i.MX DRM support

2012-07-09 Thread Sascha Hauer
On Sun, Jul 08, 2012 at 08:35:55AM +0100, Dave Airlie wrote:
> On Fri, Jul 6, 2012 at 11:58 PM, Greg Kroah-Hartman
>  wrote:
> > On Mon, Jul 02, 2012 at 12:05:06PM +0200, Sascha Hauer wrote:
> >> On Thu, Jun 14, 2012 at 03:43:22PM +0200, Sascha Hauer wrote:
> >> > Hi All,
> >> >
> >> > The following is the state-of-the-art i.MX IPU (Image Processing Unit)
> >> > DRM support.
> >> >
> >> > This code is around for quite some time now and has been posted several
> >> > times with different APIs, first with plain old framebuffer support, now
> >> > DRM, first platform device binding, now devicetree. Unfortunately there's
> >> > quite much code needed to get something useful out of the IPU, so these
> >> > patches haven't received a lot of attention from people not involved in
> >> > i.MX. I think we have now come to a point where this code needs more 
> >> > public
> >> > exposure and where it's easier to talk in incremental changes instead of
> >> > blobs. Therefore I request this to go to staging for some cycles.
> >>
> >> Dave, Greg,
> >>
> >> Comments to this one? I addressed the comments I received so far and am
> >> about to respin this series. Is it ok to put this to staging? If yes,
> >> should I move the whole stuff into drivers/staging/ or should it stay
> >> in drivers/gpu/drm with just a Kconfig dependency on STAGING?
> >
> > That's up to the DRM subsystem maintainer to choose.
> 
> Sorry guys been out of the loop on arm drivers due to other things,
> but probably should go in staging proper for now, until I can at least
> spend time reviewing it.

Right now we have dependencies on:

http://www.mail-archive.com/dri-devel@lists.freedesktop.org/msg24409.html
http://www.mail-archive.com/dri-devel@lists.freedesktop.org/msg24224.html

We could move these two helpers into staging, but they are needed by
other drivers from Laurent Pinchart and Lars-Peter Clausen aswell. So
it would be good to have them available for them aswell. Could you have
a look on these and consider applying?

Thanks,
  Sascha

-- 
Pengutronix e.K.   | |
Industrial Linux Solutions | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0|
Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 44341] Radeon HD6990M: HDMI audio output works now! Kernel gives new warning

2012-07-09 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=44341


Christopher Frömmel  changed:

   What|Removed |Added

  Attachment #75061|application/octet-stream|text/plain
  mime type||




-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 44341] Radeon HD6990M: HDMI audio output works now! Kernel gives new warning

2012-07-09 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=44341


Christopher Frömmel  changed:

   What|Removed |Added

  Attachment #75121|application/octet-stream|text/plain
  mime type||




-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 44341] Radeon HD6990M: HDMI audio output works now! Kernel gives new warning

2012-07-09 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=44341


Christopher Frömmel  changed:

   What|Removed |Added

  Attachment #75091|application/octet-stream|text/plain
  mime type||




-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


  1   2   >