[Intel-gfx] [PATCH] drm/i915/hdmi: only enable audio if there's a hdmi sink

2012-08-30 Thread Daniel Vetter
Some monitors totally don't like to receive infoframes, and naturally
don't claim to support hdmi.

But for some odd reason they've added a CEA block to their edid,
which automatically gives you basic audio. Still, we may not send
out hdmi infoframes to them, hence check whether the sink is indeed
hdmi capable.

Also kill a stale comment while at it.

References: 
http://www.mail-archive.com/dri-devel@lists.freedesktop.org/msg26765.html
Cc: Adam Jackson a...@redhat.com
Cc: Ian Pilcher arequip...@gmail.com
Cc: sta...@vger.kernel.org
Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch
---
 drivers/gpu/drm/i915/intel_hdmi.c |   14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
b/drivers/gpu/drm/i915/intel_hdmi.c
index e4c37bb..7d35367 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -735,7 +735,11 @@ intel_hdmi_detect(struct drm_connector *connector, bool 
force)
if (intel_hdmi-force_audio != HDMI_AUDIO_OFF_DVI)
intel_hdmi-has_hdmi_sink =
drm_detect_hdmi_monitor(edid);
-   intel_hdmi-has_audio = drm_detect_monitor_audio(edid);
+
+   /* We are only allowed to send audio and audio related
+* infoframes if it's an hdmi monitor. */
+   intel_hdmi-has_audio = intel_hdmi-has_hdmi_sink 
+   drm_detect_monitor_audio(edid);
}
connector-display_info.raw_edid = NULL;
kfree(edid);
@@ -755,10 +759,6 @@ static int intel_hdmi_get_modes(struct drm_connector 
*connector)
struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
struct drm_i915_private *dev_priv = connector-dev-dev_private;
 
-   /* We should parse the EDID data and find out if it's an HDMI sink so
-* we can send audio to it.
-*/
-
return intel_ddc_get_modes(connector,
   intel_gmbus_get_adapter(dev_priv,
   
intel_hdmi-ddc_bus));
@@ -783,7 +783,9 @@ intel_hdmi_detect_audio(struct drm_connector *connector)
kfree(edid);
}
 
-   return has_audio;
+   /* We are only allowed to send audio and audio related
+* infoframes if it's an hdmi monitor. */
+   return intel_hdmi-has_hdmi_sink  has_audio;
 }
 
 static int
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] xf86-video-intel 2.20.5 does not detect PCI_CHIP_SANDYBRIDGE_M_GT1

2012-08-30 Thread Daniel Vetter
On Thu, Aug 30, 2012 at 10:12 AM, Zhang, Xiong Y
xiong.y.zh...@intel.com wrote:
 I think vesafb driver should not run.
 But in following dmesg, I see vesafb driver running before drm driver.

If you are on a recent enough stable kernel that's absolutely no
problem - the i915.ko driver will kick the vesafb driver before
setting up things.
-Daniel
-- 
Daniel Vetter
daniel.vet...@ffwll.ch - +41 (0) 79 364 57 48 - http://blog.ffwll.ch
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] xf86-video-intel 2.20.5 does not detect PCI_CHIP_SANDYBRIDGE_M_GT1

2012-08-30 Thread Christian Gmeiner
2012/8/30 Daniel Vetter dan...@ffwll.ch:
 On Thu, Aug 30, 2012 at 10:12 AM, Zhang, Xiong Y
 xiong.y.zh...@intel.com wrote:
 I think vesafb driver should not run.
 But in following dmesg, I see vesafb driver running before drm driver.

 If you are on a recent enough stable kernel that's absolutely no
 problem - the i915.ko driver will kick the vesafb driver before
 setting up things.


[2.142169] fb: conflicting fb hw usage inteldrmfb vs VESA VGA -
removing generic driver

Yep that is done.

---
Christian Gmeiner, MSc
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 1/4] drm/i915: save/restore the legacy backlight control

2012-08-30 Thread Indan Zupancic
On Tue, August 28, 2012 17:15, Daniel Vetter wrote:
 On Tue, Aug 28, 2012 at 04:49:15PM +0200, Indan Zupancic wrote:
 By the way, saving LBPC only makes sense if it's done before it was
 set to 0 to disable the panel. I don't know if the current code does
 the right thing, I haven't looked at it for a while.

 I think we can coax it into doing the right thing, see my other mail. If
 your completely sure that lbpc /should/ be handled by the bios across s/r
 I think we can drop this. But tbh I have no idea how this really is
 supposed to work, and unfortunately we're not allowed to cross-check with
 the windows driver codebase :(

Of course I'm not completely sure. But I agree with Chris' reasoning,
why else have two ways of controlling the backlight? To me LBPC gives
the impression of being a system specific thing the OS shouldn't need
to worry about. Partly because it wasn't documented in the old docs at
all, and its address isn't mentioned in the 965 vol3 manual, but also
because it's from around the time that the BIOS used to do a lot more
directly (APM versus ACPI etc.) It also gives a way to lower the max
output voltage (via PWM) to the backlight hardware.

These kind of problems are caused by us not having exactly the same
info as the BIOS/machine makers got. Because that's what guided them
into making the stuff as it is, not how it's supposed to work.

The code could check if LBPC has a reasonable value after resume: Do
nothing if it has and restore the last known good value if it doesn't.

Writing 0 to LBPC before suspend seems unnecessary because the hardware
is going into sleep mode anyway. So the PWM signal should become 0 anyway,
or if it doesn't, the BIOS has a chance to disable the backlight. But I'm
not sure if that's really true.

So to get back to this patch, saving the LBPC value only makes sense if
it's done before it's set to 0. I think saving it at i915_save_display()
time is too late if the panel got disabled. Then the code is always saving
and restoring zeros.

BTW, inverted sense of the PWM register could be related to the polarity
of the PWM signal. That should be controlled with bit 28 in BLC_PWM_CTL2.

Greetings,

Indan


___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915/edp: get the panel delay before powering up

2012-08-30 Thread Daniel Vetter
On Thu, Aug 30, 2012 at 11:06:18AM +1000, Dave Airlie wrote:
 In order to setup the i2c channel, we power up the panel
 via ironlake_edp_panel_vdd_on, however it requires
 intel_dp-panel_power_up_delay to be initialised,
 which hasn't been setup yet.
 
 So move things around so we set the panel power up
 values first then init the i2c stuff.
 
 This is one step to fixing the eDP panel in the MBP
 from uninitialised state.
 
 Signed-off-by: Dave Airlie airl...@redhat.com
Picked up for -fixes, thanks for the patch.
-Daniel
-- 
Daniel Vetter
Mail: dan...@ffwll.ch
Mobile: +41 (0)79 365 57 48
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 2/4] drm/i915: remove combination mode for backlight control, again

2012-08-30 Thread Indan Zupancic
On Tue, August 28, 2012 16:55, Daniel Vetter wrote:
 On Tue, Aug 28, 2012 at 04:39:34PM +0200, Indan Zupancic wrote:
 Some backlight problems on GEN4 can be solved by not fiddling with the
 backlight. The current code sets the backlight to 0 to disable the panel
 (last year anyway, maybe the code changed), but on gen = 4 it can do the
 same by clearing bit 31 in BLC_PWM_CLT2. That way the original backlight
 value doesn't need to be saved anywhere.

 A while back I've improved the backlight code to properly switch the pipe
 that controls the pwm and also to properly toggle the enable bit for
 gen4+, see the new intel_panel_enable_backlight functions. Would it be
 correct in your opinion to simply ditch the call to
 intel_panel_actually_set_backlight for gen4+ unconditionally? Same for
 intel_panel_disable_backlight obviously?

Yes, that seems the whole point of having the PWM disable bit.

I would also ditch the backlight_enabled state tracking, as it's
unnecessary and incorrect because the enable/disable calls aren't
balanced.

I'll update my kernel to the latest git code and try out how the
current code works and if not touching LBPC at all works for gen 2
hardware. If it doesn't then LBPC needs to be saved/restored in
i915_suspend.c after all.

It would be nice if backlight control worked with ASLE disabled,
that would get rid of all complexity, including combination mode.
Or alternatively, if disabling combination mode at boot works then
we can get rid of the complicated brightness setting code to cope
with it.

Greetings,

Indan


___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 00/58] modeset-rework, the basic conversion

2012-08-30 Thread Rodrigo Vivi
I forgot to say that I tested tv out here on 945GME Express and
82945G/GZ and it worked fine as well. No regression.

On Wed, Aug 29, 2012 at 9:26 AM, Lespiau, Damien
damien.lesp...@intel.com wrote:
 On Thu, Aug 23, 2012 at 11:39 PM, Daniel Vetter dan...@ffwll.ch wrote:
 On Thu, Aug 23, 2012 at 01:26:39PM +0100, Lespiau, Damien wrote:
 On Wed, Aug 22, 2012 at 10:21 PM, Daniel Vetter dan...@ffwll.ch wrote:
  Please test the for-damien branch in my personal fdo git repo. I'm rather
  positive that the patch there should fix this (but in the least it should
  unearth the real culprit).

 After a bit of back and forth and the updated 50/58 patch, does not
 regress any more here with the testing done on an IVB system.

 Tested-by:  Damien Lespiau damien.lesp...@intel.com

 --
 Damien
 ___
 Intel-gfx mailing list
 Intel-gfx@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] xf86-video-intel 2.20.5 does not detect PCI_CHIP_SANDYBRIDGE_M_GT1

2012-08-30 Thread Chris Wilson
On Thu, 30 Aug 2012 10:24:17 +0200, Christian Gmeiner 
christian.gmei...@gmail.com wrote:
 [13.840] drmOpenDevice: node name is /dev/dri/card0
 [13.840] drmOpenDevice: open result is 7, (OK)
 [13.840] drmOpenByBusid: Searching for BusID pci::00:02.0
 [13.840] drmOpenDevice: node name is /dev/dri/card0
 [13.840] drmOpenDevice: open result is 7, (OK)
 [13.840] drmOpenByBusid: drmOpenMinor returns 7
 [13.840] drmOpenByBusid: Interface 1.4 failed, trying 1.1
 [13.840] drmOpenByBusid: drmGetBusid reports

This is the reason why we fail to detect the device. The device node
exists but the drmSetVersion call fails, which is, of course,
completely impossible. Both Fedora and Ubuntu are tracking a race
condition in the early setup with afaict exactly this symptom.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] xf86-video-intel 2.20.5 does not detect PCI_CHIP_SANDYBRIDGE_M_GT1

2012-08-30 Thread Christian Gmeiner
2012/8/30 Chris Wilson ch...@chris-wilson.co.uk:
 On Thu, 30 Aug 2012 10:24:17 +0200, Christian Gmeiner 
 christian.gmei...@gmail.com wrote:
 [13.840] drmOpenDevice: node name is /dev/dri/card0
 [13.840] drmOpenDevice: open result is 7, (OK)
 [13.840] drmOpenByBusid: Searching for BusID pci::00:02.0
 [13.840] drmOpenDevice: node name is /dev/dri/card0
 [13.840] drmOpenDevice: open result is 7, (OK)
 [13.840] drmOpenByBusid: drmOpenMinor returns 7
 [13.840] drmOpenByBusid: Interface 1.4 failed, trying 1.1
 [13.840] drmOpenByBusid: drmGetBusid reports

 This is the reason why we fail to detect the device. The device node
 exists but the drmSetVersion call fails, which is, of course,
 completely impossible. Both Fedora and Ubuntu are tracking a race
 condition in the early setup with afaict exactly this symptom.

Thanks for the hint :)

I changed /etc/initramfs-tools/modules from
intel_agp
drm
i915 modesetting=1

to
ntel_agp
drm
i915

rebuild initramfs and rebooted

[12.768] (WW) VGA arbiter: cannot open kernel arbiter, no multi-card support
[12.768] drmOpenDevice: node name is /dev/dri/card0
[12.768] drmOpenDevice: open result is 7, (OK)
[12.768] drmOpenByBusid: Searching for BusID pci::00:02.0
[12.768] drmOpenDevice: node name is /dev/dri/card0
[12.768] drmOpenDevice: open result is 7, (OK)
[12.768] drmOpenByBusid: drmOpenMinor returns 7
[12.768] drmOpenByBusid: drmGetBusid reports pci::00:02.0
[12.768] (II) intel(0): Creating default Display subsection in
Screen section
Default Screen Section for depth/fbbpp 24/32
[12.768] (==) intel(0): Depth 24, (--) framebuffer bpp 32
[12.768] (==) intel(0): RGB weight 888
[12.768] (==) intel(0): Default visual is TrueColor
[12.768] (--) intel(0): Integrated Graphics Chipset: Intel(R)
Sandybridge Mobile (GT1)
[12.768] (**) intel(0): Relaxed fencing enabled
[12.768] (**) intel(0): Wait on SwapBuffers? enabled
[12.768] (**) intel(0): Triple buffering? enabled
[12.768] (**) intel(0): Framebuffer tiled
[12.768] (**) intel(0): Pixmaps tiled
[12.768] (**) intel(0): 3D buffers tiled
[12.769] (**) intel(0): SwapBuffers wait enabled
[12.769] (==) intel(0): video overlay key set to 0x101fe
[12.769] (II) intel(0): Output LVDS1 has no monitor section
[12.769] (II) intel(0): found backlight control interface
/sys/class/backlight/acpi_video0
[12.807] (II) intel(0): Output VGA1 has no monitor section
[12.807] (II) intel(0): Output HDMI1 has no monitor section
[12.832] (II) intel(0): Output DP1 has no monitor section
[12.836] (II) intel(0): Output HDMI2 has no monitor section
[12.840] (II) intel(0): Output HDMI3 has no monitor section
[12.864] (II) intel(0): Output DP2 has no monitor section
[12.888] (II) intel(0): Output DP3 has no monitor section
[12.888] (II) intel(0): EDID for output LVDS1
[12.888] (II) intel(0): Not using default mode 320x240
(doublescan mode not supported)
[12.888] (II) intel(0): Not using default mode 400x300
(doublescan mode not supported)
[12.888] (II) intel(0): Not using default mode 400x300
(doublescan mode not supported)
[12.888] (II) intel(0): Not using default mode 512x384
(doublescan mode not supported)
[12.888] (II) intel(0): Not using default mode 640x480
(doublescan mode not supported)
[12.888] (II) intel(0): Not using default mode 640x512
(doublescan mode not supported)
[12.888] (II) intel(0): Not using default mode 800x600
(doublescan mode not supported)
[12.888] (II) intel(0): Not using default mode 896x672
(doublescan mode not supported)
[12.888] (II) intel(0): Not using default mode 928x696
(doublescan mode not supported)
[12.888] (II) intel(0): Not using default mode 960x720
(doublescan mode not supported)
[12.888] (II) intel(0): Not using default mode 576x432
(doublescan mode not supported)
[12.888] (II) intel(0): Not using default mode 680x384
(doublescan mode not supported)
[12.888] (II) intel(0): Not using default mode 680x384
(doublescan mode not supported)
[12.888] (II) intel(0): Not using default mode 700x525
(doublescan mode not supported)
[12.888] (II) intel(0): Not using default mode 720x450
(doublescan mode not supported)
[12.888] (II) intel(0): Not using default mode 800x512
(doublescan mode not supported)
[12.888] (II) intel(0): Not using default mode 840x525
(doublescan mode not supported)
[12.888] (II) intel(0): Not using default mode 840x525
(doublescan mode not supported)
[12.888] (II) intel(0): Not using default mode 960x540
(doublescan mode not supported)
[12.888] (II) intel(0): Not using default mode 960x600
(doublescan mode not supported)
[12.888] (II) intel(0): Printing probed modes for output LVDS1
[12.888] (II) intel(0): Modeline 1024x768x60.0   65.00  1024
1048 1184 1344  768 771 777 806 -hsync -vsync (48.4 kHz)
[12.888] (II) intel(0): Modeline 800x600x60.3 

