Re: Linux 3.4-rc4

2012-04-30 Thread Maarten Maathuis
On Mon, Apr 30, 2012 at 12:37 AM, Dmitry Torokhov
 wrote:
> On Sat, Apr 28, 2012 at 11:33:50AM -0400, Nick Bowler wrote:
>> On 2012-04-28 02:19 -0400, Alex Deucher wrote:
>> > On Fri, Apr 27, 2012 at 8:39 PM, Nick Bowler  
>> > wrote:
>> > > Hi Ben,
>> > >
>> > > On 2012-04-27 15:20 +1000, Ben Skeggs wrote:
>> > >> Does this patch help you at all?
>> > >>
>> > >> http://cgit.freedesktop.org/nouveau/linux-2.6/commit/?id=a3a285f17867f0018de798b5ee85731ec1268305
>> > >
>> > > Yes.  I cherry-picked this patch on top of Linus' master (3.4-rc4+) and
>> > > this appears to solve the "black screen on VGA" problem described in the
>> > > original report.  Thanks!
>> > >
>> > > Unfortunately, that's not the end of my VGA-related regressions. :(
>> > >
>> > > While tracking down the black screen issue, I've been having the monitor
>> > > directly connected to the video card the whole time, but now when I'm
>> > > connected through my KVM switch (an IOGear GCS1804), it appears that
>> > > something's going wrong with reading the EDID, because the available
>> > > modes are all screwed up (both console and X decide they want to drive
>> > > the display at 1024x768).  Here's the output of xrandr on 3.2.15:
>> > >
>> > >  % xrandr
>> > >  Screen 1: minimum 320 x 200, current 1600 x 1200, maximum 4096 x 4096
>> > >  VGA-1 connected 1600x1200+0+0 (normal left inverted right x axis y 
>> > > axis) 352mm x 264mm
>> > >     1600x1200      75.0*+   70.0     65.0     60.0
>> > >     1280x1024      85.0 +   75.0     60.0
>> > >     1920x1440      60.0
>> > >     1856x1392      60.0
>> > >     1792x1344      60.0
>> > >     1920x1200      74.9     59.9
>> > >     1680x1050      84.9     74.9     60.0
>> > >     1400x1050      85.0     74.9     60.0
>> > >     1440x900       84.8     75.0     59.9
>> > >     1280x960       85.0     60.0
>> > >     1360x768       60.0
>> > >     1280x800       84.9     74.9     59.8
>> > >     1152x864       75.0
>> > >     1280x768       84.8     74.9     59.9
>> > >     1024x768       85.0     75.1     75.0     70.1     60.0     43.5     
>> > > 43.5
>> > >     832x624        74.6
>> > >     800x600        85.1     72.2     75.0     60.3     56.2
>> > >     848x480        60.0
>> > >     640x480        85.0     75.0     72.8     72.8     66.7     60.0     
>> > > 59.9
>> > >     720x400        85.0     87.8     70.1
>> > >     640x400        85.1
>> > >     640x350        85.1
>> > >     320x200       165.1
>> > >
>> > > And on 3.4-rc4+ (with your patch cherry-picked):
>> > >
>> > >  % xrandr
>> > >  Screen 1: minimum 320 x 200, current 1024 x 768, maximum 4096 x 4096
>> > >  VGA-1 connected 1024x768+0+0 (normal left inverted right x axis y axis) 
>> > > 0mm x 0mm
>> > >     1024x768       60.0*
>> > >     800x600        60.3     56.2
>> > >     848x480        60.0
>> > >     640x480        59.9
>> > >     320x200       165.1
>> > >
>> > > Running xrandr on 3.4-rc4+ also causes the screen to go black for a
>> > > second when it does not on 3.2.15.  It also causes several messages of
>> > > the form
>> > >
>> > >  [drm] nouveau :01:00.0: Load detected on output B
>> > >
>> > > to be logged.  Also, looking at /sys/class/drm/card0-VGA-1/edid I see
>> > > that it is empty on 3.4-rc4+ and it is correct on 3.2.15.  Things seem
>> > > to work OK when the KVM is not involved.
>> >
>> > Were you ever able to fetch a EDID with the KVM involved?  KVMs are
>> > notorious for not connecting the ddc pins.
>>
>> Yes, it works on 3.2.15 as described above.
>
> I have the same (or similar) KVM (not in the office at the moment) and I
> can confirm that with newer kernels EDID fecthing in flaky. It's 50/50
> if EDED retrieval succeeds or if it fails with:
>
> Apr 26 13:06:57 dtor-d630 kernel: [13464.936336] [drm:drm_edid_block_valid] 
> *ERROR* EDID checksum is invalid, remainder is 208
> Apr 26 13:06:57 dtor-d630 kernel: [13464.955317] [drm:drm_edid_block_valid] 
> *ERROR* EDID checksum is invalid, remainder is 208
> Apr 26 13:06:57 dtor-d630 kernel: [13464.973879] [drm:drm_edid_block_valid] 
> *ERROR* EDID checksum is invalid, remainder is 208
> Apr 27 09:13:03 dtor-d630 kernel: [44602.087659] [drm:drm_edid_block_valid] 
> *ERROR* EDID checksum is invalid, remainder is 208
> Apr 27 09:13:03 dtor-d630 kernel: [44602.107147] [drm:drm_edid_block_valid] 
> *ERROR* EDID checksum is invalid, remainder is 208
> Apr 27 09:13:03 dtor-d630 kernel: [44602.126908] [drm:drm_edid_block_valid] 
> *ERROR* EDID checksum is invalid, remainder is 208
> Apr 27 09:13:03 dtor-d630 kernel: [44602.146277] [drm:drm_edid_block_valid] 
> *ERROR* EDID checksum is invalid, remainder is 208
> Apr 27 09:13:03 dtor-d630 kernel: [44602.297659] [drm:drm_edid_block_valid] 
> *ERROR* EDID checksum is invalid, remainder is 208
> Apr 27 09:13:03 dtor-d630 kernel: [44602.317063] [drm:drm_edid_block_valid] 
> *ERROR* EDID checksum is invalid, remainder is 208
>
> Earlier kernels were able to retrieve EDEDs reliably.
>
> This is with:
>
> [    1.678

[Bug 48880] Set mode has different timings than requested on VGA

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

Florian Mickler  changed:

   What|Removed |Added

 CC||flor...@mickler.org

--- Comment #27 from Florian Mickler  2012-04-30 02:53:36 
PDT ---
A patch referencing this bug report has been merged in Linux v3.4-rc5:

commit 37d4174d2d252c37dcb3d88cafae488542087848
Author: Alex Deucher 
Date:   Thu Apr 19 10:48:38 2012 -0400

drm/radeon/kms: use frac fb div on APUs

-- 
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 42490] NUTMEG DP to VGA bridge not working

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

Florian Mickler  changed:

   What|Removed |Added

 CC||flor...@mickler.org

--- Comment #27 from Florian Mickler  2012-04-30 02:54:28 
PDT ---
A patch referencing this bug report has been merged in Linux v3.4-rc5:

commit 700698e7c303f5095107c62a81872c2c3dad1702
Author: Alex Deucher 
Date:   Fri Apr 27 17:18:59 2012 -0400

drm/radeon/kms: need to set up ss on DP bridges as well

-- 
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: DVI/VGA/HDI mess on Radeon HD 6570

2012-04-30 Thread Boszormenyi Zoltan

2011-12-19 19:31 keltezéssel, Adam Jackson írta:

On Mon, 2011-12-19 at 18:56 +0100, Boszormenyi Zoltan wrote:


Thanks. As I am logged in as my user, there's no such button.
How can I set it as the system default? It was a long time ago
when GNOME allowed a root login.

Ideally, gnome would implement that button.

Failing that you can set Option "Primary" for the appropriate monitor
section in xorg.conf.

- ajax


I have found a way to match GDM's behaviour to what I have
set in my session. This is embarrassingly simple. After setting
up the monitors in the GNOME display applet:

sudo cp ~/.config/monitors.xml /var/lib/gdm/.config/

Next time GDM restarted, it behaved the way I set up.

Best regards,
Zoltán Böszörményi

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


Re: Linux 3.4-rc4

2012-04-30 Thread Luca Tettamanti
On Mon, Apr 30, 2012 at 11:07 AM, Maarten Maathuis  wrote:
> On Mon, Apr 30, 2012 at 12:37 AM, Dmitry Torokhov
>  wrote:
>> On Sat, Apr 28, 2012 at 11:33:50AM -0400, Nick Bowler wrote:
>>> On 2012-04-28 02:19 -0400, Alex Deucher wrote:
>>> > On Fri, Apr 27, 2012 at 8:39 PM, Nick Bowler  
>>> > wrote:
>>> > > Hi Ben,
>>> > >
>>> > > On 2012-04-27 15:20 +1000, Ben Skeggs wrote:
>>> > >> Does this patch help you at all?
>>> > >>
>>> > >> http://cgit.freedesktop.org/nouveau/linux-2.6/commit/?id=a3a285f17867f0018de798b5ee85731ec1268305
>>> > >
>>> > > Yes.  I cherry-picked this patch on top of Linus' master (3.4-rc4+) and
>>> > > this appears to solve the "black screen on VGA" problem described in the
>>> > > original report.  Thanks!
>>> > >
>>> > > Unfortunately, that's not the end of my VGA-related regressions. :(
>>> > >
>>> > > While tracking down the black screen issue, I've been having the monitor
>>> > > directly connected to the video card the whole time, but now when I'm
>>> > > connected through my KVM switch (an IOGear GCS1804), it appears that
>>> > > something's going wrong with reading the EDID, because the available
>>> > > modes are all screwed up (both console and X decide they want to drive
>>> > > the display at 1024x768).  Here's the output of xrandr on 3.2.15:
>>> > >
>>> > >  % xrandr
>>> > >  Screen 1: minimum 320 x 200, current 1600 x 1200, maximum 4096 x 4096
>>> > >  VGA-1 connected 1600x1200+0+0 (normal left inverted right x axis y 
>>> > > axis) 352mm x 264mm
>>> > >     1600x1200      75.0*+   70.0     65.0     60.0
>>> > >     1280x1024      85.0 +   75.0     60.0
>>> > >     1920x1440      60.0
>>> > >     1856x1392      60.0
>>> > >     1792x1344      60.0
>>> > >     1920x1200      74.9     59.9
>>> > >     1680x1050      84.9     74.9     60.0
>>> > >     1400x1050      85.0     74.9     60.0
>>> > >     1440x900       84.8     75.0     59.9
>>> > >     1280x960       85.0     60.0
>>> > >     1360x768       60.0
>>> > >     1280x800       84.9     74.9     59.8
>>> > >     1152x864       75.0
>>> > >     1280x768       84.8     74.9     59.9
>>> > >     1024x768       85.0     75.1     75.0     70.1     60.0     43.5    
>>> > >  43.5
>>> > >     832x624        74.6
>>> > >     800x600        85.1     72.2     75.0     60.3     56.2
>>> > >     848x480        60.0
>>> > >     640x480        85.0     75.0     72.8     72.8     66.7     60.0    
>>> > >  59.9
>>> > >     720x400        85.0     87.8     70.1
>>> > >     640x400        85.1
>>> > >     640x350        85.1
>>> > >     320x200       165.1
>>> > >
>>> > > And on 3.4-rc4+ (with your patch cherry-picked):
>>> > >
>>> > >  % xrandr
>>> > >  Screen 1: minimum 320 x 200, current 1024 x 768, maximum 4096 x 4096
>>> > >  VGA-1 connected 1024x768+0+0 (normal left inverted right x axis y 
>>> > > axis) 0mm x 0mm
>>> > >     1024x768       60.0*
>>> > >     800x600        60.3     56.2
>>> > >     848x480        60.0
>>> > >     640x480        59.9
>>> > >     320x200       165.1
>>> > >
>>> > > Running xrandr on 3.4-rc4+ also causes the screen to go black for a
>>> > > second when it does not on 3.2.15.  It also causes several messages of
>>> > > the form
>>> > >
>>> > >  [drm] nouveau :01:00.0: Load detected on output B
>>> > >
>>> > > to be logged.  Also, looking at /sys/class/drm/card0-VGA-1/edid I see
>>> > > that it is empty on 3.4-rc4+ and it is correct on 3.2.15.  Things seem
>>> > > to work OK when the KVM is not involved.
>>> >
>>> > Were you ever able to fetch a EDID with the KVM involved?  KVMs are
>>> > notorious for not connecting the ddc pins.
>>>
>>> Yes, it works on 3.2.15 as described above.
>>
>> I have the same (or similar) KVM (not in the office at the moment) and I
>> can confirm that with newer kernels EDID fecthing in flaky. It's 50/50
>> if EDED retrieval succeeds or if it fails with:
>>
>> Apr 26 13:06:57 dtor-d630 kernel: [13464.936336] [drm:drm_edid_block_valid] 
>> *ERROR* EDID checksum is invalid, remainder is 208
>> Apr 26 13:06:57 dtor-d630 kernel: [13464.955317] [drm:drm_edid_block_valid] 
>> *ERROR* EDID checksum is invalid, remainder is 208
>> Apr 26 13:06:57 dtor-d630 kernel: [13464.973879] [drm:drm_edid_block_valid] 
>> *ERROR* EDID checksum is invalid, remainder is 208
>> Apr 27 09:13:03 dtor-d630 kernel: [44602.087659] [drm:drm_edid_block_valid] 
>> *ERROR* EDID checksum is invalid, remainder is 208
>> Apr 27 09:13:03 dtor-d630 kernel: [44602.107147] [drm:drm_edid_block_valid] 
>> *ERROR* EDID checksum is invalid, remainder is 208
>> Apr 27 09:13:03 dtor-d630 kernel: [44602.126908] [drm:drm_edid_block_valid] 
>> *ERROR* EDID checksum is invalid, remainder is 208
>> Apr 27 09:13:03 dtor-d630 kernel: [44602.146277] [drm:drm_edid_block_valid] 
>> *ERROR* EDID checksum is invalid, remainder is 208
>> Apr 27 09:13:03 dtor-d630 kernel: [44602.297659] [drm:drm_edid_block_valid] 
>> *ERROR* EDID checksum is invalid, remainder is 208
>> Apr 27 09:13:03 dtor-d630 kernel: [44602.317063] [drm:d

[Bug 49281] radeon: black screen on resume from suspend

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

Alex Deucher  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution||DUPLICATE

--- Comment #1 from Alex Deucher  2012-04-30 05:26:56 PDT ---


*** This bug has been marked as a duplicate of bug 43829 ***

-- 
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 43829] Resuming my AMD A4-3300 based laptop leaves the screen black

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

Alex Deucher  changed:

   What|Removed |Added

 CC||vimregist...@gmail.com

--- Comment #7 from Alex Deucher  2012-04-30 05:26:56 PDT ---
*** Bug 49281 has been marked as a duplicate of this bug. ***

-- 
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 48880] Set mode has different timings than requested on VGA

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

Alex Deucher  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution||FIXED

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


[next][PATCH 0/3] radeon HDMI: next minor improvements

2012-04-30 Thread Rafał Miłecki
This is one more patchset bringing minor improvements to the current
HDMI implementation. I think after this step I'll start working on
moving Evergreen HDMI code to the separated file. Some cleanups and
making ACR re-usable were needed before that.

Patches depend on the earlier 5-patches-set I sent yesterday.

Again, tested on RV620 and HD6320. Unfortunately I don't have DCE32
card or sth to test code in r600_hdmi_enable/r600_hdmi_disable (pre
DCE3).

P.S.
I'm leaving civilization for the rest of this week.

Rafał Miłecki (3):
  drm/radeon/kms/hdmi: enable audio packets at one place
  drm/radeon/kms/hdmi: clean&improve handling HDMI mode
  drm/radeon/kms/hdmi: helper getting ready ACR entry

 drivers/gpu/drm/radeon/r600_hdmi.c |  129 +++
 drivers/gpu/drm/radeon/radeon.h|   14 
 2 files changed, 84 insertions(+), 59 deletions(-)

-- 
1.7.7

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


[next][PATCH 1/3] drm/radeon/kms/hdmi: enable audio packets at one place

2012-04-30 Thread Rafał Miłecki
---
 drivers/gpu/drm/radeon/r600_hdmi.c |   26 --
 1 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c 
b/drivers/gpu/drm/radeon/r600_hdmi.c
index c6de0022..69839df 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -303,11 +303,13 @@ void r600_hdmi_audio_workaround(struct drm_encoder 
*encoder)
r600_hdmi_is_audio_buffer_filled(encoder)) {
 
/* disable audio workaround */
-   WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, 0x0001, ~0x1001);
+   WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset,
+0, ~HDMI0_AUDIO_TEST_EN);
 
} else {
/* enable audio workaround */
-   WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, 0x1001, ~0x1001);
+   WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset,
+HDMI0_AUDIO_TEST_EN, ~HDMI0_AUDIO_TEST_EN);
}
 }
 
@@ -331,6 +333,18 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct 
drm_display_mode *mod
 
WREG32(HDMI0_AUDIO_CRC_CONTROL + offset, 0x1000);
WREG32(HDMI0_GC + offset, 0x0);
+
+   /* Send audio packets */
+   if (ASIC_IS_DCE4(rdev))
+   WREG32_P(0x74fc + offset,
+AFMT_AUDIO_SAMPLE_SEND, ~AFMT_AUDIO_SAMPLE_SEND);
+   else if (ASIC_IS_DCE32(rdev))
+   WREG32_P(AFMT_AUDIO_PACKET_CONTROL + offset,
+AFMT_AUDIO_SAMPLE_SEND, ~AFMT_AUDIO_SAMPLE_SEND);
+   else
+   WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset,
+HDMI0_AUDIO_SAMPLE_SEND, ~HDMI0_AUDIO_SAMPLE_SEND);
+
WREG32(HDMI0_ACR_PACKET_CONTROL + offset, 0x1000);
 
r600_hdmi_update_ACR(encoder, mode->clock);
@@ -495,10 +509,6 @@ void r600_hdmi_enable(struct drm_encoder *encoder)
offset = radeon_encoder->hdmi_offset;
if (ASIC_IS_DCE5(rdev)) {
/* TODO */
-   } else if (ASIC_IS_DCE4(rdev)) {
-   WREG32_P(0x74fc + radeon_encoder->hdmi_offset, 0x1, ~0x1);
-   } else if (ASIC_IS_DCE32(rdev)) {
-   WREG32_P(AFMT_AUDIO_PACKET_CONTROL + 
radeon_encoder->hdmi_offset, 0x1, ~0x1);
} else if (ASIC_IS_DCE3(rdev)) {
/* TODO */
} else if (rdev->family >= CHIP_R600) {
@@ -558,10 +568,6 @@ void r600_hdmi_disable(struct drm_encoder *encoder)
 
if (ASIC_IS_DCE5(rdev)) {
/* TODO */
-   } else if (ASIC_IS_DCE4(rdev)) {
-   WREG32_P(0x74fc + radeon_encoder->hdmi_offset, 0, ~0x1);
-   } else if (ASIC_IS_DCE32(rdev)) {
-   WREG32_P(AFMT_AUDIO_PACKET_CONTROL + 
radeon_encoder->hdmi_offset, 0, ~0x1);
} else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
-- 
1.7.7

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


[next][PATCH 2/3] drm/radeon/kms/hdmi: clean&improve handling HDMI mode

2012-04-30 Thread Rafał Miłecki
---
 drivers/gpu/drm/radeon/r600_hdmi.c |   42 +++
 1 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c 
b/drivers/gpu/drm/radeon/r600_hdmi.c
index 69839df..7d24753 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -493,6 +493,7 @@ void r600_hdmi_enable(struct drm_encoder *encoder)
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
uint32_t offset;
+   u32 hdmi;
 
if (ASIC_IS_DCE5(rdev))
return;
@@ -507,26 +508,34 @@ void r600_hdmi_enable(struct drm_encoder *encoder)
}
 
offset = radeon_encoder->hdmi_offset;
-   if (ASIC_IS_DCE5(rdev)) {
-   /* TODO */
-   } else if (ASIC_IS_DCE3(rdev)) {
-   /* TODO */
-   } else if (rdev->family >= CHIP_R600) {
+
+   /* Older chipsets require setting HDMI and routing manually */
+   if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
+   hdmi = HDMI0_ERROR_ACK | HDMI0_ENABLE;
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
WREG32_P(AVIVO_TMDSA_CNTL, AVIVO_TMDSA_CNTL_HDMI_EN,
 ~AVIVO_TMDSA_CNTL_HDMI_EN);
-   WREG32(HDMI0_CONTROL + offset, 0x101);
+   hdmi |= HDMI0_STREAM(HDMI0_STREAM_TMDSA);
break;
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
WREG32_P(AVIVO_LVTMA_CNTL, AVIVO_LVTMA_CNTL_HDMI_EN,
 ~AVIVO_LVTMA_CNTL_HDMI_EN);
-   WREG32(HDMI0_CONTROL + offset, 0x105);
+   hdmi |= HDMI0_STREAM(HDMI0_STREAM_LVTMA);
+   break;
+   case ENCODER_OBJECT_ID_INTERNAL_DDI:
+   WREG32_P(DDIA_CNTL, DDIA_HDMI_EN, ~DDIA_HDMI_EN);
+   hdmi |= HDMI0_STREAM(HDMI0_STREAM_DDIA);
+   break;
+   case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+   hdmi |= HDMI0_STREAM(HDMI0_STREAM_DVOA);
break;
default:
-   dev_err(rdev->dev, "Unknown HDMI output type\n");
+   dev_err(rdev->dev, "Invalid encoder for HDMI: 0x%X\n",
+   radeon_encoder->encoder_id);
break;
}
+   WREG32(HDMI0_CONTROL + offset, hdmi);
}
 
if (rdev->irq.installed) {
@@ -565,25 +574,28 @@ void r600_hdmi_disable(struct drm_encoder *encoder)
rdev->irq.afmt[offset == 0 ? 0 : 1] = false;
radeon_irq_set(rdev);
 
-
-   if (ASIC_IS_DCE5(rdev)) {
-   /* TODO */
-   } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
+   /* Older chipsets not handled by AtomBIOS */
+   if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
WREG32_P(AVIVO_TMDSA_CNTL, 0,
 ~AVIVO_TMDSA_CNTL_HDMI_EN);
-   WREG32(HDMI0_CONTROL + offset, 0);
break;
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
WREG32_P(AVIVO_LVTMA_CNTL, 0,
 ~AVIVO_LVTMA_CNTL_HDMI_EN);
-   WREG32(HDMI0_CONTROL + offset, 0);
+   break;
+   case ENCODER_OBJECT_ID_INTERNAL_DDI:
+   WREG32_P(DDIA_CNTL, 0, ~DDIA_HDMI_EN);
+   break;
+   case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
break;
default:
-   dev_err(rdev->dev, "Unknown HDMI output type\n");
+   dev_err(rdev->dev, "Invalid encoder for HDMI: 0x%X\n",
+   radeon_encoder->encoder_id);
break;
}
+   WREG32(HDMI0_CONTROL + offset, HDMI0_ERROR_ACK);
}
 
radeon_encoder->hdmi_enabled = false;
-- 
1.7.7

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


[next][PATCH 3/3] drm/radeon/kms/hdmi: helper getting ready ACR entry

2012-04-30 Thread Rafał Miłecki
---
 drivers/gpu/drm/radeon/r600_hdmi.c |   61 
 drivers/gpu/drm/radeon/radeon.h|   14 
 2 files changed, 41 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c 
b/drivers/gpu/drm/radeon/r600_hdmi.c
index 7d24753..0319619 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -53,19 +53,7 @@ enum r600_hdmi_iec_status_bits {
AUDIO_STATUS_LEVEL= 0x80
 };
 
-struct {
-   uint32_t Clock;
-
-   int N_32kHz;
-   int CTS_32kHz;
-
-   int N_44_1kHz;
-   int CTS_44_1kHz;
-
-   int N_48kHz;
-   int CTS_48kHz;
-
-} r600_hdmi_ACR[] = {
+struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = {
 /*  32kHz44.1kHz   48kHz*/
 /* Clock  N CTS  N CTS  N CTS */
 {  25174,  4576,  28125,  7007,  31250,  6864,  28125 }, /*  25,20/1.001 
MHz */
@@ -84,7 +72,7 @@ struct {
 /*
  * calculate CTS value if it's not found in the table
  */
-static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int N, int freq)
+static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int N, int freq)
 {
if (*CTS == 0)
*CTS = clock * N / (128 * freq) * 1000;
@@ -92,6 +80,24 @@ static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int 
N, int freq)
  N, *CTS, freq);
 }
 
+struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock)
+{
+   struct radeon_hdmi_acr res;
+   u8 i;
+
+   for (i = 0; r600_hdmi_predefined_acr[i].clock != clock &&
+r600_hdmi_predefined_acr[i].clock != 0; i++)
+   ;
+   res = r600_hdmi_predefined_acr[i];
+
+   /* In case some CTS are missing */
+   r600_hdmi_calc_cts(clock, &res.cts_32khz, res.n_32khz, 32000);
+   r600_hdmi_calc_cts(clock, &res.cts_44_1khz, res.n_44_1khz, 44100);
+   r600_hdmi_calc_cts(clock, &res.cts_48khz, res.n_48khz, 48000);
+
+   return res;
+}
+
 /*
  * update the N and CTS parameters for a given pixel clock rate
  */
@@ -99,30 +105,17 @@ static void r600_hdmi_update_ACR(struct drm_encoder 
*encoder, uint32_t clock)
 {
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
+   struct radeon_hdmi_acr acr = r600_hdmi_acr(clock);
uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
-   int CTS;
-   int N;
-   int i;
-
-   for (i = 0; r600_hdmi_ACR[i].Clock != clock && r600_hdmi_ACR[i].Clock 
!= 0; i++);
 
-   CTS = r600_hdmi_ACR[i].CTS_32kHz;
-   N = r600_hdmi_ACR[i].N_32kHz;
-   r600_hdmi_calc_CTS(clock, &CTS, N, 32000);
-   WREG32(HDMI0_ACR_32_0 + offset, HDMI0_ACR_CTS_32(CTS));
-   WREG32(HDMI0_ACR_32_1 + offset, N);
+   WREG32(HDMI0_ACR_32_0 + offset, HDMI0_ACR_CTS_32(acr.cts_32khz));
+   WREG32(HDMI0_ACR_32_1 + offset, acr.n_32khz);
 
-   CTS = r600_hdmi_ACR[i].CTS_44_1kHz;
-   N = r600_hdmi_ACR[i].N_44_1kHz;
-   r600_hdmi_calc_CTS(clock, &CTS, N, 44100);
-   WREG32(HDMI0_ACR_44_0 + offset, HDMI0_ACR_CTS_44(CTS));
-   WREG32(HDMI0_ACR_44_1 + offset, N);
+   WREG32(HDMI0_ACR_44_0 + offset, HDMI0_ACR_CTS_44(acr.cts_44_1khz));
+   WREG32(HDMI0_ACR_44_1 + offset, acr.n_44_1khz);
 
-   CTS = r600_hdmi_ACR[i].CTS_48kHz;
-   N = r600_hdmi_ACR[i].N_48kHz;
-   r600_hdmi_calc_CTS(clock, &CTS, N, 48000);
-   WREG32(HDMI0_ACR_48_0 + offset, HDMI0_ACR_CTS_48(CTS));
-   WREG32(HDMI0_ACR_48_1 + offset, N);
+   WREG32(HDMI0_ACR_48_0 + offset, HDMI0_ACR_CTS_48(acr.cts_48khz));
+   WREG32(HDMI0_ACR_48_1 + offset, acr.n_48khz);
 }
 
 /*
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 610acee..71779c8 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1860,6 +1860,20 @@ int r600_fmt_get_nblocksy(u32 format, u32 h);
 /*
  * r600 functions used by radeon_encoder.c
  */
+struct radeon_hdmi_acr {
+   u32 clock;
+
+   int n_32khz;
+   int cts_32khz;
+
+   int n_44_1khz;
+   int cts_44_1khz;
+
+   int n_48khz;
+   int cts_48khz;
+
+};
+
 extern void r600_hdmi_enable(struct drm_encoder *encoder);
 extern void r600_hdmi_disable(struct drm_encoder *encoder);
 extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct 
drm_display_mode *mode);
-- 
1.7.7

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


Re: [PATCH 05/19] drm: move dev_mapping to the minor node

2012-04-30 Thread Ilija Hadzic



On Fri, 20 Apr 2012, Dave Airlie wrote:


On Thu, Apr 12, 2012 at 7:19 PM, Ilija Hadzic
 wrote:

Make dev_mapping per-minor instead of per device. This is
a preparatory patch for introducing render nodes. This
will allow per-node instead of per-device mapping range,
once we introduce render nodes.


One problem is this introduces a ttm/drm dependency that we don't
really have so far.



Sorry for a belated follow-up (I was busy with something else). I 
understand the concern and I think that the patch can be reworked such 
that it does not introduce the dependency. What introduces the dependency 
is a call to drm_unmap_mapping in ttm_bo_unmap_virtual. If the patch is 
reworked such that the minor tracks i_mapping pointer instead of the whole 
drm_device structure, the need for drm_unmap_mapping may be eliminated, 
which in turn will take care of the dependency.


That brings me to a question for you. The patch from which I derived this 
is your patch 7c5cc4f63556e351e9e5980ed22accad410e3fdc (on your original 
render-nodes branch). That's where you introduced drm_unmap_mapping 
function, which calls unmap_mapping_range for every minor known to the 
system.


Why was that necessary at first place ? I mean we don't do the eqivalent 
of that currently when there are multiple physical GPUs in the system, so 
I don't quite get why introduction of multiple minors would require to go 
through the whole list of minors. If that's a "just in case"/"just to be 
safe" kind of thing, then I think we may be able to just call 
drm_unmap_mapping from the driver that needs to call it and only for the 
minor in question.


If we can do that, then the patch will in principle look the same to what 
the current code does, except that dev_mapping will be in the minor 
structure and there will ne no new dependencies introduced. The patch will 
also be simpler that way.


-- Ilija

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


Include request for reset-rework branch.

2012-04-30 Thread Christian König
Hi Dave,

if nobody has a last moment concern please include the following patches in 
drm-next.

Except for some minor fixes they have already been on the list for quite some 
time,
but I intentional left out the debugfs related patches cause we haven't 
finished the
discussion about them yet.

If you prefer to merge them directly, I also made them available as reset-rework
branch here: git://people.freedesktop.org/~deathsimple/linux

Cheers,
Christian.

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


[PATCH 01/26] drm/radeon: make radeon_gpu_is_lockup a per ring function

2012-04-30 Thread Christian König
Different rings have different criteria to test
if they are stuck.

v2: rebased on current drm-next

Signed-off-by: Christian König 
Reviewed-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon.h   |4 +-
 drivers/gpu/drm/radeon/radeon_asic.c  |   44 ++--
 drivers/gpu/drm/radeon/radeon_fence.c |2 +-
 3 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 566ca3b..1bcd2b3 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1153,7 +1153,6 @@ struct radeon_asic {
int (*resume)(struct radeon_device *rdev);
int (*suspend)(struct radeon_device *rdev);
void (*vga_set_state)(struct radeon_device *rdev, bool state);
-   bool (*gpu_is_lockup)(struct radeon_device *rdev, struct radeon_ring 
*cp);
int (*asic_reset)(struct radeon_device *rdev);
/* ioctl hw specific callback. Some hw might want to perform special
 * operation on specific ioctl. For instance on wait idle some hw
@@ -1182,6 +1181,7 @@ struct radeon_asic {
void (*ring_start)(struct radeon_device *rdev, struct 
radeon_ring *cp);
int (*ring_test)(struct radeon_device *rdev, struct radeon_ring 
*cp);
int (*ib_test)(struct radeon_device *rdev, struct radeon_ring 
*cp);
+   bool (*is_lockup)(struct radeon_device *rdev, struct 
radeon_ring *cp);
} ring[RADEON_NUM_RINGS];
/* irqs */
struct {
@@ -1739,7 +1739,6 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t 
v);
 #define radeon_suspend(rdev) (rdev)->asic->suspend((rdev))
 #define radeon_cs_parse(rdev, r, p) (rdev)->asic->ring[(r)].cs_parse((p))
 #define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), 
(state))
-#define radeon_gpu_is_lockup(rdev, cp) (rdev)->asic->gpu_is_lockup((rdev), 
(cp))
 #define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev))
 #define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart.tlb_flush((rdev))
 #define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart.set_page((rdev), 
(i), (p))
@@ -1748,6 +1747,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t 
v);
 #define radeon_ib_test(rdev, r, cp) (rdev)->asic->ring[(r)].ib_test((rdev), 
(cp))
 #define radeon_ring_ib_execute(rdev, r, ib) 
(rdev)->asic->ring[(r)].ib_execute((rdev), (ib))
 #define radeon_ring_ib_parse(rdev, r, ib) 
(rdev)->asic->ring[(r)].ib_parse((rdev), (ib))
+#define radeon_ring_is_lockup(rdev, r, cp) 
(rdev)->asic->ring[(r)].is_lockup((rdev), (cp))
 #define radeon_irq_set(rdev) (rdev)->asic->irq.set((rdev))
 #define radeon_irq_process(rdev) (rdev)->asic->irq.process((rdev))
 #define radeon_get_vblank_counter(rdev, crtc) 
