[PATCH] fixing dmi match for hp t5745 and hp st5747 thin client

2012-05-02 Thread Daniel Vetter
On Wed, May 02, 2012 at 01:44:15PM -0400, Adam Jackson wrote:
> On 5/1/12 1:37 PM, Marc Gariepy wrote:
> >Match the correct information which is DMI_PRODUCT_NAME instead of 
> >DMI_BOARD_NAME
> >See dmidecode information on launchpad for both thin client:
> >
> >https://bugs.launchpad.net/ubuntu/+source/linux/+bug/911920
> >https://bugs.launchpad.net/ubuntu/+source/linux/+bug/911916
> 
> Reviewed-by: Adam Jackson 
Picked up for -fixes, thanks for the patch. It's a bit late in the -rc
series, but I've figure we better fix up the broken quirk entry.
-Daniel
-- 
Daniel Vetter
Mail: daniel at ffwll.ch
Mobile: +41 (0)79 365 57 48


Linux 3.4-rc4

2012-05-02 Thread Ben Skeggs
On Wed, 2012-05-02 at 09:54 +0200, Jean Delvare wrote:
> Hi Luca, Maarten,
> 
> On Monday 30 April 2012 01:01:30 pm Luca Tettamanti wrote:
> > On Mon, Apr 30, 2012 at 11:07 AM, Maarten Maathuis  > gmail.com> 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:
> > >>> > > 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
> > >>> > > 832x62474.6
> > >>> > > 800x60085.1 72.2 75.0 60.3 56.2
> > >>> > > 848x48060.0
> > >>> > > 640x48085.0 75.0 72.8 72.8 66.7 
> > >>> > > 60.0 59.9
> > >>> > > 720x40085.0 87.8 70.1
> > >>> > > 640x40085.1
> > >>> > > 640x35085.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*
> > >>> > > 800x60060.3 56.2
> > >>> > > 848x48060.0
> > >>> > > 640x48059.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]
> > >> 

[PATCH] nouveau: initialise has_optimus variable.

2012-05-02 Thread Dave Airlie
From: Dave Airlie 

We should initialise this to 0 really to avoid getting false positives.

Signed-off-by: Dave Airlie 
---
 drivers/gpu/drm/nouveau/nouveau_acpi.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c 
b/drivers/gpu/drm/nouveau/nouveau_acpi.c
index 7814a76..284bd25 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -270,7 +270,7 @@ static bool nouveau_dsm_detect(void)
struct acpi_buffer buffer = {sizeof(acpi_method_name), 
acpi_method_name};
struct pci_dev *pdev = NULL;
int has_dsm = 0;
-   int has_optimus;
+   int has_optimus = 0;
int vga_count = 0;
bool guid_valid;
int retval;
-- 
1.7.7.6



[PATCH 13/13] gma500: mdfld_dsi_dpi_mode_set() do not corrupt DSPSTRIDE

2012-05-02 Thread Alan Cox
From: Kirill A. Shutemov 

The proper stride value set in mdfld__intel_pipe_set_base().

TODO: move tc35876x support to separate driver and get rid of all
if (mdfld_get_panel_type(dev, pipe) == TC35876X) { ... }

Signed-off-by: Kirill A. Shutemov 
Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/mdfld_dsi_dpi.c |1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c 
b/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c
index d52358b..b34ff09 100644
--- a/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c
+++ b/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c
@@ -869,7 +869,6 @@ void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder,
mdfld_set_pipe_timing(dsi_config, pipe);

REG_WRITE(DSPABASE, 0x00);
-   REG_WRITE(DSPASTRIDE, (mode->hdisplay * 4));
REG_WRITE(DSPASIZE,
((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));




[PATCH 12/13] gma500: mid-bios: rewrite VBT/GCT handling in a cleaner way

2012-05-02 Thread Alan Cox
From: Kirill A. Shutemov 

Signed-off-by: Kirill A. Shutemov 
Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/mid_bios.c|  295 +++---
 drivers/gpu/drm/gma500/oaktrail.h|   25 +--
 drivers/gpu/drm/gma500/oaktrail_device.c |8 -
 drivers/gpu/drm/gma500/oaktrail_lvds.c   |4 
 drivers/gpu/drm/gma500/psb_drv.h |2 
 5 files changed, 203 insertions(+), 131 deletions(-)

diff --git a/drivers/gpu/drm/gma500/mid_bios.c 
b/drivers/gpu/drm/gma500/mid_bios.c
index 5eee9ad..b2a790b 100644
--- a/drivers/gpu/drm/gma500/mid_bios.c
+++ b/drivers/gpu/drm/gma500/mid_bios.c
@@ -118,139 +118,214 @@ static void mid_get_pci_revID(struct drm_psb_private 
*dev_priv)
dev_priv->platform_rev_id);
 }

+struct vbt_header {
+   u32 signature;
+   u8 revision;
+} __packed;
+
+/* The same for r0 and r1 */
+struct vbt_r0 {
+   struct vbt_header vbt_header;
+   u8 size;
+   u8 checksum;
+} __packed;
+
+struct vbt_r10 {
+   struct vbt_header vbt_header;
+   u8 checksum;
+   u16 size;
+   u8 panel_count;
+   u8 primary_panel_idx;
+   u8 secondary_panel_idx;
+   u8 __reserved[5];
+} __packed;
+
+static int read_vbt_r0(u32 addr, struct vbt_r0 *vbt)
+{
+   void __iomem *vbt_virtual;
+
+   vbt_virtual = ioremap(addr, sizeof(*vbt));
+   if (vbt_virtual == NULL)
+   return -1;
+
+   memcpy_fromio(vbt, vbt_virtual, sizeof(*vbt));
+   iounmap(vbt_virtual);
+
+   return 0;
+}
+
+static int read_vbt_r10(u32 addr, struct vbt_r10 *vbt)
+{
+   void __iomem *vbt_virtual;
+
+   vbt_virtual = ioremap(addr, sizeof(*vbt));
+   if (!vbt_virtual)
+   return -1;
+
+   memcpy_fromio(vbt, vbt_virtual, sizeof(*vbt));
+   iounmap(vbt_virtual);
+
+   return 0;
+}
+
+static int mid_get_vbt_data_r0(struct drm_psb_private *dev_priv, u32 addr)
+{
+   struct vbt_r0 vbt;
+   void __iomem *gct_virtual;
+   struct gct_r0 gct;
+   u8 bpi;
+
+   if (read_vbt_r0(addr, ))
+   return -1;
+
+   gct_virtual = ioremap(addr + sizeof(vbt), vbt.size - sizeof(vbt));
+   if (!gct_virtual)
+   return -1;
+   memcpy_fromio(, gct_virtual, sizeof(gct));
+   iounmap(gct_virtual);
+
+   bpi = gct.PD.BootPanelIndex;
+   dev_priv->gct_data.bpi = bpi;
+   dev_priv->gct_data.pt = gct.PD.PanelType;
+   dev_priv->gct_data.DTD = gct.panel[bpi].DTD;
+   dev_priv->gct_data.Panel_Port_Control =
+   gct.panel[bpi].Panel_Port_Control;
+   dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
+   gct.panel[bpi].Panel_MIPI_Display_Descriptor;
+
+   return 0;
+}
+
+static int mid_get_vbt_data_r1(struct drm_psb_private *dev_priv, u32 addr)
+{
+   struct vbt_r0 vbt;
+   void __iomem *gct_virtual;
+   struct gct_r1 gct;
+   u8 bpi;
+
+   if (read_vbt_r0(addr, ))
+   return -1;
+
+   gct_virtual = ioremap(addr + sizeof(vbt), vbt.size - sizeof(vbt));
+   if (!gct_virtual)
+   return -1;
+   memcpy_fromio(, gct_virtual, sizeof(gct));
+   iounmap(gct_virtual);
+
+   bpi = gct.PD.BootPanelIndex;
+   dev_priv->gct_data.bpi = bpi;
+   dev_priv->gct_data.pt = gct.PD.PanelType;
+   dev_priv->gct_data.DTD = gct.panel[bpi].DTD;
+   dev_priv->gct_data.Panel_Port_Control =
+   gct.panel[bpi].Panel_Port_Control;
+   dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
+   gct.panel[bpi].Panel_MIPI_Display_Descriptor;
+
+   return 0;
+}
+
+static int mid_get_vbt_data_r10(struct drm_psb_private *dev_priv, u32 addr)
+{
+   struct vbt_r10 vbt;
+   void __iomem *gct_virtual;
+   struct gct_r10 *gct;
+   struct oaktrail_timing_info *dp_ti = _priv->gct_data.DTD;
+   struct gct_r10_timing_info *ti;
+   int ret = -1;
+
+   if (read_vbt_r10(addr, ))
+   return -1;
+
+   gct = kmalloc(sizeof(*gct) * vbt.panel_count, GFP_KERNEL);
+   if (!gct)
+   return -1;
+
+   gct_virtual = ioremap(addr + sizeof(vbt),
+   sizeof(*gct) * vbt.panel_count);
+   if (!gct_virtual)
+   goto out;
+   memcpy_fromio(gct, gct_virtual, sizeof(*gct));
+   iounmap(gct_virtual);
+
+   dev_priv->gct_data.bpi = vbt.primary_panel_idx;
+   dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
+   gct[vbt.primary_panel_idx].Panel_MIPI_Display_Descriptor;
+
+   ti = [vbt.primary_panel_idx].DTD;
+   dp_ti->pixel_clock = ti->pixel_clock;
+   dp_ti->hactive_hi = ti->hactive_hi;
+   dp_ti->hactive_lo = ti->hactive_lo;
+   dp_ti->hblank_hi = ti->hblank_hi;
+   dp_ti->hblank_lo = ti->hblank_lo;
+   dp_ti->hsync_offset_hi = ti->hsync_offset_hi;
+   dp_ti->hsync_offset_lo = ti->hsync_offset_lo;
+   dp_ti->hsync_pulse_width_hi = 

[PATCH 11/13] gma500: fix -Wmissing-include-dirs warnings

2012-05-02 Thread Alan Cox
From: Kirill A. Shutemov 

cc1: warning: include/drm: No such file or directory [enabled by default]

It's reproducible if you build with O=/some/obj/dir and W=1.

Signed-off-by: Kirill A. Shutemov 
Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/Makefile |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/gma500/Makefile b/drivers/gpu/drm/gma500/Makefile
index efdad01..dd7d6b5 100644
--- a/drivers/gpu/drm/gma500/Makefile
+++ b/drivers/gpu/drm/gma500/Makefile
@@ -1,7 +1,7 @@
 #
 #  KMS driver for the GMA500
 #
-ccflags-y += -Iinclude/drm
+ccflags-y += -I$(srctree)/include/drm

 gma500_gfx-y += gem_glue.o \
  accel_2d.o \



[PATCH 10/13] gma500: cdv_intel_lvds: mark cdv_intel_lvds_enc_funcs as static

2012-05-02 Thread Alan Cox
From: Kirill A. Shutemov 

Signed-off-by: Kirill A. Shutemov 
Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/cdv_intel_lvds.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c 
b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
index 44a8353..ff5b58e 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
@@ -556,7 +556,7 @@ static void cdv_intel_lvds_enc_destroy(struct drm_encoder 
*encoder)
drm_encoder_cleanup(encoder);
 }

-const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = {
+static const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = {
.destroy = cdv_intel_lvds_enc_destroy,
 };




[PATCH 09/13] gma500: oaktrail_hdmi_i2c_handler(): base should be __iomem

2012-05-02 Thread Alan Cox
From: Kirill A. Shutemov 

Signed-off-by: Kirill A. Shutemov 
Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c 
b/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c
index 5e84fbd..88627e3 100644
--- a/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c
+++ b/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c
@@ -250,7 +250,7 @@ static irqreturn_t oaktrail_hdmi_i2c_handler(int this_irq, 
void *dev)
  */
 static void oaktrail_hdmi_i2c_gpio_fix(void)
 {
-   void *base;
+   void __iomem *base;
unsigned int gpio_base = 0xff12c000;
int gpio_len = 0x1000;
u32 temp;



[PATCH 08/13] gma500: lid_state should be __iomem

2012-05-02 Thread Alan Cox
From: Kirill A. Shutemov 

This was mostly already fixed but this one change is needed to match Kirill's
original submission

Signed-off-by: Kirill A. Shutemov 
Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/opregion.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/gma500/opregion.c 
b/drivers/gpu/drm/gma500/opregion.c
index 483e0b2..05661bf 100644
--- a/drivers/gpu/drm/gma500/opregion.c
+++ b/drivers/gpu/drm/gma500/opregion.c
@@ -302,7 +302,7 @@ int psb_intel_opregion_setup(struct drm_device *dev)
struct drm_psb_private *dev_priv = dev->dev_private;
struct psb_intel_opregion *opregion = _priv->opregion;
u32 opregion_phy, mboxes;
-   void *base;
+   void __iomem *base;
int err = 0;

pci_read_config_dword(dev->pdev, PCI_ASLS, _phy);



[PATCH 07/13] gma500: psb_irq_turn_off_dpst() fix bit operation

2012-05-02 Thread Alan Cox
From: Kirill A. Shutemov 

Signed-off-by: Kirill A. Shutemov 
Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/psb_irq.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c
index 4ffb2a0..8652cdf 100644
--- a/drivers/gpu/drm/gma500/psb_irq.c
+++ b/drivers/gpu/drm/gma500/psb_irq.c
@@ -426,7 +426,7 @@ void psb_irq_turn_off_dpst(struct drm_device *dev)
psb_disable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE);

pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
-   PSB_WVDC32(pwm_reg & !(PWM_PHASEIN_INT_ENABLE),
+   PSB_WVDC32(pwm_reg & ~PWM_PHASEIN_INT_ENABLE,
PWM_CONTROL_LOGIC);
pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);




[PATCH 06/13] gma500: framebuffer: mark psb_fb_helper_funcs as static

2012-05-02 Thread Alan Cox
From: Kirill A. Shutemov 

Signed-off-by: Kirill A. Shutemov 
Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/framebuffer.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/gma500/framebuffer.c 
b/drivers/gpu/drm/gma500/framebuffer.c
index 30400b6..f47f883 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -572,7 +572,7 @@ static int psbfb_probe(struct drm_fb_helper *helper,
return new_fb;
 }

-struct drm_fb_helper_funcs psb_fb_helper_funcs = {
+static struct drm_fb_helper_funcs psb_fb_helper_funcs = {
.gamma_set = psbfb_gamma_set,
.gamma_get = psbfb_gamma_get,
.fb_probe = psbfb_probe,



[PATCH 05/13] gma500: vram_addr should be __iomem

2012-05-02 Thread Alan Cox
From: Kirill A. Shutemov 

Signed-off-by: Kirill A. Shutemov 
Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/framebuffer.c |3 +--
 drivers/gpu/drm/gma500/psb_drv.h |2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/gma500/framebuffer.c 
b/drivers/gpu/drm/gma500/framebuffer.c
index 4fc0d08..30400b6 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -455,8 +455,7 @@ static int psbfb_create(struct psb_fbdev *fbdev,
info->fix.ypanstep = 0;

/* Accessed stolen memory directly */
-   info->screen_base = (char *)dev_priv->vram_addr +
-   backing->offset;
+   info->screen_base = dev_priv->vram_addr + backing->offset;
info->screen_size = size;

if (dev_priv->gtt.stolen_size) {
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index e59511d..67a863b 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -509,7 +509,7 @@ struct drm_psb_private {
struct page *scratch_page;
u32 __iomem *gtt_map;
uint32_t stolen_base;
-   void *vram_addr;
+   u8 __iomem *vram_addr;
unsigned long vram_stolen_size;
int gtt_initialized;
u16 gmch_ctrl;  /* Saved GTT setup */



[PATCH 04/13] gma500: sgx_reg and vdc_reg should be __iomem

2012-05-02 Thread Alan Cox
From: Kirill A. Shutemov 

Signed-off-by: Kirill A. Shutemov 
Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/psb_drv.h |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index 9dc4476..e59511d 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -525,8 +525,8 @@ struct drm_psb_private {
 * Register base
 */

-   uint8_t *sgx_reg;
-   uint8_t *vdc_reg;
+   uint8_t __iomem *sgx_reg;
+   uint8_t __iomem *vdc_reg;
uint32_t gatt_free_offset;

/*



[PATCH 03/13] gma500: gtt: fix __iomem sparse warnings

2012-05-02 Thread Alan Cox
From: Kirill A. Shutemov 

Signed-off-by: Kirill A. Shutemov 
Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/gtt.c |   11 +++
 drivers/gpu/drm/gma500/psb_drv.h |2 +-
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c
index 7d6f737..4cd33df 100644
--- a/drivers/gpu/drm/gma500/gtt.c
+++ b/drivers/gpu/drm/gma500/gtt.c
@@ -61,7 +61,7 @@ static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int 
type)
  * Given a gtt_range object return the GTT offset of the page table
  * entries for this gtt_range
  */
-static u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
+static u32 __iomem *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
 {
struct drm_psb_private *dev_priv = dev->dev_private;
unsigned long offset;
@@ -82,7 +82,8 @@ static u32 *psb_gtt_entry(struct drm_device *dev, struct 
gtt_range *r)
  */
 static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
 {
-   u32 *gtt_slot, pte;
+   u32 __iomem *gtt_slot;
+   u32 pte;
struct page **pages;
int i;

@@ -126,7 +127,8 @@ static int psb_gtt_insert(struct drm_device *dev, struct 
gtt_range *r)
 static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
 {
struct drm_psb_private *dev_priv = dev->dev_private;
-   u32 *gtt_slot, pte;
+   u32 __iomem *gtt_slot;
+   u32 pte;
int i;

WARN_ON(r->stolen);
@@ -152,7 +154,8 @@ static void psb_gtt_remove(struct drm_device *dev, struct 
gtt_range *r)
  */
 void psb_gtt_roll(struct drm_device *dev, struct gtt_range *r, int roll)
 {
-   u32 *gtt_slot, pte;
+   u32 __iomem *gtt_slot;
+   u32 pte;
int i;

if (roll >= r->npage) {
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index 5c5c3d0..9dc4476 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -507,7 +507,7 @@ struct drm_psb_private {
/* GTT Memory manager */
struct psb_gtt_mm *gtt_mm;
struct page *scratch_page;
-   u32 *gtt_map;
+   u32 __iomem *gtt_map;
uint32_t stolen_base;
void *vram_addr;
unsigned long vram_stolen_size;



[PATCH 02/13] gma500: psb_gtt_init(): drop unused variable

2012-05-02 Thread Alan Cox
From: Kirill A. Shutemov 

Signed-off-by: Kirill A. Shutemov 
Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/gtt.c |3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c
index 54e5c9e..7d6f737 100644
--- a/drivers/gpu/drm/gma500/gtt.c
+++ b/drivers/gpu/drm/gma500/gtt.c
@@ -413,7 +413,6 @@ int psb_gtt_init(struct drm_device *dev, int resume)
unsigned long stolen_size, vram_stolen_size;
unsigned i, num_pages;
unsigned pfn_base;
-   uint32_t vram_pages;
uint32_t dvmt_mode = 0;
struct psb_gtt *pg;

@@ -529,7 +528,7 @@ int psb_gtt_init(struct drm_device *dev, int resume)
 */

pfn_base = dev_priv->stolen_base >> PAGE_SHIFT;
-   vram_pages = num_pages = vram_stolen_size >> PAGE_SHIFT;
+   num_pages = vram_stolen_size >> PAGE_SHIFT;
printk(KERN_INFO"Set up %d stolen pages starting at 0x%08x, GTT offset 
%dK\n",
num_pages, pfn_base << PAGE_SHIFT, 0);
for (i = 0; i < num_pages; ++i) {



[PATCH 01/13] gma500: address the lid code

2012-05-02 Thread Alan Cox
From: Alan Cox 

We need this for Poulsbo

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/psb_drv.c |2 +-
 drivers/gpu/drm/gma500/psb_drv.h |1 -
 drivers/gpu/drm/gma500/psb_lid.c |2 +-
 3 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index fc6045f..0e85978 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -351,7 +351,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned 
long chipset)
PSB_WSGX32(0x3000, PSB_CR_BIF_3D_REQ_BASE);

acpi_video_register();
-   if (dev_priv->lid_state)
+   if (dev_priv->opregion.lid_state)
psb_lid_timer_init(dev_priv);

ret = drm_vblank_init(dev, dev_priv->num_pipe);
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index 3773936..5c5c3d0 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -640,7 +640,6 @@ struct drm_psb_private {
spinlock_t lid_lock;
struct timer_list lid_timer;
struct psb_intel_opregion opregion;
-   u32 *lid_state;
u32 lid_last_state;

/*
diff --git a/drivers/gpu/drm/gma500/psb_lid.c b/drivers/gpu/drm/gma500/psb_lid.c
index b867aab..7ff8bb2b 100644
--- a/drivers/gpu/drm/gma500/psb_lid.c
+++ b/drivers/gpu/drm/gma500/psb_lid.c
@@ -29,7 +29,7 @@ static void psb_lid_timer_func(unsigned long data)
struct drm_device *dev = (struct drm_device *)dev_priv->dev;
struct timer_list *lid_timer = _priv->lid_timer;
unsigned long irq_flags;
-   u32 *lid_state = dev_priv->lid_state;
+   u32 __iomem *lid_state = dev_priv->opregion.lid_state;
u32 pp_status;

if (readl(lid_state) == dev_priv->lid_last_state)



[PATCH 00/13] More GMA500 work

2012-05-02 Thread Alan Cox
This follows on from the last set and sorts out the lid regression
they caused on the Poulsbo devices. It then includes another pile
of clean up work and Medfield fixes from Kirill.
---

Alan Cox (1):
  gma500: address the lid code

Kirill A. Shutemov (12):
  gma500: mdfld_dsi_dpi_mode_set() do not corrupt DSPSTRIDE
  gma500: mid-bios: rewrite VBT/GCT handling in a cleaner way
  gma500: fix -Wmissing-include-dirs warnings
  gma500: cdv_intel_lvds: mark cdv_intel_lvds_enc_funcs as static
  gma500: oaktrail_hdmi_i2c_handler(): base should be __iomem
  gma500: lid_state should be __iomem
  gma500: psb_irq_turn_off_dpst() fix bit operation
  gma500: framebuffer: mark psb_fb_helper_funcs as static
  gma500: vram_addr should be __iomem
  gma500: sgx_reg and vdc_reg should be __iomem
  gma500: gtt: fix __iomem sparse warnings
  gma500: psb_gtt_init(): drop unused variable


 drivers/gpu/drm/gma500/Makefile|2 
 drivers/gpu/drm/gma500/cdv_intel_lvds.c|2 
 drivers/gpu/drm/gma500/framebuffer.c   |5 
 drivers/gpu/drm/gma500/gtt.c   |   14 +
 drivers/gpu/drm/gma500/mdfld_dsi_dpi.c |1 
 drivers/gpu/drm/gma500/mid_bios.c  |  295 ++--
 drivers/gpu/drm/gma500/oaktrail.h  |   25 +-
 drivers/gpu/drm/gma500/oaktrail_device.c   |8 -
 drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c |2 
 drivers/gpu/drm/gma500/oaktrail_lvds.c |4 
 drivers/gpu/drm/gma500/opregion.c  |2 
 drivers/gpu/drm/gma500/psb_drv.c   |2 
 drivers/gpu/drm/gma500/psb_drv.h   |   11 -
 drivers/gpu/drm/gma500/psb_irq.c   |2 
 drivers/gpu/drm/gma500/psb_lid.c   |2 
 15 files changed, 224 insertions(+), 153 deletions(-)

-- 
#include 



[PATCH 3/4] drm/radeon: rework fence handling, drop fence list

2012-05-02 Thread Adam Jackson
On 5/2/12 4:20 PM, j.glisse at gmail.com wrote:
> + /* there is small chance that we overwritte a bigger last_emited
> +  * value, but in normal usage this
> +  */

Seems unfinished.  Also "overwrite".

- ajax


[PATCH] nouveau: initialise has_optimus variable.

2012-05-02 Thread Adam Jackson
On 5/2/12 3:24 PM, Dave Airlie wrote:
> From: Dave Airlie 
>
> We should initialise this to 0 really to avoid getting false positives.
>
> Signed-off-by: Dave Airlie 

Reviewed-by: Adam Jackson 

- ajax


[PATCH] drm/radeon: avoid leaking const ib (not used yet on si and newer GPU)

2012-05-02 Thread Alex Deucher
On Wed, May 2, 2012 at 4:24 PM,   wrote:
> From: Jerome Glisse 
>
> Signed-off-by: Jerome Glisse 

Reviewed-by: Alex Deucher 

> ---
> ?drivers/gpu/drm/radeon/radeon_cs.c | ? ?5 +
> ?1 files changed, 5 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
> b/drivers/gpu/drm/radeon/radeon_cs.c
> index 82f2e7b0..b3800cb 100644
> --- a/drivers/gpu/drm/radeon/radeon_cs.c
> +++ b/drivers/gpu/drm/radeon/radeon_cs.c
> @@ -161,6 +161,8 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, 
> void *data)
> ? ? ? ?/* get chunks */
> ? ? ? ?INIT_LIST_HEAD(>validated);
> ? ? ? ?p->idx = 0;
> + ? ? ? p->ib = NULL;
> + ? ? ? p->const_ib = NULL;
> ? ? ? ?p->chunk_ib_idx = -1;
> ? ? ? ?p->chunk_relocs_idx = -1;
> ? ? ? ?p->chunk_flags_idx = -1;
> @@ -318,6 +320,9 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser 
> *parser, int error)
> ? ? ? ?kfree(parser->chunks);
> ? ? ? ?kfree(parser->chunks_array);
> ? ? ? ?radeon_ib_free(parser->rdev, >ib);
> + ? ? ? if (parser->const_ib) {
> + ? ? ? ? ? ? ? radeon_ib_free(parser->rdev, >const_ib);
> + ? ? ? }
> ?}
>
> ?static int radeon_cs_ib_chunk(struct radeon_device *rdev,
> --
> 1.7.7.6
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 30383] [RADEON:KMS::R600C] GPU lockup / driver hang when playing ufoai

2012-05-02 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=30383

T?r?k Edwin  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution||FIXED

--- Comment #3 from T?r?k Edwin  2012-05-02 09:28:13 
PDT ---
(In reply to comment #1)
> Is this still an issue with recent kernel + recent mesa ?

I'm using the r600g driver since quite some time and I haven't seen any GPU
hangs.
ufoai seems to work too. I'll just close this bug then.

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


[PATCH] drm/radeon: avoid leaking const ib (not used yet on si and newer GPU)

2012-05-02 Thread j.gli...@gmail.com
From: Jerome Glisse 

Signed-off-by: Jerome Glisse 
---
 drivers/gpu/drm/radeon/radeon_cs.c |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
b/drivers/gpu/drm/radeon/radeon_cs.c
index 82f2e7b0..b3800cb 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -161,6 +161,8 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void 
*data)
/* get chunks */
INIT_LIST_HEAD(>validated);
p->idx = 0;
+   p->ib = NULL;
+   p->const_ib = NULL;
p->chunk_ib_idx = -1;
p->chunk_relocs_idx = -1;
p->chunk_flags_idx = -1;
@@ -318,6 +320,9 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser 
*parser, int error)
kfree(parser->chunks);
kfree(parser->chunks_array);
radeon_ib_free(parser->rdev, >ib);
+   if (parser->const_ib) {
+   radeon_ib_free(parser->rdev, >const_ib);
+   }
 }

 static int radeon_cs_ib_chunk(struct radeon_device *rdev,
-- 
1.7.7.6



[PATCH 4/4] drm/radeon: improve sa allocator to agressivly free idle bo

2012-05-02 Thread j.gli...@gmail.com
From: Jerome Glisse 

With fence rework it's now easier to agressivly free idle bo
when there is no hole to satisfy current allocation request.
The hit of some cs ioctl to have to go through the sa bo list
and free them is minimal, it happens once in while and avoid
some fence waiting.

Signed-off-by: Jerome Glisse 
---
 drivers/gpu/drm/radeon/radeon.h   |1 +
 drivers/gpu/drm/radeon/radeon_fence.c |2 +-
 drivers/gpu/drm/radeon/radeon_sa.c|   51 +---
 3 files changed, 48 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 141aee2..5459722 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -314,6 +314,7 @@ 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);
 unsigned radeon_fence_count_emitted(struct radeon_device *rdev, int ring);
+bool radeon_fence_poll(struct radeon_device *rdev, int ring);

 /*
  * Tiling registers
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 3f34f7b..043f431 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -78,7 +78,7 @@ int radeon_fence_emit(struct radeon_device *rdev, struct 
radeon_fence *fence)
return 0;
 }

-static bool radeon_fence_poll(struct radeon_device *rdev, int ring)
+bool radeon_fence_poll(struct radeon_device *rdev, int ring)
 {
uint64_t seq;

diff --git a/drivers/gpu/drm/radeon/radeon_sa.c 
b/drivers/gpu/drm/radeon/radeon_sa.c
index e758aaa..2cbf5ba 100644
--- a/drivers/gpu/drm/radeon/radeon_sa.c
+++ b/drivers/gpu/drm/radeon/radeon_sa.c
@@ -48,6 +48,10 @@
 #include "drm.h"
 #include "radeon.h"

+static bool radeon_sa_manager_try_free(struct radeon_device *rdev,
+  struct radeon_sa_manager *sa_manager,
+  struct radeon_sa_bo *oldest);
+
 int radeon_sa_bo_manager_init(struct radeon_device *rdev,
  struct radeon_sa_manager *sa_manager,
  unsigned size, u32 domain)
@@ -77,7 +81,16 @@ void radeon_sa_bo_manager_fini(struct radeon_device *rdev,
struct radeon_sa_bo *sa_bo, *tmp;

if (!list_empty(_manager->sa_bo)) {
-   dev_err(rdev->dev, "sa_manager is not empty, clearing 
anyway\n");
+   struct radeon_sa_bo *oldest;
+
+   /* try to free them */
+   oldest =  list_entry(sa_manager->sa_bo.next, struct 
radeon_sa_bo, list);
+   radeon_sa_manager_try_free(rdev, sa_manager, oldest);
+
+   if (!list_empty(_manager->sa_bo)) {
+   /* something went wrong */
+   dev_err(rdev->dev, "sa_manager is not empty, clearing 
anyway\n");
+   }
}
list_for_each_entry_safe(sa_bo, tmp, _manager->sa_bo, list) {
list_del_init(_bo->list);
@@ -171,15 +184,43 @@ static void radeon_sa_bo_free_locked(struct radeon_device 
*rdev, struct radeon_s
 }

 static bool radeon_sa_manager_try_free(struct radeon_device *rdev,
+  struct radeon_sa_manager *sa_manager,
   struct radeon_sa_bo *oldest)
 {
-   if (oldest->fence && oldest->fence->emitted) {
-   if (radeon_fence_signaled(oldest->fence)) {
+   struct radeon_sa_bo *tmp, *sa_bo;
+   unsigned ring, free_count = 0;
+
+   if (oldest->fence == NULL || !oldest->fence->emitted) {
+   return false;
+   }
+   ring = oldest->fence->ring;
+   radeon_fence_poll(rdev, ring);
+   if (rdev->fence_drv[ring].last_seq < oldest->fence->seq) {
+   return false;
+   }
+   free_count++;
+   /* go over the remaining of the list and try to free as much
+* as possible
+*/
+   sa_bo = oldest;
+   list_for_each_entry_safe_continue(sa_bo, tmp, _manager->sa_bo, list) 
{
+   if (sa_bo->fence == NULL || !sa_bo->fence->emitted) {
+   radeon_sa_bo_free_locked(rdev, oldest);
+   return true;
+   }
+   if (ring != sa_bo->fence->ring) {
+   ring = sa_bo->fence->ring;
+   radeon_fence_poll(rdev, ring);
+   }
+   if (rdev->fence_drv[ring].last_seq < sa_bo->fence->seq) {
radeon_sa_bo_free_locked(rdev, oldest);
return true;
}
+   radeon_sa_bo_free_locked(rdev, sa_bo);
+   free_count++;
}
-   return false;
+   radeon_sa_bo_free_locked(rdev, oldest);
+   return true;
 }

 /*
@@ -260,7 +301,7 @@ retry:
}
}
/* try to be optimist and free the oldest 

[PATCH 3/4] drm/radeon: rework fence handling, drop fence list

2012-05-02 Thread j.gli...@gmail.com
From: Jerome Glisse 

Using 64bits fence sequence we can directly compare sequence
number to know if a fence is signaled or not. Thus the fence
list became useless, so does the fence lock that mainly
protected the fence list.

Things like ring.ready are no longer behind a lock, this should
be ok as ring.ready is initialized once and will only change
when facing lockup. Worst case is that we return an -EBUSY just
after a successfull GPU reset, or we go into wait state instead
of returning -EBUSY (thus delaying reporting -EBUSY to fence
wait caller).

Signed-off-by: Jerome Glisse 
---
 drivers/gpu/drm/radeon/radeon.h|6 +-
 drivers/gpu/drm/radeon/radeon_device.c |1 -
 drivers/gpu/drm/radeon/radeon_fence.c  |  278 
 3 files changed, 102 insertions(+), 183 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 4c5a667..141aee2 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -286,15 +286,12 @@ struct radeon_fence_driver {
uint64_tlast_seq;
unsigned long   last_activity;
wait_queue_head_t   queue;
-   struct list_heademitted;
-   struct list_headsignaled;
boolinitialized;
 };

 struct radeon_fence {
struct radeon_device*rdev;
struct kref kref;
-   struct list_headlist;
/* protected by radeon_fence.lock */
uint64_tseq;
boolemitted;
@@ -316,7 +313,7 @@ int radeon_fence_wait_next(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);
+unsigned radeon_fence_count_emitted(struct radeon_device *rdev, int ring);

 /*
  * Tiling registers
@@ -1488,7 +1485,6 @@ struct radeon_device {
struct radeon_mode_info mode_info;
struct radeon_scratch   scratch;
struct radeon_mman  mman;
-   rwlock_tfence_lock;
struct radeon_fence_driver  fence_drv[RADEON_NUM_RINGS];
struct radeon_ring  ring[RADEON_NUM_RINGS];
boolib_pool_ready;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 3880aad..290b8d0 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -746,7 +746,6 @@ int radeon_device_init(struct radeon_device *rdev,
mutex_init(>gem.mutex);
mutex_init(>pm.mutex);
mutex_init(>vram_mutex);
-   rwlock_init(>fence_lock);
INIT_LIST_HEAD(>gem.objects);
init_waitqueue_head(>irq.vblank_queue);
init_waitqueue_head(>irq.idle_queue);
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 6da1535..3f34f7b 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -65,32 +65,22 @@ static u64 radeon_fence_read(struct radeon_device *rdev, 
int ring)

 int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence)
 {
-   unsigned long irq_flags;
-
-   write_lock_irqsave(>fence_lock, irq_flags);
if (fence->emitted) {
-   write_unlock_irqrestore(>fence_lock, irq_flags);
return 0;
}
fence->seq = atomic64_inc_return(>fence_drv[fence->ring].seq);
+   /* there is small chance that we overwritte a bigger last_emited
+* value, but in normal usage this
+*/
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(>fence_drv[fence->ring].emitted)) {
-   rdev->fence_drv[fence->ring].last_activity = jiffies;
-   }
-   list_move_tail(>list, >fence_drv[fence->ring].emitted);
-   write_unlock_irqrestore(>fence_lock, irq_flags);
return 0;
 }

-static bool radeon_fence_poll_locked(struct radeon_device *rdev, int ring)
+static bool radeon_fence_poll(struct radeon_device *rdev, int ring)
 {
-   struct radeon_fence *fence;
-   struct list_head *i, *n;
uint64_t seq;
-   bool wake = false;

seq = radeon_fence_read(rdev, ring);
if (seq == rdev->fence_drv[ring].last_seq)
@@ -98,40 +88,15 @@ static bool radeon_fence_poll_locked(struct radeon_device 
*rdev, int ring)

rdev->fence_drv[ring].last_seq = seq;
rdev->fence_drv[ring].last_activity = jiffies;
-
-   n = NULL;
-   

[PATCH 2/4] drm/radeon: convert fence to uint64_t

2012-05-02 Thread j.gli...@gmail.com
From: Jerome Glisse 

This convert fence to use uint64_t sequence number intention is
to use the fact that uin64_t is big enough that we don't need to
care about wrap around.

Tested with and without writeback using 0xF000 as initial
fence sequence and thus allowing to test the wrap around from
32bits to 64bits.

Signed-off-by: Jerome Glisse 
---
 drivers/gpu/drm/radeon/ni.c   |6 ++--
 drivers/gpu/drm/radeon/r100.c |5 ++-
 drivers/gpu/drm/radeon/r300.c |5 ++-
 drivers/gpu/drm/radeon/r600.c |   11 
 drivers/gpu/drm/radeon/radeon.h   |   20 +++---
 drivers/gpu/drm/radeon/radeon_fence.c |   43 +
 drivers/gpu/drm/radeon/si.c   |6 ++--
 7 files changed, 50 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 3160a74..416d7c2 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1120,9 +1120,9 @@ void cayman_fence_ring_emit(struct radeon_device *rdev,
radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | 
EVENT_INDEX(5));
radeon_ring_write(ring, addr & 0x);
-   radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | 
INT_SEL(2));
-   radeon_ring_write(ring, fence->seq);
-   radeon_ring_write(ring, 0);
+   radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(2) | 
INT_SEL(2));
+   radeon_ring_write(ring, lower_32_bits(fence->seq));
+   radeon_ring_write(ring, upper_32_bits(fence->seq));
 }

 void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 80b57c5..d6bd9ea 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -864,8 +864,9 @@ void r100_fence_ring_emit(struct radeon_device *rdev,
radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0));
radeon_ring_write(ring, rdev->config.r100.hdp_cntl);
/* Emit fence sequence & fire IRQ */
-   radeon_ring_write(ring, 
PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 0));
-   radeon_ring_write(ring, fence->seq);
+   radeon_ring_write(ring, 
PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 1));
+   radeon_ring_write(ring, lower_32_bits(fence->seq));
+   radeon_ring_write(ring, upper_32_bits(fence->seq));
radeon_ring_write(ring, PACKET0(RADEON_GEN_INT_STATUS, 0));
radeon_ring_write(ring, RADEON_SW_INT_FIRE);
 }
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 6419a59..7c9e30d 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -200,8 +200,9 @@ void r300_fence_ring_emit(struct radeon_device *rdev,
radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0));
radeon_ring_write(ring, rdev->config.r300.hdp_cntl);
/* Emit fence sequence & fire IRQ */
-   radeon_ring_write(ring, 
PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 0));
-   radeon_ring_write(ring, fence->seq);
+   radeon_ring_write(ring, 
PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 1));
+   radeon_ring_write(ring, lower_32_bits(fence->seq));
+   radeon_ring_write(ring, upper_32_bits(fence->seq));
radeon_ring_write(ring, PACKET0(RADEON_GEN_INT_STATUS, 0));
radeon_ring_write(ring, RADEON_SW_INT_FIRE);
 }
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 02abf32..4fbc590 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2313,9 +2313,9 @@ void r600_fence_ring_emit(struct radeon_device *rdev,
radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
radeon_ring_write(ring, 
EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5));
radeon_ring_write(ring, addr & 0x);
-   radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | 
DATA_SEL(1) | INT_SEL(2));
-   radeon_ring_write(ring, fence->seq);
-   radeon_ring_write(ring, 0);
+   radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | 
DATA_SEL(2) | INT_SEL(2));
+   radeon_ring_write(ring, lower_32_bits(fence->seq));
+   radeon_ring_write(ring, upper_32_bits(fence->seq));
} else {
/* flush read cache over gart */
radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
@@ -2332,9 +2332,10 @@ void r600_fence_ring_emit(struct radeon_device *rdev,
radeon_ring_write(ring, (WAIT_UNTIL - 
PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
radeon_ring_write(ring, WAIT_3D_IDLE_bit | 
WAIT_3D_IDLECLEAN_bit);
/* Emit fence sequence & fire IRQ */
-   radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
+   

[PATCH 1/4] drm/radeon: allow to allocate adjacent scratch reg

2012-05-02 Thread j.gli...@gmail.com
From: Jerome Glisse 

This add the number of adjacent scratch reg you want to allocate
or free to the scratch alloc/free function.

Signed-off-by: Jerome Glisse 
---
 drivers/gpu/drm/radeon/r100.c  |   12 ++--
 drivers/gpu/drm/radeon/r420.c  |4 ++--
 drivers/gpu/drm/radeon/r600.c  |   12 ++--
 drivers/gpu/drm/radeon/radeon.h|4 ++--
 drivers/gpu/drm/radeon/radeon_device.c |   31 +++
 drivers/gpu/drm/radeon/radeon_fence.c  |6 +++---
 6 files changed, 42 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index d47ffd5..80b57c5 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -3636,7 +3636,7 @@ int r100_ring_test(struct radeon_device *rdev, struct 
radeon_ring *ring)
unsigned i;
int r;

-   r = radeon_scratch_get(rdev, );
+   r = radeon_scratch_get(rdev, , 1);
if (r) {
DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r);
return r;
@@ -3645,7 +3645,7 @@ int r100_ring_test(struct radeon_device *rdev, struct 
radeon_ring *ring)
r = radeon_ring_lock(rdev, ring, 2);
if (r) {
DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
-   radeon_scratch_free(rdev, scratch);
+   radeon_scratch_free(rdev, scratch, 1);
return r;
}
radeon_ring_write(ring, PACKET0(scratch, 0));
@@ -3665,7 +3665,7 @@ int r100_ring_test(struct radeon_device *rdev, struct 
radeon_ring *ring)
  scratch, tmp);
r = -EINVAL;
}
-   radeon_scratch_free(rdev, scratch);
+   radeon_scratch_free(rdev, scratch, 1);
return r;
 }

@@ -3686,7 +3686,7 @@ int r100_ib_test(struct radeon_device *rdev, struct 
radeon_ring *ring)
unsigned i;
int r;

-   r = radeon_scratch_get(rdev, );
+   r = radeon_scratch_get(rdev, , 1);
if (r) {
DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r);
return r;
@@ -3707,7 +3707,7 @@ int r100_ib_test(struct radeon_device *rdev, struct 
radeon_ring *ring)
ib->length_dw = 8;
r = radeon_ib_schedule(rdev, ib);
if (r) {
-   radeon_scratch_free(rdev, scratch);
+   radeon_scratch_free(rdev, scratch, 1);
radeon_ib_free(rdev, );
return r;
}
@@ -3729,7 +3729,7 @@ int r100_ib_test(struct radeon_device *rdev, struct 
radeon_ring *ring)
  scratch, tmp);
