[PATCH 1/2] drm: use monotonic time in drm_calc_vbltimestamp_from_scanoutpos

2012-10-25 Thread Mario Kleiner
On 25.10.12 12:28, Imre Deak wrote:
> On Thu, 2012-10-25 at 01:05 +0200, Mario Kleiner wrote:
>> On 23.10.12 20:53, Imre Deak wrote:
>>> For measuring duration we want to avoid that our start/end timestamps
>>> jump, so use monotonic instead of real time for that.
>>>
>>> Signed-off-by: Imre Deak 
>>> ---
>>>drivers/gpu/drm/drm_irq.c |   18 --
>>>1 file changed, 12 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
>>> index 89b830d..7dc203d 100644
>>> --- a/drivers/gpu/drm/drm_irq.c
>>> +++ b/drivers/gpu/drm/drm_irq.c
>>> @@ -576,7 +576,8 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct 
>>> drm_device *dev, int crtc,
>>>   unsigned flags,
>>>   struct drm_crtc *refcrtc)
>>>{
>>> -   struct timeval stime, raw_time;
>>> +   ktime_t stime, etime, mono_time_offset;
>>> +   struct timeval tv_etime;
>>> struct drm_display_mode *mode;
>>> int vbl_status, vtotal, vdisplay;
>>> int vpos, hpos, i;
>>> @@ -625,13 +626,14 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct 
>>> drm_device *dev, int crtc,
>>> preempt_disable();
>>>
>>> /* Get system timestamp before query. */
>>> -   do_gettimeofday();
>>> +   stime = ktime_get();
>>>
>>> /* Get vertical and horizontal scanout pos. vpos, hpos. */
>>> vbl_status = dev->driver->get_scanout_position(dev, crtc, 
>>> , );
>>>
>>> /* Get system timestamp after query. */
>>> -   do_gettimeofday(_time);
>>> +   etime = ktime_get();
>>
>> Here is possibly a tiny race: The wall_to_monotonic offset value could
>> change between the ktime_get() - which uses it internally for wallclock
>> -> monotonic clock conversion, and the ktime_get_monotonic_offset()
>> query below, so the later subtraction of mono_time_offset from etime
>> would not cancel out the addition to etime inside ktime_get() and you
>> wouldn't get correct walltime back. There seem to be multiple sources of
>> change to the value, e.g., do_settimeofday(), do_adjtimex() - the admin
>> or ntp changing the system clock. The internal code, e.g., ktime_get()
>> use a seqlock to protect against this race.
>>
>> There's a function ktime_get_real(void) which directly gives you the
>> wall time you want as ktime_t, but then you'd still need to do the
>> ktime_get() query in the !drm_timestamp_monotonic case to calculate
>> duration_ns below.
>>
>> Same problem in the 2nd patch for get_drm_timestamp(). Otoh, the time
>> window for the race is small and it can only happen in the non-default
>> case of !drm_timestamp_monotonic, so i don't know if it is worth fixing it?
>
> I was also hold up by this for a while, since there is no function to
> get both clocks atomically. But it isn't really a problem if you think
> about it: etime - mono_time_offset is a correct wall time value
> regardless whether mono_time_offset has changed or not after
> ktime_get(). The only difference is whether the user sees the time value
> before or after the adjustment, but you can't guard against that anyway
> (except using monotonic time values always).
>
> It would be a problem if as ktime_get() we would do the reverse and
> calculate the monotonic time from the wall time. There not getting the
> wall time and the wall_to_monotonic offset atomically could result in a
> incorrect monotonic time value, for example one that jumps backwards.
>

Yes, agreed. Your patches should be good to go as they are - i like them :)

-mario


> --Imre
>
>> Other than that:
>>
>> Reviewed-by: mario.kleiner
>>


[drm:i915_hangcheck_hung] *ERROR* Hangcheck timer elapsed... GPU hung

2012-10-25 Thread Justin P. Mattock
On 10/25/2012 01:47 AM, Chris Wilson wrote:
> On Thu, 25 Oct 2012 10:16:08 +0200, Daniel Vetter  wrote:
>> On Thu, Oct 25, 2012 at 7:22 AM, Justin P. Mattock
>>  wrote:
>>>
>>> here is a link to the file..: intel_error_decode
>>> http://www.filefactory.com/file/22bypyjhs4mx
>>
>> I haven't figured out how to access this thing. Can you please file a
>> bug report on bugs.freedesktop.org and attach it there?

Oops.. I filed with the kernel. maybe can just add a cc's
https://bugzilla.kernel.org/show_bug.cgi?id=49571

>
> No worries, it is another ILK hang similar to the ones reported earlier
> - it just seems the ring stops advancing. Hopefully it is a missing w/a
> from http://cgit.freedesktop.org/~danvet/drm/log/?h=ilk-wa-pile
> -Chris
>

well if this means building libdrm etc.. then thats not a problem, more 
time consuming if anything. perhaps an *.rpm that I can test to see?


Justin P. Mattock


[PATCH] drm/i915/dp: allow configuring eDP panel fitting scaling mode

2012-10-25 Thread Daniel Vetter
On Thu, Oct 25, 2012 at 01:57:47PM -0400, Yuly Novikov wrote:
> LVDS allowed changing panel fitting scaling mode, while eDP didn't.
> Copied relevant code from LVDS to eDP.
> This also changes default mode on eDP to ascpect ratio preserving scaling.
> 
> Signed-off-by: Yuly Novikov 

Jani from our team is working on unifying a bunch of things between lvds
and eDP, some of them already merged into drm-intel-next-queued branch.
Jani, can you please take a look?

Thanks, Daniel

> ---
>  drivers/gpu/drm/i915/intel_dp.c  |   33 ++---
>  drivers/gpu/drm/i915/intel_drv.h |1 +
>  2 files changed, 31 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 368ed8e..a65546e 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -685,7 +685,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder,
>  
>   if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
>   intel_fixed_panel_mode(intel_dp->panel_fixed_mode, 
> adjusted_mode);
> - intel_pch_panel_fitting(dev, DRM_MODE_SCALE_FULLSCREEN,
> + intel_pch_panel_fitting(dev, intel_dp->fitting_mode,
>   mode, adjusted_mode);
>   }
>  
> @@ -2358,6 +2358,22 @@ intel_dp_set_property(struct drm_connector *connector,
>   goto done;
>   }
>  
> + if (is_edp(intel_dp) &&
> + property == connector->dev->mode_config.scaling_mode_property) {
> + if (val == DRM_MODE_SCALE_NONE) {
> + DRM_DEBUG_KMS("no scaling not supported\n");
> + return -EINVAL;
> + }
> +
> + if (intel_dp->fitting_mode == val) {
> + /* the eDP scaling property is not changed */
> + return 0;
> + }
> + intel_dp->fitting_mode = val;
> +
> + goto done;
> + }
> +
>   return -EINVAL;
>  
>  done:
> @@ -2469,10 +2485,21 @@ bool intel_dpd_is_edp(struct drm_device *dev)
>  }
>  
>  static void
> -intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector 
> *connector)
> +intel_dp_add_properties(struct drm_device *dev,
> + struct intel_dp *intel_dp,
> + struct drm_connector *connector)
>  {
>   intel_attach_force_audio_property(connector);
>   intel_attach_broadcast_rgb_property(connector);
> +
> + if (is_edp(intel_dp)) {
> + drm_mode_create_scaling_mode_property(dev);
> + drm_connector_attach_property(
> + connector,
> + dev->mode_config.scaling_mode_property,
> + DRM_MODE_SCALE_ASPECT);
> + intel_dp->fitting_mode = DRM_MODE_SCALE_ASPECT;
> + }
>  }
>  
>  void
> @@ -2665,7 +2692,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, 
> enum port port)
>   intel_panel_setup_backlight(dev);
>   }
>  
> - intel_dp_add_properties(intel_dp, connector);
> + intel_dp_add_properties(dev, intel_dp, connector);
>  
>   /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
>* 0xd.  Failure to do so will result in spurious interrupts being
> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
> b/drivers/gpu/drm/i915/intel_drv.h
> index fe71425..da50cd4 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -358,6 +358,7 @@ struct intel_dp {
>   int backlight_on_delay;
>   int backlight_off_delay;
>   struct drm_display_mode *panel_fixed_mode;  /* for eDP */
> + int fitting_mode;  /* for eDP */
>   struct delayed_work panel_vdd_work;
>   bool want_panel_vdd;
>   struct edid *edid; /* cached EDID for eDP */
> -- 
> 1.7.7.3
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch


[PATCH 51/51] drm/i915: Add primary plane disable logic to atomic mode setting code

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Enable/disable the primary plane accordingly when the sprite plane
coverage changes.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_atomic.c |   41 +++
 1 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
b/drivers/gpu/drm/i915/intel_atomic.c
index 238a843..41885fa 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -93,6 +93,7 @@ struct intel_crtc_state {
bool changed;
struct drm_pending_atomic_event *event;
struct intel_flip *flip;
+   bool primary_disabled;

struct {
bool enabled;
@@ -318,6 +319,8 @@ static void *intel_atomic_begin(struct drm_device *dev, 
struct drm_file *file,

s->old.connectors_bitmask = s->connectors_bitmask;
s->old.encoders_bitmask = s->encoders_bitmask;
+
+   s->primary_disabled = intel_crtc->primary_disabled;
}

i = 0;
@@ -1157,6 +1160,9 @@ static int apply_config(struct drm_device *dev,
 intel_crtc->cursor_addr);
}

+   if (!st->primary_disabled)
+   intel_enable_primary(crtc);
+
for (j = 0; j < dev->mode_config.num_plane; j++) {
struct intel_plane_state *pst = >plane[j];
struct drm_plane *plane = pst->plane;
@@ -1170,6 +1176,9 @@ static int apply_config(struct drm_device *dev,
else if (!pst->coords.visible && pst->old.crtc == crtc)
intel_plane->disable_plane(plane);
}
+
+   if (st->primary_disabled)
+   intel_disable_primary(crtc);
}

/* don't restore the old state in end() */
@@ -1207,6 +1216,7 @@ static void restore_state(struct drm_device *dev,
intel_crtc->cursor_width = s->saved_crtcs[i].cursor_width;
intel_crtc->cursor_height = s->saved_crtcs[i].cursor_height;
intel_crtc->cursor_visible = s->saved_crtcs[i].cursor_visible;
+   intel_crtc->primary_disabled = 
s->saved_crtcs[i].primary_disabled;

i++;
}
@@ -1346,6 +1356,28 @@ static int check_crtc(struct intel_crtc_state *s)
return 0;
 }

+static void update_primary_visibility(struct drm_device *dev,
+ struct intel_atomic_state *s,
+ const struct drm_crtc *crtc,
+ const struct drm_plane *plane,
+ const struct intel_plane_coords *coords)
+{
+   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+   bool primary_disabled =
+   coords->visible &&
+   coords->crtc_x == 0 &&
+   coords->crtc_y == 0 &&
+   coords->crtc_w == crtc->mode.hdisplay &&
+   coords->crtc_h == crtc->mode.vdisplay;
+
+   if (primary_disabled != intel_crtc->primary_disabled) {
+   struct intel_crtc_state *st = get_crtc_state(dev, s, crtc);
+   st->fb_dirty = true;
+   st->primary_disabled = primary_disabled;
+   s->dirty = true;
+   }
+}
+
 static int intel_atomic_check(struct drm_device *dev, void *state)
 {
struct intel_atomic_state *s = state;
@@ -1430,6 +1462,12 @@ static int intel_atomic_check(struct drm_device *dev, 
void *state)
ret = intel_check_plane(plane, plane->crtc, plane->fb, 
>coords);
if (ret)
return ret;
+
+   /* FIXME doesn't correctly handle cases where plane moves 
between crtcs */
+   if (plane->crtc)
+   update_primary_visibility(dev, s, plane->crtc, plane, 
>coords);
+   else if (st->old.crtc)
+   update_primary_visibility(dev, s, st->old.crtc, plane, 
>coords);
}

return 0;
@@ -2295,6 +2333,9 @@ static void atomic_pipe_commit(struct drm_device *dev,

intel_flip->crtc = crtc;

+   /* update primary_disabled befoer calc_plane() */
+   intel_crtc->primary_disabled = st->primary_disabled;
+
/* should already be checked so can't fail */
/* FIXME refactor the failing parts? */
dev_priv->display.calc_plane(crtc, crtc->fb, crtc->x, crtc->y);
-- 
1.7.8.6



[PATCH 50/51] drm/i915: Enable/disable primary plane in calc_plane()

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Check the active and primary_disabled flags and set the
DISPLAY_PLANE_ENABLE bit accordingly in calc_plane() hook for the
primary plane.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_display.c |   10 ++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 6a1ed7e..43cff11 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2026,6 +2026,11 @@ static int i9xx_calc_plane(struct drm_crtc *crtc, struct 
drm_framebuffer *fb,
regs->cntr &= ~DISPPLANE_TILED;
}

+   if (intel_crtc->active && !intel_crtc->primary_disabled)
+   regs->cntr |= DISPLAY_PLANE_ENABLE;
+   else
+   regs->cntr &= ~DISPLAY_PLANE_ENABLE;
+
linear_offset = fb->offsets[0] + y * fb->pitches[0] + x * cpp;

if (INTEL_INFO(dev)->gen >= 4) {
@@ -2133,6 +2138,11 @@ static int ironlake_calc_plane(struct drm_crtc *crtc,
/* must disable */
regs->cntr |= DISPPLANE_TRICKLE_FEED_DISABLE;

+   if (intel_crtc->active && !intel_crtc->primary_disabled)
+   regs->cntr |= DISPLAY_PLANE_ENABLE;
+   else
+   regs->cntr &= ~DISPLAY_PLANE_ENABLE;
+
linear_offset = fb->offsets[0] + y * fb->pitches[0] + x * 
(fb->bits_per_pixel / 8);
intel_crtc->dspaddr_offset =
gen4_compute_dspaddr_offset_xtiled(, ,
-- 
1.7.8.6



[PATCH 49/51] drm/i915: Respect primary_disabled in crtc_enable()

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Check primary_disabled state before enabling the primary plane in
crtc_enable() hooks.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_display.c |6 --
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 756cf94..6a1ed7e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3311,7 +3311,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
intel_crtc_load_lut(crtc);

intel_enable_pipe(dev_priv, pipe, is_pch_port);
-   intel_enable_plane(dev_priv, plane, pipe);
+   if (!intel_crtc->primary_disabled)
+   intel_enable_plane(dev_priv, plane, pipe);

if (is_pch_port)
ironlake_pch_enable(crtc);
@@ -3463,7 +3464,8 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)

intel_enable_pll(dev_priv, pipe);
intel_enable_pipe(dev_priv, pipe, false);
-   intel_enable_plane(dev_priv, plane, pipe);
+   if (!intel_crtc->primary_disabled)
+   intel_enable_plane(dev_priv, plane, pipe);

intel_crtc_load_lut(crtc);
intel_update_fbc(dev);
-- 
1.7.8.6



[PATCH 48/51] drm/i915: Unstatic intel_enable_primary() and intel_disable_primary()

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

intel_enable_primary() and intel_disable_primary() are needed in the
atomic mode setting code.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_drv.h|3 +++
 drivers/gpu/drm/i915/intel_sprite.c |4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 4784c44..b9b96d3 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -637,4 +637,7 @@ extern void intel_atomic_fini(struct drm_device *dev);
 extern void intel_atomic_free_events(struct drm_device *dev, struct drm_file 
*file);
 extern void intel_atomic_handle_vblank(struct drm_device *dev, int pipe);

+extern void intel_enable_primary(struct drm_crtc *crtc);
+extern void intel_disable_primary(struct drm_crtc *crtc);
+
 #endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
b/drivers/gpu/drm/i915/intel_sprite.c
index 06d62e70..88fdd0d 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -574,7 +574,7 @@ void intel_calc_sprite(struct drm_plane *plane,
ilk_calc_plane(plane, fb, coords);
 }

-static void
+void
 intel_enable_primary(struct drm_crtc *crtc)
 {
struct drm_device *dev = crtc->dev;
@@ -593,7 +593,7 @@ intel_enable_primary(struct drm_crtc *crtc)
dev_priv->display.commit_plane(crtc);
 }

-static void
+void
 intel_disable_primary(struct drm_crtc *crtc)
 {
struct drm_device *dev = crtc->dev;
-- 
1.7.8.6



[PATCH 47/51] drm/i915: Add atomic page flip support

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Add support for the DRM_MODE_ATOMIC_NONBLOCK flag.

The drm_flip helper provides the necessary logic to track the
progress of the flips. drm_flip is driven by a few extra calls
from the interrupt handling and crtc_disable code paths.

Since the hardware doesn't provide inter-plane synchronization, some
extra software magic is required to avoid flips for multiple planes
ending up on the wrong sides of the vblank leading edge.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/i915_dma.c  |3 +
 drivers/gpu/drm/i915/i915_drv.h  |4 +
 drivers/gpu/drm/i915/i915_irq.c  |   16 +-
 drivers/gpu/drm/i915/intel_atomic.c  |  622 +-
 drivers/gpu/drm/i915/intel_display.c |2 +
 drivers/gpu/drm/i915/intel_drv.h |7 +
 6 files changed, 637 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index acc4317..33999f1 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1794,6 +1794,8 @@ int i915_driver_open(struct drm_device *dev, struct 
drm_file *file)

idr_init(_priv->context_idr);

+   INIT_LIST_HEAD(_priv->pending_flips);
+
return 0;
 }

@@ -1834,6 +1836,7 @@ void i915_driver_preclose(struct drm_device * dev, struct 
drm_file *file_priv)
 {
i915_gem_context_close(dev, file_priv);
i915_gem_release(dev, file_priv);
+   intel_atomic_free_events(dev, file_priv);
 }

 void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 302b6e6..51b36c1 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -882,6 +883,8 @@ typedef struct drm_i915_private {
struct work_struct parity_error_work;
bool hw_contexts_disabled;
uint32_t hw_context_size;
+
+   struct drm_flip_driver flip_driver;
 } drm_i915_private_t;

 /* Iterate over initialised rings */
@@ -1100,6 +1103,7 @@ struct drm_i915_file_private {
struct list_head request_list;
} mm;
struct idr context_idr;
+   struct list_head pending_flips;
 };

 #define INTEL_INFO(dev)(((struct drm_i915_private *) 
(dev)->dev_private)->info)
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 32e1bda..ee22e97 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -563,8 +563,10 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS)
spin_unlock_irqrestore(_priv->irq_lock, irqflags);

for_each_pipe(pipe) {
-   if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
+   if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS) {
drm_handle_vblank(dev, pipe);
+   intel_atomic_handle_vblank(dev, pipe);
+   }