(rdev)->asic->display.get_vblank_counter((rdev), (crtc))
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c 
b/drivers/gpu/drm/radeon/radeon_asic.c
index be4dc2f..958b9ea 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -134,7 +134,6 @@ static struct radeon_asic r100_asic = {
.suspend = &r100_suspend,
.resume = &r100_resume,
.vga_set_state = &r100_vga_set_state,
-   .gpu_is_lockup = &r100_gpu_is_lockup,
.asic_reset = &r100_asic_reset,
.ioctl_wait_idle = NULL,
.gui_idle = &r100_gui_idle,
@@ -152,6 +151,7 @@ static struct radeon_asic r100_asic = {
.ring_start = &r100_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
+   .is_lockup = &r100_gpu_is_lockup,
}
},
.irq = {
@@ -208,7 +208,6 @@ static struct radeon_asic r200_asic = {
.suspend = &r100_suspend,
.resume = &r100_resume,
.vga_set_state = &r100_vga_set_state,
-   .gpu_is_lockup = &r100_gpu_is_lockup,
.asic_reset = &r100_asic_reset,
.ioctl_wait_idle = NULL,
.gui_idle = &r100_gui_idle,
@@ -226,6 +225,7 @@ static struct radeon_asic r200_asic = {
.ring_start = &r100_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
+   .is_lockup = &r100_gpu_is_lockup,
}
},
.irq = {
@@ -282,7 +282,6 @@ static struct radeon_asic r300_asic = {
.suspend = &r300_suspend,
.resume = &r300_resume,
.vga_set_state = &r100_vga_set_state,
-   .gpu_is_lockup = &r300_gpu_is_lockup,
.asic_reset = &r300_asic_reset,
.ioctl_wait_idle = NULL,
.gui_idle = &r100_gui_idle,
@@ -300,6 +299,7 @@ static struct radeon_asic r300_asic = {
.ring_start = &r300_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
+   .is_lockup = &r300_gpu_is_lockup,
}
},
   

[PATCH 03/26] drm/radeon: register ring debugfs handlers on init

2012-04-30 Thread Christian König
Just register the debugfs files on init instead of
checking the chipset type multiple times.

Signed-off-by: Christian König 
Reviewed-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon_ring.c |   31 +++
 1 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index cc33b3d..b6eb1d2 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -34,7 +34,7 @@
 #include "atom.h"
 
 int radeon_debugfs_ib_init(struct radeon_device *rdev);
-int radeon_debugfs_ring_init(struct radeon_device *rdev);
+int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring 
*ring);
 
 u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx)
 {
@@ -237,9 +237,6 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
if (radeon_debugfs_ib_init(rdev)) {
DRM_ERROR("Failed to register debugfs file for IB !\n");
}
-   if (radeon_debugfs_ring_init(rdev)) {
-   DRM_ERROR("Failed to register debugfs file for rings !\n");
-   }
radeon_mutex_unlock(&rdev->ib_pool.mutex);
return 0;
 }
@@ -411,6 +408,9 @@ int radeon_ring_init(struct radeon_device *rdev, struct 
radeon_ring *ring, unsig
}
ring->ptr_mask = (ring->ring_size / 4) - 1;
ring->ring_free_dw = ring->ring_size / 4;
+   if (radeon_debugfs_ring_init(rdev, ring)) {
+   DRM_ERROR("Failed to register debugfs file for rings !\n");
+   }
return 0;
 }
 
@@ -501,17 +501,24 @@ static char 
radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32];
 static unsigned radeon_debugfs_ib_idx[RADEON_IB_POOL_SIZE];
 #endif
 
-int radeon_debugfs_ring_init(struct radeon_device *rdev)
+int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring 
*ring)
 {
 #if defined(CONFIG_DEBUG_FS)
-   if (rdev->family >= CHIP_CAYMAN)
-   return radeon_debugfs_add_files(rdev, 
radeon_debugfs_ring_info_list,
-   
ARRAY_SIZE(radeon_debugfs_ring_info_list));
-   else
-   return radeon_debugfs_add_files(rdev, 
radeon_debugfs_ring_info_list, 1);
-#else
-   return 0;
+   unsigned i;
+   for (i = 0; i < ARRAY_SIZE(radeon_debugfs_ring_info_list); ++i) {
+   struct drm_info_list *info = &radeon_debugfs_ring_info_list[i];
+   int ridx = *(int*)radeon_debugfs_ring_info_list[i].data;
+   unsigned r;
+
+   if (&rdev->ring[ridx] != ring)
+   continue;
+
+   r = radeon_debugfs_add_files(rdev, info, 1);
+   if (r)
+   return r;
+   }
 #endif
+   return 0;
 }
 
 int radeon_debugfs_ib_init(struct radeon_device *rdev)
-- 
1.7.5.4

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


[PATCH 02/26] drm/radeon: replace gpu_lockup with ring->ready flag

2012-04-30 Thread Christian König
It makes no sense at all to have more than one flag.

Signed-off-by: Christian König 
Reviewed-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/r100.c  |1 -
 drivers/gpu/drm/radeon/r300.c  |1 -
 drivers/gpu/drm/radeon/radeon.h|1 -
 drivers/gpu/drm/radeon/radeon_device.c |1 -
 drivers/gpu/drm/radeon/radeon_fence.c  |   36 +++
 drivers/gpu/drm/radeon/rs600.c |1 -
 6 files changed, 13 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index e11df77..4b677fc 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -2300,7 +2300,6 @@ int r100_asic_reset(struct radeon_device *rdev)
if (G_000E40_SE_BUSY(status) || G_000E40_RE_BUSY(status) ||
G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) {
dev_err(rdev->dev, "failed to reset GPU\n");
-   rdev->gpu_lockup = true;
ret = -1;
} else
dev_info(rdev->dev, "GPU reset succeed\n");
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index fa14383..a63f432 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -449,7 +449,6 @@ int r300_asic_reset(struct radeon_device *rdev)
/* Check if GPU is idle */
if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) {
dev_err(rdev->dev, "failed to reset GPU\n");
-   rdev->gpu_lockup = true;
ret = -1;
} else
dev_info(rdev->dev, "GPU reset succeed\n");
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 1bcd2b3..bb08702 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1538,7 +1538,6 @@ struct radeon_device {
struct radeon_mutex cs_mutex;
struct radeon_wbwb;
struct radeon_dummy_pagedummy_page;
-   boolgpu_lockup;
boolshutdown;
boolsuspend;
boolneed_dma32;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 0fb4f89..dedb398 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -714,7 +714,6 @@ int radeon_device_init(struct radeon_device *rdev,
rdev->is_atom_bios = false;
rdev->usec_timeout = RADEON_MAX_USEC_TIMEOUT;
rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
-   rdev->gpu_lockup = false;
rdev->accel_working = false;
 
DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 
0x%04X:0x%04X).\n",
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 66b2229..36c411f 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -71,14 +71,7 @@ int radeon_fence_emit(struct radeon_device *rdev, struct 
radeon_fence *fence)
return 0;
}
fence->seq = atomic_add_return(1, &rdev->fence_drv[fence->ring].seq);
-   if (!rdev->ring[fence->ring].ready)
-   /* FIXME: cp is not running assume everythings is done right
-* away
-*/
-   radeon_fence_write(rdev, fence->seq, fence->ring);
-   else
-   radeon_fence_ring_emit(rdev, fence->ring, fence);
-
+   radeon_fence_ring_emit(rdev, fence->ring, fence);
trace_radeon_fence_emit(rdev->ddev, fence->seq);
fence->emitted = true;
list_move_tail(&fence->list, &rdev->fence_drv[fence->ring].emitted);
@@ -191,9 +184,6 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
if (!fence)
return true;
 
-   if (fence->rdev->gpu_lockup)
-   return true;
-
write_lock_irqsave(&fence->rdev->fence_lock, irq_flags);
signaled = fence->signaled;
/* if we are shuting down report all fence as signaled */
@@ -260,18 +250,16 @@ retry:
 */
if (seq == rdev->fence_drv[fence->ring].last_seq &&
radeon_ring_is_lockup(rdev, fence->ring, 
&rdev->ring[fence->ring])) {
+
/* good news we believe it's a lockup */
printk(KERN_WARNING "GPU lockup (waiting for 0x%08X 
last fence id 0x%08X)\n",
 fence->seq, seq);
-   /* FIXME: what should we do ? marking everyone
-* as signaled for now
-*/
-   rdev->gpu_lockup = true;
+
+   /* mark the ring as not ready any more */
+   rdev->ring[fence->ring].ready = false;
r = radeon_gpu_reset(rdev);
if (r)
r

[PATCH 04/26] drm/radeon: use central function for IB testing

2012-04-30 Thread Christian König
Removing all the different error messages and
having just one standard behaviour over all
chipset generations.

Signed-off-by: Christian König 
Reviewed-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/evergreen.c   |7 ++-
 drivers/gpu/drm/radeon/ni.c  |7 ++-
 drivers/gpu/drm/radeon/r100.c|7 ++-
 drivers/gpu/drm/radeon/r300.c|7 ++-
 drivers/gpu/drm/radeon/r420.c|7 ++-
 drivers/gpu/drm/radeon/r520.c|8 +++-
 drivers/gpu/drm/radeon/r600.c|7 ++-
 drivers/gpu/drm/radeon/radeon.h  |1 +
 drivers/gpu/drm/radeon/radeon_ring.c |   30 ++
 drivers/gpu/drm/radeon/rs400.c   |7 ++-
 drivers/gpu/drm/radeon/rs600.c   |7 ++-
 drivers/gpu/drm/radeon/rs690.c   |7 ++-
 drivers/gpu/drm/radeon/rv515.c   |8 +++-
 drivers/gpu/drm/radeon/rv770.c   |7 ++-
 14 files changed, 57 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index eed7ace..8b7a01b 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3376,12 +3376,9 @@ static int evergreen_startup(struct radeon_device *rdev)
if (r)
return r;
 
-   r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, 
&rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
-   if (r) {
-   DRM_ERROR("radeon: failed testing IB (%d).\n", r);
-   rdev->accel_working = false;
+   r = radeon_ib_ring_tests(rdev);
+   if (r)
return r;
-   }
 
r = r600_audio_init(rdev);
if (r) {
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index a48ca53..0146428 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1601,12 +1601,9 @@ static int cayman_startup(struct radeon_device *rdev)
if (r)
return r;
 
-   r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, 
&rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
-   if (r) {
-   DRM_ERROR("radeon: failed testing IB (%d).\n", r);
-   rdev->accel_working = false;
+   r = radeon_ib_ring_tests(rdev);
+   if (r)
return r;
-   }
 
r = radeon_vm_manager_start(rdev);
if (r)
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 4b677fc..62f9dab 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -3968,12 +3968,9 @@ static int r100_startup(struct radeon_device *rdev)
if (r)
return r;
 
-   r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, 
&rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
-   if (r) {
-   dev_err(rdev->dev, "failed testing IB (%d).\n", r);
-   rdev->accel_working = false;
+   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 a63f432..26e0db8 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -1417,12 +1417,9 @@ static int r300_startup(struct radeon_device *rdev)
if (r)
return r;
 
-   r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, 
&rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
-   if (r) {
-   dev_err(rdev->dev, "failed testing IB (%d).\n", r);
-   rdev->accel_working = false;
+   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 f3fcaac..99137be 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -279,12 +279,9 @@ static int r420_startup(struct radeon_device *rdev)
if (r)
return r;
 
-   r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, 
&rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
-   if (r) {
-   dev_err(rdev->dev, "failed testing IB (%d).\n", r);
-   rdev->accel_working = false;
+   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 ebcc15b..b5cf837 100644
--- a/drivers/gpu/drm/radeon/r520.c
+++ b/drivers/gpu/drm/radeon/r520.c
@@ -207,12 +207,10 @@ static int r520_startup(struct radeon_device *rdev)
if (r)
return r;
 
-   r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, 
&rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
-   if (r) {
-   dev_err(rdev->dev, "failed testing IB (%d).\n", r);
-   rdev->accel_working = false;
+   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/radeo

[PATCH 05/26] drm/radeon: rework gpu lockup detection and processing

2012-04-30 Thread Christian König
Previusly multiple rings could trigger multiple GPU
resets at the same time.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/radeon.h   |3 +-
 drivers/gpu/drm/radeon/radeon_fence.c |  146 +
 2 files changed, 75 insertions(+), 74 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index e237127..92682b7 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -255,8 +255,7 @@ struct radeon_fence_driver {
volatile uint32_t   *cpu_addr;
atomic_tseq;
uint32_tlast_seq;
-   unsigned long   last_jiffies;
-   unsigned long   last_timeout;
+   unsigned long   last_activity;
wait_queue_head_t   queue;
struct list_headcreated;
struct list_heademitted;
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 36c411f..1a9765a 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -74,6 +74,10 @@ int radeon_fence_emit(struct radeon_device *rdev, struct 
radeon_fence *fence)
radeon_fence_ring_emit(rdev, fence->ring, fence);
trace_radeon_fence_emit(rdev->ddev, fence->seq);
fence->emitted = true;
+   /* are we the first fence on a previusly idle ring? */
+   if (list_empty(&rdev->fence_drv[fence->ring].emitted)) {
+   rdev->fence_drv[fence->ring].last_activity = jiffies;
+   }
list_move_tail(&fence->list, &rdev->fence_drv[fence->ring].emitted);
write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
return 0;
@@ -85,34 +89,14 @@ static bool radeon_fence_poll_locked(struct radeon_device 
*rdev, int ring)
struct list_head *i, *n;
uint32_t seq;
bool wake = false;
-   unsigned long cjiffies;
 
seq = radeon_fence_read(rdev, ring);
-   if (seq != rdev->fence_drv[ring].last_seq) {
-   rdev->fence_drv[ring].last_seq = seq;
-   rdev->fence_drv[ring].last_jiffies = jiffies;
-   rdev->fence_drv[ring].last_timeout = 
RADEON_FENCE_JIFFIES_TIMEOUT;
-   } else {
-   cjiffies = jiffies;
-   if (time_after(cjiffies, rdev->fence_drv[ring].last_jiffies)) {
-   cjiffies -= rdev->fence_drv[ring].last_jiffies;
-   if (time_after(rdev->fence_drv[ring].last_timeout, 
cjiffies)) {
-   /* update the timeout */
-   rdev->fence_drv[ring].last_timeout -= cjiffies;
-   } else {
-   /* the 500ms timeout is elapsed we should test
-* for GPU lockup
-*/
-   rdev->fence_drv[ring].last_timeout = 1;
-   }
-   } else {
-   /* wrap around update last jiffies, we will just wait
-* a little longer
-*/
-   rdev->fence_drv[ring].last_jiffies = cjiffies;
-   }
+   if (seq == rdev->fence_drv[ring].last_seq)
return false;
-   }
+
+   rdev->fence_drv[ring].last_seq = seq;
+   rdev->fence_drv[ring].last_activity = jiffies;
+
n = NULL;
list_for_each(i, &rdev->fence_drv[ring].emitted) {
fence = list_entry(i, struct radeon_fence, list);
@@ -207,66 +191,84 @@ int radeon_fence_wait(struct radeon_fence *fence, bool 
intr)
struct radeon_device *rdev;
unsigned long irq_flags, timeout;
u32 seq;
-   int r;
+   int i, r;
+   bool signaled;
 
if (fence == NULL) {
WARN(1, "Querying an invalid fence : %p !\n", fence);
-   return 0;
+   return -EINVAL;
}
+
rdev = fence->rdev;
-   if (radeon_fence_signaled(fence)) {
-   return 0;
-   }
-   timeout = rdev->fence_drv[fence->ring].last_timeout;
-retry:
-   /* save current sequence used to check for GPU lockup */
-   seq = rdev->fence_drv[fence->ring].last_seq;
-   trace_radeon_fence_wait_begin(rdev->ddev, seq);
-   if (intr) {
+   signaled = radeon_fence_signaled(fence);
+   while (!signaled) {
+   read_lock_irqsave(&rdev->fence_lock, irq_flags);
+   timeout = jiffies - RADEON_FENCE_JIFFIES_TIMEOUT;
+   if (time_after(rdev->fence_drv[fence->ring].last_activity, 
timeout)) {
+   /* the normal case, timeout is somewhere before 
last_activity */
+   timeout = rdev->fence_drv[fence->ring].last_activity - 
timeout;
+   } else {
+   /* either jiffies wrapped around, or no fence was 
sign

[PATCH 06/26] drm/radeon: fix a bug in the SA code

2012-04-30 Thread Christian König
Aligning offset can make it bigger than tmp->offset
leading to an overrun bug in the following subtraction.

v2: Against initial suspicions this can't happen in mainline,
so no need to push it into stable.

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

diff --git a/drivers/gpu/drm/radeon/radeon_sa.c 
b/drivers/gpu/drm/radeon/radeon_sa.c
index 4cce47e..8fbfe69 100644
--- a/drivers/gpu/drm/radeon/radeon_sa.c
+++ b/drivers/gpu/drm/radeon/radeon_sa.c
@@ -150,7 +150,7 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
offset = 0;
list_for_each_entry(tmp, &sa_manager->sa_bo, list) {
/* room before this object ? */
-   if ((tmp->offset - offset) >= size) {
+   if (offset < tmp->offset && (tmp->offset - offset) >= size) {
head = tmp->list.prev;
goto out;
}
-- 
1.7.5.4

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


[PATCH 07/26] drm/radeon: add proper locking to the SA v2

2012-04-30 Thread Christian König
Make the suballocator self containing to locking.

v2: split the bugfix into a seperate patch.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/radeon.h|1 +
 drivers/gpu/drm/radeon/radeon_sa.c |   17 +++--
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 92682b7..99b188a 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -381,6 +381,7 @@ struct radeon_bo_list {
  * alignment).
  */
 struct radeon_sa_manager {
+   spinlock_t  lock;
struct radeon_bo*bo;
struct list_headsa_bo;
unsignedsize;
diff --git a/drivers/gpu/drm/radeon/radeon_sa.c 
b/drivers/gpu/drm/radeon/radeon_sa.c
index 8fbfe69..4ce5c51 100644
--- a/drivers/gpu/drm/radeon/radeon_sa.c
+++ b/drivers/gpu/drm/radeon/radeon_sa.c
@@ -37,6 +37,7 @@ int radeon_sa_bo_manager_init(struct radeon_device *rdev,
 {
int r;
 
+   spin_lock_init(&sa_manager->lock);
sa_manager->bo = NULL;
sa_manager->size = size;
sa_manager->domain = domain;
@@ -136,18 +137,19 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
struct radeon_sa_bo *tmp;
struct list_head *head;
unsigned offset = 0, wasted = 0;
+   unsigned long flags;
 
BUG_ON(align > RADEON_GPU_PAGE_SIZE);
BUG_ON(size > sa_manager->size);
+   spin_lock_irqsave(&sa_manager->lock, flags);
 
/* no one ? */
-   head = sa_manager->sa_bo.prev;
if (list_empty(&sa_manager->sa_bo)) {
+   head = &sa_manager->sa_bo;
goto out;
}
 
/* look for a hole big enough */
-   offset = 0;
list_for_each_entry(tmp, &sa_manager->sa_bo, list) {
/* room before this object ? */
if (offset < tmp->offset && (tmp->offset - offset) >= size) {
@@ -157,9 +159,8 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
offset = tmp->offset + tmp->size;
wasted = offset % align;
if (wasted) {
-   wasted = align - wasted;
+   offset += align - wasted;
}
-   offset += wasted;
}
/* room at the end ? */
head = sa_manager->sa_bo.prev;
@@ -167,11 +168,11 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
offset = tmp->offset + tmp->size;
wasted = offset % align;
if (wasted) {
-   wasted = align - wasted;
+   offset += wasted = align - wasted;
}
-   offset += wasted;
if ((sa_manager->size - offset) < size) {
/* failed to find somethings big enough */
+   spin_unlock_irqrestore(&sa_manager->lock, flags);
return -ENOMEM;
}
 
@@ -180,10 +181,14 @@ out:
sa_bo->offset = offset;
sa_bo->size = size;
list_add(&sa_bo->list, head);
+   spin_unlock_irqrestore(&sa_manager->lock, flags);
return 0;
 }
 
 void radeon_sa_bo_free(struct radeon_device *rdev, struct radeon_sa_bo *sa_bo)
 {
+   unsigned long flags;
+   spin_lock_irqsave(&sa_bo->manager->lock, flags);
list_del_init(&sa_bo->list);
+   spin_unlock_irqrestore(&sa_bo->manager->lock, flags);
 }
-- 
1.7.5.4

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


[PATCH 08/26] drm/radeon: add sub allocator debugfs file

2012-04-30 Thread Christian König
Dumping the current allocations.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/radeon_object.h |5 +
 drivers/gpu/drm/radeon/radeon_ring.c   |   22 ++
 drivers/gpu/drm/radeon/radeon_sa.c |   15 +++
 3 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_object.h 
b/drivers/gpu/drm/radeon/radeon_object.h
index f9104be..d9b9333 100644
--- a/drivers/gpu/drm/radeon/radeon_object.h
+++ b/drivers/gpu/drm/radeon/radeon_object.h
@@ -161,5 +161,10 @@ extern int radeon_sa_bo_new(struct radeon_device *rdev,
unsigned size, unsigned align);
 extern void radeon_sa_bo_free(struct radeon_device *rdev,
  struct radeon_sa_bo *sa_bo);
+#if defined(CONFIG_DEBUG_FS)
+extern void radeon_sa_bo_dump_debug_info(struct radeon_sa_manager *sa_manager,
+struct seq_file *m);
+#endif
+
 
 #endif
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index 1b020ef..1d9bce9 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -529,6 +529,23 @@ static int radeon_debugfs_ib_info(struct seq_file *m, void 
*data)
 static struct drm_info_list radeon_debugfs_ib_list[RADEON_IB_POOL_SIZE];
 static char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32];
 static unsigned radeon_debugfs_ib_idx[RADEON_IB_POOL_SIZE];
+
+static int radeon_debugfs_sa_info(struct seq_file *m, void *data)
+{
+   struct drm_info_node *node = (struct drm_info_node *) m->private;
+   struct drm_device *dev = node->minor->dev;
+   struct radeon_device *rdev = dev->dev_private;
+
+   radeon_sa_bo_dump_debug_info(&rdev->ib_pool.sa_manager, m);
+
+   return 0;
+
+}
+
+static struct drm_info_list radeon_debugfs_sa_list[] = {
+{"radeon_sa_info", &radeon_debugfs_sa_info, 0, NULL},
+};
+
 #endif
 
 int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring 
*ring)
@@ -555,6 +572,11 @@ int radeon_debugfs_ib_init(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
unsigned i;
+   int r;
+
+   r = radeon_debugfs_add_files(rdev, radeon_debugfs_sa_list, 1);
+   if (r)
+   return r;
 
for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
sprintf(radeon_debugfs_ib_names[i], "radeon_ib_%04u", i);
diff --git a/drivers/gpu/drm/radeon/radeon_sa.c 
b/drivers/gpu/drm/radeon/radeon_sa.c
index 4ce5c51..013a787 100644
--- a/drivers/gpu/drm/radeon/radeon_sa.c
+++ b/drivers/gpu/drm/radeon/radeon_sa.c
@@ -192,3 +192,18 @@ void radeon_sa_bo_free(struct radeon_device *rdev, struct 
radeon_sa_bo *sa_bo)
list_del_init(&sa_bo->list);
spin_unlock_irqrestore(&sa_bo->manager->lock, flags);
 }
+
+#if defined(CONFIG_DEBUG_FS)
+void radeon_sa_bo_dump_debug_info(struct radeon_sa_manager *sa_manager,
+ struct seq_file *m)
+{
+   struct radeon_sa_bo *i;
+   unsigned long flags;
+
+   spin_lock_irqsave(&sa_manager->lock, flags);
+   list_for_each_entry(i, &sa_manager->sa_bo, list) {
+   seq_printf(m, "offset %08d: size %4d\n", i->offset, i->size);
+   }
+   spin_unlock_irqrestore(&sa_manager->lock, flags);
+}
+#endif
-- 
1.7.5.4

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


[PATCH 09/26] drm/radeon: add biggest hole tracking and wakequeue to the sa v3

2012-04-30 Thread Christian König
With that in place clients are automatically blocking
until their memory request can be handled.

v2: block only if the memory request can't be satisfied
in the first try, the first version actually lacked
a night of sleep.

v3: make blocking optional, update comments and fix
another bug with biggest hole tracking.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/radeon.h|5 +-
 drivers/gpu/drm/radeon/radeon_gart.c   |2 +-
 drivers/gpu/drm/radeon/radeon_object.h |2 +-
 drivers/gpu/drm/radeon/radeon_ring.c   |   20 ++--
 drivers/gpu/drm/radeon/radeon_sa.c |  211 +++-
 5 files changed, 165 insertions(+), 75 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 99b188a..e71dc67 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -381,17 +381,16 @@ struct radeon_bo_list {
  * alignment).
  */
 struct radeon_sa_manager {
-   spinlock_t  lock;
+   wait_queue_head_t   queue;
struct radeon_bo*bo;
struct list_headsa_bo;
unsignedsize;
+   struct list_head*biggest_hole;
uint64_tgpu_addr;
void*cpu_ptr;
uint32_tdomain;
 };
 
-struct radeon_sa_bo;
-
 /* sub-allocation buffer */
 struct radeon_sa_bo {
struct list_headlist;
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index c58a036..7af4ff9 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -395,7 +395,7 @@ int radeon_vm_bind(struct radeon_device *rdev, struct 
radeon_vm *vm)
 retry:
r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager, &vm->sa_bo,
 RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8),
-RADEON_GPU_PAGE_SIZE);
+RADEON_GPU_PAGE_SIZE, false);
if (r) {
if (list_empty(&rdev->vm_manager.lru_vm)) {
return r;
diff --git a/drivers/gpu/drm/radeon/radeon_object.h 
b/drivers/gpu/drm/radeon/radeon_object.h
index d9b9333..85f33d9 100644
--- a/drivers/gpu/drm/radeon/radeon_object.h
+++ b/drivers/gpu/drm/radeon/radeon_object.h
@@ -158,7 +158,7 @@ extern int radeon_sa_bo_manager_suspend(struct 
radeon_device *rdev,
 extern int radeon_sa_bo_new(struct radeon_device *rdev,
struct radeon_sa_manager *sa_manager,
struct radeon_sa_bo *sa_bo,
-   unsigned size, unsigned align);
+   unsigned size, unsigned align, bool block);
 extern void radeon_sa_bo_free(struct radeon_device *rdev,
  struct radeon_sa_bo *sa_bo);
 #if defined(CONFIG_DEBUG_FS)
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index 1d9bce9..ccee74f 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -124,7 +124,7 @@ retry:
if (rdev->ib_pool.ibs[idx].fence == NULL) {
r = radeon_sa_bo_new(rdev, &rdev->ib_pool.sa_manager,
 &rdev->ib_pool.ibs[idx].sa_bo,
-size, 256);
+size, 256, false);
if (!r) {
*ib = &rdev->ib_pool.ibs[idx];
(*ib)->ptr = rdev->ib_pool.sa_manager.cpu_ptr;
@@ -205,10 +205,16 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct 
radeon_ib *ib)
 
 int radeon_ib_pool_init(struct radeon_device *rdev)
 {
-   struct radeon_sa_manager tmp;
int i, r;
 
-   r = radeon_sa_bo_manager_init(rdev, &tmp,
+   radeon_mutex_lock(&rdev->ib_pool.mutex);
+   if (rdev->ib_pool.ready) {
+   return 0;
+   }
+   rdev->ib_pool.ready = true;
+   radeon_mutex_unlock(&rdev->ib_pool.mutex);
+
+   r = radeon_sa_bo_manager_init(rdev, &rdev->ib_pool.sa_manager,
  RADEON_IB_POOL_SIZE*64*1024,
  RADEON_GEM_DOMAIN_GTT);
if (r) {
@@ -216,14 +222,6 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
}
 
radeon_mutex_lock(&rdev->ib_pool.mutex);
-   if (rdev->ib_pool.ready) {
-   radeon_mutex_unlock(&rdev->ib_pool.mutex);
-   radeon_sa_bo_manager_fini(rdev, &tmp);
-   return 0;
-   }
-
-   rdev->ib_pool.sa_manager = tmp;
-   INIT_LIST_HEAD(&rdev->ib_pool.sa_manager.sa_bo);
for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
rdev->ib_pool.ibs[i].fence = NULL;
rdev->ib_pool.ibs[i].idx = i;
diff --git a/drivers/gpu/drm/radeon/radeon_sa.c 
b/drivers/gpu/drm/radeon/radeon_sa.c
index 0

[PATCH 10/26] drm/radeon: add try_free callback to the SA

2012-04-30 Thread Christian König
To prevent deadlocks under extreme conditions.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/radeon.h|1 +
 drivers/gpu/drm/radeon/radeon_gart.c   |2 +-
 drivers/gpu/drm/radeon/radeon_object.h |3 ++-
 drivers/gpu/drm/radeon/radeon_ring.c   |2 +-
 drivers/gpu/drm/radeon/radeon_sa.c |   15 ---
 5 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index e71dc67..4f7e941 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -389,6 +389,7 @@ struct radeon_sa_manager {
uint64_tgpu_addr;
void*cpu_ptr;
uint32_tdomain;
+   void(*try_free)(struct radeon_device *);
 };
 
 /* sub-allocation buffer */
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index 7af4ff9..fba3884 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -291,7 +291,7 @@ int radeon_vm_manager_init(struct radeon_device *rdev)
/* 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);
+ RADEON_GEM_DOMAIN_VRAM, NULL);
if (r) {
dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n",
(rdev->vm_manager.max_pfn * 8) >> 10);
diff --git a/drivers/gpu/drm/radeon/radeon_object.h 
b/drivers/gpu/drm/radeon/radeon_object.h
index 85f33d9..08505ed 100644
--- a/drivers/gpu/drm/radeon/radeon_object.h
+++ b/drivers/gpu/drm/radeon/radeon_object.h
@@ -148,7 +148,8 @@ extern struct radeon_bo_va *radeon_bo_va(struct radeon_bo 
*rbo,
  */
 extern int radeon_sa_bo_manager_init(struct radeon_device *rdev,
 struct radeon_sa_manager *sa_manager,
-unsigned size, u32 domain);
+unsigned size, u32 domain,
+void (*try_free)(struct radeon_device 
*rdev));
 extern void radeon_sa_bo_manager_fini(struct radeon_device *rdev,
  struct radeon_sa_manager *sa_manager);
 extern int radeon_sa_bo_manager_start(struct radeon_device *rdev,
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index ccee74f..ae28129 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -216,7 +216,7 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
 
r = radeon_sa_bo_manager_init(rdev, &rdev->ib_pool.sa_manager,
  RADEON_IB_POOL_SIZE*64*1024,
- RADEON_GEM_DOMAIN_GTT);
+ RADEON_GEM_DOMAIN_GTT, NULL);
if (r) {
return r;
}
diff --git a/drivers/gpu/drm/radeon/radeon_sa.c 
b/drivers/gpu/drm/radeon/radeon_sa.c
index 92ab7b4..9d3e70a 100644
--- a/drivers/gpu/drm/radeon/radeon_sa.c
+++ b/drivers/gpu/drm/radeon/radeon_sa.c
@@ -34,7 +34,8 @@
 
 int radeon_sa_bo_manager_init(struct radeon_device *rdev,
  struct radeon_sa_manager *sa_manager,
- unsigned size, u32 domain)
+ unsigned size, u32 domain,
+ void (*try_free)(struct radeon_device *rdev))
 {
int r;
 
@@ -43,6 +44,7 @@ int radeon_sa_bo_manager_init(struct radeon_device *rdev,
sa_manager->size = size;
sa_manager->biggest_hole = &sa_manager->sa_bo;
sa_manager->domain = domain;
+   sa_manager->try_free = try_free;
INIT_LIST_HEAD(&sa_manager->sa_bo);
 
r = radeon_bo_create(rdev, size, RADEON_GPU_PAGE_SIZE, true,
@@ -224,8 +226,15 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
}
 
if (block) {
-   /* failed to find something big enough, wait
-  for the biggest hole to increase in size */
+   /* failed to find something big enough */
+   if (sa_manager->try_free) {
+   /* try to free something */
+   spin_unlock_irq(&sa_manager->queue.lock);
+   sa_manager->try_free(rdev);
+   spin_lock_irq(&sa_manager->queue.lock);
+   }
+
+   /* and wait for the biggest hole to increase in size */
r = 
wait_event_interruptible_locked_irq(sa_manager->queue,
radeon_sa_bo_min_free(sa_manager, align) >= size
);
-- 
1.7.5.4


[PATCH 12/26] drm/radeon: simplify semaphore handling

2012-04-30 Thread Christian König
Directly use the suballocator to get small chunks
of memory. It's equally fast and doesn't crash when
we encounter a GPU reset.

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/radeon.h   |   29 +--
 drivers/gpu/drm/radeon/radeon_device.c|2 -
 drivers/gpu/drm/radeon/radeon_semaphore.c |  134 -
 drivers/gpu/drm/radeon/rv770.c|1 -
 drivers/gpu/drm/radeon/si.c   |1 -
 8 files changed, 22 insertions(+), 148 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index 8b7a01b..26848d6 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3559,7 +3559,6 @@ void evergreen_fini(struct radeon_device *rdev)
evergreen_pcie_gart_fini(rdev);
r600_vram_scratch_fini(rdev);
radeon_gem_fini(rdev);
-   radeon_semaphore_driver_fini(rdev);
radeon_fence_driver_fini(rdev);
radeon_agp_fini(rdev);
radeon_bo_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 0146428..c0b0956 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1773,7 +1773,6 @@ void cayman_fini(struct radeon_device *rdev)
cayman_pcie_gart_fini(rdev);
r600_vram_scratch_fini(rdev);
radeon_gem_fini(rdev);
-   radeon_semaphore_driver_fini(rdev);
radeon_fence_driver_fini(rdev);
radeon_bo_fini(rdev);
radeon_atombios_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index db9415a..659a09c 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2672,7 +2672,6 @@ void r600_fini(struct radeon_device *rdev)
r600_vram_scratch_fini(rdev);
radeon_agp_fini(rdev);
radeon_gem_fini(rdev);
-   radeon_semaphore_driver_fini(rdev);
radeon_fence_driver_fini(rdev);
radeon_bo_fini(rdev);
radeon_atombios_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 4f7e941..e81ad96 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -428,34 +428,12 @@ int radeon_mode_dumb_destroy(struct drm_file *file_priv,
 /*
  * Semaphores.
  */
-struct radeon_ring;
-
-#defineRADEON_SEMAPHORE_BO_SIZE256
-
-struct radeon_semaphore_driver {
-   rwlock_tlock;
-   struct list_headbo;
-};
-
-struct radeon_semaphore_bo;
-
-/* everything here is constant */
 struct radeon_semaphore {
-   struct list_headlist;
-   uint64_tgpu_addr;
-   uint32_t*cpu_ptr;
-   struct radeon_semaphore_bo  *bo;
-};
-
-struct radeon_semaphore_bo {
-   struct list_headlist;
-   struct radeon_ib*ib;
-   struct list_headfree;
-   struct radeon_semaphore semaphores[RADEON_SEMAPHORE_BO_SIZE/8];
-   unsignednused;
+   struct radeon_sa_bo sa_bo;
+   signed  waiters;
+   uint64_tgpu_addr;
 };
 
-void radeon_semaphore_driver_fini(struct radeon_device *rdev);
 int radeon_semaphore_create(struct radeon_device *rdev,
struct radeon_semaphore **semaphore);
 void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring,
@@ -1528,7 +1506,6 @@ struct radeon_device {
struct radeon_mman  mman;
rwlock_tfence_lock;
struct radeon_fence_driver  fence_drv[RADEON_NUM_RINGS];
-   struct radeon_semaphore_driver  semaphore_drv;
struct radeon_ring  ring[RADEON_NUM_RINGS];
struct radeon_ib_pool   ib_pool;
struct radeon_irq   irq;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index dedb398..8c49990 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -733,11 +733,9 @@ int radeon_device_init(struct radeon_device *rdev,
mutex_init(&rdev->pm.mutex);
mutex_init(&rdev->vram_mutex);
rwlock_init(&rdev->fence_lock);
-   rwlock_init(&rdev->semaphore_drv.lock);
INIT_LIST_HEAD(&rdev->gem.objects);
init_waitqueue_head(&rdev->irq.vblank_queue);
init_waitqueue_head(&rdev->irq.idle_queue);
-   INIT_LIST_HEAD(&rdev->semaphore_drv.bo);
/* initialize vm here */
rdev->vm_manager.use_bitmap = 1;
rdev->vm_manager.max_pfn = 1 << 20;
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c 
b/drivers/gpu/drm/radeon/radeon_semaphore.c
index 61dd4e3..5a4741a 100644
--- a/drivers/gpu/drm/radeon/radeo

[PATCH 11/26] drm/radeon: use inline functions to calc sa_bo addr

2012-04-30 Thread Christian König
Instead of hacking the calculation multiple times.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/radeon_gart.c   |6 ++
 drivers/gpu/drm/radeon/radeon_object.h |   11 +++
 drivers/gpu/drm/radeon/radeon_ring.c   |6 ++
 3 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index fba3884..1766671 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -404,10 +404,8 @@ retry:
radeon_vm_unbind(rdev, vm_evict);
goto retry;
}
-   vm->pt = rdev->vm_manager.sa_manager.cpu_ptr;
-   vm->pt += (vm->sa_bo.offset >> 3);
-   vm->pt_gpu_addr = rdev->vm_manager.sa_manager.gpu_addr;
-   vm->pt_gpu_addr += vm->sa_bo.offset;
+   vm->pt = radeon_sa_bo_cpu_addr(&vm->sa_bo);
+   vm->pt_gpu_addr = radeon_sa_bo_gpu_addr(&vm->sa_bo);
memset(vm->pt, 0, RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8));
 
 retry_id:
diff --git a/drivers/gpu/drm/radeon/radeon_object.h 
b/drivers/gpu/drm/radeon/radeon_object.h
index 08505ed..242c76f 100644
--- a/drivers/gpu/drm/radeon/radeon_object.h
+++ b/drivers/gpu/drm/radeon/radeon_object.h
@@ -146,6 +146,17 @@ extern struct radeon_bo_va *radeon_bo_va(struct radeon_bo 
*rbo,
 /*
  * sub allocation
  */
+
+static inline uint64_t radeon_sa_bo_gpu_addr(struct radeon_sa_bo *sa_bo)
+{
+   return sa_bo->manager->gpu_addr + sa_bo->offset;
+}
+
+static inline void * radeon_sa_bo_cpu_addr(struct radeon_sa_bo *sa_bo)
+{
+   return sa_bo->manager->cpu_ptr + sa_bo->offset;
+}
+
 extern int radeon_sa_bo_manager_init(struct radeon_device *rdev,
 struct radeon_sa_manager *sa_manager,
 unsigned size, u32 domain,
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index ae28129..56cfb86 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -127,10 +127,8 @@ retry:
 size, 256, false);
if (!r) {
*ib = &rdev->ib_pool.ibs[idx];
-   (*ib)->ptr = rdev->ib_pool.sa_manager.cpu_ptr;
-   (*ib)->ptr += ((*ib)->sa_bo.offset >> 2);
-   (*ib)->gpu_addr = 
rdev->ib_pool.sa_manager.gpu_addr;
-   (*ib)->gpu_addr += (*ib)->sa_bo.offset;
+   (*ib)->ptr = 
radeon_sa_bo_cpu_addr(&(*ib)->sa_bo);
+   (*ib)->gpu_addr = 
radeon_sa_bo_gpu_addr(&(*ib)->sa_bo);
(*ib)->fence = fence;
(*ib)->vm_id = 0;
(*ib)->is_const_ib = false;
-- 
1.7.5.4

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


[PATCH 13/26] drm/radeon: return -ENOENT in fence_wait_next v2

2012-04-30 Thread Christian König
We should signal the caller that we haven't waited at all.

v2: only change fence_wait_next not fence_wait_last.

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

diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 1a9765a..2fbbc34 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -286,7 +286,7 @@ int radeon_fence_wait_next(struct radeon_device *rdev, int 
ring)
}
if (list_empty(&rdev->fence_drv[ring].emitted)) {
write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
-   return 0;
+   return -ENOENT;
}
fence = list_entry(rdev->fence_drv[ring].emitted.next,
   struct radeon_fence, list);
-- 
1.7.5.4

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


[PATCH 14/26] drm/radeon: rename fence_wait_last to fence_wait_empty

2012-04-30 Thread Christian König
As discussed with Michel that name better
describes the behavior of this function.

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

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index e81ad96..ce22b01 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -285,7 +285,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(struct radeon_device *rdev, int ring);
-int radeon_fence_wait_last(struct radeon_device *rdev, int ring);
+int radeon_fence_wait_empty(struct radeon_device *rdev, int ring);
 struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence);
 void radeon_fence_unref(struct radeon_fence **fence);
 int radeon_fence_count_emitted(struct radeon_device *rdev, int ring);
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 8c49990..5966b35 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -913,7 +913,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t 
state)
radeon_bo_evict_vram(rdev);
/* wait for gpu to finish processing current batch */
for (i = 0; i < RADEON_NUM_RINGS; i++)
-   radeon_fence_wait_last(rdev, i);
+   radeon_fence_wait_empty(rdev, i);
 
radeon_save_bios_scratch_regs(rdev);
 
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 2fbbc34..2d13843 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -297,7 +297,7 @@ int radeon_fence_wait_next(struct radeon_device *rdev, int 
ring)
return r;
 }
 
-int radeon_fence_wait_last(struct radeon_device *rdev, int ring)
+int radeon_fence_wait_empty(struct radeon_device *rdev, int ring)
 {
unsigned long irq_flags;
struct radeon_fence *fence;
@@ -442,7 +442,7 @@ void radeon_fence_driver_fini(struct radeon_device *rdev)
for (ring = 0; ring < RADEON_NUM_RINGS; ring++) {
if (!rdev->fence_drv[ring].initialized)
continue;
-   radeon_fence_wait_last(rdev, ring);
+   radeon_fence_wait_empty(rdev, ring);
wake_up_all(&rdev->fence_drv[ring].queue);
write_lock_irqsave(&rdev->fence_lock, irq_flags);
radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg);
-- 
1.7.5.4

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


[PATCH 15/26] drm/radeon: add general purpose fence signaled callback

2012-04-30 Thread Christian König
Should be used to free resource that are protected by a fence.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/radeon.h   |8 -
 drivers/gpu/drm/radeon/radeon_fence.c |   50 +---
 2 files changed, 52 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index ce22b01..74b6595 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -259,7 +259,6 @@ struct radeon_fence_driver {
wait_queue_head_t   queue;
struct list_headcreated;
struct list_heademitted;
-   struct list_headsignaled;
boolinitialized;
 };
 
@@ -274,6 +273,10 @@ struct radeon_fence {
/* RB, DMA, etc. */
int ring;
struct radeon_semaphore *semaphore;
+
+   /* called when fence is signaled */
+   void(*signal_callback)(struct radeon_device *rdev, void *data);
+   void*callback_data;
 };
 
 int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring);
@@ -289,6 +292,9 @@ int radeon_fence_wait_empty(struct radeon_device *rdev, int 
ring);
 struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence);
 void radeon_fence_unref(struct radeon_fence **fence);
 int radeon_fence_count_emitted(struct radeon_device *rdev, int ring);
+bool radeon_fence_set_signal_callback(struct radeon_fence *fence,
+  void (*callback)(struct radeon_device *, 
void *),
+  void *data);
 
 /*
  * Tiling registers
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 2d13843..c58660a 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -83,7 +83,8 @@ int radeon_fence_emit(struct radeon_device *rdev, struct 
radeon_fence *fence)
return 0;
 }
 
-static bool radeon_fence_poll_locked(struct radeon_device *rdev, int ring)
+static bool radeon_fence_poll_locked(struct radeon_device *rdev, int ring,
+struct list_head *signaled)
 {
struct radeon_fence *fence;
struct list_head *i, *n;
@@ -110,7 +111,7 @@ static bool radeon_fence_poll_locked(struct radeon_device 
*rdev, int ring)
i = n;
do {
n = i->prev;
-   list_move_tail(i, &rdev->fence_drv[ring].signaled);
+   list_move_tail(i, signaled);
fence = list_entry(i, struct radeon_fence, list);
fence->signaled = true;
i = n;
@@ -120,6 +121,20 @@ static bool radeon_fence_poll_locked(struct radeon_device 
*rdev, int ring)
return wake;
 }
 
+static void radeon_fence_process_signaled(struct radeon_device *rdev, struct 
list_head *signaled)
+{
+   struct radeon_fence *fence;
+   struct list_head *i, *n;
+
+   list_for_each_safe(i, n, signaled) {
+   fence = list_entry(i, struct radeon_fence, list);
+   list_del_init(&fence->list);
+   if (fence->signal_callback) {
+   fence->signal_callback(rdev, fence->callback_data);
+   }
+   }
+}
+
 static void radeon_fence_destroy(struct kref *kref)
 {
unsigned long irq_flags;
@@ -152,6 +167,8 @@ int radeon_fence_create(struct radeon_device *rdev,
(*fence)->seq = 0;
(*fence)->ring = ring;
(*fence)->semaphore = NULL;
+   (*fence)->signal_callback = NULL;
+   (*fence)->callback_data = NULL;
INIT_LIST_HEAD(&(*fence)->list);
 
write_lock_irqsave(&rdev->fence_lock, irq_flags);
@@ -164,6 +181,7 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
 {
unsigned long irq_flags;
bool signaled = false;
+   LIST_HEAD(siglist);
 
if (!fence)
return true;
@@ -179,10 +197,12 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
signaled = true;
}
if (!signaled) {
-   radeon_fence_poll_locked(fence->rdev, fence->ring);
+   radeon_fence_poll_locked(fence->rdev, fence->ring, &siglist);
signaled = fence->signaled;
}
write_unlock_irqrestore(&fence->rdev->fence_lock, irq_flags);
+   radeon_fence_process_signaled(fence->rdev, &siglist);
+
return signaled;
 }
 
@@ -341,10 +361,12 @@ void radeon_fence_process(struct radeon_device *rdev, int 
ring)
 {
unsigned long irq_flags;
bool wake;
+   LIST_HEAD(signaled);
 
write_lock_irqsave(&rdev->fence_lock, irq_flags);
-   wake = radeon_fence_poll_locked(rdev, ring);
+   wake = radeon_fence_poll_locked(rdev, ring, &signaled);
write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
+   radeon_fence_process_signaled(rde

[PATCH 16/26] drm/radeon: don't keep list of created fences.

2012-04-30 Thread Christian König
It's never used and so practically superfluous.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/radeon.h   |1 -
 drivers/gpu/drm/radeon/radeon_fence.c |7 ---
 2 files changed, 0 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 74b6595..9ba28a4 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -257,7 +257,6 @@ struct radeon_fence_driver {
uint32_tlast_seq;
unsigned long   last_activity;
wait_queue_head_t   queue;
-   struct list_headcreated;
struct list_heademitted;
boolinitialized;
 };
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index c58660a..326bdb5 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -154,8 +154,6 @@ int radeon_fence_create(struct radeon_device *rdev,
struct radeon_fence **fence,
int ring)
 {
-   unsigned long irq_flags;
-
*fence = kmalloc(sizeof(struct radeon_fence), GFP_KERNEL);
if ((*fence) == NULL) {
return -ENOMEM;
@@ -170,10 +168,6 @@ int radeon_fence_create(struct radeon_device *rdev,
(*fence)->signal_callback = NULL;
(*fence)->callback_data = NULL;
INIT_LIST_HEAD(&(*fence)->list);
-
-   write_lock_irqsave(&rdev->fence_lock, irq_flags);
-   list_add_tail(&(*fence)->list, &rdev->fence_drv[ring].created);
-   write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
return 0;
 }
 
@@ -452,7 +446,6 @@ static void radeon_fence_driver_init_ring(struct 
radeon_device *rdev, int ring)
rdev->fence_drv[ring].cpu_addr = NULL;
rdev->fence_drv[ring].gpu_addr = 0;
atomic_set(&rdev->fence_drv[ring].seq, 0);
-   INIT_LIST_HEAD(&rdev->fence_drv[ring].created);
INIT_LIST_HEAD(&rdev->fence_drv[ring].emitted);
init_waitqueue_head(&rdev->fence_drv[ring].queue);
rdev->fence_drv[ring].initialized = false;
-- 
1.7.5.4

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


[PATCH 18/26] drm/radeon: fix a bug with the ring syncing code

2012-04-30 Thread Christian König
Rings need to lock in order, otherwise
the ring subsystem can deadlock.

v2: fix error handling and number of locked doublewords.
v3: stop creating unneeded semaphores.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/radeon.h   |4 ++
 drivers/gpu/drm/radeon/radeon_cs.c|   35 ++
 drivers/gpu/drm/radeon/radeon_semaphore.c |   56 +
 drivers/gpu/drm/radeon/radeon_ttm.c   |   46 ++-
 4 files changed, 92 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 12d2003..cfd00a9 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -445,6 +445,10 @@ void radeon_semaphore_emit_signal(struct radeon_device 
*rdev, int ring,
  struct radeon_semaphore *semaphore);
 void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring,
struct radeon_semaphore *semaphore);
+int radeon_semaphore_sync_rings(struct radeon_device *rdev,
+   struct radeon_semaphore *semaphore,
+   bool sync_to[RADEON_NUM_RINGS],
+   int dst_ring);
 void radeon_semaphore_free(struct radeon_device *rdev,
   struct radeon_semaphore *semaphore);
 
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
b/drivers/gpu/drm/radeon/radeon_cs.c
index e7b0b5d..24fb001 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -118,6 +118,7 @@ static int radeon_cs_get_ring(struct radeon_cs_parser *p, 
u32 ring, s32 priority
 static int radeon_cs_sync_rings(struct radeon_cs_parser *p)
 {
bool sync_to_ring[RADEON_NUM_RINGS] = { };
+   bool need_sync = false;
int i, r;
 
for (i = 0; i < p->nrelocs; i++) {
@@ -126,36 +127,24 @@ static int radeon_cs_sync_rings(struct radeon_cs_parser 
*p)
 
if (!(p->relocs[i].flags & RADEON_RELOC_DONT_SYNC)) {
struct radeon_fence *fence = 
p->relocs[i].robj->tbo.sync_obj;
-   if (!radeon_fence_signaled(fence)) {
+   if (fence->ring != p->ring && 
!radeon_fence_signaled(fence)) {
sync_to_ring[fence->ring] = true;
+   need_sync = true;
}
}
}
 
-   for (i = 0; i < RADEON_NUM_RINGS; ++i) {
-   /* no need to sync to our own or unused rings */
-   if (i == p->ring || !sync_to_ring[i] || !p->rdev->ring[i].ready)
-   continue;
-
-   if (!p->ib->fence->semaphore) {
-   r = radeon_semaphore_create(p->rdev, 
&p->ib->fence->semaphore);
-   if (r)
-   return r;
-   }
-
-   r = radeon_ring_lock(p->rdev, &p->rdev->ring[i], 3);
-   if (r)
-   return r;
-   radeon_semaphore_emit_signal(p->rdev, i, 
p->ib->fence->semaphore);
-   radeon_ring_unlock_commit(p->rdev, &p->rdev->ring[i]);
+   if (!need_sync) {
+   return 0;
+   }
 
-   r = radeon_ring_lock(p->rdev, &p->rdev->ring[p->ring], 3);
-   if (r)
-   return r;
-   radeon_semaphore_emit_wait(p->rdev, p->ring, 
p->ib->fence->semaphore);
-   radeon_ring_unlock_commit(p->rdev, &p->rdev->ring[p->ring]);
+   r = radeon_semaphore_create(p->rdev, &p->ib->fence->semaphore);
+   if (r) {
+   return r;
}
-   return 0;
+
+   return radeon_semaphore_sync_rings(p->rdev, p->ib->fence->semaphore,
+  sync_to_ring, p->ring);
 }
 
 int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c 
b/drivers/gpu/drm/radeon/radeon_semaphore.c
index f6929c7..731ee65 100644
--- a/drivers/gpu/drm/radeon/radeon_semaphore.c
+++ b/drivers/gpu/drm/radeon/radeon_semaphore.c
@@ -70,6 +70,62 @@ void radeon_semaphore_emit_wait(struct radeon_device *rdev, 
int ring,
radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, 
true);
 }
 
+int radeon_semaphore_sync_rings(struct radeon_device *rdev,
+   struct radeon_semaphore *semaphore,
+   bool sync_to[RADEON_NUM_RINGS],
+   int dst_ring)
+{
+   int i, r;
+
+   for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+   unsigned num_ops = i == dst_ring ? RADEON_NUM_RINGS : 1;
+
+   /* don't lock unused rings */
+   if (!sync_to[i] && i != dst_ring)
+   continue;
+
+   /* prevent GPU deadlocks */
+   if (!rdev->ring[i].ready) {
+   dev_err(rdev->dev, "Trying to sync to a

[PATCH 17/26] drm/radeon: rip out the ib pool v2

2012-04-30 Thread Christian König
It isn't necessary any more and the suballocator
seems to perform even better.

v2: ignore ERESTARTSYS in error reporting,
split fence changes into seperate patch,
use try_free SA callback to avoid lockups

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/radeon.h   |   17 +--
 drivers/gpu/drm/radeon/radeon_device.c|1 -
 drivers/gpu/drm/radeon/radeon_gart.c  |   12 +-
 drivers/gpu/drm/radeon/radeon_ring.c  |  264 ++---
 drivers/gpu/drm/radeon/radeon_semaphore.c |2 +-
 5 files changed, 101 insertions(+), 195 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 9ba28a4..12d2003 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -618,7 +618,6 @@ void radeon_irq_kms_pflip_irq_put(struct radeon_device 
*rdev, int crtc);
 
 struct radeon_ib {
struct radeon_sa_bo sa_bo;
-   unsignedidx;
uint32_tlength_dw;
uint64_tgpu_addr;
uint32_t*ptr;
@@ -627,18 +626,6 @@ struct radeon_ib {
boolis_const_ib;
 };
 
-/*
- * locking -
- * mutex protects scheduled_ibs, ready, alloc_bm
- */
-struct radeon_ib_pool {
-   struct radeon_mutex mutex;
-   struct radeon_sa_managersa_manager;
-   struct radeon_ibibs[RADEON_IB_POOL_SIZE];
-   boolready;
-   unsignedhead_id;
-};
-
 struct radeon_ring {
struct radeon_bo*ring_obj;
volatile uint32_t   *ring;
@@ -779,7 +766,6 @@ struct si_rlc {
 int radeon_ib_get(struct radeon_device *rdev, int ring,
  struct radeon_ib **ib, unsigned size);
 void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib);
-bool radeon_ib_try_free(struct radeon_device *rdev, struct radeon_ib *ib);
 int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib);
 int radeon_ib_pool_init(struct radeon_device *rdev);
 void radeon_ib_pool_fini(struct radeon_device *rdev);
@@ -1512,7 +1498,8 @@ struct radeon_device {
rwlock_tfence_lock;
struct radeon_fence_driver  fence_drv[RADEON_NUM_RINGS];
struct radeon_ring  ring[RADEON_NUM_RINGS];
-   struct radeon_ib_pool   ib_pool;
+   boolib_pool_ready;
+   struct radeon_sa_managersa_manager;
struct radeon_irq   irq;
struct radeon_asic  *asic;
struct radeon_gem   gem;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 5966b35..853e1cb 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -723,7 +723,6 @@ int radeon_device_init(struct radeon_device *rdev,
/* mutex initialization are all done here so we
 * can recall function without having locking issues */
radeon_mutex_init(&rdev->cs_mutex);
-   radeon_mutex_init(&rdev->ib_pool.mutex);
for (i = 0; i < RADEON_NUM_RINGS; ++i)
mutex_init(&rdev->ring[i].mutex);
mutex_init(&rdev->dc_hw_i2c_mutex);
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index 1766671..8eba1c6 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -432,8 +432,8 @@ retry_id:
rdev->vm_manager.use_bitmap |= 1 << id;
vm->id = id;
list_add_tail(&vm->list, &rdev->vm_manager.lru_vm);
-   return radeon_vm_bo_update_pte(rdev, vm, rdev->ib_pool.sa_manager.bo,
-  &rdev->ib_pool.sa_manager.bo->tbo.mem);
+   return radeon_vm_bo_update_pte(rdev, vm, rdev->sa_manager.bo,
+  &rdev->sa_manager.bo->tbo.mem);
 }
 
 /* object have to be reserved */
@@ -631,7 +631,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct 
radeon_vm *vm)
/* map the ib pool buffer at 0 in virtual address space, set
 * read only
 */
-   r = radeon_vm_bo_add(rdev, vm, rdev->ib_pool.sa_manager.bo, 0,
+   r = radeon_vm_bo_add(rdev, vm, rdev->sa_manager.bo, 0,
 RADEON_VM_PAGE_READABLE | RADEON_VM_PAGE_SNOOPED);
return r;
 }
@@ -648,12 +648,12 @@ void radeon_vm_fini(struct radeon_device *rdev, struct 
radeon_vm *vm)
radeon_mutex_unlock(&rdev->cs_mutex);
 
/* remove all bo */
-   r = radeon_bo_reserve(rdev->ib_pool.sa_manager.bo, false);
+   r = radeon_bo_reserve(rdev->sa_manager.bo, false);
if (!r) {
-   bo_va = radeon_bo_va(rdev->ib_pool.sa_manager.bo, vm);
+   bo_va = radeon_bo_va(rdev->sa_manager.bo, vm);
list_del_init(&bo_va->bo_list);
list_del_init(&bo_va->vm_list);
-   radeon_b

[PATCH 19/26] drm/radeon: rework recursive gpu reset handling

2012-04-30 Thread Christian König
Instead of all this humpy pumpy with recursive
mutex (which also fixes only halve of the problem)
move the actual gpu reset out of the fence code,
return -EDEADLK and then reset the gpu in the
calling ioctl function.

v2: Split removal of radeon_mutex into separate patch.
Return -EAGAIN if reset is successful.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/radeon_cs.c |   13 +
 drivers/gpu/drm/radeon/radeon_device.c |5 -
 drivers/gpu/drm/radeon/radeon_fence.c  |   10 +++---
 drivers/gpu/drm/radeon/radeon_gem.c|   16 
 4 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
b/drivers/gpu/drm/radeon/radeon_cs.c
index 24fb001..02eee4b 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -496,6 +496,16 @@ out:
return r;
 }
 
+static int radeon_cs_handle_lockup(struct radeon_device *rdev, int r)
+{
+   if (r == -EDEADLK) {
+   r = radeon_gpu_reset(rdev);
+   if (!r)
+   r = -EAGAIN;
+   }
+   return r;
+}
+
 int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 {
struct radeon_device *rdev = dev->dev_private;
@@ -517,6 +527,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);
+   r = radeon_cs_handle_lockup(rdev, r);
radeon_mutex_unlock(&rdev->cs_mutex);
return r;
}
@@ -525,6 +536,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);
+   r = radeon_cs_handle_lockup(rdev, r);
radeon_mutex_unlock(&rdev->cs_mutex);
return r;
}
@@ -538,6 +550,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
}
 out:
radeon_cs_parser_fini(&parser, r);
+   r = radeon_cs_handle_lockup(rdev, r);
radeon_mutex_unlock(&rdev->cs_mutex);
return r;
 }
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 853e1cb..8a4a210 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -983,9 +983,6 @@ int radeon_gpu_reset(struct radeon_device *rdev)
int r;
int resched;
 
-   /* Prevent CS ioctl from interfering */
-   radeon_mutex_lock(&rdev->cs_mutex);
-
radeon_save_bios_scratch_regs(rdev);
/* block TTM */
resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
@@ -1000,8 +997,6 @@ int radeon_gpu_reset(struct radeon_device *rdev)
ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
}
 
-   radeon_mutex_unlock(&rdev->cs_mutex);
-
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_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 326bdb5..24a4d4b 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -264,6 +264,8 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr)
/* change sequence value on all rings, so nobody else 
things there is a lockup */
for (i = 0; i < RADEON_NUM_RINGS; ++i)
rdev->fence_drv[i].last_seq -= 0x1;
+
+   rdev->fence_drv[fence->ring].last_activity = jiffies;
write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
 
if (radeon_ring_is_lockup(rdev, fence->ring, 
&rdev->ring[fence->ring])) {
@@ -274,13 +276,7 @@ int radeon_fence_wait(struct radeon_fence *fence, bool 
intr)
 
/* mark the ring as not ready any more */
rdev->ring[fence->ring].ready = false;
-   r = radeon_gpu_reset(rdev);
-   if (r)
-   return r;
-
-   write_lock_irqsave(&rdev->fence_lock, 
irq_flags);
-   rdev->fence_drv[fence->ring].last_activity = 
jiffies;
-   write_unlock_irqrestore(&rdev->fence_lock, 
irq_flags);
+   return -EDEADLK;
}
}
}
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c 
b/drivers/gpu/drm/radeon/radeon_gem.c
index c7008b5..e15cb1f 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -154,6 +154,17 @@ void radeon_gem_object_c

[PATCH 20/26] drm/radeon: remove recursive mutex implementation

2012-04-30 Thread Christian König
Not needed anymore.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/radeon.h|   44 +---
 drivers/gpu/drm/radeon/radeon_cs.c |   10 +++---
 drivers/gpu/drm/radeon/radeon_device.c |2 +-
 drivers/gpu/drm/radeon/radeon_gart.c   |   16 ++--
 drivers/gpu/drm/radeon/radeon_gem.c|4 +-
 5 files changed, 17 insertions(+), 59 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index cfd00a9..b48b84c 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -155,48 +155,6 @@ static inline int radeon_atrm_get_bios_chunk(uint8_t 
*bios, int offset, int len)
 #endif
 bool radeon_get_bios(struct radeon_device *rdev);
 
-
-/*
- * Mutex which allows recursive locking from the same process.
- */
-struct radeon_mutex {
-   struct mutexmutex;
-   struct task_struct  *owner;
-   int level;
-};
-
-static inline void radeon_mutex_init(struct radeon_mutex *mutex)
-{
-   mutex_init(&mutex->mutex);
-   mutex->owner = NULL;
-   mutex->level = 0;
-}
-
-static inline void radeon_mutex_lock(struct radeon_mutex *mutex)
-{
-   if (mutex_trylock(&mutex->mutex)) {
-   /* The mutex was unlocked before, so it's ours now */
-   mutex->owner = current;
-   } else if (mutex->owner != current) {
-   /* Another process locked the mutex, take it */
-   mutex_lock(&mutex->mutex);
-   mutex->owner = current;
-   }
-   /* Otherwise the mutex was already locked by this process */
-
-   mutex->level++;
-}
-
-static inline void radeon_mutex_unlock(struct radeon_mutex *mutex)
-{
-   if (--mutex->level > 0)
-   return;
-
-   mutex->owner = NULL;
-   mutex_unlock(&mutex->mutex);
-}
-
-
 /*
  * Dummy page
  */
@@ -1509,7 +1467,7 @@ struct radeon_device {
struct radeon_gem   gem;
struct radeon_pmpm;
uint32_tbios_scratch[RADEON_BIOS_NUM_SCRATCH];
-   struct radeon_mutex cs_mutex;
+   struct mutexcs_mutex;
struct radeon_wbwb;
struct radeon_dummy_pagedummy_page;
boolshutdown;
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
b/drivers/gpu/drm/radeon/radeon_cs.c
index 02eee4b..c3273b8 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -512,9 +512,9 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
struct radeon_cs_parser parser;
int r;
 
-   radeon_mutex_lock(&rdev->cs_mutex);
+   mutex_lock(&rdev->cs_mutex);
if (!rdev->accel_working) {
-   radeon_mutex_unlock(&rdev->cs_mutex);
+   mutex_unlock(&rdev->cs_mutex);
return -EBUSY;
}
/* initialize parser */
@@ -528,7 +528,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
DRM_ERROR("Failed to initialize parser !\n");
radeon_cs_parser_fini(&parser, r);
r = radeon_cs_handle_lockup(rdev, r);
-   radeon_mutex_unlock(&rdev->cs_mutex);
+   mutex_unlock(&rdev->cs_mutex);
return r;
}
r = radeon_cs_parser_relocs(&parser);
@@ -537,7 +537,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
DRM_ERROR("Failed to parse relocation %d!\n", r);
radeon_cs_parser_fini(&parser, r);
r = radeon_cs_handle_lockup(rdev, r);
-   radeon_mutex_unlock(&rdev->cs_mutex);
+   mutex_unlock(&rdev->cs_mutex);
return r;
}
r = radeon_cs_ib_chunk(rdev, &parser);
@@ -551,7 +551,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
 out:
radeon_cs_parser_fini(&parser, r);
r = radeon_cs_handle_lockup(rdev, r);
-   radeon_mutex_unlock(&rdev->cs_mutex);
+   mutex_unlock(&rdev->cs_mutex);
return r;
 }
 
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 8a4a210..94f8561 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -722,7 +722,7 @@ int radeon_device_init(struct radeon_device *rdev,
 
/* mutex initialization are all done here so we
 * can recall function without having locking issues */
-   radeon_mutex_init(&rdev->cs_mutex);
+   mutex_init(&rdev->cs_mutex);
for (i = 0; i < RADEON_NUM_RINGS; ++i)
mutex_init(&rdev->ring[i].mutex);
mutex_init(&rdev->dc_hw_i2c_mutex);
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index 8eba1c6..71b28e91 100644
--- a/drivers/gpu/drm/radeon/radeon_g

[PATCH 22/26] drm/radeon: make lockup timeout a module param

2012-04-30 Thread Christian König
Don't hard code the 10 seconds timeout. Compute jobs
can run much longer.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/radeon.h  |1 +
 drivers/gpu/drm/radeon/radeon_drv.c  |4 
 drivers/gpu/drm/radeon/radeon_ring.c |2 +-
 3 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index bcf4cc4..aaeb8af 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -94,6 +94,7 @@ extern int radeon_disp_priority;
 extern int radeon_hw_i2c;
 extern int radeon_pcie_gen2;
 extern int radeon_msi;
+extern int radeon_lockup_timeout;
 
 /*
  * Copy from radeon_drv.h so we don't have to include both and have conflicting
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c 
b/drivers/gpu/drm/radeon/radeon_drv.c
index ef7bb3f..e62e56a 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -128,6 +128,7 @@ int radeon_disp_priority = 0;
 int radeon_hw_i2c = 0;
 int radeon_pcie_gen2 = 0;
 int radeon_msi = -1;
+int radeon_lockup_timeout = 1;
 
 MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
 module_param_named(no_wb, radeon_no_wb, int, 0444);
@@ -177,6 +178,9 @@ module_param_named(pcie_gen2, radeon_pcie_gen2, int, 0444);
 MODULE_PARM_DESC(msi, "MSI support (1 = enable, 0 = disable, -1 = auto)");
 module_param_named(msi, radeon_msi, int, 0444);
 
+MODULE_PARM_DESC(lockup_timeout, "GPU lockup timeout in ms (defaul 1 = 10 
seconds, 0 = disable)");
+module_param_named(lockup_timeout, radeon_lockup_timeout, int, 0444);
+
 static int radeon_suspend(struct drm_device *dev, pm_message_t state)
 {
drm_radeon_private_t *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index 4c76d21..504fb8f 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -397,7 +397,7 @@ bool radeon_ring_test_lockup(struct radeon_device *rdev, 
struct radeon_ring *rin
return false;
}
elapsed = jiffies_to_msecs(cjiffies - ring->last_activity);
-   if (elapsed >= 1) {
+   if (radeon_lockup_timeout && elapsed >= radeon_lockup_timeout) {
dev_err(rdev->dev, "GPU lockup CP stall for more than 
%lumsec\n", elapsed);
return true;
}
-- 
1.7.5.4

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


[PATCH 23/26] drm/radeon: unlock the ring mutex while waiting for the next fence

2012-04-30 Thread Christian König
Fixing just another deadlock problem with gpu reset tests.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/radeon_ring.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index 504fb8f..0f74c99 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -302,7 +302,9 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct 
radeon_ring *ring, unsi
if (ndw < ring->ring_free_dw) {
break;
}
+   mutex_unlock(&ring->mutex);
r = radeon_fence_wait_next(rdev, radeon_ring_index(rdev, ring));
+   mutex_lock(&ring->mutex);
if (r)
return r;
}
-- 
1.7.5.4

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


[PATCH 21/26] drm/radeon: move lockup detection code into radeon_ring.c

2012-04-30 Thread Christian König
It isn't chipset specific, so it makes no sense
to have that inside r100.c.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/evergreen.c   |5 +--
 drivers/gpu/drm/radeon/ni.c  |5 +--
 drivers/gpu/drm/radeon/r100.c|   57 +
 drivers/gpu/drm/radeon/r300.c|4 +-
 drivers/gpu/drm/radeon/r600.c|   10 +-
 drivers/gpu/drm/radeon/radeon.h  |   16 ++---
 drivers/gpu/drm/radeon/radeon_asic.h |5 ---
 drivers/gpu/drm/radeon/radeon_ring.c |   53 +++
 drivers/gpu/drm/radeon/si.c  |5 +--
 9 files changed, 69 insertions(+), 91 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index 26848d6..e304858 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -2424,7 +2424,6 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev, 
struct radeon_ring *rin
u32 srbm_status;
u32 grbm_status;
u32 grbm_status_se0, grbm_status_se1;
-   struct r100_gpu_lockup *lockup = &rdev->config.evergreen.lockup;
int r;
 
srbm_status = RREG32(SRBM_STATUS);
@@ -2432,7 +2431,7 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev, 
struct radeon_ring *rin
grbm_status_se0 = RREG32(GRBM_STATUS_SE0);
grbm_status_se1 = RREG32(GRBM_STATUS_SE1);
if (!(grbm_status & GUI_ACTIVE)) {
-   r100_gpu_lockup_update(lockup, ring);
+   radeon_ring_lockup_update(ring);
return false;
}
/* force CP activities */
@@ -2444,7 +2443,7 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev, 
struct radeon_ring *rin
radeon_ring_unlock_commit(rdev, ring);
}
ring->rptr = RREG32(CP_RB_RPTR);
-   return r100_gpu_cp_is_lockup(rdev, lockup, ring);
+   return radeon_ring_test_lockup(rdev, ring);
 }
 
 static int evergreen_gpu_soft_reset(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index c0b0956..4327b32 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1397,7 +1397,6 @@ bool cayman_gpu_is_lockup(struct radeon_device *rdev, 
struct radeon_ring *ring)
u32 srbm_status;
u32 grbm_status;
u32 grbm_status_se0, grbm_status_se1;
-   struct r100_gpu_lockup *lockup = &rdev->config.cayman.lockup;
int r;
 
srbm_status = RREG32(SRBM_STATUS);
@@ -1405,7 +1404,7 @@ bool cayman_gpu_is_lockup(struct radeon_device *rdev, 
struct radeon_ring *ring)
grbm_status_se0 = RREG32(GRBM_STATUS_SE0);
grbm_status_se1 = RREG32(GRBM_STATUS_SE1);
if (!(grbm_status & GUI_ACTIVE)) {
-   r100_gpu_lockup_update(lockup, ring);
+   radeon_ring_lockup_update(ring);
return false;
}
/* force CP activities */
@@ -1418,7 +1417,7 @@ bool cayman_gpu_is_lockup(struct radeon_device *rdev, 
struct radeon_ring *ring)
}
/* XXX deal with CP0,1,2 */
ring->rptr = RREG32(ring->rptr_reg);
-   return r100_gpu_cp_is_lockup(rdev, lockup, ring);
+   return radeon_ring_test_lockup(rdev, ring);
 }
 
 static int cayman_gpu_soft_reset(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 62f9dab..20bf498 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -2159,59 +2159,6 @@ int r100_mc_wait_for_idle(struct radeon_device *rdev)
return -1;
 }
 
-void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, struct radeon_ring 
*ring)
-{
-   lockup->last_cp_rptr = ring->rptr;
-   lockup->last_jiffies = jiffies;
-}
-
-/**
- * r100_gpu_cp_is_lockup() - check if CP is lockup by recording information
- * @rdev:  radeon device structure
- * @lockup:r100_gpu_lockup structure holding CP lockup tracking 
informations
- * @cp:radeon_cp structure holding CP information
- *
- * We don't need to initialize the lockup tracking information as we will 
either
- * have CP rptr to a different value of jiffies wrap around which will force
- * initialization of the lockup tracking informations.
- *
- * A possible false positivie is if we get call after while and last_cp_rptr ==
- * the current CP rptr, even if it's unlikely it might happen. To avoid this
- * if the elapsed time since last call is bigger than 2 second than we return
- * false and update the tracking information. Due to this the caller must call
- * r100_gpu_cp_is_lockup several time in less than 2sec for lockup to be 
reported
- * the fencing code should be cautious about that.
- *
- * Caller should write to the ring to force CP to do something so we don't get
- * false positive when CP is just gived nothing to do.
- *
- **/
-bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup 
*lockup, struct radeon_ring *ring)
-{
-   u

[PATCH 25/26] drm/radeon: remove r300_gpu_is_lockup

2012-04-30 Thread Christian König
Since it is now identical to r100_gpu_is_lockup.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/r300.c|   14 --
 drivers/gpu/drm/radeon/radeon_asic.c |   16 
 drivers/gpu/drm/radeon/radeon_asic.h |1 -
 3 files changed, 8 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 04ec269..6419a59 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -377,20 +377,6 @@ void r300_gpu_init(struct radeon_device *rdev)
 rdev->num_gb_pipes, rdev->num_z_pipes);
 }
 
-bool r300_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
-{
-   u32 rbbm_status;
-
-   rbbm_status = RREG32(R_000E40_RBBM_STATUS);
-   if (!G_000E40_GUI_ACTIVE(rbbm_status)) {
-   radeon_ring_lockup_update(ring);
-   return false;
-   }
-   /* force CP activities */
-   radeon_ring_force_activity(rdev, ring);
-   return radeon_ring_test_lockup(rdev, ring);
-}
-
 int r300_asic_reset(struct radeon_device *rdev)
 {
struct r100_mc_save save;
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c 
b/drivers/gpu/drm/radeon/radeon_asic.c
index 958b9ea..5e5694e 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -299,7 +299,7 @@ static struct radeon_asic r300_asic = {
.ring_start = &r300_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
-   .is_lockup = &r300_gpu_is_lockup,
+   .is_lockup = &r100_gpu_is_lockup,
}
},
.irq = {
@@ -373,7 +373,7 @@ static struct radeon_asic r300_asic_pcie = {
.ring_start = &r300_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
-   .is_lockup = &r300_gpu_is_lockup,
+   .is_lockup = &r100_gpu_is_lockup,
}
},
.irq = {
@@ -447,7 +447,7 @@ static struct radeon_asic r420_asic = {
.ring_start = &r300_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
-   .is_lockup = &r300_gpu_is_lockup,
+   .is_lockup = &r100_gpu_is_lockup,
}
},
.irq = {
@@ -521,7 +521,7 @@ static struct radeon_asic rs400_asic = {
.ring_start = &r300_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
-   .is_lockup = &r300_gpu_is_lockup,
+   .is_lockup = &r100_gpu_is_lockup,
}
},
.irq = {
@@ -595,7 +595,7 @@ static struct radeon_asic rs600_asic = {
.ring_start = &r300_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
-   .is_lockup = &r300_gpu_is_lockup,
+   .is_lockup = &r100_gpu_is_lockup,
}
},
.irq = {
@@ -669,7 +669,7 @@ static struct radeon_asic rs690_asic = {
.ring_start = &r300_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
-   .is_lockup = &r300_gpu_is_lockup,
+   .is_lockup = &r100_gpu_is_lockup,
}
},
.irq = {
@@ -743,7 +743,7 @@ static struct radeon_asic rv515_asic = {
.ring_start = &rv515_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
-   .is_lockup = &r300_gpu_is_lockup,
+   .is_lockup = &r100_gpu_is_lockup,
}
},
.irq = {
@@ -817,7 +817,7 @@ static struct radeon_asic r520_asic = {
.ring_start = &rv515_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
-   .is_lockup = &r300_gpu_is_lockup,
+   .is_lockup = &r100_gpu_is_lockup,
}
},
.irq = {
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h 
b/drivers/gpu/drm/radeon/radeon_asic.h
index b0941f9..1e128e0 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -154,7 +154,6 @@ extern int r300_init(struct radeon_device *rdev);
 extern void r300_fini(struct radeon_device *rdev);
 extern int r300_suspend(struct radeon_device *rdev);
 extern int r300_resume(struct radeon_device *rdev);
-extern bool r300_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring 
*cp);
 extern int r300_asic_reset(struct radeon_device *rdev);
 extern vo

[PATCH 24/26] drm/radeon: make forcing ring activity a common function

2012-04-30 Thread Christian König
Nothing chipset or ring specific with it,
so also move it to radon_ring.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/evergreen.c   |   10 +-
 drivers/gpu/drm/radeon/ni.c  |   11 +--
 drivers/gpu/drm/radeon/r100.c|   10 +-
 drivers/gpu/drm/radeon/r300.c|   10 +-
 drivers/gpu/drm/radeon/r600.c|   10 +-
 drivers/gpu/drm/radeon/radeon.h  |1 +
 drivers/gpu/drm/radeon/radeon_ring.c |   16 
 drivers/gpu/drm/radeon/si.c  |   11 +--
 8 files changed, 23 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index e304858..7e7ac3d 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -2424,7 +2424,6 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev, 
struct radeon_ring *rin
u32 srbm_status;
u32 grbm_status;
u32 grbm_status_se0, grbm_status_se1;
-   int r;
 
srbm_status = RREG32(SRBM_STATUS);
grbm_status = RREG32(GRBM_STATUS);
@@ -2435,14 +2434,7 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev, 
struct radeon_ring *rin
return false;
}
/* force CP activities */
-   r = radeon_ring_lock(rdev, ring, 2);
-   if (!r) {
-   /* PACKET2 NOP */
-   radeon_ring_write(ring, 0x8000);
-   radeon_ring_write(ring, 0x8000);
-   radeon_ring_unlock_commit(rdev, ring);
-   }
-   ring->rptr = RREG32(CP_RB_RPTR);
+   radeon_ring_force_activity(rdev, ring);
return radeon_ring_test_lockup(rdev, ring);
 }
 
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 4327b32..8a9c85d 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1397,7 +1397,6 @@ bool cayman_gpu_is_lockup(struct radeon_device *rdev, 
struct radeon_ring *ring)
u32 srbm_status;
u32 grbm_status;
u32 grbm_status_se0, grbm_status_se1;
-   int r;
 
srbm_status = RREG32(SRBM_STATUS);
grbm_status = RREG32(GRBM_STATUS);
@@ -1408,15 +1407,7 @@ bool cayman_gpu_is_lockup(struct radeon_device *rdev, 
struct radeon_ring *ring)
return false;
}
/* force CP activities */
-   r = radeon_ring_lock(rdev, ring, 2);
-   if (!r) {
-   /* PACKET2 NOP */
-   radeon_ring_write(ring, 0x8000);
-   radeon_ring_write(ring, 0x8000);
-   radeon_ring_unlock_commit(rdev, ring);
-   }
-   /* XXX deal with CP0,1,2 */
-   ring->rptr = RREG32(ring->rptr_reg);
+   radeon_ring_force_activity(rdev, ring);
return radeon_ring_test_lockup(rdev, ring);
 }
 
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 20bf498..217cdc2 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -2162,7 +2162,6 @@ int r100_mc_wait_for_idle(struct radeon_device *rdev)
 bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
 {
u32 rbbm_status;
-   int r;
 
rbbm_status = RREG32(R_000E40_RBBM_STATUS);
if (!G_000E40_GUI_ACTIVE(rbbm_status)) {
@@ -2170,14 +2169,7 @@ bool r100_gpu_is_lockup(struct radeon_device *rdev, 
struct radeon_ring *ring)
return false;
}
/* force CP activities */
-   r = radeon_ring_lock(rdev, ring, 2);
-   if (!r) {
-   /* PACKET2 NOP */
-   radeon_ring_write(ring, 0x8000);
-   radeon_ring_write(ring, 0x8000);
-   radeon_ring_unlock_commit(rdev, ring);
-   }
-   ring->rptr = RREG32(ring->rptr_reg);
+   radeon_ring_force_activity(rdev, ring);
return radeon_ring_test_lockup(rdev, ring);
 }
 
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index e207664..04ec269 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -380,7 +380,6 @@ void r300_gpu_init(struct radeon_device *rdev)
 bool r300_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
 {
u32 rbbm_status;
-   int r;
 
rbbm_status = RREG32(R_000E40_RBBM_STATUS);
if (!G_000E40_GUI_ACTIVE(rbbm_status)) {
@@ -388,14 +387,7 @@ bool r300_gpu_is_lockup(struct radeon_device *rdev, struct 
radeon_ring *ring)
return false;
}
/* force CP activities */
-   r = radeon_ring_lock(rdev, ring, 2);
-   if (!r) {
-   /* PACKET2 NOP */
-   radeon_ring_write(ring, 0x8000);
-   radeon_ring_write(ring, 0x8000);
-   radeon_ring_unlock_commit(rdev, ring);
-   }
-   ring->rptr = RREG32(RADEON_CP_RB_RPTR);
+   radeon_ring_force_activity(rdev, ring);
return radeon_ring_test_lockup(rdev, ring);
 }
 
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu

[PATCH 26/26] drm/radeon: remove cayman_gpu_is_lockup

2012-04-30 Thread Christian König
Since it is now identical to evergreen_gpu_is_lockup.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/radeon/ni.c  |   19 ---
 drivers/gpu/drm/radeon/radeon_asic.c |   12 ++--
 drivers/gpu/drm/radeon/radeon_asic.h |1 -
 3 files changed, 6 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 8a9c85d..107b217 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1392,25 +1392,6 @@ int cayman_cp_resume(struct radeon_device *rdev)
return 0;
 }
 
-bool cayman_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
-{
-   u32 srbm_status;
-   u32 grbm_status;
-   u32 grbm_status_se0, grbm_status_se1;
-
-   srbm_status = RREG32(SRBM_STATUS);
-   grbm_status = RREG32(GRBM_STATUS);
-   grbm_status_se0 = RREG32(GRBM_STATUS_SE0);
-   grbm_status_se1 = RREG32(GRBM_STATUS_SE1);
-   if (!(grbm_status & GUI_ACTIVE)) {
-   radeon_ring_lockup_update(ring);
-   return false;
-   }
-   /* force CP activities */
-   radeon_ring_force_activity(rdev, ring);
-   return radeon_ring_test_lockup(rdev, ring);
-}
-
 static int cayman_gpu_soft_reset(struct radeon_device *rdev)
 {
struct evergreen_mc_save save;
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c 
b/drivers/gpu/drm/radeon/radeon_asic.c
index 5e5694e..f533df5 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -1339,7 +1339,7 @@ static struct radeon_asic cayman_asic = {
.cs_parse = &evergreen_cs_parse,
.ring_test = &r600_ring_test,
.ib_test = &r600_ib_test,
-   .is_lockup = &cayman_gpu_is_lockup,
+   .is_lockup = &evergreen_gpu_is_lockup,
},
[CAYMAN_RING_TYPE_CP1_INDEX] = {
.ib_execute = &cayman_ring_ib_execute,
@@ -1349,7 +1349,7 @@ static struct radeon_asic cayman_asic = {
.cs_parse = &evergreen_cs_parse,
.ring_test = &r600_ring_test,
.ib_test = &r600_ib_test,
-   .is_lockup = &cayman_gpu_is_lockup,
+   .is_lockup = &evergreen_gpu_is_lockup,
},
[CAYMAN_RING_TYPE_CP2_INDEX] = {
.ib_execute = &cayman_ring_ib_execute,
@@ -1359,7 +1359,7 @@ static struct radeon_asic cayman_asic = {
.cs_parse = &evergreen_cs_parse,
.ring_test = &r600_ring_test,
.ib_test = &r600_ib_test,
-   .is_lockup = &cayman_gpu_is_lockup,
+   .is_lockup = &evergreen_gpu_is_lockup,
}
},
.irq = {
@@ -1433,7 +1433,7 @@ static struct radeon_asic trinity_asic = {
.cs_parse = &evergreen_cs_parse,
.ring_test = &r600_ring_test,
.ib_test = &r600_ib_test,
-   .is_lockup = &cayman_gpu_is_lockup,
+   .is_lockup = &evergreen_gpu_is_lockup,
},
[CAYMAN_RING_TYPE_CP1_INDEX] = {
.ib_execute = &cayman_ring_ib_execute,
@@ -1443,7 +1443,7 @@ static struct radeon_asic trinity_asic = {
.cs_parse = &evergreen_cs_parse,
.ring_test = &r600_ring_test,
.ib_test = &r600_ib_test,
-   .is_lockup = &cayman_gpu_is_lockup,
+   .is_lockup = &evergreen_gpu_is_lockup,
},
[CAYMAN_RING_TYPE_CP2_INDEX] = {
.ib_execute = &cayman_ring_ib_execute,
@@ -1453,7 +1453,7 @@ static struct radeon_asic trinity_asic = {
.cs_parse = &evergreen_cs_parse,
.ring_test = &r600_ring_test,
.ib_test = &r600_ib_test,
-   .is_lockup = &cayman_gpu_is_lockup,
+   .is_lockup = &evergreen_gpu_is_lockup,
}
},
.irq = {
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h 
b/drivers/gpu/drm/radeon/radeon_asic.h
index 1e128e0..7830931 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -437,7 +437,6 @@ int cayman_init(struct radeon_device *rdev);
 void cayman_fini(struct radeon_device *rdev);
 int cayman_suspend(struct radeon_device *rdev);
 int cayman_resume(struct radeon_device *rdev);
-bool cayman_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp);
 int cayman_asic_reset(struct radeon_device *rdev);
 void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
 int cayman_vm_init(struct radeon_device *rdev);
-- 
1.7.5.4

___
dri-devel mailing list
dri-

Re: Include request for reset-rework branch.

2012-04-30 Thread Jerome Glisse
On Mon, Apr 30, 2012 at 10:50 AM, Christian König
 wrote:
> Hi Dave,
>
> if nobody has a last moment concern please include the following patches in 
> drm-next.
>
> Except for some minor fixes they have already been on the list for quite some 
> time,
> but I intentional left out the debugfs related patches cause we haven't 
> finished the
> discussion about them yet.
>
> If you prefer to merge them directly, I also made them available as 
> reset-rework
> branch here: git://people.freedesktop.org/~deathsimple/linux
>
> Cheers,
> Christian.
>

I am not completely ok, i am against patch 5. I need sometime to review it.

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


Re: Include request for reset-rework branch.

2012-04-30 Thread Jerome Glisse
On Mon, Apr 30, 2012 at 11:12 AM, Jerome Glisse  wrote:
> On Mon, Apr 30, 2012 at 10:50 AM, Christian König
>  wrote:
>> Hi Dave,
>>
>> if nobody has a last moment concern please include the following patches in 
>> drm-next.
>>
>> Except for some minor fixes they have already been on the list for quite 
>> some time,
>> but I intentional left out the debugfs related patches cause we haven't 
>> finished the
>> discussion about them yet.
>>
>> If you prefer to merge them directly, I also made them available as 
>> reset-rework
>> branch here: git://people.freedesktop.org/~deathsimple/linux
>>
>> Cheers,
>> Christian.
>>
>
> I am not completely ok, i am against patch 5. I need sometime to review it.
>
> Cheers,
> Jerome

Sorr mean patch 7

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


Re: [RFC v2] Revive the work on render-nodes branch

2012-04-30 Thread Ilija Hadzic



On Fri, 20 Apr 2012, Dave Airlie wrote:


On Thu, Apr 12, 2012 at 7:19 PM, Ilija Hadzic
 wrote:

The following set of patches is the reword of the series
sent two weeks ago [2] that will revive the drm-render-nodes [1]
branch. Details of the original series are described in [2].


Thanks for looking at this,

So one thing about adding render nodes, is it gives us the chance to
maybe change the userspace API we expose to be more secure and have
less cruft in it.

Now I'm weary of a major API redesign as this could bog things now and
we'd never make forward progress, but I'd like to at least consider it
before adding new device nodes and locking us into the old APIs.

The areas suggested before:

1) GEM, drop flink/open ioctls - these make security hard, since once
you share a buffer any GEM opener can get access to it. Solutions to
this proposed before are flink_to and maybe using PRIME/dma-buf.

2) master/device ownership. We might be able to drop the first opener
is magically master, and require openers to ask for it somehow.

3) drop the old map ioctls from this interface, irq by busid, drop the AGP.

I'm not talking about changing ioctl operation, more about introducing
new ioctls and not allowing the old ones on the new nodes.

Dave.



Thanks for the feedback, point taken. So there will be some "homework" to 
be done before you can take in the render nodes work. Would you be 
perceptive to consider taking in some of the prep. patches that I sent in 
my series? They will reduce the amount of baggage that needs to be carried 
with actual render-nodes work and make it easier to keep it alive while 
the above-proposed interface rework is being worked on.


For example, this one is just a simplification that makes 
things more readable:


http://lists.freedesktop.org/archives/dri-devel/2012-April/021327.html

Then these two will make drm_mode_getplane_res more consistent with what 
other getresources calls do (i.e., use drm_mode_group instead of 
drm_mode_config).


http://lists.freedesktop.org/archives/dri-devel/2012-April/021328.html
http://lists.freedesktop.org/archives/dri-devel/2012-April/021329.html

This one won't hurt either and will make things look a little bit more 
straightforward:


http://lists.freedesktop.org/archives/dri-devel/2012-April/021330.html

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


Re: Include request for reset-rework branch.

2012-04-30 Thread Christian König

On 30.04.2012 17:12, Jerome Glisse wrote:

On Mon, Apr 30, 2012 at 11:12 AM, Jerome Glisse  wrote:

On Mon, Apr 30, 2012 at 10:50 AM, Christian König
  wrote:

Hi Dave,

if nobody has a last moment concern please include the following patches in 
drm-next.

Except for some minor fixes they have already been on the list for quite some 
time,
but I intentional left out the debugfs related patches cause we haven't 
finished the
discussion about them yet.

If you prefer to merge them directly, I also made them available as reset-rework
branch here: git://people.freedesktop.org/~deathsimple/linux

Cheers,
Christian.


I am not completely ok, i am against patch 5. I need sometime to review it.

Cheers,
Jerome

Sorr mean patch 7

I just started to wonder :) what's wrong with patch 7?

Please keep in mind that implementing proper locking in the lower level 
objects allows us to remove quite some locking in the upper layers.


By the way, do you mind when I dig into the whole locking stuff of the 
kernel driver a bit more? There seems to be allot of possibilities to 
cleanup and simplify the overall driver.


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


Re: [PATCH 09/26] drm/radeon: add biggest hole tracking and wakequeue to the sa v3

2012-04-30 Thread Jerome Glisse
On Mon, Apr 30, 2012 at 10:50 AM, Christian König
 wrote:
> With that in place clients are automatically blocking
> until their memory request can be handled.
>
> v2: block only if the memory request can't be satisfied
>    in the first try, the first version actually lacked
>    a night of sleep.
>
> v3: make blocking optional, update comments and fix
>    another bug with biggest hole tracking.
>
> Signed-off-by: Christian König 


I would say NAK, the idea of SA allocator is to be like ring buffer, a
ring allocation. All the allocation made through SA are made for
object that life are ring related, ie once allocated the object is
scheduled through one of the ring and once the ring is done consuming
it the object is free. So the idea behind the SA allocator is to make
it simple we keep track of the highest offset used and the lowest one
free, we try to find room above the highest and if we don't have
enough room we try at the begining of the ring (wrap over), idea is
that in most scenario we don't have to wait because SA is big enough
and if we have to wait well it's because GPU is full of things to do
so waiting a bit won't starve the GPU.

That being said current code doesn't exactly reflect that, i can't
remember why. Anyway i would rather make current looks like intented
as i believe it make allocation easy and fast in usual case. There is
also a reason why i intended to have several sa manager. Idea is to
have one SA manager for the VM (because VM might last longer) and one
for all the ring object (semaphore, ib, ...) because usual case is
that all ring sync from time to time and the all progress in //.