r = -EINVAL;
}
-   radeon_scratch_free(rdev, scratch);
+   radeon_scratch_free(rdev, scratch, 1);
radeon_ib_free(rdev, );
return r;
 }
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c
index 99137be..5ba459b 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -207,7 +207,7 @@ static void r420_cp_errata_init(struct radeon_device *rdev)
 * The proper workaround is to queue a RESYNC at the beginning
 * of the CP init, apparently.
 */
-   radeon_scratch_get(rdev, >config.r300.resync_scratch);
+   radeon_scratch_get(rdev, >config.r300.resync_scratch, 1);
radeon_ring_lock(rdev, ring, 8);
radeon_ring_write(ring, PACKET0(R300_CP_RESYNC_ADDR, 1));
radeon_ring_write(ring, rdev->config.r300.resync_scratch);
@@ -226,7 +226,7 @@ static void r420_cp_errata_fini(struct radeon_device *rdev)
radeon_ring_write(ring, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
radeon_ring_write(ring, R300_RB3D_DC_FINISH);
radeon_ring_unlock_commit(rdev, ring);
-   radeon_scratch_free(rdev, rdev->config.r300.resync_scratch);
+   radeon_scratch_free(rdev, rdev->config.r300.resync_scratch, 1);
 }

 static int r420_startup(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 0cbcd3a..02abf32 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2261,7 +2261,7 @@ int r600_ring_test(struct radeon_device *rdev, struct 
radeon_ring *ring)
unsigned i, ridx = radeon_ring_index(rdev, ring);
int r;

-   r = radeon_scratch_get(rdev, );
+   r = radeon_scratch_get(rdev, , 1);
if (r) {
DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r);
return r;
@@ -2270,7 +2270,7 @@ int r600_ring_test(struct radeon_device *rdev, struct 
radeon_ring *ring)
r = radeon_ring_lock(rdev, ring, 3);
if (r) {
DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n", ridx, r);
-   radeon_scratch_free(rdev, scratch);
+   radeon_scratch_free(rdev, scratch, 1);
return r;
}
radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
@@ -2290,7 +2290,7 @@ int 

[RFC] Convert fence to use 64bits sequence

2012-05-02 Thread j.gli...@gmail.com
So this patchset convert the fence to use 64bits sequence and simplify
the fence code (dropping fence lock). I am still convinced that the
best solution is to have the various helper code deals with fence
cleanup/processing. The last patch show an example of what can be
done to improve sa allocator taking advantage of u64 fence.

Cheers,
Jerome


[PATCH] dri2proto: Fix documented opcodes

2012-05-02 Thread Kristian Høgsberg
On Wed, May 2, 2012 at 3:03 PM, Chad Versace
 wrote:
> Fix the documented opcodes in dri2proto.txt to be consistent with the
> actual opcode values in dri2proto.h and in xcb/proto:src/dri2.xml. (It
> looks like the opcodes were incorrect due to copy-paste errors).

Looks correct to me.

Kristian

> CC: Kristian H?gsberg 
> Signed-off-by: Chad Versace 
> ---
> ?dri2proto.txt | ? 18 +-
> ?1 file changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/dri2proto.txt b/dri2proto.txt
> index df763c7..7bde067 100644
> --- a/dri2proto.txt
> +++ b/dri2proto.txt
> @@ -658,7 +658,7 @@ A.2 Protocol Requests
> ?
> ? ? DRI2GetBuffers
> ? ? ? ?1 ? ? ? CARD8 ? ? ? ? ? ? ? ? ? major opcode
> - ? ? ? 1 ? ? ? 3 ? ? ? ? ? ? ? ? ? ? ? DRI2 opcode
> + ? ? ? 1 ? ? ? 5 ? ? ? ? ? ? ? ? ? ? ? DRI2 opcode
> ? ? ? ?2 ? ? ? 3 ? ? ? ? ? ? ? ? ? ? ? length
> ? ? ? ?4 ? ? ? DRAWABLE ? ? ? ? ? ? ? ?drawable
> ? ? ? ?4 ? ? ? n ? ? ? ? ? ? ? ? ? ? ? number of attachments
> @@ -678,7 +678,7 @@ A.2 Protocol Requests
> ?
> ? ? DRI2CopyRegion
> ? ? ? ?1 ? ? ? CARD8 ? ? ? ? ? ? ? ? ? major opcode
> - ? ? ? 1 ? ? ? 4 ? ? ? ? ? ? ? ? ? ? ? DRI2 opcode
> + ? ? ? 1 ? ? ? 6 ? ? ? ? ? ? ? ? ? ? ? DRI2 opcode
> ? ? ? ?2 ? ? ? 3 ? ? ? ? ? ? ? ? ? ? ? length
> ? ? ? ?4 ? ? ? DRAWABLE ? ? ? ? ? ? ? ?drawable
> ? ? ? ?4 ? ? ? REGION ? ? ? ? ? ? ? ? ?region
> @@ -695,7 +695,7 @@ A.2 Protocol Requests
> ?
> ? ? DRI2GetBuffersWithFormat
> ? ? ? ?1 ? ? ? CARD8 ? ? ? ? ? ? ? ? ? major opcode
> - ? ? ? 1 ? ? ? 3 ? ? ? ? ? ? ? ? ? ? ? DRI2 opcode
> + ? ? ? 1 ? ? ? 7 ? ? ? ? ? ? ? ? ? ? ? DRI2 opcode
> ? ? ? ?2 ? ? ? 3 ? ? ? ? ? ? ? ? ? ? ? length
> ? ? ? ?4 ? ? ? DRAWABLE ? ? ? ? ? ? ? ?drawable
> ? ? ? ?4 ? ? ? n ? ? ? ? ? ? ? ? ? ? ? number of attachments
> @@ -715,7 +715,7 @@ A.2 Protocol Requests
> ?
> ? ? DRI2SwapBuffers
> ? ? ? ?1 ? ? ? CARD8 ? ? ? ? ? ? ? ? ? major opcode
> - ? ? ? 1 ? ? ? 7 ? ? ? ? ? ? ? ? ? ? ? DRI2 opcode
> + ? ? ? 1 ? ? ? 8 ? ? ? ? ? ? ? ? ? ? ? DRI2 opcode
> ? ? ? ?2 ? ? ? 8 ? ? ? ? ? ? ? ? ? ? ? length
> ? ? ? ?4 ? ? ? DRAWABLE ? ? ? ? ? ? ? ?drawable
> ? ? ? ?
> @@ -736,7 +736,7 @@ A.2 Protocol Requests
> ?
> ? ? DRI2SwapBuffers
> ? ? ? ?1 ? ? ? CARD8 ? ? ? ? ? ? ? ? ? major opcode
> - ? ? ? 1 ? ? ? 7 ? ? ? ? ? ? ? ? ? ? ? DRI2 opcode
> + ? ? ? 1 ? ? ? 8 ? ? ? ? ? ? ? ? ? ? ? DRI2 opcode
> ? ? ? ?2 ? ? ? 8 ? ? ? ? ? ? ? ? ? ? ? length
> ? ? ? ?4 ? ? ? DRAWABLE ? ? ? ? ? ? ? ?drawable
> ? ? ? ?4 ? ? ? CARD32 ? ? ? ? ? ? ? ? ?target_msc_hi
> @@ -758,7 +758,7 @@ A.2 Protocol Requests
> ?
> ? ? DRI2GetMSC
> ? ? ? ?1 ? ? ? CARD8 ? ? ? ? ? ? ? ? ? major opcode
> - ? ? ? 1 ? ? ? 7 ? ? ? ? ? ? ? ? ? ? ? DRI2 opcode
> + ? ? ? 1 ? ? ? 9 ? ? ? ? ? ? ? ? ? ? ? DRI2 opcode
> ? ? ? ?2 ? ? ? 8 ? ? ? ? ? ? ? ? ? ? ? length
> ? ? ? ?4 ? ? ? DRAWABLE ? ? ? ? ? ? ? ?drawable
> ? ? ? ?
> @@ -777,7 +777,7 @@ A.2 Protocol Requests
> ?
> ? ? DRI2WaitMSC
> ? ? ? ?1 ? ? ? CARD8 ? ? ? ? ? ? ? ? ? major opcode
> - ? ? ? 1 ? ? ? 7 ? ? ? ? ? ? ? ? ? ? ? DRI2 opcode
> + ? ? ? 1 ? ? ? 10 ? ? ? ? ? ? ? ? ? ? ?DRI2 opcode
> ? ? ? ?2 ? ? ? 8 ? ? ? ? ? ? ? ? ? ? ? length
> ? ? ? ?4 ? ? ? DRAWABLE ? ? ? ? ? ? ? ?drawable
> ? ? ? ?4 ? ? ? CARD32 ? ? ? ? ? ? ? ? ?target_msc_hi
> @@ -802,7 +802,7 @@ A.2 Protocol Requests
> ?
> ? ? DRI2WaitSBC
> ? ? ? ?1 ? ? ? CARD8 ? ? ? ? ? ? ? ? ? major opcode
> - ? ? ? 1 ? ? ? 7 ? ? ? ? ? ? ? ? ? ? ? DRI2 opcode
> + ? ? ? 1 ? ? ? 11 ? ? ? ? ? ? ? ? ? ? ?DRI2 opcode
> ? ? ? ?2 ? ? ? 8 ? ? ? ? ? ? ? ? ? ? ? length
> ? ? ? ?4 ? ? ? DRAWABLE ? ? ? ? ? ? ? ?drawable
> ? ? ? ?4 ? ? ? CARD32 ? ? ? ? ? ? ? ? ?swap_hi
> @@ -823,7 +823,7 @@ A.2 Protocol Requests
> ?
> ? ? DRI2SwapInterval
> ? ? ? ?1 ? ? ? CARD8 ? ? ? ? ? ? ? ? ? major opcode
> - ? ? ? 1 ? ? ? 7 ? ? ? ? ? ? ? ? ? ? ? DRI2 opcode
> + ? ? ? 1 ? ? ? 12 ? ? ? ? ? ? ? ? ? ? ?DRI2 opcode
> ? ? ? ?2 ? ? ? 8 ? ? ? ? ? ? ? ? ? ? ? length
> ? ? ? ?4 ? ? ? DRAWABLE ? ? ? ? ? ? ? ?drawable
> ? ? ? ?4 ? ? ? CARD32 ? ? ? ? ? ? ? ? ?interval
> --
> 1.7.10
>


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

2012-05-02 Thread Christian König
Since it is now identical to evergreen_gpu_is_lockup.

Signed-off-by: Christian K?nig 
Reviewed-by: Jerome Glisse 
---
 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 1184635..9cd2657 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 = _cs_parse,
.ring_test = _ring_test,
.ib_test = _ib_test,
-   .is_lockup = _gpu_is_lockup,
+   .is_lockup = _gpu_is_lockup,
},
[CAYMAN_RING_TYPE_CP1_INDEX] = {
.ib_execute = _ring_ib_execute,
@@ -1349,7 +1349,7 @@ static struct radeon_asic cayman_asic = {
.cs_parse = _cs_parse,
.ring_test = _ring_test,
.ib_test = _ib_test,
-   .is_lockup = _gpu_is_lockup,
+   .is_lockup = _gpu_is_lockup,
},
[CAYMAN_RING_TYPE_CP2_INDEX] = {
.ib_execute = _ring_ib_execute,
@@ -1359,7 +1359,7 @@ static struct radeon_asic cayman_asic = {
.cs_parse = _cs_parse,
.ring_test = _ring_test,
.ib_test = _ib_test,
-   .is_lockup = _gpu_is_lockup,
+   .is_lockup = _gpu_is_lockup,
}
},
.irq = {
@@ -1433,7 +1433,7 @@ static struct radeon_asic trinity_asic = {
.cs_parse = _cs_parse,
.ring_test = _ring_test,
.ib_test = _ib_test,
-   .is_lockup = _gpu_is_lockup,
+   .is_lockup = _gpu_is_lockup,
},
[CAYMAN_RING_TYPE_CP1_INDEX] = {
.ib_execute = _ring_ib_execute,
@@ -1443,7 +1443,7 @@ static struct radeon_asic trinity_asic = {
.cs_parse = _cs_parse,
.ring_test = _ring_test,
.ib_test = _ib_test,
-   .is_lockup = _gpu_is_lockup,
+   .is_lockup = _gpu_is_lockup,
},
[CAYMAN_RING_TYPE_CP2_INDEX] = {
.ib_execute = _ring_ib_execute,
@@ -1453,7 +1453,7 @@ static struct radeon_asic trinity_asic = {
.cs_parse = _cs_parse,
.ring_test = _ring_test,
.ib_test = _ib_test,
-   .is_lockup = _gpu_is_lockup,
+   .is_lockup = _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



[PATCH 16/17] drm/radeon: remove r300_gpu_is_lockup

2012-05-02 Thread Christian König
Since it is now identical to r100_gpu_is_lockup.

Signed-off-by: Christian K?nig 
Reviewed-by: Jerome Glisse 
---
 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 = _ring_start,
.ring_test = _ring_test,
.ib_test = _ib_test,
-   .is_lockup = _gpu_is_lockup,
+   .is_lockup = _gpu_is_lockup,
}
},
.irq = {
@@ -373,7 +373,7 @@ static struct radeon_asic r300_asic_pcie = {
.ring_start = _ring_start,
.ring_test = _ring_test,
.ib_test = _ib_test,
-   .is_lockup = _gpu_is_lockup,
+   .is_lockup = _gpu_is_lockup,
}
},
.irq = {
@@ -447,7 +447,7 @@ static struct radeon_asic r420_asic = {
.ring_start = _ring_start,
.ring_test = _ring_test,
.ib_test = _ib_test,
-   .is_lockup = _gpu_is_lockup,
+   .is_lockup = _gpu_is_lockup,
}
},
.irq = {
@@ -521,7 +521,7 @@ static struct radeon_asic rs400_asic = {
.ring_start = _ring_start,
.ring_test = _ring_test,
.ib_test = _ib_test,
-   .is_lockup = _gpu_is_lockup,
+   .is_lockup = _gpu_is_lockup,
}
},
.irq = {
@@ -595,7 +595,7 @@ static struct radeon_asic rs600_asic = {
.ring_start = _ring_start,
.ring_test = _ring_test,
.ib_test = _ib_test,
-   .is_lockup = _gpu_is_lockup,
+   .is_lockup = _gpu_is_lockup,
}
},
.irq = {
@@ -669,7 +669,7 @@ static struct radeon_asic rs690_asic = {
.ring_start = _ring_start,
.ring_test = _ring_test,
.ib_test = _ib_test,
-   .is_lockup = _gpu_is_lockup,
+   .is_lockup = _gpu_is_lockup,
}
},
.irq = {
@@ -743,7 +743,7 @@ static struct radeon_asic rv515_asic = {
.ring_start = _ring_start,
.ring_test = _ring_test,
.ib_test = _ib_test,
-   .is_lockup = _gpu_is_lockup,
+   .is_lockup = _gpu_is_lockup,
}
},
.irq = {
@@ -817,7 +817,7 @@ static struct radeon_asic r520_asic = {
.ring_start = _ring_start,
.ring_test = _ring_test,
.ib_test = _ib_test,
-   .is_lockup = _gpu_is_lockup,
+   .is_lockup = _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 void r300_ring_start(struct radeon_device *rdev, struct radeon_ring 
*ring);
 extern void r300_fence_ring_emit(struct radeon_device *rdev,
-- 
1.7.5.4



[PATCH 15/17] drm/radeon: make forcing ring activity a common function

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

Signed-off-by: Christian K?nig 
Reviewed-by: Jerome Glisse 
---
 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 66f05bb..ecc29bc 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 8404b2a..1184635 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 ccf5e3b..42d60ab 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 

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

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

Signed-off-by: Christian K?nig 
Reviewed-by: Jerome Glisse 
---
 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 08e1578..407d90a 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -346,7 +346,9 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct 
radeon_ring *ring, unsi
if (ndw < ring->ring_free_dw) {
break;
}
+   mutex_unlock(>mutex);
r = radeon_fence_wait_next(rdev, radeon_ring_index(rdev, ring));
+   mutex_lock(>mutex);
if (r)
return r;
}
-- 
1.7.5.4



[PATCH 13/17] drm/radeon: make lockup timeout a module param

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

Signed-off-by: Christian K?nig 
Reviewed-by: Jerome Glisse 
---
 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 b8d4d94..0784e4d 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 203ec1f..08e1578 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -441,7 +441,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 12/17] drm/radeon: move lockup detection code into radeon_ring.c

2012-05-02 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 
Reviewed-by: Jerome Glisse 
---
 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 8b7a01b..66f05bb 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 = >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 0146428..8404b2a 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 = >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 825f117..ccf5e3b 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)

[PATCH 11/17] drm/radeon: rework recursive gpu reset handling

2012-05-02 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 
Reviewed-by: Jerome Glisse 
---
 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(, r);
+   r = radeon_cs_handle_lockup(rdev, r);
radeon_mutex_unlock(>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(, r);
+   r = radeon_cs_handle_lockup(rdev, r);
radeon_mutex_unlock(>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(, r);
+   r = radeon_cs_handle_lockup(rdev, r);
radeon_mutex_unlock(>cs_mutex);
return r;
 }
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 89be94b..d18f0c4 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -986,9 +986,6 @@ int radeon_gpu_reset(struct radeon_device *rdev)
int r;
int resched;

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

-   radeon_mutex_unlock(>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 aadd73a..5bb78bf 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -244,6 +244,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(>fence_lock, irq_flags);

if (radeon_ring_is_lockup(rdev, fence->ring, 
>ring[fence->ring])) {
@@ -254,13 +256,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(>fence_lock, 
irq_flags);
-   rdev->fence_drv[fence->ring].last_activity = 
jiffies;
-   write_unlock_irqrestore(>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(struct drm_gem_object *obj,

[PATCH 10/17] drm/radeon: fix a bug with the ring syncing code

2012-05-02 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 
Reviewed-by: Jerome Glisse 
---
 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 794182a..f7372c4 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -460,6 +460,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, 
>ib->fence->semaphore);
-   if (r)
-   return r;
-   }
-
-   r = radeon_ring_lock(p->rdev, >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, >rdev->ring[i]);
+   if (!need_sync) {
+   return 0;
+   }

-   r = radeon_ring_lock(p->rdev, >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, >rdev->ring[p->ring]);
+   r = radeon_semaphore_create(p->rdev, >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 61dd4e3..930a08a 100644
--- a/drivers/gpu/drm/radeon/radeon_semaphore.c
+++ b/drivers/gpu/drm/radeon/radeon_semaphore.c
@@ -149,6 +149,62 @@ void radeon_semaphore_emit_wait(struct radeon_device 
*rdev, int ring,
radeon_semaphore_ring_emit(rdev, ring, >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 09/17] drm/radeon: don't keep list of created fences.

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

Signed-off-by: Christian K?nig 
Reviewed-by: Jerome Glisse 
---
 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 d73bba8..794182a 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;
struct list_headsignaled;
boolinitialized;
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 2d13843..aadd73a 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -139,8 +139,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;
@@ -153,10 +151,6 @@ int radeon_fence_create(struct radeon_device *rdev,
(*fence)->ring = ring;
(*fence)->semaphore = NULL;
INIT_LIST_HEAD(&(*fence)->list);
-
-   write_lock_irqsave(>fence_lock, irq_flags);
-   list_add_tail(&(*fence)->list, >fence_drv[ring].created);
-   write_unlock_irqrestore(>fence_lock, irq_flags);
return 0;
 }

@@ -411,7 +405,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(>fence_drv[ring].seq, 0);
-   INIT_LIST_HEAD(>fence_drv[ring].created);
INIT_LIST_HEAD(>fence_drv[ring].emitted);
INIT_LIST_HEAD(>fence_drv[ring].signaled);
init_waitqueue_head(>fence_drv[ring].queue);
-- 
1.7.5.4



[PATCH 08/17] drm/radeon: rename fence_wait_last to fence_wait_empty

2012-05-02 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 
Reviewed-by: Jerome Glisse 
---
 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 35db5bd..d73bba8 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 dedb398..89be94b 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -915,7 +915,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(>fence_drv[ring].queue);
write_lock_irqsave(>fence_lock, irq_flags);
radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg);
-- 
1.7.5.4



[PATCH 07/17] drm/radeon: return -ENOENT in fence_wait_next v2

2012-05-02 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 
Reviewed-by: Jerome Glisse 
---
 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(>fence_drv[ring].emitted)) {
write_unlock_irqrestore(>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 06/17] drm/radeon: fix a bug in the SA code

2012-05-02 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 
Reviewed-by: Jerome Glisse 
---
 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, _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 05/17] drm/radeon: rework gpu lockup detection and processing

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

Signed-off-by: Christian K?nig 
Reviewed-by: Jerome Glisse 
---
 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 65855af..35db5bd 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(>fence_drv[fence->ring].emitted)) {
+   rdev->fence_drv[fence->ring].last_activity = jiffies;
+   }
list_move_tail(>list, >fence_drv[fence->ring].emitted);
write_unlock_irqrestore(>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, >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(>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 
signaled in 

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

2012-05-02 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 
Reviewed-by: Jerome Glisse 
---
 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, 
>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, 
>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 a0b44a5..825f117 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, 
>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, 
>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, 
>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, 
>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
index 

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

2012-05-02 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 
Reviewed-by: Jerome Glisse 
---
 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(>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 = _debugfs_ring_info_list[i];
+   int ridx = *(int*)radeon_debugfs_ring_info_list[i].data;
+   unsigned r;
+
+   if (>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/17] drm/radeon: replace gpu_lockup with ring->ready flag

2012-05-02 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 
Reviewed-by: Jerome Glisse 
---
 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 cb11418..a0b44a5 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 4026a4c0..c76724b 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1547,7 +1547,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, >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(>list, >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(>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, 
>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)

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

2012-05-02 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 
Reviewed-by: Jerome Glisse 
---
 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 610acee..4026a4c0 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1162,7 +1162,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
@@ -1191,6 +1190,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 {
@@ -1740,7 +1740,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))
@@ -1749,6 +1748,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 = _suspend,
.resume = _resume,
.vga_set_state = _vga_set_state,
-   .gpu_is_lockup = _gpu_is_lockup,
.asic_reset = _asic_reset,
.ioctl_wait_idle = NULL,
.gui_idle = _gui_idle,
@@ -152,6 +151,7 @@ static struct radeon_asic r100_asic = {
.ring_start = _ring_start,
.ring_test = _ring_test,
.ib_test = _ib_test,
+   .is_lockup = _gpu_is_lockup,
}
},
.irq = {
@@ -208,7 +208,6 @@ static struct radeon_asic r200_asic = {
.suspend = _suspend,
.resume = _resume,
.vga_set_state = _vga_set_state,
-   .gpu_is_lockup = _gpu_is_lockup,
.asic_reset = _asic_reset,
.ioctl_wait_idle = NULL,
.gui_idle = _gui_idle,
@@ -226,6 +225,7 @@ static struct radeon_asic r200_asic = {
.ring_start = _ring_start,
.ring_test = _ring_test,
.ib_test = _ib_test,
+   .is_lockup = _gpu_is_lockup,
}
},
.irq = {
@@ -282,7 +282,6 @@ static struct radeon_asic r300_asic = {
.suspend = _suspend,
.resume = _resume,
.vga_set_state = _vga_set_state,
-   .gpu_is_lockup = _gpu_is_lockup,
.asic_reset = _asic_reset,
.ioctl_wait_idle = NULL,
.gui_idle = _gui_idle,
@@ -300,6 +299,7 @@ static struct radeon_asic r300_asic = {
.ring_start = _ring_start,
.ring_test = _ring_test,
.ib_test = _ib_test,
+   .is_lockup = _gpu_is_lockup,
}
},
.irq = {
@@ -356,7 +356,6 @@ static struct radeon_asic r300_asic_pcie = {
.suspend = _suspend,
.resume 

Include request for reset-rework branch v4

2012-05-02 Thread Christian König
Hi Dave,

there still seems to be the need for some further discussion about the SA code,
so I again split that out of the patchset and tested the result a bit.

Most of the stuff still works fine without those offending changes, so to avoid
mailing around unrelated and already reviewed patches, I request the include
the following 17 patches into drm-next.

If you prefer to merge they are also available from
git://people.freedesktop.org/~deathsimple/linux branch reset-rework.

Cheers,
Christian.



[PATCH] fixing dmi match for hp t5745 and hp st5747 thin client

2012-05-02 Thread Adam Jackson
On 5/1/12 1:37 PM, Marc Gariepy wrote:
> Match the correct information which is DMI_PRODUCT_NAME instead of 
> DMI_BOARD_NAME
> See dmidecode information on launchpad for both thin client:
>
> https://bugs.launchpad.net/ubuntu/+source/linux/+bug/911920
> https://bugs.launchpad.net/ubuntu/+source/linux/+bug/911916

Reviewed-by: Adam Jackson 

- ajax



[PATCH] drm/kms: driver for virtual cirrus under qemu

2012-05-02 Thread Adam Jackson
On 5/2/12 6:27 AM, Dave Airlie wrote:
> From: Dave Airlie 
>
> This is the initial driver for emulated cirrus GPU found in qemu.
> This driver only supports the emulated GPU and doesn't attempt
> to bind to any real cirrus GPUs.

In particular,

> +/* only bind to the cirrus chip in qemu */
> +static DEFINE_PCI_DEVICE_TABLE(pciidlist) = {
> + { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446, 0x1af4, 0x1100, 0,
> +   0, 0 },
> + {0,}
> +};

This requires a (somewhat) new qemu:

http://git.savannah.gnu.org/cgit/qemu.git/commit/hw/pci.c?id=d350d97d196a632b6c7493acf07a061017fc6f7d

Reviewed-by: Adam Jackson 

- ajax


Include request for reset-rework branch v3

2012-05-02 Thread Christian König
On 02.05.2012 12:32, Dave Airlie wrote:
> On Wed, May 2, 2012 at 10:04 AM, Christian K?nig
>   wrote:
>> On 02.05.2012 06:04, Jerome Glisse wrote:
>>> On Wed, May 2, 2012 at 12:00 AM,wrote:
 Ok so i reread stuff and the :
 drm/radeon: add general purpose fence signaled callback
 is a big NAK actually. It change the paradigm. Moving most of
 the handling into the irq process which is something i am intimatly
 convinced we should avoid.

 Here is the patchset up to ib pool cleanup. I have yet rebase the
 other patches as i am tracking done some issue in the sa allocation.

 Cheers,
 Jerome

>>> Before i forget, the big issue with doing work from irq handler is that
>>> we never know in middle of what other part can be. I believe it's lot
>>> better to have irq process only update fence (signaled/not signaled).
>>> and have the actual work happening on behalf of the process wether
>>> through sa alloc path or ttm path.
>>
>> Disagree.
>>
>> Why should it be better to delay work outside of the interrupt context if
>> proper locking can make the driver much more responsive and easier to
>> implement?
>>
>> I don't want to call into TTM or stuff like that, just want make it possible
>> to release the resources acquired for a job immediately after the job is
>> completed instead of waiting for the next allocation to happen. Cause then
>> you don't need to check if a bunch of fences might possible be signaled and
>> instead just get a proper signal that resources can be deallocated.
>>
>> Also if you really want to keep the irq context out of the drivers upper
>> layers, it should be quite easy to modify the code so that the callback
>> won't happen from there.
> as a general rule try an minimise how much work we do in irq context,
> the locking gets very messy once you have to use a mutex somewhere
> else in the future.
Akk, that sounds reasonable, but I still think that a fence should 
signal it's completion by itself. Because that releases us from the 
burden to walk the list of emitted fences and heuristically check if any 
of them is already signaled.

Also it is pretty easy to move the callback outside of interrupt 
context, but first things first.  I'm going to write together a patchset 
with everything that is already accepted, so we can stop mailing around 
actually unrelated patches.

Thanks for the comments,
Christian.



Include request for reset-rework branch v3

2012-05-02 Thread Alex Deucher
2012/5/2 Christian K?nig :
> On 02.05.2012 06:04, Jerome Glisse wrote:
>>
>> On Wed, May 2, 2012 at 12:00 AM, ?wrote:
>>>
>>> Ok so i reread stuff and the :
>>> drm/radeon: add general purpose fence signaled callback
>>> is a big NAK actually. It change the paradigm. Moving most of
>>> the handling into the irq process which is something i am intimatly
>>> convinced we should avoid.
>>>
>>> Here is the patchset up to ib pool cleanup. I have yet rebase the
>>> other patches as i am tracking done some issue in the sa allocation.
>>>
>>> Cheers,
>>> Jerome
>>>
>> Before i forget, the big issue with doing work from irq handler is that
>> we never know in middle of what other part can be. I believe it's lot
>> better to have irq process only update fence (signaled/not signaled).
>> and have the actual work happening on behalf of the process wether
>> through sa alloc path or ttm path.
>
>
> Disagree.
>
> Why should it be better to delay work outside of the interrupt context if
> proper locking can make the driver much more responsive and easier to
> implement?
>
> I don't want to call into TTM or stuff like that, just want make it possible
> to release the resources acquired for a job immediately after the job is
> completed instead of waiting for the next allocation to happen. Cause then
> you don't need to check if a bunch of fences might possible be signaled and
> instead just get a proper signal that resources can be deallocated.

We use two fences per IB, one for the command buffer itself and the
other for the actual IB allocations.  That way the the IB can be
re-used without waiting for the fence after the synchronization.  I'm
not sure it's worth the extra complexity though.

Alex


[PATCH] drm/radeon: add connector table for SAM440ep embedded board

2012-05-02 Thread alexdeuc...@gmail.com
From: Alex Deucher 

RV250 found on ppc embedded boards.

Cc: Hans Verkuil 
Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon_combios.c |   66 +++
 drivers/gpu/drm/radeon/radeon_mode.h|1 +
 2 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_combios.c 
b/drivers/gpu/drm/radeon/radeon_combios.c
index 81fc100..7e747ec 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -1561,6 +1561,11 @@ bool radeon_get_legacy_connector_info_from_table(struct 
drm_device *dev)
   (rdev->pdev->subsystem_device == 0x4150)) {
/* Mac G5 tower 9600 */
rdev->mode_info.connector_table = CT_MAC_G5_9600;
+   } else if ((rdev->pdev->device == 0x4c66) &&
+  (rdev->pdev->subsystem_vendor == 0x1002) &&
+  (rdev->pdev->subsystem_device == 0x4c66)) {
+   /* SAM440ep RV250 embedded board */
+   rdev->mode_info.connector_table = CT_SAM440EP;
} else
 #endif /* CONFIG_PPC_PMAC */
 #ifdef CONFIG_PPC64
@@ -2134,6 +2139,67 @@ bool radeon_get_legacy_connector_info_from_table(struct 
drm_device *dev)
CONNECTOR_OBJECT_ID_SVIDEO,
);
break;
+   case CT_SAM440EP:
+   DRM_INFO("Connector Table: %d (SAM440ep embedded board)\n",
+rdev->mode_info.connector_table);
+   /* LVDS */
+   ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0);
+   hpd.hpd = RADEON_HPD_NONE;
+   radeon_add_legacy_encoder(dev,
+ radeon_get_encoder_enum(dev,
+   
ATOM_DEVICE_LCD1_SUPPORT,
+   0),
+ ATOM_DEVICE_LCD1_SUPPORT);
+   radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
+   DRM_MODE_CONNECTOR_LVDS, _i2c,
+   CONNECTOR_OBJECT_ID_LVDS,
+   );
+   /* DVI-I - secondary dac, int tmds */
+   ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
+   hpd.hpd = RADEON_HPD_1; /* ??? */
+   radeon_add_legacy_encoder(dev,
+ radeon_get_encoder_enum(dev,
+   
ATOM_DEVICE_DFP1_SUPPORT,
+   0),
+ ATOM_DEVICE_DFP1_SUPPORT);
+   radeon_add_legacy_encoder(dev,
+ radeon_get_encoder_enum(dev,
+   
ATOM_DEVICE_CRT2_SUPPORT,
+   2),
+ ATOM_DEVICE_CRT2_SUPPORT);
+   radeon_add_legacy_connector(dev, 1,
+   ATOM_DEVICE_DFP1_SUPPORT |
+   ATOM_DEVICE_CRT2_SUPPORT,
+   DRM_MODE_CONNECTOR_DVII, _i2c,
+   
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
+   );
+   /* VGA - primary dac */
+   ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
+   hpd.hpd = RADEON_HPD_NONE;
+   radeon_add_legacy_encoder(dev,
+ radeon_get_encoder_enum(dev,
+   
ATOM_DEVICE_CRT1_SUPPORT,
+   1),
+ ATOM_DEVICE_CRT1_SUPPORT);
+   radeon_add_legacy_connector(dev, 2,
+   ATOM_DEVICE_CRT1_SUPPORT,
+   DRM_MODE_CONNECTOR_VGA, _i2c,
+   CONNECTOR_OBJECT_ID_VGA,
+   );
+   /* TV - TV DAC */
+   ddc_i2c.valid = false;
+   hpd.hpd = RADEON_HPD_NONE;
+   radeon_add_legacy_encoder(dev,
+ radeon_get_encoder_enum(dev,
+   
ATOM_DEVICE_TV1_SUPPORT,
+   2),
+ ATOM_DEVICE_TV1_SUPPORT);
+   radeon_add_legacy_connector(dev, 3, 

[PATCH] dri2proto: Fix documented opcodes

2012-05-02 Thread Chad Versace
Fix the documented opcodes in dri2proto.txt to be consistent with the
actual opcode values in dri2proto.h and in xcb/proto:src/dri2.xml. (It
looks like the opcodes were incorrect due to copy-paste errors).

CC: Kristian H?gsberg 
---
 dri2proto.txt |   18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/dri2proto.txt b/dri2proto.txt
index df763c7..7bde067 100644
--- a/dri2proto.txt
+++ b/dri2proto.txt
@@ -658,7 +658,7 @@ A.2 Protocol Requests
 
 DRI2GetBuffers
1   CARD8   major opcode
-   1   3   DRI2 opcode
+   1   5   DRI2 opcode
2   3   length
4   DRAWABLEdrawable
4   n   number of attachments
@@ -678,7 +678,7 @@ A.2 Protocol Requests
 
 DRI2CopyRegion
1   CARD8   major opcode
-   1   4   DRI2 opcode
+   1   6   DRI2 opcode
2   3   length
4   DRAWABLEdrawable
4   REGION  region
@@ -695,7 +695,7 @@ A.2 Protocol Requests
 
 DRI2GetBuffersWithFormat
1   CARD8   major opcode
-   1   3   DRI2 opcode
+   1   7   DRI2 opcode
2   3   length
4   DRAWABLEdrawable
4   n   number of attachments
@@ -715,7 +715,7 @@ A.2 Protocol Requests
 
 DRI2SwapBuffers
1   CARD8   major opcode
-   1   7   DRI2 opcode
+   1   8   DRI2 opcode
2   8   length
4   DRAWABLEdrawable
   ?
@@ -736,7 +736,7 @@ A.2 Protocol Requests
 
 DRI2SwapBuffers
1   CARD8   major opcode
-   1   7   DRI2 opcode
+   1   8   DRI2 opcode
2   8   length
4   DRAWABLEdrawable
4   CARD32  target_msc_hi
@@ -758,7 +758,7 @@ A.2 Protocol Requests
 
 DRI2GetMSC
1   CARD8   major opcode
-   1   7   DRI2 opcode
+   1   9   DRI2 opcode
2   8   length
4   DRAWABLEdrawable
   ?
@@ -777,7 +777,7 @@ A.2 Protocol Requests
 
 DRI2WaitMSC
1   CARD8   major opcode
-   1   7   DRI2 opcode
+   1   10  DRI2 opcode
2   8   length
4   DRAWABLEdrawable
4   CARD32  target_msc_hi
@@ -802,7 +802,7 @@ A.2 Protocol Requests
 
 DRI2WaitSBC
1   CARD8   major opcode
-   1   7   DRI2 opcode
+   1   11  DRI2 opcode
2   8   length
4   DRAWABLEdrawable
4   CARD32  swap_hi
@@ -823,7 +823,7 @@ A.2 Protocol Requests
 
 DRI2SwapInterval
1   CARD8   major opcode
-   1   7   DRI2 opcode
+   1   12  DRI2 opcode
2   8   length
4   DRAWABLEdrawable
4   CARD32  interval
-- 
1.7.10



Include request for reset-rework branch v4

2012-05-02 Thread Jerome Glisse
On Wed, May 2, 2012 at 9:11 AM, Christian K?nig  
wrote:
> Hi Dave,
>
> there still seems to be the need for some further discussion about the SA 
> code,
> so I again split that out of the patchset and tested the result a bit.
>
> Most of the stuff still works fine without those offending changes, so to 
> avoid
> mailing around unrelated and already reviewed patches, I request the include
> the following 17 patches into drm-next.
>
> If you prefer to merge they are also available from
> git://people.freedesktop.org/~deathsimple/linux branch reset-rework.
>
> Cheers,
> Christian.
>

I am ok with this 17 patchset, i just sent 3 patch on top of those 17 that
bring back some other of the previous cleanup.

So for the 17
Reviewed-by: Jerome Glisse 

Cheers,
Jerome


[PATCH 3/3] drm/radeon: rework ib and semaphore to take advantage of sa allocator

2012-05-02 Thread j.gli...@gmail.com
From: Jerome Glisse 

Both ib and semaphore are always associated with a fence, rework the
sa allocator to store the fence in the sa_bo allowing sa allocator
to wait for a fence and retry allocation. This also simplify the ib
& semaphore code. Simpify semaphore code to use the sa allocator.

Signed-off-by: Christian K?nig 
Signed-off-by: Jerome Glisse 
---
 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   |   75 +
 drivers/gpu/drm/radeon/radeon_cs.c|4 +-
 drivers/gpu/drm/radeon/radeon_device.c|2 -
 drivers/gpu/drm/radeon/radeon_fence.c |7 +-
 drivers/gpu/drm/radeon/radeon_semaphore.c |  161 ++---
 drivers/gpu/drm/radeon/radeon_test.c  |   33 +++---
 drivers/gpu/drm/radeon/radeon_ttm.c   |4 +-
 drivers/gpu/drm/radeon/rv770.c|1 -
 drivers/gpu/drm/radeon/si.c   |1 -
 12 files changed, 84 insertions(+), 207 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index 465026a..2f39fe4 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3422,7 +3422,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 e55ee7b..3160a74 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1744,7 +1744,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 9bac947..0cbcd3a 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2658,7 +2658,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 2e83a66..b899cec 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -248,6 +248,34 @@ extern void evergreen_tiling_fields(unsigned tiling_flags, 
unsigned *bankw,
unsigned *tile_split);

 /*
+ * Semaphores.
+ */
+struct radeon_ring;
+struct radeon_fence;
+
+/* everything here is constant */
+struct radeon_semaphore {
+   struct radeon_sa_bo *sa_bo;
+   struct list_headlist;
+   uint64_tgpu_addr;
+   uint32_t*cpu_ptr;
+   int waiters;
+};
+
+int radeon_semaphore_create(struct radeon_device *rdev,
+   struct radeon_fence *fence);
+void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring,
+ struct radeon_fence *fence);
+void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring,
+   struct radeon_fence *fence);
+int radeon_semaphore_sync_rings(struct radeon_device *rdev,
+   struct radeon_fence *fence,
+   bool sync_to[RADEON_NUM_RINGS],
+   int dst_ring);
+void radeon_semaphore_free(struct radeon_device *rdev,
+  struct radeon_fence *fence);
+
+/*
  * Fences.
  */
 struct radeon_fence_driver {
@@ -273,7 +301,7 @@ struct radeon_fence {
boolsignaled;
/* RB, DMA, etc. */
int ring;
-   struct radeon_semaphore *semaphore;
+   struct radeon_semaphore semaphore;
 };

 int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring);
@@ -431,50 +459,6 @@ int radeon_mode_dumb_destroy(struct drm_file *file_priv,
 uint32_t handle);

 /*
- * 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_t  

[PATCH 2/3] drm/radeon: rip out the ib pool v4

2012-05-02 Thread j.gli...@gmail.com
From: 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
v3: rebase on top of sa manager new patch
v4: rebase on top of lastest patchset

Signed-off-by: Christian K?nig 
Signed-off-by: Jerome Glisse 
---
 drivers/gpu/drm/radeon/evergreen.c|2 +-
 drivers/gpu/drm/radeon/ni.c   |2 +-
 drivers/gpu/drm/radeon/r100.c |2 +-
 drivers/gpu/drm/radeon/r600.c |6 +-
 drivers/gpu/drm/radeon/r600_blit_kms.c|2 +-
 drivers/gpu/drm/radeon/radeon.h   |   18 +--
 drivers/gpu/drm/radeon/radeon_cs.c|8 +-
 drivers/gpu/drm/radeon/radeon_device.c|1 -
 drivers/gpu/drm/radeon/radeon_gart.c  |   12 +-
 drivers/gpu/drm/radeon/radeon_ring.c  |  236 -
 drivers/gpu/drm/radeon/radeon_semaphore.c |7 +-
 drivers/gpu/drm/radeon/si.c   |6 +-
 12 files changed, 91 insertions(+), 211 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index 0e860c6..465026a 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -1366,7 +1366,7 @@ void evergreen_mc_program(struct radeon_device *rdev)
  */
 void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib 
*ib)
 {
-   struct radeon_ring *ring = >ring[ib->fence->ring];
+   struct radeon_ring *ring = >ring[ib->sa_bo->fence->ring];

/* set to DX10/11 mode */
radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0));
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 9cd2657..e55ee7b 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1127,7 +1127,7 @@ void cayman_fence_ring_emit(struct radeon_device *rdev,

 void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
 {
-   struct radeon_ring *ring = >ring[ib->fence->ring];
+   struct radeon_ring *ring = >ring[ib->sa_bo->fence->ring];

/* set to DX10/11 mode */
radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0));
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index ee0103c..d47ffd5 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -3711,7 +3711,7 @@ int r100_ib_test(struct radeon_device *rdev, struct 
radeon_ring *ring)
radeon_ib_free(rdev, );
return r;
}
-   r = radeon_fence_wait(ib->fence, false);
+   r = radeon_fence_wait(ib->sa_bo->fence, false);
if (r) {
return r;
}
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 1cadf97..9bac947 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2672,7 +2672,7 @@ void r600_fini(struct radeon_device *rdev)
  */
 void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
 {
-   struct radeon_ring *ring = >ring[ib->fence->ring];
+   struct radeon_ring *ring = >ring[ib->sa_bo->fence->ring];

/* FIXME: implement */
radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
@@ -2716,7 +2716,7 @@ int r600_ib_test(struct radeon_device *rdev, struct 
radeon_ring *ring)
DRM_ERROR("radeon: failed to schedule ib (%d).\n", r);
return r;
}
-   r = radeon_fence_wait(ib->fence, false);
+   r = radeon_fence_wait(ib->sa_bo->fence, false);
if (r) {
DRM_ERROR("radeon: fence wait failed (%d).\n", r);
return r;
@@ -2728,7 +2728,7 @@ int r600_ib_test(struct radeon_device *rdev, struct 
radeon_ring *ring)
DRM_UDELAY(1);
}
if (i < rdev->usec_timeout) {
-   DRM_INFO("ib test on ring %d succeeded in %u usecs\n", 
ib->fence->ring, i);
+   DRM_INFO("ib test on ring %d succeeded in %u usecs\n", 
ib->sa_bo->fence->ring, i);
} else {
DRM_ERROR("radeon: ib test failed (scratch(0x%04X)=0x%08X)\n",
  scratch, tmp);
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c 
b/drivers/gpu/drm/radeon/r600_blit_kms.c
index db38f58..9580b06 100644
--- a/drivers/gpu/drm/radeon/r600_blit_kms.c
+++ b/drivers/gpu/drm/radeon/r600_blit_kms.c
@@ -638,7 +638,7 @@ static int r600_vb_ib_get(struct radeon_device *rdev, 
unsigned size)

 static void r600_vb_ib_put(struct radeon_device *rdev)
 {
-   radeon_fence_emit(rdev, rdev->r600_blit.vb_ib->fence);
+   radeon_fence_emit(rdev, rdev->r600_blit.vb_ib->sa_bo->fence);
radeon_ib_free(rdev, >r600_blit.vb_ib);
 }

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index acbb642..2e83a66 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ 

[PATCH 1/3] drm/radeon: improve sa allocator (add fence and make it self contain)

2012-05-02 Thread j.gli...@gmail.com
From: Jerome Glisse 

This patch is ground work for having the sa allocator as a standalone
self contained helper. Each sa_bo can be associated with a fence and
when allocating new one you can ask to block until there is room for
satisfying your request.

It also change the sa allocation logic. The sa manager now keep a
last ptr that point to the last allocated sa bo. As sa bo are
allocated from begining to end and as the sa bo list is shorted in
offset order then the sa bo after the last one in the list is also
the oldest sa bo so the one that should finish first.

Thus the allocation alogirthm is simple, it check if there is enough
room after the last sa bo, if so it allocate new sa bo there. If
there isn't it can wait the next sa bo to finish. Code also handle
wrap around ie when last reach the end offset of the sa manager,
next sa bo is allocated from begining (offset 0).

Idea is that bo allocated through this are bo that have lifetime
linked to one of the ring of the GPU, thus when ring progress sa
bo are progresivly freed starting with last->next.

Signed-off-by: Christian K?nig 
Signed-off-by: Jerome Glisse 
---
 drivers/gpu/drm/radeon/radeon.h   |   16 ++-
 drivers/gpu/drm/radeon/radeon_cs.c|4 +-
 drivers/gpu/drm/radeon/radeon_gart.c  |   11 +-
 drivers/gpu/drm/radeon/radeon_object.h|   11 +-
 drivers/gpu/drm/radeon/radeon_ring.c  |   33 +++-
 drivers/gpu/drm/radeon/radeon_sa.c|  266 -
 drivers/gpu/drm/radeon/radeon_semaphore.c |4 +-
 7 files changed, 278 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 729d332..acbb642 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -380,23 +380,29 @@ struct radeon_bo_list {
  * Assumption is that there won't be hole (all object on same
  * alignment).
  */
+
+struct radeon_sa_bo;
+
 struct radeon_sa_manager {
+   spinlock_t  lock;
struct radeon_bo*bo;
struct list_headsa_bo;
unsignedsize;
+   struct radeon_sa_bo *last;
uint64_tgpu_addr;
void*cpu_ptr;
uint32_tdomain;
 };

-struct radeon_sa_bo;
-
 /* sub-allocation buffer */
 struct radeon_sa_bo {
struct list_headlist;
struct radeon_sa_manager*manager;
-   unsignedoffset;
+   unsignedsoffset;
+   unsignedeoffset;
unsignedsize;
+   struct radeon_fence *fence;
+   boolfree;
 };

 /*
@@ -628,7 +634,7 @@ void radeon_irq_kms_pflip_irq_put(struct radeon_device 
*rdev, int crtc);
  */

 struct radeon_ib {
-   struct radeon_sa_bo sa_bo;
+   struct radeon_sa_bo *sa_bo;
unsignedidx;
uint32_tlength_dw;
uint64_tgpu_addr;
@@ -684,7 +690,7 @@ struct radeon_vm {
unsignedlast_pfn;
u64 pt_gpu_addr;
u64 *pt;
-   struct radeon_sa_bo sa_bo;
+   struct radeon_sa_bo *sa_bo;
struct mutexmutex;
/* last fence for cs using this vm */
struct radeon_fence *fence;
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
b/drivers/gpu/drm/radeon/radeon_cs.c
index a0826bb..3989015 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -465,7 +465,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
/* ib pool is bind at 0 in virtual address space to gpu_addr is 
the
 * offset inside the pool bo
 */
-   parser->const_ib->gpu_addr = parser->const_ib->sa_bo.offset;
+   parser->const_ib->gpu_addr = parser->const_ib->sa_bo->soffset;
r = radeon_ib_schedule(rdev, parser->const_ib);
if (r)
goto out;
@@ -475,7 +475,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
/* ib pool is bind at 0 in virtual address space to gpu_addr is the
 * offset inside the pool bo
 */
-   parser->ib->gpu_addr = parser->ib->sa_bo.offset;
+   parser->ib->gpu_addr = parser->ib->sa_bo->soffset;
parser->ib->is_const_ib = false;
r = radeon_ib_schedule(rdev, parser->ib);
 out:
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index c58a036..cc5036c 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -393,10 +393,13 @@ int radeon_vm_bind(struct radeon_device *rdev, struct 
radeon_vm *vm)
}

 retry:
-   r = radeon_sa_bo_new(rdev, 

Include request for reset-rework branch v4 PART2

2012-05-02 Thread j.gli...@gmail.com
So here are sa improvement, ib pool cleanup and semaphore cleanup.
Those are Christian patches rebased on top of its last 17 patchset
and on top of sa allocator change.

The idea is that the sa_bo struct is not free until associated fence
is signaled. Meanwhile the ib structure or the semaphore/fence structure
holding a reference to the sa_bo can be free.

I have given this patchset moderated testing (things seems ok with desktop
firefox, libreoffice, evince, + few gl app running at the same time.

I haven't tested the semaphore things or vm change yet.

Patch can also be found:
http://people.freedesktop.org/~glisse/reset3/

Cheers,
Jerome



Include request for reset-rework branch v3

2012-05-02 Thread Dave Airlie
On Wed, May 2, 2012 at 10:04 AM, Christian K?nig
 wrote:
> On 02.05.2012 06:04, Jerome Glisse wrote:
>>
>> On Wed, May 2, 2012 at 12:00 AM, ?wrote:
>>>
>>> Ok so i reread stuff and the :
>>> drm/radeon: add general purpose fence signaled callback
>>> is a big NAK actually. It change the paradigm. Moving most of
>>> the handling into the irq process which is something i am intimatly
>>> convinced we should avoid.
>>>
>>> Here is the patchset up to ib pool cleanup. I have yet rebase the
>>> other patches as i am tracking done some issue in the sa allocation.
>>>
>>> Cheers,
>>> Jerome
>>>
>> Before i forget, the big issue with doing work from irq handler is that
>> we never know in middle of what other part can be. I believe it's lot
>> better to have irq process only update fence (signaled/not signaled).
>> and have the actual work happening on behalf of the process wether
>> through sa alloc path or ttm path.
>
>
> Disagree.
>
> Why should it be better to delay work outside of the interrupt context if
> proper locking can make the driver much more responsive and easier to
> implement?
>
> I don't want to call into TTM or stuff like that, just want make it possible
> to release the resources acquired for a job immediately after the job is
> completed instead of waiting for the next allocation to happen. Cause then
> you don't need to check if a bunch of fences might possible be signaled and
> instead just get a proper signal that resources can be deallocated.
>
> Also if you really want to keep the irq context out of the drivers upper
> layers, it should be quite easy to modify the code so that the callback
> won't happen from there.

as a general rule try an minimise how much work we do in irq context,
the locking gets very messy once you have to use a mutex somewhere
else in the future.

Dave.


[PATCH] drm/kms: driver for virtual cirrus under qemu

2012-05-02 Thread Dave Airlie
From: Dave Airlie 

This is the initial driver for emulated cirrus GPU found in qemu.
This driver only supports the emulated GPU and doesn't attempt
to bind to any real cirrus GPUs.

This driver is intended to be used with xf86-video-modesetting in userspace.

This follow the same design as ast and mgag200, and is based on work
done by Matthew Garrett previously.

This GPU has no hw cursor, and it can't scanout 32-bpp, only packed 24-bpp.
i.e. it sucks.

Signed-off-by: Dave Airlie 
---
 drivers/gpu/drm/Kconfig   |2 +
 drivers/gpu/drm/Makefile  |1 +
 drivers/gpu/drm/cirrus/Kconfig|7 +
 drivers/gpu/drm/cirrus/Makefile   |5 +
 drivers/gpu/drm/cirrus/cirrus_drv.c   |  106 ++
 drivers/gpu/drm/cirrus/cirrus_drv.h   |  246 +
 drivers/gpu/drm/cirrus/cirrus_fbdev.c |  307 
 drivers/gpu/drm/cirrus/cirrus_main.c  |  337 ++
 drivers/gpu/drm/cirrus/cirrus_mode.c  |  626 +
 drivers/gpu/drm/cirrus/cirrus_ttm.c   |  453 
 10 files changed, 2090 insertions(+), 0 deletions(-)
 create mode 100644 drivers/gpu/drm/cirrus/Kconfig
 create mode 100644 drivers/gpu/drm/cirrus/Makefile
 create mode 100644 drivers/gpu/drm/cirrus/cirrus_drv.c
 create mode 100644 drivers/gpu/drm/cirrus/cirrus_drv.h
 create mode 100644 drivers/gpu/drm/cirrus/cirrus_fbdev.c
 create mode 100644 drivers/gpu/drm/cirrus/cirrus_main.c
 create mode 100644 drivers/gpu/drm/cirrus/cirrus_mode.c
 create mode 100644 drivers/gpu/drm/cirrus/cirrus_ttm.c

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 47b1d3a..2bc0396 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -168,3 +168,5 @@ source "drivers/gpu/drm/gma500/Kconfig"
 source "drivers/gpu/drm/ast/Kconfig"

 source "drivers/gpu/drm/mgag200/Kconfig"
+
+source "drivers/gpu/drm/cirrus/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 0d91e1a..99ec9e0 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_DRM_MGA) += mga/
 obj-$(CONFIG_DRM_I810) += i810/
 obj-$(CONFIG_DRM_I915)  += i915/
 obj-$(CONFIG_DRM_MGAG200) += mgag200/
+obj-$(CONFIG_DRM_CIRRUS) += cirrus/
 obj-$(CONFIG_DRM_SIS)   += sis/
 obj-$(CONFIG_DRM_SAVAGE)+= savage/
 obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/
diff --git a/drivers/gpu/drm/cirrus/Kconfig b/drivers/gpu/drm/cirrus/Kconfig
new file mode 100644
index 000..67643b9
--- /dev/null
+++ b/drivers/gpu/drm/cirrus/Kconfig
@@ -0,0 +1,7 @@
+config DRM_CIRRUS
+   tristate "Cirrus driver"
+   depends on DRM && PCI
+   select FB_CFB_FILLRECT
+   select FB_CFB_COPYAREA
+   select FB_CFB_IMAGEBLIT
+   select DRM_KMS_HELPER
diff --git a/drivers/gpu/drm/cirrus/Makefile b/drivers/gpu/drm/cirrus/Makefile
new file mode 100644
index 000..8bd345b
--- /dev/null
+++ b/drivers/gpu/drm/cirrus/Makefile
@@ -0,0 +1,5 @@
+ccflags-y := -Iinclude/drm
+cirrus-y   := cirrus_main.o cirrus_mode.o \
+   cirrus_drv.o cirrus_fbdev.o cirrus_ttm.o
+
+obj-$(CONFIG_DRM_CIRRUS) += cirrus.o
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c 
b/drivers/gpu/drm/cirrus/cirrus_drv.c
new file mode 100644
index 000..2e1f925
--- /dev/null
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2012 Red Hat 
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License version 2. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * Authors: Matthew Garrett
+ *  Dave Airlie
+ */
+#include 
+#include 
+#include "drmP.h"
+#include "drm.h"
+
+#include "cirrus_drv.h"
+
+int cirrus_modeset = -1;
+
+MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
+module_param_named(modeset, cirrus_modeset, int, 0400);
+
+/*
+ * This is the generic driver code. This binds the driver to the drm core,
+ * which then performs further device association and calls our graphics init
+ * functions
+ */
+
+static struct drm_driver driver;
+
+/* only bind to the cirrus chip in qemu */
+static DEFINE_PCI_DEVICE_TABLE(pciidlist) = {
+   { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446, 0x1af4, 0x1100, 0,
+ 0, 0 },
+   {0,}
+};
+
+static int __devinit
+cirrus_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+   return drm_get_pci_dev(pdev, ent, );
+}
+
+static void cirrus_pci_remove(struct pci_dev *pdev)
+{
+   struct drm_device *dev = pci_get_drvdata(pdev);
+
+   drm_put_dev(dev);
+}
+
+static const struct file_operations cirrus_driver_fops = {
+   .owner = THIS_MODULE,
+   .open = drm_open,
+   .release = drm_release,
+   .unlocked_ioctl = drm_ioctl,
+   .mmap = cirrus_mmap,
+   .poll = drm_poll,
+   .fasync = drm_fasync,
+};
+static struct drm_driver driver = {
+   .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_USE_MTRR,
+   .load = cirrus_driver_load,
+   

Include request for reset-rework branch v3

2012-05-02 Thread Christian König
On 02.05.2012 06:04, Jerome Glisse wrote:
> On Wed, May 2, 2012 at 12:00 AM,  wrote:
>> Ok so i reread stuff and the :
>> drm/radeon: add general purpose fence signaled callback
>> is a big NAK actually. It change the paradigm. Moving most of
>> the handling into the irq process which is something i am intimatly
>> convinced we should avoid.
>>
>> Here is the patchset up to ib pool cleanup. I have yet rebase the
>> other patches as i am tracking done some issue in the sa allocation.
>>
>> Cheers,
>> Jerome
>>
> Before i forget, the big issue with doing work from irq handler is that
> we never know in middle of what other part can be. I believe it's lot
> better to have irq process only update fence (signaled/not signaled).
> and have the actual work happening on behalf of the process wether
> through sa alloc path or ttm path.

Disagree.

Why should it be better to delay work outside of the interrupt context 
if proper locking can make the driver much more responsive and easier to 
implement?

I don't want to call into TTM or stuff like that, just want make it 
possible to release the resources acquired for a job immediately after 
the job is completed instead of waiting for the next allocation to 
happen. Cause then you don't need to check if a bunch of fences might 
possible be signaled and instead just get a proper signal that resources 
can be deallocated.

Also if you really want to keep the irq context out of the drivers upper 
layers, it should be quite easy to modify the code so that the callback 
won't happen from there.

Christian.


[PATCH] drm/radeon: Original Radeons had PCI GART, not PCIe GART.

2012-05-02 Thread Michel Dänzer
From: Michel D?nzer 

Just a cosmetic fix to make dmesg a little less confusing.

Signed-off-by: Michel D?nzer 
---
 drivers/gpu/drm/radeon/r100.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index cbac1cb..53ec2de 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -660,7 +660,7 @@ int r100_pci_gart_enable(struct radeon_device *rdev)
tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN;
WREG32(RADEON_AIC_CNTL, tmp);
r100_pci_gart_tlb_flush(rdev);
-   DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
+   DRM_INFO("PCI GART of %uM enabled (table at 0x%016llX).\n",
 (unsigned)(rdev->mc.gtt_size >> 20),
 (unsigned long long)rdev->gart.table_addr);
rdev->gart.ready = true;
-- 
1.7.10



[PATCH 07/27] drm/radeon: add proper locking to the SA v3

2012-05-02 Thread Christian König
On 01.05.2012 19:19, j.glisse at gmail.com wrote:
> From: Christian K?nig
>
> Make the suballocator self containing to locking.
>
> v2: split the bugfix into a seperate patch.
> v3: Jerome Glisse use mutex, no reason to use spinlock that
>  are more heavyweight than mutex
NAK, radeon_sa_bo_free is called from interrupt context, so a mutex 
won't work here.

Also because of the short amount of time the lock is (or should be) hold 
a spinlock seems to be more appropriate here.

Christian.

>
> Signed-off-by: Christian K?nig
> Signed-off-by: Jerome Glisse
> ---
>   drivers/gpu/drm/radeon/radeon.h|1 +
>   drivers/gpu/drm/radeon/radeon_sa.c |   15 +--
>   2 files changed, 10 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index 85a3aa9..34c1041 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 {
> + struct mutexmutex;
>   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..8c76c2e 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;
>
> + mutex_init(_manager->mutex);
>   sa_manager->bo = NULL;
>   sa_manager->size = size;
>   sa_manager->domain = domain;
> @@ -139,15 +140,15 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
>
>   BUG_ON(align>  RADEON_GPU_PAGE_SIZE);
>   BUG_ON(size>  sa_manager->size);
> + mutex_lock(_manager->mutex);
>
>   /* no one ? */
> - head = sa_manager->sa_bo.prev;
>   if (list_empty(_manager->sa_bo)) {
> + head =_manager->sa_bo;
>   goto out;
>   }
>
>   /* look for a hole big enough */
> - offset = 0;
>   list_for_each_entry(tmp,_manager->sa_bo, list) {
>   /* room before this object ? */
>   if (offset<  tmp->offset&&  (tmp->offset - offset)>= size) {
> @@ -157,9 +158,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 +167,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 */
> + mutex_unlock(_manager->mutex);
>   return -ENOMEM;
>   }
>
> @@ -180,10 +180,13 @@ out:
>   sa_bo->offset = offset;
>   sa_bo->size = size;
>   list_add(_bo->list, head);
> + mutex_unlock(_manager->mutex);
>   return 0;
>   }
>
>   void radeon_sa_bo_free(struct radeon_device *rdev, struct radeon_sa_bo 
> *sa_bo)
>   {
> + mutex_lock(_bo->manager->mutex);
>   list_del_init(_bo->list);
> + mutex_unlock(_bo->manager->mutex);
>   }



Include request for reset-rework branch v3

2012-05-02 Thread Jerome Glisse
On Wed, May 2, 2012 at 7:25 AM, Christian K?nig  
wrote:
> On 02.05.2012 12:32, Dave Airlie wrote:
>>
>> On Wed, May 2, 2012 at 10:04 AM, Christian K?nig
>>  ?wrote:
>>>
>>> On 02.05.2012 06:04, Jerome Glisse wrote:

 On Wed, May 2, 2012 at 12:00 AM, ? ?wrote:
>
> Ok so i reread stuff and the :
> drm/radeon: add general purpose fence signaled callback
> is a big NAK actually. It change the paradigm. Moving most of
> the handling into the irq process which is something i am intimatly
> convinced we should avoid.
>
> Here is the patchset up to ib pool cleanup. I have yet rebase the
> other patches as i am tracking done some issue in the sa allocation.
>
> Cheers,
> Jerome
>
 Before i forget, the big issue with doing work from irq handler is that
 we never know in middle of what other part can be. I believe it's lot
 better to have irq process only update fence (signaled/not signaled).
 and have the actual work happening on behalf of the process wether
 through sa alloc path or ttm path.
>>>
>>>
>>> Disagree.
>>>
>>> Why should it be better to delay work outside of the interrupt context if
>>> proper locking can make the driver much more responsive and easier to
>>> implement?
>>>
>>> I don't want to call into TTM or stuff like that, just want make it
>>> possible
>>> to release the resources acquired for a job immediately after the job is
>>> completed instead of waiting for the next allocation to happen. Cause
>>> then
>>> you don't need to check if a bunch of fences might possible be signaled
>>> and
>>> instead just get a proper signal that resources can be deallocated.
>>>
>>> Also if you really want to keep the irq context out of the drivers upper
>>> layers, it should be quite easy to modify the code so that the callback
>>> won't happen from there.
>>
>> as a general rule try an minimise how much work we do in irq context,
>> the locking gets very messy once you have to use a mutex somewhere
>> else in the future.
>
> Akk, that sounds reasonable, but I still think that a fence should signal
> it's completion by itself. Because that releases us from the burden to walk
> the list of emitted fences and heuristically check if any of them is already
> signaled.
>
> Also it is pretty easy to move the callback outside of interrupt context,
> but first things first. ?I'm going to write together a patchset with
> everything that is already accepted, so we can stop mailing around actually
> unrelated patches.
>
> Thanks for the comments,
> Christian.
>

Yes i agree, the fence should check for itself, irq process should
only write a per
ring seq_last value (probably good to use an atomic one for this) and when
querying fence status the signaling should happen. There is 2
possibilities there, either
we keep 32bits seq and keep list. Or we move toward 64bit seq and use arithmetic
to know if a fence is signaled or not (assuming that we will never
wrap around 64bits
fence counter in up time).

But i am still against callback it's just make locking a mess. As
discussed previously
i think we should be able to have at most 4 lock:
dispatch lock (all ring all gpu related activities)
ttm lock
temporary memory alloc lock
fence lock (that one can go away if we don't keep a list of fence
anymore) idea is that either
ttm path or temporary memory path might call in fence checking.

Cheers,
Jerome Glisse

Cheers,
Jerome


Linux 3.4-rc4

2012-05-02 Thread Jean Delvare
Hi Luca, Maarten,

On Monday 30 April 2012 01:01:30 pm Luca Tettamanti wrote:
> 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:
> >>> > > 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
> >>> > > 832x62474.6
> >>> > > 800x60085.1 72.2 75.0 60.3 56.2
> >>> > > 848x48060.0
> >>> > > 640x48085.0 75.0 72.8 72.8 66.7 60.0  
> >>> > >59.9
> >>> > > 720x40085.0 87.8 70.1
> >>> > > 640x40085.1
> >>> > > 640x35085.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*
> >>> > > 800x60060.3 56.2
> >>> > > 848x48060.0
> >>> > > 640x48059.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 

[PATCH] drm/radeon: Original Radeons had PCI GART, not PCIe GART.

2012-05-02 Thread Alex Deucher
2012/5/2 Michel D?nzer :
> From: Michel D?nzer 
>
> Just a cosmetic fix to make dmesg a little less confusing.
>
> Signed-off-by: Michel D?nzer 

Reviewed-by: Alex Deucher 

> ---
> ?drivers/gpu/drm/radeon/r100.c | ? ?2 +-
> ?1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
> index cbac1cb..53ec2de 100644
> --- a/drivers/gpu/drm/radeon/r100.c
> +++ b/drivers/gpu/drm/radeon/r100.c
> @@ -660,7 +660,7 @@ int r100_pci_gart_enable(struct radeon_device *rdev)
> ? ? ? ?tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN;
> ? ? ? ?WREG32(RADEON_AIC_CNTL, tmp);
> ? ? ? ?r100_pci_gart_tlb_flush(rdev);
> - ? ? ? DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
> + ? ? ? DRM_INFO("PCI GART of %uM enabled (table at 0x%016llX).\n",
> ? ? ? ? ? ? ? ? (unsigned)(rdev->mc.gtt_size >> 20),
> ? ? ? ? ? ? ? ? (unsigned long long)rdev->gart.table_addr);
> ? ? ? ?rdev->gart.ready = true;
> --
> 1.7.10
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


Include request for reset-rework branch v3

2012-05-02 Thread Jerome Glisse
On Wed, May 2, 2012 at 12:00 AM,   wrote:
> Ok so i reread stuff and the :
> drm/radeon: add general purpose fence signaled callback
> is a big NAK actually. It change the paradigm. Moving most of
> the handling into the irq process which is something i am intimatly
> convinced we should avoid.
>
> Here is the patchset up to ib pool cleanup. I have yet rebase the
> other patches as i am tracking done some issue in the sa allocation.
>
> Cheers,
> Jerome
>

Before i forget, the big issue with doing work from irq handler is that
we never know in middle of what other part can be. I believe it's lot
better to have irq process only update fence (signaled/not signaled).
and have the actual work happening on behalf of the process wether
through sa alloc path or ttm path.

Cheers,
Jerome


[PATCH 13/13] drm/radeon: add fence and retry to sa allocator v2

2012-05-02 Thread j.gli...@gmail.com
From: Jerome Glisse 

This allow to associate a fence with sa bo and retry and
wait if sa bo alloc can block.

v2: bug fixes

Signed-off-by: Jerome Glisse 
---
 drivers/gpu/drm/radeon/radeon.h   |   10 ++-
 drivers/gpu/drm/radeon/radeon_cs.c|4 +-
 drivers/gpu/drm/radeon/radeon_gart.c  |   14 ++--
 drivers/gpu/drm/radeon/radeon_object.h|   10 ++--
 drivers/gpu/drm/radeon/radeon_ring.c  |   14 ++--
 drivers/gpu/drm/radeon/radeon_sa.c|  102 ++---
 drivers/gpu/drm/radeon/radeon_semaphore.c |4 +-
 7 files changed, 122 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 59bcfb9..4815ebe 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -379,6 +379,8 @@ struct radeon_bo_list {
  * Assumption is that there won't be hole (all object on same
  * alignment).
  */
+struct radeon_sa_bo;
+
 struct radeon_sa_manager {
spinlock_t  lock;
struct radeon_bo*bo;
@@ -390,8 +392,6 @@ struct radeon_sa_manager {
uint32_tdomain;
 };

-struct radeon_sa_bo;
-
 /* sub-allocation buffer */
 struct radeon_sa_bo {
struct list_headlist;
@@ -399,6 +399,8 @@ struct radeon_sa_bo {
unsignedsoffset;
unsignedeoffset;
unsignedsize;
+   struct radeon_fence *fence;
+   boolfree;
 };

 /*
@@ -626,7 +628,7 @@ void radeon_irq_kms_pflip_irq_put(struct radeon_device 
*rdev, int crtc);
  */

 struct radeon_ib {
-   struct radeon_sa_bo sa_bo;
+   struct radeon_sa_bo *sa_bo;
unsignedidx;
uint32_tlength_dw;
uint64_tgpu_addr;
@@ -680,7 +682,7 @@ struct radeon_vm {
unsignedlast_pfn;
u64 pt_gpu_addr;
u64 *pt;
-   struct radeon_sa_bo sa_bo;
+   struct radeon_sa_bo *sa_bo;
struct mutexmutex;
/* last fence for cs using this vm */
struct radeon_fence *fence;
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
b/drivers/gpu/drm/radeon/radeon_cs.c
index 8de6b3a..b39f22e 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -476,7 +476,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
/* ib pool is bind at 0 in virtual address space to gpu_addr is 
the
 * offset inside the pool bo
 */
-   parser->const_ib->gpu_addr = parser->const_ib->sa_bo.soffset;
+   parser->const_ib->gpu_addr = parser->const_ib->sa_bo->soffset;
r = radeon_ib_schedule(rdev, parser->const_ib);
if (r)
goto out;
@@ -486,7 +486,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
/* ib pool is bind at 0 in virtual address space to gpu_addr is the
 * offset inside the pool bo
 */
-   parser->ib->gpu_addr = parser->ib->sa_bo.soffset;
+   parser->ib->gpu_addr = parser->ib->sa_bo->soffset;
parser->ib->is_const_ib = false;
r = radeon_ib_schedule(rdev, parser->ib);
 out:
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index 4a5d9d4..89328e3 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -393,19 +393,19 @@ int radeon_vm_bind(struct radeon_device *rdev, struct 
radeon_vm *vm)
}

 retry:
-   r = radeon_sa_bo_new(rdev, >vm_manager.sa_manager, >sa_bo,
-RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8),
-RADEON_GPU_PAGE_SIZE);
-   if (r) {
+   vm->sa_bo = radeon_sa_bo_new(rdev, >vm_manager.sa_manager,
+RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8),
+RADEON_GPU_PAGE_SIZE, false, NULL);
+   if (vm->sa_bo == NULL) {
if (list_empty(>vm_manager.lru_vm)) {
-   return r;
+   return -ENOMEM;
}
vm_evict = list_first_entry(>vm_manager.lru_vm, struct 
radeon_vm, list);
radeon_vm_unbind(rdev, vm_evict);
goto retry;
}
-   vm->pt = radeon_sa_bo_cpu_addr(>sa_bo);
-   vm->pt_gpu_addr = radeon_sa_bo_gpu_addr(>sa_bo);
+   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 99ab46a..7bbc319 100644
--- 

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

2012-05-02 Thread j.gli...@gmail.com
From: Christian K?nig 

It's never used and so practically superfluous.

Signed-off-by: Christian K?nig 
Reviewed-by: Jerome Glisse 
---
 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 f1a9bd0..59bcfb9 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;
struct list_headsignaled;
boolinitialized;
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 2d13843..aadd73a 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -139,8 +139,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;
@@ -153,10 +151,6 @@ int radeon_fence_create(struct radeon_device *rdev,
(*fence)->ring = ring;
(*fence)->semaphore = NULL;
INIT_LIST_HEAD(&(*fence)->list);
-
-   write_lock_irqsave(>fence_lock, irq_flags);
-   list_add_tail(&(*fence)->list, >fence_drv[ring].created);
-   write_unlock_irqrestore(>fence_lock, irq_flags);
return 0;
 }

@@ -411,7 +405,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(>fence_drv[ring].seq, 0);
-   INIT_LIST_HEAD(>fence_drv[ring].created);
INIT_LIST_HEAD(>fence_drv[ring].emitted);
INIT_LIST_HEAD(>fence_drv[ring].signaled);
init_waitqueue_head(>fence_drv[ring].queue);
-- 
1.7.7.6



[PATCH 11/13] drm/radeon: rename fence_wait_last to fence_wait_empty

2012-05-02 Thread j.gli...@gmail.com
From: 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 
Reviewed-by: Jerome Glisse 
---
 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 dc4f4f3..f1a9bd0 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 eb63a06..f6f9d6c 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -915,7 +915,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(>fence_drv[ring].queue);
write_lock_irqsave(>fence_lock, irq_flags);
radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg);
-- 
1.7.7.6



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

2012-05-02 Thread j.gli...@gmail.com
From: 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 
Reviewed-by: Jerome Glisse 
---
 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(>fence_drv[ring].emitted)) {
write_unlock_irqrestore(>fence_lock, irq_flags);
-   return 0;
+   return -ENOENT;
}
fence = list_entry(rdev->fence_drv[ring].emitted.next,
   struct radeon_fence, list);
-- 
1.7.7.6



[PATCH 09/13] drm/radeon: improve sa allocator v2

2012-05-02 Thread j.gli...@gmail.com
From: Jerome Glisse 

The sa allocator is suppose to be a ring allocator, ie allocation
happen first at the end and if there is no more room we start at
the begining again. This patch make the code match this design.
sa_manager keep track of the start & end hole, it first try to
allocate in the end hole, if it fails it allocate in the begining
hole, if it fails it returns (caller is expected to retry).

When freeing we need to make sure that we properly grow the end
hole and start hole. We take advantage of the fact that the sa_bo
list is ordered by offset. That means that when we free an sa_bo
the previous sa_bo in list is also the sa_bo just before the
sa_bo we are freeing and reversly for the next.

v2: Use read ptr metaphore to mimic ring behavior and simplify
code a bit.

Signed-off-by: Jerome Glisse 
---
 drivers/gpu/drm/radeon/radeon.h   |4 +-
 drivers/gpu/drm/radeon/radeon_cs.c|4 +-
 drivers/gpu/drm/radeon/radeon_gart.c  |6 +-
 drivers/gpu/drm/radeon/radeon_object.h|   11 +++
 drivers/gpu/drm/radeon/radeon_ring.c  |6 +-
 drivers/gpu/drm/radeon/radeon_sa.c|  128 +++--
 drivers/gpu/drm/radeon/radeon_semaphore.c |4 +-
 7 files changed, 107 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 1aefbd9..dc4f4f3 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -385,6 +385,7 @@ struct radeon_sa_manager {
struct radeon_bo*bo;
struct list_headsa_bo;
unsignedsize;
+   struct radeon_sa_bo *last;
uint64_tgpu_addr;
void*cpu_ptr;
uint32_tdomain;
@@ -396,7 +397,8 @@ struct radeon_sa_bo;
 struct radeon_sa_bo {
struct list_headlist;
struct radeon_sa_manager*manager;
-   unsignedoffset;
+   unsignedsoffset;
+   unsignedeoffset;
unsignedsize;
 };

diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
b/drivers/gpu/drm/radeon/radeon_cs.c
index 5cac832..8de6b3a 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -476,7 +476,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
/* ib pool is bind at 0 in virtual address space to gpu_addr is 
the
 * offset inside the pool bo
 */
-   parser->const_ib->gpu_addr = parser->const_ib->sa_bo.offset;
+   parser->const_ib->gpu_addr = parser->const_ib->sa_bo.soffset;
r = radeon_ib_schedule(rdev, parser->const_ib);
if (r)
goto out;
@@ -486,7 +486,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
/* ib pool is bind at 0 in virtual address space to gpu_addr is the
 * offset inside the pool bo
 */
-   parser->ib->gpu_addr = parser->ib->sa_bo.offset;
+   parser->ib->gpu_addr = parser->ib->sa_bo.soffset;
parser->ib->is_const_ib = false;
r = radeon_ib_schedule(rdev, parser->ib);
 out:
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index c58a036..4a5d9d4 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(>sa_bo);
+   vm->pt_gpu_addr = radeon_sa_bo_gpu_addr(>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 d9b9333..99ab46a 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->soffset;
+}
+
+static inline void * radeon_sa_bo_cpu_addr(struct radeon_sa_bo *sa_bo)
+{
+   return sa_bo->manager->cpu_ptr + sa_bo->soffset;
+}
+
 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 1d9bce9..981ab95 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ 

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

2012-05-02 Thread j.gli...@gmail.com
From: Christian K?nig 

Dumping the current allocations.

Signed-off-by: Christian K?nig 
Reviewed-by: Jerome Glisse 
---
 drivers/gpu/drm/radeon/radeon_object.h |5 +
 drivers/gpu/drm/radeon/radeon_ring.c   |   22 ++
 drivers/gpu/drm/radeon/radeon_sa.c |   14 ++
 3 files changed, 41 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(>ib_pool.sa_manager, m);
+
+   return 0;
+
+}
+
+static struct drm_info_list radeon_debugfs_sa_list[] = {
+{"radeon_sa_info", _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 472d346..1e1bec1 100644
--- a/drivers/gpu/drm/radeon/radeon_sa.c
+++ b/drivers/gpu/drm/radeon/radeon_sa.c
@@ -192,3 +192,17 @@ void radeon_sa_bo_free(struct radeon_device *rdev, struct 
radeon_sa_bo *sa_bo)
list_del_init(_bo->list);
spin_unlock(_manager->lock);
 }
+
+#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;
+
+   spin_lock(_manager->lock);
+   list_for_each_entry(i, _manager->sa_bo, list) {
+   seq_printf(m, "offset %08d: size %4d\n", i->offset, i->size);
+   }
+   spin_unlock(_manager->lock);
+}
+#endif
-- 
1.7.7.6



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

2012-05-02 Thread j.gli...@gmail.com
From: Christian K?nig 

Make the suballocator self containing to locking.

v2: split the bugfix into a seperate patch.

Signed-off-by: Christian K?nig 
Reviewed-by: Jerome Glisse 
---
 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 85a3aa9..1aefbd9 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..472d346 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(_manager->lock);
sa_manager->bo = NULL;
sa_manager->size = size;
sa_manager->domain = domain;
@@ -139,15 +140,15 @@ int radeon_sa_bo_new(struct radeon_device *rdev,

BUG_ON(align > RADEON_GPU_PAGE_SIZE);
BUG_ON(size > sa_manager->size);
+   spin_lock(_manager->lock);

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

/* look for a hole big enough */
-   offset = 0;
list_for_each_entry(tmp, _manager->sa_bo, list) {
/* room before this object ? */
if (offset < tmp->offset && (tmp->offset - offset) >= size) {
@@ -157,9 +158,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 +167,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(_manager->lock);
return -ENOMEM;
}

@@ -180,10 +180,15 @@ out:
sa_bo->offset = offset;
sa_bo->size = size;
list_add(_bo->list, head);
+   spin_unlock(_manager->lock);
return 0;
 }

 void radeon_sa_bo_free(struct radeon_device *rdev, struct radeon_sa_bo *sa_bo)
 {
+   struct radeon_sa_manager *sa_manager = sa_bo->manager;
+
+   spin_lock(_manager->lock);
list_del_init(_bo->list);
+   spin_unlock(_manager->lock);
 }
-- 
1.7.7.6



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

2012-05-02 Thread j.gli...@gmail.com
From: 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 
Reviewed-by: Jerome Glisse 
---
 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, _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.7.6



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

2012-05-02 Thread j.gli...@gmail.com
From: Christian K?nig 

Previusly multiple rings could trigger multiple GPU
resets at the same time.

Signed-off-by: Christian K?nig 
Reviewed-by: Jerome Glisse 
---
 drivers/gpu/drm/radeon/radeon.h   |3 +-
 drivers/gpu/drm/radeon/radeon_fence.c |  150 +
 2 files changed, 77 insertions(+), 76 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 8801657..85a3aa9 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(>fence_drv[fence->ring].emitted)) {
+   rdev->fence_drv[fence->ring].last_activity = jiffies;
+   }
list_move_tail(>list, >fence_drv[fence->ring].emitted);
write_unlock_irqrestore(>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, >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(>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 

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

2012-05-02 Thread j.gli...@gmail.com
From: 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 
Reviewed-by: Jerome Glisse 
---
 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 cfa372c..ca47f52 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3248,12 +3248,9 @@ static int evergreen_startup(struct radeon_device *rdev)
if (r)
return r;

-   r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, 
>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, 
>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 6573e28..ac53bd8 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -3964,12 +3964,9 @@ static int r100_startup(struct radeon_device *rdev)
if (r)
return r;

-   r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, 
>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, 
>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, 
>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, 
>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 

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

2012-05-02 Thread j.gli...@gmail.com
From: 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 
Reviewed-by: Jerome Glisse 
---
 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(>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 = _debugfs_ring_info_list[i];
+   int ridx = *(int*)radeon_debugfs_ring_info_list[i].data;
+   unsigned r;
+
+   if (>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.7.6



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

2012-05-02 Thread j.gli...@gmail.com
From: 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 
Reviewed-by: Jerome Glisse 
---
 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 fe33d35..6573e28 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -2296,7 +2296,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 bea99e3..365334b 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1529,7 +1529,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 ea7df16..eb63a06 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, >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(>list, >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(>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, 
>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);
 

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

2012-05-02 Thread j.gli...@gmail.com
From: 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 
Reviewed-by: Jerome Glisse 
---
 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 138b952..bea99e3 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1144,7 +1144,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
@@ -1173,6 +1172,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 {
@@ -1730,7 +1730,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))
@@ -1739,6 +1738,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 = _suspend,
.resume = _resume,
.vga_set_state = _vga_set_state,
-   .gpu_is_lockup = _gpu_is_lockup,
.asic_reset = _asic_reset,
.ioctl_wait_idle = NULL,
.gui_idle = _gui_idle,
@@ -152,6 +151,7 @@ static struct radeon_asic r100_asic = {
.ring_start = _ring_start,
.ring_test = _ring_test,
.ib_test = _ib_test,
+   .is_lockup = _gpu_is_lockup,
}
},
.irq = {
@@ -208,7 +208,6 @@ static struct radeon_asic r200_asic = {
.suspend = _suspend,
.resume = _resume,
.vga_set_state = _vga_set_state,
-   .gpu_is_lockup = _gpu_is_lockup,
.asic_reset = _asic_reset,
.ioctl_wait_idle = NULL,
.gui_idle = _gui_idle,
@@ -226,6 +225,7 @@ static struct radeon_asic r200_asic = {
.ring_start = _ring_start,
.ring_test = _ring_test,
.ib_test = _ib_test,
+   .is_lockup = _gpu_is_lockup,
}
},
.irq = {
@@ -282,7 +282,6 @@ static struct radeon_asic r300_asic = {
.suspend = _suspend,
.resume = _resume,
.vga_set_state = _vga_set_state,
-   .gpu_is_lockup = _gpu_is_lockup,
.asic_reset = _asic_reset,
.ioctl_wait_idle = NULL,
.gui_idle = _gui_idle,
@@ -300,6 +299,7 @@ static struct radeon_asic r300_asic = {
.ring_start = _ring_start,
.ring_test = _ring_test,
.ib_test = _ib_test,
+   .is_lockup = _gpu_is_lockup,
}
},
.irq = {
@@ -356,7 +356,6 @@ static struct radeon_asic r300_asic_pcie = 

Include request for reset-rework branch v3

2012-05-02 Thread j.gli...@gmail.com
Ok so i reread stuff and the :
drm/radeon: add general purpose fence signaled callback
is a big NAK actually. It change the paradigm. Moving most of
the handling into the irq process which is something i am intimatly
convinced we should avoid.

Here is the patchset up to ib pool cleanup. I have yet rebase the
other patches as i am tracking done some issue in the sa allocation.

Cheers,
Jerome



Re: [PATCH 07/27] drm/radeon: add proper locking to the SA v3

2012-05-02 Thread Christian König

On 01.05.2012 19:19, j.gli...@gmail.com wrote:

From: Christian Königdeathsim...@vodafone.de

Make the suballocator self containing to locking.

v2: split the bugfix into a seperate patch.
v3: Jerome Glisse use mutex, no reason to use spinlock that
 are more heavyweight than mutex
NAK, radeon_sa_bo_free is called from interrupt context, so a mutex 
won't work here.


Also because of the short amount of time the lock is (or should be) hold 
a spinlock seems to be more appropriate here.


Christian.



Signed-off-by: Christian Königdeathsim...@vodafone.de
Signed-off-by: Jerome Glissejgli...@redhat.com
---
  drivers/gpu/drm/radeon/radeon.h|1 +
  drivers/gpu/drm/radeon/radeon_sa.c |   15 +--
  2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 85a3aa9..34c1041 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 {
+   struct mutexmutex;
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..8c76c2e 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;

+   mutex_init(sa_manager-mutex);
sa_manager-bo = NULL;
sa_manager-size = size;
sa_manager-domain = domain;
@@ -139,15 +140,15 @@ int radeon_sa_bo_new(struct radeon_device *rdev,

BUG_ON(align  RADEON_GPU_PAGE_SIZE);
BUG_ON(size  sa_manager-size);
+   mutex_lock(sa_manager-mutex);

/* 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 +158,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 +167,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 */
+   mutex_unlock(sa_manager-mutex);
return -ENOMEM;
}

@@ -180,10 +180,13 @@ out:
sa_bo-offset = offset;
sa_bo-size = size;
list_add(sa_bo-list, head);
+   mutex_unlock(sa_manager-mutex);
return 0;
  }

  void radeon_sa_bo_free(struct radeon_device *rdev, struct radeon_sa_bo *sa_bo)
  {
+   mutex_lock(sa_bo-manager-mutex);
list_del_init(sa_bo-list);
+   mutex_unlock(sa_bo-manager-mutex);
  }


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


[PATCH] drm/radeon: Original Radeons had PCI GART, not PCIe GART.

2012-05-02 Thread Michel Dänzer
From: Michel Dänzer michel.daen...@amd.com

Just a cosmetic fix to make dmesg a little less confusing.

Signed-off-by: Michel Dänzer michel.daen...@amd.com
---
 drivers/gpu/drm/radeon/r100.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index cbac1cb..53ec2de 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -660,7 +660,7 @@ int r100_pci_gart_enable(struct radeon_device *rdev)
tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN;
WREG32(RADEON_AIC_CNTL, tmp);
r100_pci_gart_tlb_flush(rdev);
-   DRM_INFO(PCIE GART of %uM enabled (table at 0x%016llX).\n,
+   DRM_INFO(PCI GART of %uM enabled (table at 0x%016llX).\n,
 (unsigned)(rdev-mc.gtt_size  20),
 (unsigned long long)rdev-gart.table_addr);
rdev-gart.ready = true;
-- 
1.7.10

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


Re: Linux 3.4-rc4

2012-05-02 Thread Jean Delvare
Hi Luca, Maarten,

On Monday 30 April 2012 01:01:30 pm Luca Tettamanti wrote:
 On Mon, Apr 30, 2012 at 11:07 AM, Maarten Maathuis madman2...@gmail.com 
 wrote:
  On Mon, Apr 30, 2012 at 12:37 AM, Dmitry Torokhov
 
  dmitry.torok...@gmail.com 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 nbow...@elliptictech.com 
   wrote:
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
832x62474.6
800x60085.1 72.2 75.0 60.3 56.2
848x48060.0
640x48085.0 75.0 72.8 72.8 66.7 60.0  
   59.9
720x40085.0 87.8 70.1
640x40085.1
640x35085.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*
800x60060.3 56.2
848x48060.0
640x48059.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.678392] [drm] nouveau :01:00.0: Detected an NV50
  generation card (0x086b00a2)
 
  Just a crazy thought, but didn't we change some timings related to
  EDID retrieval? To make it faster.
 
 Hum, this commit:
 
 commit 1849ecb22fb3b5d57b65e7369a3957adf9f26f39
 Author: Jean Delvare jdelv...@suse.de
 Date:   Sat Jan 28 11:07:09 2012 +0100
 
 drm/kms: Make i2c buses faster
 
 doubled the data rate but only 

Re: Re: Include request for reset-rework branch v3

2012-05-02 Thread Christian König

On 02.05.2012 06:04, Jerome Glisse wrote:

On Wed, May 2, 2012 at 12:00 AM,j.gli...@gmail.com  wrote:

Ok so i reread stuff and the :
drm/radeon: add general purpose fence signaled callback
is a big NAK actually. It change the paradigm. Moving most of
the handling into the irq process which is something i am intimatly
convinced we should avoid.

Here is the patchset up to ib pool cleanup. I have yet rebase the
other patches as i am tracking done some issue in the sa allocation.

Cheers,
Jerome


Before i forget, the big issue with doing work from irq handler is that
we never know in middle of what other part can be. I believe it's lot
better to have irq process only update fence (signaled/not signaled).
and have the actual work happening on behalf of the process wether
through sa alloc path or ttm path.


Disagree.

Why should it be better to delay work outside of the interrupt context 
if proper locking can make the driver much more responsive and easier to 
implement?


I don't want to call into TTM or stuff like that, just want make it 
possible to release the resources acquired for a job immediately after 
the job is completed instead of waiting for the next allocation to 
happen. Cause then you don't need to check if a bunch of fences might 
possible be signaled and instead just get a proper signal that resources 
can be deallocated.


Also if you really want to keep the irq context out of the drivers upper 
layers, it should be quite easy to modify the code so that the callback 
won't happen from there.


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


[PATCH] drm/kms: driver for virtual cirrus under qemu

2012-05-02 Thread Dave Airlie
From: Dave Airlie airl...@redhat.com

This is the initial driver for emulated cirrus GPU found in qemu.
This driver only supports the emulated GPU and doesn't attempt
to bind to any real cirrus GPUs.

This driver is intended to be used with xf86-video-modesetting in userspace.

This follow the same design as ast and mgag200, and is based on work
done by Matthew Garrett previously.

This GPU has no hw cursor, and it can't scanout 32-bpp, only packed 24-bpp.
i.e. it sucks.

Signed-off-by: Dave Airlie airl...@redhat.com
---
 drivers/gpu/drm/Kconfig   |2 +
 drivers/gpu/drm/Makefile  |1 +
 drivers/gpu/drm/cirrus/Kconfig|7 +
 drivers/gpu/drm/cirrus/Makefile   |5 +
 drivers/gpu/drm/cirrus/cirrus_drv.c   |  106 ++
 drivers/gpu/drm/cirrus/cirrus_drv.h   |  246 +
 drivers/gpu/drm/cirrus/cirrus_fbdev.c |  307 
 drivers/gpu/drm/cirrus/cirrus_main.c  |  337 ++
 drivers/gpu/drm/cirrus/cirrus_mode.c  |  626 +
 drivers/gpu/drm/cirrus/cirrus_ttm.c   |  453 
 10 files changed, 2090 insertions(+), 0 deletions(-)
 create mode 100644 drivers/gpu/drm/cirrus/Kconfig
 create mode 100644 drivers/gpu/drm/cirrus/Makefile
 create mode 100644 drivers/gpu/drm/cirrus/cirrus_drv.c
 create mode 100644 drivers/gpu/drm/cirrus/cirrus_drv.h
 create mode 100644 drivers/gpu/drm/cirrus/cirrus_fbdev.c
 create mode 100644 drivers/gpu/drm/cirrus/cirrus_main.c
 create mode 100644 drivers/gpu/drm/cirrus/cirrus_mode.c
 create mode 100644 drivers/gpu/drm/cirrus/cirrus_ttm.c

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 47b1d3a..2bc0396 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -168,3 +168,5 @@ source drivers/gpu/drm/gma500/Kconfig
 source drivers/gpu/drm/ast/Kconfig
 
 source drivers/gpu/drm/mgag200/Kconfig
+
+source drivers/gpu/drm/cirrus/Kconfig
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 0d91e1a..99ec9e0 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_DRM_MGA) += mga/
 obj-$(CONFIG_DRM_I810) += i810/
 obj-$(CONFIG_DRM_I915)  += i915/
 obj-$(CONFIG_DRM_MGAG200) += mgag200/
+obj-$(CONFIG_DRM_CIRRUS) += cirrus/
 obj-$(CONFIG_DRM_SIS)   += sis/
 obj-$(CONFIG_DRM_SAVAGE)+= savage/
 obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/
diff --git a/drivers/gpu/drm/cirrus/Kconfig b/drivers/gpu/drm/cirrus/Kconfig
new file mode 100644
index 000..67643b9
--- /dev/null
+++ b/drivers/gpu/drm/cirrus/Kconfig
@@ -0,0 +1,7 @@
+config DRM_CIRRUS
+   tristate Cirrus driver
+   depends on DRM  PCI
+   select FB_CFB_FILLRECT
+   select FB_CFB_COPYAREA
+   select FB_CFB_IMAGEBLIT
+   select DRM_KMS_HELPER
diff --git a/drivers/gpu/drm/cirrus/Makefile b/drivers/gpu/drm/cirrus/Makefile
new file mode 100644
index 000..8bd345b
--- /dev/null
+++ b/drivers/gpu/drm/cirrus/Makefile
@@ -0,0 +1,5 @@
+ccflags-y := -Iinclude/drm
+cirrus-y   := cirrus_main.o cirrus_mode.o \
+   cirrus_drv.o cirrus_fbdev.o cirrus_ttm.o
+
+obj-$(CONFIG_DRM_CIRRUS) += cirrus.o
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c 
b/drivers/gpu/drm/cirrus/cirrus_drv.c
new file mode 100644
index 000..2e1f925
--- /dev/null
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2012 Red Hat m...@redhat.com
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License version 2. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * Authors: Matthew Garrett
+ *  Dave Airlie
+ */
+#include linux/module.h
+#include linux/console.h
+#include drmP.h
+#include drm.h
+
+#include cirrus_drv.h
+
+int cirrus_modeset = -1;
+
+MODULE_PARM_DESC(modeset, Disable/Enable modesetting);
+module_param_named(modeset, cirrus_modeset, int, 0400);
+
+/*
+ * This is the generic driver code. This binds the driver to the drm core,
+ * which then performs further device association and calls our graphics init
+ * functions
+ */
+
+static struct drm_driver driver;
+
+/* only bind to the cirrus chip in qemu */
+static DEFINE_PCI_DEVICE_TABLE(pciidlist) = {
+   { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446, 0x1af4, 0x1100, 0,
+ 0, 0 },
+   {0,}
+};
+
+static int __devinit
+cirrus_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+   return drm_get_pci_dev(pdev, ent, driver);
+}
+
+static void cirrus_pci_remove(struct pci_dev *pdev)
+{
+   struct drm_device *dev = pci_get_drvdata(pdev);
+
+   drm_put_dev(dev);
+}
+
+static const struct file_operations cirrus_driver_fops = {
+   .owner = THIS_MODULE,
+   .open = drm_open,
+   .release = drm_release,
+   .unlocked_ioctl = drm_ioctl,
+   .mmap = cirrus_mmap,
+   .poll = drm_poll,
+   .fasync = drm_fasync,
+};
+static struct drm_driver driver = {
+   .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_USE_MTRR,

Re: Re: Include request for reset-rework branch v3

2012-05-02 Thread Dave Airlie
On Wed, May 2, 2012 at 10:04 AM, Christian König
deathsim...@vodafone.de wrote:
 On 02.05.2012 06:04, Jerome Glisse wrote:

 On Wed, May 2, 2012 at 12:00 AM,j.gli...@gmail.com  wrote:

 Ok so i reread stuff and the :
 drm/radeon: add general purpose fence signaled callback
 is a big NAK actually. It change the paradigm. Moving most of
 the handling into the irq process which is something i am intimatly
 convinced we should avoid.

 Here is the patchset up to ib pool cleanup. I have yet rebase the
 other patches as i am tracking done some issue in the sa allocation.

 Cheers,
 Jerome

 Before i forget, the big issue with doing work from irq handler is that
 we never know in middle of what other part can be. I believe it's lot
 better to have irq process only update fence (signaled/not signaled).
 and have the actual work happening on behalf of the process wether
 through sa alloc path or ttm path.


 Disagree.

 Why should it be better to delay work outside of the interrupt context if
 proper locking can make the driver much more responsive and easier to
 implement?

 I don't want to call into TTM or stuff like that, just want make it possible
 to release the resources acquired for a job immediately after the job is
 completed instead of waiting for the next allocation to happen. Cause then
 you don't need to check if a bunch of fences might possible be signaled and
 instead just get a proper signal that resources can be deallocated.

 Also if you really want to keep the irq context out of the drivers upper
 layers, it should be quite easy to modify the code so that the callback
 won't happen from there.

as a general rule try an minimise how much work we do in irq context,
the locking gets very messy once you have to use a mutex somewhere
else in the future.

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


Re: Include request for reset-rework branch v3

2012-05-02 Thread Christian König

On 02.05.2012 12:32, Dave Airlie wrote:

On Wed, May 2, 2012 at 10:04 AM, Christian König
deathsim...@vodafone.de  wrote:

On 02.05.2012 06:04, Jerome Glisse wrote:

On Wed, May 2, 2012 at 12:00 AM,j.gli...@gmail.comwrote:

Ok so i reread stuff and the :
drm/radeon: add general purpose fence signaled callback
is a big NAK actually. It change the paradigm. Moving most of
the handling into the irq process which is something i am intimatly
convinced we should avoid.

Here is the patchset up to ib pool cleanup. I have yet rebase the
other patches as i am tracking done some issue in the sa allocation.

Cheers,
Jerome


Before i forget, the big issue with doing work from irq handler is that
we never know in middle of what other part can be. I believe it's lot
better to have irq process only update fence (signaled/not signaled).
and have the actual work happening on behalf of the process wether
through sa alloc path or ttm path.


Disagree.

Why should it be better to delay work outside of the interrupt context if
proper locking can make the driver much more responsive and easier to
implement?

I don't want to call into TTM or stuff like that, just want make it possible
to release the resources acquired for a job immediately after the job is
completed instead of waiting for the next allocation to happen. Cause then
you don't need to check if a bunch of fences might possible be signaled and
instead just get a proper signal that resources can be deallocated.

Also if you really want to keep the irq context out of the drivers upper
layers, it should be quite easy to modify the code so that the callback
won't happen from there.

as a general rule try an minimise how much work we do in irq context,
the locking gets very messy once you have to use a mutex somewhere
else in the future.
Akk, that sounds reasonable, but I still think that a fence should 
signal it's completion by itself. Because that releases us from the 
burden to walk the list of emitted fences and heuristically check if any 
of them is already signaled.


Also it is pretty easy to move the callback outside of interrupt 
context, but first things first.  I'm going to write together a patchset 
with everything that is already accepted, so we can stop mailing around 
actually unrelated patches.


Thanks for the comments,
Christian.

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


Re: Linux 3.4-rc4

2012-05-02 Thread Ben Skeggs
On Wed, 2012-05-02 at 09:54 +0200, Jean Delvare wrote:
 Hi Luca, Maarten,
 
 On Monday 30 April 2012 01:01:30 pm Luca Tettamanti wrote:
  On Mon, Apr 30, 2012 at 11:07 AM, Maarten Maathuis madman2...@gmail.com 
  wrote:
   On Mon, Apr 30, 2012 at 12:37 AM, Dmitry Torokhov
  
   dmitry.torok...@gmail.com 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 
nbow...@elliptictech.com wrote:
 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
 832x62474.6
 800x60085.1 72.2 75.0 60.3 56.2
 848x48060.0
 640x48085.0 75.0 72.8 72.8 66.7 
 60.0 59.9
 720x40085.0 87.8 70.1
 640x40085.1
 640x35085.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*
 800x60060.3 56.2
 848x48060.0
 640x48059.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.678392] [drm] nouveau :01:00.0: Detected an NV50
   generation card (0x086b00a2)
  
   Just a crazy thought, but didn't we change some timings related to
   EDID retrieval? To make it faster.
  
  Hum, this commit:
  
  commit 

Include request for reset-rework branch v4

2012-05-02 Thread Christian König
Hi Dave,

there still seems to be the need for some further discussion about the SA code,
so I again split that out of the patchset and tested the result a bit.

Most of the stuff still works fine without those offending changes, so to avoid
mailing around unrelated and already reviewed patches, I request the include
the following 17 patches into drm-next.

If you prefer to merge they are also available from
git://people.freedesktop.org/~deathsimple/linux branch reset-rework.

Cheers,
Christian.

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


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

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

Signed-off-by: Christian König deathsim...@vodafone.de
Reviewed-by: Alex Deucher alexander.deuc...@amd.com
Reviewed-by: Jerome Glisse jgli...@redhat.com
---
 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 cb11418..a0b44a5 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 4026a4c0..c76724b 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1547,7 +1547,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 

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

2012-05-02 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 deathsim...@vodafone.de
Reviewed-by: Alex Deucher alexander.deuc...@amd.com
Reviewed-by: Jerome Glisse jgli...@redhat.com
---
 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 610acee..4026a4c0 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1162,7 +1162,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
@@ -1191,6 +1190,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 {
@@ -1740,7 +1740,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))
@@ -1749,6 +1748,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 = 

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

2012-05-02 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 deathsim...@vodafone.de
Reviewed-by: Alex Deucher alexander.deuc...@amd.com
Reviewed-by: Jerome Glisse jgli...@redhat.com
---
 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 06/17] drm/radeon: fix a bug in the SA code

2012-05-02 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 deathsim...@vodafone.de
Reviewed-by: Michel Dänzer michel.daen...@amd.com
Reviewed-by: Jerome Glisse jgli...@redhat.com
---
 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 04/17] drm/radeon: use central function for IB testing

2012-05-02 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 deathsim...@vodafone.de
Reviewed-by: Alex Deucher alexander.deuc...@amd.com
Reviewed-by: Jerome Glisse jgli...@redhat.com
---
 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 a0b44a5..825f117 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 

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

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

Signed-off-by: Christian König deathsim...@vodafone.de
Reviewed-by: Jerome Glisse jgli...@redhat.com
---
 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 65855af..35db5bd 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 

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

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

Signed-off-by: Christian König deathsim...@vodafone.de
Reviewed-by: Jerome Glisse jgli...@redhat.com
---
 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 d73bba8..794182a 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;
struct list_headsignaled;
boolinitialized;
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 2d13843..aadd73a 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -139,8 +139,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;
@@ -153,10 +151,6 @@ int radeon_fence_create(struct radeon_device *rdev,
(*fence)-ring = ring;
(*fence)-semaphore = 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;
 }
 
@@ -411,7 +405,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_LIST_HEAD(rdev-fence_drv[ring].signaled);
init_waitqueue_head(rdev-fence_drv[ring].queue);
-- 
1.7.5.4

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


[PATCH 07/17] drm/radeon: return -ENOENT in fence_wait_next v2

2012-05-02 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 deathsim...@vodafone.de
Reviewed-by: Michel Dänzer michel.daen...@amd.com
Reviewed-by: Jerome Glisse jgli...@redhat.com
---
 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 08/17] drm/radeon: rename fence_wait_last to fence_wait_empty

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

Signed-off-by: Christian König deathsim...@vodafone.de
Reviewed-by: Michel Dänzer michel.daen...@amd.com
Reviewed-by: Jerome Glisse jgli...@redhat.com
---
 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 35db5bd..d73bba8 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 dedb398..89be94b 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -915,7 +915,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 10/17] drm/radeon: fix a bug with the ring syncing code

2012-05-02 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 deathsim...@vodafone.de
Reviewed-by: Jerome Glisse jgli...@redhat.com
---
 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 794182a..f7372c4 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -460,6 +460,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 61dd4e3..930a08a 100644
--- a/drivers/gpu/drm/radeon/radeon_semaphore.c
+++ b/drivers/gpu/drm/radeon/radeon_semaphore.c
@@ -149,6 +149,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 

[PATCH 13/17] drm/radeon: make lockup timeout a module param

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

Signed-off-by: Christian König deathsim...@vodafone.de
Reviewed-by: Jerome Glisse jgli...@redhat.com
---
 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 b8d4d94..0784e4d 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 203ec1f..08e1578 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -441,7 +441,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


  1   2   >