[Intel-gfx] [PATCH] drm/i915: add a tracepoint for gpu frequency changes

2012-08-30 Thread Daniel Vetter
We've had and still have too many issues where the gpu turbot doesn't
quite to what it's supposed to do (or what we want it to do).

Adding a tracepoint to track when the desired gpu frequence changes
should help a lot in characterizing and understanding problematic
workloads.

Also, this should be fairly interesting for power tuning (and
especially noticing when the gpu is stuck in high frequencies, as has
happened in the past) and hence for integration into powertop and
similar tools.

Cc: Arjan van de Ven ar...@linux.intel.com
Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch
---
 drivers/gpu/drm/i915/i915_trace.h |   15 +++
 drivers/gpu/drm/i915/intel_pm.c   |2 ++
 2 files changed, 17 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_trace.h 
b/drivers/gpu/drm/i915/i915_trace.h
index 3c4093d..8134421 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -430,6 +430,21 @@ TRACE_EVENT(i915_reg_rw,
(u32)(__entry-val  32))
 );
 
+TRACE_EVENT(intel_gpu_freq_change,
+   TP_PROTO(u32 freq),
+   TP_ARGS(freq),
+
+   TP_STRUCT__entry(
+__field(u32, freq)
+),
+
+   TP_fast_assign(
+  __entry-freq = freq;
+  ),
+
+   TP_printk(new_freq=%u, __entry-freq)
+);
+
 #endif /* _I915_TRACE_H_ */
 
 /* This part must be outside protection */
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index ebe3498..194a72f 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2343,6 +2343,8 @@ void gen6_set_rps(struct drm_device *dev, u8 val)
I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits);
 
dev_priv-rps.cur_delay = val;
+
+   trace_intel_gpu_freq_change(val * 50);
 }
 
 static void gen6_disable_rps(struct drm_device *dev)
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] xf86-video-intel 2.20.5 does not detect PCI_CHIP_SANDYBRIDGE_M_GT1

2012-08-30 Thread Christian Gmeiner
2012/8/30 Christian Gmeiner christian.gmei...@gmail.com:
 2012/8/30 Chris Wilson ch...@chris-wilson.co.uk:
 On Thu, 30 Aug 2012 10:24:17 +0200, Christian Gmeiner 
 christian.gmei...@gmail.com wrote:
 [13.840] drmOpenDevice: node name is /dev/dri/card0
 [13.840] drmOpenDevice: open result is 7, (OK)
 [13.840] drmOpenByBusid: Searching for BusID pci::00:02.0
 [13.840] drmOpenDevice: node name is /dev/dri/card0
 [13.840] drmOpenDevice: open result is 7, (OK)
 [13.840] drmOpenByBusid: drmOpenMinor returns 7
 [13.840] drmOpenByBusid: Interface 1.4 failed, trying 1.1
 [13.840] drmOpenByBusid: drmGetBusid reports

 This is the reason why we fail to detect the device. The device node
 exists but the drmSetVersion call fails, which is, of course,
 completely impossible. Both Fedora and Ubuntu are tracking a race
 condition in the early setup with afaict exactly this symptom.

 Thanks for the hint :)

 I changed /etc/initramfs-tools/modules from
 intel_agp
 drm
 i915 modesetting=1

 to
 ntel_agp
 drm
 i915

 rebuild initramfs and rebooted

 [12.768] (WW) VGA arbiter: cannot open kernel arbiter, no multi-card 
 support
 [12.768] drmOpenDevice: node name is /dev/dri/card0
 [12.768] drmOpenDevice: open result is 7, (OK)
 [12.768] drmOpenByBusid: Searching for BusID pci::00:02.0
 [12.768] drmOpenDevice: node name is /dev/dri/card0
 [12.768] drmOpenDevice: open result is 7, (OK)
 [12.768] drmOpenByBusid: drmOpenMinor returns 7
 [12.768] drmOpenByBusid: drmGetBusid reports pci::00:02.0
 [12.768] (II) intel(0): Creating default Display subsection in
 Screen section
 Default Screen Section for depth/fbbpp 24/32
 [12.768] (==) intel(0): Depth 24, (--) framebuffer bpp 32
 [12.768] (==) intel(0): RGB weight 888
 [12.768] (==) intel(0): Default visual is TrueColor
 [12.768] (--) intel(0): Integrated Graphics Chipset: Intel(R)
 Sandybridge Mobile (GT1)
 [12.768] (**) intel(0): Relaxed fencing enabled
 [12.768] (**) intel(0): Wait on SwapBuffers? enabled
 [12.768] (**) intel(0): Triple buffering? enabled
 [12.768] (**) intel(0): Framebuffer tiled
 [12.768] (**) intel(0): Pixmaps tiled
 [12.768] (**) intel(0): 3D buffers tiled
 [12.769] (**) intel(0): SwapBuffers wait enabled
 [12.769] (==) intel(0): video overlay key set to 0x101fe
 [12.769] (II) intel(0): Output LVDS1 has no monitor section
 [12.769] (II) intel(0): found backlight control interface
 /sys/class/backlight/acpi_video0
 [12.807] (II) intel(0): Output VGA1 has no monitor section
 [12.807] (II) intel(0): Output HDMI1 has no monitor section
 [12.832] (II) intel(0): Output DP1 has no monitor section
 [12.836] (II) intel(0): Output HDMI2 has no monitor section
 [12.840] (II) intel(0): Output HDMI3 has no monitor section
 [12.864] (II) intel(0): Output DP2 has no monitor section
 [12.888] (II) intel(0): Output DP3 has no monitor section
 [12.888] (II) intel(0): EDID for output LVDS1
 [12.888] (II) intel(0): Not using default mode 320x240
 (doublescan mode not supported)
 [12.888] (II) intel(0): Not using default mode 400x300
 (doublescan mode not supported)
 [12.888] (II) intel(0): Not using default mode 400x300
 (doublescan mode not supported)
 [12.888] (II) intel(0): Not using default mode 512x384
 (doublescan mode not supported)
 [12.888] (II) intel(0): Not using default mode 640x480
 (doublescan mode not supported)
 [12.888] (II) intel(0): Not using default mode 640x512
 (doublescan mode not supported)
 [12.888] (II) intel(0): Not using default mode 800x600
 (doublescan mode not supported)
 [12.888] (II) intel(0): Not using default mode 896x672
 (doublescan mode not supported)
 [12.888] (II) intel(0): Not using default mode 928x696
 (doublescan mode not supported)
 [12.888] (II) intel(0): Not using default mode 960x720
 (doublescan mode not supported)
 [12.888] (II) intel(0): Not using default mode 576x432
 (doublescan mode not supported)
 [12.888] (II) intel(0): Not using default mode 680x384
 (doublescan mode not supported)
 [12.888] (II) intel(0): Not using default mode 680x384
 (doublescan mode not supported)
 [12.888] (II) intel(0): Not using default mode 700x525
 (doublescan mode not supported)
 [12.888] (II) intel(0): Not using default mode 720x450
 (doublescan mode not supported)
 [12.888] (II) intel(0): Not using default mode 800x512
 (doublescan mode not supported)
 [12.888] (II) intel(0): Not using default mode 840x525
 (doublescan mode not supported)
 [12.888] (II) intel(0): Not using default mode 840x525
 (doublescan mode not supported)
 [12.888] (II) intel(0): Not using default mode 960x540
 (doublescan mode not supported)
 [12.888] (II) intel(0): Not using default mode 960x600
 (doublescan mode not supported)
 [12.888] (II) intel(0): Printing probed modes for output LVDS1
 [12.888] (II) 

Re: [Intel-gfx] [PATCH] drm/i915: add a tracepoint for gpu frequency changes

2012-08-30 Thread Chris Wilson
On Thu, 30 Aug 2012 13:26:48 +0200, Daniel Vetter daniel.vet...@ffwll.ch 
wrote:
 We've had and still have too many issues where the gpu turbot doesn't
 quite to what it's supposed to do (or what we want it to do).
 
 Adding a tracepoint to track when the desired gpu frequence changes
 should help a lot in characterizing and understanding problematic
 workloads.
 
 Also, this should be fairly interesting for power tuning (and
 especially noticing when the gpu is stuck in high frequencies, as has
 happened in the past) and hence for integration into powertop and
 similar tools.
 
 Cc: Arjan van de Ven ar...@linux.intel.com
 Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch

Like it, even the naming scheme.
Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: add a tracepoint for gpu frequency changes

2012-08-30 Thread Paul Menzel
Am Donnerstag, den 30.08.2012, 13:26 +0200 schrieb Daniel Vetter:
 We've had and still have too many issues where the gpu turbot doesn't

s,turbot,turbo,

 quite to what it's supposed to do (or what we want it to do).

s,to,do,

 Adding a tracepoint to track when the desired gpu frequence changes

frequenc*y*

 should help a lot in characterizing and understanding problematic
 workloads.
 
 Also, this should be fairly interesting for power tuning (and
 especially noticing when the gpu is stuck in high frequencies, as has
 happened in the past) and hence for integration into powertop and
 similar tools.

If this can be used from user space already, it would be nice to add
some notes to the commit how this can be done.

 Cc: Arjan van de Ven ar...@linux.intel.com
 Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch
 ---
  drivers/gpu/drm/i915/i915_trace.h |   15 +++
  drivers/gpu/drm/i915/intel_pm.c   |2 ++
  2 files changed, 17 insertions(+)
 
 diff --git a/drivers/gpu/drm/i915/i915_trace.h 
 b/drivers/gpu/drm/i915/i915_trace.h
 index 3c4093d..8134421 100644
 --- a/drivers/gpu/drm/i915/i915_trace.h
 +++ b/drivers/gpu/drm/i915/i915_trace.h
 @@ -430,6 +430,21 @@ TRACE_EVENT(i915_reg_rw,
   (u32)(__entry-val  32))
  );
  
 +TRACE_EVENT(intel_gpu_freq_change,
 + TP_PROTO(u32 freq),
 + TP_ARGS(freq),
 +
 + TP_STRUCT__entry(
 +  __field(u32, freq)
 +  ),
 +
 + TP_fast_assign(
 +__entry-freq = freq;
 +),
 +
 + TP_printk(new_freq=%u, __entry-freq)
 +);
 +
  #endif /* _I915_TRACE_H_ */
  
  /* This part must be outside protection */
 diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
 index ebe3498..194a72f 100644
 --- a/drivers/gpu/drm/i915/intel_pm.c
 +++ b/drivers/gpu/drm/i915/intel_pm.c
 @@ -2343,6 +2343,8 @@ void gen6_set_rps(struct drm_device *dev, u8 val)
   I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits);
  
   dev_priv-rps.cur_delay = val;
 +
 + trace_intel_gpu_freq_change(val * 50);
  }
  
  static void gen6_disable_rps(struct drm_device *dev)

Acked-by: Paul Menzel paulepan...@users.sourceforge.net


Thanks,

Paul


signature.asc
Description: This is a digitally signed message part
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 22/29] drm/i915: Handle stolen objects in pwrite

2012-08-30 Thread Chris Wilson
On Mon, 20 Aug 2012 21:56:08 +0200, Daniel Vetter dan...@ffwll.ch wrote:
 On Sat, Aug 11, 2012 at 03:41:21PM +0100, Chris Wilson wrote:
  Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
 
 What about putting kmap/unmap abstractions into obj-ops (like the dma_buf
 interface already has)? Since the pwrite/pread code is already rather
 branch heave I hope we don't see the overhead of the indirect call even
 in microbenchmarks (haven't checked). And this way we would also neatly
 wrap up dma_bufs for pwrite (if anyone ever really wants that ...).
 
 The kmap(_atomic) for stolen mem backed objects would boil down to doing
 the pointer arithmetic, kunmap would be just a noop.

Tried doing so. The lack of struct page for the stolen makes it more
cumbersome than it is worth, and worse confusing.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] Next iteration of stolen support

2012-08-30 Thread Chris Wilson
Just to keep the context for deciding upon the correct colour of paint,
here are the current patches to replace obj-pages with a scatterlist
and use that to map objects into the stolen memory.
-Chris

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 05/24] drm/i915: Replace the array of pages with a scatterlist

2012-08-30 Thread Chris Wilson
Rather than have multiple data structures for describing our page layout
in conjunction with the array of pages, we can migrate all users over to
a scatterlist.

One major advantage, other than unifying the page tracking structures,
this offers is that we replace the vmalloc'ed array (which can be up to
a megabyte in size) with a chain of individual pages which helps reduce
memory pressure.