Cheers,
Jerome
> ---
>  drivers/gpu/drm/radeon/radeon.h        |    5 +-
>  drivers/gpu/drm/radeon/radeon_gart.c   |    2 +-
>  drivers/gpu/drm/radeon/radeon_object.h |    2 +-
>  drivers/gpu/drm/radeon/radeon_ring.c   |   20 ++--
>  drivers/gpu/drm/radeon/radeon_sa.c     |  211 
> +++-
>  5 files changed, 165 insertions(+), 75 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index 99b188a..e71dc67 100644
> --- a/drivers/gpu/drm/radeon/radeon.h
> +++ b/drivers/gpu/drm/radeon/radeon.h
> @@ -381,17 +381,16 @@ struct radeon_bo_list {
>  * alignment).
>  */
>  struct radeon_sa_manager {
> -       spinlock_t              lock;
> +       wait_queue_head_t       queue;
>        struct radeon_bo        *bo;
>        struct list_head        sa_bo;
>        unsigned                size;
> +       struct list_head        *biggest_hole;
>        uint64_t                gpu_addr;
>        void                    *cpu_ptr;
>        uint32_t                domain;
>  };
>
> -struct radeon_sa_bo;
> -
>  /* sub-allocation buffer */
>  struct radeon_sa_bo {
>        struct list_head                list;
> diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
> b/drivers/gpu/drm/radeon/radeon_gart.c
> index c58a036..7af4ff9 100644
> --- a/drivers/gpu/drm/radeon/radeon_gart.c
> +++ b/drivers/gpu/drm/radeon/radeon_gart.c
> @@ -395,7 +395,7 @@ int radeon_vm_bind(struct radeon_device *rdev, struct 
> radeon_vm *vm)
>  retry:
>        r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager, &vm->sa_bo,
>                             RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8),
> -                            RADEON_GPU_PAGE_SIZE);
> +                            RADEON_GPU_PAGE_SIZE, false);
>        if (r) {
>                if (list_empty(&rdev->vm_manager.lru_vm)) {
>                        return r;
> diff --git a/drivers/gpu/drm/radeon/radeon_object.h 
> b/drivers/gpu/drm/radeon/radeon_object.h
> index d9b9333..85f33d9 100644
> --- a/drivers/gpu/drm/radeon/radeon_object.h
> +++ b/drivers/gpu/drm/radeon/radeon_object.h
> @@ -158,7 +158,7 @@ extern int radeon_sa_bo_manager_suspend(struct 
> radeon_device *rdev,
>  extern int radeon_sa_bo_new(struct radeon_device *rdev,
>                            struct radeon_sa_manager *sa_manager,
>                            struct radeon_sa_bo *sa_bo,
> -                           unsigned size, unsigned align);
> +                           unsigned size, unsigned align, bool block);
>  extern void radeon_sa_bo_free(struct radeon_device *rdev,
>                              struct radeon_sa_bo *sa_bo);
>  #if defined(CONFIG_DEBUG_FS)
> diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
> b/drivers/gpu/drm/radeon/radeon_ring.c
> index 1d9bce9..ccee74f 100644
> --- a/drivers/gpu/drm/radeon/radeon_ring.c
> +++ b/drivers/gpu/drm/radeon/radeon_ring.c
> @@ -124,7 +124,7 @@ retry:
>                if (rdev->ib_pool.ibs[idx].fence == NULL) {
>                        r = radeon_sa_bo_new(rdev, &rdev->ib_pool.sa_manager,
>                                             &rdev->ib_pool.ibs[idx].sa_bo,
> -                                            size, 256);
> +                                            size, 256, false);
>                        if (!r) {
>                                *ib = &rdev->ib_pool.ibs[idx];
>      

Re: [PATCH 07/26] drm/radeon: add proper locking to the SA v2

2012-04-30 Thread Jerome Glisse
On Mon, Apr 30, 2012 at 10:50 AM, Christian König
 wrote:
> Make the suballocator self containing to locking.
>
> v2: split the bugfix into a seperate patch.
>
> Signed-off-by: Christian König 

I would say NAK but i don't have better solution yet to the issue.
Idea is that cs mutex protect the SA, i am trying hard to avoid adding
new lock, in fact i would like to remove more lock and have some idea
for that. I looked at the whole patch set and the issue is with radeon
semaphore allocation in ttm move blit case, all other case have the cs
mutex taken already. So if no better solution than yeah introduce a
new lock.

Cheers,
Jerome

> ---
>  drivers/gpu/drm/radeon/radeon.h    |    1 +
>  drivers/gpu/drm/radeon/radeon_sa.c |   17 +++--
>  2 files changed, 12 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index 92682b7..99b188a 100644
> --- a/drivers/gpu/drm/radeon/radeon.h
> +++ b/drivers/gpu/drm/radeon/radeon.h
> @@ -381,6 +381,7 @@ struct radeon_bo_list {
>  * alignment).
>  */
>  struct radeon_sa_manager {
> +       spinlock_t              lock;
>        struct radeon_bo        *bo;
>        struct list_head        sa_bo;
>        unsigned                size;
> diff --git a/drivers/gpu/drm/radeon/radeon_sa.c 
> b/drivers/gpu/drm/radeon/radeon_sa.c
> index 8fbfe69..4ce5c51 100644
> --- a/drivers/gpu/drm/radeon/radeon_sa.c
> +++ b/drivers/gpu/drm/radeon/radeon_sa.c
> @@ -37,6 +37,7 @@ int radeon_sa_bo_manager_init(struct radeon_device *rdev,
>  {
>        int r;
>
> +       spin_lock_init(&sa_manager->lock);
>        sa_manager->bo = NULL;
>        sa_manager->size = size;
>        sa_manager->domain = domain;
> @@ -136,18 +137,19 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
>        struct radeon_sa_bo *tmp;
>        struct list_head *head;
>        unsigned offset = 0, wasted = 0;
> +       unsigned long flags;
>
>        BUG_ON(align > RADEON_GPU_PAGE_SIZE);
>        BUG_ON(size > sa_manager->size);
> +       spin_lock_irqsave(&sa_manager->lock, flags);
>
>        /* no one ? */
> -       head = sa_manager->sa_bo.prev;
>        if (list_empty(&sa_manager->sa_bo)) {
> +               head = &sa_manager->sa_bo;
>                goto out;
>        }
>
>        /* look for a hole big enough */
> -       offset = 0;
>        list_for_each_entry(tmp, &sa_manager->sa_bo, list) {
>                /* room before this object ? */
>                if (offset < tmp->offset && (tmp->offset - offset) >= size) {
> @@ -157,9 +159,8 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
>                offset = tmp->offset + tmp->size;
>                wasted = offset % align;
>                if (wasted) {
> -                       wasted = align - wasted;
> +                       offset += align - wasted;
>                }
> -               offset += wasted;
>        }
>        /* room at the end ? */
>        head = sa_manager->sa_bo.prev;
> @@ -167,11 +168,11 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
>        offset = tmp->offset + tmp->size;
>        wasted = offset % align;
>        if (wasted) {
> -               wasted = align - wasted;
> +               offset += wasted = align - wasted;
>        }
> -       offset += wasted;
>        if ((sa_manager->size - offset) < size) {
>                /* failed to find somethings big enough */
> +               spin_unlock_irqrestore(&sa_manager->lock, flags);
>                return -ENOMEM;
>        }
>
> @@ -180,10 +181,14 @@ out:
>        sa_bo->offset = offset;
>        sa_bo->size = size;
>        list_add(&sa_bo->list, head);
> +       spin_unlock_irqrestore(&sa_manager->lock, flags);
>        return 0;
>  }
>
>  void radeon_sa_bo_free(struct radeon_device *rdev, struct radeon_sa_bo 
> *sa_bo)
>  {
> +       unsigned long flags;
> +       spin_lock_irqsave(&sa_bo->manager->lock, flags);
>        list_del_init(&sa_bo->list);
> +       spin_unlock_irqrestore(&sa_bo->manager->lock, flags);
>  }
> --
> 1.7.5.4
>
> ___
> 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


Re: Include request for reset-rework branch.

2012-04-30 Thread Jerome Glisse
On Mon, Apr 30, 2012 at 11:37 AM, Christian König
 wrote:
> On 30.04.2012 17:12, Jerome Glisse wrote:
>>
>> On Mon, Apr 30, 2012 at 11:12 AM, Jerome Glisse
>>  wrote:
>>>
>>> On Mon, Apr 30, 2012 at 10:50 AM, Christian König
>>>   wrote:

 Hi Dave,

 if nobody has a last moment concern please include the following patches
 in drm-next.

 Except for some minor fixes they have already been on the list for quite
 some time,
 but I intentional left out the debugfs related patches cause we haven't
 finished the
 discussion about them yet.

 If you prefer to merge them directly, I also made them available as
 reset-rework
 branch here: git://people.freedesktop.org/~deathsimple/linux

 Cheers,
 Christian.

>>> I am not completely ok, i am against patch 5. I need sometime to review
>>> it.
>>>
>>> Cheers,
>>> Jerome
>>
>> Sorr mean patch 7
>
> I just started to wonder :) what's wrong with patch 7?
>
> Please keep in mind that implementing proper locking in the lower level
> objects allows us to remove quite some locking in the upper layers.
>
> By the way, do you mind when I dig into the whole locking stuff of the
> kernel driver a bit more? There seems to be allot of possibilities to
> cleanup and simplify the overall driver.
>
> Cheers,
> Christian.

Well when it comes to lock, i have some kind of an idea i wanted to
work for a while. GPU is transaction based in a sense, we feed rings
and it works on them, 90% of the work is cs ioctl so we should be able
to have one and only one lock (ignoring the whole modesetting path
here for which i believe one lock too is enough). Things like PM would
need to take all lock but hey i believe that's a good thing as my
understanding is PM we do right now need most of the GPU idle.

So here is what we have
ih spinlock (can be ignored ie left as is)
irq spinlock (can be ignored ie left as is)
blit mutex
pm mutex
cs mutex
dc_hw_i2c mutex
vram mutex
ib mutex
rings[] lock

So the real issue is ttm calling back into the driver. So the idea i
had is to have a work thread that is the only one allowed to mess with
the GPU. The work thread would use some locking in which it has
preference over the writer (writer being cs ioctl or ttm call back or
anything else that needs to schedule GPU work). This would require
only two lock. I am actually thinking of having 2 list one where
writer add there "transaction" and one where the worker empty the
transaction, something like:

cs_ioct
{
sa_alloc_for_trans
...
lock(trans_lock)
list_add_tail(trans, trans_temp_list)
unlock(trans_lock)
}

workeur
{
lock(trans_lock)
list_splice_tail(trans_list, trans_temp_list)
unlock(trans_lock)
// schedule ib
...
// process fence & semaphore
}

So there would be one transaction lock and one lock for the
transaction memory allocation (ib, semaphore and alike) The workeur
would also be responsible for GPU reset, there wouldn't be any ring
lock as i believe one worker is enough for all rings.

For transaction the only issue really is ttm, cs is easy it's an
ib+fence+semaphore, ttm can be more complex, it can be bo move, bind,
unbind, ... Anyway it's doable and it's design i had in mind for a
while.

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


Re: [PATCH 05/19] drm: move dev_mapping to the minor node

2012-04-30 Thread Dave Airlie
On Mon, Apr 30, 2012 at 3:48 PM, Ilija Hadzic
 wrote:
>
>
> On Fri, 20 Apr 2012, Dave Airlie wrote:
>
>> On Thu, Apr 12, 2012 at 7:19 PM, Ilija Hadzic
>>  wrote:
>>>
>>> Make dev_mapping per-minor instead of per device. This is
>>> a preparatory patch for introducing render nodes. This
>>> will allow per-node instead of per-device mapping range,
>>> once we introduce render nodes.
>>
>>
>> One problem is this introduces a ttm/drm dependency that we don't
>> really have so far.
>>
>
> Sorry for a belated follow-up (I was busy with something else). I understand
> the concern and I think that the patch can be reworked such that it does not
> introduce the dependency. What introduces the dependency is a call to
> drm_unmap_mapping in ttm_bo_unmap_virtual. If the patch is reworked such
> that the minor tracks i_mapping pointer instead of the whole drm_device
> structure, the need for drm_unmap_mapping may be eliminated, which in turn
> will take care of the dependency.
>
> That brings me to a question for you. The patch from which I derived this is
> your patch 7c5cc4f63556e351e9e5980ed22accad410e3fdc (on your original
> render-nodes branch). That's where you introduced drm_unmap_mapping
> function, which calls unmap_mapping_range for every minor known to the
> system.
>
> Why was that necessary at first place ? I mean we don't do the eqivalent of
> that currently when there are multiple physical GPUs in the system, so I
> don't quite get why introduction of multiple minors would require to go
> through the whole list of minors. If that's a "just in case"/"just to be
> safe" kind of thing, then I think we may be able to just call
> drm_unmap_mapping from the driver that needs to call it and only for the
> minor in question.

When we move a buffer from VRAM->RAM we have to invalidate all
userspace mappings for it.

There could be userspace mappings on any of the device nodes, so we
need to get them all.

I think some of this code could be redone, to be less complex, Al Viro
questions why we weren't just setting the
inode mapping ourselves, citing some references in an fs somewhere
(maybe cifs), I haven't had time to follow up and check.

This would also make the case where you have something else create a
device node inside a chroot.

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


Re: [PATCH 05/19] drm: move dev_mapping to the minor node

2012-04-30 Thread Ilija Hadzic



On Mon, 30 Apr 2012, Dave Airlie wrote:



When we move a buffer from VRAM->RAM we have to invalidate all
userspace mappings for it.

There could be userspace mappings on any of the device nodes, so we
need to get them all.



Ah OK, I get it ... and the reason you don't have to do this when you have 
multiple physical cards, but only one node per card (i.e. current state of 
the code) is that VRAMs of each card are disjoint, so there can't possibly 
be mappings through different /dev/dri/whatever of the same piece of VRAM. 
Multiple render nodes, introduce that possibility.



I think some of this code could be redone, to be less complex, Al Viro
questions why we weren't just setting the
inode mapping ourselves, citing some references in an fs somewhere
(maybe cifs), I haven't had time to follow up and check.

This would also make the case where you have something else create a
device node inside a chroot.



Do you have pointers to that discussion (assuming it was on sime mailing 
list)? The least I can do, while I am at it, is try to understand it and

see if I can incorporate some ideas from there in the rework of the patch.

-- Ilija

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


Re: [PATCH 05/19] drm: move dev_mapping to the minor node

2012-04-30 Thread Dave Airlie
>
> Do you have pointers to that discussion (assuming it was on sime mailing
> list)? The least I can do, while I am at it, is try to understand it and
> see if I can incorporate some ideas from there in the rework of the patch.

Nope it was an offhand discussion on irc while we were talking about
some other ugly code.

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


Re: [PATCH 05/19] drm: move dev_mapping to the minor node

2012-04-30 Thread Dave Airlie
On Mon, Apr 30, 2012 at 6:53 PM, Dave Airlie  wrote:
>>
>> Do you have pointers to that discussion (assuming it was on sime mailing
>> list)? The least I can do, while I am at it, is try to understand it and
>> see if I can incorporate some ideas from there in the rework of the patch.
>
> Nope it was an offhand discussion on irc while we were talking about
> some other ugly code.

Okay I think it was the code in coda,

   if (coda_inode->i_mapping == &coda_inode->i_data)
coda_inode->i_mapping = host_inode->i_mapping;

/* only allow additional mmaps as long as userspace isn't changing
 * the container file on us! */
else if (coda_inode->i_mapping != host_inode->i_mapping) {
spin_unlock(&cii->c_lock);
return -EBUSY;
}

We could use code like that to change the i_mapping, instead of failing.

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


[Bug 49309] New: R600_STREAMOUT is broken

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

 Bug #: 49309
   Summary: R600_STREAMOUT is broken
Classification: Unclassified
   Product: Mesa
   Version: git
  Platform: x86 (IA32)
OS/Version: Linux (All)
Status: NEW
  Severity: normal
  Priority: medium
 Component: Drivers/DRI/R600
AssignedTo: dri-devel@lists.freedesktop.org
ReportedBy: nedan...@gmail.com


Created attachment 60802
  --> https://bugs.freedesktop.org/attachment.cgi?id=60802
glxinfo output

I use drivers from this PPA:
https://launchpad.net/~oibaf/+archive/graphics-drivers/. xserver-xorg-video-ati
version is 1204181041.0bda30, mesa version is 1204271238.6af4c9.

I don't know when it has started but yesterday I discovered that "OpenGL
version string" reports OGL 2.1 instead of 3.0 while using R600_STREAMOUT and
R600_GLSL130.

My GPU is a AMD Radeon HD6570 (TURKS Pro, Northern Islands). If you need other
information, please let me know.

-- 
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: [RFC v2] Revive the work on render-nodes branch

2012-04-30 Thread Kristian Høgsberg
On Fri, Apr 20, 2012 at 6:20 AM, Dave Airlie  wrote:
> On Thu, Apr 12, 2012 at 7:19 PM, Ilija Hadzic
>  wrote:
>> The following set of patches is the reword of the series
>> sent two weeks ago [2] that will revive the drm-render-nodes [1]
>> branch. Details of the original series are described in [2].
>
> Thanks for looking at this,
>
> So one thing about adding render nodes, is it gives us the chance to
> maybe change the userspace API we expose to be more secure and have
> less cruft in it.
>
> Now I'm weary of a major API redesign as this could bog things now and
> we'd never make forward progress, but I'd like to at least consider it
> before adding new device nodes and locking us into the old APIs.
>
> The areas suggested before:
>
> 1) GEM, drop flink/open ioctls - these make security hard, since once
> you share a buffer any GEM opener can get access to it. Solutions to
> this proposed before are flink_to and maybe using PRIME/dma-buf.

Yup, and I retract my flink_to proposal.  Passing the buffer as an fd
has a few benefits over the flink_to idea: 1) we don't have to
establish an id/handle that represents the other process.  We could
use the process ID or the drm magic, but either way we'd need an
initial handshake to pass that id across before we can share buffer.
Not a deal breaker, just awkward.  2) Passing buffers as fds keeps the
buffer alive "in flight".  This allows the sender to send the buffer
and immediately destroy it, if it needs to.

Another thing I'd change for render nodes is to not require
authentication.  We can still protect access to render nodes to local
sessions using file system permissions (ie, you won't be able to ssh
in and start a GPGPU jobs).  Being able to use the drm device doesn't
give you access to the xserver frontbuffer like it did in the DRI1
days.  You can only render to your own buffers and send or receive
buffer handles over sockets.  If we restrict the ioctls to just GEM
and PRIME, I don't think authentication protects anything we couldn't
just use file system permission for instead.

> 2) master/device ownership. We might be able to drop the first opener
> is magically master, and require openers to ask for it somehow.

If we add render nodes that clients are expected to use, we can
restrict access to the legacy drm device node, such that only X can
open it.  That way it wouldn't matter too much whether we keep the
auto-master behavior or not.  I would like to see the root requirement
dropped from the drop and set master ioctls so that you could put X,
weston etc in a group that allows them to open /dev/dri/card0 and not
need root to perform vt switching duties.  Even today there's no need
for the root requirements, certainly drop master is harmless and
setmaster can just be restricted to drm fds that were previously
masters and only when there's no current master.

> 3) drop the old map ioctls from this interface, irq by busid, drop the AGP.

Yup, or another way to put it: what todays mesa needs, minus flink_to,
open, get_magic (this is the only libdrm call in the glx dri and
egl_dri2 loaders btw) , auth_magic, but with the PRIME ioctls added.

> I'm not talking about changing ioctl operation, more about introducing
> new ioctls and not allowing the old ones on the new nodes.

Yup, agree.

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


[Bug 49309] R600_STREAMOUT is broken

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

--- Comment #1 from Marek Olšák  2012-04-30 12:12:08 PDT ---
So what's the issue? The GL version? There's a new requirement for GL3: 4x
multisampling.

-- 
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 49309] R600_STREAMOUT is broken

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

--- Comment #2 from Alexandre Demers  2012-04-30 
15:41:04 PDT ---
(In reply to comment #1)
> So what's the issue? The GL version? There's a new requirement for GL3: 4x
> multisampling.

If Matteo is interested, it's Mesa's commit
8e90913e9f99ff3296a3c3da36e73cd2d4730269
mesa: require GL_MAX_SAMPLES >= 4 for GL 3.0

As noted in commit i965: Claim to support 4 multisamples on gen6+.,
this was missing before.

NOTE: This is a candidate for the 8.0 branch.

Reviewed-by: Kenneth Graunke 


So as you were pointing Marek, this is not a bug and it should be closed as so.

-- 
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 49309] R600_STREAMOUT is broken

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

Alex Deucher  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution||NOTABUG

-- 
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 49309] R600_STREAMOUT is broken

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

--- Comment #3 from Matteo Rapone  2012-04-30 16:19:01 UTC 
---
So is it a missing functionality? Thank you. Sorry if I've wasted your time.

-- 
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 49309] R600_STREAMOUT is broken

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

--- Comment #4 from Alex Deucher  2012-04-30 16:34:16 PDT ---
GL3 requires MSAA which is not yet supported.  GL3 was mistakenly enabled
without it initially.  Dave has a branch with initial support which will be
merged when ready:
http://cgit.freedesktop.org/~airlied/mesa/log/?h=r600g-ms

-- 
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 49321] New: Khronos WebGL conformance test and shadertoy failure

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

 Bug #: 49321
   Summary: Khronos WebGL conformance test and shadertoy failure
Classification: Unclassified
   Product: Mesa
   Version: unspecified
  Platform: Other
OS/Version: All
Status: NEW
  Severity: normal
  Priority: medium
 Component: Drivers/Gallium/r600
AssignedTo: dri-devel@lists.freedesktop.org
ReportedBy: e...@iki.fi


Full report @
http://groups.google.com/group/webgl-driver-testing/browse_thread/thread/14e726ff2da20438

Partial paste from above:


This run was on Ubuntu 10.10 amd64 with self compiled 
Mesa 3.0.2 (+deps, like libdrm 2.4.33 and llvm 3.0), 
Firefox nightly 15.0~a1~hg20120428r92608-0ubuntu1~umd1~lucid 
from http://ppa.launchpad.net/ubuntu-mozilla-daily/ppa/ubuntu 
and Linux 3.1.0. 

Also I notice about half of 
the shaders at  http://www.iquilezles.org/apps/shadertoy/ fail 
(eg. Motion Blur shows just two brown rectangles, Flower 
a flashing green box) 

WebGL Conformance Test Runner 
Version 1.0.1 
Results: (8827 of 8863 passed) 
WebGL Conformance Test Results 
Version 1.0.1 
--- 
User Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0) Gecko/20120425
Firefox/15.0a1 
WebGL VENDOR: Mozilla 
WebGL VERSION: WebGL 1.0 
WebGL RENDERER: Mozilla 
Unmasked VENDOR: undefined 
Unmasked RENDERER: undefined 
WebGL R/G/B/A/Depth/Stencil bits (default config): 8/8/8/8/24/0 
--- 
Test Summary (8863 total tests): 
Tests PASSED: 8827 
Tests FAILED: 36 
Tests TIMED OUT: 0

-- 
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 49322] New: No picture on display connected via Displayport adaptor to HD 7870

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

 Bug #: 49322
   Summary: No picture on display connected via Displayport
adaptor to HD 7870
Classification: Unclassified
   Product: DRI
   Version: XOrg CVS
  Platform: x86-64 (AMD64)
OS/Version: Linux (All)
Status: NEW
  Severity: normal
  Priority: medium
 Component: DRM/Radeon
AssignedTo: dri-devel@lists.freedesktop.org
ReportedBy: briancsch...@gmail.com


Created attachment 60820
  --> https://bugs.freedesktop.org/attachment.cgi?id=60820
dmesg output

Radeon HD 7870
mesa 8.0.2
Kernel 3.4-rc5
X.Org X Server 1.12.0
xf86-video-modesetting 0.2.0

* Monitor is a DVI monitor connected to an active mini-displayport to DVI
adaptor.
* Output to all three screens functions in Windows.
* dmesg output and xrandr output are able to see the display and print out the
correct supported resolutions
* HDMI and DVI output are functioning correctly on the card.
* Using xrandr I'm able to get the X server to think that the display is
present and functioning. (I can place windows and the cursor on the screen)
* The display is in power-saving mode from the moment that the framebuffer
console initializes. I'm not able to get any image on it.

-- 
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: [PATCH RESEND] egl-fbdev: Fix compile-error by including errno.h

2012-04-30 Thread Kristian Hoegsberg
On Sun, Apr 29, 2012 at 11:53:16AM +0200, David Herrmann wrote:
> We use errno and EINVAL so include errno.h.
> 
> This patch introduced this bug:
> http://cgit.freedesktop.org/mesa/mesa/commit/src/gallium/state_trackers/egl/fbdev/native_fbdev.c?id=b60120608f6ddf4098bc324363197c979ee04cb7
> 
> Signed-off-by: David Herrmann 
> Cc: Chia-I Wu 
> Cc: Dave Airlie 
> Cc: Adam Jackson 
> Cc: Jesse Barnes 
> ---
> I've CC'ed everyone who reviewed/applied the patch that broke fbdev. 
> Hopefully,
> someone can apply it this time.

Thanks, applied.
Kristian

>  src/gallium/state_trackers/egl/fbdev/native_fbdev.c |1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c 
> b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c
> index b45ab5c..b17a8ce 100644
> --- a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c
> +++ b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c
> @@ -41,6 +41,7 @@
>   *  - no pixmap support
>   */
>  
> +#include 
>  #include 
>  #include 
>  #include 
> -- 
> 1.7.10
> 
> ___
> 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


[PATCH] drm/nouveau/hdmi: Fix chipset check for HDMI sound

2012-04-30 Thread Ben Skeggs
On Sun, 2012-04-29 at 20:12 +0200, Alexander Stein wrote:
> NVIDIA Corporation C77 [GeForce 8300] (rev a2) has chipset 0xaa which
> supports HDMI Audio.
This was fixed in nouveau git already a few days ago:

http://cgit.freedesktop.org/nouveau/linux-2.6/commit/?id=2c421e3ad2672e1253abca6387ccbb10cf422717

Cheers,
Ben.

> 
> Signed-off-by: Alexander Stein 
> ---
>  drivers/gpu/drm/nouveau/nouveau_hdmi.c |4 +++-
>  1 files changed, 3 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/gpu/drm/nouveau/nouveau_hdmi.c 
> b/drivers/gpu/drm/nouveau/nouveau_hdmi.c
> index 59ea1c1..2feafaa 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_hdmi.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_hdmi.c
> @@ -32,7 +32,9 @@ static bool
>  hdmi_sor(struct drm_encoder *encoder)
>  {
>   struct drm_nouveau_private *dev_priv = encoder->dev->dev_private;
> - if (dev_priv->chipset < 0xa3)
> + int chipset = dev_priv->chipset;
> +
> + if (chipset < 0xa3 || chipset == 0xaa || chipset == 0xa)
>   return false;
>   return true;
>  }




Linux 3.4-rc4

2012-04-30 Thread Maarten Maathuis
On Mon, Apr 30, 2012 at 12:37 AM, Dmitry Torokhov
 wrote:
> On Sat, Apr 28, 2012 at 11:33:50AM -0400, Nick Bowler wrote:
>> On 2012-04-28 02:19 -0400, Alex Deucher wrote:
>> > On Fri, Apr 27, 2012 at 8:39 PM, Nick Bowler  
>> > wrote:
>> > > Hi Ben,
>> > >
>> > > On 2012-04-27 15:20 +1000, Ben Skeggs wrote:
>> > >> Does this patch help you at all?
>> > >>
>> > >> http://cgit.freedesktop.org/nouveau/linux-2.6/commit/?id=a3a285f17867f0018de798b5ee85731ec1268305
>> > >
>> > > Yes. ?I cherry-picked this patch on top of Linus' master (3.4-rc4+) and
>> > > this appears to solve the "black screen on VGA" problem described in the
>> > > original report. ?Thanks!
>> > >
>> > > Unfortunately, that's not the end of my VGA-related regressions. :(
>> > >
>> > > While tracking down the black screen issue, I've been having the monitor
>> > > directly connected to the video card the whole time, but now when I'm
>> > > connected through my KVM switch (an IOGear GCS1804), it appears that
>> > > something's going wrong with reading the EDID, because the available
>> > > modes are all screwed up (both console and X decide they want to drive
>> > > the display at 1024x768). ?Here's the output of xrandr on 3.2.15:
>> > >
>> > > ?% xrandr
>> > > ?Screen 1: minimum 320 x 200, current 1600 x 1200, maximum 4096 x 4096
>> > > ?VGA-1 connected 1600x1200+0+0 (normal left inverted right x axis y 
>> > > axis) 352mm x 264mm
>> > > ? ? 1600x1200 ? ? ?75.0*+ ? 70.0 ? ? 65.0 ? ? 60.0
>> > > ? ? 1280x1024 ? ? ?85.0 + ? 75.0 ? ? 60.0
>> > > ? ? 1920x1440 ? ? ?60.0
>> > > ? ? 1856x1392 ? ? ?60.0
>> > > ? ? 1792x1344 ? ? ?60.0
>> > > ? ? 1920x1200 ? ? ?74.9 ? ? 59.9
>> > > ? ? 1680x1050 ? ? ?84.9 ? ? 74.9 ? ? 60.0
>> > > ? ? 1400x1050 ? ? ?85.0 ? ? 74.9 ? ? 60.0
>> > > ? ? 1440x900 ? ? ? 84.8 ? ? 75.0 ? ? 59.9
>> > > ? ? 1280x960 ? ? ? 85.0 ? ? 60.0
>> > > ? ? 1360x768 ? ? ? 60.0
>> > > ? ? 1280x800 ? ? ? 84.9 ? ? 74.9 ? ? 59.8
>> > > ? ? 1152x864 ? ? ? 75.0
>> > > ? ? 1280x768 ? ? ? 84.8 ? ? 74.9 ? ? 59.9
>> > > ? ? 1024x768 ? ? ? 85.0 ? ? 75.1 ? ? 75.0 ? ? 70.1 ? ? 60.0 ? ? 43.5 ? ? 
>> > > 43.5
>> > > ? ? 832x624 ? ? ? ?74.6
>> > > ? ? 800x600 ? ? ? ?85.1 ? ? 72.2 ? ? 75.0 ? ? 60.3 ? ? 56.2
>> > > ? ? 848x480 ? ? ? ?60.0
>> > > ? ? 640x480 ? ? ? ?85.0 ? ? 75.0 ? ? 72.8 ? ? 72.8 ? ? 66.7 ? ? 60.0 ? ? 
>> > > 59.9
>> > > ? ? 720x400 ? ? ? ?85.0 ? ? 87.8 ? ? 70.1
>> > > ? ? 640x400 ? ? ? ?85.1
>> > > ? ? 640x350 ? ? ? ?85.1
>> > > ? ? 320x200 ? ? ? 165.1
>> > >
>> > > And on 3.4-rc4+ (with your patch cherry-picked):
>> > >
>> > > ?% xrandr
>> > > ?Screen 1: minimum 320 x 200, current 1024 x 768, maximum 4096 x 4096
>> > > ?VGA-1 connected 1024x768+0+0 (normal left inverted right x axis y axis) 
>> > > 0mm x 0mm
>> > > ? ? 1024x768 ? ? ? 60.0*
>> > > ? ? 800x600 ? ? ? ?60.3 ? ? 56.2
>> > > ? ? 848x480 ? ? ? ?60.0
>> > > ? ? 640x480 ? ? ? ?59.9
>> > > ? ? 320x200 ? ? ? 165.1
>> > >
>> > > Running xrandr on 3.4-rc4+ also causes the screen to go black for a
>> > > second when it does not on 3.2.15. ?It also causes several messages of
>> > > the form
>> > >
>> > > ?[drm] nouveau :01:00.0: Load detected on output B
>> > >
>> > > to be logged. ?Also, looking at /sys/class/drm/card0-VGA-1/edid I see
>> > > that it is empty on 3.4-rc4+ and it is correct on 3.2.15. ?Things seem
>> > > to work OK when the KVM is not involved.
>> >
>> > Were you ever able to fetch a EDID with the KVM involved? ?KVMs are
>> > notorious for not connecting the ddc pins.
>>
>> Yes, it works on 3.2.15 as described above.
>
> I have the same (or similar) KVM (not in the office at the moment) and I
> can confirm that with newer kernels EDID fecthing in flaky. It's 50/50
> if EDED retrieval succeeds or if it fails with:
>
> Apr 26 13:06:57 dtor-d630 kernel: [13464.936336] [drm:drm_edid_block_valid] 
> *ERROR* EDID checksum is invalid, remainder is 208
> Apr 26 13:06:57 dtor-d630 kernel: [13464.955317] [drm:drm_edid_block_valid] 
> *ERROR* EDID checksum is invalid, remainder is 208
> Apr 26 13:06:57 dtor-d630 kernel: [13464.973879] [drm:drm_edid_block_valid] 
> *ERROR* EDID checksum is invalid, remainder is 208
> Apr 27 09:13:03 dtor-d630 kernel: [44602.087659] [drm:drm_edid_block_valid] 
> *ERROR* EDID checksum is invalid, remainder is 208
> Apr 27 09:13:03 dtor-d630 kernel: [44602.107147] [drm:drm_edid_block_valid] 
> *ERROR* EDID checksum is invalid, remainder is 208
> Apr 27 09:13:03 dtor-d630 kernel: [44602.126908] [drm:drm_edid_block_valid] 
> *ERROR* EDID checksum is invalid, remainder is 208
> Apr 27 09:13:03 dtor-d630 kernel: [44602.146277] [drm:drm_edid_block_valid] 
> *ERROR* EDID checksum is invalid, remainder is 208
> Apr 27 09:13:03 dtor-d630 kernel: [44602.297659] [drm:drm_edid_block_valid] 
> *ERROR* EDID checksum is invalid, remainder is 208
> Apr 27 09:13:03 dtor-d630 kernel: [44602.317063] [drm:drm_edid_block_valid] 
> *ERROR* EDID checksum is invalid, remainder is 208
>
> Earlier kernels were able to retrieve EDEDs reliably.
>
> This is with:
>
> [ ? ?1.678

[Bug 48880] Set mode has different timings than requested on VGA

2012-04-30 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=48880

Florian Mickler  changed:

   What|Removed |Added

 CC||florian at mickler.org

--- Comment #27 from Florian Mickler  2012-04-30 
02:53:36 PDT ---
A patch referencing this bug report has been merged in Linux v3.4-rc5:

commit 37d4174d2d252c37dcb3d88cafae488542087848
Author: Alex Deucher 
Date:   Thu Apr 19 10:48:38 2012 -0400

drm/radeon/kms: use frac fb div on APUs

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


[Bug 42490] NUTMEG DP to VGA bridge not working

2012-04-30 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=42490

Florian Mickler  changed:

   What|Removed |Added

 CC||florian at mickler.org

--- Comment #27 from Florian Mickler  2012-04-30 
02:54:28 PDT ---
A patch referencing this bug report has been merged in Linux v3.4-rc5:

commit 700698e7c303f5095107c62a81872c2c3dad1702
Author: Alex Deucher 
Date:   Fri Apr 27 17:18:59 2012 -0400

drm/radeon/kms: need to set up ss on DP bridges as well

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


DVI/VGA/HDI mess on Radeon HD 6570

2012-04-30 Thread Boszormenyi Zoltan
2011-12-19 19:31 keltez?ssel, Adam Jackson ?rta:
> On Mon, 2011-12-19 at 18:56 +0100, Boszormenyi Zoltan wrote:
>
>> Thanks. As I am logged in as my user, there's no such button.
>> How can I set it as the system default? It was a long time ago
>> when GNOME allowed a root login.
> Ideally, gnome would implement that button.
>
> Failing that you can set Option "Primary" for the appropriate monitor
> section in xorg.conf.
>
> - ajax

I have found a way to match GDM's behaviour to what I have
set in my session. This is embarrassingly simple. After setting
up the monitors in the GNOME display applet:

sudo cp ~/.config/monitors.xml /var/lib/gdm/.config/

Next time GDM restarted, it behaved the way I set up.

Best regards,
Zolt?n B?sz?rm?nyi



Linux 3.4-rc4

2012-04-30 Thread Luca Tettamanti
On Mon, Apr 30, 2012 at 11:07 AM, Maarten Maathuis  
wrote:
> On Mon, Apr 30, 2012 at 12:37 AM, Dmitry Torokhov
>  wrote:
>> On Sat, Apr 28, 2012 at 11:33:50AM -0400, Nick Bowler wrote:
>>> On 2012-04-28 02:19 -0400, Alex Deucher wrote:
>>> > On Fri, Apr 27, 2012 at 8:39 PM, Nick Bowler >> > elliptictech.com> wrote:
>>> > > Hi Ben,
>>> > >
>>> > > On 2012-04-27 15:20 +1000, Ben Skeggs wrote:
>>> > >> Does this patch help you at all?
>>> > >>
>>> > >> http://cgit.freedesktop.org/nouveau/linux-2.6/commit/?id=a3a285f17867f0018de798b5ee85731ec1268305
>>> > >
>>> > > Yes. ?I cherry-picked this patch on top of Linus' master (3.4-rc4+) and
>>> > > this appears to solve the "black screen on VGA" problem described in the
>>> > > original report. ?Thanks!
>>> > >
>>> > > Unfortunately, that's not the end of my VGA-related regressions. :(
>>> > >
>>> > > While tracking down the black screen issue, I've been having the monitor
>>> > > directly connected to the video card the whole time, but now when I'm
>>> > > connected through my KVM switch (an IOGear GCS1804), it appears that
>>> > > something's going wrong with reading the EDID, because the available
>>> > > modes are all screwed up (both console and X decide they want to drive
>>> > > the display at 1024x768). ?Here's the output of xrandr on 3.2.15:
>>> > >
>>> > > ?% xrandr
>>> > > ?Screen 1: minimum 320 x 200, current 1600 x 1200, maximum 4096 x 4096
>>> > > ?VGA-1 connected 1600x1200+0+0 (normal left inverted right x axis y 
>>> > > axis) 352mm x 264mm
>>> > > ? ? 1600x1200 ? ? ?75.0*+ ? 70.0 ? ? 65.0 ? ? 60.0
>>> > > ? ? 1280x1024 ? ? ?85.0 + ? 75.0 ? ? 60.0
>>> > > ? ? 1920x1440 ? ? ?60.0
>>> > > ? ? 1856x1392 ? ? ?60.0
>>> > > ? ? 1792x1344 ? ? ?60.0
>>> > > ? ? 1920x1200 ? ? ?74.9 ? ? 59.9
>>> > > ? ? 1680x1050 ? ? ?84.9 ? ? 74.9 ? ? 60.0
>>> > > ? ? 1400x1050 ? ? ?85.0 ? ? 74.9 ? ? 60.0
>>> > > ? ? 1440x900 ? ? ? 84.8 ? ? 75.0 ? ? 59.9
>>> > > ? ? 1280x960 ? ? ? 85.0 ? ? 60.0
>>> > > ? ? 1360x768 ? ? ? 60.0
>>> > > ? ? 1280x800 ? ? ? 84.9 ? ? 74.9 ? ? 59.8
>>> > > ? ? 1152x864 ? ? ? 75.0
>>> > > ? ? 1280x768 ? ? ? 84.8 ? ? 74.9 ? ? 59.9
>>> > > ? ? 1024x768 ? ? ? 85.0 ? ? 75.1 ? ? 75.0 ? ? 70.1 ? ? 60.0 ? ? 43.5 ? 
>>> > > ? 43.5
>>> > > ? ? 832x624 ? ? ? ?74.6
>>> > > ? ? 800x600 ? ? ? ?85.1 ? ? 72.2 ? ? 75.0 ? ? 60.3 ? ? 56.2
>>> > > ? ? 848x480 ? ? ? ?60.0
>>> > > ? ? 640x480 ? ? ? ?85.0 ? ? 75.0 ? ? 72.8 ? ? 72.8 ? ? 66.7 ? ? 60.0 ? 
>>> > > ? 59.9
>>> > > ? ? 720x400 ? ? ? ?85.0 ? ? 87.8 ? ? 70.1
>>> > > ? ? 640x400 ? ? ? ?85.1
>>> > > ? ? 640x350 ? ? ? ?85.1
>>> > > ? ? 320x200 ? ? ? 165.1
>>> > >
>>> > > And on 3.4-rc4+ (with your patch cherry-picked):
>>> > >
>>> > > ?% xrandr
>>> > > ?Screen 1: minimum 320 x 200, current 1024 x 768, maximum 4096 x 4096
>>> > > ?VGA-1 connected 1024x768+0+0 (normal left inverted right x axis y 
>>> > > axis) 0mm x 0mm
>>> > > ? ? 1024x768 ? ? ? 60.0*
>>> > > ? ? 800x600 ? ? ? ?60.3 ? ? 56.2
>>> > > ? ? 848x480 ? ? ? ?60.0
>>> > > ? ? 640x480 ? ? ? ?59.9
>>> > > ? ? 320x200 ? ? ? 165.1
>>> > >
>>> > > Running xrandr on 3.4-rc4+ also causes the screen to go black for a
>>> > > second when it does not on 3.2.15. ?It also causes several messages of
>>> > > the form
>>> > >
>>> > > ?[drm] nouveau :01:00.0: Load detected on output B
>>> > >
>>> > > to be logged. ?Also, looking at /sys/class/drm/card0-VGA-1/edid I see
>>> > > that it is empty on 3.4-rc4+ and it is correct on 3.2.15. ?Things seem
>>> > > to work OK when the KVM is not involved.
>>> >
>>> > Were you ever able to fetch a EDID with the KVM involved? ?KVMs are
>>> > notorious for not connecting the ddc pins.
>>>
>>> Yes, it works on 3.2.15 as described above.
>>
>> I have the same (or similar) KVM (not in the office at the moment) and I
>> can confirm that with newer kernels EDID fecthing in flaky. It's 50/50
>> if EDED retrieval succeeds or if it fails with:
>>
>> Apr 26 13:06:57 dtor-d630 kernel: [13464.936336] [drm:drm_edid_block_valid] 
>> *ERROR* EDID checksum is invalid, remainder is 208
>> Apr 26 13:06:57 dtor-d630 kernel: [13464.955317] [drm:drm_edid_block_valid] 
>> *ERROR* EDID checksum is invalid, remainder is 208
>> Apr 26 13:06:57 dtor-d630 kernel: [13464.973879] [drm:drm_edid_block_valid] 
>> *ERROR* EDID checksum is invalid, remainder is 208
>> Apr 27 09:13:03 dtor-d630 kernel: [44602.087659] [drm:drm_edid_block_valid] 
>> *ERROR* EDID checksum is invalid, remainder is 208
>> Apr 27 09:13:03 dtor-d630 kernel: [44602.107147] [drm:drm_edid_block_valid] 
>> *ERROR* EDID checksum is invalid, remainder is 208
>> Apr 27 09:13:03 dtor-d630 kernel: [44602.126908] [drm:drm_edid_block_valid] 
>> *ERROR* EDID checksum is invalid, remainder is 208
>> Apr 27 09:13:03 dtor-d630 kernel: [44602.146277] [drm:drm_edid_block_valid] 
>> *ERROR* EDID checksum is invalid, remainder is 208
>> Apr 27 09:13:03 dtor-d630 kernel: [44602.297659] [drm:drm_edid_block_valid] 
>> *ERROR* EDID checksum is invalid, remainder is 208
>> Apr 27 09:13:03 dtor-d630 kernel: [4460

[Bug 49281] radeon: black screen on resume from suspend

2012-04-30 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=49281

Alex Deucher  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution||DUPLICATE

--- Comment #1 from Alex Deucher  2012-04-30 05:26:56 PDT 
---


*** This bug has been marked as a duplicate of bug 43829 ***

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


[Bug 43829] Resuming my AMD A4-3300 based laptop leaves the screen black

2012-04-30 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=43829

Alex Deucher  changed:

   What|Removed |Added

 CC||vimregisters at gmail.com

--- Comment #7 from Alex Deucher  2012-04-30 05:26:56 PDT 
---
*** Bug 49281 has been marked as a duplicate of this bug. ***

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


[Bug 48880] Set mode has different timings than requested on VGA

2012-04-30 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=48880

Alex Deucher  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution||FIXED

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


[next][PATCH 0/3] radeon HDMI: next minor improvements

2012-04-30 Thread Rafał Miłecki
This is one more patchset bringing minor improvements to the current
HDMI implementation. I think after this step I'll start working on
moving Evergreen HDMI code to the separated file. Some cleanups and
making ACR re-usable were needed before that.

Patches depend on the earlier 5-patches-set I sent yesterday.

Again, tested on RV620 and HD6320. Unfortunately I don't have DCE32
card or sth to test code in r600_hdmi_enable/r600_hdmi_disable (pre
DCE3).

P.S.
I'm leaving civilization for the rest of this week.

Rafa? Mi?ecki (3):
  drm/radeon/kms/hdmi: enable audio packets at one place
  drm/radeon/kms/hdmi: clean&improve handling HDMI mode
  drm/radeon/kms/hdmi: helper getting ready ACR entry

 drivers/gpu/drm/radeon/r600_hdmi.c |  129 +++
 drivers/gpu/drm/radeon/radeon.h|   14 
 2 files changed, 84 insertions(+), 59 deletions(-)

-- 
1.7.7



[next][PATCH 1/3] drm/radeon/kms/hdmi: enable audio packets at one place

2012-04-30 Thread Rafał Miłecki
---
 drivers/gpu/drm/radeon/r600_hdmi.c |   26 --
 1 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c 
b/drivers/gpu/drm/radeon/r600_hdmi.c
index c6de0022..69839df 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -303,11 +303,13 @@ void r600_hdmi_audio_workaround(struct drm_encoder 
*encoder)
r600_hdmi_is_audio_buffer_filled(encoder)) {

/* disable audio workaround */
-   WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, 0x0001, ~0x1001);
+   WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset,
+0, ~HDMI0_AUDIO_TEST_EN);

} else {
/* enable audio workaround */
-   WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, 0x1001, ~0x1001);
+   WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset,
+HDMI0_AUDIO_TEST_EN, ~HDMI0_AUDIO_TEST_EN);
}
 }

@@ -331,6 +333,18 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct 
drm_display_mode *mod

WREG32(HDMI0_AUDIO_CRC_CONTROL + offset, 0x1000);
WREG32(HDMI0_GC + offset, 0x0);
+
+   /* Send audio packets */
+   if (ASIC_IS_DCE4(rdev))
+   WREG32_P(0x74fc + offset,
+AFMT_AUDIO_SAMPLE_SEND, ~AFMT_AUDIO_SAMPLE_SEND);
+   else if (ASIC_IS_DCE32(rdev))
+   WREG32_P(AFMT_AUDIO_PACKET_CONTROL + offset,
+AFMT_AUDIO_SAMPLE_SEND, ~AFMT_AUDIO_SAMPLE_SEND);
+   else
+   WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset,
+HDMI0_AUDIO_SAMPLE_SEND, ~HDMI0_AUDIO_SAMPLE_SEND);
+
WREG32(HDMI0_ACR_PACKET_CONTROL + offset, 0x1000);

r600_hdmi_update_ACR(encoder, mode->clock);
@@ -495,10 +509,6 @@ void r600_hdmi_enable(struct drm_encoder *encoder)
offset = radeon_encoder->hdmi_offset;
if (ASIC_IS_DCE5(rdev)) {
/* TODO */
-   } else if (ASIC_IS_DCE4(rdev)) {
-   WREG32_P(0x74fc + radeon_encoder->hdmi_offset, 0x1, ~0x1);
-   } else if (ASIC_IS_DCE32(rdev)) {
-   WREG32_P(AFMT_AUDIO_PACKET_CONTROL + 
radeon_encoder->hdmi_offset, 0x1, ~0x1);
} else if (ASIC_IS_DCE3(rdev)) {
/* TODO */
} else if (rdev->family >= CHIP_R600) {
@@ -558,10 +568,6 @@ void r600_hdmi_disable(struct drm_encoder *encoder)

if (ASIC_IS_DCE5(rdev)) {
/* TODO */
-   } else if (ASIC_IS_DCE4(rdev)) {
-   WREG32_P(0x74fc + radeon_encoder->hdmi_offset, 0, ~0x1);
-   } else if (ASIC_IS_DCE32(rdev)) {
-   WREG32_P(AFMT_AUDIO_PACKET_CONTROL + 
radeon_encoder->hdmi_offset, 0, ~0x1);
} else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
-- 
1.7.7



[next][PATCH 2/3] drm/radeon/kms/hdmi: clean&improve handling HDMI mode

2012-04-30 Thread Rafał Miłecki
---
 drivers/gpu/drm/radeon/r600_hdmi.c |   42 +++
 1 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c 
b/drivers/gpu/drm/radeon/r600_hdmi.c
index 69839df..7d24753 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -493,6 +493,7 @@ void r600_hdmi_enable(struct drm_encoder *encoder)
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
uint32_t offset;
+   u32 hdmi;

if (ASIC_IS_DCE5(rdev))
return;
@@ -507,26 +508,34 @@ void r600_hdmi_enable(struct drm_encoder *encoder)
}

offset = radeon_encoder->hdmi_offset;
-   if (ASIC_IS_DCE5(rdev)) {
-   /* TODO */
-   } else if (ASIC_IS_DCE3(rdev)) {
-   /* TODO */
-   } else if (rdev->family >= CHIP_R600) {
+
+   /* Older chipsets require setting HDMI and routing manually */
+   if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
+   hdmi = HDMI0_ERROR_ACK | HDMI0_ENABLE;
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
WREG32_P(AVIVO_TMDSA_CNTL, AVIVO_TMDSA_CNTL_HDMI_EN,
 ~AVIVO_TMDSA_CNTL_HDMI_EN);
-   WREG32(HDMI0_CONTROL + offset, 0x101);
+   hdmi |= HDMI0_STREAM(HDMI0_STREAM_TMDSA);
break;
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
WREG32_P(AVIVO_LVTMA_CNTL, AVIVO_LVTMA_CNTL_HDMI_EN,
 ~AVIVO_LVTMA_CNTL_HDMI_EN);
-   WREG32(HDMI0_CONTROL + offset, 0x105);
+   hdmi |= HDMI0_STREAM(HDMI0_STREAM_LVTMA);
+   break;
+   case ENCODER_OBJECT_ID_INTERNAL_DDI:
+   WREG32_P(DDIA_CNTL, DDIA_HDMI_EN, ~DDIA_HDMI_EN);
+   hdmi |= HDMI0_STREAM(HDMI0_STREAM_DDIA);
+   break;
+   case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+   hdmi |= HDMI0_STREAM(HDMI0_STREAM_DVOA);
break;
default:
-   dev_err(rdev->dev, "Unknown HDMI output type\n");
+   dev_err(rdev->dev, "Invalid encoder for HDMI: 0x%X\n",
+   radeon_encoder->encoder_id);
break;
}
+   WREG32(HDMI0_CONTROL + offset, hdmi);
}

if (rdev->irq.installed) {
@@ -565,25 +574,28 @@ void r600_hdmi_disable(struct drm_encoder *encoder)
rdev->irq.afmt[offset == 0 ? 0 : 1] = false;
radeon_irq_set(rdev);

-
-   if (ASIC_IS_DCE5(rdev)) {
-   /* TODO */
-   } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
+   /* Older chipsets not handled by AtomBIOS */
+   if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
WREG32_P(AVIVO_TMDSA_CNTL, 0,
 ~AVIVO_TMDSA_CNTL_HDMI_EN);
-   WREG32(HDMI0_CONTROL + offset, 0);
break;
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
WREG32_P(AVIVO_LVTMA_CNTL, 0,
 ~AVIVO_LVTMA_CNTL_HDMI_EN);
-   WREG32(HDMI0_CONTROL + offset, 0);
+   break;
+   case ENCODER_OBJECT_ID_INTERNAL_DDI:
+   WREG32_P(DDIA_CNTL, 0, ~DDIA_HDMI_EN);
+   break;
+   case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
break;
default:
-   dev_err(rdev->dev, "Unknown HDMI output type\n");
+   dev_err(rdev->dev, "Invalid encoder for HDMI: 0x%X\n",
+   radeon_encoder->encoder_id);
break;
}
+   WREG32(HDMI0_CONTROL + offset, HDMI0_ERROR_ACK);
}

radeon_encoder->hdmi_enabled = false;
-- 
1.7.7



[next][PATCH 3/3] drm/radeon/kms/hdmi: helper getting ready ACR entry

2012-04-30 Thread Rafał Miłecki
---
 drivers/gpu/drm/radeon/r600_hdmi.c |   61 
 drivers/gpu/drm/radeon/radeon.h|   14 
 2 files changed, 41 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c 
b/drivers/gpu/drm/radeon/r600_hdmi.c
index 7d24753..0319619 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -53,19 +53,7 @@ enum r600_hdmi_iec_status_bits {
AUDIO_STATUS_LEVEL= 0x80
 };

-struct {
-   uint32_t Clock;
-
-   int N_32kHz;
-   int CTS_32kHz;
-
-   int N_44_1kHz;
-   int CTS_44_1kHz;
-
-   int N_48kHz;
-   int CTS_48kHz;
-
-} r600_hdmi_ACR[] = {
+struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = {
 /*  32kHz44.1kHz   48kHz*/
 /* Clock  N CTS  N CTS  N CTS */
 {  25174,  4576,  28125,  7007,  31250,  6864,  28125 }, /*  25,20/1.001 
MHz */
@@ -84,7 +72,7 @@ struct {
 /*
  * calculate CTS value if it's not found in the table
  */
-static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int N, int freq)
+static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int N, int freq)
 {
if (*CTS == 0)
*CTS = clock * N / (128 * freq) * 1000;
@@ -92,6 +80,24 @@ static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int 
N, int freq)
  N, *CTS, freq);
 }

+struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock)
+{
+   struct radeon_hdmi_acr res;
+   u8 i;
+
+   for (i = 0; r600_hdmi_predefined_acr[i].clock != clock &&
+r600_hdmi_predefined_acr[i].clock != 0; i++)
+   ;
+   res = r600_hdmi_predefined_acr[i];
+
+   /* In case some CTS are missing */
+   r600_hdmi_calc_cts(clock, &res.cts_32khz, res.n_32khz, 32000);
+   r600_hdmi_calc_cts(clock, &res.cts_44_1khz, res.n_44_1khz, 44100);
+   r600_hdmi_calc_cts(clock, &res.cts_48khz, res.n_48khz, 48000);
+
+   return res;
+}
+
 /*
  * update the N and CTS parameters for a given pixel clock rate
  */
@@ -99,30 +105,17 @@ static void r600_hdmi_update_ACR(struct drm_encoder 
*encoder, uint32_t clock)
 {
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
+   struct radeon_hdmi_acr acr = r600_hdmi_acr(clock);
uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
-   int CTS;
-   int N;
-   int i;
-
-   for (i = 0; r600_hdmi_ACR[i].Clock != clock && r600_hdmi_ACR[i].Clock 
!= 0; i++);

-   CTS = r600_hdmi_ACR[i].CTS_32kHz;
-   N = r600_hdmi_ACR[i].N_32kHz;
-   r600_hdmi_calc_CTS(clock, &CTS, N, 32000);
-   WREG32(HDMI0_ACR_32_0 + offset, HDMI0_ACR_CTS_32(CTS));
-   WREG32(HDMI0_ACR_32_1 + offset, N);
+   WREG32(HDMI0_ACR_32_0 + offset, HDMI0_ACR_CTS_32(acr.cts_32khz));
+   WREG32(HDMI0_ACR_32_1 + offset, acr.n_32khz);

-   CTS = r600_hdmi_ACR[i].CTS_44_1kHz;
-   N = r600_hdmi_ACR[i].N_44_1kHz;
-   r600_hdmi_calc_CTS(clock, &CTS, N, 44100);
-   WREG32(HDMI0_ACR_44_0 + offset, HDMI0_ACR_CTS_44(CTS));
-   WREG32(HDMI0_ACR_44_1 + offset, N);
+   WREG32(HDMI0_ACR_44_0 + offset, HDMI0_ACR_CTS_44(acr.cts_44_1khz));
+   WREG32(HDMI0_ACR_44_1 + offset, acr.n_44_1khz);

-   CTS = r600_hdmi_ACR[i].CTS_48kHz;
-   N = r600_hdmi_ACR[i].N_48kHz;
-   r600_hdmi_calc_CTS(clock, &CTS, N, 48000);
-   WREG32(HDMI0_ACR_48_0 + offset, HDMI0_ACR_CTS_48(CTS));
-   WREG32(HDMI0_ACR_48_1 + offset, N);
+   WREG32(HDMI0_ACR_48_0 + offset, HDMI0_ACR_CTS_48(acr.cts_48khz));
+   WREG32(HDMI0_ACR_48_1 + offset, acr.n_48khz);
 }

 /*
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 610acee..71779c8 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1860,6 +1860,20 @@ int r600_fmt_get_nblocksy(u32 format, u32 h);
 /*
  * r600 functions used by radeon_encoder.c
  */
+struct radeon_hdmi_acr {
+   u32 clock;
+
+   int n_32khz;
+   int cts_32khz;
+
+   int n_44_1khz;
+   int cts_44_1khz;
+
+   int n_48khz;
+   int cts_48khz;
+
+};
+
 extern void r600_hdmi_enable(struct drm_encoder *encoder);
 extern void r600_hdmi_disable(struct drm_encoder *encoder);
 extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct 
drm_display_mode *mode);
-- 
1.7.7



[PATCH 05/19] drm: move dev_mapping to the minor node

2012-04-30 Thread Ilija Hadzic


On Fri, 20 Apr 2012, Dave Airlie wrote:

> On Thu, Apr 12, 2012 at 7:19 PM, Ilija Hadzic
>  wrote:
>> Make dev_mapping per-minor instead of per device. This is
>> a preparatory patch for introducing render nodes. This
>> will allow per-node instead of per-device mapping range,
>> once we introduce render nodes.
>
> One problem is this introduces a ttm/drm dependency that we don't
> really have so far.
>

Sorry for a belated follow-up (I was busy with something else). I 
understand the concern and I think that the patch can be reworked such 
that it does not introduce the dependency. What introduces the dependency 
is a call to drm_unmap_mapping in ttm_bo_unmap_virtual. If the patch is 
reworked such that the minor tracks i_mapping pointer instead of the whole 
drm_device structure, the need for drm_unmap_mapping may be eliminated, 
which in turn will take care of the dependency.

That brings me to a question for you. The patch from which I derived this 
is your patch 7c5cc4f63556e351e9e5980ed22accad410e3fdc (on your original 
render-nodes branch). That's where you introduced drm_unmap_mapping 
function, which calls unmap_mapping_range for every minor known to the 
system.

Why was that necessary at first place ? I mean we don't do the eqivalent 
of that currently when there are multiple physical GPUs in the system, so 
I don't quite get why introduction of multiple minors would require to go 
through the whole list of minors. If that's a "just in case"/"just to be 
safe" kind of thing, then I think we may be able to just call 
drm_unmap_mapping from the driver that needs to call it and only for the 
minor in question.

If we can do that, then the patch will in principle look the same to what 
the current code does, except that dev_mapping will be in the minor 
structure and there will ne no new dependencies introduced. The patch will 
also be simpler that way.

-- Ilija



Include request for reset-rework branch.

2012-04-30 Thread Christian König
Hi Dave,

if nobody has a last moment concern please include the following patches in 
drm-next.

Except for some minor fixes they have already been on the list for quite some 
time,
but I intentional left out the debugfs related patches cause we haven't 
finished the
discussion about them yet.

If you prefer to merge them directly, I also made them available as reset-rework
branch here: git://people.freedesktop.org/~deathsimple/linux

Cheers,
Christian.



[PATCH 01/26] drm/radeon: make radeon_gpu_is_lockup a per ring function

2012-04-30 Thread Christian König
Different rings have different criteria to test
if they are stuck.

v2: rebased on current drm-next

Signed-off-by: Christian K?nig 
Reviewed-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon.h   |4 +-
 drivers/gpu/drm/radeon/radeon_asic.c  |   44 ++--
 drivers/gpu/drm/radeon/radeon_fence.c |2 +-
 3 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 566ca3b..1bcd2b3 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1153,7 +1153,6 @@ struct radeon_asic {
int (*resume)(struct radeon_device *rdev);
int (*suspend)(struct radeon_device *rdev);
void (*vga_set_state)(struct radeon_device *rdev, bool state);
-   bool (*gpu_is_lockup)(struct radeon_device *rdev, struct radeon_ring 
*cp);
int (*asic_reset)(struct radeon_device *rdev);
/* ioctl hw specific callback. Some hw might want to perform special
 * operation on specific ioctl. For instance on wait idle some hw
@@ -1182,6 +1181,7 @@ struct radeon_asic {
void (*ring_start)(struct radeon_device *rdev, struct 
radeon_ring *cp);
int (*ring_test)(struct radeon_device *rdev, struct radeon_ring 
*cp);
int (*ib_test)(struct radeon_device *rdev, struct radeon_ring 
*cp);
+   bool (*is_lockup)(struct radeon_device *rdev, struct 
radeon_ring *cp);
} ring[RADEON_NUM_RINGS];
/* irqs */
struct {
@@ -1739,7 +1739,6 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t 
v);
 #define radeon_suspend(rdev) (rdev)->asic->suspend((rdev))
 #define radeon_cs_parse(rdev, r, p) (rdev)->asic->ring[(r)].cs_parse((p))
 #define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), 
(state))
-#define radeon_gpu_is_lockup(rdev, cp) (rdev)->asic->gpu_is_lockup((rdev), 
(cp))
 #define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev))
 #define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart.tlb_flush((rdev))
 #define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart.set_page((rdev), 
(i), (p))
@@ -1748,6 +1747,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t 
v);
 #define radeon_ib_test(rdev, r, cp) (rdev)->asic->ring[(r)].ib_test((rdev), 
(cp))
 #define radeon_ring_ib_execute(rdev, r, ib) 
(rdev)->asic->ring[(r)].ib_execute((rdev), (ib))
 #define radeon_ring_ib_parse(rdev, r, ib) 
(rdev)->asic->ring[(r)].ib_parse((rdev), (ib))
+#define radeon_ring_is_lockup(rdev, r, cp) 
(rdev)->asic->ring[(r)].is_lockup((rdev), (cp))
 #define radeon_irq_set(rdev) (rdev)->asic->irq.set((rdev))
 #define radeon_irq_process(rdev) (rdev)->asic->irq.process((rdev))
 #define radeon_get_vblank_counter(rdev, crtc) 
(rdev)->asic->display.get_vblank_counter((rdev), (crtc))
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c 
b/drivers/gpu/drm/radeon/radeon_asic.c
index be4dc2f..958b9ea 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -134,7 +134,6 @@ static struct radeon_asic r100_asic = {
.suspend = &r100_suspend,
.resume = &r100_resume,
.vga_set_state = &r100_vga_set_state,
-   .gpu_is_lockup = &r100_gpu_is_lockup,
.asic_reset = &r100_asic_reset,
.ioctl_wait_idle = NULL,
.gui_idle = &r100_gui_idle,
@@ -152,6 +151,7 @@ static struct radeon_asic r100_asic = {
.ring_start = &r100_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
+   .is_lockup = &r100_gpu_is_lockup,
}
},
.irq = {
@@ -208,7 +208,6 @@ static struct radeon_asic r200_asic = {
.suspend = &r100_suspend,
.resume = &r100_resume,
.vga_set_state = &r100_vga_set_state,
-   .gpu_is_lockup = &r100_gpu_is_lockup,
.asic_reset = &r100_asic_reset,
.ioctl_wait_idle = NULL,
.gui_idle = &r100_gui_idle,
@@ -226,6 +225,7 @@ static struct radeon_asic r200_asic = {
.ring_start = &r100_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
+   .is_lockup = &r100_gpu_is_lockup,
}
},
.irq = {
@@ -282,7 +282,6 @@ static struct radeon_asic r300_asic = {
.suspend = &r300_suspend,
.resume = &r300_resume,
.vga_set_state = &r100_vga_set_state,
-   .gpu_is_lockup = &r300_gpu_is_lockup,
.asic_reset = &r300_asic_reset,
.ioctl_wait_idle = NULL,
.gui_idle = &r100_gui_idle,
@@ -300,6 +299,7 @@ static struct radeon_asic r300_asic = {
.ring_start = &r300_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
+   .is_lockup = &r300_gpu_is_lockup,
}
},
   

[PATCH 03/26] drm/radeon: register ring debugfs handlers on init

2012-04-30 Thread Christian König
Just register the debugfs files on init instead of
checking the chipset type multiple times.

Signed-off-by: Christian K?nig 
Reviewed-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon_ring.c |   31 +++
 1 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index cc33b3d..b6eb1d2 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -34,7 +34,7 @@
 #include "atom.h"

 int radeon_debugfs_ib_init(struct radeon_device *rdev);
-int radeon_debugfs_ring_init(struct radeon_device *rdev);
+int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring 
*ring);

 u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx)
 {
@@ -237,9 +237,6 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
if (radeon_debugfs_ib_init(rdev)) {
DRM_ERROR("Failed to register debugfs file for IB !\n");
}
-   if (radeon_debugfs_ring_init(rdev)) {
-   DRM_ERROR("Failed to register debugfs file for rings !\n");
-   }
radeon_mutex_unlock(&rdev->ib_pool.mutex);
return 0;
 }
@@ -411,6 +408,9 @@ int radeon_ring_init(struct radeon_device *rdev, struct 
radeon_ring *ring, unsig
}
ring->ptr_mask = (ring->ring_size / 4) - 1;
ring->ring_free_dw = ring->ring_size / 4;
+   if (radeon_debugfs_ring_init(rdev, ring)) {
+   DRM_ERROR("Failed to register debugfs file for rings !\n");
+   }
return 0;
 }

@@ -501,17 +501,24 @@ static char 
radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32];
 static unsigned radeon_debugfs_ib_idx[RADEON_IB_POOL_SIZE];
 #endif

-int radeon_debugfs_ring_init(struct radeon_device *rdev)
+int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring 
*ring)
 {
 #if defined(CONFIG_DEBUG_FS)
-   if (rdev->family >= CHIP_CAYMAN)
-   return radeon_debugfs_add_files(rdev, 
radeon_debugfs_ring_info_list,
-   
ARRAY_SIZE(radeon_debugfs_ring_info_list));
-   else
-   return radeon_debugfs_add_files(rdev, 
radeon_debugfs_ring_info_list, 1);
-#else
-   return 0;
+   unsigned i;
+   for (i = 0; i < ARRAY_SIZE(radeon_debugfs_ring_info_list); ++i) {
+   struct drm_info_list *info = &radeon_debugfs_ring_info_list[i];
+   int ridx = *(int*)radeon_debugfs_ring_info_list[i].data;
+   unsigned r;
+
+   if (&rdev->ring[ridx] != ring)
+   continue;
+
+   r = radeon_debugfs_add_files(rdev, info, 1);
+   if (r)
+   return r;
+   }
 #endif
+   return 0;
 }

 int radeon_debugfs_ib_init(struct radeon_device *rdev)
-- 
1.7.5.4



[PATCH 02/26] drm/radeon: replace gpu_lockup with ring->ready flag

2012-04-30 Thread Christian König
It makes no sense at all to have more than one flag.

Signed-off-by: Christian K?nig 
Reviewed-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/r100.c  |1 -
 drivers/gpu/drm/radeon/r300.c  |1 -
 drivers/gpu/drm/radeon/radeon.h|1 -
 drivers/gpu/drm/radeon/radeon_device.c |1 -
 drivers/gpu/drm/radeon/radeon_fence.c  |   36 +++
 drivers/gpu/drm/radeon/rs600.c |1 -
 6 files changed, 13 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index e11df77..4b677fc 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -2300,7 +2300,6 @@ int r100_asic_reset(struct radeon_device *rdev)
if (G_000E40_SE_BUSY(status) || G_000E40_RE_BUSY(status) ||
G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) {
dev_err(rdev->dev, "failed to reset GPU\n");
-   rdev->gpu_lockup = true;
ret = -1;
} else
dev_info(rdev->dev, "GPU reset succeed\n");
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index fa14383..a63f432 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -449,7 +449,6 @@ int r300_asic_reset(struct radeon_device *rdev)
/* Check if GPU is idle */
if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) {
dev_err(rdev->dev, "failed to reset GPU\n");
-   rdev->gpu_lockup = true;
ret = -1;
} else
dev_info(rdev->dev, "GPU reset succeed\n");
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 1bcd2b3..bb08702 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1538,7 +1538,6 @@ struct radeon_device {
struct radeon_mutex cs_mutex;
struct radeon_wbwb;
struct radeon_dummy_pagedummy_page;
-   boolgpu_lockup;
boolshutdown;
boolsuspend;
boolneed_dma32;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 0fb4f89..dedb398 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -714,7 +714,6 @@ int radeon_device_init(struct radeon_device *rdev,
rdev->is_atom_bios = false;
rdev->usec_timeout = RADEON_MAX_USEC_TIMEOUT;
rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
-   rdev->gpu_lockup = false;
rdev->accel_working = false;

DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 
0x%04X:0x%04X).\n",
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 66b2229..36c411f 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -71,14 +71,7 @@ int radeon_fence_emit(struct radeon_device *rdev, struct 
radeon_fence *fence)
return 0;
}
fence->seq = atomic_add_return(1, &rdev->fence_drv[fence->ring].seq);
-   if (!rdev->ring[fence->ring].ready)
-   /* FIXME: cp is not running assume everythings is done right
-* away
-*/
-   radeon_fence_write(rdev, fence->seq, fence->ring);
-   else
-   radeon_fence_ring_emit(rdev, fence->ring, fence);
-
+   radeon_fence_ring_emit(rdev, fence->ring, fence);
trace_radeon_fence_emit(rdev->ddev, fence->seq);
fence->emitted = true;
list_move_tail(&fence->list, &rdev->fence_drv[fence->ring].emitted);
@@ -191,9 +184,6 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
if (!fence)
return true;

-   if (fence->rdev->gpu_lockup)
-   return true;
-
write_lock_irqsave(&fence->rdev->fence_lock, irq_flags);
signaled = fence->signaled;
/* if we are shuting down report all fence as signaled */
@@ -260,18 +250,16 @@ retry:
 */
if (seq == rdev->fence_drv[fence->ring].last_seq &&
radeon_ring_is_lockup(rdev, fence->ring, 
&rdev->ring[fence->ring])) {
+
/* good news we believe it's a lockup */
printk(KERN_WARNING "GPU lockup (waiting for 0x%08X 
last fence id 0x%08X)\n",
 fence->seq, seq);
-   /* FIXME: what should we do ? marking everyone
-* as signaled for now
-*/
-   rdev->gpu_lockup = true;
+
+   /* mark the ring as not ready any more */
+   rdev->ring[fence->ring].ready = false;
r = radeon_gpu_reset(rdev);
if (r)
ret

[PATCH 04/26] drm/radeon: use central function for IB testing

2012-04-30 Thread Christian König
Removing all the different error messages and
having just one standard behaviour over all
chipset generations.

Signed-off-by: Christian K?nig 
Reviewed-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/evergreen.c   |7 ++-
 drivers/gpu/drm/radeon/ni.c  |7 ++-
 drivers/gpu/drm/radeon/r100.c|7 ++-
 drivers/gpu/drm/radeon/r300.c|7 ++-
 drivers/gpu/drm/radeon/r420.c|7 ++-
 drivers/gpu/drm/radeon/r520.c|8 +++-
 drivers/gpu/drm/radeon/r600.c|7 ++-
 drivers/gpu/drm/radeon/radeon.h  |1 +
 drivers/gpu/drm/radeon/radeon_ring.c |   30 ++
 drivers/gpu/drm/radeon/rs400.c   |7 ++-
 drivers/gpu/drm/radeon/rs600.c   |7 ++-
 drivers/gpu/drm/radeon/rs690.c   |7 ++-
 drivers/gpu/drm/radeon/rv515.c   |8 +++-
 drivers/gpu/drm/radeon/rv770.c   |7 ++-
 14 files changed, 57 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index eed7ace..8b7a01b 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3376,12 +3376,9 @@ static int evergreen_startup(struct radeon_device *rdev)
if (r)
return r;

-   r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, 
&rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
-   if (r) {
-   DRM_ERROR("radeon: failed testing IB (%d).\n", r);
-   rdev->accel_working = false;
+   r = radeon_ib_ring_tests(rdev);
+   if (r)
return r;
-   }

r = r600_audio_init(rdev);
if (r) {
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index a48ca53..0146428 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1601,12 +1601,9 @@ static int cayman_startup(struct radeon_device *rdev)
if (r)
return r;

-   r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, 
&rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
-   if (r) {
-   DRM_ERROR("radeon: failed testing IB (%d).\n", r);
-   rdev->accel_working = false;
+   r = radeon_ib_ring_tests(rdev);
+   if (r)
return r;
-   }

r = radeon_vm_manager_start(rdev);
if (r)
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 4b677fc..62f9dab 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -3968,12 +3968,9 @@ static int r100_startup(struct radeon_device *rdev)
if (r)
return r;

-   r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, 
&rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
-   if (r) {
-   dev_err(rdev->dev, "failed testing IB (%d).\n", r);
-   rdev->accel_working = false;
+   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 a63f432..26e0db8 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -1417,12 +1417,9 @@ static int r300_startup(struct radeon_device *rdev)
if (r)
return r;

-   r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, 
&rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
-   if (r) {
-   dev_err(rdev->dev, "failed testing IB (%d).\n", r);
-   rdev->accel_working = false;
+   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 f3fcaac..99137be 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -279,12 +279,9 @@ static int r420_startup(struct radeon_device *rdev)
if (r)
return r;

-   r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, 
&rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
-   if (r) {
-   dev_err(rdev->dev, "failed testing IB (%d).\n", r);
-   rdev->accel_working = false;
+   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 ebcc15b..b5cf837 100644
--- a/drivers/gpu/drm/radeon/r520.c
+++ b/drivers/gpu/drm/radeon/r520.c
@@ -207,12 +207,10 @@ static int r520_startup(struct radeon_device *rdev)
if (r)
return r;

-   r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, 
&rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
-   if (r) {
-   dev_err(rdev->dev, "failed testing IB (%d).\n", r);
-   rdev->accel_working = false;
+   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
ind

[PATCH 05/26] drm/radeon: rework gpu lockup detection and processing

2012-04-30 Thread Christian König
Previusly multiple rings could trigger multiple GPU
resets at the same time.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon.h   |3 +-
 drivers/gpu/drm/radeon/radeon_fence.c |  146 +
 2 files changed, 75 insertions(+), 74 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index e237127..92682b7 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -255,8 +255,7 @@ struct radeon_fence_driver {
volatile uint32_t   *cpu_addr;
atomic_tseq;
uint32_tlast_seq;
-   unsigned long   last_jiffies;
-   unsigned long   last_timeout;
+   unsigned long   last_activity;
wait_queue_head_t   queue;
struct list_headcreated;
struct list_heademitted;
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 36c411f..1a9765a 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -74,6 +74,10 @@ int radeon_fence_emit(struct radeon_device *rdev, struct 
radeon_fence *fence)
radeon_fence_ring_emit(rdev, fence->ring, fence);
trace_radeon_fence_emit(rdev->ddev, fence->seq);
fence->emitted = true;
+   /* are we the first fence on a previusly idle ring? */
+   if (list_empty(&rdev->fence_drv[fence->ring].emitted)) {
+   rdev->fence_drv[fence->ring].last_activity = jiffies;
+   }
list_move_tail(&fence->list, &rdev->fence_drv[fence->ring].emitted);
write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
return 0;
@@ -85,34 +89,14 @@ static bool radeon_fence_poll_locked(struct radeon_device 
*rdev, int ring)
struct list_head *i, *n;
uint32_t seq;
bool wake = false;
-   unsigned long cjiffies;

seq = radeon_fence_read(rdev, ring);
-   if (seq != rdev->fence_drv[ring].last_seq) {
-   rdev->fence_drv[ring].last_seq = seq;
-   rdev->fence_drv[ring].last_jiffies = jiffies;
-   rdev->fence_drv[ring].last_timeout = 
RADEON_FENCE_JIFFIES_TIMEOUT;
-   } else {
-   cjiffies = jiffies;
-   if (time_after(cjiffies, rdev->fence_drv[ring].last_jiffies)) {
-   cjiffies -= rdev->fence_drv[ring].last_jiffies;
-   if (time_after(rdev->fence_drv[ring].last_timeout, 
cjiffies)) {
-   /* update the timeout */
-   rdev->fence_drv[ring].last_timeout -= cjiffies;
-   } else {
-   /* the 500ms timeout is elapsed we should test
-* for GPU lockup
-*/
-   rdev->fence_drv[ring].last_timeout = 1;
-   }
-   } else {
-   /* wrap around update last jiffies, we will just wait
-* a little longer
-*/
-   rdev->fence_drv[ring].last_jiffies = cjiffies;
-   }
+   if (seq == rdev->fence_drv[ring].last_seq)
return false;
-   }
+
+   rdev->fence_drv[ring].last_seq = seq;
+   rdev->fence_drv[ring].last_activity = jiffies;
+
n = NULL;
list_for_each(i, &rdev->fence_drv[ring].emitted) {
fence = list_entry(i, struct radeon_fence, list);
@@ -207,66 +191,84 @@ int radeon_fence_wait(struct radeon_fence *fence, bool 
intr)
struct radeon_device *rdev;
unsigned long irq_flags, timeout;
u32 seq;
-   int r;
+   int i, r;
+   bool signaled;

if (fence == NULL) {
WARN(1, "Querying an invalid fence : %p !\n", fence);
-   return 0;
+   return -EINVAL;
}
+
rdev = fence->rdev;
-   if (radeon_fence_signaled(fence)) {
-   return 0;
-   }
-   timeout = rdev->fence_drv[fence->ring].last_timeout;
-retry:
-   /* save current sequence used to check for GPU lockup */
-   seq = rdev->fence_drv[fence->ring].last_seq;
-   trace_radeon_fence_wait_begin(rdev->ddev, seq);
-   if (intr) {
+   signaled = radeon_fence_signaled(fence);
+   while (!signaled) {
+   read_lock_irqsave(&rdev->fence_lock, irq_flags);
+   timeout = jiffies - RADEON_FENCE_JIFFIES_TIMEOUT;
+   if (time_after(rdev->fence_drv[fence->ring].last_activity, 
timeout)) {
+   /* the normal case, timeout is somewhere before 
last_activity */
+   timeout = rdev->fence_drv[fence->ring].last_activity - 
timeout;
+   } else {
+   /* either jiffies wrapped around, or no fence was 
signal

[PATCH 06/26] drm/radeon: fix a bug in the SA code

2012-04-30 Thread Christian König
Aligning offset can make it bigger than tmp->offset
leading to an overrun bug in the following subtraction.

v2: Against initial suspicions this can't happen in mainline,
so no need to push it into stable.

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

diff --git a/drivers/gpu/drm/radeon/radeon_sa.c 
b/drivers/gpu/drm/radeon/radeon_sa.c
index 4cce47e..8fbfe69 100644
--- a/drivers/gpu/drm/radeon/radeon_sa.c
+++ b/drivers/gpu/drm/radeon/radeon_sa.c
@@ -150,7 +150,7 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
offset = 0;
list_for_each_entry(tmp, &sa_manager->sa_bo, list) {
/* room before this object ? */
-   if ((tmp->offset - offset) >= size) {
+   if (offset < tmp->offset && (tmp->offset - offset) >= size) {
head = tmp->list.prev;
goto out;
}
-- 
1.7.5.4



[PATCH 07/26] drm/radeon: add proper locking to the SA v2

2012-04-30 Thread Christian König
Make the suballocator self containing to locking.

v2: split the bugfix into a seperate patch.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon.h|1 +
 drivers/gpu/drm/radeon/radeon_sa.c |   17 +++--
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 92682b7..99b188a 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -381,6 +381,7 @@ struct radeon_bo_list {
  * alignment).
  */
 struct radeon_sa_manager {
+   spinlock_t  lock;
struct radeon_bo*bo;
struct list_headsa_bo;
unsignedsize;
diff --git a/drivers/gpu/drm/radeon/radeon_sa.c 
b/drivers/gpu/drm/radeon/radeon_sa.c
index 8fbfe69..4ce5c51 100644
--- a/drivers/gpu/drm/radeon/radeon_sa.c
+++ b/drivers/gpu/drm/radeon/radeon_sa.c
@@ -37,6 +37,7 @@ int radeon_sa_bo_manager_init(struct radeon_device *rdev,
 {
int r;

+   spin_lock_init(&sa_manager->lock);
sa_manager->bo = NULL;
sa_manager->size = size;
sa_manager->domain = domain;
@@ -136,18 +137,19 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
struct radeon_sa_bo *tmp;
struct list_head *head;
unsigned offset = 0, wasted = 0;
+   unsigned long flags;

BUG_ON(align > RADEON_GPU_PAGE_SIZE);
BUG_ON(size > sa_manager->size);
+   spin_lock_irqsave(&sa_manager->lock, flags);

/* no one ? */
-   head = sa_manager->sa_bo.prev;
if (list_empty(&sa_manager->sa_bo)) {
+   head = &sa_manager->sa_bo;
goto out;
}

/* look for a hole big enough */
-   offset = 0;
list_for_each_entry(tmp, &sa_manager->sa_bo, list) {
/* room before this object ? */
if (offset < tmp->offset && (tmp->offset - offset) >= size) {
@@ -157,9 +159,8 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
offset = tmp->offset + tmp->size;
wasted = offset % align;
if (wasted) {
-   wasted = align - wasted;
+   offset += align - wasted;
}
-   offset += wasted;
}
/* room at the end ? */
head = sa_manager->sa_bo.prev;
@@ -167,11 +168,11 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
offset = tmp->offset + tmp->size;
wasted = offset % align;
if (wasted) {
-   wasted = align - wasted;
+   offset += wasted = align - wasted;
}
-   offset += wasted;
if ((sa_manager->size - offset) < size) {
/* failed to find somethings big enough */
+   spin_unlock_irqrestore(&sa_manager->lock, flags);
return -ENOMEM;
}

@@ -180,10 +181,14 @@ out:
sa_bo->offset = offset;
sa_bo->size = size;
list_add(&sa_bo->list, head);
+   spin_unlock_irqrestore(&sa_manager->lock, flags);
return 0;
 }

 void radeon_sa_bo_free(struct radeon_device *rdev, struct radeon_sa_bo *sa_bo)
 {
+   unsigned long flags;
+   spin_lock_irqsave(&sa_bo->manager->lock, flags);
list_del_init(&sa_bo->list);
+   spin_unlock_irqrestore(&sa_bo->manager->lock, flags);
 }
-- 
1.7.5.4



[PATCH 08/26] drm/radeon: add sub allocator debugfs file

2012-04-30 Thread Christian König
Dumping the current allocations.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon_object.h |5 +
 drivers/gpu/drm/radeon/radeon_ring.c   |   22 ++
 drivers/gpu/drm/radeon/radeon_sa.c |   15 +++
 3 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_object.h 
b/drivers/gpu/drm/radeon/radeon_object.h
index f9104be..d9b9333 100644
--- a/drivers/gpu/drm/radeon/radeon_object.h
+++ b/drivers/gpu/drm/radeon/radeon_object.h
@@ -161,5 +161,10 @@ extern int radeon_sa_bo_new(struct radeon_device *rdev,
unsigned size, unsigned align);
 extern void radeon_sa_bo_free(struct radeon_device *rdev,
  struct radeon_sa_bo *sa_bo);
+#if defined(CONFIG_DEBUG_FS)
+extern void radeon_sa_bo_dump_debug_info(struct radeon_sa_manager *sa_manager,
+struct seq_file *m);
+#endif
+

 #endif
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index 1b020ef..1d9bce9 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -529,6 +529,23 @@ static int radeon_debugfs_ib_info(struct seq_file *m, void 
*data)
 static struct drm_info_list radeon_debugfs_ib_list[RADEON_IB_POOL_SIZE];
 static char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32];
 static unsigned radeon_debugfs_ib_idx[RADEON_IB_POOL_SIZE];
+
+static int radeon_debugfs_sa_info(struct seq_file *m, void *data)
+{
+   struct drm_info_node *node = (struct drm_info_node *) m->private;
+   struct drm_device *dev = node->minor->dev;
+   struct radeon_device *rdev = dev->dev_private;
+
+   radeon_sa_bo_dump_debug_info(&rdev->ib_pool.sa_manager, m);
+
+   return 0;
+
+}
+
+static struct drm_info_list radeon_debugfs_sa_list[] = {
+{"radeon_sa_info", &radeon_debugfs_sa_info, 0, NULL},
+};
+
 #endif

 int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring 
*ring)
@@ -555,6 +572,11 @@ int radeon_debugfs_ib_init(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
unsigned i;
+   int r;
+
+   r = radeon_debugfs_add_files(rdev, radeon_debugfs_sa_list, 1);
+   if (r)
+   return r;

for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
sprintf(radeon_debugfs_ib_names[i], "radeon_ib_%04u", i);
diff --git a/drivers/gpu/drm/radeon/radeon_sa.c 
b/drivers/gpu/drm/radeon/radeon_sa.c
index 4ce5c51..013a787 100644
--- a/drivers/gpu/drm/radeon/radeon_sa.c
+++ b/drivers/gpu/drm/radeon/radeon_sa.c
@@ -192,3 +192,18 @@ void radeon_sa_bo_free(struct radeon_device *rdev, struct 
radeon_sa_bo *sa_bo)
list_del_init(&sa_bo->list);
spin_unlock_irqrestore(&sa_bo->manager->lock, flags);
 }
+
+#if defined(CONFIG_DEBUG_FS)
+void radeon_sa_bo_dump_debug_info(struct radeon_sa_manager *sa_manager,
+ struct seq_file *m)
+{
+   struct radeon_sa_bo *i;
+   unsigned long flags;
+
+   spin_lock_irqsave(&sa_manager->lock, flags);
+   list_for_each_entry(i, &sa_manager->sa_bo, list) {
+   seq_printf(m, "offset %08d: size %4d\n", i->offset, i->size);
+   }
+   spin_unlock_irqrestore(&sa_manager->lock, flags);
+}
+#endif
-- 
1.7.5.4



[PATCH 09/26] drm/radeon: add biggest hole tracking and wakequeue to the sa v3

2012-04-30 Thread Christian König
With that in place clients are automatically blocking
until their memory request can be handled.

v2: block only if the memory request can't be satisfied
in the first try, the first version actually lacked
a night of sleep.

v3: make blocking optional, update comments and fix
another bug with biggest hole tracking.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon.h|5 +-
 drivers/gpu/drm/radeon/radeon_gart.c   |2 +-
 drivers/gpu/drm/radeon/radeon_object.h |2 +-
 drivers/gpu/drm/radeon/radeon_ring.c   |   20 ++--
 drivers/gpu/drm/radeon/radeon_sa.c |  211 +++-
 5 files changed, 165 insertions(+), 75 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 99b188a..e71dc67 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -381,17 +381,16 @@ struct radeon_bo_list {
  * alignment).
  */
 struct radeon_sa_manager {
-   spinlock_t  lock;
+   wait_queue_head_t   queue;
struct radeon_bo*bo;
struct list_headsa_bo;
unsignedsize;
+   struct list_head*biggest_hole;
uint64_tgpu_addr;
void*cpu_ptr;
uint32_tdomain;
 };

-struct radeon_sa_bo;
-
 /* sub-allocation buffer */
 struct radeon_sa_bo {
struct list_headlist;
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index c58a036..7af4ff9 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -395,7 +395,7 @@ int radeon_vm_bind(struct radeon_device *rdev, struct 
radeon_vm *vm)
 retry:
r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager, &vm->sa_bo,
 RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8),
-RADEON_GPU_PAGE_SIZE);
+RADEON_GPU_PAGE_SIZE, false);
if (r) {
if (list_empty(&rdev->vm_manager.lru_vm)) {
return r;
diff --git a/drivers/gpu/drm/radeon/radeon_object.h 
b/drivers/gpu/drm/radeon/radeon_object.h
index d9b9333..85f33d9 100644
--- a/drivers/gpu/drm/radeon/radeon_object.h
+++ b/drivers/gpu/drm/radeon/radeon_object.h
@@ -158,7 +158,7 @@ extern int radeon_sa_bo_manager_suspend(struct 
radeon_device *rdev,
 extern int radeon_sa_bo_new(struct radeon_device *rdev,
struct radeon_sa_manager *sa_manager,
struct radeon_sa_bo *sa_bo,
-   unsigned size, unsigned align);
+   unsigned size, unsigned align, bool block);
 extern void radeon_sa_bo_free(struct radeon_device *rdev,
  struct radeon_sa_bo *sa_bo);
 #if defined(CONFIG_DEBUG_FS)
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index 1d9bce9..ccee74f 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -124,7 +124,7 @@ retry:
if (rdev->ib_pool.ibs[idx].fence == NULL) {
r = radeon_sa_bo_new(rdev, &rdev->ib_pool.sa_manager,
 &rdev->ib_pool.ibs[idx].sa_bo,
-size, 256);
+size, 256, false);
if (!r) {
*ib = &rdev->ib_pool.ibs[idx];
(*ib)->ptr = rdev->ib_pool.sa_manager.cpu_ptr;
@@ -205,10 +205,16 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct 
radeon_ib *ib)

 int radeon_ib_pool_init(struct radeon_device *rdev)
 {
-   struct radeon_sa_manager tmp;
int i, r;

-   r = radeon_sa_bo_manager_init(rdev, &tmp,
+   radeon_mutex_lock(&rdev->ib_pool.mutex);
+   if (rdev->ib_pool.ready) {
+   return 0;
+   }
+   rdev->ib_pool.ready = true;
+   radeon_mutex_unlock(&rdev->ib_pool.mutex);
+
+   r = radeon_sa_bo_manager_init(rdev, &rdev->ib_pool.sa_manager,
  RADEON_IB_POOL_SIZE*64*1024,
  RADEON_GEM_DOMAIN_GTT);
if (r) {
@@ -216,14 +222,6 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
}

radeon_mutex_lock(&rdev->ib_pool.mutex);
-   if (rdev->ib_pool.ready) {
-   radeon_mutex_unlock(&rdev->ib_pool.mutex);
-   radeon_sa_bo_manager_fini(rdev, &tmp);
-   return 0;
-   }
-
-   rdev->ib_pool.sa_manager = tmp;
-   INIT_LIST_HEAD(&rdev->ib_pool.sa_manager.sa_bo);
for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
rdev->ib_pool.ibs[i].fence = NULL;
rdev->ib_pool.ibs[i].idx = i;
diff --git a/drivers/gpu/drm/radeon/radeon_sa.c 
b/drivers/gpu/drm/radeon/radeon_sa.c
index 013a7

[PATCH 10/26] drm/radeon: add try_free callback to the SA

2012-04-30 Thread Christian König
To prevent deadlocks under extreme conditions.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon.h|1 +
 drivers/gpu/drm/radeon/radeon_gart.c   |2 +-
 drivers/gpu/drm/radeon/radeon_object.h |3 ++-
 drivers/gpu/drm/radeon/radeon_ring.c   |2 +-
 drivers/gpu/drm/radeon/radeon_sa.c |   15 ---
 5 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index e71dc67..4f7e941 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -389,6 +389,7 @@ struct radeon_sa_manager {
uint64_tgpu_addr;
void*cpu_ptr;
uint32_tdomain;
+   void(*try_free)(struct radeon_device *);
 };

 /* sub-allocation buffer */
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index 7af4ff9..fba3884 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -291,7 +291,7 @@ int radeon_vm_manager_init(struct radeon_device *rdev)
/* 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);
+ RADEON_GEM_DOMAIN_VRAM, NULL);
if (r) {
dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n",
(rdev->vm_manager.max_pfn * 8) >> 10);
diff --git a/drivers/gpu/drm/radeon/radeon_object.h 
b/drivers/gpu/drm/radeon/radeon_object.h
index 85f33d9..08505ed 100644
--- a/drivers/gpu/drm/radeon/radeon_object.h
+++ b/drivers/gpu/drm/radeon/radeon_object.h
@@ -148,7 +148,8 @@ extern struct radeon_bo_va *radeon_bo_va(struct radeon_bo 
*rbo,
  */
 extern int radeon_sa_bo_manager_init(struct radeon_device *rdev,
 struct radeon_sa_manager *sa_manager,
-unsigned size, u32 domain);
+unsigned size, u32 domain,
+void (*try_free)(struct radeon_device 
*rdev));
 extern void radeon_sa_bo_manager_fini(struct radeon_device *rdev,
  struct radeon_sa_manager *sa_manager);
 extern int radeon_sa_bo_manager_start(struct radeon_device *rdev,
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index ccee74f..ae28129 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -216,7 +216,7 @@ int radeon_ib_pool_init(struct radeon_device *rdev)

r = radeon_sa_bo_manager_init(rdev, &rdev->ib_pool.sa_manager,
  RADEON_IB_POOL_SIZE*64*1024,
- RADEON_GEM_DOMAIN_GTT);
+ RADEON_GEM_DOMAIN_GTT, NULL);
if (r) {
return r;
}
diff --git a/drivers/gpu/drm/radeon/radeon_sa.c 
b/drivers/gpu/drm/radeon/radeon_sa.c
index 92ab7b4..9d3e70a 100644
--- a/drivers/gpu/drm/radeon/radeon_sa.c
+++ b/drivers/gpu/drm/radeon/radeon_sa.c
@@ -34,7 +34,8 @@

 int radeon_sa_bo_manager_init(struct radeon_device *rdev,
  struct radeon_sa_manager *sa_manager,
- unsigned size, u32 domain)
+ unsigned size, u32 domain,
+ void (*try_free)(struct radeon_device *rdev))
 {
int r;

@@ -43,6 +44,7 @@ int radeon_sa_bo_manager_init(struct radeon_device *rdev,
sa_manager->size = size;
sa_manager->biggest_hole = &sa_manager->sa_bo;
sa_manager->domain = domain;
+   sa_manager->try_free = try_free;
INIT_LIST_HEAD(&sa_manager->sa_bo);

r = radeon_bo_create(rdev, size, RADEON_GPU_PAGE_SIZE, true,
@@ -224,8 +226,15 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
}

if (block) {
-   /* failed to find something big enough, wait
-  for the biggest hole to increase in size */
+   /* failed to find something big enough */
+   if (sa_manager->try_free) {
+   /* try to free something */
+   spin_unlock_irq(&sa_manager->queue.lock);
+   sa_manager->try_free(rdev);
+   spin_lock_irq(&sa_manager->queue.lock);
+   }
+
+   /* and wait for the biggest hole to increase in size */
r = 
wait_event_interruptible_locked_irq(sa_manager->queue,
radeon_sa_bo_min_free(sa_manager, align) >= size
);
-- 
1.7.5.4



[PATCH 12/26] drm/radeon: simplify semaphore handling

2012-04-30 Thread Christian König
Directly use the suballocator to get small chunks
of memory. It's equally fast and doesn't crash when
we encounter a GPU reset.

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/radeon.h   |   29 +--
 drivers/gpu/drm/radeon/radeon_device.c|2 -
 drivers/gpu/drm/radeon/radeon_semaphore.c |  134 -
 drivers/gpu/drm/radeon/rv770.c|1 -
 drivers/gpu/drm/radeon/si.c   |1 -
 8 files changed, 22 insertions(+), 148 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index 8b7a01b..26848d6 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3559,7 +3559,6 @@ void evergreen_fini(struct radeon_device *rdev)
evergreen_pcie_gart_fini(rdev);
r600_vram_scratch_fini(rdev);
radeon_gem_fini(rdev);
-   radeon_semaphore_driver_fini(rdev);
radeon_fence_driver_fini(rdev);
radeon_agp_fini(rdev);
radeon_bo_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 0146428..c0b0956 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1773,7 +1773,6 @@ void cayman_fini(struct radeon_device *rdev)
cayman_pcie_gart_fini(rdev);
r600_vram_scratch_fini(rdev);
radeon_gem_fini(rdev);
-   radeon_semaphore_driver_fini(rdev);
radeon_fence_driver_fini(rdev);
radeon_bo_fini(rdev);
radeon_atombios_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index db9415a..659a09c 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2672,7 +2672,6 @@ void r600_fini(struct radeon_device *rdev)
r600_vram_scratch_fini(rdev);
radeon_agp_fini(rdev);
radeon_gem_fini(rdev);
-   radeon_semaphore_driver_fini(rdev);
radeon_fence_driver_fini(rdev);
radeon_bo_fini(rdev);
radeon_atombios_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 4f7e941..e81ad96 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -428,34 +428,12 @@ int radeon_mode_dumb_destroy(struct drm_file *file_priv,
 /*
  * Semaphores.
  */
-struct radeon_ring;
-
-#defineRADEON_SEMAPHORE_BO_SIZE256
-
-struct radeon_semaphore_driver {
-   rwlock_tlock;
-   struct list_headbo;
-};
-
-struct radeon_semaphore_bo;
-
-/* everything here is constant */
 struct radeon_semaphore {
-   struct list_headlist;
-   uint64_tgpu_addr;
-   uint32_t*cpu_ptr;
-   struct radeon_semaphore_bo  *bo;
-};
-
-struct radeon_semaphore_bo {
-   struct list_headlist;
-   struct radeon_ib*ib;
-   struct list_headfree;
-   struct radeon_semaphore semaphores[RADEON_SEMAPHORE_BO_SIZE/8];
-   unsignednused;
+   struct radeon_sa_bo sa_bo;
+   signed  waiters;
+   uint64_tgpu_addr;
 };

-void radeon_semaphore_driver_fini(struct radeon_device *rdev);
 int radeon_semaphore_create(struct radeon_device *rdev,
struct radeon_semaphore **semaphore);
 void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring,
@@ -1528,7 +1506,6 @@ struct radeon_device {
struct radeon_mman  mman;
rwlock_tfence_lock;
struct radeon_fence_driver  fence_drv[RADEON_NUM_RINGS];
-   struct radeon_semaphore_driver  semaphore_drv;
struct radeon_ring  ring[RADEON_NUM_RINGS];
struct radeon_ib_pool   ib_pool;
struct radeon_irq   irq;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index dedb398..8c49990 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -733,11 +733,9 @@ int radeon_device_init(struct radeon_device *rdev,
mutex_init(&rdev->pm.mutex);
mutex_init(&rdev->vram_mutex);
rwlock_init(&rdev->fence_lock);
-   rwlock_init(&rdev->semaphore_drv.lock);
INIT_LIST_HEAD(&rdev->gem.objects);
init_waitqueue_head(&rdev->irq.vblank_queue);
init_waitqueue_head(&rdev->irq.idle_queue);
-   INIT_LIST_HEAD(&rdev->semaphore_drv.bo);
/* initialize vm here */
rdev->vm_manager.use_bitmap = 1;
rdev->vm_manager.max_pfn = 1 << 20;
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c 
b/drivers/gpu/drm/radeon/radeon_semaphore.c
index 61dd4e3..5a4741a 100644
--- a/drivers/gpu/drm/radeon/radeon

[PATCH 11/26] drm/radeon: use inline functions to calc sa_bo addr

2012-04-30 Thread Christian König
Instead of hacking the calculation multiple times.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon_gart.c   |6 ++
 drivers/gpu/drm/radeon/radeon_object.h |   11 +++
 drivers/gpu/drm/radeon/radeon_ring.c   |6 ++
 3 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index fba3884..1766671 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -404,10 +404,8 @@ retry:
radeon_vm_unbind(rdev, vm_evict);
goto retry;
}
-   vm->pt = rdev->vm_manager.sa_manager.cpu_ptr;
-   vm->pt += (vm->sa_bo.offset >> 3);
-   vm->pt_gpu_addr = rdev->vm_manager.sa_manager.gpu_addr;
-   vm->pt_gpu_addr += vm->sa_bo.offset;
+   vm->pt = radeon_sa_bo_cpu_addr(&vm->sa_bo);
+   vm->pt_gpu_addr = radeon_sa_bo_gpu_addr(&vm->sa_bo);
memset(vm->pt, 0, RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8));

 retry_id:
diff --git a/drivers/gpu/drm/radeon/radeon_object.h 
b/drivers/gpu/drm/radeon/radeon_object.h
index 08505ed..242c76f 100644
--- a/drivers/gpu/drm/radeon/radeon_object.h
+++ b/drivers/gpu/drm/radeon/radeon_object.h
@@ -146,6 +146,17 @@ extern struct radeon_bo_va *radeon_bo_va(struct radeon_bo 
*rbo,
 /*
  * sub allocation
  */
+
+static inline uint64_t radeon_sa_bo_gpu_addr(struct radeon_sa_bo *sa_bo)
+{
+   return sa_bo->manager->gpu_addr + sa_bo->offset;
+}
+
+static inline void * radeon_sa_bo_cpu_addr(struct radeon_sa_bo *sa_bo)
+{
+   return sa_bo->manager->cpu_ptr + sa_bo->offset;
+}
+
 extern int radeon_sa_bo_manager_init(struct radeon_device *rdev,
 struct radeon_sa_manager *sa_manager,
 unsigned size, u32 domain,
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index ae28129..56cfb86 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -127,10 +127,8 @@ retry:
 size, 256, false);
if (!r) {
*ib = &rdev->ib_pool.ibs[idx];
-   (*ib)->ptr = rdev->ib_pool.sa_manager.cpu_ptr;
-   (*ib)->ptr += ((*ib)->sa_bo.offset >> 2);
-   (*ib)->gpu_addr = 
rdev->ib_pool.sa_manager.gpu_addr;
-   (*ib)->gpu_addr += (*ib)->sa_bo.offset;
+   (*ib)->ptr = 
radeon_sa_bo_cpu_addr(&(*ib)->sa_bo);
+   (*ib)->gpu_addr = 
radeon_sa_bo_gpu_addr(&(*ib)->sa_bo);
(*ib)->fence = fence;
(*ib)->vm_id = 0;
(*ib)->is_const_ib = false;
-- 
1.7.5.4



[PATCH 13/26] drm/radeon: return -ENOENT in fence_wait_next v2

2012-04-30 Thread Christian König
We should signal the caller that we haven't waited at all.

v2: only change fence_wait_next not fence_wait_last.

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

diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 1a9765a..2fbbc34 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -286,7 +286,7 @@ int radeon_fence_wait_next(struct radeon_device *rdev, int 
ring)
}
if (list_empty(&rdev->fence_drv[ring].emitted)) {
write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
-   return 0;
+   return -ENOENT;
}
fence = list_entry(rdev->fence_drv[ring].emitted.next,
   struct radeon_fence, list);
-- 
1.7.5.4



[PATCH 14/26] drm/radeon: rename fence_wait_last to fence_wait_empty

2012-04-30 Thread Christian König
As discussed with Michel that name better
describes the behavior of this function.

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

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index e81ad96..ce22b01 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -285,7 +285,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(struct radeon_device *rdev, int ring);
-int radeon_fence_wait_last(struct radeon_device *rdev, int ring);
+int radeon_fence_wait_empty(struct radeon_device *rdev, int ring);
 struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence);
 void radeon_fence_unref(struct radeon_fence **fence);
 int radeon_fence_count_emitted(struct radeon_device *rdev, int ring);
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 8c49990..5966b35 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -913,7 +913,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t 
state)
radeon_bo_evict_vram(rdev);
/* wait for gpu to finish processing current batch */
for (i = 0; i < RADEON_NUM_RINGS; i++)
-   radeon_fence_wait_last(rdev, i);
+   radeon_fence_wait_empty(rdev, i);

radeon_save_bios_scratch_regs(rdev);

diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 2fbbc34..2d13843 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -297,7 +297,7 @@ int radeon_fence_wait_next(struct radeon_device *rdev, int 
ring)
return r;
 }

-int radeon_fence_wait_last(struct radeon_device *rdev, int ring)
+int radeon_fence_wait_empty(struct radeon_device *rdev, int ring)
 {
unsigned long irq_flags;
struct radeon_fence *fence;
@@ -442,7 +442,7 @@ void radeon_fence_driver_fini(struct radeon_device *rdev)
for (ring = 0; ring < RADEON_NUM_RINGS; ring++) {
if (!rdev->fence_drv[ring].initialized)
continue;
-   radeon_fence_wait_last(rdev, ring);
+   radeon_fence_wait_empty(rdev, ring);
wake_up_all(&rdev->fence_drv[ring].queue);
write_lock_irqsave(&rdev->fence_lock, irq_flags);
radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg);
-- 
1.7.5.4



[PATCH 15/26] drm/radeon: add general purpose fence signaled callback

2012-04-30 Thread Christian König
Should be used to free resource that are protected by a fence.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon.h   |8 -
 drivers/gpu/drm/radeon/radeon_fence.c |   50 +---
 2 files changed, 52 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index ce22b01..74b6595 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -259,7 +259,6 @@ struct radeon_fence_driver {
wait_queue_head_t   queue;
struct list_headcreated;
struct list_heademitted;
-   struct list_headsignaled;
boolinitialized;
 };

@@ -274,6 +273,10 @@ struct radeon_fence {
/* RB, DMA, etc. */
int ring;
struct radeon_semaphore *semaphore;
+
+   /* called when fence is signaled */
+   void(*signal_callback)(struct radeon_device *rdev, void *data);
+   void*callback_data;
 };

 int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring);
@@ -289,6 +292,9 @@ int radeon_fence_wait_empty(struct radeon_device *rdev, int 
ring);
 struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence);
 void radeon_fence_unref(struct radeon_fence **fence);
 int radeon_fence_count_emitted(struct radeon_device *rdev, int ring);
+bool radeon_fence_set_signal_callback(struct radeon_fence *fence,
+  void (*callback)(struct radeon_device *, 
void *),
+  void *data);

 /*
  * Tiling registers
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 2d13843..c58660a 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -83,7 +83,8 @@ int radeon_fence_emit(struct radeon_device *rdev, struct 
radeon_fence *fence)
return 0;
 }

-static bool radeon_fence_poll_locked(struct radeon_device *rdev, int ring)
+static bool radeon_fence_poll_locked(struct radeon_device *rdev, int ring,
+struct list_head *signaled)
 {
struct radeon_fence *fence;
struct list_head *i, *n;
@@ -110,7 +111,7 @@ static bool radeon_fence_poll_locked(struct radeon_device 
*rdev, int ring)
i = n;
do {
n = i->prev;
-   list_move_tail(i, &rdev->fence_drv[ring].signaled);
+   list_move_tail(i, signaled);
fence = list_entry(i, struct radeon_fence, list);
fence->signaled = true;
i = n;
@@ -120,6 +121,20 @@ static bool radeon_fence_poll_locked(struct radeon_device 
*rdev, int ring)
return wake;
 }

+static void radeon_fence_process_signaled(struct radeon_device *rdev, struct 
list_head *signaled)
+{
+   struct radeon_fence *fence;
+   struct list_head *i, *n;
+
+   list_for_each_safe(i, n, signaled) {
+   fence = list_entry(i, struct radeon_fence, list);
+   list_del_init(&fence->list);
+   if (fence->signal_callback) {
+   fence->signal_callback(rdev, fence->callback_data);
+   }
+   }
+}
+
 static void radeon_fence_destroy(struct kref *kref)
 {
unsigned long irq_flags;
@@ -152,6 +167,8 @@ int radeon_fence_create(struct radeon_device *rdev,
(*fence)->seq = 0;
(*fence)->ring = ring;
(*fence)->semaphore = NULL;
+   (*fence)->signal_callback = NULL;
+   (*fence)->callback_data = NULL;
INIT_LIST_HEAD(&(*fence)->list);

write_lock_irqsave(&rdev->fence_lock, irq_flags);
@@ -164,6 +181,7 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
 {
unsigned long irq_flags;
bool signaled = false;
+   LIST_HEAD(siglist);

if (!fence)
return true;
@@ -179,10 +197,12 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
signaled = true;
}
if (!signaled) {
-   radeon_fence_poll_locked(fence->rdev, fence->ring);
+   radeon_fence_poll_locked(fence->rdev, fence->ring, &siglist);
signaled = fence->signaled;
}
write_unlock_irqrestore(&fence->rdev->fence_lock, irq_flags);
+   radeon_fence_process_signaled(fence->rdev, &siglist);
+
return signaled;
 }

@@ -341,10 +361,12 @@ void radeon_fence_process(struct radeon_device *rdev, int 
ring)
 {
unsigned long irq_flags;
bool wake;
+   LIST_HEAD(signaled);

write_lock_irqsave(&rdev->fence_lock, irq_flags);
-   wake = radeon_fence_poll_locked(rdev, ring);
+   wake = radeon_fence_poll_locked(rdev, ring, &signaled);
write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
+   radeon_fence_process_signaled(rdev, &signa

[PATCH 16/26] drm/radeon: don't keep list of created fences.

2012-04-30 Thread Christian König
It's never used and so practically superfluous.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon.h   |1 -
 drivers/gpu/drm/radeon/radeon_fence.c |7 ---
 2 files changed, 0 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 74b6595..9ba28a4 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -257,7 +257,6 @@ struct radeon_fence_driver {
uint32_tlast_seq;
unsigned long   last_activity;
wait_queue_head_t   queue;
-   struct list_headcreated;
struct list_heademitted;
boolinitialized;
 };
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index c58660a..326bdb5 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -154,8 +154,6 @@ int radeon_fence_create(struct radeon_device *rdev,
struct radeon_fence **fence,
int ring)
 {
-   unsigned long irq_flags;
-
*fence = kmalloc(sizeof(struct radeon_fence), GFP_KERNEL);
if ((*fence) == NULL) {
return -ENOMEM;
@@ -170,10 +168,6 @@ int radeon_fence_create(struct radeon_device *rdev,
(*fence)->signal_callback = NULL;
(*fence)->callback_data = NULL;
INIT_LIST_HEAD(&(*fence)->list);
-
-   write_lock_irqsave(&rdev->fence_lock, irq_flags);
-   list_add_tail(&(*fence)->list, &rdev->fence_drv[ring].created);
-   write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
return 0;
 }

@@ -452,7 +446,6 @@ static void radeon_fence_driver_init_ring(struct 
radeon_device *rdev, int ring)
rdev->fence_drv[ring].cpu_addr = NULL;
rdev->fence_drv[ring].gpu_addr = 0;
atomic_set(&rdev->fence_drv[ring].seq, 0);
-   INIT_LIST_HEAD(&rdev->fence_drv[ring].created);
INIT_LIST_HEAD(&rdev->fence_drv[ring].emitted);
init_waitqueue_head(&rdev->fence_drv[ring].queue);
rdev->fence_drv[ring].initialized = false;
-- 
1.7.5.4



[PATCH 18/26] drm/radeon: fix a bug with the ring syncing code

2012-04-30 Thread Christian König
Rings need to lock in order, otherwise
the ring subsystem can deadlock.

v2: fix error handling and number of locked doublewords.
v3: stop creating unneeded semaphores.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon.h   |4 ++
 drivers/gpu/drm/radeon/radeon_cs.c|   35 ++
 drivers/gpu/drm/radeon/radeon_semaphore.c |   56 +
 drivers/gpu/drm/radeon/radeon_ttm.c   |   46 ++-
 4 files changed, 92 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 12d2003..cfd00a9 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -445,6 +445,10 @@ void radeon_semaphore_emit_signal(struct radeon_device 
*rdev, int ring,
  struct radeon_semaphore *semaphore);
 void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring,
struct radeon_semaphore *semaphore);
+int radeon_semaphore_sync_rings(struct radeon_device *rdev,
+   struct radeon_semaphore *semaphore,
+   bool sync_to[RADEON_NUM_RINGS],
+   int dst_ring);
 void radeon_semaphore_free(struct radeon_device *rdev,
   struct radeon_semaphore *semaphore);

diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
b/drivers/gpu/drm/radeon/radeon_cs.c
index e7b0b5d..24fb001 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -118,6 +118,7 @@ static int radeon_cs_get_ring(struct radeon_cs_parser *p, 
u32 ring, s32 priority
 static int radeon_cs_sync_rings(struct radeon_cs_parser *p)
 {
bool sync_to_ring[RADEON_NUM_RINGS] = { };
+   bool need_sync = false;
int i, r;

for (i = 0; i < p->nrelocs; i++) {
@@ -126,36 +127,24 @@ static int radeon_cs_sync_rings(struct radeon_cs_parser 
*p)

if (!(p->relocs[i].flags & RADEON_RELOC_DONT_SYNC)) {
struct radeon_fence *fence = 
p->relocs[i].robj->tbo.sync_obj;
-   if (!radeon_fence_signaled(fence)) {
+   if (fence->ring != p->ring && 
!radeon_fence_signaled(fence)) {
sync_to_ring[fence->ring] = true;
+   need_sync = true;
}
}
}

-   for (i = 0; i < RADEON_NUM_RINGS; ++i) {
-   /* no need to sync to our own or unused rings */
-   if (i == p->ring || !sync_to_ring[i] || !p->rdev->ring[i].ready)
-   continue;
-
-   if (!p->ib->fence->semaphore) {
-   r = radeon_semaphore_create(p->rdev, 
&p->ib->fence->semaphore);
-   if (r)
-   return r;
-   }
-
-   r = radeon_ring_lock(p->rdev, &p->rdev->ring[i], 3);
-   if (r)
-   return r;
-   radeon_semaphore_emit_signal(p->rdev, i, 
p->ib->fence->semaphore);
-   radeon_ring_unlock_commit(p->rdev, &p->rdev->ring[i]);
+   if (!need_sync) {
+   return 0;
+   }

-   r = radeon_ring_lock(p->rdev, &p->rdev->ring[p->ring], 3);
-   if (r)
-   return r;
-   radeon_semaphore_emit_wait(p->rdev, p->ring, 
p->ib->fence->semaphore);
-   radeon_ring_unlock_commit(p->rdev, &p->rdev->ring[p->ring]);
+   r = radeon_semaphore_create(p->rdev, &p->ib->fence->semaphore);
+   if (r) {
+   return r;
}
-   return 0;
+
+   return radeon_semaphore_sync_rings(p->rdev, p->ib->fence->semaphore,
+  sync_to_ring, p->ring);
 }

 int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c 
b/drivers/gpu/drm/radeon/radeon_semaphore.c
index f6929c7..731ee65 100644
--- a/drivers/gpu/drm/radeon/radeon_semaphore.c
+++ b/drivers/gpu/drm/radeon/radeon_semaphore.c
@@ -70,6 +70,62 @@ void radeon_semaphore_emit_wait(struct radeon_device *rdev, 
int ring,
radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, 
true);
 }

+int radeon_semaphore_sync_rings(struct radeon_device *rdev,
+   struct radeon_semaphore *semaphore,
+   bool sync_to[RADEON_NUM_RINGS],
+   int dst_ring)
+{
+   int i, r;
+
+   for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+   unsigned num_ops = i == dst_ring ? RADEON_NUM_RINGS : 1;
+
+   /* don't lock unused rings */
+   if (!sync_to[i] && i != dst_ring)
+   continue;
+
+   /* prevent GPU deadlocks */
+   if (!rdev->ring[i].ready) {
+   dev_err(rdev->dev, "Trying to sync to a disabl

[PATCH 17/26] drm/radeon: rip out the ib pool v2

2012-04-30 Thread Christian König
It isn't necessary any more and the suballocator
seems to perform even better.

v2: ignore ERESTARTSYS in error reporting,
split fence changes into seperate patch,
use try_free SA callback to avoid lockups

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon.h   |   17 +--
 drivers/gpu/drm/radeon/radeon_device.c|1 -
 drivers/gpu/drm/radeon/radeon_gart.c  |   12 +-
 drivers/gpu/drm/radeon/radeon_ring.c  |  264 ++---
 drivers/gpu/drm/radeon/radeon_semaphore.c |2 +-
 5 files changed, 101 insertions(+), 195 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 9ba28a4..12d2003 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -618,7 +618,6 @@ void radeon_irq_kms_pflip_irq_put(struct radeon_device 
*rdev, int crtc);

 struct radeon_ib {
struct radeon_sa_bo sa_bo;
-   unsignedidx;
uint32_tlength_dw;
uint64_tgpu_addr;
uint32_t*ptr;
@@ -627,18 +626,6 @@ struct radeon_ib {
boolis_const_ib;
 };

-/*
- * locking -
- * mutex protects scheduled_ibs, ready, alloc_bm
- */
-struct radeon_ib_pool {
-   struct radeon_mutex mutex;
-   struct radeon_sa_managersa_manager;
-   struct radeon_ibibs[RADEON_IB_POOL_SIZE];
-   boolready;
-   unsignedhead_id;
-};
-
 struct radeon_ring {
struct radeon_bo*ring_obj;
volatile uint32_t   *ring;
@@ -779,7 +766,6 @@ struct si_rlc {
 int radeon_ib_get(struct radeon_device *rdev, int ring,
  struct radeon_ib **ib, unsigned size);
 void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib);
-bool radeon_ib_try_free(struct radeon_device *rdev, struct radeon_ib *ib);
 int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib);
 int radeon_ib_pool_init(struct radeon_device *rdev);
 void radeon_ib_pool_fini(struct radeon_device *rdev);
@@ -1512,7 +1498,8 @@ struct radeon_device {
rwlock_tfence_lock;
struct radeon_fence_driver  fence_drv[RADEON_NUM_RINGS];
struct radeon_ring  ring[RADEON_NUM_RINGS];
-   struct radeon_ib_pool   ib_pool;
+   boolib_pool_ready;
+   struct radeon_sa_managersa_manager;
struct radeon_irq   irq;
struct radeon_asic  *asic;
struct radeon_gem   gem;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 5966b35..853e1cb 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -723,7 +723,6 @@ int radeon_device_init(struct radeon_device *rdev,
/* mutex initialization are all done here so we
 * can recall function without having locking issues */
radeon_mutex_init(&rdev->cs_mutex);
-   radeon_mutex_init(&rdev->ib_pool.mutex);
for (i = 0; i < RADEON_NUM_RINGS; ++i)
mutex_init(&rdev->ring[i].mutex);
mutex_init(&rdev->dc_hw_i2c_mutex);
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index 1766671..8eba1c6 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -432,8 +432,8 @@ retry_id:
rdev->vm_manager.use_bitmap |= 1 << id;
vm->id = id;
list_add_tail(&vm->list, &rdev->vm_manager.lru_vm);
-   return radeon_vm_bo_update_pte(rdev, vm, rdev->ib_pool.sa_manager.bo,
-  &rdev->ib_pool.sa_manager.bo->tbo.mem);
+   return radeon_vm_bo_update_pte(rdev, vm, rdev->sa_manager.bo,
+  &rdev->sa_manager.bo->tbo.mem);
 }

 /* object have to be reserved */
@@ -631,7 +631,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct 
radeon_vm *vm)
/* map the ib pool buffer at 0 in virtual address space, set
 * read only
 */
-   r = radeon_vm_bo_add(rdev, vm, rdev->ib_pool.sa_manager.bo, 0,
+   r = radeon_vm_bo_add(rdev, vm, rdev->sa_manager.bo, 0,
 RADEON_VM_PAGE_READABLE | RADEON_VM_PAGE_SNOOPED);
return r;
 }
@@ -648,12 +648,12 @@ void radeon_vm_fini(struct radeon_device *rdev, struct 
radeon_vm *vm)
radeon_mutex_unlock(&rdev->cs_mutex);

/* remove all bo */
-   r = radeon_bo_reserve(rdev->ib_pool.sa_manager.bo, false);
+   r = radeon_bo_reserve(rdev->sa_manager.bo, false);
if (!r) {
-   bo_va = radeon_bo_va(rdev->ib_pool.sa_manager.bo, vm);
+   bo_va = radeon_bo_va(rdev->sa_manager.bo, vm);
list_del_init(&bo_va->bo_list);
list_del_init(&bo_va->vm_list);
-   radeon_bo_un

[PATCH 19/26] drm/radeon: rework recursive gpu reset handling

2012-04-30 Thread Christian König
Instead of all this humpy pumpy with recursive
mutex (which also fixes only halve of the problem)
move the actual gpu reset out of the fence code,
return -EDEADLK and then reset the gpu in the
calling ioctl function.

v2: Split removal of radeon_mutex into separate patch.
Return -EAGAIN if reset is successful.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon_cs.c |   13 +
 drivers/gpu/drm/radeon/radeon_device.c |5 -
 drivers/gpu/drm/radeon/radeon_fence.c  |   10 +++---
 drivers/gpu/drm/radeon/radeon_gem.c|   16 
 4 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
b/drivers/gpu/drm/radeon/radeon_cs.c
index 24fb001..02eee4b 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -496,6 +496,16 @@ out:
return r;
 }

+static int radeon_cs_handle_lockup(struct radeon_device *rdev, int r)
+{
+   if (r == -EDEADLK) {
+   r = radeon_gpu_reset(rdev);
+   if (!r)
+   r = -EAGAIN;
+   }
+   return r;
+}
+
 int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 {
struct radeon_device *rdev = dev->dev_private;
@@ -517,6 +527,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);
+   r = radeon_cs_handle_lockup(rdev, r);
radeon_mutex_unlock(&rdev->cs_mutex);
return r;
}
@@ -525,6 +536,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);
+   r = radeon_cs_handle_lockup(rdev, r);
radeon_mutex_unlock(&rdev->cs_mutex);
return r;
}
@@ -538,6 +550,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
}
 out:
radeon_cs_parser_fini(&parser, r);
+   r = radeon_cs_handle_lockup(rdev, r);
radeon_mutex_unlock(&rdev->cs_mutex);
return r;
 }
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 853e1cb..8a4a210 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -983,9 +983,6 @@ int radeon_gpu_reset(struct radeon_device *rdev)
int r;
int resched;

-   /* Prevent CS ioctl from interfering */
-   radeon_mutex_lock(&rdev->cs_mutex);
-
radeon_save_bios_scratch_regs(rdev);
/* block TTM */
resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
@@ -1000,8 +997,6 @@ int radeon_gpu_reset(struct radeon_device *rdev)
ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
}

-   radeon_mutex_unlock(&rdev->cs_mutex);
-
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_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 326bdb5..24a4d4b 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -264,6 +264,8 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr)
/* change sequence value on all rings, so nobody else 
things there is a lockup */
for (i = 0; i < RADEON_NUM_RINGS; ++i)
rdev->fence_drv[i].last_seq -= 0x1;
+
+   rdev->fence_drv[fence->ring].last_activity = jiffies;
write_unlock_irqrestore(&rdev->fence_lock, irq_flags);

if (radeon_ring_is_lockup(rdev, fence->ring, 
&rdev->ring[fence->ring])) {
@@ -274,13 +276,7 @@ int radeon_fence_wait(struct radeon_fence *fence, bool 
intr)

/* mark the ring as not ready any more */
rdev->ring[fence->ring].ready = false;
-   r = radeon_gpu_reset(rdev);
-   if (r)
-   return r;
-
-   write_lock_irqsave(&rdev->fence_lock, 
irq_flags);
-   rdev->fence_drv[fence->ring].last_activity = 
jiffies;
-   write_unlock_irqrestore(&rdev->fence_lock, 
irq_flags);
+   return -EDEADLK;
}
}
}
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c 
b/drivers/gpu/drm/radeon/radeon_gem.c
index c7008b5..e15cb1f 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -154,6 +154,17 @@ void radeon_gem_object_close(

[PATCH 20/26] drm/radeon: remove recursive mutex implementation

2012-04-30 Thread Christian König
Not needed anymore.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon.h|   44 +---
 drivers/gpu/drm/radeon/radeon_cs.c |   10 +++---
 drivers/gpu/drm/radeon/radeon_device.c |2 +-
 drivers/gpu/drm/radeon/radeon_gart.c   |   16 ++--
 drivers/gpu/drm/radeon/radeon_gem.c|4 +-
 5 files changed, 17 insertions(+), 59 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index cfd00a9..b48b84c 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -155,48 +155,6 @@ static inline int radeon_atrm_get_bios_chunk(uint8_t 
*bios, int offset, int len)
 #endif
 bool radeon_get_bios(struct radeon_device *rdev);

-
-/*
- * Mutex which allows recursive locking from the same process.
- */
-struct radeon_mutex {
-   struct mutexmutex;
-   struct task_struct  *owner;
-   int level;
-};
-
-static inline void radeon_mutex_init(struct radeon_mutex *mutex)
-{
-   mutex_init(&mutex->mutex);
-   mutex->owner = NULL;
-   mutex->level = 0;
-}
-
-static inline void radeon_mutex_lock(struct radeon_mutex *mutex)
-{
-   if (mutex_trylock(&mutex->mutex)) {
-   /* The mutex was unlocked before, so it's ours now */
-   mutex->owner = current;
-   } else if (mutex->owner != current) {
-   /* Another process locked the mutex, take it */
-   mutex_lock(&mutex->mutex);
-   mutex->owner = current;
-   }
-   /* Otherwise the mutex was already locked by this process */
-
-   mutex->level++;
-}
-
-static inline void radeon_mutex_unlock(struct radeon_mutex *mutex)
-{
-   if (--mutex->level > 0)
-   return;
-
-   mutex->owner = NULL;
-   mutex_unlock(&mutex->mutex);
-}
-
-
 /*
  * Dummy page
  */
@@ -1509,7 +1467,7 @@ struct radeon_device {
struct radeon_gem   gem;
struct radeon_pmpm;
uint32_tbios_scratch[RADEON_BIOS_NUM_SCRATCH];
-   struct radeon_mutex cs_mutex;
+   struct mutexcs_mutex;
struct radeon_wbwb;
struct radeon_dummy_pagedummy_page;
boolshutdown;
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
b/drivers/gpu/drm/radeon/radeon_cs.c
index 02eee4b..c3273b8 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -512,9 +512,9 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
struct radeon_cs_parser parser;
int r;

-   radeon_mutex_lock(&rdev->cs_mutex);
+   mutex_lock(&rdev->cs_mutex);
if (!rdev->accel_working) {
-   radeon_mutex_unlock(&rdev->cs_mutex);
+   mutex_unlock(&rdev->cs_mutex);
return -EBUSY;
}
/* initialize parser */
@@ -528,7 +528,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
DRM_ERROR("Failed to initialize parser !\n");
radeon_cs_parser_fini(&parser, r);
r = radeon_cs_handle_lockup(rdev, r);
-   radeon_mutex_unlock(&rdev->cs_mutex);
+   mutex_unlock(&rdev->cs_mutex);
return r;
}
r = radeon_cs_parser_relocs(&parser);
@@ -537,7 +537,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
DRM_ERROR("Failed to parse relocation %d!\n", r);
radeon_cs_parser_fini(&parser, r);
r = radeon_cs_handle_lockup(rdev, r);
-   radeon_mutex_unlock(&rdev->cs_mutex);
+   mutex_unlock(&rdev->cs_mutex);
return r;
}
r = radeon_cs_ib_chunk(rdev, &parser);
@@ -551,7 +551,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
 out:
radeon_cs_parser_fini(&parser, r);
r = radeon_cs_handle_lockup(rdev, r);
-   radeon_mutex_unlock(&rdev->cs_mutex);
+   mutex_unlock(&rdev->cs_mutex);
return r;
 }

diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 8a4a210..94f8561 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -722,7 +722,7 @@ int radeon_device_init(struct radeon_device *rdev,

/* mutex initialization are all done here so we
 * can recall function without having locking issues */
-   radeon_mutex_init(&rdev->cs_mutex);
+   mutex_init(&rdev->cs_mutex);
for (i = 0; i < RADEON_NUM_RINGS; ++i)
mutex_init(&rdev->ring[i].mutex);
mutex_init(&rdev->dc_hw_i2c_mutex);
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index 8eba1c6..71b28e91 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.

[PATCH 22/26] drm/radeon: make lockup timeout a module param

2012-04-30 Thread Christian König
Don't hard code the 10 seconds timeout. Compute jobs
can run much longer.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon.h  |1 +
 drivers/gpu/drm/radeon/radeon_drv.c  |4 
 drivers/gpu/drm/radeon/radeon_ring.c |2 +-
 3 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index bcf4cc4..aaeb8af 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -94,6 +94,7 @@ extern int radeon_disp_priority;
 extern int radeon_hw_i2c;
 extern int radeon_pcie_gen2;
 extern int radeon_msi;
+extern int radeon_lockup_timeout;

 /*
  * Copy from radeon_drv.h so we don't have to include both and have conflicting
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c 
b/drivers/gpu/drm/radeon/radeon_drv.c
index ef7bb3f..e62e56a 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -128,6 +128,7 @@ int radeon_disp_priority = 0;
 int radeon_hw_i2c = 0;
 int radeon_pcie_gen2 = 0;
 int radeon_msi = -1;
+int radeon_lockup_timeout = 1;

 MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
 module_param_named(no_wb, radeon_no_wb, int, 0444);
@@ -177,6 +178,9 @@ module_param_named(pcie_gen2, radeon_pcie_gen2, int, 0444);
 MODULE_PARM_DESC(msi, "MSI support (1 = enable, 0 = disable, -1 = auto)");
 module_param_named(msi, radeon_msi, int, 0444);

+MODULE_PARM_DESC(lockup_timeout, "GPU lockup timeout in ms (defaul 1 = 10 
seconds, 0 = disable)");
+module_param_named(lockup_timeout, radeon_lockup_timeout, int, 0444);
+
 static int radeon_suspend(struct drm_device *dev, pm_message_t state)
 {
drm_radeon_private_t *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index 4c76d21..504fb8f 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -397,7 +397,7 @@ bool radeon_ring_test_lockup(struct radeon_device *rdev, 
struct radeon_ring *rin
return false;
}
elapsed = jiffies_to_msecs(cjiffies - ring->last_activity);
-   if (elapsed >= 1) {
+   if (radeon_lockup_timeout && elapsed >= radeon_lockup_timeout) {
dev_err(rdev->dev, "GPU lockup CP stall for more than 
%lumsec\n", elapsed);
return true;
}
-- 
1.7.5.4



[PATCH 23/26] drm/radeon: unlock the ring mutex while waiting for the next fence

2012-04-30 Thread Christian König
Fixing just another deadlock problem with gpu reset tests.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon_ring.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index 504fb8f..0f74c99 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -302,7 +302,9 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct 
radeon_ring *ring, unsi
if (ndw < ring->ring_free_dw) {
break;
}
+   mutex_unlock(&ring->mutex);
r = radeon_fence_wait_next(rdev, radeon_ring_index(rdev, ring));
+   mutex_lock(&ring->mutex);
if (r)
return r;
}
-- 
1.7.5.4



[PATCH 21/26] drm/radeon: move lockup detection code into radeon_ring.c

2012-04-30 Thread Christian König
It isn't chipset specific, so it makes no sense
to have that inside r100.c.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/evergreen.c   |5 +--
 drivers/gpu/drm/radeon/ni.c  |5 +--
 drivers/gpu/drm/radeon/r100.c|   57 +
 drivers/gpu/drm/radeon/r300.c|4 +-
 drivers/gpu/drm/radeon/r600.c|   10 +-
 drivers/gpu/drm/radeon/radeon.h  |   16 ++---
 drivers/gpu/drm/radeon/radeon_asic.h |5 ---
 drivers/gpu/drm/radeon/radeon_ring.c |   53 +++
 drivers/gpu/drm/radeon/si.c  |5 +--
 9 files changed, 69 insertions(+), 91 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index 26848d6..e304858 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -2424,7 +2424,6 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev, 
struct radeon_ring *rin
u32 srbm_status;
u32 grbm_status;
u32 grbm_status_se0, grbm_status_se1;
-   struct r100_gpu_lockup *lockup = &rdev->config.evergreen.lockup;
int r;

srbm_status = RREG32(SRBM_STATUS);
@@ -2432,7 +2431,7 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev, 
struct radeon_ring *rin
grbm_status_se0 = RREG32(GRBM_STATUS_SE0);
grbm_status_se1 = RREG32(GRBM_STATUS_SE1);
if (!(grbm_status & GUI_ACTIVE)) {
-   r100_gpu_lockup_update(lockup, ring);
+   radeon_ring_lockup_update(ring);
return false;
}
/* force CP activities */
@@ -2444,7 +2443,7 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev, 
struct radeon_ring *rin
radeon_ring_unlock_commit(rdev, ring);
}
ring->rptr = RREG32(CP_RB_RPTR);
-   return r100_gpu_cp_is_lockup(rdev, lockup, ring);
+   return radeon_ring_test_lockup(rdev, ring);
 }

 static int evergreen_gpu_soft_reset(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index c0b0956..4327b32 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1397,7 +1397,6 @@ bool cayman_gpu_is_lockup(struct radeon_device *rdev, 
struct radeon_ring *ring)
u32 srbm_status;
u32 grbm_status;
u32 grbm_status_se0, grbm_status_se1;
-   struct r100_gpu_lockup *lockup = &rdev->config.cayman.lockup;
int r;

srbm_status = RREG32(SRBM_STATUS);
@@ -1405,7 +1404,7 @@ bool cayman_gpu_is_lockup(struct radeon_device *rdev, 
struct radeon_ring *ring)
grbm_status_se0 = RREG32(GRBM_STATUS_SE0);
grbm_status_se1 = RREG32(GRBM_STATUS_SE1);
if (!(grbm_status & GUI_ACTIVE)) {
-   r100_gpu_lockup_update(lockup, ring);
+   radeon_ring_lockup_update(ring);
return false;
}
/* force CP activities */
@@ -1418,7 +1417,7 @@ bool cayman_gpu_is_lockup(struct radeon_device *rdev, 
struct radeon_ring *ring)
}
/* XXX deal with CP0,1,2 */
ring->rptr = RREG32(ring->rptr_reg);
-   return r100_gpu_cp_is_lockup(rdev, lockup, ring);
+   return radeon_ring_test_lockup(rdev, ring);
 }

 static int cayman_gpu_soft_reset(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 62f9dab..20bf498 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -2159,59 +2159,6 @@ int r100_mc_wait_for_idle(struct radeon_device *rdev)
return -1;
 }

-void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, struct radeon_ring 
*ring)
-{
-   lockup->last_cp_rptr = ring->rptr;
-   lockup->last_jiffies = jiffies;
-}
-
-/**
- * r100_gpu_cp_is_lockup() - check if CP is lockup by recording information
- * @rdev:  radeon device structure
- * @lockup:r100_gpu_lockup structure holding CP lockup tracking 
informations
- * @cp:radeon_cp structure holding CP information
- *
- * We don't need to initialize the lockup tracking information as we will 
either
- * have CP rptr to a different value of jiffies wrap around which will force
- * initialization of the lockup tracking informations.
- *
- * A possible false positivie is if we get call after while and last_cp_rptr ==
- * the current CP rptr, even if it's unlikely it might happen. To avoid this
- * if the elapsed time since last call is bigger than 2 second than we return
- * false and update the tracking information. Due to this the caller must call
- * r100_gpu_cp_is_lockup several time in less than 2sec for lockup to be 
reported
- * the fencing code should be cautious about that.
- *
- * Caller should write to the ring to force CP to do something so we don't get
- * false positive when CP is just gived nothing to do.
- *
- **/
-bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup 
*lockup, struct radeon_ring *ring)
-{
-   unsign

[PATCH 25/26] drm/radeon: remove r300_gpu_is_lockup

2012-04-30 Thread Christian König
Since it is now identical to r100_gpu_is_lockup.

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/r300.c|   14 --
 drivers/gpu/drm/radeon/radeon_asic.c |   16 
 drivers/gpu/drm/radeon/radeon_asic.h |1 -
 3 files changed, 8 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 04ec269..6419a59 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -377,20 +377,6 @@ void r300_gpu_init(struct radeon_device *rdev)
 rdev->num_gb_pipes, rdev->num_z_pipes);
 }

-bool r300_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
-{
-   u32 rbbm_status;
-
-   rbbm_status = RREG32(R_000E40_RBBM_STATUS);
-   if (!G_000E40_GUI_ACTIVE(rbbm_status)) {
-   radeon_ring_lockup_update(ring);
-   return false;
-   }
-   /* force CP activities */
-   radeon_ring_force_activity(rdev, ring);
-   return radeon_ring_test_lockup(rdev, ring);
-}
-
 int r300_asic_reset(struct radeon_device *rdev)
 {
struct r100_mc_save save;
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c 
b/drivers/gpu/drm/radeon/radeon_asic.c
index 958b9ea..5e5694e 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -299,7 +299,7 @@ static struct radeon_asic r300_asic = {
.ring_start = &r300_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
-   .is_lockup = &r300_gpu_is_lockup,
+   .is_lockup = &r100_gpu_is_lockup,
}
},
.irq = {
@@ -373,7 +373,7 @@ static struct radeon_asic r300_asic_pcie = {
.ring_start = &r300_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
-   .is_lockup = &r300_gpu_is_lockup,
+   .is_lockup = &r100_gpu_is_lockup,
}
},
.irq = {
@@ -447,7 +447,7 @@ static struct radeon_asic r420_asic = {
.ring_start = &r300_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
-   .is_lockup = &r300_gpu_is_lockup,
+   .is_lockup = &r100_gpu_is_lockup,
}
},
.irq = {
@@ -521,7 +521,7 @@ static struct radeon_asic rs400_asic = {
.ring_start = &r300_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
-   .is_lockup = &r300_gpu_is_lockup,
+   .is_lockup = &r100_gpu_is_lockup,
}
},
.irq = {
@@ -595,7 +595,7 @@ static struct radeon_asic rs600_asic = {
.ring_start = &r300_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
-   .is_lockup = &r300_gpu_is_lockup,
+   .is_lockup = &r100_gpu_is_lockup,
}
},
.irq = {
@@ -669,7 +669,7 @@ static struct radeon_asic rs690_asic = {
.ring_start = &r300_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
-   .is_lockup = &r300_gpu_is_lockup,
+   .is_lockup = &r100_gpu_is_lockup,
}
},
.irq = {
@@ -743,7 +743,7 @@ static struct radeon_asic rv515_asic = {
.ring_start = &rv515_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
-   .is_lockup = &r300_gpu_is_lockup,
+   .is_lockup = &r100_gpu_is_lockup,
}
},
.irq = {
@@ -817,7 +817,7 @@ static struct radeon_asic r520_asic = {
.ring_start = &rv515_ring_start,
.ring_test = &r100_ring_test,
.ib_test = &r100_ib_test,
-   .is_lockup = &r300_gpu_is_lockup,
+   .is_lockup = &r100_gpu_is_lockup,
}
},
.irq = {
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h 
b/drivers/gpu/drm/radeon/radeon_asic.h
index b0941f9..1e128e0 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -154,7 +154,6 @@ extern int r300_init(struct radeon_device *rdev);
 extern void r300_fini(struct radeon_device *rdev);
 extern int r300_suspend(struct radeon_device *rdev);
 extern int r300_resume(struct radeon_device *rdev);
-extern bool r300_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring 
*cp);
 extern int r300_asic_reset(struct radeon_device *rdev);
 extern voi

  1   2   >