if (pipe_stats[pipe] & PLANE_FLIPDONE_INT_STATUS_VLV) {
intel_prepare_page_flip(dev, pipe);
@@ -697,8 +699,10 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
intel_opregion_gse_intr(dev);

for (i = 0; i < 3; i++) {
-   if (de_iir & (DE_PIPEA_VBLANK_IVB << (5 * i)))
+   if (de_iir & (DE_PIPEA_VBLANK_IVB << (5 * i))) {
drm_handle_vblank(dev, i);
+   intel_atomic_handle_vblank(dev, i);
+   }
if (de_iir & (DE_PLANEA_FLIP_DONE_IVB << (5 * i))) {
intel_prepare_page_flip(dev, i);
intel_finish_page_flip_plane(dev, i);
@@ -784,11 +788,15 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
if (de_iir & DE_GSE)
intel_opregion_gse_intr(dev);

-   if (de_iir & DE_PIPEA_VBLANK)
+   if (de_iir & DE_PIPEA_VBLANK) {
drm_handle_vblank(dev, 0);
+   intel_atomic_handle_vblank(dev, 0);
+   }

-   if (de_iir & DE_PIPEB_VBLANK)
+   if (de_iir & DE_PIPEB_VBLANK) {
drm_handle_vblank(dev, 1);
+   intel_atomic_handle_vblank(dev, 1);
+   }

if (de_iir & DE_PLANEA_FLIP_DONE) {
intel_prepare_page_flip(dev, 0);
diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
b/drivers/gpu/drm/i915/intel_atomic.c
index 3adb140..238a843 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -26,6 +26,7 @@

 #include 
 #include 
+#include 

 #include "intel_drv.h"

@@ -47,6 +48,20 @@ static struct drm_property *prop_cursor_y;
 static struct drm_property *prop_cursor_w;
 static struct drm_property *prop_cursor_h;


[PATCH 46/51] drm/i915: Add support for atomic modesetting completion events

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Send completion events when the atomic modesetting operations has
finished succesfully.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_atomic.c |  195 ++-
 1 files changed, 192 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
b/drivers/gpu/drm/i915/intel_atomic.c
index 4899f8c..3adb140 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -53,6 +53,7 @@ struct intel_plane_state {
bool dirty;
bool pinned;
bool changed;
+   struct drm_pending_atomic_event *event;

struct {
struct drm_crtc *crtc;
@@ -74,6 +75,7 @@ struct intel_crtc_state {
unsigned long connectors_bitmask;
unsigned long encoders_bitmask;
bool changed;
+   struct drm_pending_atomic_event *event;

struct {
bool enabled;
@@ -922,6 +924,111 @@ int intel_commit_plane_nopin(struct drm_plane *plane,
 struct drm_framebuffer *fb,
 const struct intel_plane_coords *coords);

+static struct drm_pending_atomic_event *alloc_event(struct drm_device *dev,
+   struct drm_file *file_priv,
+   uint64_t user_data)
+{
+   struct drm_pending_atomic_event *e;
+   unsigned long flags;
+
+   spin_lock_irqsave(>event_lock, flags);
+
+   if (file_priv->event_space < sizeof e->event) {
+   spin_unlock_irqrestore(>event_lock, flags);
+   return ERR_PTR(-ENOSPC);
+   }
+
+   file_priv->event_space -= sizeof e->event;
+   spin_unlock_irqrestore(>event_lock, flags);
+
+   e = kzalloc(sizeof *e, GFP_KERNEL);
+   if (!e) {
+   spin_lock_irqsave(>event_lock, flags);
+   file_priv->event_space += sizeof e->event;
+   spin_unlock_irqrestore(>event_lock, flags);
+
+   return ERR_PTR(-ENOMEM);
+   }
+
+   e->event.base.type = DRM_EVENT_ATOMIC_COMPLETE;
+   e->event.base.length = sizeof e->event;
+   e->event.user_data = user_data;
+   e->base.event = >event.base;
+   e->base.file_priv = file_priv;
+   e->base.destroy = (void (*) (struct drm_pending_event *)) kfree;
+
+   return e;
+}
+
+static void free_event(struct drm_pending_atomic_event *e)
+{
+   e->base.file_priv->event_space += sizeof e->event;
+   kfree(e);
+}
+
+static void queue_event(struct drm_device *dev, struct drm_crtc *crtc,
+   struct drm_pending_atomic_event *e)
+{
+   struct timeval tvbl;
+
+   if (crtc) {
+   int pipe = to_intel_crtc(crtc)->pipe;
+
+   /* FIXME this is wrong for flips that are completed not at 
vblank */
+   e->event.sequence = drm_vblank_count_and_time(dev, pipe, );
+   e->event.tv_sec = tvbl.tv_sec;
+   e->event.tv_usec = tvbl.tv_usec;
+   } else {
+   e->event.sequence = 0;
+   e->event.tv_sec = 0;
+   e->event.tv_usec = 0;
+   }
+
+   list_add_tail(>base.link, >base.file_priv->event_list);
+   wake_up_interruptible(>base.file_priv->event_wait);
+}
+
+static void queue_remaining_events(struct drm_device *dev, struct 
intel_atomic_state *s)
+{
+   int i;
+
+   for (i = 0; i < dev->mode_config.num_crtc; i++) {
+   struct intel_crtc_state *st = >crtc[i];
+
+   if (st->event) {
+   if (st->old.fb)
+   st->event->event.old_fb_id = 
st->old.fb->base.id;
+
+   spin_lock_irq(>event_lock);
+   queue_event(dev, st->crtc, st->event);
+   spin_unlock_irq(>event_lock);
+
+   st->event = NULL;
+   }
+   }
+
+   for (i = 0; i < dev->mode_config.num_plane; i++) {
+   struct intel_plane_state *st = >plane[i];
+   struct drm_crtc *crtc;
+
+   if (!st->event)
+   continue;
+
+   crtc = st->plane->crtc;
+   if (!crtc)
+   crtc = st->old.crtc;
+
+   if (st->old.fb)
+   st->event->event.old_fb_id = st->old.fb->base.id;
+
+   spin_lock_irq(>event_lock);
+   queue_event(dev, crtc, st->event);
+   spin_unlock_irq(>event_lock);
+
+   st->event = NULL;
+   }
+}
+
 static void swap_old_new(struct drm_device *dev,
 struct intel_atomic_state *s)
 {
@@ -1426,6 +1533,73 @@ static void update_crtc(struct drm_device *dev,
}
 }

+static int alloc_flip_data(struct drm_device *dev, struct intel_atomic_state 
*s)
+{
+   int i;
+
+   for (i = 0; i < dev->mode_config.num_crtc; i++) {
+   struct intel_crtc_state *st = 

[PATCH 45/51] drm/i915: Implement atomic modesetting

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Implement the mandatory hooks for the atomic modeset ioctl.

The code first makes a backup of the current state, then proceeds to
modify the state as properties are modified. After all the properties
have been handled the new state is checked, and if everything checks
out, the new state is commited to hardware. Finally we clean up any
temporary storage.

In theory everything is checked before the hardware state is clobbered,
so there should be no need for rollback. But as the current modesetting
code can still return errors from some of of the operation, the rollback
code is included.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/Makefile|1 +
 drivers/gpu/drm/i915/intel_atomic.c  | 1625 ++
 drivers/gpu/drm/i915/intel_display.c |5 +
 drivers/gpu/drm/i915/intel_drv.h |3 +
 include/drm/drm_crtc.h   |2 +
 5 files changed, 1636 insertions(+), 0 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_atomic.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 0f2c549..cca14e4 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -16,6 +16,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \
  i915_gem_tiling.o \
  i915_sysfs.o \
  i915_trace_points.o \
+ intel_atomic.o \
  intel_display.o \
  intel_crt.o \
  intel_lvds.o \
diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
b/drivers/gpu/drm/i915/intel_atomic.c
new file mode 100644
index 000..4899f8c
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -0,0 +1,1625 @@
+/*
+ * Copyright (C) 2011-2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Ville Syrj?l? 
+ */
+
+#include 
+#include 
+
+#include "intel_drv.h"
+
+static struct drm_property *prop_src_x;
+static struct drm_property *prop_src_y;
+static struct drm_property *prop_src_w;
+static struct drm_property *prop_src_h;
+static struct drm_property *prop_crtc_x;
+static struct drm_property *prop_crtc_y;
+static struct drm_property *prop_crtc_w;
+static struct drm_property *prop_crtc_h;
+static struct drm_property *prop_fb_id;
+static struct drm_property *prop_crtc_id;
+static struct drm_property *prop_mode;
+static struct drm_property *prop_connector_ids;
+static struct drm_property *prop_cursor_id;
+static struct drm_property *prop_cursor_x;
+static struct drm_property *prop_cursor_y;
+static struct drm_property *prop_cursor_w;
+static struct drm_property *prop_cursor_h;
+
+struct intel_plane_state {
+   struct drm_plane *plane;
+   struct intel_plane_coords coords;
+   bool dirty;
+   bool pinned;
+   bool changed;
+
+   struct {
+   struct drm_crtc *crtc;
+   struct drm_framebuffer *fb;
+   uint32_t src_x, src_y, src_w, src_h;
+   int32_t crtc_x, crtc_y;
+   uint32_t crtc_w, crtc_h;
+   } old;
+};
+
+struct intel_crtc_state {
+   struct drm_crtc *crtc;
+   bool mode_dirty;
+   bool fb_dirty;
+   bool cursor_dirty;
+   bool active_dirty;
+   bool pinned;
+   bool cursor_pinned;
+   unsigned long connectors_bitmask;
+   unsigned long encoders_bitmask;
+   bool changed;
+
+   struct {
+   bool enabled;
+   struct drm_display_mode mode;
+   struct drm_framebuffer *fb;
+   int x, y;
+   unsigned long connectors_bitmask;
+   unsigned long encoders_bitmask;
+
+   struct drm_i915_gem_object *cursor_bo;
+   uint32_t cursor_handle;
+   int16_t cursor_x, cursor_y;
+   int16_t cursor_width, cursor_height;
+   bool cursor_visible;
+   } old;
+};
+
+struct intel_atomic_state {
+   struct 

[PATCH 44/51] drm/i915: Split sprite update_plane() into calc+commit phases

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Separate the part that calculates the register values from the part that
writes the registers. This will be useful in the atomic page flip code.
Also move the watermark magic into a prepare function that can be
performed outside the critical parts of the atomic page flip code.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_drv.h|5 +
 drivers/gpu/drm/i915/intel_sprite.c |  398 ++-
 2 files changed, 259 insertions(+), 144 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 1389eeb..6ab8f65 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -252,6 +252,11 @@ struct intel_plane {
   struct drm_intel_sprite_colorkey *key);
void (*get_colorkey)(struct drm_plane *plane,
 struct drm_intel_sprite_colorkey *key);
+   void (*calc)(struct drm_plane *plane, struct drm_framebuffer *fb,
+const struct intel_plane_coords *clip);
+   void (*prepare)(struct drm_plane *plane);
+   void (*commit)(struct drm_plane *plane);
+   struct intel_plane_regs regs;
 };

 struct intel_watermark_params {
diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
b/drivers/gpu/drm/i915/intel_sprite.c
index fee6f17..06d62e70 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -187,14 +187,12 @@ int intel_check_plane(const struct drm_plane *plane,
 }

 static void
-ivb_update_plane(struct drm_plane *plane,
-struct drm_framebuffer *fb,
-const struct intel_plane_coords *coords)
+ivb_calc_plane(struct drm_plane *plane,
+  struct drm_framebuffer *fb,
+  const struct intel_plane_coords *coords)
 {
-   struct drm_device *dev = plane->dev;
-   struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_plane *intel_plane = to_intel_plane(plane);
-   const struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj;
+   const struct drm_i915_gem_object *obj;
int crtc_x = coords->crtc_x;
int crtc_y = coords->crtc_y;
unsigned int crtc_w = coords->crtc_w;
@@ -203,47 +201,55 @@ ivb_update_plane(struct drm_plane *plane,
uint32_t y = coords->src_y;
uint32_t src_w = coords->src_w;
uint32_t src_h = coords->src_h;
-   int pipe = intel_plane->pipe;
-   u32 sprctl, sprscale = 0;
-   int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
+   int pixel_size;
+   struct intel_plane_regs *regs = _plane->regs;
+
+   if (!coords->visible) {
+   regs->cntr &= ~SPRITE_ENABLE;
+   /* Disable the scaler */
+   regs->scale = 0;
+   return;
+   }

-   sprctl = I915_READ(SPRCTL(pipe));
+   obj = to_intel_framebuffer(fb)->obj;
+   pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);

/* Mask out pixel format bits in case we change it */
-   sprctl &= ~SPRITE_PIXFORMAT_MASK;
-   sprctl &= ~SPRITE_RGB_ORDER_RGBX;
-   sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK;
-   sprctl &= ~SPRITE_TILED;
+   regs->cntr &= ~(SPRITE_PIXFORMAT_MASK |
+   SPRITE_RGB_ORDER_RGBX |
+   SPRITE_YUV_BYTE_ORDER_MASK |
+   SPRITE_TILED |
+   SPRITE_ENABLE);

switch (fb->pixel_format) {
case DRM_FORMAT_XBGR:
-   sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
+   regs->cntr |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
break;
case DRM_FORMAT_XRGB:
-   sprctl |= SPRITE_FORMAT_RGBX888;
+   regs->cntr |= SPRITE_FORMAT_RGBX888;
break;
case DRM_FORMAT_YUYV:
-   sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
+   regs->cntr |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
break;
case DRM_FORMAT_YVYU:
-   sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
+   regs->cntr |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
break;
case DRM_FORMAT_UYVY:
-   sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
+   regs->cntr |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
break;
case DRM_FORMAT_VYUY:
-   sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
+   regs->cntr |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
break;
default:
BUG();
}

if (obj->tiling_mode != I915_TILING_NONE)
-   sprctl |= SPRITE_TILED;
+   regs->cntr |= SPRITE_TILED;

/* must disable */
-   sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
-   sprctl |= SPRITE_ENABLE;
+   regs->cntr |= 

[PATCH 43/51] drm/i915: Split primary plane update_plane() into calc+commit phases

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Separate the part that calculates the register values from the part that
writes the registers. This will be useful in the atomic page flip code.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/i915_drv.h  |3 +
 drivers/gpu/drm/i915/intel_display.c |  145 ++
 drivers/gpu/drm/i915/intel_drv.h |1 +
 3 files changed, 100 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 53a35fd..302b6e6 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -269,6 +269,9 @@ struct drm_i915_display_funcs {
  struct drm_i915_gem_object *obj);
int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb,
int x, int y);
+   int (*calc_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb,
+ int x, int y);
+   void (*commit_plane)(struct drm_crtc *crtc);
/* clock updates for mode set */
/* cursor updates */
/* render clock increase/decrease */
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index ba737b8..0fb1e09 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1940,8 +1940,27 @@ static unsigned long 
gen4_compute_dspaddr_offset_xtiled(int *x, int *y,
return tile_rows * pitch * 8 + tiles * 4096;
 }

-static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
-int x, int y)
+static void intel_commit_plane(struct drm_crtc *crtc)
+{
+   struct drm_device *dev = crtc->dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+   int plane = intel_crtc->plane;
+   const struct intel_plane_regs *regs = _crtc->primary_regs;
+
+   I915_WRITE(DSPCNTR(plane), regs->cntr);
+   I915_WRITE(DSPSTRIDE(plane), regs->stride);
+
+   if (INTEL_INFO(dev)->gen >= 4) {
+   I915_WRITE(DSPTILEOFF(plane), regs->tileoff);
+   I915_WRITE(DSPLINOFF(plane), regs->linoff);
+   I915_WRITE(DSPSURF(plane), regs->surf);
+   } else
+   I915_WRITE(DSPADDR(plane), regs->linoff);
+}
+
+static int i9xx_calc_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
+  int x, int y)
 {
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1950,9 +1969,8 @@ static int i9xx_update_plane(struct drm_crtc *crtc, 
struct drm_framebuffer *fb,
struct drm_i915_gem_object *obj;
int plane = intel_crtc->plane;
unsigned long linear_offset;
-   u32 dspcntr;
-   u32 reg;
unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
+   struct intel_plane_regs *regs = _crtc->primary_regs;

switch (plane) {
case 0:
@@ -1966,36 +1984,35 @@ static int i9xx_update_plane(struct drm_crtc *crtc, 
struct drm_framebuffer *fb,
intel_fb = to_intel_framebuffer(fb);
obj = intel_fb->obj;

-   reg = DSPCNTR(plane);
-   dspcntr = I915_READ(reg);
+   regs->cntr = I915_READ(DSPCNTR(plane));
/* Mask out pixel format bits in case we change it */
-   dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
+   regs->cntr &= ~DISPPLANE_PIXFORMAT_MASK;
switch (fb->pixel_format) {
case DRM_FORMAT_C8:
-   dspcntr |= DISPPLANE_8BPP;
+   regs->cntr |= DISPPLANE_8BPP;
break;
case DRM_FORMAT_XRGB1555:
case DRM_FORMAT_ARGB1555:
-   dspcntr |= DISPPLANE_BGRX555;
+   regs->cntr |= DISPPLANE_BGRX555;
break;
case DRM_FORMAT_RGB565:
-   dspcntr |= DISPPLANE_BGRX565;
+   regs->cntr |= DISPPLANE_BGRX565;
break;
case DRM_FORMAT_XRGB:
case DRM_FORMAT_ARGB:
-   dspcntr |= DISPPLANE_BGRX888;
+   regs->cntr |= DISPPLANE_BGRX888;
break;
case DRM_FORMAT_XBGR:
case DRM_FORMAT_ABGR:
-   dspcntr |= DISPPLANE_RGBX888;
+   regs->cntr |= DISPPLANE_RGBX888;
break;
case DRM_FORMAT_XRGB2101010:
case DRM_FORMAT_ARGB2101010:
-   dspcntr |= DISPPLANE_BGRX101010;
+   regs->cntr |= DISPPLANE_BGRX101010;
break;
case DRM_FORMAT_XBGR2101010:
case DRM_FORMAT_ABGR2101010:
-   dspcntr |= DISPPLANE_RGBX101010;
+   regs->cntr |= DISPPLANE_RGBX101010;
break;
default:
DRM_ERROR("Unknown pixel format 0x%08x\n", fb->pixel_format);
@@ -2004,13 +2021,11 @@ static int i9xx_update_plane(struct drm_crtc *crtc, 
struct drm_framebuffer *fb,

if 

[PATCH 42/51] drm/i915: Introduce intel_plane_regs

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

intel_plane_regs can be used to shadow all the typical plane registers.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_drv.h |   14 ++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 2b9acba..5dab482 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -181,6 +181,20 @@ struct intel_connector {
bool (*get_hw_state)(struct intel_connector *);
 };

+struct intel_plane_regs {
+   u32 cntr;
+   u32 linoff;
+   u32 stride;
+   u32 pos;
+   u32 size;
+   u32 keyval;
+   u32 keymsk;
+   u32 surf;
+   u32 keymaxval;
+   u32 tileoff;
+   u32 scale;
+};
+
 struct intel_crtc {
struct drm_crtc base;
enum pipe pipe;
-- 
1.7.8.6



[PATCH 41/51] drm/i915: Unstatic intel_crtc_mode_fixup()

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Make intel_crtc_mode_fixup() available for the upcoming atomic
modesetting code.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_display.c |6 +++---
 drivers/gpu/drm/i915/intel_drv.h |4 
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 683d434..ba737b8 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3669,9 +3669,9 @@ bool intel_connector_get_hw_state(struct intel_connector 
*connector)
return encoder->get_hw_state(encoder, );
 }

-static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
+  const struct drm_display_mode *mode,
+  struct drm_display_mode *adjusted_mode)
 {
struct drm_device *dev = crtc->dev;

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index c65c97fc..2b9acba 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -603,4 +603,8 @@ extern void intel_crtc_cursor_commit(struct drm_crtc *crtc, 
uint32_t handle,
 extern void intel_crtc_update_sarea(struct drm_crtc *crtc, bool enabled);
 extern void intel_crtc_update_sarea_pos(struct drm_crtc *crtc, int x, int y);

+extern bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);
+
 #endif /* __INTEL_DRV_H__ */
-- 
1.7.8.6



[PATCH 40/51] drm/i915: Constify mode argument to intel_modeset_adjusted_mode()

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

intel_modeset_adjusted_mode() doesn't modify the passed display mode. So
pass it as const.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_display.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index ff51171..683d434 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6823,7 +6823,7 @@ static void intel_modeset_commit_output_state(struct 
drm_device *dev)

 static struct drm_display_mode *
 intel_modeset_adjusted_mode(struct drm_crtc *crtc,
-   struct drm_display_mode *mode)
+   const struct drm_display_mode *mode)
 {
struct drm_device *dev = crtc->dev;
struct drm_display_mode *adjusted_mode;
-- 
1.7.8.6



[PATCH 39/51] drm/i915: Introduce intel_crtc_update_sarea_pos()

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Refactor the code that stores the panning x/y position into the sarea.
Make the new function intel_crtc_update_sarea_pos() available to the
atomic mode setting code.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_display.c |   43 ++
 drivers/gpu/drm/i915/intel_drv.h |1 +
 2 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 6a5a82b..ff51171 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2166,13 +2166,39 @@ intel_finish_fb(struct drm_framebuffer *old_fb)
return ret;
 }

+void intel_crtc_update_sarea_pos(struct drm_crtc *crtc, int x, int y)
+{
+   struct drm_device *dev = crtc->dev;
+   struct drm_i915_master_private *master_priv;
+   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+   if (!dev->primary->master)
+   return;
+
+   master_priv = dev->primary->master->driver_priv;
+   if (!master_priv->sarea_priv)
+   return;
+
+   switch (intel_crtc->pipe) {
+   case 0:
+   master_priv->sarea_priv->pipeA_x = x;
+   master_priv->sarea_priv->pipeA_y = y;
+   break;
+   case 1:
+   master_priv->sarea_priv->pipeB_x = x;
+   master_priv->sarea_priv->pipeB_y = y;
+   break;
+   default:
+   break;
+   }
+}
+
 static int
 intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *fb)
 {
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
-   struct drm_i915_master_private *master_priv;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_framebuffer *old_fb;
int ret;
@@ -2224,20 +2250,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
intel_update_fbc(dev);
mutex_unlock(>struct_mutex);

-   if (!dev->primary->master)
-   return 0;
-
-   master_priv = dev->primary->master->driver_priv;
-   if (!master_priv->sarea_priv)
-   return 0;
-
-   if (intel_crtc->pipe) {
-   master_priv->sarea_priv->pipeB_x = x;
-   master_priv->sarea_priv->pipeB_y = y;
-   } else {
-   master_priv->sarea_priv->pipeA_x = x;
-   master_priv->sarea_priv->pipeA_y = y;
-   }
+   intel_crtc_update_sarea_pos(crtc, x, y);

return 0;
 }
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index cd6ea3b..c65c97fc 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -601,5 +601,6 @@ extern void intel_crtc_cursor_commit(struct drm_crtc *crtc, 
uint32_t handle,
 uint32_t addr);

 extern void intel_crtc_update_sarea(struct drm_crtc *crtc, bool enabled);
+extern void intel_crtc_update_sarea_pos(struct drm_crtc *crtc, int x, int y);

 #endif /* __INTEL_DRV_H__ */
-- 
1.7.8.6



[PATCH 38/51] drm/i915: Unstatic intel_crtc_update_sarea()

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Make intel_crtc_update_sarea() available for the atomic mode setting
code.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_display.c |4 ++--
 drivers/gpu/drm/i915/intel_drv.h |2 ++
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 79b6de7..6a5a82b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3457,8 +3457,8 @@ static void i9xx_crtc_off(struct drm_crtc *crtc)
 {
 }

-static void intel_crtc_update_sarea(struct drm_crtc *crtc,
-   bool enabled)
+void intel_crtc_update_sarea(struct drm_crtc *crtc,
+bool enabled)
 {
struct drm_device *dev = crtc->dev;
struct drm_i915_master_private *master_priv;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 9dea410..cd6ea3b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -600,4 +600,6 @@ extern void intel_crtc_cursor_commit(struct drm_crtc *crtc, 
uint32_t handle,
 struct drm_i915_gem_object *obj,
 uint32_t addr);

+extern void intel_crtc_update_sarea(struct drm_crtc *crtc, bool enabled);
+
 #endif /* __INTEL_DRV_H__ */
-- 
1.7.8.6



[PATCH 37/51] drm/i915: Pull intel_pipe_set_base() out of the crtc_mode_set() functions

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

intel_pipe_set_base() (un)pins the buffers, so it can't be called from
the atomic modeset paths. Pull the intel_pipe_set_base() and watermark
modifications out of i9xx_crtc_mode_set() and ironlake_crtc_mode_set()
into intel_crtc_mode_set(), so that the former two can be used from the
atomic modeset paths.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_display.c |   26 --
 1 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index f27ac4d..79b6de7 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4387,7 +4387,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
u32 dspcntr, pipeconf, vsyncshift;
bool ok, has_reduced_clock = false;
bool is_dp = false;
-   int ret;

ok = i9xx_compute_clocks(crtc, adjusted_mode, ,
 _reduced_clock, _clock,
@@ -4517,11 +4516,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
I915_WRITE(DSPCNTR(plane), dspcntr);
POSTING_READ(DSPCNTR(plane));

-   ret = intel_pipe_set_base(crtc, x, y, fb);
-
-   intel_update_watermarks(dev);
-
-   return ret;
+   return 0;
 }

 /*
@@ -4795,7 +4790,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
bool ok, has_reduced_clock = false, is_sdvo = false;
bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
struct intel_encoder *encoder, *edp_encoder = NULL;
-   int ret;
struct fdi_m_n m_n = {0};
u32 temp;
int target_clock, pixel_multiplier, lane, link_bw, factor;
@@ -5115,13 +5109,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE);
POSTING_READ(DSPCNTR(plane));

-   ret = intel_pipe_set_base(crtc, x, y, fb);
-
-   intel_update_watermarks(dev);
-
-   intel_update_linetime_watermarks(dev, pipe, adjusted_mode);
-
-   return ret;
+   return 0;
 }

 int intel_check_clock(struct drm_crtc *crtc,
@@ -5164,6 +5152,16 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,

ret = dev_priv->display.crtc_mode_set(crtc, mode, adjusted_mode,
  x, y, fb);
+
+   if (!ret) {
+   ret = intel_pipe_set_base(crtc, x, y, fb);
+
+   intel_update_watermarks(dev);
+
+   if (HAS_PCH_SPLIT(dev))
+   intel_update_linetime_watermarks(dev, pipe, 
adjusted_mode);
+   }
+
drm_vblank_post_modeset(dev, pipe);

return ret;
-- 
1.7.8.6



[PATCH 36/51] drm/i915: Unstatic intel_finish_fb()

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

intel_finish_fb() will be used by the atomic modeset code, so make it
non-static.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_display.c |2 +-
 drivers/gpu/drm/i915/intel_drv.h |1 +
 2 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index da59490..f27ac4d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2139,7 +2139,7 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct 
drm_framebuffer *fb,
return dev_priv->display.update_plane(crtc, fb, x, y);
 }

-static int
+int
 intel_finish_fb(struct drm_framebuffer *old_fb)
 {
struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 19bef3e..9dea410 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -511,6 +511,7 @@ extern int intel_pin_and_fence_fb_obj(struct drm_device 
*dev,
  struct drm_i915_gem_object *obj,
  struct intel_ring_buffer *pipelined);
 extern void intel_unpin_fb_obj(struct drm_i915_gem_object *obj);
+extern int intel_finish_fb(struct drm_framebuffer *old_fb);

 extern int intel_framebuffer_init(struct drm_device *dev,
  struct intel_framebuffer *ifb,
-- 
1.7.8.6



[PATCH 35/51] drm/i915: unstatic cursor functions for use with atomic modesetting

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ander Conselvan de Oliveira 

---
 drivers/gpu/drm/i915/intel_display.c |   24 
 drivers/gpu/drm/i915/intel_drv.h |   13 +
 2 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 20539c4..da59490 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5587,12 +5587,12 @@ static void intel_crtc_update_cursor(struct drm_crtc 
*crtc,
}
 }

-static int intel_crtc_cursor_prepare(struct drm_crtc *crtc,
-struct drm_file *file,
-uint32_t handle,
-uint32_t width, uint32_t height,
-struct drm_i915_gem_object **obj_ret,
-uint32_t *addr_ret)
+int intel_crtc_cursor_prepare(struct drm_crtc *crtc,
+ struct drm_file *file,
+ uint32_t handle,
+ uint32_t width, uint32_t height,
+ struct drm_i915_gem_object **obj_ret,
+ uint32_t *addr_ret)
 {
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5677,8 +5677,8 @@ fail:
return ret;
 }

-static void intel_crtc_cursor_bo_unref(struct drm_crtc *crtc,
-  struct drm_i915_gem_object *obj)
+void intel_crtc_cursor_bo_unref(struct drm_crtc *crtc,
+   struct drm_i915_gem_object *obj)
 {
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5696,10 +5696,10 @@ static void intel_crtc_cursor_bo_unref(struct drm_crtc 
*crtc,
mutex_unlock(>struct_mutex);
 }

-static void intel_crtc_cursor_commit(struct drm_crtc *crtc, uint32_t handle,
-uint32_t width, uint32_t height,
-struct drm_i915_gem_object *obj,
-uint32_t addr)
+void intel_crtc_cursor_commit(struct drm_crtc *crtc, uint32_t handle,
+ uint32_t width, uint32_t height,
+ struct drm_i915_gem_object *obj,
+ uint32_t addr)
 {
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index abe646d..19bef3e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -586,4 +586,17 @@ extern void intel_ddi_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);

+extern int intel_crtc_cursor_prepare(struct drm_crtc *crtc,
+struct drm_file *file,
+uint32_t handle,
+uint32_t width, uint32_t height,
+struct drm_i915_gem_object **obj_ret,
+uint32_t *addr_ret);
+extern void intel_crtc_cursor_bo_unref(struct drm_crtc *crtc,
+  struct drm_i915_gem_object *obj);
+extern void intel_crtc_cursor_commit(struct drm_crtc *crtc, uint32_t handle,
+uint32_t width, uint32_t height,
+struct drm_i915_gem_object *obj,
+uint32_t addr);
+
 #endif /* __INTEL_DRV_H__ */
-- 
1.7.8.6



[PATCH 34/51] drm/i915: split cursor setting code into prepare/commit/unref parts

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ander Conselvan de Oliveira 

The atomic mode setting API will need to pin the cursor bo without
making changes to the current setup. Only on a later stage the cursor
registers can be written and the previous bo released.

This patch splits intel_crtc_cursor_set() into three parts: prepare,
commit and unref. intel_crtc_cursor_prepare() will pin the cursor bo
and return a gem object and the address to be written to the cursor
registers. intel_crtc_cursor_commit() takes that object and address
and actually changes the cursor. intel_crtc_cursor_unref() is used to
release the previous cursor bo.
---
 drivers/gpu/drm/i915/intel_display.c |   90 +
 1 files changed, 68 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index c59985d..20539c4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5587,10 +5587,12 @@ static void intel_crtc_update_cursor(struct drm_crtc 
*crtc,
}
 }

-static int intel_crtc_cursor_set(struct drm_crtc *crtc,
+static int intel_crtc_cursor_prepare(struct drm_crtc *crtc,
 struct drm_file *file,
 uint32_t handle,
-uint32_t width, uint32_t height)
+uint32_t width, uint32_t height,
+struct drm_i915_gem_object **obj_ret,
+uint32_t *addr_ret)
 {
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5602,10 +5604,9 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
/* if we want to turn off the cursor ignore width and height */
if (!handle) {
DRM_DEBUG_KMS("cursor off\n");
-   addr = 0;
-   obj = NULL;
-   mutex_lock(>struct_mutex);
-   goto finish;
+   *addr_ret = 0;
+   *obj_ret = NULL;
+   return 0;
}

/* Currently we only support 64x64 cursors */
@@ -5661,17 +5662,46 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
if (IS_GEN2(dev))
I915_WRITE(CURSIZE, (height << 12) | width);

- finish:
-   if (intel_crtc->cursor_bo) {
-   if (dev_priv->info->cursor_needs_physical) {
-   if (intel_crtc->cursor_bo != obj)
-   i915_gem_detach_phys_object(dev, 
intel_crtc->cursor_bo);
-   } else
-   i915_gem_object_unpin(intel_crtc->cursor_bo);
-   drm_gem_object_unreference(_crtc->cursor_bo->base);
-   }
+   mutex_unlock(>struct_mutex);

+   *obj_ret = obj;
+   *addr_ret = addr;
+
+   return 0;
+fail_unpin:
+   i915_gem_object_unpin(obj);
+fail_locked:
mutex_unlock(>struct_mutex);
+fail:
+   drm_gem_object_unreference_unlocked(>base);
+   return ret;
+}
+
+static void intel_crtc_cursor_bo_unref(struct drm_crtc *crtc,
+  struct drm_i915_gem_object *obj)
+{
+   struct drm_device *dev = crtc->dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+   mutex_lock(>struct_mutex);
+
+   if (dev_priv->info->cursor_needs_physical) {
+   if (obj != intel_crtc->cursor_bo)
+   i915_gem_detach_phys_object(dev, obj);
+   } else
+   i915_gem_object_unpin(obj);
+   drm_gem_object_unreference(>base);
+
+   mutex_unlock(>struct_mutex);
+}
+
+static void intel_crtc_cursor_commit(struct drm_crtc *crtc, uint32_t handle,
+uint32_t width, uint32_t height,
+struct drm_i915_gem_object *obj,
+uint32_t addr)
+{
+   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);

intel_crtc->cursor_addr = addr;
intel_crtc->cursor_handle = handle;
@@ -5680,15 +5710,31 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
intel_crtc->cursor_height = height;

intel_crtc_update_cursor(crtc, true);
+}
+
+static int intel_crtc_cursor_set(struct drm_crtc *crtc,
+struct drm_file *file,
+uint32_t handle,
+uint32_t width, uint32_t height)
+{
+   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+   int ret;
+   struct drm_i915_gem_object *obj, *old_obj;
+   uint32_t addr;
+
+   ret = intel_crtc_cursor_prepare(crtc, file, handle, width, height,
+   , );
+   if (ret)
+   return ret;
+
+   old_obj = intel_crtc->cursor_bo;
+
+   intel_crtc_cursor_commit(crtc, handle, width, height, obj, addr);
+
+   if (old_obj)
+

[PATCH 33/51] drm/i915: store cursor_handle in struct intel_crtc

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ander Conselvan de Oliveira 

This way it is possible to check if the cursor changed without doing
any setup. Will be useful for the atomic modesetting api.
---
 drivers/gpu/drm/i915/intel_display.c |1 +
 drivers/gpu/drm/i915/intel_drv.h |2 +-
 2 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index d4d7454..c59985d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5674,6 +5674,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
mutex_unlock(>struct_mutex);

intel_crtc->cursor_addr = addr;
+   intel_crtc->cursor_handle = handle;
intel_crtc->cursor_bo = obj;
intel_crtc->cursor_width = width;
intel_crtc->cursor_height = height;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 0660d38..abe646d 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -204,7 +204,7 @@ struct intel_crtc {
unsigned long dspaddr_offset;

struct drm_i915_gem_object *cursor_bo;
-   uint32_t cursor_addr;
+   uint32_t cursor_addr, cursor_handle;
int16_t cursor_x, cursor_y;
int16_t cursor_width, cursor_height;
bool cursor_visible;
-- 
1.7.8.6



[PATCH 32/51] drm/i915: Add intel_check_clock()

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

intel_check_clock() can be used to check clock validity w/o modifying
hardware state.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/i915_drv.h  |2 ++
 drivers/gpu/drm/i915/intel_display.c |   24 
 2 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f511fa2..53a35fd 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1600,6 +1600,8 @@ extern bool intel_fbc_enabled(struct drm_device *dev);
 extern void intel_disable_fbc(struct drm_device *dev);
 extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
 extern void ironlake_init_pch_refclk(struct drm_device *dev);
+extern int intel_check_clock(struct drm_crtc *crtc,
+const struct drm_display_mode *adjusted_mode);
 extern void gen6_set_rps(struct drm_device *dev, u8 val);
 extern void intel_detect_pch(struct drm_device *dev);
 extern int intel_trans_dp_port_sel(struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index d6b4bfe..d4d7454 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5124,6 +5124,30 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
return ret;
 }

+int intel_check_clock(struct drm_crtc *crtc,
+ const struct drm_display_mode *adjusted_mode)
+{
+   struct drm_device *dev = crtc->dev;
+   intel_clock_t clock, reduced_clock;
+   bool has_reduced_clock = false;
+   bool ok;
+
+   if (HAS_PCH_SPLIT(dev)) {
+   ok = ironlake_compute_clocks(crtc, adjusted_mode, ,
+_reduced_clock, 
_clock);
+   } else {
+   int num_connectors = 0;
+   bool is_dp = false;
+   int refclk;
+
+   ok = i9xx_compute_clocks(crtc, adjusted_mode, ,
+_reduced_clock, _clock,
+, _connectors, _dp);
+   }
+
+   return ok ? 0 : -EINVAL;
+}
+
 static int intel_crtc_mode_set(struct drm_crtc *crtc,
   struct drm_display_mode *mode,
   struct drm_display_mode *adjusted_mode,
-- 
1.7.8.6



[PATCH 31/51] drm/i915: Consitify adjusted_mode parameter

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

i9xx_adjust_sdvo_tv_clock(), i9xx_compute_clocks() and
ironlake_compute_clocks() do not modify the adjusted_mode passed in, so
pass it as const.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_display.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 2a0748c..d6b4bfe 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3963,7 +3963,7 @@ static int i9xx_get_refclk(struct drm_crtc *crtc, int 
num_connectors)
return refclk;
 }

-static void i9xx_adjust_sdvo_tv_clock(struct drm_display_mode *adjusted_mode,
+static void i9xx_adjust_sdvo_tv_clock(const struct drm_display_mode 
*adjusted_mode,
  intel_clock_t *clock)
 {
/* SDVO TV has fixed PLL values depend on its clock range,
@@ -4302,7 +4302,7 @@ static void i8xx_update_pll(struct drm_crtc *crtc,
 }

 static bool i9xx_compute_clocks(struct drm_crtc *crtc,
-   struct drm_display_mode *adjusted_mode,
+   const struct drm_display_mode *adjusted_mode,
intel_clock_t *clock,
bool *has_reduced_clock,
intel_clock_t *reduced_clock,
@@ -4716,7 +4716,7 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc,
 }

 static bool ironlake_compute_clocks(struct drm_crtc *crtc,
-   struct drm_display_mode *adjusted_mode,
+   const struct drm_display_mode 
*adjusted_mode,
intel_clock_t *clock,
bool *has_reduced_clock,
intel_clock_t *reduced_clock)
-- 
1.7.8.6



[PATCH 30/51] drm/i915: Factor out i9xx_compute_clocks() like ironlake_compute_clocks()

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Split the clock stuff out.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_display.c |   88 +-
 1 files changed, 55 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index a4eb64f..2a0748c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4301,25 +4301,20 @@ static void i8xx_update_pll(struct drm_crtc *crtc,
I915_WRITE(DPLL(pipe), dpll);
 }

-static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode,
- int x, int y,
- struct drm_framebuffer *fb)
+static bool i9xx_compute_clocks(struct drm_crtc *crtc,
+   struct drm_display_mode *adjusted_mode,
+   intel_clock_t *clock,
+   bool *has_reduced_clock,
+   intel_clock_t *reduced_clock,
+   int *refclk, int *num_connectors, bool *is_dp)
 {
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
-   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-   int pipe = intel_crtc->pipe;
-   int plane = intel_crtc->plane;
-   int refclk, num_connectors = 0;
-   intel_clock_t clock, reduced_clock;
-   u32 dspcntr, pipeconf, vsyncshift;
-   bool ok, has_reduced_clock = false, is_sdvo = false;
-   bool is_lvds = false, is_tv = false, is_dp = false;
struct intel_encoder *encoder;
const intel_limit_t *limit;
-   int ret;
+   bool ret, is_sdvo = false, is_tv = false, is_lvds = false;
+
+   *num_connectors = 0;

for_each_encoder_on_crtc(dev, crtc, encoder) {
switch (encoder->type) {
@@ -4336,30 +4331,25 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
is_tv = true;
break;
case INTEL_OUTPUT_DISPLAYPORT:
-   is_dp = true;
+   *is_dp = true;
break;
}

-   num_connectors++;
+   (*num_connectors)++;
}

-   refclk = i9xx_get_refclk(crtc, num_connectors);
+   *refclk = i9xx_get_refclk(crtc, *num_connectors);

/*
 * Returns a set of divisors for the desired target clock with the given
 * refclk, or FALSE.  The returned values represent the clock equation:
 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
 */
-   limit = intel_limit(crtc, refclk);
-   ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL,
-);
-   if (!ok) {
-   DRM_ERROR("Couldn't find PLL settings for mode!\n");
-   return -EINVAL;
-   }
-
-   /* Ensure that the cursor is valid for the new mode before changing... 
*/
-   intel_crtc_update_cursor(crtc, true);
+   limit = intel_limit(crtc, *refclk);
+   ret = limit->find_pll(limit, crtc, adjusted_mode->clock, *refclk, NULL,
+ clock);
+   if (!ret)
+   return false;

if (is_lvds && dev_priv->lvds_downclock_avail) {
/*
@@ -4368,15 +4358,47 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
 * by using the FP0/FP1. In such case we will disable the LVDS
 * downclock feature.
*/
-   has_reduced_clock = limit->find_pll(limit, crtc,
-   dev_priv->lvds_downclock,
-   refclk,
-   ,
-   _clock);
+   *has_reduced_clock = limit->find_pll(limit, crtc,
+dev_priv->lvds_downclock,
+*refclk,
+clock,
+reduced_clock);
}

if (is_sdvo && is_tv)
-   i9xx_adjust_sdvo_tv_clock(adjusted_mode, );
+   i9xx_adjust_sdvo_tv_clock(adjusted_mode, clock);
+
+   return true;
+}
+
+static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode,
+ int x, int y,
+ struct drm_framebuffer *fb)
+{
+   struct drm_device *dev = crtc->dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct intel_crtc *intel_crtc = 

[PATCH 29/51] drm/i915: Split clipping and checking from update_plane hook

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Split the update_plane() codepath into two separate steps. The first
step checkis and clips the plane, and the second step actually commits
the changes to the hardware. This allows the atomic modesetting code
to perform all checks before clobering hardware state.

The update_plane() hook is reduced to a thin wrapper calling both check
and commit functions.

Buffer (un)pinning is still being performed in the commit step. This
needs to be changed as well, so that the atomic modesetting code can
try to pin all new buffers before touching the hardware.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_drv.h|   15 +-
 drivers/gpu/drm/i915/intel_sprite.c |  367 ++
 2 files changed, 247 insertions(+), 135 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 64d87c2..0660d38 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -214,6 +214,15 @@ struct intel_crtc {
struct intel_pch_pll *pch_pll;
 };

+struct intel_plane_coords {
+   /* disabled or fully clipped? */
+   bool visible;
+   /* coordinates clipped against pipe dimensions */
+   int32_t crtc_x, crtc_y;
+   uint32_t crtc_w, crtc_h;
+   uint32_t src_x, src_y, src_w, src_h;
+};
+
 struct intel_plane {
struct drm_plane base;
enum pipe pipe;
@@ -222,11 +231,7 @@ struct intel_plane {
u32 lut_r[1024], lut_g[1024], lut_b[1024];
void (*update_plane)(struct drm_plane *plane,
 struct drm_framebuffer *fb,
-struct drm_i915_gem_object *obj,
-int crtc_x, int crtc_y,
-unsigned int crtc_w, unsigned int crtc_h,
-uint32_t x, uint32_t y,
-uint32_t src_w, uint32_t src_h);
+const struct intel_plane_coords *clip);
void (*disable_plane)(struct drm_plane *plane);
int (*update_colorkey)(struct drm_plane *plane,
   struct drm_intel_sprite_colorkey *key);
diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
b/drivers/gpu/drm/i915/intel_sprite.c
index cd6777f..fee6f17 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -36,16 +36,173 @@
 #include 
 #include "i915_drv.h"

+static bool
+format_is_yuv(uint32_t format)
+{
+   switch (format) {
+   case DRM_FORMAT_YUYV:
+   case DRM_FORMAT_UYVY:
+   case DRM_FORMAT_VYUY:
+   case DRM_FORMAT_YVYU:
+   return true;
+   default:
+   return false;
+   }
+}
+
+static void intel_clip_plane(const struct drm_plane *plane,
+const struct drm_crtc *crtc,
+const struct drm_framebuffer *fb,
+struct intel_plane_coords *coords)
+{
+   const struct intel_plane *intel_plane = to_intel_plane(plane);
+   const struct drm_display_mode *mode = >mode;
+   int hscale, vscale;
+   struct drm_region src = {
+   .x1 = coords->src_x,
+   .x2 = coords->src_x + coords->src_w,
+   .y1 = coords->src_y,
+   .y2 = coords->src_y + coords->src_h,
+   };
+   struct drm_region dst = {
+   .x1 = coords->crtc_x,
+   .x2 = coords->crtc_x + coords->crtc_w,
+   .y1 = coords->crtc_y,
+   .y2 = coords->crtc_y + coords->crtc_h,
+   };
+   const struct drm_region clip = {
+   .x2 = mode->hdisplay,
+   .y2 = mode->vdisplay,
+   };
+
+   hscale = drm_calc_hscale(, , 1, intel_plane->max_downscale << 
16);
+   vscale = drm_calc_vscale(, , 1, intel_plane->max_downscale << 
16);
+
+   coords->visible = drm_region_clip_scaled(, , , hscale, 
vscale);
+
+   coords->crtc_x = dst.x1;
+   coords->crtc_y = dst.y1;
+   coords->crtc_w = drm_region_width();
+   coords->crtc_h = drm_region_height();
+
+   /* HW doesn't seem to like smaller sprite, even when scaling */
+   /* FIXME return an error instead? */
+   if (coords->crtc_w < 3 || coords->crtc_h < 3)
+   coords->visible = false;
+
+   /*
+* Hardware doesn't handle subpixel coordinates.
+* Round to nearest (macro)pixel boundary.
+*/
+   if (format_is_yuv(fb->pixel_format)) {
+   coords->src_x = ((src.x1 + 0x1) >> 17) << 1;
+   coords->src_w = (((src.x2 + 0x1) >> 17) << 1) - 
coords->src_x;
+   } else {
+   coords->src_x = (src.x1 + 0x8000) >> 16;
+   coords->src_w = ((src.x2 + 0x8000) >> 16) - coords->src_x;
+   }
+   coords->src_y = (src.y1 + 0x8000) >> 16;
+   coords->src_h = ((src.y2 + 0x8000) >> 16) - coords->src_y;
+
+   /* Account for minimum source size when scaling */
+ 

[PATCH 28/51] drm/i915: Implement restore_fbdev_mode hook

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Convert intel_fb_restore_mode to be useable as the
drm_fb_helper.restore_fbdev_mode hook. This will cause all planes to be
disabled when swithing back to fbcon.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/i915_dma.c  |2 +-
 drivers/gpu/drm/i915/intel_drv.h |2 +-
 drivers/gpu/drm/i915/intel_fb.c  |   14 ++
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index c9bfd83..acc4317 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1820,7 +1820,7 @@ void i915_driver_lastclose(struct drm_device * dev)
return;

if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-   intel_fb_restore_mode(dev);
+   intel_fb_restore_mode(_priv->fbdev->helper);
vga_switcheroo_process_delayed_switch();
return;
}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index fe71425..64d87c2 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -527,7 +527,7 @@ extern int intel_overlay_attrs(struct drm_device *dev, void 
*data,
   struct drm_file *file_priv);

 extern void intel_fb_output_poll_changed(struct drm_device *dev);
-extern void intel_fb_restore_mode(struct drm_device *dev);
+extern int intel_fb_restore_mode(struct drm_fb_helper *helper);

 extern void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
bool state);
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index 7b30b5c..f087041 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -193,6 +193,7 @@ static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
.gamma_set = intel_crtc_fb_gamma_set,
.gamma_get = intel_crtc_fb_gamma_get,
.fb_probe = intel_fb_find_or_create_single,
+   .restore_fbdev_mode = intel_fb_restore_mode,
 };

 static void intel_fbdev_destroy(struct drm_device *dev,
@@ -273,22 +274,27 @@ void intel_fb_output_poll_changed(struct drm_device *dev)
drm_fb_helper_hotplug_event(_priv->fbdev->helper);
 }

-void intel_fb_restore_mode(struct drm_device *dev)
+int intel_fb_restore_mode(struct drm_fb_helper *helper)
 {
+   struct drm_device *dev = helper->dev;
int ret;
-   drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_mode_config *config = >mode_config;
struct drm_plane *plane;

mutex_lock(>mode_config.mutex);

-   ret = drm_fb_helper_restore_fbdev_mode(_priv->fbdev->helper);
-   if (ret)
+   ret = drm_fb_helper_restore_fbdev_mode(helper);
+   if (ret) {
DRM_DEBUG("failed to restore crtc mode\n");
+   goto out;
+   }

/* Be sure to shut off any planes that may be active */
list_for_each_entry(plane, >plane_list, head)
plane->funcs->disable_plane(plane);

+out:
mutex_unlock(>mode_config.mutex);
+
+   return ret;
 }
-- 
1.7.8.6



[PATCH 27/51] drm/i915: Bad pixel formats can't reach the sprite code

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

The framebuffer pixel format is already checked by the common code.
So there's no way an invalid format could reach the driver. So instead
of falling back to a default format, call BUG().

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_sprite.c |8 ++--
 1 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
b/drivers/gpu/drm/i915/intel_sprite.c
index 709b978..cd6777f 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -78,9 +78,7 @@ ivb_update_plane(struct drm_plane *plane, struct 
drm_framebuffer *fb,
sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
break;
default:
-   DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n");
-   sprctl |= SPRITE_FORMAT_RGBX888;
-   break;
+   BUG();
}

if (obj->tiling_mode != I915_TILING_NONE)
@@ -253,9 +251,7 @@ ilk_update_plane(struct drm_plane *plane, struct 
drm_framebuffer *fb,
dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
break;
default:
-   DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n");
-   dvscntr |= DVS_FORMAT_RGBX888;
-   break;
+   BUG();
}

if (obj->tiling_mode != I915_TILING_NONE)
-- 
1.7.8.6



[PATCH 26/51] drm/i915: pixel_size == cpp

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Use drm_format_plane_cpp() to get 'pixel_size' in the sprite code.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_sprite.c |   19 +++
 1 files changed, 3 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
b/drivers/gpu/drm/i915/intel_sprite.c
index 7d1da04..709b978 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -48,7 +48,7 @@ ivb_update_plane(struct drm_plane *plane, struct 
drm_framebuffer *fb,
struct intel_plane *intel_plane = to_intel_plane(plane);
int pipe = intel_plane->pipe;
u32 sprctl, sprscale = 0;
-   int pixel_size;
+   int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);

sprctl = I915_READ(SPRCTL(pipe));

@@ -61,32 +61,25 @@ ivb_update_plane(struct drm_plane *plane, struct 
drm_framebuffer *fb,
switch (fb->pixel_format) {
case DRM_FORMAT_XBGR:
sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
-   pixel_size = 4;
break;
case DRM_FORMAT_XRGB:
sprctl |= SPRITE_FORMAT_RGBX888;
-   pixel_size = 4;
break;
case DRM_FORMAT_YUYV:
sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
-   pixel_size = 2;
break;
case DRM_FORMAT_YVYU:
sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
-   pixel_size = 2;
break;
case DRM_FORMAT_UYVY:
sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
-   pixel_size = 2;
break;
case DRM_FORMAT_VYUY:
sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
-   pixel_size = 2;
break;
default:
DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n");
sprctl |= SPRITE_FORMAT_RGBX888;
-   pixel_size = 4;
break;
}

@@ -228,8 +221,9 @@ ilk_update_plane(struct drm_plane *plane, struct 
drm_framebuffer *fb,
struct drm_device *dev = plane->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_plane *intel_plane = to_intel_plane(plane);
-   int pipe = intel_plane->pipe, pixel_size;
+   int pipe = intel_plane->pipe;
u32 dvscntr, dvsscale;
+   int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);

dvscntr = I915_READ(DVSCNTR(pipe));

@@ -242,32 +236,25 @@ ilk_update_plane(struct drm_plane *plane, struct 
drm_framebuffer *fb,
switch (fb->pixel_format) {
case DRM_FORMAT_XBGR:
dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
-   pixel_size = 4;
break;
case DRM_FORMAT_XRGB:
dvscntr |= DVS_FORMAT_RGBX888;
-   pixel_size = 4;
break;
case DRM_FORMAT_YUYV:
dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
-   pixel_size = 2;
break;
case DRM_FORMAT_YVYU:
dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
-   pixel_size = 2;
break;
case DRM_FORMAT_UYVY:
dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
-   pixel_size = 2;
break;
case DRM_FORMAT_VYUY:
dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
-   pixel_size = 2;
break;
default:
DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n");
dvscntr |= DVS_FORMAT_RGBX888;
-   pixel_size = 4;
break;
}

-- 
1.7.8.6



[PATCH 25/51] drm/i915: Implement proper clipping for video sprites

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Properly clip the source when the destination gets clipped
by the pipe dimensions.

Sadly the video sprite hardware is rather limited so it can't do proper
sub-pixel postitioning. Resort to a best effort approach, where the
source coordinates are rounded to the nearest (macro)pixel boundary.

Also do some additional checking against various hardware limits.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_sprite.c |  150 ---
 1 files changed, 102 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
b/drivers/gpu/drm/i915/intel_sprite.c
index 82f5e5c..7d1da04 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -128,11 +128,14 @@ ivb_update_plane(struct drm_plane *plane, struct 
drm_framebuffer *fb,
I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);
I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
if (obj->tiling_mode != I915_TILING_NONE) {
+   y += fb->offsets[0] / fb->pitches[0];
+   x += fb->offsets[0] % fb->pitches[0] / pixel_size;
+
I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
} else {
unsigned long offset;

-   offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
+   offset = fb->offsets[0] + y * fb->pitches[0] + x * pixel_size;
I915_WRITE(SPRLINOFF(pipe), offset);
}
I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
@@ -290,11 +293,14 @@ ilk_update_plane(struct drm_plane *plane, struct 
drm_framebuffer *fb,
I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]);
I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
if (obj->tiling_mode != I915_TILING_NONE) {
+   y += fb->offsets[0] / fb->pitches[0];
+   x += fb->offsets[0] % fb->pitches[0] / pixel_size;
+
I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x);
} else {
unsigned long offset;

-   offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
+   offset = fb->offsets[0] + y * fb->pitches[0] + x * pixel_size;
I915_WRITE(DVSLINOFF(pipe), offset);
}
I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
@@ -408,6 +414,20 @@ ilk_get_colorkey(struct drm_plane *plane, struct 
drm_intel_sprite_colorkey *key)
key->flags = I915_SET_COLORKEY_NONE;
 }

+static bool
+format_is_yuv(uint32_t format)
+{
+   switch (format) {
+   case DRM_FORMAT_YUYV:
+   case DRM_FORMAT_UYVY:
+   case DRM_FORMAT_VYUY:
+   case DRM_FORMAT_YVYU:
+   return true;
+   default:
+   return false;
+   }
+}
+
 static int
 intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
   struct drm_framebuffer *fb, int crtc_x, int crtc_y,
@@ -419,65 +439,97 @@ intel_update_plane(struct drm_plane *plane, struct 
drm_crtc *crtc,
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_plane *intel_plane = to_intel_plane(plane);
-   struct intel_framebuffer *intel_fb;
-   struct drm_i915_gem_object *obj, *old_obj;
+   struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
+   struct drm_i915_gem_object *obj = intel_fb->obj;
+   struct drm_i915_gem_object *old_obj = intel_plane->obj;
int pipe = intel_plane->pipe;
int ret = 0;
-   int x = src_x >> 16, y = src_y >> 16;
int primary_w = crtc->mode.hdisplay, primary_h = crtc->mode.vdisplay;
bool disable_primary = false;
+   bool visible;
+   int hscale, vscale;
+   int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
+   struct drm_region src = {
+   .x1 = src_x,
+   .x2 = src_x + src_w,
+   .y1 = src_y,
+   .y2 = src_y + src_h,
+   };
+   struct drm_region dst = {
+   .x1 = crtc_x,
+   .x2 = crtc_x + crtc_w,
+   .y1 = crtc_y,
+   .y2 = crtc_y + crtc_h,
+   };
+   const struct drm_region clip = {
+   .x2 = crtc->mode.hdisplay,
+   .y2 = crtc->mode.vdisplay,
+   };

-   intel_fb = to_intel_framebuffer(fb);
-   obj = intel_fb->obj;
+   /* Don't modify another pipe's plane */
+   if (intel_plane->pipe != intel_crtc->pipe)
+   return -EINVAL;

-   old_obj = intel_plane->obj;
+   if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > 16384)
+   return -EINVAL;

-   src_w = src_w >> 16;
-   src_h = src_h >> 16;
+   hscale = drm_calc_hscale(, , 1, intel_plane->max_downscale << 
16);
+   vscale = drm_calc_vscale(, , 1, intel_plane->max_downscale << 
16);

-   /* Pipe must be running... */
-   if (!(I915_READ(PIPECONF(pipe)) & PIPECONF_ENABLE))
-   

[PATCH 24/51] drm/i915: Handle framebuffer offsets[]

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Take fb->offset[0] into account when calculating the linear and tile x/y
offsets.

For non-tiled surfaces fb->offset[0] is simply added to the linear
byte offset.

For tiled surfaces treat fb->offsets[0] as a byte offset into the
linearized view of the surface. So we end up converting fb->offsets[0]
into additional x and y offsets.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_display.c |   12 ++--
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index f3fea88..a4eb64f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1952,6 +1952,7 @@ static int i9xx_update_plane(struct drm_crtc *crtc, 
struct drm_framebuffer *fb,
unsigned long linear_offset;
u32 dspcntr;
u32 reg;
+   unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, 0);

switch (plane) {
case 0:
@@ -2010,13 +2011,12 @@ static int i9xx_update_plane(struct drm_crtc *crtc, 
struct drm_framebuffer *fb,

I915_WRITE(reg, dspcntr);

-   linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
+   linear_offset = fb->offsets[0] + y * fb->pitches[0] + x * cpp;

if (INTEL_INFO(dev)->gen >= 4) {
intel_crtc->dspaddr_offset =
gen4_compute_dspaddr_offset_xtiled(, ,
-  fb->bits_per_pixel / 
8,
-  fb->pitches[0]);
+  cpp, fb->pitches[0]);
linear_offset -= intel_crtc->dspaddr_offset;
} else {
intel_crtc->dspaddr_offset = linear_offset;
@@ -2049,6 +2049,7 @@ static int ironlake_update_plane(struct drm_crtc *crtc,
unsigned long linear_offset;
u32 dspcntr;
u32 reg;
+   unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, 0);

switch (plane) {
case 0:
@@ -2105,11 +2106,10 @@ static int ironlake_update_plane(struct drm_crtc *crtc,

I915_WRITE(reg, dspcntr);

-   linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
+   linear_offset = fb->offsets[0] + y * fb->pitches[0] + x * 
(fb->bits_per_pixel / 8);
intel_crtc->dspaddr_offset =
gen4_compute_dspaddr_offset_xtiled(, ,
-  fb->bits_per_pixel / 8,
-  fb->pitches[0]);
+  cpp, fb->pitches[0]);
linear_offset -= intel_crtc->dspaddr_offset;

DRM_DEBUG_KMS("Writing base %08X %08lX %d %d %d\n",
-- 
1.7.8.6



[PATCH 23/51] drm/i915: Check the framebuffer offset

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

The framebuffer offset must be aligned to (macro)pixel size.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_display.c |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 581772c..f3fea88 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7729,6 +7729,7 @@ int intel_framebuffer_init(struct drm_device *dev,
   struct drm_i915_gem_object *obj)
 {
int ret;
+   unsigned int align = drm_format_plane_cpp(mode_cmd->pixel_format, 0);

if (obj->tiling_mode == I915_TILING_Y)
return -EINVAL;
@@ -7768,6 +7769,7 @@ int intel_framebuffer_init(struct drm_device *dev,
case DRM_FORMAT_UYVY:
case DRM_FORMAT_YVYU:
case DRM_FORMAT_VYUY:
+   align <<= 1;
if (INTEL_INFO(dev)->gen < 6)
return -EINVAL;
break;
@@ -7776,6 +7778,9 @@ int intel_framebuffer_init(struct drm_device *dev,
return -EINVAL;
}

+   if (mode_cmd->offsets[0] % align)
+   return -EINVAL;
+
ret = drm_framebuffer_init(dev, _fb->base, _fb_funcs);
if (ret) {
DRM_ERROR("framebuffer init failed %d\n", ret);
-- 
1.7.8.6



[PATCH 22/51] drm/i915: Check framebuffer stride more thoroughly

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Make sure the the framebuffer stride is smaller than the maximum
accepted by any plane.

Also when using a tiled memory make sure the object stride matches
the framebuffer stride.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/intel_display.c |   18 ++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 2dd19f3..581772c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7712,6 +7712,17 @@ static const struct drm_framebuffer_funcs intel_fb_funcs 
= {
.create_handle = intel_user_framebuffer_create_handle,
 };

+static unsigned int intel_max_fb_stride(const struct drm_device *dev)
+{
+   /* FIXME: BSpec for pre-Gen5 is a bit unclear on stride limits */
+   if (INTEL_INFO(dev)->gen <= 3)
+   return 8192;
+   else if (INTEL_INFO(dev)->gen <= 4)
+   return 16384;
+   else
+   return 32768;
+}
+
 int intel_framebuffer_init(struct drm_device *dev,
   struct intel_framebuffer *intel_fb,
   struct drm_mode_fb_cmd2 *mode_cmd,
@@ -7725,6 +7736,13 @@ int intel_framebuffer_init(struct drm_device *dev,
if (mode_cmd->pitches[0] & 63)
return -EINVAL;

+   if (mode_cmd->pitches[0] > intel_max_fb_stride(dev))
+   return -EINVAL;
+
+   if (obj->tiling_mode != I915_TILING_NONE &&
+   mode_cmd->pitches[0] != obj->stride)
+   return -EINVAL;
+
/* Reject formats not supported by any plane early. */
switch (mode_cmd->pixel_format) {
case DRM_FORMAT_C8:
-- 
1.7.8.6



[PATCH 21/51] drm/i915: Implement execbuffer wait for all planes

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Add the MI_WAIT_FOR_EVENT bits for sprites, and fix up the whole thing
for IVB which moved most of the bits around.

Not tested at all!

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |   44 +--
 drivers/gpu/drm/i915/i915_reg.h|9 ++
 2 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 3eea143..cb4d9f7 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -625,10 +625,46 @@ i915_gem_execbuffer_wait_for_flips(struct 
intel_ring_buffer *ring, u32 flips)
if (((flips >> plane) & 1) == 0)
continue;

-   if (plane)
-   flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
-   else
-   flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
+   if (IS_GEN7(ring->dev)) {
+   switch (plane) {
+   case 0:
+   flip_mask = MI_WAIT_FOR_PLANE_A_FLIP_IVB;
+   break;
+   case 1:
+   flip_mask = MI_WAIT_FOR_PLANE_B_FLIP_IVB;
+   break;
+   case 2:
+   flip_mask = MI_WAIT_FOR_PLANE_C_FLIP_IVB;
+   break;
+   case 16:
+   flip_mask = MI_WAIT_FOR_SPRITE_A_FLIP_IVB;
+   break;
+   case 17:
+   flip_mask = MI_WAIT_FOR_SPRITE_B_FLIP_IVB;
+   break;
+   case 18:
+   flip_mask = MI_WAIT_FOR_SPRITE_C_FLIP_IVB;
+   break;
+   }
+   } else {
+   switch (plane) {
+   case 0:
+   flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
+   break;
+   case 1:
+   flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
+   break;
+   case 2:
+   flip_mask = MI_WAIT_FOR_PLANE_C_FLIP;
+   break;
+   case 16:
+   flip_mask = MI_WAIT_FOR_SPRITE_A_FLIP;
+   break;
+   case 17:
+   flip_mask = MI_WAIT_FOR_SPRITE_B_FLIP;
+   break;
+   }
+   }

ret = intel_ring_begin(ring, 2);
if (ret)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 5ea4570..6d09411 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -188,7 +188,16 @@
 #define MI_NOOPMI_INSTR(0, 0)
 #define MI_USER_INTERRUPT  MI_INSTR(0x02, 0)
 #define MI_WAIT_FOR_EVENT   MI_INSTR(0x03, 0)
+#define   MI_WAIT_FOR_SPRITE_C_FLIP_IVB(1<<20)
+#define   MI_WAIT_FOR_PLANE_C_FLIP_IVB (1<<15)
+#define   MI_WAIT_FOR_SPRITE_B_FLIP_IVB(1<<10)
+#define   MI_WAIT_FOR_PLANE_B_FLIP_IVB (1<<9)
+#define   MI_WAIT_FOR_SPRITE_A_FLIP_IVB(1<<2)
+#define   MI_WAIT_FOR_PLANE_A_FLIP_IVB (1<<1)
 #define   MI_WAIT_FOR_OVERLAY_FLIP (1<<16)
+#define   MI_WAIT_FOR_SPRITE_B_FLIP(1<<16)
+#define   MI_WAIT_FOR_SPRITE_A_FLIP(1<<8)
+#define   MI_WAIT_FOR_PLANE_C_FLIP (1<<8)
 #define   MI_WAIT_FOR_PLANE_B_FLIP  (1<<6)
 #define   MI_WAIT_FOR_PLANE_A_FLIP  (1<<2)
 #define   MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
-- 
1.7.8.6



[PATCH 20/51] drm/i915: Add SURFLIVE register definitions

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/i915_reg.h |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index c2e82cc..5ea4570 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3031,6 +3031,7 @@
 #define _DSPASIZE  0x70190
 #define _DSPASURF  0x7019C /* 965+ only */
 #define _DSPATILEOFF   0x701A4 /* 965+ only */
+#define _DSPASURFLIVE  0x701AC

 #define DSPCNTR(plane) _PIPE(plane, _DSPACNTR, _DSPBCNTR)
 #define DSPADDR(plane) _PIPE(plane, _DSPAADDR, _DSPBADDR)
@@ -3040,6 +3041,7 @@
 #define DSPSURF(plane) _PIPE(plane, _DSPASURF, _DSPBSURF)
 #define DSPTILEOFF(plane) _PIPE(plane, _DSPATILEOFF, _DSPBTILEOFF)
 #define DSPLINOFF(plane) DSPADDR(plane)
+#define DSPSURFLIVE(plane) _PIPE(plane, _DSPASURFLIVE, _DSPBSURFLIVE)

 /* Display/Sprite base address macros */
 #define DISP_BASEADDR_MASK (0xf000)
@@ -3085,6 +3087,7 @@
 #define _DSPBSIZE  0x71190
 #define _DSPBSURF  0x7119C
 #define _DSPBTILEOFF   0x711A4
+#define _DSPBSURFLIVE  0x711AC

 /* Sprite A control */
 #define _DVSACNTR  0x72180
@@ -3150,6 +3153,7 @@
 #define DVSTILEOFF(pipe) _PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF)
 #define DVSKEYVAL(pipe) _PIPE(pipe, _DVSAKEYVAL, _DVSBKEYVAL)
 #define DVSKEYMSK(pipe) _PIPE(pipe, _DVSAKEYMSK, _DVSBKEYMSK)
+#define DVSSURFLIVE(pipe) _PIPE(pipe, _DVSASURFLIVE, _DVSBSURFLIVE)

 #define _SPRA_CTL  0x70280
 #define   SPRITE_ENABLE(1<<31)
@@ -3184,6 +3188,7 @@
 #define _SPRA_SURF 0x7029c
 #define _SPRA_KEYMAX   0x702a0
 #define _SPRA_TILEOFF  0x702a4
+#define _SPRA_SURFLIVE 0x702ac
 #define _SPRA_SCALE0x70304
 #define   SPRITE_SCALE_ENABLE  (1<<31)
 #define   SPRITE_FILTER_MASK   (3<<29)
@@ -3204,6 +3209,7 @@
 #define _SPRB_SURF 0x7129c
 #define _SPRB_KEYMAX   0x712a0
 #define _SPRB_TILEOFF  0x712a4
+#define _SPRB_SURFLIVE 0x712ac
 #define _SPRB_SCALE0x71304
 #define _SPRB_GAMC 0x71400

@@ -3219,6 +3225,7 @@
 #define SPRTILEOFF(pipe) _PIPE(pipe, _SPRA_TILEOFF, _SPRB_TILEOFF)
 #define SPRSCALE(pipe) _PIPE(pipe, _SPRA_SCALE, _SPRB_SCALE)
 #define SPRGAMC(pipe) _PIPE(pipe, _SPRA_GAMC, _SPRB_GAMC)
+#define SPRSURFLIVE(pipe) _PIPE(pipe, _SPRA_SURFLIVE, _SPRB_SURFLIVE)

 /* VBIOS regs */
 #define VGACNTRL   0x71400
-- 
1.7.8.6



[PATCH 19/51] drm/i915: Fix display pixel format handling

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Fix support for all RGB/BGR pixel formats (except the 16:16:16:16 float
format).

Fix intel_init_framebuffer() to match hardware and driver limitations:
* RGB332 is not supported at all
* CI8 is supported
* XRGB1555 & co. are supported on Gen3 and earlier
* XRGB210101010 & co. are supported from Gen4 onwards
* BGR formats are supported from Gen4 onwards
* YUV formats are supported from Gen5 onwards (driver limitation)

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/i915/i915_reg.h  |   17 --
 drivers/gpu/drm/i915/intel_display.c |   94 ++
 2 files changed, 74 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index a4162dd..c2e82cc 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2998,12 +2998,19 @@
 #define   DISPPLANE_GAMMA_ENABLE   (1<<30)
 #define   DISPPLANE_GAMMA_DISABLE  0
 #define   DISPPLANE_PIXFORMAT_MASK (0xf<<26)
+#define   DISPPLANE_YUV422 (0x0<<26)
 #define   DISPPLANE_8BPP   (0x2<<26)
-#define   DISPPLANE_15_16BPP   (0x4<<26)
-#define   DISPPLANE_16BPP  (0x5<<26)
-#define   DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
-#define   DISPPLANE_32BPP  (0x7<<26)
-#define   DISPPLANE_32BPP_30BIT_NO_ALPHA   (0xa<<26)
+#define   DISPPLANE_BGRA555(0x3<<26)
+#define   DISPPLANE_BGRX555(0x4<<26)
+#define   DISPPLANE_BGRX565(0x5<<26)
+#define   DISPPLANE_BGRX888(0x6<<26)
+#define   DISPPLANE_BGRA888(0x7<<26)
+#define   DISPPLANE_RGBX101010 (0x8<<26)
+#define   DISPPLANE_RGBA101010 (0x9<<26)
+#define   DISPPLANE_BGRX101010 (0xa<<26)
+#define   DISPPLANE_RGBX161616 (0xc<<26)
+#define   DISPPLANE_RGBX888(0xe<<26)
+#define   DISPPLANE_RGBA888(0xf<<26)
 #define   DISPPLANE_STEREO_ENABLE  (1<<25)
 #define   DISPPLANE_STEREO_DISABLE 0
 #define   DISPPLANE_SEL_PIPE_SHIFT 24
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 461a637..2dd19f3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1969,24 +1969,38 @@ static int i9xx_update_plane(struct drm_crtc *crtc, 
struct drm_framebuffer *fb,
dspcntr = I915_READ(reg);
/* Mask out pixel format bits in case we change it */
dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
-   switch (fb->bits_per_pixel) {
-   case 8:
+   switch (fb->pixel_format) {
+   case DRM_FORMAT_C8:
dspcntr |= DISPPLANE_8BPP;
break;
-   case 16:
-   if (fb->depth == 15)
-   dspcntr |= DISPPLANE_15_16BPP;
-   else
-   dspcntr |= DISPPLANE_16BPP;
+   case DRM_FORMAT_XRGB1555:
+   case DRM_FORMAT_ARGB1555:
+   dspcntr |= DISPPLANE_BGRX555;
break;
-   case 24:
-   case 32:
-   dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
+   case DRM_FORMAT_RGB565:
+   dspcntr |= DISPPLANE_BGRX565;
+   break;
+   case DRM_FORMAT_XRGB:
+   case DRM_FORMAT_ARGB:
+   dspcntr |= DISPPLANE_BGRX888;
+   break;
+   case DRM_FORMAT_XBGR:
+   case DRM_FORMAT_ABGR:
+   dspcntr |= DISPPLANE_RGBX888;
+   break;
+   case DRM_FORMAT_XRGB2101010:
+   case DRM_FORMAT_ARGB2101010:
+   dspcntr |= DISPPLANE_BGRX101010;
+   break;
+   case DRM_FORMAT_XBGR2101010:
+   case DRM_FORMAT_ABGR2101010:
+   dspcntr |= DISPPLANE_RGBX101010;
break;
default:
-   DRM_ERROR("Unknown color depth %d\n", fb->bits_per_pixel);
+   DRM_ERROR("Unknown pixel format 0x%08x\n", fb->pixel_format);
return -EINVAL;
}
+
if (INTEL_INFO(dev)->gen >= 4) {
if (obj->tiling_mode != I915_TILING_NONE)
dspcntr |= DISPPLANE_TILED;
@@ -2053,27 +2067,31 @@ static int ironlake_update_plane(struct drm_crtc *crtc,
dspcntr = I915_READ(reg);
/* Mask out pixel format bits in case we change it */
dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
-   switch (fb->bits_per_pixel) {
-   case 8:
+   switch (fb->pixel_format) {
+   case DRM_FORMAT_C8:
dspcntr |= DISPPLANE_8BPP;
break;
-   case 16:
-   if (fb->depth != 16)
-   return -EINVAL;
-
-   dspcntr |= DISPPLANE_16BPP;
+   case DRM_FORMAT_RGB565:
+   dspcntr |= DISPPLANE_BGRX565;
break;
-   

[PATCH 18/51] drm: Add the atomic modeset ioctl

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

This new ioctl can be used to update an arbitrary set of object
properties in one operation.

The ioctl simply takes a list of object IDs and property IDs and their
values. For setting values of blob properties, the property value
indicates the length of the data, and the actual data is passed via
another blob pointer.

Three flags are currently supported to alter the behaviour of the ioctl:
- DRM_MODE_ATOMIC_TEST_ONLY indicates that the new state chould only be
  checked for validity, but not hardware state is to be modified.
- DRM_MODE_ATOMIC_EVENT requests that asynchronous completion events be
  sent back to user space. A new event type is added for this purpose.
- DRM_MODE_ATOMIC_NONBLOCK indicates that the operation must be
  completed asynchronously without blocking the the caller for
  significant amounts of time.

Internally the driver must implement the functions pointers in struct
drm_atomic_funcs to support the new ioctl.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c  |  146 +++
 drivers/gpu/drm/drm_drv.c   |1 +
 include/drm/drmP.h  |8 +++
 include/drm/drm_crtc.h  |   13 
 include/uapi/drm/drm.h  |   12 
 include/uapi/drm/drm_mode.h |   17 +
 6 files changed, 197 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 7a6ed7d..4736cfe 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -4236,3 +4236,149 @@ int drm_calc_vscale(struct drm_region *src, struct 
drm_region *dst,
return vscale;
 }
 EXPORT_SYMBOL(drm_calc_vscale);
+
+int drm_mode_atomic_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
+{
+   struct drm_mode_atomic *arg = data;
+   uint32_t __user *objs_ptr = (uint32_t __user *)(unsigned 
long)(arg->objs_ptr);
+   uint32_t __user *count_props_ptr = (uint32_t __user *)(unsigned 
long)(arg->count_props_ptr);
+   uint32_t __user *props_ptr = (uint32_t __user *)(unsigned 
long)(arg->props_ptr);
+   uint64_t __user *prop_values_ptr = (uint64_t __user *)(unsigned 
long)(arg->prop_values_ptr);
+   uint64_t __user *blob_values_ptr = (uint64_t __user *)(unsigned 
long)(arg->blob_values_ptr);
+   unsigned int copied_objs = 0;
+   unsigned int copied_props = 0;
+   unsigned int copied_blobs = 0;
+   void *state;
+   int ret = 0;
+   unsigned int i, j;
+
+   if (!dev->driver->atomic_funcs ||
+   !dev->driver->atomic_funcs->begin ||
+   !dev->driver->atomic_funcs->set ||
+   !dev->driver->atomic_funcs->check ||
+   !dev->driver->atomic_funcs->commit ||
+   !dev->driver->atomic_funcs->end)
+   return -ENOSYS;
+
+   if (arg->flags & ~(DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_EVENT | 
DRM_MODE_ATOMIC_NONBLOCK))
+   return -EINVAL;
+
+   /* can't test and expect an event at the same time. */
+   if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY && arg->flags & 
DRM_MODE_ATOMIC_EVENT)
+   return -EINVAL;
+
+   mutex_lock(>mode_config.mutex);
+
+   state = dev->driver->atomic_funcs->begin(dev, file_priv, arg->flags, 
arg->user_data);
+   if (IS_ERR(state)) {
+   ret = PTR_ERR(state);
+   goto unlock;
+   }
+
+   for (i = 0; i < arg->count_objs; i++) {
+   uint32_t obj_id, count_props;
+   struct drm_mode_object *obj;
+
+   if (get_user(obj_id, objs_ptr + copied_objs)) {
+   ret = -EFAULT;
+   goto out;
+   }
+
+   obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_ANY);
+   if (!obj || !obj->properties) {
+   ret = -ENOENT;
+   goto out;
+   }
+
+   if (get_user(count_props, count_props_ptr + copied_objs)) {
+   ret = -EFAULT;
+   goto out;
+   }
+
+   copied_objs++;
+
+   for (j = 0; j < count_props; j++) {
+   uint32_t prop_id;
+   uint64_t prop_value;
+   struct drm_mode_object *prop_obj;
+   struct drm_property *prop;
+   void *blob_data = NULL;
+
+   if (get_user(prop_id, props_ptr + copied_props)) {
+   ret = -EFAULT;
+   goto out;
+   }
+
+   if (!object_has_prop(obj, prop_id)) {
+   ret = -EINVAL;
+   goto out;
+   }
+
+   prop_obj = drm_mode_object_find(dev, prop_id, 
DRM_MODE_OBJECT_PROPERTY);
+   if (!prop_obj) {
+   ret = -ENOENT;
+ 

[PATCH 17/51] drm: Add mode_blob and connector_ids_blob to drm_crtc

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

These will be ued by standard properties MODE and CONNECTOR_IDS.

Signed-off-by: Ville Syrj?l? 
---
 include/drm/drm_crtc.h |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 710f490..011f51b 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -423,6 +423,9 @@ struct drm_crtc {
void *helper_private;

struct drm_object_properties properties;
+
+   struct drm_property_blob *mode_blob;
+   struct drm_property_blob *connector_ids_blob;
 };


-- 
1.7.8.6



[PATCH 16/51] drm: Add drm_flip helper

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

The drm_flip mechanism can be used to implement robust page flipping
support, and also to synchronize the flips on multiple hardware
scanout engines (eg. CRTCs and overlays).

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/Makefile   |2 +-
 drivers/gpu/drm/drm_flip.c |  376 
 include/drm/drm_flip.h |  244 
 3 files changed, 621 insertions(+), 1 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_flip.c
 create mode 100644 include/drm/drm_flip.h

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 2ff5cef..f98afd8 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -12,7 +12,7 @@ drm-y   :=drm_auth.o drm_buffer.o drm_bufs.o 
drm_cache.o \
drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \
drm_crtc.o drm_modes.o drm_edid.o \
drm_info.o drm_debugfs.o drm_encoder_slave.o \
-   drm_trace_points.o drm_global.o drm_prime.o
+   drm_trace_points.o drm_global.o drm_prime.o drm_flip.o

 drm-$(CONFIG_COMPAT) += drm_ioc32.o
 drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
diff --git a/drivers/gpu/drm/drm_flip.c b/drivers/gpu/drm/drm_flip.c
new file mode 100644
index 000..6ccc3f8
--- /dev/null
+++ b/drivers/gpu/drm/drm_flip.c
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Ville Syrj?l? 
+ */
+
+#include 
+
+static void drm_flip_driver_cleanup(struct work_struct *work)
+{
+   struct drm_flip *flip, *next;
+   struct drm_flip_driver *driver =
+   container_of(work, struct drm_flip_driver, cleanup_work);
+   LIST_HEAD(list);
+
+   spin_lock_irq(>lock);
+
+   list_cut_position(,
+ >cleanup_list,
+ driver->cleanup_list.prev);
+
+   spin_unlock_irq(>lock);
+
+   if (list_empty())
+   return;
+
+   list_for_each_entry_safe(flip, next, , list) {
+   struct drm_flip_helper *helper = flip->helper;
+
+   WARN_ON(!flip->finished);
+
+   helper->funcs->cleanup(flip);
+   }
+}
+
+static void drm_flip_driver_finish(struct work_struct *work)
+{
+   struct drm_flip *flip, *next;
+   struct drm_flip_driver *driver =
+   container_of(work, struct drm_flip_driver, finish_work);
+   LIST_HEAD(list);
+   bool need_cleanup = false;
+
+   spin_lock_irq(>lock);
+
+   list_cut_position(,
+ >finish_list,
+ driver->finish_list.prev);
+
+   spin_unlock_irq(>lock);
+
+   if (list_empty())
+   return;
+
+   list_for_each_entry_safe(flip, next, , list) {
+   struct drm_flip_helper *helper = flip->helper;
+
+   helper->funcs->finish(flip);
+
+   spin_lock_irq(>lock);
+
+   flip->finished = true;
+
+   /*
+* It's possible that drm_flip_set_scanout() was called after we
+* pulled this flip from finish_list, in which case the flip
+* could be in need of cleanup, but not on cleanup_list.
+*/
+   if (flip == helper->scanout_flip) {
+   list_del_init(>list);
+   } else {
+   need_cleanup = true;
+   list_move_tail(>list, >cleanup_list);
+   }
+
+   spin_unlock_irq(>lock);
+   }
+
+   if (need_cleanup)
+   queue_work(driver->wq, >cleanup_work);
+}
+
+static bool drm_flip_set_scanout(struct drm_flip_helper *helper,
+struct drm_flip *flip)
+{
+   struct drm_flip_driver *driver = helper->driver;
+   struct 

[PATCH 15/51] drm: Make blobs resizeable

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

When first allocated blobs can be given a maximum size for which memory
is allocated. Later the data inside the blob can be replaced, assuming
that the maximum size is not exceeded.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |   45 ++-
 include/drm/drm_crtc.h |8 ++-
 2 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 177bc73..7a6ed7d 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2922,6 +2922,9 @@ void drm_property_destroy(struct drm_device *dev, struct 
drm_property *property)
 {
struct drm_property_enum *prop_enum, *pt;

+   if (!property)
+   return;
+
list_for_each_entry_safe(prop_enum, pt, >enum_blob_list, 
head) {
list_del(_enum->head);
kfree(prop_enum);
@@ -3111,16 +3114,24 @@ done:
return ret;
 }

-struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int 
length,
-  void *data)
+struct drm_property_blob *drm_property_create_blob(struct drm_device *dev,
+  unsigned int length,
+  unsigned int max_length,
+  const void *data)
 {
struct drm_property_blob *blob;
int ret;

-   if (!length || !data)
+   if (!!length != !!data)
return NULL;

-   blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
+   if (max_length < length)
+   max_length = length;
+
+   if (max_length == 0)
+   return NULL;
+
+   blob = kzalloc(sizeof(struct drm_property_blob)+max_length, GFP_KERNEL);
if (!blob)
return NULL;

@@ -3130,18 +3141,40 @@ struct drm_property_blob 
*drm_property_create_blob(struct drm_device *dev, int l
return NULL;
}

+   blob->max_length = max_length;
blob->length = length;

-   memcpy(blob->data, data, length);
+   if (length)
+   memcpy(blob->data, data, length);

list_add_tail(>head, >mode_config.property_blob_list);
return blob;
 }
 EXPORT_SYMBOL(drm_property_create_blob);

+int drm_property_blob_replace_data(struct drm_property_blob *blob,
+  unsigned int length, const void *data)
+{
+   if (!!length != !!data)
+   return -EINVAL;
+
+   if (length > blob->max_length)
+   return -ENOSPC;
+
+   blob->length = length;
+   if (length)
+   memcpy(blob->data, data, length);
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_property_blob_replace_data);
+
 void drm_property_destroy_blob(struct drm_device *dev,
   struct drm_property_blob *blob)
 {
+   if (!blob)
+   return;
+
drm_mode_object_put(dev, >base);
list_del(>head);
kfree(blob);
@@ -3200,7 +3233,7 @@ int drm_mode_connector_update_edid_property(struct 
drm_connector *connector,

size = EDID_LENGTH * (1 + edid->extensions);
connector->edid_blob_ptr = drm_property_create_blob(connector->dev,
-   size, edid);
+   size, 0, edid);

ret = drm_connector_property_set_value(connector,
   dev->mode_config.edid_property,
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 4830b47..710f490 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -276,6 +276,7 @@ struct drm_property_blob {
struct drm_mode_object base;
struct list_head head;
unsigned int length;
+   unsigned int max_length;
unsigned char data[];
 };

@@ -971,7 +972,12 @@ struct drm_property *drm_property_create_range(struct 
drm_device *dev, int flags
 uint64_t min, uint64_t max);
 extern void drm_property_destroy(struct drm_device *dev, struct drm_property 
*property);
 extern struct drm_property_blob *drm_property_create_blob(struct drm_device 
*dev,
- int length, void 
*data);
+ unsigned int level,
+ unsigned int 
max_length,
+ const void *data);
+extern int drm_property_blob_replace_data(struct drm_property_blob *blob,
+ unsigned int length,
+ const void *data);
 extern void drm_property_destroy_blob(struct drm_device *dev,
  struct 

[PATCH 14/51] drm: Export mode<->umode conversion functions

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Export drm_crtc_convert_to_umode() and drm_crtc_convert_umode().

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |   10 ++
 include/drm/drm_crtc.h |4 
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index ad18e23..177bc73 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1120,8 +1120,8 @@ EXPORT_SYMBOL(drm_mode_config_cleanup);
  * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
  * the user.
  */
-static void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
- const struct drm_display_mode *in)
+void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
+  const struct drm_display_mode *in)
 {
WARN(in->hdisplay > USHRT_MAX || in->hsync_start > USHRT_MAX ||
 in->hsync_end > USHRT_MAX || in->htotal > USHRT_MAX ||
@@ -1147,6 +1147,7 @@ static void drm_crtc_convert_to_umode(struct 
drm_mode_modeinfo *out,
strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
 }
+EXPORT_SYMBOL(drm_crtc_convert_to_umode);

 /**
  * drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode
@@ -1162,8 +1163,8 @@ static void drm_crtc_convert_to_umode(struct 
drm_mode_modeinfo *out,
  * RETURNS:
  * Zero on success, errno on failure.
  */
-static int drm_crtc_convert_umode(struct drm_display_mode *out,
- const struct drm_mode_modeinfo *in)
+int drm_crtc_convert_umode(struct drm_display_mode *out,
+  const struct drm_mode_modeinfo *in)
 {
if (in->clock > INT_MAX || in->vrefresh > INT_MAX)
return -ERANGE;
@@ -1187,6 +1188,7 @@ static int drm_crtc_convert_umode(struct drm_display_mode 
*out,

return 0;
 }
+EXPORT_SYMBOL(drm_crtc_convert_umode);

 /**
  * drm_mode_getresources - get graphics configuration
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 45f56ce..4830b47 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1087,6 +1087,10 @@ extern int drm_format_num_planes(uint32_t format);
 extern int drm_format_plane_cpp(uint32_t format, int plane);
 extern int drm_format_horz_chroma_subsampling(uint32_t format);
 extern int drm_format_vert_chroma_subsampling(uint32_t format);
+extern void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
+ const struct drm_display_mode *in);
+extern int drm_crtc_convert_umode(struct drm_display_mode *out,
+ const struct drm_mode_modeinfo *in);

 /**
  * drm_region - two dimensional region
-- 
1.7.8.6



[PATCH 13/51] drm: Refactor object property check code

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Refactor the code to check whether an object has a specific property
to a new function.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |   20 ++--
 1 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 1a7a6aa..ad18e23 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3368,6 +3368,19 @@ out:
return ret;
 }

+static bool object_has_prop(const struct drm_mode_object *obj, u32 prop_id)
+{
+   int i;
+
+   if (!obj->properties)
+   return false;
+
+   for (i = 0; i < obj->properties->count; i++)
+   if (obj->properties->ids[i] == prop_id)
+   return true;
+   return false;
+}
+
 int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
 {
@@ -3376,7 +3389,6 @@ int drm_mode_obj_set_property_ioctl(struct drm_device 
*dev, void *data,
struct drm_mode_object *prop_obj;
struct drm_property *property;
int ret = -EINVAL;
-   int i;

if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
@@ -3389,11 +3401,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device 
*dev, void *data,
if (!arg_obj->properties)
goto out;

-   for (i = 0; i < arg_obj->properties->count; i++)
-   if (arg_obj->properties->ids[i] == arg->prop_id)
-   break;
-
-   if (i == arg_obj->properties->count)
+   if (!object_has_prop(arg_obj, arg->prop_id))
goto out;

prop_obj = drm_mode_object_find(dev, arg->prop_id,
-- 
1.7.8.6



[PATCH 12/51] drm: Export drm_crtc_prepare_encoders()

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

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

diff --git a/drivers/gpu/drm/drm_crtc_helper.c 
b/drivers/gpu/drm/drm_crtc_helper.c
index d30e0dd..80bbbda 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -307,7 +307,7 @@ EXPORT_SYMBOL(drm_encoder_crtc_ok);
  * CRTC.  If they don't match, we have to disable the output and the CRTC
  * since the driver will have to re-route things.
  */
-static void
+void
 drm_crtc_prepare_encoders(struct drm_device *dev)
 {
struct drm_encoder_helper_funcs *encoder_funcs;
@@ -324,6 +324,7 @@ drm_crtc_prepare_encoders(struct drm_device *dev)
drm_encoder_disable(encoder);
}
 }
+EXPORT_SYMBOL(drm_crtc_prepare_encoders);

 /**
  * drm_crtc_set_mode - set a mode
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index a17285c..d3be5ae 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -168,5 +168,6 @@ extern void drm_kms_helper_poll_enable(struct drm_device 
*dev);

 extern bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
struct drm_crtc *crtc);
+extern void drm_crtc_prepare_encoders(struct drm_device *dev);

 #endif
-- 
1.7.8.6



[PATCH 11/51] drm: Export drm_encoder_crtc_ok

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

---
 drivers/gpu/drm/drm_crtc_helper.c |5 +++--
 include/drm/drm_crtc_helper.h |3 +++
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc_helper.c 
b/drivers/gpu/drm/drm_crtc_helper.c
index 1227adf..d30e0dd 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -279,8 +279,8 @@ EXPORT_SYMBOL(drm_helper_disable_unused_functions);
  *
  * Return false if @encoder can't be driven by @crtc, true otherwise.
  */
-static bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
-   struct drm_crtc *crtc)
+bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
+struct drm_crtc *crtc)
 {
struct drm_device *dev;
struct drm_crtc *tmp;
@@ -300,6 +300,7 @@ static bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
return true;
return false;
 }
+EXPORT_SYMBOL(drm_encoder_crtc_ok);

 /*
  * Check the CRTC we're going to map each output to vs. its current
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index e01cc80..a17285c 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -166,4 +166,7 @@ extern void drm_helper_hpd_irq_event(struct drm_device 
*dev);
 extern void drm_kms_helper_poll_disable(struct drm_device *dev);
 extern void drm_kms_helper_poll_enable(struct drm_device *dev);

+extern bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
+   struct drm_crtc *crtc);
+
 #endif
-- 
1.7.8.6



[PATCH 10/51] drm: Allow drm_mode_object_find() to look up an object of any type

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

To avoid having to pass object types from userspace for atomic mode
setting ioctl, allow drm_mode_object_find() to look up an object of any
type. This will only work as long as the all object types share the ID
space.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |3 ++-
 include/drm/drm_crtc.h |1 +
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 8ee7e45..1a7a6aa 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -267,7 +267,8 @@ struct drm_mode_object *drm_mode_object_find(struct 
drm_device *dev,

mutex_lock(>mode_config.idr_mutex);
obj = idr_find(>mode_config.crtc_idr, id);
-   if (!obj || (obj->type != type) || (obj->id != id))
+   if (!obj || (type != DRM_MODE_OBJECT_ANY && obj->type != type) ||
+   (obj->id != id))
obj = NULL;
mutex_unlock(>mode_config.idr_mutex);

diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 8eb04c9..45f56ce 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -48,6 +48,7 @@ struct drm_object_properties;
 #define DRM_MODE_OBJECT_FB 0xfbfbfbfb
 #define DRM_MODE_OBJECT_BLOB 0x
 #define DRM_MODE_OBJECT_PLANE 0x
+#define DRM_MODE_OBJECT_ANY 0

 struct drm_mode_object {
uint32_t id;
-- 
1.7.8.6



[PATCH 09/51] drm: Allow signed values for range properties

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Treat a range property as signed when the unsigned minimum value is
larger than the unsigned maximum value.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |   17 ++---
 1 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index ddd7252..8ee7e45 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3207,14 +3207,25 @@ int drm_mode_connector_update_edid_property(struct 
drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_mode_connector_update_edid_property);

-static bool drm_property_change_is_valid(struct drm_property *property,
+static bool range_property_is_signed(const struct drm_property *property)
+{
+   return property->values[0] > property->values[1];
+}
+
+static bool drm_property_change_is_valid(const struct drm_property *property,
 uint64_t value)
 {
if (property->flags & DRM_MODE_PROP_IMMUTABLE)
return false;
if (property->flags & DRM_MODE_PROP_RANGE) {
-   if (value < property->values[0] || value > property->values[1])
-   return false;
+   if (range_property_is_signed(property)) {
+   if ((int64_t)value < (int64_t)property->values[0] ||
+   (int64_t)value > (int64_t)property->values[1])
+   return false;
+   } else {
+   if (value < property->values[0] || value > 
property->values[1])
+   return false;
+   }
return true;
} else if (property->flags & DRM_MODE_PROP_BITMASK) {
int i;
-- 
1.7.8.6



[PATCH 08/51] drm: Export drm_property_create_blob() and drm_property_destroy_blob()

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |8 +---
 include/drm/drm_crtc.h |4 
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index d5ceff0..ddd7252 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3108,8 +3108,8 @@ done:
return ret;
 }

-static struct drm_property_blob *drm_property_create_blob(struct drm_device 
*dev, int length,
- void *data)
+struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int 
length,
+  void *data)
 {
struct drm_property_blob *blob;
int ret;
@@ -3134,14 +3134,16 @@ static struct drm_property_blob 
*drm_property_create_blob(struct drm_device *dev
list_add_tail(>head, >mode_config.property_blob_list);
return blob;
 }
+EXPORT_SYMBOL(drm_property_create_blob);

-static void drm_property_destroy_blob(struct drm_device *dev,
+void drm_property_destroy_blob(struct drm_device *dev,
   struct drm_property_blob *blob)
 {
drm_mode_object_put(dev, >base);
list_del(>head);
kfree(blob);
 }
+EXPORT_SYMBOL(drm_property_destroy_blob);

 int drm_mode_getblob_ioctl(struct drm_device *dev,
   void *data, struct drm_file *file_priv)
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 6a66704..8eb04c9 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -969,6 +969,10 @@ struct drm_property *drm_property_create_range(struct 
drm_device *dev, int flags
 const char *name,
 uint64_t min, uint64_t max);
 extern void drm_property_destroy(struct drm_device *dev, struct drm_property 
*property);
+extern struct drm_property_blob *drm_property_create_blob(struct drm_device 
*dev,
+ int length, void 
*data);
+extern void drm_property_destroy_blob(struct drm_device *dev,
+ struct drm_property_blob *blob);
 extern int drm_property_add_enum(struct drm_property *property, int index,
 uint64_t value, const char *name);
 extern int drm_mode_create_dvi_i_properties(struct drm_device *dev);
-- 
1.7.8.6



[PATCH 07/51] drm: Add restore_fbdev_mode() hook to drm_fb_helper

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Add an optional driver specific restore_fbdev_mode() hook to
drm_fb_helper. If the driver doesn't provide the hook,
drm_fb_helper_restore_fbdev_mode() is called directly as before.

In this hook the driver can disable additional planes, cursors etc.
that shouldn't be visible while fbdev is in control.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_fb_helper.c |5 -
 include/drm/drm_fb_helper.h |1 +
 2 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 4d58d7e..082a837 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -248,7 +248,10 @@ static bool drm_fb_helper_force_kernel_mode(void)
if (helper->dev->switch_power_state == DRM_SWITCH_POWER_OFF)
continue;

-   ret = drm_fb_helper_restore_fbdev_mode(helper);
+   if (helper->funcs->restore_fbdev_mode)
+   ret = helper->funcs->restore_fbdev_mode(helper);
+   else
+   ret = drm_fb_helper_restore_fbdev_mode(helper);
if (ret)
error = true;
}
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 5120b01..7f76e9c 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -56,6 +56,7 @@ struct drm_fb_helper_funcs {

int (*fb_probe)(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes);
+   int (*restore_fbdev_mode)(struct drm_fb_helper *helper);
 };

 struct drm_fb_helper_connector {
-- 
1.7.8.6



[PATCH 06/51] drm: Keep a copy of last plane coordinates

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

If the update_plane() operation succeeds, make a copy of the requested
src and crtc coordinates, so that the the plane may be reclipped if the
display mode changed later.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |8 
 include/drm/drm_crtc.h |4 
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index c0b064e..d5ceff0 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1853,6 +1853,14 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
if (!ret) {
plane->crtc = crtc;
plane->fb = fb;
+   plane->crtc_x = plane_req->crtc_x;
+   plane->crtc_y = plane_req->crtc_y;
+   plane->crtc_w = plane_req->crtc_w;
+   plane->crtc_h = plane_req->crtc_h;
+   plane->src_x = plane_req->src_x;
+   plane->src_y = plane_req->src_y;
+   plane->src_w = plane_req->src_w;
+   plane->src_h = plane_req->src_h;
}

 out:
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index bc89654..6a66704 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -672,6 +672,10 @@ struct drm_plane {
void *helper_private;

struct drm_object_properties properties;
+
+   uint32_t src_x, src_y, src_w, src_h;
+   int32_t crtc_x, crtc_y;
+   uint32_t crtc_w, crtc_h;
 };

 /**
-- 
1.7.8.6



[PATCH 05/51] drm: Add drm_calc_{hscale, vscale}() utility functions

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |  102 
 include/drm/drm_crtc.h |4 ++
 2 files changed, 106 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index e60beda..c0b064e 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -4069,3 +4069,105 @@ bool drm_region_clip_scaled(struct drm_region *src, 
struct drm_region *dst,
return drm_region_clip(dst, clip);
 }
 EXPORT_SYMBOL(drm_region_clip_scaled);
+
+/**
+ * drm_calc_hscale - calculate the horizontal scaling factor
+ * @src: source window region
+ * @dst: destination window region
+ * @min_hscale: minimum allowed horizontal scaling factor
+ * @max_hscale: maximum allowed horizontal scaling factor
+ *
+ * Calculate the horizontal scaling factor as
+ * (@src width) / (@dst width).
+ *
+ * If the calculated scaling factor is below @min_hscale,
+ * decrease the width of region @dst to compensate.
+ *
+ * If the calculcated scaling factor is above @max_hscale,
+ * decrease the width of region @src to compensate.
+ *
+ * RETURNS:
+ * The horizontal scaling factor.
+ */
+int drm_calc_hscale(struct drm_region *src, struct drm_region *dst,
+   int min_hscale, int max_hscale)
+{
+   int src_w = drm_region_width(src);
+   int dst_w = drm_region_width(dst);
+   int hscale;
+
+   if (dst_w <= 0)
+   return 0;
+
+   hscale = src_w / dst_w;
+
+   if (hscale < min_hscale) {
+   int max_dst_w = src_w / min_hscale;
+
+   drm_region_adjust_size(dst, max_dst_w - dst_w, 0);
+
+   return min_hscale;
+   }
+
+   if (hscale > max_hscale) {
+   int max_src_w = dst_w * max_hscale;
+
+   drm_region_adjust_size(src, max_src_w - src_w, 0);
+
+   return max_hscale;
+   }
+
+   return hscale;
+}
+EXPORT_SYMBOL(drm_calc_hscale);
+
+/**
+ * drm_calc_vscale - calculate the vertical scaling factor
+ * @src: source window region
+ * @dst: destination window region
+ * @min_vscale: minimum allowed vertical scaling factor
+ * @max_vscale: maximum allowed vertical scaling factor
+ *
+ * Calculate the vertical scaling factor as
+ * (@src height) / (@dst height).
+ *
+ * If the calculated scaling factor is below @min_vscale,
+ * decrease the height of region @dst to compensate.
+ *
+ * If the calculcated scaling factor is above @max_vscale,
+ * decrease the height of region @src to compensate.
+ *
+ * RETURNS:
+ * The vertical scaling factor.
+ */
+int drm_calc_vscale(struct drm_region *src, struct drm_region *dst,
+   int min_vscale, int max_vscale)
+{
+   int src_h = drm_region_height(src);
+   int dst_h = drm_region_height(dst);
+   int vscale;
+
+   if (dst_h <= 0)
+   return 0;
+
+   vscale = src_h / dst_h;
+
+   if (vscale < min_vscale) {
+   int max_dst_h = src_h / min_vscale;
+
+   drm_region_adjust_size(dst, 0, max_dst_h - dst_h);
+
+   return min_vscale;
+   }
+
+   if (vscale > max_vscale) {
+   int max_src_h = dst_h * max_vscale;
+
+   drm_region_adjust_size(src, 0, max_src_h - src_h);
+
+   return max_vscale;
+   }
+
+   return vscale;
+}
+EXPORT_SYMBOL(drm_calc_vscale);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 5252c11..bc89654 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1102,5 +1102,9 @@ extern bool drm_region_clip_scaled(struct drm_region *src,
   struct drm_region *dst,
   const struct drm_region *clip,
   int hscale, int vscale);
+extern int drm_calc_hscale(struct drm_region *src, struct drm_region *dst,
+  int min_hscale, int max_hscale);
+extern int drm_calc_vscale(struct drm_region *src, struct drm_region *dst,
+  int min_vscale, int max_vscale);

 #endif /* __DRM_CRTC_H__ */
-- 
1.7.8.6



[PATCH 04/51] drm: Add struct drm_region and assorted utility functions

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

struct drm_region represents a two dimensional region. The utility
functions are there to help driver writers.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |  155 
 include/drm/drm_crtc.h |   24 +++
 2 files changed, 179 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 3533609..e60beda 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3914,3 +3914,158 @@ int drm_format_vert_chroma_subsampling(uint32_t format)
}
 }
 EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);
+
+/**
+ * drm_region_adjust_size - adjust the size of the region
+ * @r: region to be adjusted
+ * @x: horizontal adjustment
+ * @y: vertical adjustment
+ *
+ * Change the size of region @r by @x in the horizontal direction,
+ * and by @y in the vertical direction, while keeping the center
+ * of @r stationary.
+ *
+ * Positive @x and @y increase the size, negative values decrease it.
+ */
+void drm_region_adjust_size(struct drm_region *r, int x, int y)
+{
+   r->x1 -= x >> 1;
+   r->y1 -= y >> 1;
+   r->x2 += (x + 1) >> 1;
+   r->y2 += (y + 1) >> 1;
+}
+EXPORT_SYMBOL(drm_region_adjust_size);
+
+/**
+ * drm_region_translate - translate the region
+ * @r: region to be tranlated
+ * @x: horizontal translation
+ * @y: vertical translation
+ *
+ * Move region @r by @x in the horizontal direction,
+ * and by @y in the vertical direction.
+ */
+void drm_region_translate(struct drm_region *r, int x, int y)
+{
+   r->x1 += x;
+   r->y1 += y;
+   r->x2 += x;
+   r->y2 += y;
+}
+EXPORT_SYMBOL(drm_region_translate);
+
+/**
+ * drm_region_subsample - subsample a region
+ * @r: region to be subsampled
+ * @hsub: horizontal subsampling factor
+ * @vsub: vertical subsampling factor
+ *
+ * Divide the coordinates of region @r by @hsub and @vsub.
+ */
+void drm_region_subsample(struct drm_region *r, int hsub, int vsub)
+{
+   r->x1 /= hsub;
+   r->y1 /= vsub;
+   r->x2 /= hsub;
+   r->y2 /= vsub;
+}
+EXPORT_SYMBOL(drm_region_subsample);
+
+/**
+ * drm_region_width - determine the region width
+ * @r: region whose width is returned
+ *
+ * RETURNS:
+ * The width of the region.
+ */
+int drm_region_width(const struct drm_region *r)
+{
+   return r->x2 - r->x1;
+}
+EXPORT_SYMBOL(drm_region_width);
+
+/**
+ * drm_region_height - determine the region height
+ * @r: region whose height is returned
+ *
+ * RETURNS:
+ * The height of the region.
+ */
+int drm_region_height(const struct drm_region *r)
+{
+   return r->y2 - r->y1;
+}
+EXPORT_SYMBOL(drm_region_height);
+
+/**
+ * drm_region_visible - determine if the the region is visible
+ * @r: region whose visibility is returned
+ *
+ * RETURNS:
+ * @true if the region is visible, @false otherwise.
+ */
+bool drm_region_visible(const struct drm_region *r)
+{
+   return drm_region_width(r) > 0 && drm_region_height(r) > 0;
+}
+EXPORT_SYMBOL(drm_region_visible);
+
+/**
+ * drm_region_clip - clip one region by another region
+ * @r: region to be clipped
+ * @clip: clip region
+ *
+ * Clip region @r by region @clip.
+ *
+ * RETURNS:
+ * @true if the region is still visible after being clipped,
+ * @false otherwise.
+ */
+bool drm_region_clip(struct drm_region *r, const struct drm_region *clip)
+{
+   r->x1 = max(r->x1, clip->x1);
+   r->y1 = max(r->y1, clip->y1);
+   r->x2 = min(r->x2, clip->x2);
+   r->y2 = min(r->y2, clip->y2);
+
+   return drm_region_visible(r);
+}
+EXPORT_SYMBOL(drm_region_clip);
+
+/**
+ * drm_region_clip_scaled - perform a scaled clip operation
+ * @src: source window region
+ * @dst: destination window region
+ * @clip: clip region
+ * @hscale: horizontal scaling factor
+ * @vscale: vertical scaling factor
+ *
+ * Clip region @dst by region @clip. Clip region @src by the same
+ * amounts multiplied by @hscale and @vscale.
+ *
+ * RETUTRNS:
+ * @true if region @dst is still visible after being clipped,
+ * @false otherwise
+ */
+bool drm_region_clip_scaled(struct drm_region *src, struct drm_region *dst,
+   const struct drm_region *clip,
+   int hscale, int vscale)
+{
+   int diff;
+
+   diff = clip->x1 - dst->x1;
+   if (diff > 0)
+   src->x1 += diff * hscale;
+   diff = clip->y1 - dst->y1;
+   if (diff > 0)
+   src->y1 += diff * vscale;
+   diff = dst->x2 - clip->x2;
+   if (diff > 0)
+   src->x2 -= diff * hscale;
+   diff = dst->y2 - clip->y2;
+   if (diff > 0)
+   src->y2 -= diff * vscale;
+
+   return drm_region_clip(dst, clip);
+}
+EXPORT_SYMBOL(drm_region_clip_scaled);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 49dd8c2..5252c11 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1079,4 +1079,28 @@ extern int 

[PATCH 03/51] drm: Ignore blob propertys in drm_property_change_is_valid()

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

In case of a blob property drm_property_change_is_valid() can't
tell whether the change is valid or not. So just return true
for all blob properties, and leave it up to someone else to
check it.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index d9a639c..3533609 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3212,6 +3212,9 @@ static bool drm_property_change_is_valid(struct 
drm_property *property,
for (i = 0; i < property->num_values; i++)
valid_mask |= (1ULL << property->values[i]);
return !(value & ~valid_mask);
+   } else if (property->flags & DRM_MODE_PROP_BLOB) {
+   /* Only the driver knows */
+   return true;
} else {
int i;
for (i = 0; i < property->num_values; i++)
-- 
1.7.8.6



[PATCH 02/51] drm: Constify some function arguments

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

None of drm_mode_debug_printmodeline(), drm_mode_equal(), drm_mode_width()
or drm_mode_height() change the mode passed in, so make the arguments
const.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_modes.c |8 
 include/drm/drm_crtc.h  |8 
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 59450f3..d8da30e 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -46,7 +46,7 @@
  *
  * Describe @mode using DRM_DEBUG.
  */
-void drm_mode_debug_printmodeline(struct drm_display_mode *mode)
+void drm_mode_debug_printmodeline(const struct drm_display_mode *mode)
 {
DRM_DEBUG_KMS("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d "
"0x%x 0x%x\n",
@@ -558,7 +558,7 @@ EXPORT_SYMBOL(drm_mode_list_concat);
  * RETURNS:
  * @mode->hdisplay
  */
-int drm_mode_width(struct drm_display_mode *mode)
+int drm_mode_width(const struct drm_display_mode *mode)
 {
return mode->hdisplay;

@@ -579,7 +579,7 @@ EXPORT_SYMBOL(drm_mode_width);
  * RETURNS:
  * @mode->vdisplay
  */
-int drm_mode_height(struct drm_display_mode *mode)
+int drm_mode_height(const struct drm_display_mode *mode)
 {
return mode->vdisplay;
 }
@@ -768,7 +768,7 @@ EXPORT_SYMBOL(drm_mode_duplicate);
  * RETURNS:
  * True if the modes are equal, false otherwise.
  */
-bool drm_mode_equal(struct drm_display_mode *mode1, struct drm_display_mode 
*mode2)
+bool drm_mode_equal(const struct drm_display_mode *mode1, const struct 
drm_display_mode *mode2)
 {
/* do clock check convert to PICOS so fb modes get matched
 * the same */
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 3fa18b7..49dd8c2 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -887,14 +887,14 @@ extern void drm_mode_remove(struct drm_connector 
*connector, struct drm_display_
 extern void drm_mode_copy(struct drm_display_mode *dst, const struct 
drm_display_mode *src);
 extern struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
   const struct 
drm_display_mode *mode);
-extern void drm_mode_debug_printmodeline(struct drm_display_mode *mode);
+extern void drm_mode_debug_printmodeline(const struct drm_display_mode *mode);
 extern void drm_mode_config_init(struct drm_device *dev);
 extern void drm_mode_config_reset(struct drm_device *dev);
 extern void drm_mode_config_cleanup(struct drm_device *dev);
 extern void drm_mode_set_name(struct drm_display_mode *mode);
-extern bool drm_mode_equal(struct drm_display_mode *mode1, struct 
drm_display_mode *mode2);
-extern int drm_mode_width(struct drm_display_mode *mode);
-extern int drm_mode_height(struct drm_display_mode *mode);
+extern bool drm_mode_equal(const struct drm_display_mode *mode1, const struct 
drm_display_mode *mode2);
+extern int drm_mode_width(const struct drm_display_mode *mode);
+extern int drm_mode_height(const struct drm_display_mode *mode);

 /* for us by fb module */
 extern int drm_mode_attachmode_crtc(struct drm_device *dev,
-- 
1.7.8.6



[PATCH 01/51] drm: Be more paranoid with integer overflows

2012-10-25 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Make sure 'width * cpp' and 'height * pitch + offset' don't exceed
UINT_MAX.

Signed-off-by: Ville Syrj?l? 
Reviewed-by: Alex Deucher 
---
 drivers/gpu/drm/drm_crtc.c |   10 +-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index ef1b221..d9a639c 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2280,13 +2280,21 @@ static int framebuffer_check(const struct 
drm_mode_fb_cmd2 *r)

for (i = 0; i < num_planes; i++) {
unsigned int width = r->width / (i != 0 ? hsub : 1);
+   unsigned int height = r->height / (i != 0 ? vsub : 1);
+   unsigned int cpp = drm_format_plane_cpp(r->pixel_format, i);

if (!r->handles[i]) {
DRM_DEBUG_KMS("no buffer object handle for plane %d\n", 
i);
return -EINVAL;
}

-   if (r->pitches[i] < drm_format_plane_cpp(r->pixel_format, i) * 
width) {
+   if ((uint64_t) width * cpp > UINT_MAX)
+   return -ERANGE;
+
+   if ((uint64_t) height * r->pitches[i] + r->offsets[i] > 
UINT_MAX)
+   return -ERANGE;
+
+   if (r->pitches[i] < width * cpp) {
DRM_DEBUG_KMS("bad pitch %u for plane %d\n", 
r->pitches[i], i);
return -EINVAL;
}
-- 
1.7.8.6



[PATCH 00/51] Atomic mode setting and page flip

2012-10-25 Thread ville.syrj...@linux.intel.com
Here's the latest atomic stuff. It's finally starting to look somewhat
reasonable.

I rebased the work on top of drm-fixes as of today.

There are quite a few preparatory patches in the series. Some of those are just
fixes/cleanups that could be pushed independently.

What's still unfinished:
- some integration w/ legacy code paths is missing
  (eg. for the MODE and CONNECTOR_IDS props)
- ioctl blocks until the GPU rendering has caught up. Need to make it fully 
async.
- I took a shortcut w/ danvet's modeset rework new vs. old state logic
- some other ugly bits are probably still left in the code, but I'm starting to 
get
  tunnel vision and some extra eyes on the code wouldn't hurt
- other stuff I might be forgetting...

git repos can be found on gitorious, as usual:
https://gitorious.org/vsyrjala/linux/commits/drm_atomic_15
https://gitorious.org/vsyrjala/drm/commits/drm_atomic_7

A test app of sorts can be found here:
https://gitorious.org/vsyrjala/plane/commits/buffer_tracking

I also made a modifed version of the test app that renders via GL, but I need to
clean that up a bit before I push it. Will do so tomorrow.


Breakage in "track dev_mapping in more robust and flexible way"

2012-10-25 Thread Thomas Hellström
On 10/25/12 7:12 PM, Ilija Hadzic wrote:
> On Thu, Oct 25, 2012 at 11:10 AM, Thomas Hellstr?m
>  wrote:
>> On 10/25/12 4:41 PM, Jerome Glisse wrote:
>>> On Thu, Oct 25, 2012 at 04:02:25PM +0200, Thomas Hellstrom wrote:
 Hi,

 This commit

   From 949c4a34afacfe800fc442afac117aba15284962 Mon Sep 17 00:00:00 2001
 From: Ilija Hadzic 
 Date: Tue, 15 May 2012 16:40:10 -0400
 Subject: [PATCH] drm: track dev_mapping in more robust and flexible way

 Setting dev_mapping (pointer to the address_space structure
 used for memory mappings) to the address_space of the first
 opener's inode and then failing if other openers come in
 through a different inode has a few restrictions that are
 eliminated by this patch.

 If we already have valid dev_mapping and we spot an opener
 with different i_node, we force its i_mapping pointer to the
 already established address_space structure (first opener's
 inode). This will make all mappings from drm device hang off
 the same address_space object.
 ...

 Breaks drivers using TTM, since when the X server calls into the
 driver open, drm's dev_mapping has not
 yet been setup. The setup needs to be moved before the driver's open
 hook is called.

 Typically, if a TTM-aware driver is provoked by the Xorg server to
 move a buffer from system to VRAM or AGP,
 before any other drm client is started, The user-space page table
 entries are not killed before the move, and left pointing
 into freed pages, causing system crashes and / or user-space access
 to arbitrary memory.
>>> Doesn't handle move invalidate the drm file mapping before scheduling
>>> the move ?
>> Yes, but to do that it needs a correct value of bdev::dev_mapping, which is
>> now incorrectly set on the
>> *second* open instead of the first open.
>>
> So you are implying that in the first open the assignment of dev->dev_mapping 
> is
> somehow skipped (which could happen if drm_setup returns an error) or that the
> driver on which you are having problems with (nouveau I presume) needs
> dev_mapping
> in the firstopen hook ?
No. On open, driver::open is called from drm::open. It copies the value 
of dev->dev_mapping, however,
driver::open is called *before* dev->dev_mapping is set up, so what I'm 
saying is that the setup of
dev->dev_mapping must be moved to before driver::open is called from 
drm::open

(this was hit while testing vmwgfx with new code, BTW. It will be hard, 
but probably possible to trigger
from unpriviliged user-space with the current vmwgfx code.

Thanks,
Thomas



Linux 3.7-rc1 (nouveau_bios_score oops).

2012-10-25 Thread Heinz Diehl
On 25.10.2012, Pawe? Sikora wrote: 

> what is the reason of loading nouveau driver for laptops 
> with nvidia optimus and enabling vga switcheroo
> which doesn't work in such (optimus) cases.

You can safely compile a kernel without nouveau, your Nvidia 
card will not be used at all since neither Linux nor the 
proprietary nvidia driver does support optimus at this time
(and frankly, I won't buy any further machines with opticrap).
So having nouveau compiled and loaded seems like a waste of ressources
in this case.

For me it's important to have nouveau working, because I try/use
Bumblebee and optirun: 

http://bumblebee-project.org/
https://fedoraproject.org/wiki/Bumblebee



[Bug 49531] Powering down inactive GPU while running X causes NULL pointer dereference

2012-10-25 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=49531





--- Comment #4 from Igor Murzov   2012-10-25 19:58:36 ---
I use xorg-server-1.12.3 and i'm not switching GPUs while X is running. I've
tried to power down unused GPU and then kernel crashed. Switching GPUs while X
is running doesn't work:

[ 6514.980755] vga_switcheroo: client 0 refused switch

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


Linux 3.7-rc1 (nouveau_bios_score oops).

2012-10-25 Thread Paweł Sikora
On Saturday 20 of October 2012 11:40:04 Martin Peres wrote:
> On 20/10/2012 11:26, Heinz Diehl wrote:
> > On 20.10.2012, Linus Torvalds wrote:
> >
> >> Added more appropriate people to this. Added both i915 and nouveau
> >> people, since apparently that fine piece of hardware has both.
> >>
> >> Guys, any ideas?
> >
> > Plese see https://lkml.org/lkml/2012/10/19/371 , this is the same
> > thing going on. Reverting
> >
> >   Ben Skeggs 
> >   drm/nouveau/bios: fix shadowing of ACPI ROMs larger than 64KiB
> >
> > fixes the problem.
> 
> Can you test the attached patch too ? I rebased the previous one I sent 
> on top on 3.7-rc1 as I accidentally used an older version.
> 
> Martin

Hi all once again,

i've tested current 3.7.0-rc2-00145-g4864ccb and it works fine (boots and works
with builtin core-i7 intel video) but i have one more question - what is the 
reason
of loading nouveau driver for laptops with nvidia optimus and enabling vga 
switcheroo
which doesn't work in such (optimus) cases. or maybe i've missed something
and switchereoo works with optimus?

BR,
Pawe?.



[Bug 49531] Powering down inactive GPU while running X causes NULL pointer dereference

2012-10-25 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=49531





--- Comment #3 from Alex Deucher   2012-10-25 
19:33:44 ---
Are you using the new dynamic gpu switching stuff in xserver 1.13 or just the
old static switching?

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


[Bug 49531] Powering down inactive GPU while running X causes NULL pointer dereference

2012-10-25 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=49531





--- Comment #2 from Igor Murzov   2012-10-25 19:29:01 ---
Created an attachment (id=84861)
 --> (https://bugzilla.kernel.org/attachment.cgi?id=84861)
Call stack information from GDB

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


[Bug 56405] Distorted graphics on Radeon HD 6620G

2012-10-25 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=56405

--- Comment #1 from Alex Deucher  ---
Can you checkout mesa from git an bisect?  Also please attach your xorg log and
dmesg output.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20121025/31d34926/attachment.html>


[Bug 49531] Powering down inactive GPU while running X causes NULL pointer dereference

2012-10-25 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=49531





--- Comment #1 from Igor Murzov   2012-10-25 18:45:46 ---
Created an attachment (id=84851)
 --> (https://bugzilla.kernel.org/attachment.cgi?id=84851)
lspci -vvv

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


[Bug 49531] New: Powering down inactive GPU while running X causes NULL pointer dereference

2012-10-25 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=49531

   Summary: Powering down inactive GPU while running X causes NULL
pointer dereference
   Product: Drivers
   Version: 2.5
Kernel Version: 3.7.0-rc2+
  Platform: All
OS/Version: Linux
  Tree: Mainline
Status: NEW
  Severity: normal
  Priority: P1
 Component: Video(DRI - non Intel)
AssignedTo: drivers_video-dri at kernel-bugs.osdl.org
ReportedBy: e-mail at date.by
CC: alexdeucher at gmail.com
Regression: No


Created an attachment (id=84841)
 --> (https://bugzilla.kernel.org/attachment.cgi?id=84841)
/var/log/syslog

On my muxed hybrid system (Lenovo IdeaPad U455) vga_switcheroo works fine if X
is not running. But if both GPUs are powered and X is running, then when i try
to power down inactive GPU with

 # echo OFF > /sys/kernel/debug/vgaswitcheroo/switch

kernel crashes after a couple of minutes.
There is an error message in the /var/log/syslog:

 BUG: unable to handle kernel NULL pointer dereference at   (null)
 IP: [] r600_pcie_gart_tlb_flush+0xeb/0x110 [radeon]
 PGD 8d24c067 PUD 8d24b067 PMD 0 
 Oops:  [#1] SMP DEBUG_PAGEALLOC
 Modules linked in: snd_seq_dummy snd_seq_oss snd_seq_midi_event snd_seq
snd_seq_device snd_pcm_oss snd_mixer_oss ipv6 pcmcia pcmcia_core xfs exportfs
ext2 mbcache cpufreq_ondemand mperf lp parport_pc parport fuse uvcvideo
videobuf2_vmalloc videobuf2_memops videobuf2_core videodev media btusb
bluetooth joydev brcmsmac radeon cordic brcmutil mac80211 ttm drm_kms_helper
snd_hda_codec_hdmi snd_hda_codec_conexant drm cfg80211 snd_hda_intel agpgart
snd_hda_codec snd_hwdep sp5100_tco ohci_hcd i2c_piix4 powernow_k8
ideapad_laptop i2c_algo_bit psmouse sparse_keymap snd_pcm ehci_hcd i2c_core
processor freq_table rfkill thermal bcma rtc_cmos atl1c snd_page_alloc
serio_raw k8temp thermal_sys snd_timer shpchp button battery snd soundcore
hwmon evdev ac loop btrfs [last unloaded: pcmcia_core]
 CPU 0 
 Pid: 2291, comm: X Not tainted 3.7.0-rc2+ #70 LENOVO 20046
  /AMD CRB
 RIP: 0010:[]  []
r600_pcie_gart_tlb_flush+0xeb/0x110 [radeon]
 RSP: 0018:8800894d1918  EFLAGS: 00010282
 RAX: c90001322f34 RBX:  RCX: aadfb000
 RDX:  RSI: 2f34 RDI: 8800aad18000
 RBP: 8800894d1928 R08: dfff R09: 00d0
 R10: 00031cd5 R11:  R12: 8800aad18000
 R13: 0219 R14: 0219 R15: 
 FS:  7f8819d618c0() GS:8800afa0() knlGS:
 CS:  0010 DS:  ES:  CR0: 80050033
 CR2:  CR3: 8d18d000 CR4: 07f0
 DR0:  DR1:  DR2: 
 DR3:  DR6: 0ff0 DR7: 0400
 Process X (pid: 2291, threadinfo 8800894d, task 88008d128000)
 Stack:
  8800aad18000 0219 8800894d1958 a043d365
  8800896f1580 8800894d1bc8  8800894d1bc8
  8800894d1968 a043a98a 8800894d1988 a01ef097
 Call Trace:
  [] radeon_gart_unbind+0xa5/0xe0 [radeon]
  [] radeon_ttm_backend_unbind+0x1a/0x20 [radeon]
  [] ttm_tt_unbind+0x27/0x40 [ttm]
  [] ttm_bo_move_memcpy+0x266/0x580 [ttm]
  [] radeon_bo_move+0xd3/0x180 [radeon]
  [] ttm_bo_handle_move_mem+0x216/0x3f0 [ttm]
  [] ? ttm_bo_mem_space+0x180/0x360 [ttm]
  [] ttm_bo_move_buffer+0x142/0x150 [ttm]
  [] ttm_bo_validate+0x9c/0x120 [ttm]
  [] radeon_bo_pin_restricted+0x10a/0x1b0 [radeon]
  [] radeon_crtc_cursor_set+0x9b/0x4a0 [radeon]
  [] ? drm_mode_object_find+0x68/0x90 [drm]
  [] drm_mode_cursor_ioctl+0x105/0x160 [drm]
  [] drm_ioctl+0x4c3/0x570 [drm]
  [] ? drm_mode_setcrtc+0x5a0/0x5a0 [drm]
  [] ? __do_page_fault+0x25c/0x4b0
  [] do_vfs_ioctl+0x90/0x570
  [] ? rw_verify_area+0x4b/0xf0
  [] ? __set_task_blocked+0x37/0x80
  [] ? _raw_spin_unlock_irq+0xe/0x20
  [] ? __set_current_blocked+0x52/0x60
  [] sys_ioctl+0x91/0xb0
  [] system_call_fastpath+0x16/0x1b
 Code: c1 e8 04 83 f8 02 74 2a 85 c0 74 cc 5b 41 5c 5d c3 0f 1f 80 00 00 00 00
31 d2 be 34 2f 00 00 48 8b 9f 98 03 00 00 e8 e5 37 ff ff <8b> 03 e9 4a ff ff ff
48 c7 c7 f0 9f 4b a0 31 c0 e8 f3 5d 0d e1 
 RIP  [] r600_pcie_gart_tlb_flush+0xeb/0x110 [radeon]
  RSP 
 CR2: 
 ---[ end trace 4363d7f2115bb109 ]---

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


[Bug 56405] Distorted graphics on Radeon HD 6620G

2012-10-25 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=56405

mdrslmr at t-online.de changed:

   What|Removed |Added

  Attachment #69083|text/plain  |image/png
  mime type||

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20121025/c0039823/attachment.html>


[Bug 56405] New: Distorted graphics on Radeon HD 6620G

2012-10-25 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=56405

  Priority: medium
Bug ID: 56405
  Assignee: dri-devel at lists.freedesktop.org
   Summary: Distorted graphics on Radeon HD 6620G
  Severity: critical
Classification: Unclassified
OS: Linux (All)
  Reporter: mdrslmr at t-online.de
  Hardware: x86-64 (AMD64)
Status: NEW
   Version: unspecified
 Component: Drivers/DRI/Radeon
   Product: Mesa

Created attachment 69083
  --> https://bugs.freedesktop.org/attachment.cgi?id=69083=edit
Distorted graphics

On my dell vostro laptop I get distorted graphics. I use Gnome3 shell.

See attached screen shot.

The kernel used is 3.6.3-1-ARCH.   

I found the problem is apparent with the versions 9.0-1 of ati-dri and
libgl and is not seen when I downgrade to the versions:

ati-dri-8.0.4-3-x86_64.pkg.tar.xz
libgl-8.0.4-3-x86_64.pkg.tar.xz

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20121025/d76db792/attachment-0001.html>


[PATCH] drm/omap: only advertise rotation prop if supported

2012-10-25 Thread Rob Clark
From: Rob Clark 

For hardware that does not have DMM/TILER, there is no rotation,
so no point in getting userspace's hopes up.

Signed-off-by: Rob Clark 
---
 drivers/staging/omapdrm/omap_drv.c   |   27 +++
 drivers/staging/omapdrm/omap_plane.c |   34 ++
 2 files changed, 33 insertions(+), 28 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_drv.c 
b/drivers/staging/omapdrm/omap_drv.c
index 2bf7259..e4f3cd8 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -670,19 +670,22 @@ static void dev_lastclose(struct drm_device *dev)

DBG("lastclose: dev=%p", dev);

-   /* need to restore default rotation state.. not sure if there is
-* a cleaner way to restore properties to default state?  Maybe
-* a flag that properties should automatically be restored to
-* default state on lastclose?
-*/
-   for (i = 0; i < priv->num_crtcs; i++) {
-   drm_object_property_set_value(>crtcs[i]->base,
-   priv->rotation_prop, 0);
-   }
+   if (priv->rotation_prop) {
+   /* need to restore default rotation state.. not sure
+* if there is a cleaner way to restore properties to
+* default state?  Maybe a flag that properties should
+* automatically be restored to default state on
+* lastclose?
+*/
+   for (i = 0; i < priv->num_crtcs; i++) {
+   drm_object_property_set_value(>crtcs[i]->base,
+   priv->rotation_prop, 0);
+   }

-   for (i = 0; i < priv->num_planes; i++) {
-   drm_object_property_set_value(>planes[i]->base,
-   priv->rotation_prop, 0);
+   for (i = 0; i < priv->num_planes; i++) {
+   drm_object_property_set_value(>planes[i]->base,
+   priv->rotation_prop, 0);
+   }
}

ret = drm_fb_helper_restore_fbdev_mode(priv->fbdev);
diff --git a/drivers/staging/omapdrm/omap_plane.c 
b/drivers/staging/omapdrm/omap_plane.c
index 4bde639..1b3a9fe 100644
--- a/drivers/staging/omapdrm/omap_plane.c
+++ b/drivers/staging/omapdrm/omap_plane.c
@@ -416,23 +416,25 @@ void omap_plane_install_properties(struct drm_plane 
*plane,
struct omap_drm_private *priv = dev->dev_private;
struct drm_property *prop;

-   prop = priv->rotation_prop;
-   if (!prop) {
-   const struct drm_prop_enum_list props[] = {
-   { DRM_ROTATE_0,   "rotate-0" },
-   { DRM_ROTATE_90,  "rotate-90" },
-   { DRM_ROTATE_180, "rotate-180" },
-   { DRM_ROTATE_270, "rotate-270" },
-   { DRM_REFLECT_X,  "reflect-x" },
-   { DRM_REFLECT_Y,  "reflect-y" },
-   };
-   prop = drm_property_create_bitmask(dev, 0, "rotation",
-   props, ARRAY_SIZE(props));
-   if (prop == NULL)
-   return;
-   priv->rotation_prop = prop;
+   if (priv->has_dmm) {
+   prop = priv->rotation_prop;
+   if (!prop) {
+   const struct drm_prop_enum_list props[] = {
+   { DRM_ROTATE_0,   "rotate-0" },
+   { DRM_ROTATE_90,  "rotate-90" },
+   { DRM_ROTATE_180, "rotate-180" },
+   { DRM_ROTATE_270, "rotate-270" },
+   { DRM_REFLECT_X,  "reflect-x" },
+   { DRM_REFLECT_Y,  "reflect-y" },
+   };
+   prop = drm_property_create_bitmask(dev, 0, "rotation",
+   props, ARRAY_SIZE(props));
+   if (prop == NULL)
+   return;
+   priv->rotation_prop = prop;
+   }
+   drm_object_attach_property(obj, prop, 0);
}
-   drm_object_attach_property(obj, prop, 0);

 prop = priv->zorder_prop;
 if (!prop) {
-- 
1.7.9.5



Breakage in "track dev_mapping in more robust and flexible way"

2012-10-25 Thread Thomas Hellström
On 10/25/12 4:41 PM, Jerome Glisse wrote:
> On Thu, Oct 25, 2012 at 04:02:25PM +0200, Thomas Hellstrom wrote:
>> Hi,
>>
>> This commit
>>
>>  From 949c4a34afacfe800fc442afac117aba15284962 Mon Sep 17 00:00:00 2001
>> From: Ilija Hadzic 
>> Date: Tue, 15 May 2012 16:40:10 -0400
>> Subject: [PATCH] drm: track dev_mapping in more robust and flexible way
>>
>> Setting dev_mapping (pointer to the address_space structure
>> used for memory mappings) to the address_space of the first
>> opener's inode and then failing if other openers come in
>> through a different inode has a few restrictions that are
>> eliminated by this patch.
>>
>> If we already have valid dev_mapping and we spot an opener
>> with different i_node, we force its i_mapping pointer to the
>> already established address_space structure (first opener's
>> inode). This will make all mappings from drm device hang off
>> the same address_space object.
>> ...
>>
>> Breaks drivers using TTM, since when the X server calls into the
>> driver open, drm's dev_mapping has not
>> yet been setup. The setup needs to be moved before the driver's open
>> hook is called.
>>
>> Typically, if a TTM-aware driver is provoked by the Xorg server to
>> move a buffer from system to VRAM or AGP,
>> before any other drm client is started, The user-space page table
>> entries are not killed before the move, and left pointing
>> into freed pages, causing system crashes and / or user-space access
>> to arbitrary memory.
> Doesn't handle move invalidate the drm file mapping before scheduling
> the move ?
Yes, but to do that it needs a correct value of bdev::dev_mapping, which 
is now incorrectly set on the
*second* open instead of the first open.

/Thomas


> Cheers,
> Jerome



[PATCH 2/2] vga_switcheroo: Drop unused include and unused variables.

2012-10-25 Thread Igor Murzov
Signed-off-by: Igor Murzov 
---
 drivers/gpu/vga/vga_switcheroo.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index e25cf31..fa60add 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -18,7 +18,6 @@
  */

 #include 
-#include 
 #include 
 #include 
 #include 
@@ -376,7 +375,6 @@ vga_switcheroo_debugfs_write(struct file *filp, const char 
__user *ubuf,
 size_t cnt, loff_t *ppos)
 {
char usercmd[64];
-   const char *pdev_name;
int ret;
bool delay = false, can_switch;
bool just_mux = false;
@@ -468,7 +466,6 @@ vga_switcheroo_debugfs_write(struct file *filp, const char 
__user *ubuf,
goto out;

if (can_switch) {
-   pdev_name = pci_name(client->pdev);
ret = vga_switchto_stage1(client);
if (ret)
printk(KERN_ERR "vga_switcheroo: switching failed stage 
1 %d\n", ret);
@@ -540,7 +537,6 @@ fail:
 int vga_switcheroo_process_delayed_switch(void)
 {
struct vga_switcheroo_client *client;
-   const char *pdev_name;
int ret;
int err = -EINVAL;

@@ -555,7 +551,6 @@ int vga_switcheroo_process_delayed_switch(void)
if (!client || !check_can_switch())
goto err;

-   pdev_name = pci_name(client->pdev);
ret = vga_switchto_stage2(client);
if (ret)
printk(KERN_ERR "vga_switcheroo: delayed switching failed stage 
2 %d\n", ret);
@@ -567,4 +562,3 @@ err:
return err;
 }
 EXPORT_SYMBOL(vga_switcheroo_process_delayed_switch);
-
-- 
1.7.12.1



[PATCH 1/2] drm/radeon: fix ATPX function documentation

2012-10-25 Thread Igor Murzov
Fix a copy documentation.

Signed-off-by: Igor Murzov 
---
 drivers/gpu/drm/radeon/radeon_atpx_handler.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c 
b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index 37f6a90..15f5ded 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -352,9 +352,9 @@ static int radeon_atpx_switchto(enum 
vga_switcheroo_client_id id)
 }

 /**
- * radeon_atpx_switchto - switch to the requested GPU
+ * radeon_atpx_power_state - power down/up the requested GPU
  *
- * @id: GPU to switch to
+ * @id: GPU to power down/up
  * @state: requested power state (0 = off, 1 = on)
  *
  * Execute the necessary ATPX function to power down/up the discrete GPU
-- 
1.7.12.1



Breakage in "track dev_mapping in more robust and flexible way"

2012-10-25 Thread Ilija Hadzic

Can you give the attached patch a whirl and let me know if it fixes the 
problem?

As I indicated in my previous note, vmwgfx should be the only affected 
driver because it looks at dev_mapping in the open hook (others do it when 
they create an object, so they are not affected).

I'll probably revise it (and I'll have some general questions about 
drm_open syscall) before officially send the patch, but I wanted to get 
something quickly to you to check if it fixes your problem. I hope that 
your vmwgfx test environment is such that you can reproduce the original
problem.

thanks,

-- Ilija
-- next part --


Breakage in "track dev_mapping in more robust and flexible way"

2012-10-25 Thread Thomas Hellstrom
Hi,

This commit

 From 949c4a34afacfe800fc442afac117aba15284962 Mon Sep 17 00:00:00 2001
From: Ilija Hadzic 
Date: Tue, 15 May 2012 16:40:10 -0400
Subject: [PATCH] drm: track dev_mapping in more robust and flexible way

Setting dev_mapping (pointer to the address_space structure
used for memory mappings) to the address_space of the first
opener's inode and then failing if other openers come in
through a different inode has a few restrictions that are
eliminated by this patch.

If we already have valid dev_mapping and we spot an opener
with different i_node, we force its i_mapping pointer to the
already established address_space structure (first opener's
inode). This will make all mappings from drm device hang off
the same address_space object.
...

Breaks drivers using TTM, since when the X server calls into the driver 
open, drm's dev_mapping has not
yet been setup. The setup needs to be moved before the driver's open 
hook is called.

Typically, if a TTM-aware driver is provoked by the Xorg server to move 
a buffer from system to VRAM or AGP,
before any other drm client is started, The user-space page table 
entries are not killed before the move, and left pointing
into freed pages, causing system crashes and / or user-space access to 
arbitrary memory.

/Thomas



[PATCH] drm: set dev_mapping before calling drm_open_helper

2012-10-25 Thread Ilija Hadzic
Some drivers (specifically vmwgfx) look at dev_mapping
in their open hook, so we have to set dev->dev_mapping
earlier in the process.

Signed-off-by: Ilija Hadzic 
---
 drivers/gpu/drm/drm_fops.c |   43 +--
 1 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 7ef1b67..50b7b47 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -121,6 +121,8 @@ int drm_open(struct inode *inode, struct file *filp)
int minor_id = iminor(inode);
struct drm_minor *minor;
int retcode = 0;
+   int need_setup = 0;
+   struct address_space *old_mapping;

minor = idr_find(_minors_idr, minor_id);
if (!minor)
@@ -132,23 +134,36 @@ int drm_open(struct inode *inode, struct file *filp)
if (drm_device_is_unplugged(dev))
return -ENODEV;

+   if (!dev->open_count++)
+   need_setup = 1;
+   mutex_lock(>struct_mutex);
+   old_mapping = dev->dev_mapping;
+   if (old_mapping == NULL)
+   dev->dev_mapping = >i_data;
+   mutex_unlock(>struct_mutex);
+
retcode = drm_open_helper(inode, filp, dev);
-   if (!retcode) {
-   atomic_inc(>counts[_DRM_STAT_OPENS]);
-   if (!dev->open_count++)
-   retcode = drm_setup(dev);
-   }
-   if (!retcode) {
-   mutex_lock(>struct_mutex);
-   if (dev->dev_mapping == NULL)
-   dev->dev_mapping = >i_data;
-   /* ihold ensures nobody can remove inode with our i_data */
-   ihold(container_of(dev->dev_mapping, struct inode, i_data));
-   inode->i_mapping = dev->dev_mapping;
-   filp->f_mapping = dev->dev_mapping;
-   mutex_unlock(>struct_mutex);
+   if (retcode)
+   goto err_undo;
+   atomic_inc(>counts[_DRM_STAT_OPENS]);
+   if (need_setup) {
+   retcode = drm_setup(dev);
+   if (retcode)
+   goto err_undo;
}
+   /* ihold ensures nobody can remove inode with our i_data */
+   mutex_lock(>struct_mutex);
+   ihold(container_of(dev->dev_mapping, struct inode, i_data));
+   inode->i_mapping = dev->dev_mapping;
+   filp->f_mapping = dev->dev_mapping;
+   mutex_unlock(>struct_mutex);
+   return 0;

+err_undo:
+   dev->open_count--;
+   mutex_lock(>struct_mutex);
+   dev->dev_mapping = old_mapping;
+   mutex_unlock(>struct_mutex);
return retcode;
 }
 EXPORT_SYMBOL(drm_open);
-- 
1.7.4.1



[PATCH] drm/i915/dp: allow configuring eDP panel fitting scaling mode

2012-10-25 Thread Yuly Novikov
LVDS allowed changing panel fitting scaling mode, while eDP didn't.
Copied relevant code from LVDS to eDP.
This also changes default mode on eDP to ascpect ratio preserving scaling.

Signed-off-by: Yuly Novikov 
---
 drivers/gpu/drm/i915/intel_dp.c  |   33 ++---
 drivers/gpu/drm/i915/intel_drv.h |1 +
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 368ed8e..a65546e 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -685,7 +685,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder,

if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
intel_fixed_panel_mode(intel_dp->panel_fixed_mode, 
adjusted_mode);
-   intel_pch_panel_fitting(dev, DRM_MODE_SCALE_FULLSCREEN,
+   intel_pch_panel_fitting(dev, intel_dp->fitting_mode,
mode, adjusted_mode);
}

@@ -2358,6 +2358,22 @@ intel_dp_set_property(struct drm_connector *connector,
goto done;
}

+   if (is_edp(intel_dp) &&
+   property == connector->dev->mode_config.scaling_mode_property) {
+   if (val == DRM_MODE_SCALE_NONE) {
+   DRM_DEBUG_KMS("no scaling not supported\n");
+   return -EINVAL;
+   }
+
+   if (intel_dp->fitting_mode == val) {
+   /* the eDP scaling property is not changed */
+   return 0;
+   }
+   intel_dp->fitting_mode = val;
+
+   goto done;
+   }
+
return -EINVAL;

 done:
@@ -2469,10 +2485,21 @@ bool intel_dpd_is_edp(struct drm_device *dev)
 }

 static void
-intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector 
*connector)
+intel_dp_add_properties(struct drm_device *dev,
+   struct intel_dp *intel_dp,
+   struct drm_connector *connector)
 {
intel_attach_force_audio_property(connector);
intel_attach_broadcast_rgb_property(connector);
+
+   if (is_edp(intel_dp)) {
+   drm_mode_create_scaling_mode_property(dev);
+   drm_connector_attach_property(
+   connector,
+   dev->mode_config.scaling_mode_property,
+   DRM_MODE_SCALE_ASPECT);
+   intel_dp->fitting_mode = DRM_MODE_SCALE_ASPECT;
+   }
 }

 void
@@ -2665,7 +2692,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, 
enum port port)
intel_panel_setup_backlight(dev);
}

-   intel_dp_add_properties(intel_dp, connector);
+   intel_dp_add_properties(dev, intel_dp, connector);

/* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
 * 0xd.  Failure to do so will result in spurious interrupts being
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index fe71425..da50cd4 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -358,6 +358,7 @@ struct intel_dp {
int backlight_on_delay;
int backlight_off_delay;
struct drm_display_mode *panel_fixed_mode;  /* for eDP */
+   int fitting_mode;  /* for eDP */
struct delayed_work panel_vdd_work;
bool want_panel_vdd;
struct edid *edid; /* cached EDID for eDP */
-- 
1.7.7.3



[PATCH 1/2] drm: use monotonic time in drm_calc_vbltimestamp_from_scanoutpos

2012-10-25 Thread Imre Deak
On Thu, 2012-10-25 at 01:05 +0200, Mario Kleiner wrote:
> On 23.10.12 20:53, Imre Deak wrote:
> > For measuring duration we want to avoid that our start/end timestamps
> > jump, so use monotonic instead of real time for that.
> >
> > Signed-off-by: Imre Deak 
> > ---
> >   drivers/gpu/drm/drm_irq.c |   18 --
> >   1 file changed, 12 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
> > index 89b830d..7dc203d 100644
> > --- a/drivers/gpu/drm/drm_irq.c
> > +++ b/drivers/gpu/drm/drm_irq.c
> > @@ -576,7 +576,8 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct 
> > drm_device *dev, int crtc,
> >   unsigned flags,
> >   struct drm_crtc *refcrtc)
> >   {
> > -   struct timeval stime, raw_time;
> > +   ktime_t stime, etime, mono_time_offset;
> > +   struct timeval tv_etime;
> > struct drm_display_mode *mode;
> > int vbl_status, vtotal, vdisplay;
> > int vpos, hpos, i;
> > @@ -625,13 +626,14 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct 
> > drm_device *dev, int crtc,
> > preempt_disable();
> >
> > /* Get system timestamp before query. */
> > -   do_gettimeofday();
> > +   stime = ktime_get();
> >
> > /* Get vertical and horizontal scanout pos. vpos, hpos. */
> > vbl_status = dev->driver->get_scanout_position(dev, crtc, 
> > , );
> >
> > /* Get system timestamp after query. */
> > -   do_gettimeofday(_time);
> > +   etime = ktime_get();
> 
> Here is possibly a tiny race: The wall_to_monotonic offset value could 
> change between the ktime_get() - which uses it internally for wallclock 
> -> monotonic clock conversion, and the ktime_get_monotonic_offset() 
> query below, so the later subtraction of mono_time_offset from etime 
> would not cancel out the addition to etime inside ktime_get() and you 
> wouldn't get correct walltime back. There seem to be multiple sources of 
> change to the value, e.g., do_settimeofday(), do_adjtimex() - the admin 
> or ntp changing the system clock. The internal code, e.g., ktime_get() 
> use a seqlock to protect against this race.
> 
> There's a function ktime_get_real(void) which directly gives you the 
> wall time you want as ktime_t, but then you'd still need to do the 
> ktime_get() query in the !drm_timestamp_monotonic case to calculate 
> duration_ns below.
> 
> Same problem in the 2nd patch for get_drm_timestamp(). Otoh, the time 
> window for the race is small and it can only happen in the non-default 
> case of !drm_timestamp_monotonic, so i don't know if it is worth fixing it?

I was also hold up by this for a while, since there is no function to
get both clocks atomically. But it isn't really a problem if you think
about it: etime - mono_time_offset is a correct wall time value
regardless whether mono_time_offset has changed or not after
ktime_get(). The only difference is whether the user sees the time value
before or after the adjustment, but you can't guard against that anyway
(except using monotonic time values always).

It would be a problem if as ktime_get() we would do the reverse and
calculate the monotonic time from the wall time. There not getting the
wall time and the wall_to_monotonic offset atomically could result in a
incorrect monotonic time value, for example one that jumps backwards.

--Imre

> Other than that:
> 
> Reviewed-by: mario.kleiner
> 
> > +   mono_time_offset = ktime_get_monotonic_offset();
> >
> > preempt_enable();
> >
> > @@ -642,7 +644,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct 
> > drm_device *dev, int crtc,
> > return -EIO;
> > }
> >
> > -   duration_ns = timeval_to_ns(_time) - timeval_to_ns();
> > +   duration_ns = ktime_to_ns(etime) - ktime_to_ns(stime);
> >
> > /* Accept result with <  max_error nsecs timing uncertainty. */
> > if (duration_ns <= (s64) *max_error)
> > @@ -689,14 +691,18 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct 
> > drm_device *dev, int crtc,
> > vbl_status |= 0x8;
> > }
> >
> > +   etime = ktime_sub(etime, mono_time_offset);
> > +   /* save this only for debugging purposes */
> > +   tv_etime = ktime_to_timeval(etime);
> > /* Subtract time delta from raw timestamp to get final
> >  * vblank_time timestamp for end of vblank.
> >  */
> > -   *vblank_time = ns_to_timeval(timeval_to_ns(_time) - delta_ns);
> > +   etime = ktime_sub_ns(etime, delta_ns);
> > +   *vblank_time = ktime_to_timeval(etime);
> >
> > DRM_DEBUG("crtc %d : v %d p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d 
> > rep]\n",
> >   crtc, (int)vbl_status, hpos, vpos,
> > - (long)raw_time.tv_sec, (long)raw_time.tv_usec,
> > + (long)tv_etime.tv_sec, (long)tv_etime.tv_usec,
> >   (long)vblank_time->tv_sec, 

Breakage in "track dev_mapping in more robust and flexible way"

2012-10-25 Thread Ilija Hadzic
On Thu, Oct 25, 2012 at 11:10 AM, Thomas Hellstr?m
 wrote:
> On 10/25/12 4:41 PM, Jerome Glisse wrote:
>>
>> On Thu, Oct 25, 2012 at 04:02:25PM +0200, Thomas Hellstrom wrote:
>>>
>>> Hi,
>>>
>>> This commit
>>>
>>>  From 949c4a34afacfe800fc442afac117aba15284962 Mon Sep 17 00:00:00 2001
>>> From: Ilija Hadzic 
>>> Date: Tue, 15 May 2012 16:40:10 -0400
>>> Subject: [PATCH] drm: track dev_mapping in more robust and flexible way
>>>
>>> Setting dev_mapping (pointer to the address_space structure
>>> used for memory mappings) to the address_space of the first
>>> opener's inode and then failing if other openers come in
>>> through a different inode has a few restrictions that are
>>> eliminated by this patch.
>>>
>>> If we already have valid dev_mapping and we spot an opener
>>> with different i_node, we force its i_mapping pointer to the
>>> already established address_space structure (first opener's
>>> inode). This will make all mappings from drm device hang off
>>> the same address_space object.
>>> ...
>>>
>>> Breaks drivers using TTM, since when the X server calls into the
>>> driver open, drm's dev_mapping has not
>>> yet been setup. The setup needs to be moved before the driver's open
>>> hook is called.
>>>
>>> Typically, if a TTM-aware driver is provoked by the Xorg server to
>>> move a buffer from system to VRAM or AGP,
>>> before any other drm client is started, The user-space page table
>>> entries are not killed before the move, and left pointing
>>> into freed pages, causing system crashes and / or user-space access
>>> to arbitrary memory.
>>
>> Doesn't handle move invalidate the drm file mapping before scheduling
>> the move ?
>
> Yes, but to do that it needs a correct value of bdev::dev_mapping, which is
> now incorrectly set on the
> *second* open instead of the first open.
>

So you are implying that in the first open the assignment of dev->dev_mapping is
somehow skipped (which could happen if drm_setup returns an error) or that the
driver on which you are having problems with (nouveau I presume) needs
dev_mapping
in the firstopen hook ?

It's been a while since I did it, but if my memory serves me well I
thought I explicitly
verified that dev_mapping was correctly set in the first open (though
GPUs I use are
primarily AMD).

-- Ilija


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


DRM agp_init error path oops

2012-10-25 Thread Bjorn Helgaas
I think there's a latent bug in a DRM error path, at least when used
by i915.  In the scenario below, if dev->driver->bus->agp_init()
fails, we call drm_lastclose().  At least in i915_driver_lastclose(),
this dereferences dev->dev_private (at "1" below).

But dev->dev_private isn't initialized until "2", in i915_driver_load().

i915_pci_probe
drm_get_pci_dev
drm_fill_in_dev
drm_pci_agp_init(dev->driver->bus->agp_init)
drm_lastclose   # error path when agp_init fails
i915_driver_lastclose   (dev->driver->lastclose)
intel_fb_restore_mode
1)
drm_fb_helper_restore_fbdev_mode(>dev_private->fbdev->helper)
i915_driver_load(dev->driver->load)
2)  dev->dev_private = (void *)dev_priv

We tripped over this because a different bug caused drm_pci_agp_init()
to fail when it shouldn't have.  Details about that bug are here:
https://bugzilla.kernel.org/show_bug.cgi?id=46481#c16

That bug has been fixed, but this dev_private initialization ordering
problem is still there, waiting to bite us again on the next machine
where drm_pci_agp_init() fails for some reason.

Bjorn


Breakage in "track dev_mapping in more robust and flexible way"

2012-10-25 Thread Ilija Hadzic

Or could the driver that causes the problem be vmwgfx ? I now looked at 
the code and I notice that indeed vmwgfx sets its private dev_mapping in 
the open hook, while all other TTM-based drivers (radeon and nouveau) do 
it when they create an object.

-- Ilija




[PATCH 1/2] drm/radeon: fix ATPX function documentation

2012-10-25 Thread Alex Deucher
On Thu, Oct 25, 2012 at 9:09 AM, Igor Murzov  wrote:
> Fix a copy documentation.
>
> Signed-off-by: Igor Murzov 

Thanks.  I've added this to my queue.

Alex

> ---
>  drivers/gpu/drm/radeon/radeon_atpx_handler.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c 
> b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
> index 37f6a90..15f5ded 100644
> --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
> +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
> @@ -352,9 +352,9 @@ static int radeon_atpx_switchto(enum 
> vga_switcheroo_client_id id)
>  }
>
>  /**
> - * radeon_atpx_switchto - switch to the requested GPU
> + * radeon_atpx_power_state - power down/up the requested GPU
>   *
> - * @id: GPU to switch to
> + * @id: GPU to power down/up
>   * @state: requested power state (0 = off, 1 = on)
>   *
>   * Execute the necessary ATPX function to power down/up the discrete GPU
> --
> 1.7.12.1
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


[BUG 3.7-rc1] nouveau cli->mutex possible recursive locking detected

2012-10-25 Thread Arend van Spriel
On 10/24/2012 02:45 PM, Arend van Spriel wrote:
> On 10/24/2012 01:14 PM, Arend van Spriel wrote:
>> On 10/16/2012 02:43 PM, Stanislaw Gruszka wrote:
>>> I have this lockdep warning on wireless-testing tree based
>>> on 3.7-rc1 (no other patches except wireless bits).
>>>
>>> =
>>> Restarting tasks ... done.
>>> [ INFO: possible recursive locking detected ]
>>> 3.7.0-rc1-wl+ #2 Not tainted
>>> -
>>> Xorg/2269 is trying to acquire lock:
>>>   (>mutex){+.+.+.}, at: []
>>> nouveau_bo_move_m2mf+0x5f/0x170 [nouveau]
>>>
>>> but task is already holding lock:
>>>   (>mutex){+.+.+.}, at: []
>>> nouveau_abi16_get+0x34/0x100 [nouveau]
>>>
>>
>> I have observed the same bug so I built and tested v3.7-rc2 tag with
>> lockdep enabled. It has the same problem and it results in a failure to
>> resume after suspend. See below.
>>
>> Gr. AvS
>
> digging into the trace:
>
>
> nouveau_gem_ioctl_pushbuf() calls nouveau_abi16_get() which grabs the
> mutex. Assume this should protect the chan variable passed to
> nouveau_gem_pushbuf_validate(), which does a bit more that validate as
> it ends up in nouveau_bo_move_m2mf() which uses the drm->chan. However,
> it deadlocks before that.
>
> Gr. AvS

I reverted the two drm merges:

ceb736c Merge branch 'drm-nouveau-fixes' of 
git://anongit.freedesktop.org/git/no
612a9aa Merge branch 'drm-next' of 
git://people.freedesktop.org/~airlied/linux

It is not surprising that it solved the deadlock (doing pm_test). 
Unfortunately, suspend/resume still does not work. System goes to sleep 
just fine, but when trying to resume the BIOS kicks in and system boots 
instead of waking up.

Gr. AvS




[BUG 3.7-rc1] nouveau cli->mutex possible recursive locking detected

2012-10-25 Thread Arend van Spriel
On 10/24/2012 02:45 PM, Arend van Spriel wrote:
> On 10/24/2012 01:14 PM, Arend van Spriel wrote:
>> On 10/16/2012 02:43 PM, Stanislaw Gruszka wrote:
>>> I have this lockdep warning on wireless-testing tree based
>>> on 3.7-rc1 (no other patches except wireless bits).
>>>
>>> =
>>> Restarting tasks ... done.
>>> [ INFO: possible recursive locking detected ]
>>> 3.7.0-rc1-wl+ #2 Not tainted
>>> -
>>> Xorg/2269 is trying to acquire lock:
>>>   (>mutex){+.+.+.}, at: []
>>> nouveau_bo_move_m2mf+0x5f/0x170 [nouveau]
>>>
>>> but task is already holding lock:
>>>   (>mutex){+.+.+.}, at: []
>>> nouveau_abi16_get+0x34/0x100 [nouveau]
>>>
>>
>> I have observed the same bug so I built and tested v3.7-rc2 tag with
>> lockdep enabled. It has the same problem and it results in a failure to
>> resume after suspend. See below.
>>
>> Gr. AvS
>
> digging into the trace:
>
>
> nouveau_gem_ioctl_pushbuf() calls nouveau_abi16_get() which grabs the
> mutex. Assume this should protect the chan variable passed to
> nouveau_gem_pushbuf_validate(), which does a bit more that validate as
> it ends up in nouveau_bo_move_m2mf() which uses the drm->chan. However,
> it deadlocks before that.
>
> Gr. AvS

Maybe this helps. The two locations where the lock is grabbed are from 
the same commit (see below).

Gr. AvS

commit ebb945a94bba2ce8dff7b0942ff2b3f2a52a0a69
Author: Ben Skeggs 
Date:   Fri Jul 20 08:17:34 2012 +1000

 drm/nouveau: port all engines to new engine module format

 This is a HUGE commit, but it's not nearly as bad as it looks - any 
problems
 can be isolated to a particular chipset and engine combination.  It was
 simply too difficult to port each one at a time, the compat layers are
 *already* ridiculous.

 Most of the changes here are simply to the glue, the process for 
each of the
 engine modules was to start with a standard skeleton and copy+paste 
the old
 code into the appropriate places, fixing up variable names etc as 
needed.

 v2: Marcin Slusarz 
 - fix find/replace bug in license header

 v3: Ben Skeggs 
 - bump indirect pushbuf size to 8KiB, 4KiB barely enough for 
userspace and
   left no space for kernel's requirements during GEM pushbuf 
submission.
 - fix duplicate assignments noticed by clang

 v4: Marcin Slusarz 
 - add sparse annotations to nv04_fifo_pause/nv04_fifo_start
 - use ioread32_native/iowrite32_native for fifo control registers

 v5: Ben Skeggs 
 - rebase on v3.6-rc4, modified to keep copy engine fix intact
 - nv10/fence: unmap fence bo before destroying
 - fixed fermi regression when using nvidia gr fuc
 - fixed typo in supported dma_mask checking

 Signed-off-by: Ben Skeggs 





[Bug 49431] [Apple Inc. MacBookPro5,4] suspend/resume failure

2012-10-25 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=49431


Alan  changed:

   What|Removed |Added

 CC||alan at lxorguk.ukuu.org.uk
  Component|Hibernation/Suspend |Video(DRI - non Intel)
 AssignedTo|power-management_other at kern |drivers_video-dri at 
kernel-bu
   |el-bugs.osdl.org|gs.osdl.org
Product|Power Management|Drivers




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


Breakage in "track dev_mapping in more robust and flexible way"

2012-10-25 Thread Jerome Glisse
On Thu, Oct 25, 2012 at 04:02:25PM +0200, Thomas Hellstrom wrote:
> Hi,
> 
> This commit
> 
> From 949c4a34afacfe800fc442afac117aba15284962 Mon Sep 17 00:00:00 2001
> From: Ilija Hadzic 
> Date: Tue, 15 May 2012 16:40:10 -0400
> Subject: [PATCH] drm: track dev_mapping in more robust and flexible way
> 
> Setting dev_mapping (pointer to the address_space structure
> used for memory mappings) to the address_space of the first
> opener's inode and then failing if other openers come in
> through a different inode has a few restrictions that are
> eliminated by this patch.
> 
> If we already have valid dev_mapping and we spot an opener
> with different i_node, we force its i_mapping pointer to the
> already established address_space structure (first opener's
> inode). This will make all mappings from drm device hang off
> the same address_space object.
> ...
> 
> Breaks drivers using TTM, since when the X server calls into the
> driver open, drm's dev_mapping has not
> yet been setup. The setup needs to be moved before the driver's open
> hook is called.
> 
> Typically, if a TTM-aware driver is provoked by the Xorg server to
> move a buffer from system to VRAM or AGP,
> before any other drm client is started, The user-space page table
> entries are not killed before the move, and left pointing
> into freed pages, causing system crashes and / or user-space access
> to arbitrary memory.

Doesn't handle move invalidate the drm file mapping before scheduling
the move ?

Cheers,
Jerome


[drm:i915_hangcheck_hung] *ERROR* Hangcheck timer elapsed... GPU hung

2012-10-25 Thread Daniel Vetter
On Thu, Oct 25, 2012 at 7:22 AM, Justin P. Mattock
 wrote:
>
> here is a link to the file..: intel_error_decode
> http://www.filefactory.com/file/22bypyjhs4mx

I haven't figured out how to access this thing. Can you please file a
bug report on bugs.freedesktop.org and attach it there?

Thanks, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch


[PATCH] drm: kms_helper: don't lose hotplug event

2012-10-25 Thread Chris Wilson
On Wed, 24 Oct 2012 21:16:53 +0200, Daniel Vetter  
wrote:
> There's a race window (small for hpd, 10s large for polled outputs)
> where userspace could sneak in with an unrelated connnector probe
> ioctl call and eat the hotplug event (since neither the hpd nor the
> poll code see a state change).
> 
> To avoid this, check whether the connector state changes in all other
> ->detect calls (in the current helper code that's only probe_single)
> and if that's the case, fire off a hotplug event. Note that we can't
> directly call the hotplug event handler, since that expects that no
> locks are held (due to reentrancy with the fb code to update the kms
> console).
> 
> Also, this requires that drivers using the probe_single helper
> function set up the poll work. All current drivers do that already,
> and with the reworked hpd handling there'll be no downside to
> unconditionally setting up the poll work any more.
> 
> Signed-off-by: Daniel Vetter 

Aye, we do want the hotplug notification for the desktop to respond to
if the user happens to steal it by haplessly querying the system with
xrandr. lgtm,

Reviewed-by: Chris Wilson 
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH 1/4] drm/vmwgfx: remove use of fence_obj_args

2012-10-25 Thread Thomas Hellstrom
On 10/12/2012 05:01 PM, Maarten Lankhorst wrote:
> It's always hardcoded to the same value.
>
> Signed-off-by: Maarten Lankhorst 
> ---
>   drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c   |7 ++-
>   drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c  |   15 ++-
>   drivers/gpu/drm/vmwgfx/vmwgfx_resource.c |4 
>   3 files changed, 4 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c 
> b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
> index 9826fbc..da12922 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
> @@ -318,19 +318,16 @@ static int vmw_sync_obj_flush(void *sync_obj, void 
> *sync_arg)
>   
>   static bool vmw_sync_obj_signaled(void *sync_obj, void *sync_arg)
>   {
> - unsigned long flags = (unsigned long) sync_arg;
>   return  vmw_fence_obj_signaled((struct vmw_fence_obj *) sync_obj,
> -(uint32_t) flags);
> +DRM_VMW_FENCE_FLAG_EXEC);
>   
>   }
>   
>   static int vmw_sync_obj_wait(void *sync_obj, void *sync_arg,
>bool lazy, bool interruptible)
>   {
> - unsigned long flags = (unsigned long) sync_arg;
> -
>   return vmw_fence_obj_wait((struct vmw_fence_obj *) sync_obj,
> -   (uint32_t) flags,
> +   DRM_VMW_FENCE_FLAG_EXEC,
> lazy, interruptible,
> VMW_FENCE_WAIT_TIMEOUT);
>   }
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c 
> b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
> index 30654b4..e5775a0 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
> @@ -71,7 +71,6 @@ static void vmw_resource_to_validate_list(struct 
> vmw_sw_context *sw_context,
>*/
>   static int vmw_bo_to_validate_list(struct vmw_sw_context *sw_context,
>  struct ttm_buffer_object *bo,
> -uint32_t fence_flags,
>  uint32_t *p_val_node)
>   {
>   uint32_t val_node;
> @@ -87,15 +86,12 @@ static int vmw_bo_to_validate_list(struct vmw_sw_context 
> *sw_context,
>   
>   val_buf = _context->val_bufs[val_node];
>   if (unlikely(val_node == sw_context->cur_val_buf)) {
> - val_buf->new_sync_obj_arg = NULL;
>   val_buf->bo = ttm_bo_reference(bo);
>   list_add_tail(_buf->head, _context->validate_nodes);
>   ++sw_context->cur_val_buf;
>   }
>   
> - val_buf->new_sync_obj_arg = (void *)
> - ((unsigned long) val_buf->new_sync_obj_arg | fence_flags);
> - sw_context->fence_flags |= fence_flags;
> + sw_context->fence_flags |= DRM_VMW_FENCE_FLAG_EXEC;
>   
>   if (p_val_node)
>   *p_val_node = val_node;
> @@ -313,7 +309,6 @@ static int vmw_query_bo_switch_prepare(struct vmw_private 
> *dev_priv,
>   cid_to_add = sw_context->cur_query_cid;
>   ret = vmw_bo_to_validate_list(sw_context,
> sw_context->cur_query_bo,
> -   DRM_VMW_FENCE_FLAG_EXEC,
> NULL);
>   if (unlikely(ret != 0))
>   return ret;
> @@ -322,7 +317,6 @@ static int vmw_query_bo_switch_prepare(struct vmw_private 
> *dev_priv,
>   
>   ret = vmw_bo_to_validate_list(sw_context,
> dev_priv->dummy_query_bo,
> -   DRM_VMW_FENCE_FLAG_EXEC,
> NULL);
>   if (unlikely(ret != 0))
>   return ret;
> @@ -346,7 +340,6 @@ static int vmw_query_bo_switch_prepare(struct vmw_private 
> *dev_priv,
> _context->query_list);
>   ret = vmw_bo_to_validate_list(sw_context,
> dev_priv->dummy_query_bo,
> -   DRM_VMW_FENCE_FLAG_EXEC,
> NULL);
>   if (unlikely(ret != 0))
>   return ret;
> @@ -465,8 +458,7 @@ static int vmw_translate_guest_ptr(struct vmw_private 
> *dev_priv,
>   reloc = _context->relocs[sw_context->cur_reloc++];
>   reloc->location = ptr;
>   
> - ret = vmw_bo_to_validate_list(sw_context, bo, DRM_VMW_FENCE_FLAG_EXEC,
> -   >index);
> + ret = vmw_bo_to_validate_list(sw_context, bo, >index);
>   if (unlikely(ret != 0))
>   goto out_no_reloc;
>   
> @@ -1290,12 +1282,9 @@ void vmw_execbuf_release_pinned_bo(struct vmw_private 
> *dev_priv,
>   
>   INIT_LIST_HEAD(_list);
>   
> - pinned_val.new_sync_obj_arg = (void *)(unsigned long)
> - 

[PATCH] drivers/gpu/drm/radeon/evergreen_cs.c: Remove unnecessary semicolon

2012-10-25 Thread Alex Deucher
On Wed, Oct 24, 2012 at 10:42 AM, Peter Senna Tschudin
 wrote:
> A simplified version of the semantic match that finds this problem is as
> follows: (http://coccinelle.lip6.fr/)
>
> // 
> @r1@
> statement S;
> position p,p1;
> @@
> S at p1;@p
>
> @script:python r2@
> p << r1.p;
> p1 << r1.p1;
> @@
> if p[0].line != p1[0].line_end:
> cocci.include_match(False)
> @@
> position r1.p;
> @@
> -;@p
> // 
>
> Signed-off-by: Peter Senna Tschudin 

Thanks!  I've added this to my patch queue.

Alex

>
> ---
>
> The full version of the semantic patch can be found at:
> http://www.mail-archive.com/cocci at systeme.lip6.fr/msg00014.html
>
>  drivers/gpu/drm/radeon/evergreen_cs.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c 
> b/drivers/gpu/drm/radeon/evergreen_cs.c
> index 573ed1b..5daf0c5 100644
> --- a/drivers/gpu/drm/radeon/evergreen_cs.c
> +++ b/drivers/gpu/drm/radeon/evergreen_cs.c
> @@ -264,7 +264,7 @@ static int evergreen_surface_check_2d(struct 
> radeon_cs_parser *p,
> /* macro tile width & height */
> palign = (8 * surf->bankw * track->npipes) * surf->mtilea;
> halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea;
> -   mtileb = (palign / 8) * (halign / 8) * tileb;;
> +   mtileb = (palign / 8) * (halign / 8) * tileb;
> mtile_pr = surf->nbx / palign;
> mtile_ps = (mtile_pr * surf->nby) / halign;
> surf->layer_size = mtile_ps * mtileb * slice_pt;
> --
> 1.7.11.7
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


[drm:i915_hangcheck_hung] *ERROR* Hangcheck timer elapsed... GPU hung

2012-10-25 Thread Chris Wilson
On Thu, 25 Oct 2012 10:16:08 +0200, Daniel Vetter  wrote:
> On Thu, Oct 25, 2012 at 7:22 AM, Justin P. Mattock
>  wrote:
> >
> > here is a link to the file..: intel_error_decode
> > http://www.filefactory.com/file/22bypyjhs4mx
> 
> I haven't figured out how to access this thing. Can you please file a
> bug report on bugs.freedesktop.org and attach it there?

No worries, it is another ILK hang similar to the ones reported earlier
- it just seems the ring stops advancing. Hopefully it is a missing w/a
from http://cgit.freedesktop.org/~danvet/drm/log/?h=ilk-wa-pile
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH 3/3] drm/vmwgfx: use ttm_bo_is_reserved

2012-10-25 Thread Thomas Hellstrom
On 10/12/2012 04:59 PM, Maarten Lankhorst wrote:
> Signed-off-by: Maarten Lankhorst 
> ---
>   drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c |2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c 
> b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
> index 3ce68a2..bd78257 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
> @@ -304,7 +304,7 @@ void vmw_bo_pin(struct ttm_buffer_object *bo, bool pin)
>   uint32_t old_mem_type = bo->mem.mem_type;
>   int ret;
>   
> - BUG_ON(!atomic_read(>reserved));
> + BUG_ON(!ttm_bo_is_reserved(bo));
>   BUG_ON(old_mem_type != TTM_PL_VRAM &&
>  old_mem_type != VMW_PL_FLAG_GMR);
>   
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
Reviewed-by: Thomas Hellstrom 





[PATCH 2/3] drm/radeon: Use ttm_bo_is_reserved

2012-10-25 Thread Thomas Hellstrom
On 10/12/2012 04:59 PM, Maarten Lankhorst wrote:
> Signed-off-by: Maarten Lankhorst 
> ---
>   drivers/gpu/drm/radeon/radeon_gart.c   |2 +-
>   drivers/gpu/drm/radeon/radeon_object.c |6 +++---
>   drivers/gpu/drm/radeon/radeon_object.h |2 +-
>   3 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
> b/drivers/gpu/drm/radeon/radeon_gart.c
> index f0c06d1..0ee5e29 100644
> --- a/drivers/gpu/drm/radeon/radeon_gart.c
> +++ b/drivers/gpu/drm/radeon/radeon_gart.c
> @@ -1044,7 +1044,7 @@ void radeon_vm_bo_invalidate(struct radeon_device *rdev,
>   {
>   struct radeon_bo_va *bo_va;
>   
> - BUG_ON(!atomic_read(>tbo.reserved));
> + BUG_ON(!radeon_bo_is_reserved(bo));
>   list_for_each_entry(bo_va, >va, bo_list) {
>   bo_va->valid = false;
>   }
> diff --git a/drivers/gpu/drm/radeon/radeon_object.c 
> b/drivers/gpu/drm/radeon/radeon_object.c
> index 8b27dd6..808c444 100644
> --- a/drivers/gpu/drm/radeon/radeon_object.c
> +++ b/drivers/gpu/drm/radeon/radeon_object.c
> @@ -403,7 +403,7 @@ int radeon_bo_get_surface_reg(struct radeon_bo *bo)
>   int steal;
>   int i;
>   
> - BUG_ON(!atomic_read(>tbo.reserved));
> + BUG_ON(!radeon_bo_is_reserved(bo));
>   
>   if (!bo->tiling_flags)
>   return 0;
> @@ -529,7 +529,7 @@ void radeon_bo_get_tiling_flags(struct radeon_bo *bo,
>   uint32_t *tiling_flags,
>   uint32_t *pitch)
>   {
> - BUG_ON(!atomic_read(>tbo.reserved));
> + BUG_ON(!radeon_bo_is_reserved(bo));
>   if (tiling_flags)
>   *tiling_flags = bo->tiling_flags;
>   if (pitch)
> @@ -539,7 +539,7 @@ void radeon_bo_get_tiling_flags(struct radeon_bo *bo,
>   int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved,
>   bool force_drop)
>   {
> - BUG_ON(!atomic_read(>tbo.reserved));
> + BUG_ON(!radeon_bo_is_reserved(bo));
>   
>   if (!(bo->tiling_flags & RADEON_TILING_SURFACE))
>   return 0;
> diff --git a/drivers/gpu/drm/radeon/radeon_object.h 
> b/drivers/gpu/drm/radeon/radeon_object.h
> index 93cd491..5fc86b0 100644
> --- a/drivers/gpu/drm/radeon/radeon_object.h
> +++ b/drivers/gpu/drm/radeon/radeon_object.h
> @@ -80,7 +80,7 @@ static inline unsigned long radeon_bo_size(struct radeon_bo 
> *bo)
>   
>   static inline bool radeon_bo_is_reserved(struct radeon_bo *bo)
>   {
> - return !!atomic_read(>tbo.reserved);
> + return ttm_bo_is_reserved(>tbo);
>   }
>   
>   static inline unsigned radeon_bo_ngpu_pages(struct radeon_bo *bo)
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
Looks good.
Reviewed-by: Thomas Hellstrom 





[PATCH 1/3] drm/ttm: add ttm_bo_is_reserved

2012-10-25 Thread Thomas Hellstrom
On 10/12/2012 04:58 PM, Maarten Lankhorst wrote:
> Signed-off-by: Maarten Lankhorst 
> ---
>   drivers/gpu/drm/ttm/ttm_bo.c |   12 ++--
>   include/drm/ttm/ttm_bo_api.h |   14 ++
>   2 files changed, 20 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
> index be1148e..d9d8541 100644
> --- a/drivers/gpu/drm/ttm/ttm_bo.c
> +++ b/drivers/gpu/drm/ttm/ttm_bo.c
> @@ -161,9 +161,9 @@ int ttm_bo_wait_unreserved(struct ttm_buffer_object *bo, 
> bool interruptible)
>   {
>   if (interruptible) {
>   return wait_event_interruptible(bo->event_queue,
> -atomic_read(>reserved) == 0);
> +!ttm_bo_is_reserved(bo));
>   } else {
> - wait_event(bo->event_queue, atomic_read(>reserved) == 0);
> + wait_event(bo->event_queue, !ttm_bo_is_reserved(bo));
>   return 0;
>   }
>   }
> @@ -174,7 +174,7 @@ void ttm_bo_add_to_lru(struct ttm_buffer_object *bo)
>   struct ttm_bo_device *bdev = bo->bdev;
>   struct ttm_mem_type_manager *man;
>   
> - BUG_ON(!atomic_read(>reserved));
> + BUG_ON(!ttm_bo_is_reserved(bo));
>   
>   if (!(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) {
>   
> @@ -748,7 +748,7 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, 
> bool interruptible,
>   goto out;
>   }
>   
> - BUG_ON(!atomic_read(>reserved));
> + BUG_ON(!ttm_bo_is_reserved(bo));
>   
>   evict_mem = bo->mem;
>   evict_mem.mm_node = NULL;
> @@ -1058,7 +1058,7 @@ int ttm_bo_move_buffer(struct ttm_buffer_object *bo,
>   struct ttm_mem_reg mem;
>   struct ttm_bo_device *bdev = bo->bdev;
>   
> - BUG_ON(!atomic_read(>reserved));
> + BUG_ON(!ttm_bo_is_reserved(bo));
>   
>   /*
>* FIXME: It's possible to pipeline buffer moves.
> @@ -1115,7 +1115,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
>   {
>   int ret;
>   
> - BUG_ON(!atomic_read(>reserved));
> + BUG_ON(!ttm_bo_is_reserved(bo));
>   /* Check that range is valid */
>   if (placement->lpfn || placement->fpfn)
>   if (placement->fpfn > placement->lpfn ||
> diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h
> index 9654451..1d71f6b 100644
> --- a/include/drm/ttm/ttm_bo_api.h
> +++ b/include/drm/ttm/ttm_bo_api.h
> @@ -705,4 +705,18 @@ extern ssize_t ttm_bo_io(struct ttm_bo_device *bdev, 
> struct file *filp,
>   
>   extern void ttm_bo_swapout_all(struct ttm_bo_device *bdev);
>   
> +/**
> + * ttm_bo_is_reserved - return an indication if a ttm buffer object is 
> reserved
> + *
> + * @bo: The buffer object to check.
> + *
> + * This function returns an indication if a bo is reserved or not, and should
> + * only be used to print an error when it is not from incorrect api usage, 
> since
> + * there's no guarantee that it is the caller that is holding the 
> reservation.
> + */
> +static inline bool ttm_bo_is_reserved(struct ttm_buffer_object *bo)
> +{
> + return atomic_read(>reserved);
> +}
> +
>   #endif
This looks good, although for clarity we should add in the comments that
if the caller is holding the reservation, the function is guaranteed to 
return true.

Otherwise
Reviewed-by: Thomas Hellstrom 
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel





mmotm 2012-10-24-17-15 uploaded (drm/i915)

2012-10-25 Thread Randy Dunlap
On 10/24/2012 05:16 PM, akpm at linux-foundation.org wrote:

> The mm-of-the-moment snapshot 2012-10-24-17-15 has been uploaded to
> 
>http://www.ozlabs.org/~akpm/mmotm/
> 
> mmotm-readme.txt says
> 
> README for mm-of-the-moment:
> 
> http://www.ozlabs.org/~akpm/mmotm/
> 


on i386:

ERROR: "__build_bug_on_failed" [drivers/gpu/drm/i915/i915.ko] undefined!

Full randconfig file is attached.

-- 
~Randy
-- next part --
An embedded and charset-unspecified text was scrubbed...
Name: config-r8339
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20121025/93dbd1fd/attachment-0001.ksh>


[PATCH] DRM/Radeon: Set depth on low mem Radeon cards to 16 instead of 8.

2012-10-25 Thread Michel Dänzer
On Mit, 2012-10-24 at 18:33 +0200, Egbert Eich wrote: 
> The Radeon driver reduces the framebuffer resolution to 8bpp if
> a device with less than 32 Mb VRAM is found. This causes the
> framebuffer to run in 8 bit paletted mode. For a text console this
> is not an issue as 256 different colors is more than one gets
> on a VGA text console.
> It is done to give X more memory to work with since the console memory
> is not freed but remains allocated while X is active.
> Still, running the fbdev Xserver driver - which we do during installation
> - will give applications an 8bit pseudo-color visual which doesn't look
> too pretty.

Is it not possible for xf86-video-fbdev to choose a higher depth anyway,
even if specified explicitly in xorg.conf or on the Xorg command line?


> We therefore limit the framebuffer bpp to 16 when memory is 24MB or lower
> and to 8 only if 8MB or less VRAM is found.
> This should be a reasonable compromise for us.
> This patch will most likely not ever make it upstream.

This last sentence seems stale here. :)


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


[Bug 56329] System does not hibernate ATI Technologies Inc RV370 secondary [Sapphire X550 Silent]

2012-10-25 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=56329

--- Comment #7 from Giacomo Perale  ---
FWIW I've got the same card and hibernation has been working reliably for at
least two years and it's still working with current git.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20121025/6dcf65dd/attachment.html>


[PATCH] DRM/Radeon: Set depth on low mem Radeon cards to 16 instead of 8.

2012-10-25 Thread Dave Airlie
On Thu, Oct 25, 2012 at 3:07 AM, Alex Deucher  wrote:
> On Wed, Oct 24, 2012 at 12:33 PM, Egbert Eich  wrote:
>> The Radeon driver reduces the framebuffer resolution to 8bpp if
>> a device with less than 32 Mb VRAM is found. This causes the
>> framebuffer to run in 8 bit paletted mode. For a text console this
>> is not an issue as 256 different colors is more than one gets
>> on a VGA text console.
>> It is done to give X more memory to work with since the console memory
>> is not freed but remains allocated while X is active.
>> Still, running the fbdev Xserver driver - which we do during installation
>> - will give applications an 8bit pseudo-color visual which doesn't look
>> too pretty.
>> We therefore limit the framebuffer bpp to 16 when memory is 24MB or lower
>> and to 8 only if 8MB or less VRAM is found.
>> This should be a reasonable compromise for us.
>> This patch will most likely not ever make it upstream.
>>
>> This works around ugly modes on crappy IPMI cards using ES1000.
>
> I don't have a strong opinion either way on this one.

Why would you use fbdev? package -modesetting at least if not the real ATI DDX.

Dave.


[PATCH 1/2] drm: use monotonic time in drm_calc_vbltimestamp_from_scanoutpos

2012-10-25 Thread Mario Kleiner
On 23.10.12 20:53, Imre Deak wrote:
> For measuring duration we want to avoid that our start/end timestamps
> jump, so use monotonic instead of real time for that.
>
> Signed-off-by: Imre Deak 
> ---
>   drivers/gpu/drm/drm_irq.c |   18 --
>   1 file changed, 12 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
> index 89b830d..7dc203d 100644
> --- a/drivers/gpu/drm/drm_irq.c
> +++ b/drivers/gpu/drm/drm_irq.c
> @@ -576,7 +576,8 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct 
> drm_device *dev, int crtc,
> unsigned flags,
> struct drm_crtc *refcrtc)
>   {
> - struct timeval stime, raw_time;
> + ktime_t stime, etime, mono_time_offset;
> + struct timeval tv_etime;
>   struct drm_display_mode *mode;
>   int vbl_status, vtotal, vdisplay;
>   int vpos, hpos, i;
> @@ -625,13 +626,14 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct 
> drm_device *dev, int crtc,
>   preempt_disable();
>
>   /* Get system timestamp before query. */
> - do_gettimeofday();
> + stime = ktime_get();
>
>   /* Get vertical and horizontal scanout pos. vpos, hpos. */
>   vbl_status = dev->driver->get_scanout_position(dev, crtc, 
> , );
>
>   /* Get system timestamp after query. */
> - do_gettimeofday(_time);
> + etime = ktime_get();

Here is possibly a tiny race: The wall_to_monotonic offset value could 
change between the ktime_get() - which uses it internally for wallclock 
-> monotonic clock conversion, and the ktime_get_monotonic_offset() 
query below, so the later subtraction of mono_time_offset from etime 
would not cancel out the addition to etime inside ktime_get() and you 
wouldn't get correct walltime back. There seem to be multiple sources of 
change to the value, e.g., do_settimeofday(), do_adjtimex() - the admin 
or ntp changing the system clock. The internal code, e.g., ktime_get() 
use a seqlock to protect against this race.

There's a function ktime_get_real(void) which directly gives you the 
wall time you want as ktime_t, but then you'd still need to do the 
ktime_get() query in the !drm_timestamp_monotonic case to calculate 
duration_ns below.

Same problem in the 2nd patch for get_drm_timestamp(). Otoh, the time 
window for the race is small and it can only happen in the non-default 
case of !drm_timestamp_monotonic, so i don't know if it is worth fixing it?

Other than that:

Reviewed-by: mario.kleiner

> + mono_time_offset = ktime_get_monotonic_offset();
>
>   preempt_enable();
>
> @@ -642,7 +644,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct 
> drm_device *dev, int crtc,
>   return -EIO;
>   }
>
> - duration_ns = timeval_to_ns(_time) - timeval_to_ns();
> + duration_ns = ktime_to_ns(etime) - ktime_to_ns(stime);
>
>   /* Accept result with <  max_error nsecs timing uncertainty. */
>   if (duration_ns <= (s64) *max_error)
> @@ -689,14 +691,18 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct 
> drm_device *dev, int crtc,
>   vbl_status |= 0x8;
>   }
>
> + etime = ktime_sub(etime, mono_time_offset);
> + /* save this only for debugging purposes */
> + tv_etime = ktime_to_timeval(etime);
>   /* Subtract time delta from raw timestamp to get final
>* vblank_time timestamp for end of vblank.
>*/
> - *vblank_time = ns_to_timeval(timeval_to_ns(_time) - delta_ns);
> + etime = ktime_sub_ns(etime, delta_ns);
> + *vblank_time = ktime_to_timeval(etime);
>
>   DRM_DEBUG("crtc %d : v %d p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d 
> rep]\n",
> crtc, (int)vbl_status, hpos, vpos,
> -   (long)raw_time.tv_sec, (long)raw_time.tv_usec,
> +   (long)tv_etime.tv_sec, (long)tv_etime.tv_usec,
> (long)vblank_time->tv_sec, (long)vblank_time->tv_usec,
> (int)duration_ns/1000, i);
>
>


Re: [BUG 3.7-rc1] nouveau cli-mutex possible recursive locking detected

2012-10-25 Thread Arend van Spriel

On 10/16/2012 02:43 PM, Stanislaw Gruszka wrote:

I have this lockdep warning on wireless-testing tree based
on 3.7-rc1 (no other patches except wireless bits).

=
Restarting tasks ... done.
[ INFO: possible recursive locking detected ]
3.7.0-rc1-wl+ #2 Not tainted
-
Xorg/2269 is trying to acquire lock:
  (cli-mutex){+.+.+.}, at: [a012a27f] 
nouveau_bo_move_m2mf+0x5f/0x170 [nouveau]

but task is already holding lock:
  (cli-mutex){+.+.+.}, at: [a012f3c4] nouveau_abi16_get+0x34/0x100 
[nouveau]



I have observed the same bug so I built and tested v3.7-rc2 tag with 
lockdep enabled. It has the same problem and it results in a failure to 
resume after suspend. See below.


Gr. AvS

[   76.272795] PM: suspend of devices complete after 2149.188 msecs
[   76.273110] PM: suspend devices took 2.152 seconds
[   76.273354] suspend debug: Waiting for 5 seconds.
[   81.233082] ehci_hcd :00:1a.0: setting latency timer to 64
[   81.233369] ehci_hcd :00:1d.0: setting latency timer to 64
[   81.233422] pci :00:1e.0: setting latency timer to 64
[   81.248934] e1000e :00:19.0: wake-up capability disabled by ACPI
[   81.249398] e1000e :00:19.0: irq 41 for MSI/MSI-X
[   81.249903] ahci :00:1f.2: setting latency timer to 64
[   81.249982] snd_hda_intel :00:1b.0: irq 43 for MSI/MSI-X
[   81.250515] nouveau  [ DRM] re-enabling device...
[   81.250548] nouveau  [ DRM] resuming client object trees...
[   81.250557] nouveau  [   VBIOS][:01:00.0] running init tables
[   81.701998] nouveau  [ DRM] resuming display...
[   81.803923] firewire_core :04:00.4: rediscovered device fw0
[   81.823913] dell_wmi: Received unknown WMI event (0x11)
[   81.824521] serial 00:08: activated
[   82.135333] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
[   82.187115] ata6: SATA link down (SStatus 0 SControl 300)
[   82.232290] ata2: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
[   82.284002] ata5: SATA link down (SStatus 0 SControl 300)
[   82.330629] ata1.00: ACPI cmd 00/00:00:00:00:00:a0 (NOP) rejected by 
device (Stat=0x51 Err=0x04)

[   82.408079] ata2.00: configured for UDMA/133
[   84.073571] ata1.00: failed to get Identify Device Data, Emask 0x1
[   84.127965] ata1.00: ACPI cmd 00/00:00:00:00:00:a0 (NOP) rejected by 
device (Stat=0x51 Err=0x04)

[   84.202292] ata1.00: failed to get Identify Device Data, Emask 0x1
[   84.254039] ata1.00: configured for UDMA/133
[   84.303718] sd 0:0:0:0: [sda] Starting disk
[   84.360186] PM: resume of devices complete after 3132.774 msecs
[   84.410322] PM: resume devices took 3.180 seconds
[   84.449642] PM: Finishing wakeup.
[   84.505964]
[   84.506716] e1000e: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow 
Control: Rx

[   84.477326] Restarting tasks ... done.
[   84.575294] video LNXVIDEO:00: Restoring backlight state
[   84.623825] =
[   84.623825] [ INFO: possible recursive locking detected ]
[   84.623826] 3.7.0-rc2-testing-lockdep #1 Not tainted
[   84.623827] -
[   84.623827] Xorg/1369 is trying to acquire lock:
[   84.623828]  (cli-mutex){+.+.+.}, at: [f8974ca8] 
nouveau_bo_move_m2mf.isra.13+0x38/0x120 [nouveau]

[   84.623856]
[   84.623856] but task is already holding lock:
[   84.623856]  (cli-mutex){+.+.+.}, at: [f8979346] 
nouveau_abi16_get+0x26/0x110 [nouveau]

[   84.623871]
[   84.623871] other info that might help us debug this:
[   84.623872]  Possible unsafe locking scenario:
[   84.623872]
[   84.623872]CPU0
[   84.623872]
[   84.623873]   lock(cli-mutex);
[   84.623874]   lock(cli-mutex);
[   84.623874]
[   84.623874]  *** DEADLOCK ***
[   84.623874]
[   84.623874]  May be due to missing lock nesting notation
[   84.623874]
[   84.623875] 1 lock held by Xorg/1369:
[   84.623889]  #0:  (cli-mutex){+.+.+.}, at: [f8979346] 
nouveau_abi16_get+0x26/0x110 [nouveau]

[   84.623890]


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


Re: [BUG 3.7-rc1] nouveau cli-mutex possible recursive locking detected

2012-10-25 Thread Arend van Spriel

On 10/24/2012 01:14 PM, Arend van Spriel wrote:

On 10/16/2012 02:43 PM, Stanislaw Gruszka wrote:

I have this lockdep warning on wireless-testing tree based
on 3.7-rc1 (no other patches except wireless bits).

=
Restarting tasks ... done.
[ INFO: possible recursive locking detected ]
3.7.0-rc1-wl+ #2 Not tainted
-
Xorg/2269 is trying to acquire lock:
  (cli-mutex){+.+.+.}, at: [a012a27f]
nouveau_bo_move_m2mf+0x5f/0x170 [nouveau]

but task is already holding lock:
  (cli-mutex){+.+.+.}, at: [a012f3c4]
nouveau_abi16_get+0x34/0x100 [nouveau]



I have observed the same bug so I built and tested v3.7-rc2 tag with
lockdep enabled. It has the same problem and it results in a failure to
resume after suspend. See below.

Gr. AvS


digging into the trace:


nouveau_gem_ioctl_pushbuf() calls nouveau_abi16_get() which grabs the 
mutex. Assume this should protect the chan variable passed to 
nouveau_gem_pushbuf_validate(), which does a bit more that validate as 
it ends up in nouveau_bo_move_m2mf() which uses the drm-chan. However, 
it deadlocks before that.


Gr. AvS

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


[PATCH] drivers/gpu/drm/radeon/evergreen_cs.c: Remove unnecessary semicolon

2012-10-25 Thread Peter Senna Tschudin
A simplified version of the semantic match that finds this problem is as
follows: (http://coccinelle.lip6.fr/)

// smpl
@r1@
statement S;
position p,p1;
@@
S@p1;@p

@script:python r2@
p  r1.p;
p1  r1.p1;
@@
if p[0].line != p1[0].line_end:
cocci.include_match(False)
@@
position r1.p;
@@
-;@p
// /smpl

Signed-off-by: Peter Senna Tschudin peter.se...@gmail.com

---

The full version of the semantic patch can be found at:
http://www.mail-archive.com/cocci@systeme.lip6.fr/msg00014.html

 drivers/gpu/drm/radeon/evergreen_cs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c 
b/drivers/gpu/drm/radeon/evergreen_cs.c
index 573ed1b..5daf0c5 100644
--- a/drivers/gpu/drm/radeon/evergreen_cs.c
+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -264,7 +264,7 @@ static int evergreen_surface_check_2d(struct 
radeon_cs_parser *p,
/* macro tile width  height */
palign = (8 * surf-bankw * track-npipes) * surf-mtilea;
halign = (8 * surf-bankh * surf-nbanks) / surf-mtilea;
-   mtileb = (palign / 8) * (halign / 8) * tileb;;
+   mtileb = (palign / 8) * (halign / 8) * tileb;
mtile_pr = surf-nbx / palign;
mtile_ps = (mtile_pr * surf-nby) / halign;
surf-layer_size = mtile_ps * mtileb * slice_pt;
-- 
1.7.11.7

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


Re: [drm:i915_hangcheck_hung] *ERROR* Hangcheck timer elapsed... GPU hung

2012-10-25 Thread Justin P. Mattock



On Tue, Oct 23, 2012 at 10:06:52AM -0700, Justin P. Mattock wrote:
  This is happening both with MAINLINE and NEXT.
 
  basically system is running fine, then under load system becomes
  really sluggish and unresponsive. I was able to get dmesg of the
  error..:
 
  [ 7745.007008] ath9k :05:00.0 wlan0: disabling VHT as WMM/QoS is
  not supported by the AP
  [ 7745.007736] wlan0: associate with 68:7f:74:b8:05:82 (try 1/3)
  [ 7745.011456] wlan0: RX AssocResp from 68:7f:74:b8:05:82
  (capab=0x411 status=0 aid=5)
  [ 7745.011529] wlan0: associated
  [ 8120.812482] [drm:i915_hangcheck_hung] *ERROR* Hangcheck timer
  elapsed... GPU hung
  [ 8120.812642] [drm] capturing error event; look for more
  information in /debug/dri/0/i915_error_state
  [ 8122.328682] [drm:i915_hangcheck_hung] *ERROR* Hangcheck timer
  elapsed... GPU hung
  [ 8122.328845] [drm:i915_reset] *ERROR* GPU hanging too fast,
  declaring wedged!
  [ 8122.328850] [drm:i915_reset] *ERROR* Failed to reset chip.
 
  full log is here: http://fpaste.org/7xH8/
 
  as for good kernels from what I remember 3.6.0-rc1. I can try a
  bisect on this once I get the time. or if anybody has a patch I can
  test.

Can you please rehand your machine, and then grab the i915_error_state
from debugfs? That contains the gpu hang dump we need to diagnose things.

And the bisect would obviously be awesome.

Thanks, Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch


took a bit to trigger, but finally fired off.

here is a link to the file..: intel_error_decode
http://www.filefactory.com/file/22bypyjhs4mx

the file was to large to send to the list.. let me know if you need more 
info with this.
also if anybody has any ideas to trigger this would be appreciated so 
the bisect can be more precise. right now dont even think its worth it, 
due to not being able to trigger the crash causing the bisect to go 
astray and pointing to a wrong commit(which has happened in the past) 
but then again you never know.


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


  1   2   >