The disadvantage is that we then do not have a simple array to iterate,
or to access randomly. The common case for this is in the relocation
processing, which will typically fit within a single scatterlist page
and so be almost the same cost as the simple array. For iterating over
the array, the extra function call could be optimised away, but in
reality is an insignificant cost of either binding the pages, or
performing the pwrite/pread.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/char/agp/intel-gtt.c   |   51 +---
 drivers/gpu/drm/drm_cache.c|   23 ++
 drivers/gpu/drm/i915/i915_drv.h|   18 +++--
 drivers/gpu/drm/i915/i915_gem.c|   79 --
 drivers/gpu/drm/i915/i915_gem_dmabuf.c |   99 +++
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |3 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c|  121 ++--
 drivers/gpu/drm/i915/i915_gem_tiling.c |   16 ++--
 drivers/gpu/drm/i915/i915_irq.c|   25 +++---
 drivers/gpu/drm/i915/intel_ringbuffer.c|9 ++-
 include/drm/drmP.h |1 +
 include/drm/intel-gtt.h|   10 +--
 12 files changed, 236 insertions(+), 219 deletions(-)

diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index 08fc5cb..b78e196 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -84,40 +84,33 @@ static struct _intel_private {
 #define IS_IRONLAKEintel_private.driver-is_ironlake
 #define HAS_PGTBL_EN   intel_private.driver-has_pgtbl_enable
 
-int intel_gtt_map_memory(struct page **pages, unsigned int num_entries,
-struct scatterlist **sg_list, int *num_sg)
+static int intel_gtt_map_memory(struct page **pages,
+   unsigned int num_entries,
+   struct sg_table *st)
 {
-   struct sg_table st;
struct scatterlist *sg;
int i;
 
-   if (*sg_list)
-   return 0; /* already mapped (for e.g. resume */
-
DBG(try mapping %lu pages\n, (unsigned long)num_entries);
 
-   if (sg_alloc_table(st, num_entries, GFP_KERNEL))
+   if (sg_alloc_table(st, num_entries, GFP_KERNEL))
goto err;
 
-   *sg_list = sg = st.sgl;
-
-   for (i = 0 ; i  num_entries; i++, sg = sg_next(sg))
+   for_each_sg(st-sgl, sg, num_entries,i)
sg_set_page(sg, pages[i], PAGE_SIZE, 0);
 
-   *num_sg = pci_map_sg(intel_private.pcidev, *sg_list,
-num_entries, PCI_DMA_BIDIRECTIONAL);
-   if (unlikely(!*num_sg))
+   if (!pci_map_sg(intel_private.pcidev,
+   st-sgl, st-nents, PCI_DMA_BIDIRECTIONAL))
goto err;
 
return 0;
 
 err:
-   sg_free_table(st);
+   sg_free_table(st);
return -ENOMEM;
 }
-EXPORT_SYMBOL(intel_gtt_map_memory);
 
-void intel_gtt_unmap_memory(struct scatterlist *sg_list, int num_sg)
+static void intel_gtt_unmap_memory(struct scatterlist *sg_list, int num_sg)
 {
struct sg_table st;
DBG(try unmapping %lu pages\n, (unsigned long)mem-page_count);
@@ -130,7 +123,6 @@ void intel_gtt_unmap_memory(struct scatterlist *sg_list, 
int num_sg)
 
sg_free_table(st);
 }
-EXPORT_SYMBOL(intel_gtt_unmap_memory);
 
 static void intel_fake_agp_enable(struct agp_bridge_data *bridge, u32 mode)
 {
@@ -879,8 +871,7 @@ static bool i830_check_flags(unsigned int flags)
return false;
 }
 
-void intel_gtt_insert_sg_entries(struct scatterlist *sg_list,
-unsigned int sg_len,
+void intel_gtt_insert_sg_entries(struct sg_table *st,
 unsigned int pg_start,
 unsigned int flags)
 {
@@ -892,12 +883,11 @@ void intel_gtt_insert_sg_entries(struct scatterlist 
*sg_list,
 
/* sg may merge pages, but we have to separate
 * per-page addr for GTT */
-   for_each_sg(sg_list, sg, sg_len, i) {
+   for_each_sg(st-sgl, sg, st-nents, i) {
len = sg_dma_len(sg)  PAGE_SHIFT;
for (m = 0; m  len; m++) {
dma_addr_t addr = sg_dma_address(sg) + (m  
PAGE_SHIFT);
-   intel_private.driver-write_entry(addr,
- j, flags);
+   intel_private.driver-write_entry(addr, j, flags);
j++;
}
}
@@ -905,8 +895,10 @@ void 

[Intel-gfx] [PATCH 06/24] drm/i915: Convert the dmabuf object to use the new i915_gem_object_ops

2012-08-30 Thread Chris Wilson
By providing a callback for when we need to bind the pages, and then
release them again later, we can shorten the amount of time we hold the
foreign pages mapped and pinned, and importantly the dmabuf objects then
behave as any other normal object with respect to the shrinker and
memory management.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_drv.h|1 -
 drivers/gpu/drm/i915/i915_gem.c|   10 
 drivers/gpu/drm/i915/i915_gem_dmabuf.c |   44 ++--
 drivers/gpu/drm/i915/i915_gem_gtt.c|4 +--
 4 files changed, 37 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1a714fa..a86f50d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -998,7 +998,6 @@ struct drm_i915_gem_object {
int pages_pin_count;
 
/* prime dma-buf support */
-   struct sg_table *sg_table;
void *dma_buf_vmapping;
int vmapping_count;
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index c420e01..c922aef 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1692,7 +1692,7 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
 {
const struct drm_i915_gem_object_ops *ops = obj-ops;
 
-   if (obj-sg_table || obj-pages == NULL)
+   if (obj-pages == NULL)
return 0;
 
BUG_ON(obj-gtt_space);
@@ -1838,7 +1838,7 @@ i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
const struct drm_i915_gem_object_ops *ops = obj-ops;
int ret;
 
-   if (obj-sg_table || obj-pages)
+   if (obj-pages)
return 0;
 
BUG_ON(obj-pages_pin_count);
@@ -3731,9 +3731,6 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
 
trace_i915_gem_object_destroy(obj);
 
-   if (gem_obj-import_attach)
-   drm_prime_gem_destroy(gem_obj, obj-sg_table);
-
if (obj-phys_obj)
i915_gem_detach_phys_object(dev, obj);
 
@@ -3755,6 +3752,9 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
 
BUG_ON(obj-pages);
 
+   if (obj-base.import_attach)
+   drm_prime_gem_destroy(obj-base, NULL);
+
drm_gem_object_release(obj-base);
i915_gem_info_remove_obj(dev_priv, obj-base.size);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
index 4bb1b94..ca3497e 100644
--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
@@ -82,7 +82,8 @@ out:
 }
 
 static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment,
-   struct sg_table *sg, enum dma_data_direction dir)
+  struct sg_table *sg,
+  enum dma_data_direction dir)
 {
dma_unmap_sg(attachment-dev, sg-sgl, sg-nents, dir);
sg_free_table(sg);
@@ -228,11 +229,35 @@ struct dma_buf *i915_gem_prime_export(struct drm_device 
*dev,
return dma_buf_export(obj, i915_dmabuf_ops, obj-base.size, 0600);
 }
 
+static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
+{
+   struct sg_table *sg;
+
+   sg = dma_buf_map_attachment(obj-base.import_attach, DMA_BIDIRECTIONAL);
+   if (IS_ERR(sg))
+   return PTR_ERR(sg);
+
+   obj-pages = sg;
+   obj-has_dma_mapping = true;
+   return 0;
+}
+
+static void i915_gem_object_put_pages_dmabuf(struct drm_i915_gem_object *obj)
+{
+   dma_buf_unmap_attachment(obj-base.import_attach,
+obj-pages, DMA_BIDIRECTIONAL);
+   obj-has_dma_mapping = false;
+}
+
+static const struct drm_i915_gem_object_ops i915_gem_object_dmabuf_ops = {
+   .get_pages = i915_gem_object_get_pages_dmabuf,
+   .put_pages = i915_gem_object_put_pages_dmabuf,
+};
+
 struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
 struct dma_buf *dma_buf)
 {
struct dma_buf_attachment *attach;
-   struct sg_table *sg;
struct drm_i915_gem_object *obj;
int ret;
 
@@ -251,34 +276,25 @@ struct drm_gem_object *i915_gem_prime_import(struct 
drm_device *dev,
if (IS_ERR(attach))
return ERR_CAST(attach);
 
-   sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
-   if (IS_ERR(sg)) {
-   ret = PTR_ERR(sg);
-   goto fail_detach;
-   }
 
obj = kzalloc(sizeof(*obj), GFP_KERNEL);
if (obj == NULL) {
ret = -ENOMEM;
-   goto fail_unmap;
+   goto fail_detach;
}
 
ret = drm_gem_private_object_init(dev, obj-base, dma_buf-size);
if (ret) {
kfree(obj);
-   goto fail_unmap;
+   goto fail_detach;
}
 
-   obj-has_dma_mapping = true;
-  

[Intel-gfx] [PATCH 10/24] drm/i915: Avoid clearing preallocated regions from the GTT

2012-08-30 Thread Chris Wilson
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_drv.h |2 ++
 drivers/gpu/drm/i915/i915_gem_gtt.c |   35 ---
 2 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f614c26..533361e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -899,6 +899,8 @@ enum i915_cache_level {
I915_CACHE_LLC_MLC, /* gen6+, in docs at least! */
 };
 
+#define I915_GTT_RESERVED ((struct drm_mm_node *)0x1)
+
 struct drm_i915_gem_object_ops {
int (*get_pages)(struct drm_i915_gem_object *);
void (*put_pages)(struct drm_i915_gem_object *);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index ea4fc20..528fd43 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -375,18 +375,47 @@ void i915_gem_init_global_gtt(struct drm_device *dev,
  unsigned long end)
 {
drm_i915_private_t *dev_priv = dev-dev_private;
+   struct drm_mm_node *entry;
+   struct drm_i915_gem_object *obj;
 
-   /* Substract the guard page ... */
+   /* Subtract the guard page ... */
drm_mm_init(dev_priv-mm.gtt_space, start, end - start - PAGE_SIZE);
if (!HAS_LLC(dev))
dev_priv-mm.gtt_space.color_adjust = i915_gtt_color_adjust;
 
+   /* Mark any preallocated objects as occupied */
+   list_for_each_entry(obj, dev_priv-mm.bound_list, gtt_list) {
+   DRM_DEBUG_KMS(reserving preallocated space: %x + %zx\n,
+ obj-gtt_offset, obj-base.size);
+
+   BUG_ON(obj-gtt_space != I915_GTT_RESERVED);
+   obj-gtt_space = drm_mm_create_block(dev_priv-mm.gtt_space,
+obj-gtt_offset,
+obj-base.size,
+false);
+   obj-has_global_gtt_mapping = 1;
+   }
+
dev_priv-mm.gtt_start = start;
dev_priv-mm.gtt_mappable_end = mappable_end;
dev_priv-mm.gtt_end = end;
dev_priv-mm.gtt_total = end - start;
dev_priv-mm.mappable_gtt_total = min(end, mappable_end) - start;
 
-   /* ... but ensure that we clear the entire range. */
-   intel_gtt_clear_range(start / PAGE_SIZE, (end-start) / PAGE_SIZE);
+   /* Clear any non-preallocated blocks */
+   list_for_each_entry(entry, dev_priv-mm.gtt_space.hole_stack, 
hole_stack) {
+   unsigned long hole_start = entry-start + entry-size;
+   unsigned long hole_end = list_entry(entry-node_list.next,
+   struct drm_mm_node,
+   node_list)-start;
+
+   DRM_DEBUG_KMS(clearing unused GTT space: [%lx, %lx]\n,
+ hole_start, hole_end);
+
+   intel_gtt_clear_range(hole_start / PAGE_SIZE,
+ (hole_end-hole_start) / PAGE_SIZE);
+   }
+
+   /* And finally clear the reserved guard page */
+   intel_gtt_clear_range(end / PAGE_SIZE - 1, 1);
 }
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 13/24] drm/i915: Defer allocation of stolen memory for FBC until first use

2012-08-30 Thread Chris Wilson
As FBC is commonly disabled due to limitations of the chipset upon
output configurations, on many systems FBC is never enabled. For those
systems, it is advantageous to make use of the stolen memory for other
objects and so we defer allocation of the FBC chunk until we actually
require it. This increases the likelihood of that allocation failing,
which in turns means that we are already taking advantage of the stolen
memory!

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/intel_pm.c |   13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 008263c..9e9eded 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -438,12 +438,6 @@ void intel_update_fbc(struct drm_device *dev)
dev_priv-no_fbc_reason = FBC_MODULE_PARAM;
goto out_disable;
}
-   if (intel_fb-obj-base.size  dev_priv-cfb_size) {
-   DRM_DEBUG_KMS(framebuffer too large, disabling 
- compression\n);
-   dev_priv-no_fbc_reason = FBC_STOLEN_TOO_SMALL;
-   goto out_disable;
-   }
if ((crtc-mode.flags  DRM_MODE_FLAG_INTERLACE) ||
(crtc-mode.flags  DRM_MODE_FLAG_DBLSCAN)) {
DRM_DEBUG_KMS(mode incompatible with compression, 
@@ -477,6 +471,13 @@ void intel_update_fbc(struct drm_device *dev)
if (in_dbg_master())
goto out_disable;
 
+   if (intel_fb-obj-base.size  i915_gem_stolen_setup_compression(dev)) {
+   DRM_DEBUG_KMS(framebuffer too large, disabling 
+ compression\n);
+   dev_priv-no_fbc_reason = FBC_STOLEN_TOO_SMALL;
+   goto out_disable;
+   }
+
/* If the scanout has not changed, don't modify the FBC settings.
 * Note that we make the fundamental assumption that the fb-obj
 * cannot be unpinned (and have its GTT offset and fence revoked)
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 16/24] drm/i915: Support readback of stolen objects upon error

2012-08-30 Thread Chris Wilson
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_irq.c |8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index f437398..7324850 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -894,6 +894,14 @@ i915_error_object_create(struct drm_i915_private *dev_priv,
 reloc_offset);
memcpy_fromio(d, s, PAGE_SIZE);
io_mapping_unmap_atomic(s);
+   } else if (src-stolen) {
+   unsigned long offset;
+
+   offset = dev_priv-mm.stolen_base;
+   offset += src-stolen-start;
+   offset += i  PAGE_SHIFT;
+
+   memcpy_fromio(d, (void *)offset, PAGE_SIZE);
} else {
struct page *page;
void *s;
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 18/24] drm/i915: Handle stolen objects for pread

2012-08-30 Thread Chris Wilson
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_gem.c |  175 ++-
 1 file changed, 116 insertions(+), 59 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index bcf0708..d1c1b60 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -324,24 +324,21 @@ __copy_from_user_swizzled(char *gpu_vaddr, int gpu_offset,
  * Flushes invalid cachelines before reading the target if
  * needs_clflush is set. */
 static int
-shmem_pread_fast(struct page *page, int shmem_page_offset, int page_length,
+shmem_pread_fast(char *vaddr, int shmem_page_offset, int page_length,
 char __user *user_data,
 bool page_do_bit17_swizzling, bool needs_clflush)
 {
-   char *vaddr;
int ret;
 
if (unlikely(page_do_bit17_swizzling))
return -EINVAL;
 
-   vaddr = kmap_atomic(page);
if (needs_clflush)
drm_clflush_virt_range(vaddr + shmem_page_offset,
   page_length);
ret = __copy_to_user_inatomic(user_data,
  vaddr + shmem_page_offset,
  page_length);
-   kunmap_atomic(vaddr);
 
return ret ? -EFAULT : 0;
 }
@@ -371,14 +368,12 @@ shmem_clflush_swizzled_range(char *addr, unsigned long 
length,
 /* Only difference to the fast-path function is that this can handle bit17
  * and uses non-atomic copy and kmap functions. */
 static int
-shmem_pread_slow(struct page *page, int shmem_page_offset, int page_length,
+shmem_pread_slow(char *vaddr, int shmem_page_offset, int page_length,
 char __user *user_data,
 bool page_do_bit17_swizzling, bool needs_clflush)
 {
-   char *vaddr;
int ret;
 
-   vaddr = kmap(page);
if (needs_clflush)
shmem_clflush_swizzled_range(vaddr + shmem_page_offset,
 page_length,
@@ -392,7 +387,6 @@ shmem_pread_slow(struct page *page, int shmem_page_offset, 
int page_length,
ret = __copy_to_user(user_data,
 vaddr + shmem_page_offset,
 page_length);
-   kunmap(page);
 
return ret ? - EFAULT : 0;
 }
@@ -403,6 +397,7 @@ i915_gem_shmem_pread(struct drm_device *dev,
 struct drm_i915_gem_pread *args,
 struct drm_file *file)
 {
+   struct drm_i915_private *dev_priv = dev-dev_private;
char __user *user_data;
ssize_t remain;
loff_t offset;
@@ -433,76 +428,138 @@ i915_gem_shmem_pread(struct drm_device *dev,
}
}
 
-   ret = i915_gem_object_get_pages(obj);
-   if (ret)
-   return ret;
+   offset = args-offset;
 
-   i915_gem_object_pin_pages(obj);
+   if (obj-stolen) {
+   char *vaddr;
 
-   offset = args-offset;
+   vaddr = (char *)dev_priv-mm.stolen_base;
+   vaddr += obj-stolen-start + offset;
 
-   for_each_sg(obj-pages-sgl, sg, obj-pages-nents, i) {
-   struct page *page;
+   shmem_page_offset = offset_in_page(offset);
+   while (remain  0) {
+   /* Operation in this page
+*
+* shmem_page_offset = offset within page in shmem file
+* page_length = bytes to copy for this page
+*/
+   page_length = remain;
+   if ((shmem_page_offset + page_length)  PAGE_SIZE)
+   page_length = PAGE_SIZE - shmem_page_offset;
 
-   if (i  offset  PAGE_SHIFT)
-   continue;
+   page_do_bit17_swizzling = obj_do_bit17_swizzling 
+   ((uintptr_t)vaddr  (1  17)) != 0;
 
-   if (remain = 0)
-   break;
+   ret = shmem_pread_fast(vaddr, shmem_page_offset, 
page_length,
+  user_data, 
page_do_bit17_swizzling,
+  needs_clflush);
+   if (ret == 0)
+   goto next_stolen;
 
-   /* Operation in this page
-*
-* shmem_page_offset = offset within page in shmem file
-* page_length = bytes to copy for this page
-*/
-   shmem_page_offset = offset_in_page(offset);
-   page_length = remain;
-   if ((shmem_page_offset + page_length)  PAGE_SIZE)
-   page_length = PAGE_SIZE - shmem_page_offset;
+   hit_slowpath = 1;
+   mutex_unlock(dev-struct_mutex);
 
-   page = sg_page(sg);
-  

[Intel-gfx] [PATCH 21/24] drm/i915: Allocate ringbuffers from stolen memory

2012-08-30 Thread Chris Wilson
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/intel_ringbuffer.c |6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c 
b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 984a0c5..577a96a 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1096,7 +1096,11 @@ static int intel_init_ring_buffer(struct drm_device *dev,
return ret;
}
 
-   obj = i915_gem_alloc_object(dev, ring-size);
+   obj = NULL;
+   if (!HAS_LLC(dev))
+   obj = i915_gem_object_create_stolen(dev, ring-size);
+   if (obj == NULL)
+   obj = i915_gem_alloc_object(dev, ring-size);
if (obj == NULL) {
DRM_ERROR(Failed to allocate ringbuffer\n);
ret = -ENOMEM;
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 23/24] drm/i915: Use a slab for object allocation

2012-08-30 Thread Chris Wilson
The primary purpose of this was to debug some use-after-free memory
corruption that was causing an OOPS inside drm/i915. As it turned out
the corruption was being caused elsewhere and i915.ko as a major user of
many objects was being hit hardest.

Indeed as we do frequent the generic kmalloc caches, dedicating one to
ourselves (or at least naming one for us depending upon the core) aids
debugging our own slab usage.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_dma.c|3 +++
 drivers/gpu/drm/i915/i915_drv.h|4 
 drivers/gpu/drm/i915/i915_gem.c|   28 +++-
 drivers/gpu/drm/i915/i915_gem_dmabuf.c |5 ++---
 drivers/gpu/drm/i915/i915_gem_stolen.c |4 ++--
 5 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 2c09900..f2e3439 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1760,6 +1760,9 @@ int i915_driver_unload(struct drm_device *dev)
 
destroy_workqueue(dev_priv-wq);
 
+   if (dev_priv-slab)
+   kmem_cache_destroy(dev_priv-slab);
+
pci_dev_put(dev_priv-bridge_dev);
kfree(dev-dev_private);
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f19a4f2..ec8c0fc 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -391,6 +391,7 @@ struct intel_gmbus {
 
 typedef struct drm_i915_private {
struct drm_device *dev;
+   struct kmem_cache *slab;
 
const struct intel_device_info *info;
 
@@ -1316,12 +1317,15 @@ int i915_gem_get_aperture_ioctl(struct drm_device *dev, 
void *data,
 int i915_gem_wait_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
 void i915_gem_load(struct drm_device *dev);
+void *i915_gem_object_alloc(struct drm_device *dev);
+void i915_gem_object_free(struct drm_i915_gem_object *obj);
 int i915_gem_init_object(struct drm_gem_object *obj);
 void i915_gem_object_init(struct drm_i915_gem_object *obj,
 const struct drm_i915_gem_object_ops *ops);
 struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
  size_t size);
 void i915_gem_free_object(struct drm_gem_object *obj);
+
 int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj,
 uint32_t alignment,
 bool map_and_fenceable,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index f420272..70f6c53 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -193,6 +193,18 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void 
*data,
return 0;
 }
 
+void *i915_gem_object_alloc(struct drm_device *dev)
+{
+   struct drm_i915_private *dev_priv = dev-dev_private;
+   return kmem_cache_alloc(dev_priv-slab, GFP_KERNEL | __GFP_ZERO);
+}
+
+void i915_gem_object_free(struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *dev_priv = obj-base.dev-dev_private;
+   kmem_cache_free(dev_priv-slab, obj);
+}
+
 static int
 i915_gem_create(struct drm_file *file,
struct drm_device *dev,
@@ -216,7 +228,7 @@ i915_gem_create(struct drm_file *file,
if (ret) {
drm_gem_object_release(obj-base);
i915_gem_info_remove_obj(dev-dev_private, obj-base.size);
-   kfree(obj);
+   i915_gem_object_free(obj);
return ret;
}
 
@@ -3770,12 +3782,12 @@ struct drm_i915_gem_object 
*i915_gem_alloc_object(struct drm_device *dev,
struct address_space *mapping;
u32 mask;
 
-   obj = kzalloc(sizeof(*obj), GFP_KERNEL);
+   obj = i915_gem_object_alloc(dev);
if (obj == NULL)
return NULL;
 
if (drm_gem_object_init(dev, obj-base, size) != 0) {
-   kfree(obj);
+   i915_gem_object_free(obj);
return NULL;
}
 
@@ -3858,7 +3870,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
i915_gem_info_remove_obj(dev_priv, obj-base.size);
 
kfree(obj-bit_17);
-   kfree(obj);
+   i915_gem_object_free(obj);
 }
 
 int
@@ -4236,8 +4248,14 @@ init_ring_lists(struct intel_ring_buffer *ring)
 void
 i915_gem_load(struct drm_device *dev)
 {
-   int i;
drm_i915_private_t *dev_priv = dev-dev_private;
+   int i;
+
+   dev_priv-slab =
+   kmem_cache_create(i915_gem_object,
+ sizeof(struct drm_i915_gem_object), 0,
+ SLAB_HWCACHE_ALIGN,
+ NULL);
 
INIT_LIST_HEAD(dev_priv-mm.active_list);
INIT_LIST_HEAD(dev_priv-mm.inactive_list);
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c 

[Intel-gfx] [PATCH 24/24] drm/i915: Introduce mapping of user pages into video memory (userptr) ioctl

2012-08-30 Thread Chris Wilson
By exporting the ability to map user address and inserting PTEs
representing their backing pages into the GTT, we can exploit UMA in order
to utilize normal application data as a texture source or even as a
render target (depending upon the capabilities of the chipset). This has
a number of uses, with zero-copy downloads to the GPU and efficient
readback making the intermixed streaming of CPU and GPU operations
fairly efficient. This ability has many widespread implications from
faster rendering of partial software fallbacks (xterm!) to faster
pipelining of texture data (such as pixel buffer objects in GL).

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/Makefile   |1 +
 drivers/gpu/drm/i915/i915_dma.c |1 +
 drivers/gpu/drm/i915/i915_drv.h |   14 +++
 drivers/gpu/drm/i915/i915_gem.c |6 +-
 drivers/gpu/drm/i915/i915_gem_userptr.c |  209 +++
 include/drm/i915_drm.h  |   15 +++
 6 files changed, 243 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/i915_gem_userptr.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 0f2c549..754d665 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -14,6 +14,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \
  i915_gem_gtt.o \
  i915_gem_stolen.o \
  i915_gem_tiling.o \
+ i915_gem_userptr.o \
  i915_sysfs.o \
  i915_trace_points.o \
  intel_display.o \
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index f2e3439..837fc63 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1883,6 +1883,7 @@ struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE, 
i915_gem_context_create_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, 
i915_gem_context_destroy_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_UNLOCKED),
+   DRM_IOCTL_DEF_DRV(I915_GEM_USERPTR, i915_gem_userptr_ioctl, 
DRM_MASTER|DRM_UNLOCKED),
 };
 
 int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ec8c0fc..1467cc1 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1050,6 +1050,18 @@ struct drm_i915_gem_object {
atomic_t pending_flip;
 };
 
+struct i915_gem_userptr_object {
+   struct drm_i915_gem_object gem;
+   uintptr_t user_ptr;
+   size_t user_size;
+   int read_only;
+};
+
+union drm_i915_gem_objects {
+   struct drm_i915_gem_object base;
+   struct i915_gem_userptr_object userptr;
+};
+
 inline static bool i915_gem_object_is_prime(struct drm_i915_gem_object *obj)
 {
return obj-base.import_attach != NULL;
@@ -1308,6 +1320,8 @@ int i915_gem_entervt_ioctl(struct drm_device *dev, void 
*data,
   struct drm_file *file_priv);
 int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file_priv);
+int i915_gem_userptr_ioctl(struct drm_device *dev, void *data,
+  struct drm_file *file);
 int i915_gem_set_tiling(struct drm_device *dev, void *data,
struct drm_file *file_priv);
 int i915_gem_get_tiling(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 70f6c53..69972f6 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2556,9 +2556,9 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj)
/* Avoid an unnecessary call to unbind on rebind. */
obj-map_and_fenceable = true;
 
+   obj-gtt_offset -= obj-gtt_space-start;
drm_mm_put_block(obj-gtt_space);
obj-gtt_space = NULL;
-   obj-gtt_offset = 0;
 
return 0;
 }
@@ -3074,7 +3074,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object 
*obj,
list_move_tail(obj-gtt_list, dev_priv-mm.bound_list);
list_add_tail(obj-mm_list, dev_priv-mm.inactive_list);
 
-   obj-gtt_offset = obj-gtt_space-start;
+   obj-gtt_offset += obj-gtt_space-start;
 
fenceable =
obj-gtt_space-size == fence_size 
@@ -4253,7 +4253,7 @@ i915_gem_load(struct drm_device *dev)
 
dev_priv-slab =
kmem_cache_create(i915_gem_object,
- sizeof(struct drm_i915_gem_object), 0,
+ sizeof(union drm_i915_gem_objects), 0,
  SLAB_HWCACHE_ALIGN,
  NULL);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c 
b/drivers/gpu/drm/i915/i915_gem_userptr.c
new file mode 100644
index 000..8604dad
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright 

[Intel-gfx] [PATCH 19/24] drm/i915: Introduce i915_gem_object_create_stolen()

2012-08-30 Thread Chris Wilson
Allow for the creation of GEM objects backed by stolen memory. As these
are not backed by ordinary pages, we create a fake dma mapping and store
the address in the scatterlist rather than obj-pages.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_drv.h|3 +
 drivers/gpu/drm/i915/i915_gem.c|1 +
 drivers/gpu/drm/i915/i915_gem_stolen.c |  122 
 3 files changed, 126 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index cc3cc4f..f19a4f2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1500,6 +1500,9 @@ int i915_gem_evict_everything(struct drm_device *dev);
 int i915_gem_init_stolen(struct drm_device *dev);
 int i915_gem_stolen_setup_compression(struct drm_device *dev);
 void i915_gem_cleanup_stolen(struct drm_device *dev);
+struct drm_i915_gem_object *
+i915_gem_object_create_stolen(struct drm_device *dev, u32 size);
+void i915_gem_object_release_stolen(struct drm_i915_gem_object *obj);
 
 /* i915_gem_tiling.c */
 void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index d1c1b60..f420272 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3847,6 +3847,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
obj-pages_pin_count = 0;
i915_gem_object_put_pages(obj);
i915_gem_object_free_mmap_offset(obj);
+   i915_gem_object_release_stolen(obj);
 
BUG_ON(obj-pages);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c 
b/drivers/gpu/drm/i915/i915_gem_stolen.c
index 17119d7..d91f6eb 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -198,3 +198,125 @@ int i915_gem_init_stolen(struct drm_device *dev)
 
return 0;
 }
+
+static struct sg_table *
+i915_pages_create_for_stolen(struct drm_device *dev,
+u32 offset, u32 size)
+{
+   struct drm_i915_private *dev_priv = dev-dev_private;
+   struct sg_table *st;
+   struct scatterlist *sg;
+
+   /* We hide that we have no struct page backing our stolen object
+* by wrapping the contiguous physical allocation with a fake
+* dma mapping in a single scatterlist.
+*/
+
+   st = kmalloc(sizeof(*st), GFP_KERNEL);
+   if (st == NULL)
+   return NULL;
+
+   if (!sg_alloc_table(st, 1, GFP_KERNEL)) {
+   kfree(st);
+   return NULL;
+   }
+
+   sg = st-sgl;
+   sg-offset = offset;
+   sg-length = size;
+
+   sg_dma_address(sg) = dev_priv-mm.stolen_base + offset;
+   sg_dma_len(sg) = size;
+
+   return st;
+}
+
+static int i915_gem_object_get_pages_stolen(struct drm_i915_gem_object *obj)
+{
+   BUG();
+   return -EINVAL;
+}
+
+static void i915_gem_object_put_pages_stolen(struct drm_i915_gem_object *obj)
+{
+   /* Should only be called during free */
+   sg_free_table(obj-pages);
+   kfree(obj-pages);
+}
+
+static const struct drm_i915_gem_object_ops i915_gem_object_stolen_ops = {
+   .get_pages = i915_gem_object_get_pages_stolen,
+   .put_pages = i915_gem_object_put_pages_stolen,
+};
+
+struct drm_i915_gem_object *
+_i915_gem_object_create_stolen(struct drm_device *dev,
+  struct drm_mm_node *stolen)
+{
+   struct drm_i915_gem_object *obj;
+
+   obj = kzalloc(sizeof(*obj), GFP_KERNEL);
+   if (obj == NULL)
+   return NULL;
+
+   if (drm_gem_private_object_init(dev, obj-base, stolen-size))
+   goto cleanup;
+
+   i915_gem_object_init(obj, i915_gem_object_stolen_ops);
+
+   obj-pages = i915_pages_create_for_stolen(dev,
+ stolen-start, stolen-size);
+   if (obj-pages == NULL)
+   goto cleanup;
+
+   obj-has_dma_mapping = true;
+   obj-pages_pin_count = 1;
+   obj-stolen = stolen;
+
+   obj-base.write_domain = I915_GEM_DOMAIN_GTT;
+   obj-base.read_domains = I915_GEM_DOMAIN_GTT;
+   obj-cache_level = I915_CACHE_NONE;
+
+   return obj;
+
+cleanup:
+   kfree(obj);
+   return NULL;
+}
+
+struct drm_i915_gem_object *
+i915_gem_object_create_stolen(struct drm_device *dev, u32 size)
+{
+   struct drm_i915_private *dev_priv = dev-dev_private;
+   struct drm_i915_gem_object *obj;
+   struct drm_mm_node *stolen;
+
+   if (dev_priv-mm.stolen_base == 0)
+   return 0;
+
+   DRM_DEBUG_KMS(creating stolen object: size=%x\n, size);
+   if (size == 0)
+   return NULL;
+
+   stolen = drm_mm_search_free(dev_priv-mm.stolen, size, 4096, 0);
+   if (stolen)
+   stolen = drm_mm_get_block(stolen, size, 4096);
+   if (stolen == NULL)
+   return NULL;
+
+   obj = _i915_gem_object_create_stolen(dev, 

[Intel-gfx] [PATCH 17/24] drm/i915: Handle stolen objects in pwrite

2012-08-30 Thread Chris Wilson
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_gem.c |  159 ---
 1 file changed, 100 insertions(+), 59 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b0b81aa..bcf0708 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -664,19 +664,17 @@ out:
  * needs_clflush_before is set and flushes out any written cachelines after
  * writing if needs_clflush is set. */
 static int
-shmem_pwrite_fast(struct page *page, int shmem_page_offset, int page_length,
+shmem_pwrite_fast(char *vaddr, int shmem_page_offset, int page_length,
  char __user *user_data,
  bool page_do_bit17_swizzling,
  bool needs_clflush_before,
  bool needs_clflush_after)
 {
-   char *vaddr;
int ret;
 
if (unlikely(page_do_bit17_swizzling))
return -EINVAL;
 
-   vaddr = kmap_atomic(page);
if (needs_clflush_before)
drm_clflush_virt_range(vaddr + shmem_page_offset,
   page_length);
@@ -686,7 +684,6 @@ shmem_pwrite_fast(struct page *page, int shmem_page_offset, 
int page_length,
if (needs_clflush_after)
drm_clflush_virt_range(vaddr + shmem_page_offset,
   page_length);
-   kunmap_atomic(vaddr);
 
return ret ? -EFAULT : 0;
 }
@@ -694,16 +691,14 @@ shmem_pwrite_fast(struct page *page, int 
shmem_page_offset, int page_length,
 /* Only difference to the fast-path function is that this can handle bit17
  * and uses non-atomic copy and kmap functions. */
 static int
-shmem_pwrite_slow(struct page *page, int shmem_page_offset, int page_length,
+shmem_pwrite_slow(char *vaddr, int shmem_page_offset, int page_length,
  char __user *user_data,
  bool page_do_bit17_swizzling,
  bool needs_clflush_before,
  bool needs_clflush_after)
 {
-   char *vaddr;
int ret;
 
-   vaddr = kmap(page);
if (unlikely(needs_clflush_before || page_do_bit17_swizzling))
shmem_clflush_swizzled_range(vaddr + shmem_page_offset,
 page_length,
@@ -720,7 +715,6 @@ shmem_pwrite_slow(struct page *page, int shmem_page_offset, 
int page_length,
shmem_clflush_swizzled_range(vaddr + shmem_page_offset,
 page_length,
 page_do_bit17_swizzling);
-   kunmap(page);
 
return ret ? -EFAULT : 0;
 }
@@ -731,10 +725,11 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
  struct drm_i915_gem_pwrite *args,
  struct drm_file *file)
 {
+   struct drm_i915_private *dev_priv = dev-dev_private;
ssize_t remain;
loff_t offset;
char __user *user_data;
-   int shmem_page_offset, page_length, ret = 0;
+   int page_length, ret = 0;
int obj_do_bit17_swizzling, page_do_bit17_swizzling;
int hit_slowpath = 0;
int needs_clflush_after = 0;
@@ -770,74 +765,120 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
if (ret)
return ret;
 
-   i915_gem_object_pin_pages(obj);
-
offset = args-offset;
obj-dirty = 1;
 
-   for_each_sg(obj-pages-sgl, sg, obj-pages-nents, i) {
-   struct page *page;
-   int partial_cacheline_write;
+   if (obj-stolen) {
+   char *vaddr;
 
-   if (i  offset  PAGE_SHIFT)
-   continue;
+   vaddr = (char *)dev_priv-mm.stolen_base;
+   vaddr += obj-stolen-start + offset;
 
-   if (remain = 0)
-   break;
+   offset = offset_in_page(offset);
+   while (remain  0) {
+   int partial_cacheline_write;
 
-   /* Operation in this page
-*
-* shmem_page_offset = offset within page in shmem file
-* page_length = bytes to copy for this page
-*/
-   shmem_page_offset = offset_in_page(offset);
+   page_length = remain;
+   if ((offset + page_length)  PAGE_SIZE)
+   page_length = PAGE_SIZE - offset;
 
-   page_length = remain;
-   if ((shmem_page_offset + page_length)  PAGE_SIZE)
-   page_length = PAGE_SIZE - shmem_page_offset;
+   /* If we don't overwrite a cacheline completely we need 
to be
+* careful to have up-to-date data by first clflushing. 
Don't
+* overcomplicate things and flush the entire patch. */
+   partial_cacheline_write = needs_clflush_before 
+   

[Intel-gfx] [PATCH 22/24] drm/i915: Allocate overlay registers from stolen memory

2012-08-30 Thread Chris Wilson
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/intel_overlay.c |6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_overlay.c 
b/drivers/gpu/drm/i915/intel_overlay.c
index afd0f30..2fa20a4 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -1368,8 +1368,10 @@ void intel_setup_overlay(struct drm_device *dev)
 
overlay-dev = dev;
 
-   reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
-   if (!reg_bo)
+   reg_bo = i915_gem_object_create_stolen(dev, PAGE_SIZE);
+   if (reg_bo == NULL)
+   reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
+   if (reg_bo == NULL)
goto out_free;
overlay-reg_bo = reg_bo;
 
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 15/24] drm/i915: Differentiate between prime and stolen objects

2012-08-30 Thread Chris Wilson
Stolen objects also share the property that they have no backing shmemfs
filp, but they can be used with pwrite/pread/gtt-mapping.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_drv.h |5 +
 drivers/gpu/drm/i915/i915_gem.c |4 ++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 637babb..cc3cc4f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1049,6 +1049,11 @@ struct drm_i915_gem_object {
atomic_t pending_flip;
 };
 
+inline static bool i915_gem_object_is_prime(struct drm_i915_gem_object *obj)
+{
+   return obj-base.import_attach != NULL;
+}
+
 #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base)
 
 /**
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index c922aef..b0b81aa 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -553,7 +553,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
/* prime objects have no backing filp to GEM pread/pwrite
 * pages from.
 */
-   if (!obj-base.filp) {
+   if (i915_gem_object_is_prime(obj)) {
ret = -EINVAL;
goto out;
}
@@ -902,7 +902,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
/* prime objects have no backing filp to GEM pread/pwrite
 * pages from.
 */
-   if (!obj-base.filp) {
+   if (i915_gem_object_is_prime(obj)) {
ret = -EINVAL;
goto out;
}
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 11/24] drm: Introduce an iterator over holes in the drm_mm range manager

2012-08-30 Thread Chris Wilson
This will be used i915 in forthcoming patches in order to measure the
largest contiguous chunk of memory available for enabling chipset
features.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
Cc: Dave Airlie airl...@redhat.com
---
 drivers/gpu/drm/drm_mm.c |   55 +++---
 include/drm/drm_mm.h |   26 ++
 2 files changed, 44 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 5db8c20..c3d11ec 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -102,20 +102,6 @@ int drm_mm_pre_get(struct drm_mm *mm)
 }
 EXPORT_SYMBOL(drm_mm_pre_get);
 
-static inline unsigned long drm_mm_hole_node_start(struct drm_mm_node 
*hole_node)
-{
-   return hole_node-start + hole_node-size;
-}
-
-static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node)
-{
-   struct drm_mm_node *next_node =
-   list_entry(hole_node-node_list.next, struct drm_mm_node,
-  node_list);
-
-   return next_node-start;
-}
-
 static void drm_mm_insert_helper(struct drm_mm_node *hole_node,
 struct drm_mm_node *node,
 unsigned long size, unsigned alignment,
@@ -127,7 +113,7 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
unsigned long adj_start = hole_start;
unsigned long adj_end = hole_end;
 
-   BUG_ON(!hole_node-hole_follows || node-allocated);
+   BUG_ON(node-allocated);
 
if (mm-color_adjust)
mm-color_adjust(hole_node, color, adj_start, adj_end);
@@ -168,15 +154,10 @@ struct drm_mm_node *drm_mm_create_block(struct drm_mm *mm,
 {
struct drm_mm_node *hole, *node;
unsigned long end = start + size;
+   unsigned long hole_start;
+   unsigned long hole_end;
 
-   list_for_each_entry(hole, mm-hole_stack, hole_stack) {
-   unsigned long hole_start;
-   unsigned long hole_end;
-
-   BUG_ON(!hole-hole_follows);
-   hole_start = drm_mm_hole_node_start(hole);
-   hole_end = drm_mm_hole_node_end(hole);
-
+   drm_mm_for_each_hole(hole, mm, hole_start, hole_end) {
if (hole_start  start || hole_end  end)
continue;
 
@@ -361,8 +342,10 @@ void drm_mm_remove_node(struct drm_mm_node *node)
== drm_mm_hole_node_end(node));
list_del(node-hole_stack);
} else
-   BUG_ON(drm_mm_hole_node_start(node)
-   != drm_mm_hole_node_end(node));
+   BUG_ON(node-start + node-size !=
+  list_entry(node-node_list.next,
+ struct drm_mm_node, node_list)-start);
+
 
if (!prev_node-hole_follows) {
prev_node-hole_follows = 1;
@@ -420,6 +403,8 @@ struct drm_mm_node *drm_mm_search_free_generic(const struct 
drm_mm *mm,
 {
struct drm_mm_node *entry;
struct drm_mm_node *best;
+   unsigned long adj_start;
+   unsigned long adj_end;
unsigned long best_size;
 
BUG_ON(mm-scanned_blocks);
@@ -427,17 +412,13 @@ struct drm_mm_node *drm_mm_search_free_generic(const 
struct drm_mm *mm,
best = NULL;
best_size = ~0UL;
 
-   list_for_each_entry(entry, mm-hole_stack, hole_stack) {
-   unsigned long adj_start = drm_mm_hole_node_start(entry);
-   unsigned long adj_end = drm_mm_hole_node_end(entry);
-
+   drm_mm_for_each_hole(entry, mm, adj_start, adj_end) {
if (mm-color_adjust) {
mm-color_adjust(entry, color, adj_start, adj_end);
if (adj_end = adj_start)
continue;
}
 
-   BUG_ON(!entry-hole_follows);
if (!check_free_hole(adj_start, adj_end, size, alignment))
continue;
 
@@ -464,6 +445,8 @@ struct drm_mm_node 
*drm_mm_search_free_in_range_generic(const struct drm_mm *mm,
 {
struct drm_mm_node *entry;
struct drm_mm_node *best;
+   unsigned long adj_start;
+   unsigned long adj_end;
unsigned long best_size;
 
BUG_ON(mm-scanned_blocks);
@@ -471,13 +454,11 @@ struct drm_mm_node 
*drm_mm_search_free_in_range_generic(const struct drm_mm *mm,
best = NULL;
best_size = ~0UL;
 
-   list_for_each_entry(entry, mm-hole_stack, hole_stack) {
-   unsigned long adj_start = drm_mm_hole_node_start(entry)  start 
?
-   start : drm_mm_hole_node_start(entry);
-   unsigned long adj_end = drm_mm_hole_node_end(entry)  end ?
-   end : drm_mm_hole_node_end(entry);
-
-   BUG_ON(!entry-hole_follows);
+   drm_mm_for_each_hole(entry, mm, adj_start, adj_end) {
+   if (adj_start  start)
+ 

[Intel-gfx] [PATCH 07/24] drm: Introduce drm_mm_create_block()

2012-08-30 Thread Chris Wilson
To be used later by i915 to preallocate exact blocks of space from the
range manager.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
Cc: Dave Airlie airl...@redhat.com
---
 drivers/gpu/drm/drm_mm.c |   49 ++
 include/drm/drm_mm.h |4 
 2 files changed, 53 insertions(+)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 9bb82f7..5db8c20 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -161,6 +161,55 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
}
 }
 
+struct drm_mm_node *drm_mm_create_block(struct drm_mm *mm,
+   unsigned long start,
+   unsigned long size,
+   bool atomic)
+{
+   struct drm_mm_node *hole, *node;
+   unsigned long end = start + size;
+
+   list_for_each_entry(hole, mm-hole_stack, hole_stack) {
+   unsigned long hole_start;
+   unsigned long hole_end;
+
+   BUG_ON(!hole-hole_follows);
+   hole_start = drm_mm_hole_node_start(hole);
+   hole_end = drm_mm_hole_node_end(hole);
+
+   if (hole_start  start || hole_end  end)
+   continue;
+
+   node = drm_mm_kmalloc(mm, atomic);
+   if (unlikely(node == NULL))
+   return NULL;
+
+   node-start = start;
+   node-size = size;
+   node-mm = mm;
+   node-allocated = 1;
+
+   INIT_LIST_HEAD(node-hole_stack);
+   list_add(node-node_list, hole-node_list);
+
+   if (start == hole_start) {
+   hole-hole_follows = 0;
+   list_del_init(hole-hole_stack);
+   }
+
+   node-hole_follows = 0;
+   if (end != hole_end) {
+   list_add(node-hole_stack, mm-hole_stack);
+   node-hole_follows = 1;
+   }
+
+   return node;
+   }
+
+   return NULL;
+}
+EXPORT_SYMBOL(drm_mm_create_block);
+
 struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node,
 unsigned long size,
 unsigned alignment,
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index 06d7f79..4020f96 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -102,6 +102,10 @@ static inline bool drm_mm_initialized(struct drm_mm *mm)
 /*
  * Basic range manager support (drm_mm.c)
  */
+extern struct drm_mm_node *drm_mm_create_block(struct drm_mm *mm,
+  unsigned long start,
+  unsigned long size,
+  bool atomic);
 extern struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node,
unsigned long size,
unsigned alignment,
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 12/24] drm/i915: Delay allocation of stolen space for FBC

2012-08-30 Thread Chris Wilson
As we may wish to wrap regions preallocated by the BIOS, we need to do
that before carving out contiguous chunks of stolen space for FBC.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_drv.h|1 +
 drivers/gpu/drm/i915/i915_gem_stolen.c |  110 
 drivers/gpu/drm/i915/intel_display.c   |3 +
 3 files changed, 59 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 533361e..31d3a9f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1491,6 +1491,7 @@ int i915_gem_evict_everything(struct drm_device *dev);
 
 /* i915_gem_stolen.c */
 int i915_gem_init_stolen(struct drm_device *dev);
+int i915_gem_stolen_setup_compression(struct drm_device *dev);
 void i915_gem_cleanup_stolen(struct drm_device *dev);
 
 /* i915_gem_tiling.c */
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c 
b/drivers/gpu/drm/i915/i915_gem_stolen.c
index a528e4a..17119d7 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -86,21 +86,13 @@ static unsigned long i915_stolen_to_physical(struct 
drm_device *dev)
return base;
 }
 
-static void i915_warn_stolen(struct drm_device *dev)
-{
-   DRM_INFO(not enough stolen space for compressed buffer, disabling\n);
-   DRM_INFO(hint: you may be able to increase stolen memory size in the 
BIOS to avoid this\n);
-}
-
-static void i915_setup_compression(struct drm_device *dev, int size)
+static int i915_setup_compression(struct drm_device *dev, int size)
 {
struct drm_i915_private *dev_priv = dev-dev_private;
struct drm_mm_node *compressed_fb, *uninitialized_var(compressed_llb);
-   unsigned long cfb_base;
-   unsigned long ll_base = 0;
 
-   /* Just in case the BIOS is doing something questionable. */
-   intel_disable_fbc(dev);
+   DRM_DEBUG_KMS(reserving %d bytes of contiguous stolen space for FBC\n,
+ size);
 
compressed_fb = drm_mm_search_free(dev_priv-mm.stolen, size, 4096, 0);
if (compressed_fb)
@@ -108,11 +100,11 @@ static void i915_setup_compression(struct drm_device 
*dev, int size)
if (!compressed_fb)
goto err;
 
-   cfb_base = dev_priv-mm.stolen_base + compressed_fb-start;
-   if (!cfb_base)
-   goto err_fb;
-
-   if (!(IS_GM45(dev) || HAS_PCH_SPLIT(dev))) {
+   if (HAS_PCH_SPLIT(dev))
+   I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb-start);
+   else if (IS_GM45(dev)) {
+   I915_WRITE(DPFC_CB_BASE, compressed_fb-start);
+   } else {
compressed_llb = drm_mm_search_free(dev_priv-mm.stolen,
4096, 4096, 0);
if (compressed_llb)
@@ -121,56 +113,78 @@ static void i915_setup_compression(struct drm_device 
*dev, int size)
if (!compressed_llb)
goto err_fb;
 
-   ll_base = dev_priv-mm.stolen_base + compressed_llb-start;
-   if (!ll_base)
-   goto err_llb;
-   }
+   dev_priv-compressed_llb = compressed_llb;
 
-   dev_priv-cfb_size = size;
+   I915_WRITE(FBC_CFB_BASE,
+  dev_priv-mm.stolen_base + compressed_fb-start);
+   I915_WRITE(FBC_LL_BASE,
+  dev_priv-mm.stolen_base + compressed_llb-start);
+   }
 
dev_priv-compressed_fb = compressed_fb;
-   if (HAS_PCH_SPLIT(dev))
-   I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb-start);
-   else if (IS_GM45(dev)) {
-   I915_WRITE(DPFC_CB_BASE, compressed_fb-start);
-   } else {
-   I915_WRITE(FBC_CFB_BASE, cfb_base);
-   I915_WRITE(FBC_LL_BASE, ll_base);
-   dev_priv-compressed_llb = compressed_llb;
-   }
+   dev_priv-cfb_size = size;
 
-   DRM_DEBUG_KMS(FBC base 0x%08lx, ll base 0x%08lx, size %dM\n,
- (long)cfb_base, (long)ll_base, size  20);
-   return;
+   return size;
 
-err_llb:
-   drm_mm_put_block(compressed_llb);
 err_fb:
drm_mm_put_block(compressed_fb);
 err:
dev_priv-no_fbc_reason = FBC_STOLEN_TOO_SMALL;
-   i915_warn_stolen(dev);
+   DRM_INFO(not enough stolen space for compressed buffer (need %d 
bytes), disabling\n, size);
+   DRM_INFO(hint: you may be able to increase stolen memory size in the 
BIOS to avoid this\n);
+   return 0;
+}
+
+int i915_gem_stolen_setup_compression(struct drm_device *dev)
+{
+   struct drm_i915_private *dev_priv = dev-dev_private;
+   struct drm_mm_node *node;
+   unsigned long hole_start, hole_end, size;
+
+   if (dev_priv-mm.stolen_base == 0)
+   return 0;
+
+   if (dev_priv-cfb_size)
+   return dev_priv-cfb_size;
+
+   /* Try to set up FBC with a reasonable compressed buffer 

[Intel-gfx] [PATCH 14/24] drm/i915: Allow objects to be created with no backing pages, but stolen space

2012-08-30 Thread Chris Wilson
In order to accommodate objects that are not backed by struct pages, but
instead point into a contiguous region of stolen space, we need to make
various changes to avoid dereferencing obj-pages or obj-base.filp.

First introduce a marker for the stolen object, that specifies its
offset into the stolen region and implies that it has no backing pages.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_debugfs.c |2 ++
 drivers/gpu/drm/i915/i915_drv.h |2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 3d886af..e419e77 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -125,6 +125,8 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object 
*obj)
if (obj-gtt_space != NULL)
seq_printf(m,  (gtt offset: %08x, size: %08x),
   obj-gtt_offset, (unsigned int)obj-gtt_space-size);
+   if (obj-stolen)
+   seq_printf(m,  (stolen: %08lx), obj-stolen-start);
if (obj-pin_mappable || obj-fault_mappable) {
char s[3], *t = s;
if (obj-pin_mappable)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 31d3a9f..637babb 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -913,6 +913,8 @@ struct drm_i915_gem_object {
 
/** Current space allocated to this object in the GTT, if any. */
struct drm_mm_node *gtt_space;
+   /** Stolen memory for this object, instead of being backed by shmem. */
+   struct drm_mm_node *stolen;
struct list_head gtt_list;
 
/** This object's place on the active/inactive lists */
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 09/24] drm/i915: Fix location of stolen memory register for SandyBridge+

2012-08-30 Thread Chris Wilson
A few of the earlier registers where enlarged and so the Base Data of
Stolem Memory Register (BDSM) was pushed to 0xb0.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_gem_stolen.c |9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c 
b/drivers/gpu/drm/i915/i915_gem_stolen.c
index a01ff74..a528e4a 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -63,7 +63,11 @@ static unsigned long i915_stolen_to_physical(struct 
drm_device *dev)
 * its value of TOLUD.
 */
base = 0;
-   if (INTEL_INFO(dev)-gen  3 || IS_G33(dev)) {
+   if (INTEL_INFO(dev)-gen = 6) {
+   /* Read Base Data of Stolen Memory Register (BDSM) directly */
+   pci_read_config_dword(pdev, 0xB0, base);
+   base = ~4095; /* lower bits used for locking register */
+   } else if (INTEL_INFO(dev)-gen  3 || IS_G33(dev)) {
/* Read Graphics Base of Stolen Memory directly */
pci_read_config_dword(pdev, 0xA4, base);
 #if 0
@@ -172,6 +176,9 @@ int i915_gem_init_stolen(struct drm_device *dev)
if (dev_priv-mm.stolen_base == 0)
return 0;
 
+   DRM_DEBUG_KMS(found %d bytes of stolen memory at %08lx\n,
+ dev_priv-mm.gtt-stolen_size, dev_priv-mm.stolen_base);
+
/* Basic memrange allocator for stolen space */
drm_mm_init(dev_priv-mm.stolen, 0, prealloc_size);
 
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 08/24] drm/i915: Fix detection of stolen base for gen2

2012-08-30 Thread Chris Wilson
It was not until the G33 refresh, that a PCI config register was
introduced that explicitly said where the stolen memory was. Prior to
865G there was not even a register that said where the end of usable
low memory was and where the stolen memory began (or ended depending
upon chipset). Before then, one has to look at the BIOS memory maps to
find the Top of Memory. Alas that is not exported by arch/x86 and so we
have to resort to disabling stolen memory on gen2 for the time being.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_drv.h|1 +
 drivers/gpu/drm/i915/i915_gem_stolen.c |   69 ++--
 2 files changed, 31 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a86f50d..f614c26 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -697,6 +697,7 @@ typedef struct drm_i915_private {
unsigned long gtt_start;
unsigned long gtt_mappable_end;
unsigned long gtt_end;
+   unsigned long stolen_base; /* limited to low memory (32-bit) */
 
struct io_mapping *gtt_mapping;
phys_addr_t gtt_base_addr;
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c 
b/drivers/gpu/drm/i915/i915_gem_stolen.c
index ada2e90..a01ff74 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -43,56 +43,43 @@
  * for is a boon.
  */
 
-#define PTE_ADDRESS_MASK   0xf000
-#define PTE_ADDRESS_MASK_HIGH  0x00f0 /* i915+ */
-#define PTE_MAPPING_TYPE_UNCACHED  (0  1)
-#define PTE_MAPPING_TYPE_DCACHE(1  1) /* i830 only */
-#define PTE_MAPPING_TYPE_CACHED(3  1)
-#define PTE_MAPPING_TYPE_MASK  (3  1)
-#define PTE_VALID  (1  0)
-
-/**
- * i915_stolen_to_phys - take an offset into stolen memory and turn it into
- *   a physical one
- * @dev: drm device
- * @offset: address to translate
- *
- * Some chip functions require allocations from stolen space and need the
- * physical address of the memory in question.
- */
-static unsigned long i915_stolen_to_phys(struct drm_device *dev, u32 offset)
+static unsigned long i915_stolen_to_physical(struct drm_device *dev)
 {
struct drm_i915_private *dev_priv = dev-dev_private;
struct pci_dev *pdev = dev_priv-bridge_dev;
u32 base;
 
-#if 0
/* On the machines I have tested the Graphics Base of Stolen Memory
-* is unreliable, so compute the base by subtracting the stolen memory
-* from the Top of Low Usable DRAM which is where the BIOS places
-* the graphics stolen memory.
+* is unreliable, so on those compute the base by subtracting the
+* stolen memory from the Top of Low Usable DRAM which is where the
+* BIOS places the graphics stolen memory.
+*
+* On gen2, the layout is slightly different with the Graphics Segment
+* immediately following Top of Memory (or Top of Usable DRAM). Note
+* it appears that TOUD is only reported by 865g, so we just use the
+* top of memory as determined by the e820 probe.
+*
+* XXX gen2 requires an unavailable symbol and 945gm fails with
+* its value of TOLUD.
 */
+   base = 0;
if (INTEL_INFO(dev)-gen  3 || IS_G33(dev)) {
-   /* top 32bits are reserved = 0 */
+   /* Read Graphics Base of Stolen Memory directly */
pci_read_config_dword(pdev, 0xA4, base);
-   } else {
-   /* XXX presume 8xx is the same as i915 */
-   pci_bus_read_config_dword(pdev-bus, 2, 0x5C, base);
-   }
-#else
-   if (INTEL_INFO(dev)-gen  3 || IS_G33(dev)) {
-   u16 val;
-   pci_read_config_word(pdev, 0xb0, val);
-   base = val  4  20;
-   } else {
+#if 0
+   } else if (IS_GEN3(dev)) {
u8 val;
+   /* Stolen is immediately below Top of Low Usable DRAM */
pci_read_config_byte(pdev, 0x9c, val);
base = val  3  27;
-   }
-   base -= dev_priv-mm.gtt-stolen_size;
+   base -= dev_priv-mm.gtt-stolen_size;
+   } else {
+   /* Stolen is immediately above Top of Memory */
+   base = max_low_pfn_mapped  PAGE_SHIFT;
 #endif
+   }
 
-   return base + offset;
+   return base;
 }
 
 static void i915_warn_stolen(struct drm_device *dev)
@@ -117,7 +104,7 @@ static void i915_setup_compression(struct drm_device *dev, 
int size)
if (!compressed_fb)
goto err;
 
-   cfb_base = i915_stolen_to_phys(dev, compressed_fb-start);
+   cfb_base = dev_priv-mm.stolen_base + compressed_fb-start;
if (!cfb_base)
goto err_fb;
 
@@ -130,7 +117,7 @@ static void i915_setup_compression(struct 

[Intel-gfx] [PATCH 04/24] drm/i915: Pin backing pages for pread

2012-08-30 Thread Chris Wilson
By using the recently introduced pinning of pages, we can safely drop
the mutex in the knowledge that the pages are not going to disappear
beneath us, and so we can simplify the code for iterating over the pages.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_gem.c |   36 +---
 1 file changed, 13 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index f1a0fc7..ebe4fa1 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -343,7 +343,7 @@ shmem_pread_fast(struct page *page, int shmem_page_offset, 
int page_length,
  page_length);
kunmap_atomic(vaddr);
 
-   return ret;
+   return ret ? -EFAULT : 0;
 }
 
 static void
@@ -394,7 +394,7 @@ shmem_pread_slow(struct page *page, int shmem_page_offset, 
int page_length,
 page_length);
kunmap(page);
 
-   return ret;
+   return ret ? - EFAULT : 0;
 }
 
 static int
@@ -403,7 +403,6 @@ i915_gem_shmem_pread(struct drm_device *dev,
 struct drm_i915_gem_pread *args,
 struct drm_file *file)
 {
-   struct address_space *mapping = 
obj-base.filp-f_path.dentry-d_inode-i_mapping;
char __user *user_data;
ssize_t remain;
loff_t offset;
@@ -412,7 +411,6 @@ i915_gem_shmem_pread(struct drm_device *dev,
int hit_slowpath = 0;
int prefaulted = 0;
int needs_clflush = 0;
-   int release_page;
 
user_data = (char __user *) (uintptr_t) args-data_ptr;
remain = args-size;
@@ -433,6 +431,12 @@ i915_gem_shmem_pread(struct drm_device *dev,
}
}
 
+   ret = i915_gem_object_get_pages(obj);
+   if (ret)
+   return ret;
+
+   i915_gem_object_pin_pages(obj);
+
offset = args-offset;
 
while (remain  0) {
@@ -448,18 +452,7 @@ i915_gem_shmem_pread(struct drm_device *dev,
if ((shmem_page_offset + page_length)  PAGE_SIZE)
page_length = PAGE_SIZE - shmem_page_offset;
 
-   if (obj-pages) {
-   page = obj-pages[offset  PAGE_SHIFT];
-   release_page = 0;
-   } else {
-   page = shmem_read_mapping_page(mapping, offset  
PAGE_SHIFT);
-   if (IS_ERR(page)) {
-   ret = PTR_ERR(page);
-   goto out;
-   }
-   release_page = 1;
-   }
-
+   page = obj-pages[offset  PAGE_SHIFT];
page_do_bit17_swizzling = obj_do_bit17_swizzling 
(page_to_phys(page)  (1  17)) != 0;
 
@@ -470,7 +463,6 @@ i915_gem_shmem_pread(struct drm_device *dev,
goto next_page;
 
hit_slowpath = 1;
-   page_cache_get(page);
mutex_unlock(dev-struct_mutex);
 
if (!prefaulted) {
@@ -488,16 +480,12 @@ i915_gem_shmem_pread(struct drm_device *dev,
   needs_clflush);
 
mutex_lock(dev-struct_mutex);
-   page_cache_release(page);
+
 next_page:
mark_page_accessed(page);
-   if (release_page)
-   page_cache_release(page);
 
-   if (ret) {
-   ret = -EFAULT;
+   if (ret)
goto out;
-   }
 
remain -= page_length;
user_data += page_length;
@@ -505,6 +493,8 @@ next_page:
}
 
 out:
+   i915_gem_object_unpin_pages(obj);
+
if (hit_slowpath) {
/* Fixup: Kill any reinstated backing storage pages */
if (obj-madv == __I915_MADV_PURGED)
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 02/24] drm/i915: Pin backing pages whilst exporting through a dmabuf vmap

2012-08-30 Thread Chris Wilson
We need to refcount our pages in order to prevent reaping them at
inopportune times, such as when they currently vmapped or exported to
another driver. However, we also wish to keep the lazy deallocation of
our pages so we need to take a pin/unpinned approach rather than a
simple refcount.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_drv.h|   12 
 drivers/gpu/drm/i915/i915_gem.c|   11 +--
 drivers/gpu/drm/i915/i915_gem_dmabuf.c |8 ++--
 3 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f180874..0747472 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -994,6 +994,7 @@ struct drm_i915_gem_object {
unsigned int has_global_gtt_mapping:1;
 
struct page **pages;
+   int pages_pin_count;
 
/**
 * DMAR support
@@ -1327,6 +1328,17 @@ void i915_gem_release_mmap(struct drm_i915_gem_object 
*obj);
 void i915_gem_lastclose(struct drm_device *dev);
 
 int __must_check i915_gem_object_get_pages(struct drm_i915_gem_object *obj);
+static inline void i915_gem_object_pin_pages(struct drm_i915_gem_object *obj)
+{
+   BUG_ON(obj-pages == NULL);
+   obj-pages_pin_count++;
+}
+static inline void i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj)
+{
+   BUG_ON(obj-pages_pin_count == 0);
+   obj-pages_pin_count--;
+}
+
 int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
 int i915_gem_object_sync(struct drm_i915_gem_object *obj,
 struct intel_ring_buffer *to);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 5e2e6bf..98c434c7 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1699,6 +1699,9 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
 
BUG_ON(obj-gtt_space);
 
+   if (obj-pages_pin_count)
+   return -EBUSY;
+
ops-put_pages(obj);
 
list_del(obj-gtt_list);
@@ -1830,6 +1833,8 @@ i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
if (obj-sg_table || obj-pages)
return 0;
 
+   BUG_ON(obj-pages_pin_count);
+
ret = ops-get_pages(obj);
if (ret)
return ret;
@@ -3736,6 +3741,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
dev_priv-mm.interruptible = was_interruptible;
}
 
+   obj-pages_pin_count = 0;
i915_gem_object_put_pages(obj);
i915_gem_object_free_mmap_offset(obj);
 
@@ -4395,9 +4401,10 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, 
struct shrink_control *sc)
 
cnt = 0;
list_for_each_entry(obj, dev_priv-mm.unbound_list, gtt_list)
-   cnt += obj-base.size  PAGE_SHIFT;
+   if (obj-pages_pin_count == 0)
+   cnt += obj-base.size  PAGE_SHIFT;
list_for_each_entry(obj, dev_priv-mm.bound_list, gtt_list)
-   if (obj-pin_count == 0)
+   if (obj-pin_count == 0  obj-pages_pin_count == 0)
cnt += obj-base.size  PAGE_SHIFT;
 
mutex_unlock(dev-struct_mutex);
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
index e4f1141..eca4726 100644
--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
@@ -50,6 +50,8 @@ static struct sg_table *i915_gem_map_dma_buf(struct 
dma_buf_attachment *attachme
/* link the pages into an SG then map the sg */
sg = drm_prime_pages_to_sg(obj-pages, npages);
nents = dma_map_sg(attachment-dev, sg-sgl, sg-nents, dir);
+   i915_gem_object_pin_pages(obj);
+
 out:
mutex_unlock(dev-struct_mutex);
return sg;
@@ -102,6 +104,7 @@ static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)
}
 
obj-vmapping_count = 1;
+   i915_gem_object_pin_pages(obj);
 out_unlock:
mutex_unlock(dev-struct_mutex);
return obj-dma_buf_vmapping;
@@ -117,10 +120,11 @@ static void i915_gem_dmabuf_vunmap(struct dma_buf 
*dma_buf, void *vaddr)
if (ret)
return;
 
-   --obj-vmapping_count;
-   if (obj-vmapping_count == 0) {
+   if (--obj-vmapping_count == 0) {
vunmap(obj-dma_buf_vmapping);
obj-dma_buf_vmapping = NULL;
+
+   i915_gem_object_unpin_pages(obj);
}
mutex_unlock(dev-struct_mutex);
 }
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 03/24] drm/i915: Pin backing pages for pwrite

2012-08-30 Thread Chris Wilson
By using the recently introduced pinning of pages, we can safely drop
the mutex in the knowledge that the pages are not going to disappear
beneath us, and so we can simplify the code for iterating over the pages.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_gem.c |   37 +
 1 file changed, 13 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 98c434c7..f1a0fc7 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -690,7 +690,7 @@ shmem_pwrite_fast(struct page *page, int shmem_page_offset, 
int page_length,
   page_length);
kunmap_atomic(vaddr);
 
-   return ret;
+   return ret ? -EFAULT : 0;
 }
 
 /* Only difference to the fast-path function is that this can handle bit17
@@ -724,7 +724,7 @@ shmem_pwrite_slow(struct page *page, int shmem_page_offset, 
int page_length,
 page_do_bit17_swizzling);
kunmap(page);
 
-   return ret;
+   return ret ? -EFAULT : 0;
 }
 
 static int
@@ -733,7 +733,6 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
  struct drm_i915_gem_pwrite *args,
  struct drm_file *file)
 {
-   struct address_space *mapping = 
obj-base.filp-f_path.dentry-d_inode-i_mapping;
ssize_t remain;
loff_t offset;
char __user *user_data;
@@ -742,7 +741,6 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
int hit_slowpath = 0;
int needs_clflush_after = 0;
int needs_clflush_before = 0;
-   int release_page;
 
user_data = (char __user *) (uintptr_t) args-data_ptr;
remain = args-size;
@@ -768,6 +766,12 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
 obj-cache_level == I915_CACHE_NONE)
needs_clflush_before = 1;
 
+   ret = i915_gem_object_get_pages(obj);
+   if (ret)
+   return ret;
+
+   i915_gem_object_pin_pages(obj);
+
offset = args-offset;
obj-dirty = 1;
 
@@ -793,18 +797,7 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
((shmem_page_offset | page_length)
 (boot_cpu_data.x86_clflush_size - 1));
 
-   if (obj-pages) {
-   page = obj-pages[offset  PAGE_SHIFT];
-   release_page = 0;
-   } else {
-   page = shmem_read_mapping_page(mapping, offset  
PAGE_SHIFT);
-   if (IS_ERR(page)) {
-   ret = PTR_ERR(page);
-   goto out;
-   }
-   release_page = 1;
-   }
-
+   page = obj-pages[offset  PAGE_SHIFT];
page_do_bit17_swizzling = obj_do_bit17_swizzling 
(page_to_phys(page)  (1  17)) != 0;
 
@@ -816,26 +809,20 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
goto next_page;
 
hit_slowpath = 1;
-   page_cache_get(page);
mutex_unlock(dev-struct_mutex);
-
ret = shmem_pwrite_slow(page, shmem_page_offset, page_length,
user_data, page_do_bit17_swizzling,
partial_cacheline_write,
needs_clflush_after);
 
mutex_lock(dev-struct_mutex);
-   page_cache_release(page);
+
 next_page:
set_page_dirty(page);
mark_page_accessed(page);
-   if (release_page)
-   page_cache_release(page);
 
-   if (ret) {
-   ret = -EFAULT;
+   if (ret)
goto out;
-   }
 
remain -= page_length;
user_data += page_length;
@@ -843,6 +830,8 @@ next_page:
}
 
 out:
+   i915_gem_object_unpin_pages(obj);
+
if (hit_slowpath) {
/* Fixup: Kill any reinstated backing storage pages */
if (obj-madv == __I915_MADV_PURGED)
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 01/24] drm/i915: Introduce drm_i915_gem_object_ops

2012-08-30 Thread Chris Wilson
In order to specialise functions depending upon the type of object, we
can attach vfuncs to each object via a new -ops pointer.

For instance, this will be used in future patches to only bind pages from
a dma-buf for the duration that the object is used by the GPU - and so
prevent them from pinning those pages for the entire of the object.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_drv.h|   12 +-
 drivers/gpu/drm/i915/i915_gem.c|   71 +---
 drivers/gpu/drm/i915/i915_gem_dmabuf.c |4 +-
 3 files changed, 60 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f16ab5e..f180874 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -898,9 +898,16 @@ enum i915_cache_level {
I915_CACHE_LLC_MLC, /* gen6+, in docs at least! */
 };
 
+struct drm_i915_gem_object_ops {
+   int (*get_pages)(struct drm_i915_gem_object *);
+   void (*put_pages)(struct drm_i915_gem_object *);
+};
+
 struct drm_i915_gem_object {
struct drm_gem_object base;
 
+   const struct drm_i915_gem_object_ops *ops;
+
/** Current space allocated to this object in the GTT, if any. */
struct drm_mm_node *gtt_space;
struct list_head gtt_list;
@@ -1305,7 +1312,8 @@ int i915_gem_wait_ioctl(struct drm_device *dev, void 
*data,
struct drm_file *file_priv);
 void i915_gem_load(struct drm_device *dev);
 int i915_gem_init_object(struct drm_gem_object *obj);
-void i915_gem_object_init(struct drm_i915_gem_object *obj);
+void i915_gem_object_init(struct drm_i915_gem_object *obj,
+const struct drm_i915_gem_object_ops *ops);
 struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
  size_t size);
 void i915_gem_free_object(struct drm_gem_object *obj);
@@ -1318,7 +1326,7 @@ int __must_check i915_gem_object_unbind(struct 
drm_i915_gem_object *obj);
 void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
 void i915_gem_lastclose(struct drm_device *dev);
 
-int __must_check i915_gem_object_get_pages_gtt(struct drm_i915_gem_object 
*obj);
+int __must_check i915_gem_object_get_pages(struct drm_i915_gem_object *obj);
 int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
 int i915_gem_object_sync(struct drm_i915_gem_object *obj,
 struct intel_ring_buffer *to);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index ac050e6..5e2e6bf 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1650,18 +1650,12 @@ i915_gem_object_is_purgeable(struct drm_i915_gem_object 
*obj)
return obj-madv == I915_MADV_DONTNEED;
 }
 
-static int
+static void
 i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj)
 {
int page_count = obj-base.size / PAGE_SIZE;
int ret, i;
 
-   BUG_ON(obj-gtt_space);
-
-   if (obj-pages == NULL)
-   return 0;
-
-   BUG_ON(obj-gtt_space);
BUG_ON(obj-madv == __I915_MADV_PURGED);
 
ret = i915_gem_object_set_to_cpu_domain(obj, true);
@@ -1693,9 +1687,21 @@ i915_gem_object_put_pages_gtt(struct drm_i915_gem_object 
*obj)
 
drm_free_large(obj-pages);
obj-pages = NULL;
+}
 
-   list_del(obj-gtt_list);
+static int
+i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
+{
+   const struct drm_i915_gem_object_ops *ops = obj-ops;
+
+   if (obj-sg_table || obj-pages == NULL)
+   return 0;
+
+   BUG_ON(obj-gtt_space);
 
+   ops-put_pages(obj);
+
+   list_del(obj-gtt_list);
if (i915_gem_object_is_purgeable(obj))
i915_gem_object_truncate(obj);
 
@@ -1712,7 +1718,7 @@ i915_gem_purge(struct drm_i915_private *dev_priv, long 
target)
 dev_priv-mm.unbound_list,
 gtt_list) {
if (i915_gem_object_is_purgeable(obj) 
-   i915_gem_object_put_pages_gtt(obj) == 0) {
+   i915_gem_object_put_pages(obj) == 0) {
count += obj-base.size  PAGE_SHIFT;
if (count = target)
return count;
@@ -1724,7 +1730,7 @@ i915_gem_purge(struct drm_i915_private *dev_priv, long 
target)
 mm_list) {
if (i915_gem_object_is_purgeable(obj) 
i915_gem_object_unbind(obj) == 0 
-   i915_gem_object_put_pages_gtt(obj) == 0) {
+   i915_gem_object_put_pages(obj) == 0) {
count += obj-base.size  PAGE_SHIFT;
if (count = target)
return count;
@@ -1742,10 +1748,10 @@ i915_gem_shrink_all(struct drm_i915_private *dev_priv)

[Intel-gfx] [PATCH] intel_reg_dumper: Add a single register decode mode

2012-08-30 Thread Damien Lespiau
From: Damien Lespiau damien.lesp...@intel.com

From time to time, one would like to decode a register value that have
been captured at a certain point in time (and say printed out with a
printk). intel_reg_dumper has all the knowledge to do that and this
patch adds a -r option to use the tool in that mode.

Example usage:

$ ./tools/intel_reg_dumper -r PCH_PP_CONTROL 0xabcd0002
   PCH_PP_CONTROL: 0xabcd0002 (blacklight disabled, power...

Signed-off-by: Damien Lespiau damien.lesp...@intel.com
---
 tools/intel_reg_dumper.c | 102 ---
 1 file changed, 88 insertions(+), 14 deletions(-)

diff --git a/tools/intel_reg_dumper.c b/tools/intel_reg_dumper.c
index b49d967..88d7216 100644
--- a/tools/intel_reg_dumper.c
+++ b/tools/intel_reg_dumper.c
@@ -1911,26 +1911,33 @@ static struct reg_debug i945gm_mi_regs[] = {
DEFINEREG(ECOSKPD),
 };
 
+static void
+_intel_dump_reg(struct reg_debug *reg, uint32_t val)
+{
+   char debug[1024];
+
+   if (reg-debug_output != NULL) {
+   reg-debug_output(debug, sizeof(debug), reg-reg, val);
+   printf(%30.30s: 0x%08x (%s)\n,
+  reg-name,
+  (unsigned int)val, debug);
+   } else {
+   printf(%30.30s: 0x%08x\n, reg-name,
+  (unsigned int)val);
+   }
+}
+
 #define intel_dump_regs(regs) _intel_dump_regs(regs, ARRAY_SIZE(regs))
 
 static void
 _intel_dump_regs(struct reg_debug *regs, int count)
 {
-   char debug[1024];
int i;
 
for (i = 0; i  count; i++) {
uint32_t val = INREG(regs[i].reg);
 
-   if (regs[i].debug_output != NULL) {
-   regs[i].debug_output(debug, sizeof(debug), regs[i].reg, 
val);
-   printf(%30.30s: 0x%08x (%s)\n,
-  regs[i].name,
-  (unsigned int)val, debug);
-   } else {
-   printf(%30.30s: 0x%08x\n, regs[i].name,
-  (unsigned int)val);
-   }
+   _intel_dump_reg(regs[i], val);
}
 }
 
@@ -1964,6 +1971,54 @@ static struct reg_debug gen6_rp_debug_regs[] = {
DEFINEREG(GEN6_PMINTRMSK),
 };
 
+#define DECLARE_REGS(r){ .regs = r, .count = ARRAY_SIZE(r) }
+static struct {
+   struct reg_debug *regs;
+   int count;
+}known_registers[] = {
+   DECLARE_REGS(ironlake_debug_regs),
+   DECLARE_REGS(i945gm_mi_regs),
+   DECLARE_REGS(intel_debug_regs),
+   DECLARE_REGS(gen6_rp_debug_regs),
+   DECLARE_REGS(haswell_debug_regs)
+};
+#undef DECLARE_REGS
+
+static struct reg_debug *
+find_register_by_name(struct reg_debug *regs, int count,
+ const char *name)
+{
+   int i;
+
+   for (i = 0; i  count; i++)
+   if (strcmp(name, regs[i].name) == 0)
+   return regs[i];
+
+   return NULL;
+}
+
+static void
+decode_register(const char *name, uint32_t val)
+{
+   int i;
+   struct reg_debug *reg = NULL;
+
+   for (i = 0; i  ARRAY_SIZE(known_registers); i++) {
+   reg = find_register_by_name(known_registers[i].regs,
+   known_registers[i].count,
+   name);
+   if (reg)
+   break;
+   }
+
+   if (!reg) {
+   fprintf(stderr, Unknown register: %s\n, name);
+   return;
+   }
+
+   _intel_dump_reg(reg, val);
+}
+
 static void
 intel_dump_other_regs(void)
 {
@@ -2171,10 +2226,11 @@ intel_dump_other_regs(void)
 
 static void print_usage(void)
 {
-   printf(Usage: intel_reg_dumper [options] [file]\n
+   printf(Usage: intel_reg_dumper [options] [file|value]\n
   Options:\n
 -d id   when a dump file is used, use 'id' as device id (in 
   hex)\n
+-r name name of the register to decode\n
 -h  prints this help\n);
 }
 
@@ -2182,13 +2238,17 @@ int main(int argc, char** argv)
 {
struct pci_device *pci_dev;
int opt;
-   char *file = NULL;
+   char *reg_name = NULL;
+   char *arg = NULL, *file = NULL;
 
-   while ((opt = getopt(argc, argv, d:h)) != -1) {
+   while ((opt = getopt(argc, argv, d:r:h)) != -1) {
switch (opt) {
case 'd':
devid = strtol(optarg, NULL, 16);
break;
+   case 'r':
+   reg_name = optarg;
+   break;
case 'h':
print_usage();
return 0;
@@ -2198,8 +2258,22 @@ int main(int argc, char** argv)
}
}
if (optind  argc)
-   file = argv[optind];
+   arg = argv[optind];
+
+   if (reg_name  !arg) {
+   fprintf (stderr, -r needs a value to decode\n);

Re: [Intel-gfx] Next iteration of stolen support

2012-08-30 Thread Chris Wilson
You can ignore this complete set, I managed to blow away half the
changes from the last round of review.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] intel_reg_dumper: Add a single register decode mode

2012-08-30 Thread Chris Wilson
On Thu, 30 Aug 2012 17:07:39 +0100, Damien Lespiau damien.lesp...@gmail.com 
wrote:
 From: Damien Lespiau damien.lesp...@intel.com
 
 From time to time, one would like to decode a register value that have
 been captured at a certain point in time (and say printed out with a
 printk). intel_reg_dumper has all the knowledge to do that and this
 patch adds a -r option to use the tool in that mode.
 
 Example usage:
 
 $ ./tools/intel_reg_dumper -r PCH_PP_CONTROL 0xabcd0002
PCH_PP_CONTROL: 0xabcd0002 (blacklight disabled, power...

It's a good idea. Though I would rather have:
  $ intel_reg_decode PCH_PP_CONTROL 0xabcd1234
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 23/24] drm/i915: Use a slab for object allocation

2012-08-30 Thread Ben Widawsky
On Thu, 30 Aug 2012 16:31:18 +0100
Chris Wilson ch...@chris-wilson.co.uk wrote:

 The primary purpose of this was to debug some use-after-free memory
 corruption that was causing an OOPS inside drm/i915. As it turned out
 the corruption was being caused elsewhere and i915.ko as a major user
 of many objects was being hit hardest.
 
 Indeed as we do frequent the generic kmalloc caches, dedicating one to
 ourselves (or at least naming one for us depending upon the core) aids
 debugging our own slab usage.
 
 Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
Acked-by: Ben Widawsky b...@bwidawsk.net

-- 
Ben Widawsky, Intel Open Source Technology Center
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [QA 08/31] Testing report for `drm-intel-testing` (was: Updated -next)

2012-08-30 Thread Sun, Yi
Summary

We finished a new round of kernel testing. During this round 1 new bug, and 
close 1 bugs. Till now, 15 related bugs are still open.

Test Environment
The Linux Kernel, the operating system core itself
Kernel: (drm-intel-testing)ef6113ad0f406db4fbe2bcf3359dd938a6046d75
Some additional commit info:
Merge: cd7988e a51d4ed
Author: Daniel Vetter daniel.vet...@ffwll.chmailto:daniel.vet...@ffwll.ch
Date:   Sun Aug 26 21:12:02 2012 +0200

Hardware

We covered the platform of IvyBridge, SandyBridge, IronLake,G45 and Pineview

Findings

new bugs

Bug 54253 - [SNB]eDP can't work while booting with miniVGA

closed bugs

Bug 52429https://bugs.freedesktop.org/show_bug.cgi?id=52429 - [IVB ]GPU hung 
after S3 with X and glxgears

opened bugs

Bug 36997https://bugs.freedesktop.org/show_bug.cgi?id=36997 - [G45] TV can't 
display after loading drm driver

Bug 41976https://bugs.freedesktop.org/show_bug.cgi?id=41976 - [IVB] screen 
turn to be black while switching between console and x-window with 3-pipe active

Bug 42194https://bugs.freedesktop.org/show_bug.cgi?id=42194 - [IVB/SNB] 
coldplug new monitors for fbcon on lastclose()

Bug 45729https://bugs.freedesktop.org/show_bug.cgi?id=45729 - [bisected 
regression] Incorrect Mode Timing on DP Display, with 3.3-rc (due to interlaced 
CEA modes)

Bug 47034https://bugs.freedesktop.org/show_bug.cgi?id=47034 - [G45] mode set 
failure with testdisplay, low resolution modes fail and display doesn't come 
back

Bug 50069https://bugs.freedesktop.org/show_bug.cgi?id=50069 - 
[IVB]I-G-T/flip_test never finish

Bug 50823https://bugs.freedesktop.org/show_bug.cgi?id=50823 - [IVB]EDP can't 
show all modes correctly

Bug 51055https://bugs.freedesktop.org/show_bug.cgi?id=51055 - 
[IVB]I-G-T/gem_tiled_blits fails while running two or more times

Bug 51490https://bugs.freedesktop.org/show_bug.cgi?id=51490 - [SNB ILK] Some 
modes can't work normally on VGA display

Bug 51491https://bugs.freedesktop.org/show_bug.cgi?id=51491 - [SNB] 1024x768 
86Hz mode can't work normally on HDMI display

Bug 51493https://bugs.freedesktop.org/show_bug.cgi?id=51493 - [ILK] Prefer 
mode(2560x1600) can't light up for the second time with DP external display 
connected

Bug 51499https://bugs.freedesktop.org/show_bug.cgi?id=51499 - [SNB 
regression] Some modes can't work normally on DVI port

Bug 51677https://bugs.freedesktop.org/show_bug.cgi?id=51677 - [IVB] Running 
module_reload after calling function drm_open_any() will cause GPU hang

Bug 51975https://bugs.freedesktop.org/show_bug.cgi?id=51975 - [IVB]can't find 
the HDMI audio device

Bug 54111https://bugs.freedesktop.org/show_bug.cgi?id=54111 - 
[IVB]I-G-T/module_reload fail with *ERROR* Memory manager not clean. Delaying 
takedown


Thanks
   --Yi Sun

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx