Re: [PATCH v5 1/5] drm/i915: Add enable/disable flip done and flip done handler

2020-07-24 Thread Paulo Zanoni
Em seg, 2020-07-20 às 17:01 +0530, Karthik B S escreveu:
> Add enable/disable flip done functions and the flip done handler
> function which handles the flip done interrupt.
> 
> Enable the flip done interrupt in IER.
> 
> Enable flip done function is called before writing the
> surface address register as the write to this register triggers
> the flip done interrupt
> 
> Flip done handler is used to send the page flip event as soon as the
> surface address is written as per the requirement of async flips.
> The interrupt is disabled after the event is sent.
> 
> v2: -Change function name from icl_* to skl_* (Paulo)
> -Move flip handler to this patch (Paulo)
> -Remove vblank_put() (Paulo)
> -Enable flip done interrupt for gen9+ only (Paulo)
> -Enable flip done interrupt in power_well_post_enable hook (Paulo)
> -Removed the event check in flip done handler to handle async
>  flips without pageflip events.
> 
> v3: -Move skl_disable_flip_done out of interrupt handler (Paulo)
> -Make the pending vblank event NULL in the beginning of
>  flip_done_handler to remove sporadic WARN_ON that is seen.
> 
> v4: -Calculate timestamps using flip done time stamp and current
>  timestamp for async flips (Ville)
> 
> v5: -Fix the sparse warning by making the function 'g4x_get_flip_counter'
>  static.(Reported-by: kernel test robot )
> -Fix the typo in commit message.
> 
> Signed-off-by: Karthik B S 
> Signed-off-by: Vandita Kulkarni 
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 10 +++
>  drivers/gpu/drm/i915/i915_irq.c  | 83 ++--
>  drivers/gpu/drm/i915/i915_irq.h  |  2 +
>  drivers/gpu/drm/i915/i915_reg.h  |  4 +-
>  4 files changed, 91 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index db2a5a1a9b35..b8ff032195d9 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -15562,6 +15562,13 @@ static void intel_atomic_commit_tail(struct 
> intel_atomic_state *state)
>  
>   intel_dbuf_pre_plane_update(state);
>  
> + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
> + if (new_crtc_state->uapi.async_flip) {
> + skl_enable_flip_done(>base);
> + break;

Do we really want the break here? What if more than one CRTC wants an
async flip?

Perhaps you could extend IGT to try this.

> + }
> + }
> +
>   /* Now enable the clocks, plane, pipe, and connectors that we set up. */
>   dev_priv->display.commit_modeset_enables(state);
>  
> @@ -15583,6 +15590,9 @@ static void intel_atomic_commit_tail(struct 
> intel_atomic_state *state)
>   drm_atomic_helper_wait_for_flip_done(dev, >base);
>  
>   for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
> + if (new_crtc_state->uapi.async_flip)
> + skl_disable_flip_done(>base);

Here we don't break in the first found, so at least there's an
inconsistency.

> +
>   if (new_crtc_state->hw.active &&
>   !needs_modeset(new_crtc_state) &&
>   !new_crtc_state->preload_luts &&
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 1fa67700d8f4..95953b393941 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -697,14 +697,24 @@ u32 i915_get_vblank_counter(struct drm_crtc *crtc)
>   return (((high1 << 8) | low) + (pixel >= vbl_start)) & 0xff;
>  }
>  
> +static u32 g4x_get_flip_counter(struct drm_crtc *crtc)
> +{
> + struct drm_i915_private *dev_priv = to_i915(crtc->dev);
> + enum pipe pipe = to_intel_crtc(crtc)->pipe;
> +
> + return I915_READ(PIPE_FLIPCOUNT_G4X(pipe));
> +}
> +
>  u32 g4x_get_vblank_counter(struct drm_crtc *crtc)
>  {
>   struct drm_i915_private *dev_priv = to_i915(crtc->dev);
>   enum pipe pipe = to_intel_crtc(crtc)->pipe;
>  
> + if (crtc->state->async_flip)
> + return g4x_get_flip_counter(crtc);
> +
>   return I915_READ(PIPE_FRMCOUNT_G4X(pipe));

I don't understand the intention behind this, can you please clarify?
This goes back to my reply of the cover letter. It seems that here
we're going to alternate between two different counters in our vblank
count. So if user space alternates between sometimes using async flips
and sometimes using normal flip it's going to get some very weird
deltas, isn't it? At least this is what I remember from when I played
with these registers: FLIPCOUNT drifts away from FRMCOUNT when we start
using async flips.

IMHO we really need our IGT to exercise this possibility.

>  }
> -

Don't remove this blank line, please.

>  /*
>   * On certain encoders on certain platforms, pipe
>   * scanline register will not work to get the scanline,
> @@ -737,17 +747,24 @@ static u32 
> 

Re: [PATCH v5 2/5] drm/i915: Add support for async flips in I915

2020-07-24 Thread Paulo Zanoni
Em seg, 2020-07-20 às 17:01 +0530, Karthik B S escreveu:
> Set the Async Address Update Enable bit in plane ctl
> when async flip is requested.
> 
> v2: -Move the Async flip enablement to individual patch (Paulo)
> 
> v3: -Rebased.
> 
> v4: -Add separate plane hook for async flip case (Ville)
> 
> v5: -Rebased.
> 
> Signed-off-by: Karthik B S 
> Signed-off-by: Vandita Kulkarni 
> ---
>  drivers/gpu/drm/i915/display/intel_display.c |  6 +
>  drivers/gpu/drm/i915/display/intel_sprite.c  | 25 
>  drivers/gpu/drm/i915/i915_reg.h  |  1 +
>  3 files changed, 32 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index b8ff032195d9..4773f39e5924 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -4766,6 +4766,12 @@ u32 skl_plane_ctl(const struct intel_crtc_state 
> *crtc_state,
>   const struct drm_intel_sprite_colorkey *key = _state->ckey;
>   u32 plane_ctl;
>  
> + /* During Async flip, no other updates are allowed */

My understanding is that this function is fully setting the right bits
based on the chosen config (instead of doing read-modify-write), and
the checks for "other updates" were done before. So the logic
implemented here of early returning doesn't make sense.


> + if (crtc_state->uapi.async_flip) {
> + plane_ctl |= PLANE_CTL_ASYNC_FLIP;

I wonder why gcc does not complain we're ORing with an unitialized
value.


> + return plane_ctl;
> + }
> +
>   plane_ctl = PLANE_CTL_ENABLE;

It seems to be the return above means we'll never even try to enable
the plane, we're only relying on the fact that plane_ctl is not zero
initialize so maybe  bit 31 is already set.


>  
>   if (INTEL_GEN(dev_priv) < 10 && !IS_GEMINILAKE(dev_priv)) {
> diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c 
> b/drivers/gpu/drm/i915/display/intel_sprite.c
> index c26ca029fc0a..3747482e8fa3 100644
> --- a/drivers/gpu/drm/i915/display/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/display/intel_sprite.c
> @@ -603,6 +603,24 @@ icl_program_input_csc(struct intel_plane *plane,
> PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0);
>  }
>  
> +static void
> +skl_program_async_surface_address(struct drm_i915_private *dev_priv,
> +   const struct intel_plane_state *plane_state,
> +   enum pipe pipe, enum plane_id plane_id,
> +   u32 surf_addr)
> +{
> + unsigned long irqflags;
> + u32 plane_ctl = plane_state->ctl;
> +
> + spin_lock_irqsave(_priv->uncore.lock, irqflags);
> +
> + intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
> + intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
> +   intel_plane_ggtt_offset(plane_state) + surf_addr);
> +
> + spin_unlock_irqrestore(_priv->uncore.lock, irqflags);
> +}
> +
>  static void
>  skl_program_plane(struct intel_plane *plane,
> const struct intel_crtc_state *crtc_state,
> @@ -631,6 +649,13 @@ skl_program_plane(struct intel_plane *plane,
>   u32 keymsk, keymax;
>   u32 plane_ctl = plane_state->ctl;
>  
> + /* During Async flip, no other updates are allowed */
> + if (crtc_state->uapi.async_flip) {
> + skl_program_async_surface_address(dev_priv, plane_state,
> +   pipe, plane_id, surf_addr);
> + return;
> + }


I'd vote for us to keep the "don't rewrite registers that shouldn't
change" part on its own commit, since it's just an optimization. It
could even go at the end of the series. But perhaps this is simple
enough and not needed.


> +
>   plane_ctl |= skl_plane_ctl_crtc(crtc_state);
>  
>   if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 8cee06314d5d..19aad4199874 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -6935,6 +6935,7 @@ enum {
>  #define   PLANE_CTL_TILED_X  (1 << 10)
>  #define   PLANE_CTL_TILED_Y  (4 << 10)
>  #define   PLANE_CTL_TILED_YF (5 << 10)
> +#define   PLANE_CTL_ASYNC_FLIP   (1 << 9)
>  #define   PLANE_CTL_FLIP_HORIZONTAL  (1 << 8)
>  #define   PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE   (1 << 4) /* TGL+ */
>  #define   PLANE_CTL_ALPHA_MASK   (0x3 << 4) /* Pre-GLK */

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


Re: [PATCH v5 0/5] Asynchronous flip implementation for i915

2020-07-24 Thread Paulo Zanoni
Em seg, 2020-07-20 às 17:01 +0530, Karthik B S escreveu:
> Without async flip support in the kernel, fullscreen apps where game
> resolution is equal to the screen resolution, must perform an extra blit
> per frame prior to flipping.
> 
> Asynchronous page flips will also boost the FPS of Mesa benchmarks.

We had a discussion in patch 1 of v3 regarding the semantics of
asynchronous flips from the point of view of the user space: how we
handle our vblank counters, how/when we increment the sequence events
and how we handle timestamps, how/when we deliver vblank events. Since
apparently AMD has already enabled this feature, our job would be to
implement their current behavior so KMS clients can continue to work
regardless of the driver. 

From reading this series it's not super clear to me what exactly is the
behavior that we're trying to follow. Can you please document somewhere
what are these rules and expectations? This way, people writing user
space code (or people improving the other drivers) will have an easier
time. In addition to text documentation, I believe all our assumptions
and rules should be coded in IGT: we want to be confident a driver
implements async page flips correctly when we can verify it passes the
IGT.

Also, in the other patches I raise some additional questions regarding
mixing async with non-async vblanks: IMHO this should also be
documented as text and as IGT.

> 
> v2: -Few patches have been squashed and patches have been shuffled as
>  per the reviews on the previous version.
> 
> v3: -Few patches have been squashed and patches have been shuffled as
>  per the reviews on the previous version.
> 
> v4: -Made changes to fix the sequence and time stamp issue as per the
>  comments received on the previous version.
> -Timestamps are calculated using the flip done time stamp and current
>  timestamp. Here I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP flag is used
>  for timestamp calculations.
> -Event is sent from the interrupt handler immediately using this
>  updated timestamps and sequence.
> -Added more state checks as async flip should only allow change in plane
>  surface address and nothing else should be allowed to change.
> -Added a separate plane hook for async flip.
> -Need to find a way to reject fbc enabling if it comes as part of this
>  flip as bspec states that changes to FBC are not allowed.
> 
> v5: -Fixed the Checkpatch and sparse warnings.
> 
> Karthik B S (5):
>   drm/i915: Add enable/disable flip done and flip done handler
>   drm/i915: Add support for async flips in I915
>   drm/i915: Add checks specific to async flips
>   drm/i915: Do not call drm_crtc_arm_vblank_event in async flips
>   drm/i915: Enable async flips in i915
> 
>  drivers/gpu/drm/i915/display/intel_display.c | 123 +++
>  drivers/gpu/drm/i915/display/intel_sprite.c  |  33 -
>  drivers/gpu/drm/i915/i915_irq.c  |  83 +++--
>  drivers/gpu/drm/i915/i915_irq.h  |   2 +
>  drivers/gpu/drm/i915/i915_reg.h  |   5 +-
>  5 files changed, 237 insertions(+), 9 deletions(-)
> 

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


Re: [PATCH] i915: disable framebuffer compression on GeminiLake

2019-04-24 Thread Paulo Zanoni
Em qua, 2019-04-24 às 20:58 +0100, Chris Wilson escreveu:
> Quoting Jian-Hong Pan (2019-04-23 10:28:10)
> > From: Daniel Drake 
> > 
> > On many (all?) the Gemini Lake systems we work with, there is frequent
> > momentary graphical corruption at the top of the screen, and it seems
> > that disabling framebuffer compression can avoid this.
> > 
> > The ticket was reported 6 months ago and has already affected a
> > multitude of users, without any real progress being made. So, lets
> > disable framebuffer compression on GeminiLake until a solution is found.
> > 
> > Buglink: https://bugs.freedesktop.org/show_bug.cgi?id=108085
> > Signed-off-by: Daniel Drake 
> > Signed-off-by: Jian-Hong Pan 
> 
> Fixes: fd7d6c5c8f3e ("drm/i915: enable FBC on gen9+ too") ?
> Cc: Paulo Zanoni 
> Cc: Daniel Vetter 
> Cc: Jani Nikula 
> Cc:  # v4.11+
> 
> glk landed 1 month before, so that seems the earliest broken point.
> 

The bug is well reported, the bug author is helpful and it even has a
description of "steps to reproduce" that looks very easy (although I
didn't try it). Everything suggests this is a bug the display team
could actually solve with not-so-many hours of debugging.

In the meantime, unbreak the systems:
Reviewed-by: Paulo Zanoni 

> > ---
> >  drivers/gpu/drm/i915/intel_fbc.c | 4 
> >  1 file changed, 4 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_fbc.c 
> > b/drivers/gpu/drm/i915/intel_fbc.c
> > index 656e684e7c9a..fc018f3f53a1 100644
> > --- a/drivers/gpu/drm/i915/intel_fbc.c
> > +++ b/drivers/gpu/drm/i915/intel_fbc.c
> > @@ -1278,6 +1278,10 @@ static int intel_sanitize_fbc_option(struct 
> > drm_i915_private *dev_priv)
> > if (!HAS_FBC(dev_priv))
> > return 0;
> >  
> > +   /* https://bugs.freedesktop.org/show_bug.cgi?id=108085 */
> > +   if (IS_GEMINILAKE(dev_priv))
> > +   return 0;
> > +
> > if (IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9)
> > return 1;
> >  
> > -- 
> > 2.21.0
> > 

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

Re: [PATCH] drm/i915/dp: fix shifting by a negative number of bits

2018-09-12 Thread Paulo Zanoni
Em Qua, 2018-09-12 às 09:31 -0500, Gustavo A. R. Silva escreveu:
> Function intel_port_to_tc() returns PORT_TC_NONE on error, which is
> a negative value -1. In case PORT_TC_NONE is returned, there is an
> undefined behavior when shifting by a negative number of bits in
> both DP_PHY_MODE_STATUS_NOT_SAFE and P_PHY_MODE_STATUS_COMPLETED
> macros.
> 
> Fix this by adding sanity checks on intel_port_to_tc return value,
> before
> using macros DP_PHY_MODE_STATUS_NOT_SAFE and
> P_PHY_MODE_STATUS_COMPLETED.

This was just discussed yesterday in a patch by Rodrigo:

https://patchwork.freedesktop.org/patch/246903/

I would personally prefer his version because it avoids passing -1 to
register macros that Coverity doesn't seem to care about, it's a single
check and it prints WARN() instead of DRM_DEBUG_KMS().

Although I do prefer your commit message explanation :).

Perhaps I should reconsider my vote to not merge it. Or we could
actually go and test what happens when intel_port_to_tc() is broken,
fixing all the issues instead of just the ones reported by Coverity.

Anyway, Rodrigo's patch with an improved commit message could receive
my R-B tag now.

> 
> Addresses-Coverity-ID: 1473324 ("Bad bit shift operation")
> Addresses-Coverity-ID: 1473325 ("Bad bit shift operation")
> Fixes: 39d1e234e1e1 ("drm/i915/icl: implement the tc/legacy HPD
> {dis,}connect flows")
> Signed-off-by: Gustavo A. R. Silva 
> ---
>  drivers/gpu/drm/i915/intel_dp.c | 9 +
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp.c
> b/drivers/gpu/drm/i915/intel_dp.c
> index 436c22d..e34b7b1 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -4811,6 +4811,11 @@ static bool icl_tc_phy_connect(struct
> drm_i915_private *dev_priv,
>   dig_port->tc_type != TC_PORT_TYPEC)
>   return true;
>  
> + if (tc_port < 0) {
> + DRM_DEBUG_KMS("Bad TC port %d\n", tc_port);
> + return false;
> + }
> +
>   val = I915_READ(PORT_TX_DFLEXDPPMS);
>   if (!(val & DP_PHY_MODE_STATUS_COMPLETED(tc_port))) {
>   DRM_DEBUG_KMS("DP PHY for TC port %d not ready\n",
> tc_port);
> @@ -4857,6 +4862,10 @@ static void icl_tc_phy_disconnect(struct
> drm_i915_private *dev_priv,
>   dig_port->tc_type != TC_PORT_TYPEC)
>   return;
>  
> + if (tc_port < 0) {
> + DRM_DEBUG_KMS("Bad TC port %d\n", tc_port);
> + return;
> + }
>   /*
>* This function may be called many times in a row without
> an HPD event
>* in between, so try to avoid the write when we can.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/dp: add missing ')' to I2C nack debug message

2018-07-27 Thread Paulo Zanoni
 "(an unmatched left parenthesis
  creates an unresolved tension
  that will stay with you all day."
   -- Randall Munroe

Signed-off-by: Paulo Zanoni 
---
 drivers/gpu/drm/drm_dp_helper.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 0cccbcb2d03e..8c6b9fd89f8a 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -850,7 +850,8 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct 
drm_dp_aux_msg *msg)
return ret;
 
case DP_AUX_I2C_REPLY_NACK:
-   DRM_DEBUG_KMS("I2C nack (result=%d, size=%zu\n", ret, 
msg->size);
+   DRM_DEBUG_KMS("I2C nack (result=%d, size=%zu)\n",
+ ret, msg->size);
aux->i2c_nack_count++;
return -EREMOTEIO;
 
-- 
2.14.4

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


Re: [PATCH libdrm] intel: add support for ICL 11

2018-05-01 Thread Paulo Zanoni
Em Qua, 2018-04-25 às 17:29 -0700, Michel Thierry escreveu:
> On 04/25/2018 05:09 PM, Paulo Zanoni wrote:
> > Add the PCI IDs and the basic code to enable ICL.  This is the
> > current
> > PCI ID list in our documentation.
> > 
> > Kernel commit: d55cb4fa2cf0 ("drm/i915/icl: Add the ICL PCI IDs")
> > 
> > v2: Michel provided a fix to IS_9XX that was broken by rebase bot.
> > v3: Fix double definition of PCI IDs, update IDs according to bspec
> >  and keep them in the same order and rebase (Lucas)
> > 
> > Cc: Michel Thierry <michel.thie...@intel.com>
> > Signed-off-by: Paulo Zanoni <paulo.r.zan...@intel.com>
> > Signed-off-by: Rodrigo Vivi <rodrigo.v...@intel.com>
> > Signed-off-by: Lucas De Marchi <lucas.demar...@intel.com>
> > ---
> >   intel/intel_bufmgr_gem.c |  2 ++
> >   intel/intel_chipset.h| 27 ++-
> >   intel/intel_decode.c |  4 +++-
> >   3 files changed, 31 insertions(+), 2 deletions(-)
> > 
> > diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
> > index 5c47a46f..8c3a4b20 100644
> > --- a/intel/intel_bufmgr_gem.c
> > +++ b/intel/intel_bufmgr_gem.c
> > @@ -3660,6 +3660,8 @@ drm_intel_bufmgr_gem_init(int fd, int
> > batch_size)
> > bufmgr_gem->gen = 9;
> > else if (IS_GEN10(bufmgr_gem->pci_device))
> > bufmgr_gem->gen = 10;
> > +   else if (IS_GEN11(bufmgr_gem->pci_device))
> > +   bufmgr_gem->gen = 11;
> > else {
> > free(bufmgr_gem);
> > bufmgr_gem = NULL;
> > diff --git a/intel/intel_chipset.h b/intel/intel_chipset.h
> > index ba2e3ac1..32b2c48f 100644
> > --- a/intel/intel_chipset.h
> > +++ b/intel/intel_chipset.h
> > @@ -257,6 +257,16 @@
> >   #define PCI_CHIP_CANNONLAKE_120x5A44
> >   #define PCI_CHIP_CANNONLAKE_130x5A4C
> >   
> > +#define PCI_CHIP_ICELAKE_11_0  0x8A50
> > +#define PCI_CHIP_ICELAKE_11_1  0x8A51
> > +#define PCI_CHIP_ICELAKE_11_2  0x8A5C
> > +#define PCI_CHIP_ICELAKE_11_3  0x8A5D
> > +#define PCI_CHIP_ICELAKE_11_4  0x8A52
> > +#define PCI_CHIP_ICELAKE_11_5  0x8A5A
> > +#define PCI_CHIP_ICELAKE_11_6  0x8A5B
> > +#define PCI_CHIP_ICELAKE_11_7  0x8A71
> > +#define PCI_CHIP_ICELAKE_11_8  0x8A70
> > +
> 
> matches what we have in the kernel's i915_pciids.h
> 
> >   #define IS_MOBILE(devid)  ((devid) == PCI_CHIP_I855_GM || \
> >  (devid) == PCI_CHIP_I915_GM || \
> >  (devid) == PCI_CHIP_I945_GM || \
> > @@ -538,6 +548,20 @@
> >   
> >   #define IS_GEN10(devid)   (IS_CANNONLAKE(devid))
> >   
> > +#define IS_ICELAKE_11(devid)   ((devid) ==
> > PCI_CHIP_ICELAKE_11_0 || \
> > +(devid) == PCI_CHIP_ICELAKE_11_1
> > || \
> > +(devid) == PCI_CHIP_ICELAKE_11_2
> > || \
> > +(devid) == PCI_CHIP_ICELAKE_11_3
> > || \
> > +(devid) == PCI_CHIP_ICELAKE_11_4
> > || \
> > +(devid) == PCI_CHIP_ICELAKE_11_5
> > || \
> > +(devid) == PCI_CHIP_ICELAKE_11_6
> > || \
> > +(devid) == PCI_CHIP_ICELAKE_11_7
> > || \
> > +(devid) == PCI_CHIP_ICELAKE_11_8)
> > +
> > +#define IS_ICELAKE(devid)  (IS_ICELAKE_11(devid))
> > +
> > +#define IS_GEN11(devid)(IS_ICELAKE_11(devid))
> > +
> >   #define IS_9XX(dev)   (IS_GEN3(dev) || \
> >  IS_GEN4(dev) || \
> >  IS_GEN5(dev) || \
> > @@ -545,6 +569,7 @@
> >  IS_GEN7(dev) || \
> >  IS_GEN8(dev) || \
> >  IS_GEN9(dev) || \
> > -IS_GEN10(dev))
> > +IS_GEN10(dev) || \
> > +IS_GEN11(dev))
> >   
> >   #endif /* _INTEL_CHIPSET_H */
> > diff --git a/intel/intel_decode.c b/intel/intel_decode.c
> > index bc7b04b8..b24861b1 100644
> > --- a/intel/intel_decode.c
> > +++ b/intel/intel_decode.c
> > @@ -3823,7 +3823,9 @@ drm_intel_decode_context_alloc(uint32_t
> > devid)
> > ctx->devid = devid;
> > ctx->out = stdout;
> >   
> > -   if (IS_GEN10(devid))
> > +   if (IS_GEN11(devid))
> > +   ctx->gen = 11;
> > +   else if (IS_GEN10(devid))
> > ctx->gen = 10;
> > else if (IS_GEN9(devid))
> > ctx->gen = 9;
> > 
> 
> Reviewed-by: Michel Thierry <michel.thie...@intel.com>

Patch merged. Thanks everybody involved.

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


[PATCH libdrm] intel: add support for ICL 11

2018-04-25 Thread Paulo Zanoni
Add the PCI IDs and the basic code to enable ICL.  This is the current
PCI ID list in our documentation.

Kernel commit: d55cb4fa2cf0 ("drm/i915/icl: Add the ICL PCI IDs")

v2: Michel provided a fix to IS_9XX that was broken by rebase bot.
v3: Fix double definition of PCI IDs, update IDs according to bspec
and keep them in the same order and rebase (Lucas)

Cc: Michel Thierry <michel.thie...@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zan...@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.v...@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demar...@intel.com>
---
 intel/intel_bufmgr_gem.c |  2 ++
 intel/intel_chipset.h| 27 ++-
 intel/intel_decode.c |  4 +++-
 3 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
index 5c47a46f..8c3a4b20 100644
--- a/intel/intel_bufmgr_gem.c
+++ b/intel/intel_bufmgr_gem.c
@@ -3660,6 +3660,8 @@ drm_intel_bufmgr_gem_init(int fd, int batch_size)
bufmgr_gem->gen = 9;
else if (IS_GEN10(bufmgr_gem->pci_device))
bufmgr_gem->gen = 10;
+   else if (IS_GEN11(bufmgr_gem->pci_device))
+   bufmgr_gem->gen = 11;
else {
free(bufmgr_gem);
bufmgr_gem = NULL;
diff --git a/intel/intel_chipset.h b/intel/intel_chipset.h
index ba2e3ac1..32b2c48f 100644
--- a/intel/intel_chipset.h
+++ b/intel/intel_chipset.h
@@ -257,6 +257,16 @@
 #define PCI_CHIP_CANNONLAKE_12 0x5A44
 #define PCI_CHIP_CANNONLAKE_13 0x5A4C
 
+#define PCI_CHIP_ICELAKE_11_0  0x8A50
+#define PCI_CHIP_ICELAKE_11_1  0x8A51
+#define PCI_CHIP_ICELAKE_11_2  0x8A5C
+#define PCI_CHIP_ICELAKE_11_3  0x8A5D
+#define PCI_CHIP_ICELAKE_11_4  0x8A52
+#define PCI_CHIP_ICELAKE_11_5  0x8A5A
+#define PCI_CHIP_ICELAKE_11_6  0x8A5B
+#define PCI_CHIP_ICELAKE_11_7  0x8A71
+#define PCI_CHIP_ICELAKE_11_8  0x8A70
+
 #define IS_MOBILE(devid)   ((devid) == PCI_CHIP_I855_GM || \
 (devid) == PCI_CHIP_I915_GM || \
 (devid) == PCI_CHIP_I945_GM || \
@@ -538,6 +548,20 @@
 
 #define IS_GEN10(devid)(IS_CANNONLAKE(devid))
 
+#define IS_ICELAKE_11(devid)   ((devid) == PCI_CHIP_ICELAKE_11_0 || \
+(devid) == PCI_CHIP_ICELAKE_11_1 || \
+(devid) == PCI_CHIP_ICELAKE_11_2 || \
+(devid) == PCI_CHIP_ICELAKE_11_3 || \
+(devid) == PCI_CHIP_ICELAKE_11_4 || \
+(devid) == PCI_CHIP_ICELAKE_11_5 || \
+(devid) == PCI_CHIP_ICELAKE_11_6 || \
+(devid) == PCI_CHIP_ICELAKE_11_7 || \
+(devid) == PCI_CHIP_ICELAKE_11_8)
+
+#define IS_ICELAKE(devid)  (IS_ICELAKE_11(devid))
+
+#define IS_GEN11(devid)(IS_ICELAKE_11(devid))
+
 #define IS_9XX(dev)(IS_GEN3(dev) || \
 IS_GEN4(dev) || \
 IS_GEN5(dev) || \
@@ -545,6 +569,7 @@
 IS_GEN7(dev) || \
 IS_GEN8(dev) || \
 IS_GEN9(dev) || \
-IS_GEN10(dev))
+IS_GEN10(dev) || \
+IS_GEN11(dev))
 
 #endif /* _INTEL_CHIPSET_H */
diff --git a/intel/intel_decode.c b/intel/intel_decode.c
index bc7b04b8..b24861b1 100644
--- a/intel/intel_decode.c
+++ b/intel/intel_decode.c
@@ -3823,7 +3823,9 @@ drm_intel_decode_context_alloc(uint32_t devid)
ctx->devid = devid;
ctx->out = stdout;
 
-   if (IS_GEN10(devid))
+   if (IS_GEN11(devid))
+   ctx->gen = 11;
+   else if (IS_GEN10(devid))
ctx->gen = 10;
else if (IS_GEN9(devid))
ctx->gen = 9;
-- 
2.14.3

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


[Intel-gfx] [PATCH 9/9] drm/i915: Add render decompression support

2017-01-04 Thread Paulo Zanoni
Em Qua, 2017-01-04 às 20:42 +0200, ville.syrjala at linux.intel.com
escreveu:
> From: Ville Syrjälä 
> 
> SKL+ display engine can scan out certain kinds of compressed surfaces
> produced by the render engine. This involved telling the display
> engine
> the location of the color control surfae (CCS) which describes
> which parts of the main surface are compressed and which are not. The
> location of CCS is provided by userspace as just another plane with
> its
> own offset.
> 
> Add the required stuff to validate the user provided AUX plane
> metadata
> and convert the user provided linear offset into something the
> hardware
> can consume.
> 
> Due to hardware limitations we require that the main surface and
> the AUX surface (CCS) be part of the same bo. The hardware also
> makes life hard by not allowing you to provide separate x/y offsets
> for the main and AUX surfaces (excpet with NV12), so finding suitable
> offsets for both requires a bit of work. Assuming we still want keep
> playing tricks with the offsets. I've just gone with a dumb "search
> backward for suitable offsets" approach, which is far from optimal,
> but it works.
> 
> Also not all planes will be capable of scanning out compressed
> surfaces,
> and eg. 90/270 degree rotation is not supported in combination with
> decompression either.
> 
> This patch may contain work from at least the following people:
> * Vandana Kannan 
> * Daniel Vetter 
> * Ben Widawsky 

As I mentioned to Ben in the other email, there are some points of
BSpec that say "if render decompression is enabled, to this", which we
largely ignored so far. I hope they are all marked as workarounds. From
a quick look, it looks like we need at least Display WAs #0390, #0531
and #1125, and maybe some other non-display WAs (please take a look at
the BSpec list). I'll assume they were not implemented yet since I
don't see WA comments on the patches. I think we need them, otherwise
we may introduce more SKL flickering problems.

Thanks,
Paulo

> 
> Cc: Vandana Kannan 
> Cc: Daniel Vetter 
> Cc: Ben Widawsky 
> Cc: Jason Ekstrand 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/i915_reg.h      |  22 
>  drivers/gpu/drm/i915/intel_display.c | 219
> +--
>  drivers/gpu/drm/i915/intel_pm.c      |   8 +-
>  drivers/gpu/drm/i915/intel_sprite.c  |   5 +
>  4 files changed, 240 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h
> b/drivers/gpu/drm/i915/i915_reg.h
> index 00970aa77afa..05e18e742776 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -6209,6 +6209,28 @@ enum {
>  _ID(id, _PS_ECC_STAT_1A,
> _PS_ECC_STAT_2A),   \
>  _ID(id, _PS_ECC_STAT_1B, _PS_ECC_STAT_2B))
>  
> +#define PLANE_AUX_DIST_1_A   0x701c0
> +#define PLANE_AUX_DIST_2_A   0x702c0
> +#define PLANE_AUX_DIST_1_B   0x711c0
> +#define PLANE_AUX_DIST_2_B   0x712c0
> +#define _PLANE_AUX_DIST_1(pipe) \
> + _PIPE(pipe, PLANE_AUX_DIST_1_A,
> PLANE_AUX_DIST_1_B)
> +#define _PLANE_AUX_DIST_2(pipe) \
> + _PIPE(pipe, PLANE_AUX_DIST_2_A,
> PLANE_AUX_DIST_2_B)
> +#define PLANE_AUX_DIST(pipe, plane)     \
> + _MMIO_PLANE(plane, _PLANE_AUX_DIST_1(pipe),
> _PLANE_AUX_DIST_2(pipe))
> +
> +#define PLANE_AUX_OFFSET_1_A 0x701c4
> +#define PLANE_AUX_OFFSET_2_A 0x702c4
> +#define PLANE_AUX_OFFSET_1_B 0x711c4
> +#define PLANE_AUX_OFFSET_2_B 0x712c4
> +#define _PLANE_AUX_OFFSET_1(pipe)       \
> + _PIPE(pipe, PLANE_AUX_OFFSET_1_A,
> PLANE_AUX_OFFSET_1_B)
> +#define _PLANE_AUX_OFFSET_2(pipe)       \
> + _PIPE(pipe, PLANE_AUX_OFFSET_2_A,
> PLANE_AUX_OFFSET_2_B)
> +#define PLANE_AUX_OFFSET(pipe, plane)   \
> + _MMIO_PLANE(plane, _PLANE_AUX_OFFSET_1(pipe),
> _PLANE_AUX_OFFSET_2(pipe))
> +
>  /* legacy palette */
>  #define _LGC_PALETTE_A           0x4a000
>  #define _LGC_PALETTE_B           0x4a800
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index 38de9df0ec60..b547332eeda1 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2064,11 +2064,19 @@ intel_tile_width_bytes(const struct
> drm_framebuffer *fb, int plane)
>  return 128;
>  else
>  return 512;
> + case I915_FORMAT_MOD_Y_TILED_CCS:
> + if (plane == 1)
> + return 64;
> + /* fall through */
>  case I915_FORMAT_MOD_Y_TILED:
>  if (IS_GEN2(dev_priv) ||
> HAS_128_BYTE_Y_TILING(dev_priv))
>  return 128;
>  else
>  return 512;
> + case I915_FORMAT_MOD_Yf_TILED_CCS:
> + if (plane == 1)
> + return 64;
> +   

[Intel-gfx] [PATCH 17/19] drm/i915: Use new atomic iterator macros in wm code

2016-11-03 Thread Paulo Zanoni
Em Qui, 2016-11-03 às 18:49 +0200, Ville Syrjälä escreveu:
> On Mon, Oct 17, 2016 at 02:37:16PM +0200, Maarten Lankhorst wrote:
> > 
> > Signed-off-by: Maarten Lankhorst  > >
> > ---
> >  drivers/gpu/drm/i915/intel_pm.c | 12 ++--
> >  1 file changed, 6 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c
> > b/drivers/gpu/drm/i915/intel_pm.c
> > index 2df06b703e3d..163b73b493bf 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -3227,7 +3227,7 @@ skl_get_total_relative_data_rate(struct
> > intel_crtc_state *intel_cstate)
> >    return 0;
> >  
> >    /* Calculate and cache data rate for each plane */
> > -   for_each_plane_in_state(state, plane, pstate, i) {
> > +   for_each_new_plane_in_state(state, plane, pstate, i) {
> 
> Looks like this patch needs a refresh due to my tardiness in
> reviewing
> it.
> 
> Also unrelated, but I recently noticed that
> skl_get_total_relative_data_rate() doesn't exclude the cursor plane
> from the calculation. I'm thinking it should. Adding some Cc:s...

It seems we're safe because skl_plane_relative_data_rate() returns 0
for cursor. But an explicitly check at the caller would probably be
much much better instead of hidden deep in the code. OTOH, Matt's plans
to exclude cursor case-handling would remove this need again.

> 
> > 
> >    id = skl_wm_plane_id(to_intel_plane(plane));
> >    intel_plane = to_intel_plane(plane);
> >  
> > @@ -3364,14 +3364,14 @@ skl_allocate_pipe_ddb(struct
> > intel_crtc_state *cstate,
> >    alloc_size -= cursor_blocks;
> >  
> >    /* 1. Allocate the mininum required blocks for each active
> > plane */
> > -   for_each_plane_in_state(state, plane, pstate, i) {
> > +   for_each_new_plane_in_state(state, plane, pstate, i) {
> >    intel_plane = to_intel_plane(plane);
> >    id = skl_wm_plane_id(intel_plane);
> >  
> >    if (intel_plane->pipe != pipe)
> >    continue;
> >  
> > -   if (!to_intel_plane_state(pstate)->base.visible) {
> > +   if (!pstate->visible) {
> >    minimum[id] = 0;
> >    y_minimum[id] = 0;
> >    continue;
> > @@ -3933,7 +3933,7 @@ pipes_modified(struct drm_atomic_state
> > *state)
> >    struct drm_crtc_state *cstate;
> >    uint32_t i, ret = 0;
> >  
> > -   for_each_crtc_in_state(state, crtc, cstate, i)
> > +   for_each_new_crtc_in_state(state, crtc, cstate, i)
> >    ret |= drm_crtc_mask(crtc);
> >  
> >    return ret;
> > @@ -4048,7 +4048,7 @@ skl_compute_wm(struct drm_atomic_state
> > *state)
> >     * since any racing commits that want to update them would
> > need to
> >     * hold _all_ CRTC state mutexes.
> >     */
> > -   for_each_crtc_in_state(state, crtc, cstate, i)
> > +   for_each_new_crtc_in_state(state, crtc, cstate, i)
> >    changed = true;
> >    if (!changed)
> >    return 0;
> > @@ -4070,7 +4070,7 @@ skl_compute_wm(struct drm_atomic_state
> > *state)
> >     * should allow skl_update_pipe_wm() to return failure in
> > cases where
> >     * no suitable watermark values can be found.
> >     */
> > -   for_each_crtc_in_state(state, crtc, cstate, i) {
> > +   for_each_new_crtc_in_state(state, crtc, cstate, i) {
> >    struct intel_crtc *intel_crtc =
> > to_intel_crtc(crtc);
> >    struct intel_crtc_state *intel_cstate =
> >    to_intel_crtc_state(cstate);
> > -- 
> > 2.7.4
> > 
> > ___
> > Intel-gfx mailing list
> > Intel-gfx at lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 


[Intel-gfx] [PATCH 16/19] drm/i915: Use new atomic iterator macros in fbc

2016-11-03 Thread Paulo Zanoni
Em Qui, 2016-11-03 às 18:45 +0200, Ville Syrjälä escreveu:
> On Mon, Oct 17, 2016 at 02:37:15PM +0200, Maarten Lankhorst wrote:
> > 
> > Signed-off-by: Maarten Lankhorst  > >
> > ---
> >  drivers/gpu/drm/i915/intel_fbc.c | 6 +++---
> >  1 file changed, 3 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_fbc.c
> > b/drivers/gpu/drm/i915/intel_fbc.c
> > index faa67624e1ed..0028335fc1bb 100644
> > --- a/drivers/gpu/drm/i915/intel_fbc.c
> > +++ b/drivers/gpu/drm/i915/intel_fbc.c
> > @@ -1060,7 +1060,7 @@ void intel_fbc_choose_crtc(struct
> > drm_i915_private *dev_priv,
> >  
> >    mutex_lock(>lock);
> >  
> > -   for_each_crtc_in_state(state, crtc, crtc_state, i) {
> > +   for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
> >    if (fbc->crtc == to_intel_crtc(crtc)) {
> >    fbc_crtc_present = true;
> >    break;
> > @@ -1074,14 +1074,14 @@ void intel_fbc_choose_crtc(struct
> > drm_i915_private *dev_priv,
> >     * plane. We could go for fancier schemes such as checking
> > the plane
> >     * size, but this would just affect the few platforms that
> > don't tie FBC
> >     * to pipe or plane A. */
> > -   for_each_plane_in_state(state, plane, plane_state, i) {
> > +   for_each_new_plane_in_state(state, plane, plane_state, i)
> > {
> >    struct intel_plane_state *intel_plane_state =
> >    to_intel_plane_state(plane_state);
> >  
> >    if (!intel_plane_state->base.visible)
> >    continue;
> 
> Unrelated but this thing looks somewhat bogus. FBC is tied to the
> primary plane only, so why do we care about the visibility of the
> other
> planes? Adding Paulo to Cc...

Looks like you've found a bug... Thanks! We should really be iterating
over primary planes only. Adding to the TODO list.

> 
> > 
> >  
> > -   for_each_crtc_in_state(state, crtc, crtc_state, j)
> > {
> > +   for_each_new_crtc_in_state(state, crtc,
> > crtc_state, j) {
> 
> Also, can't this inner loop be replaced with a simple
> crtc = plane_state->crtc ?

Is there a way to get the proposed crtc_state without the loop?


> 
> > 
> >    struct intel_crtc_state *intel_crtc_state
> > =
> >    to_intel_crtc_state(crtc_state);
> >  
> > -- 
> > 2.7.4
> > 
> > ___
> > Intel-gfx mailing list
> > Intel-gfx at lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 


[PATCH v2 07/10] drm/i915/gen9: Make skl_pipe_wm_get_hw_state() reusable

2016-10-18 Thread Paulo Zanoni
Em Sex, 2016-10-14 às 17:31 -0400, Lyude escreveu:
> There's not much of a reason this should have the locations to read
> out
> the hardware state hardcoded, so allow the caller to specify the
> location and add this function to intel_drv.h. As well, we're going
> to
> need this function to be reusable for the next patch.
> 
> Changes since v1:
> - Fix accidental behavior change in the code that Paulo pointed out

Reviewed-by: Paulo Zanoni 

I just submitted v4 of patch 5 solving the conflicts I created. With
that + this review, we can merge this series. If you give me an ack on
patch 5 I can just go and merge these, so we can move to Maarten's
series and then later to Mahesh's series.

> 
> Signed-off-by: Lyude 
> Cc: Maarten Lankhorst 
> Cc: Ville Syrjälä 
> Cc: Matt Roper  Cc: Paulo Zanoni 
> ---
>  drivers/gpu/drm/i915/intel_drv.h |  2 ++
>  drivers/gpu/drm/i915/intel_pm.c  | 28 ++--
>  2 files changed, 20 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index a85ce2c..7036310 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1756,6 +1756,8 @@ void ilk_wm_get_hw_state(struct drm_device
> *dev);
>  void skl_wm_get_hw_state(struct drm_device *dev);
>  void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
>    struct skl_ddb_allocation *ddb /* out */);
> +void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc,
> +       struct skl_pipe_wm *out);
>  bool intel_can_enable_sagv(struct drm_atomic_state *state);
>  int intel_enable_sagv(struct drm_i915_private *dev_priv);
>  int intel_disable_sagv(struct drm_i915_private *dev_priv);
> diff --git a/drivers/gpu/drm/i915/intel_pm.c
> b/drivers/gpu/drm/i915/intel_pm.c
> index 2fe851e..6eaeb87 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -4288,15 +4288,13 @@ static inline void
> skl_wm_level_from_reg_val(uint32_t val,
>  PLANE_WM_LINES_MASK;
>  }
>  
> -static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
> +void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc,
> +       struct skl_pipe_wm *out)
>  {
>  struct drm_device *dev = crtc->dev;
>  struct drm_i915_private *dev_priv = to_i915(dev);
> - struct skl_wm_values *hw = _priv->wm.skl_hw;
>  struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> - struct intel_crtc_state *cstate = to_intel_crtc_state(crtc-
> >state);
>  struct intel_plane *intel_plane;
> - struct skl_pipe_wm *active = >wm.skl.optimal;
>  struct skl_plane_wm *wm;
>  enum pipe pipe = intel_crtc->pipe;
>  int level, id, max_level;
> @@ -4306,7 +4304,7 @@ static void skl_pipe_wm_get_hw_state(struct
> drm_crtc *crtc)
>  
>  for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
>  id = skl_wm_plane_id(intel_plane);
> - wm = >wm.skl.optimal.planes[id];
> + wm = >planes[id];
>  
>  for (level = 0; level <= max_level; level++) {
>  if (id != PLANE_CURSOR)
> @@ -4328,20 +4326,30 @@ static void skl_pipe_wm_get_hw_state(struct
> drm_crtc *crtc)
>  if (!intel_crtc->active)
>  return;
>  
> - hw->dirty_pipes |= drm_crtc_mask(crtc);
> - active->linetime = I915_READ(PIPE_WM_LINETIME(pipe));
> - intel_crtc->wm.active.skl = *active;
> + out->linetime = I915_READ(PIPE_WM_LINETIME(pipe));
>  }
>  
>  void skl_wm_get_hw_state(struct drm_device *dev)
>  {
>  struct drm_i915_private *dev_priv = to_i915(dev);
> + struct skl_wm_values *hw = _priv->wm.skl_hw;
>  struct skl_ddb_allocation *ddb = _priv->wm.skl_hw.ddb;
>  struct drm_crtc *crtc;
> + struct intel_crtc *intel_crtc;
> + struct intel_crtc_state *cstate;
>  
>  skl_ddb_get_hw_state(dev_priv, ddb);
> - list_for_each_entry(crtc, >mode_config.crtc_list, head)
> - skl_pipe_wm_get_hw_state(crtc);
> + list_for_each_entry(crtc, >mode_config.crtc_list, head)
> {
> + intel_crtc = to_intel_crtc(crtc);
> + cstate = to_intel_crtc_state(crtc->state);
> +
> + skl_pipe_wm_get_hw_state(crtc, 
> >wm.skl.optimal);
> +
> + if (intel_crtc->active) {
> + hw->dirty_pipes |= drm_crtc_mask(crtc);
> + intel_crtc->wm.active.skl = cstate-
> >wm.skl.optimal;
> + }
> + }
>  
>  if (dev_priv->active_crtcs) {
>  /* Fully recompute DDB on first atomic commit */


[Intel-gfx] [PATCH 09/10] drm/i915/gen9: Actually verify WM levels in verify_wm_state()

2016-10-13 Thread Paulo Zanoni
Em Qui, 2016-10-13 às 18:15 -0300, Paulo Zanoni escreveu:
> Em Sex, 2016-10-07 às 20:11 -0400, Lyude escreveu:
> > 
> > Thanks to Paulo Zanoni for indirectly pointing this out.
> > 
> > Looks like we never actually added any code for checking whether or
> > not
> > we actually wrote watermark levels properly. Let's fix that.
> 
> Thanks for doing this!
> 
> Reviewed-by: Paulo Zanoni 
> 
> A check that would have prevented one of the bugs I solved would be
> "if
> plane is active, then level 0 must be enabled, and DDB partitioning
> size must be non-zero". I'll put this in my TODO list, but I won't
> complain if somebody does it first :)

Also, bikeshed: use %u instead of %d for the unsigned types
(plane_res_b, plane_res_l).

> 
> > 
> > 
> > Signed-off-by: Lyude 
> > Cc: Maarten Lankhorst 
> > Cc: Ville Syrjälä 
> > Cc: Paulo Zanoni 
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 100
> > +--
> >  1 file changed, 84 insertions(+), 16 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index 39400a0..2c682bc 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -13444,30 +13444,66 @@ static void verify_wm_state(struct
> > drm_crtc
> > *crtc,
> >    struct drm_device *dev = crtc->dev;
> >    struct drm_i915_private *dev_priv = to_i915(dev);
> >    struct skl_ddb_allocation hw_ddb, *sw_ddb;
> > -   struct skl_ddb_entry *hw_entry, *sw_entry;
> > +   struct skl_pipe_wm hw_wm, *sw_wm;
> > +   struct skl_plane_wm *hw_plane_wm, *sw_plane_wm;
> > +   struct skl_ddb_entry *hw_ddb_entry, *sw_ddb_entry;
> >    struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> >    const enum pipe pipe = intel_crtc->pipe;
> > -   int plane;
> > +   int plane, level, max_level = ilk_wm_max_level(dev);
> >  
> >    if (INTEL_INFO(dev)->gen < 9 || !new_state->active)
> >    return;
> >  
> > +   skl_pipe_wm_get_hw_state(crtc, _wm);
> > +   sw_wm = _crtc->wm.active.skl;
> > +
> >    skl_ddb_get_hw_state(dev_priv, _ddb);
> >    sw_ddb = _priv->wm.skl_hw.ddb;
> >  
> >    /* planes */
> >    for_each_plane(dev_priv, pipe, plane) {
> > -   hw_entry = _ddb.plane[pipe][plane];
> > -   sw_entry = _ddb->plane[pipe][plane];
> > +   hw_plane_wm = _wm.planes[plane];
> > +   sw_plane_wm = _wm->planes[plane];
> >  
> > -   if (skl_ddb_entry_equal(hw_entry, sw_entry))
> > -   continue;
> > +   /* Watermarks */
> > +   for (level = 0; level <= max_level; level++) {
> > +   if (skl_wm_level_equals(_plane_wm-
> > > 
> > > wm[level],
> > +   _plane_wm-
> > > 
> > > wm[level]))
> > +   continue;
> > +
> > +   DRM_ERROR("mismatch in WM pipe %c plane %d
> > level %d (expected e=%d b=%d l=%d, got e=%d b=%d l=%d)\n",
> > +     pipe_name(pipe), plane + 1,
> > level,
> > +     sw_plane_wm->wm[level].plane_en,
> > +     sw_plane_wm-
> > > 
> > > wm[level].plane_res_b,
> > +     sw_plane_wm-
> > > 
> > > wm[level].plane_res_l,
> > +     hw_plane_wm->wm[level].plane_en,
> > +     hw_plane_wm-
> > > 
> > > wm[level].plane_res_b,
> > +     hw_plane_wm-
> > > 
> > > wm[level].plane_res_l);
> > +   }
> >  
> > -   DRM_ERROR("mismatch in DDB state pipe %c plane %d
> > "
> > -     "(expected (%u,%u), found (%u,%u))\n",
> > -     pipe_name(pipe), plane + 1,
> > -     sw_entry->start, sw_entry->end,
> > -     hw_entry->start, hw_entry->end);
> > +   if (!skl_wm_level_equals(_plane_wm->trans_wm,
> > +    _plane_wm->trans_wm))
> > {
> > +   DRM_ERROR("mismatch in trans WM pipe %c
> > plane %d (expected e=%d b=%d l=%d, got e=%d b=%d l=%d)\n",
> > +     pipe_name(pipe), plane + 1,
> > +     sw_plane_

[PATCH 10/10] drm/i915/gen9: Don't wrap strings in verify_wm_state()

2016-10-13 Thread Paulo Zanoni
Em Sex, 2016-10-07 às 20:11 -0400, Lyude escreveu:

Bikesheding: it would be nice to write a commit message explaining why,
even if the message just tells the user to read
Documentation/CodingStyle.

Reviewed-by: Paulo Zanoni 

> Signed-off-by: Lyude 
> Cc: Maarten Lankhorst 
> Cc: Ville Syrjälä 
> Cc: Paulo Zanoni 
> ---
>  drivers/gpu/drm/i915/intel_display.c | 6 ++
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index 2c682bc..6191baf 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -13498,8 +13498,7 @@ static void verify_wm_state(struct drm_crtc
> *crtc,
>  sw_ddb_entry = _ddb->plane[pipe][plane];
>  
>  if (!skl_ddb_entry_equal(hw_ddb_entry,
> sw_ddb_entry)) {
> - DRM_ERROR("mismatch in DDB state pipe %c
> plane %d "
> -   "(expected (%u,%u), found
> (%u,%u))\n",
> + DRM_ERROR("mismatch in DDB state pipe %c
> plane %d (expected (%u,%u), found (%u,%u))\n",
>    pipe_name(pipe), plane + 1,
>    sw_ddb_entry->start, sw_ddb_entry-
> >end,
>    hw_ddb_entry->start, hw_ddb_entry-
> >end);
> @@ -13549,8 +13548,7 @@ static void verify_wm_state(struct drm_crtc
> *crtc,
>  sw_ddb_entry = _ddb->plane[pipe][PLANE_CURSOR];
>  
>  if (!skl_ddb_entry_equal(hw_ddb_entry,
> sw_ddb_entry)) {
> - DRM_ERROR("mismatch in DDB state pipe %c
> cursor "
> -   "(expected (%u,%u), found
> (%u,%u))\n",
> + DRM_ERROR("mismatch in DDB state pipe %c
> cursor (expected (%u,%u), found (%u,%u))\n",
>    pipe_name(pipe),
>    sw_ddb_entry->start, sw_ddb_entry-
> >end,
>    hw_ddb_entry->start, hw_ddb_entry-
> >end);


[PATCH 09/10] drm/i915/gen9: Actually verify WM levels in verify_wm_state()

2016-10-13 Thread Paulo Zanoni
Em Sex, 2016-10-07 às 20:11 -0400, Lyude escreveu:
> Thanks to Paulo Zanoni for indirectly pointing this out.
> 
> Looks like we never actually added any code for checking whether or
> not
> we actually wrote watermark levels properly. Let's fix that.

Thanks for doing this!

Reviewed-by: Paulo Zanoni 

A check that would have prevented one of the bugs I solved would be "if
plane is active, then level 0 must be enabled, and DDB partitioning
size must be non-zero". I'll put this in my TODO list, but I won't
complain if somebody does it first :)

> 
> Signed-off-by: Lyude 
> Cc: Maarten Lankhorst 
> Cc: Ville Syrjälä 
> Cc: Paulo Zanoni 
> ---
>  drivers/gpu/drm/i915/intel_display.c | 100
> +--
>  1 file changed, 84 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index 39400a0..2c682bc 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -13444,30 +13444,66 @@ static void verify_wm_state(struct drm_crtc
> *crtc,
>  struct drm_device *dev = crtc->dev;
>  struct drm_i915_private *dev_priv = to_i915(dev);
>  struct skl_ddb_allocation hw_ddb, *sw_ddb;
> - struct skl_ddb_entry *hw_entry, *sw_entry;
> + struct skl_pipe_wm hw_wm, *sw_wm;
> + struct skl_plane_wm *hw_plane_wm, *sw_plane_wm;
> + struct skl_ddb_entry *hw_ddb_entry, *sw_ddb_entry;
>  struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  const enum pipe pipe = intel_crtc->pipe;
> - int plane;
> + int plane, level, max_level = ilk_wm_max_level(dev);
>  
>  if (INTEL_INFO(dev)->gen < 9 || !new_state->active)
>  return;
>  
> + skl_pipe_wm_get_hw_state(crtc, _wm);
> + sw_wm = _crtc->wm.active.skl;
> +
>  skl_ddb_get_hw_state(dev_priv, _ddb);
>  sw_ddb = _priv->wm.skl_hw.ddb;
>  
>  /* planes */
>  for_each_plane(dev_priv, pipe, plane) {
> - hw_entry = _ddb.plane[pipe][plane];
> - sw_entry = _ddb->plane[pipe][plane];
> + hw_plane_wm = _wm.planes[plane];
> + sw_plane_wm = _wm->planes[plane];
>  
> - if (skl_ddb_entry_equal(hw_entry, sw_entry))
> - continue;
> + /* Watermarks */
> + for (level = 0; level <= max_level; level++) {
> + if (skl_wm_level_equals(_plane_wm-
> >wm[level],
> + _plane_wm-
> >wm[level]))
> + continue;
> +
> + DRM_ERROR("mismatch in WM pipe %c plane %d
> level %d (expected e=%d b=%d l=%d, got e=%d b=%d l=%d)\n",
> +   pipe_name(pipe), plane + 1, level,
> +   sw_plane_wm->wm[level].plane_en,
> +   sw_plane_wm-
> >wm[level].plane_res_b,
> +   sw_plane_wm-
> >wm[level].plane_res_l,
> +   hw_plane_wm->wm[level].plane_en,
> +   hw_plane_wm-
> >wm[level].plane_res_b,
> +   hw_plane_wm-
> >wm[level].plane_res_l);
> + }
>  
> - DRM_ERROR("mismatch in DDB state pipe %c plane %d "
> -   "(expected (%u,%u), found (%u,%u))\n",
> -   pipe_name(pipe), plane + 1,
> -   sw_entry->start, sw_entry->end,
> -   hw_entry->start, hw_entry->end);
> + if (!skl_wm_level_equals(_plane_wm->trans_wm,
> +  _plane_wm->trans_wm)) {
> + DRM_ERROR("mismatch in trans WM pipe %c
> plane %d (expected e=%d b=%d l=%d, got e=%d b=%d l=%d)\n",
> +   pipe_name(pipe), plane + 1,
> +   sw_plane_wm->trans_wm.plane_en,
> +   sw_plane_wm->trans_wm.plane_res_b,
> +   sw_plane_wm->trans_wm.plane_res_l,
> +   hw_plane_wm->trans_wm.plane_en,
> +   hw_plane_wm->trans_wm.plane_res_b,
> +   hw_plane_wm-
> >trans_wm.plane_res_l);
> + }
> +
> + /* DDB */
> + hw_ddb_entry = _ddb.plane[pipe][plane];
> + sw_ddb_entry = _ddb->plane[pipe][plane];
> +
> + if (!skl_ddb_entry_equal(hw_ddb_entry,
> sw_ddb_entry)) {
> +

[PATCH 08/10] drm/i915/gen9: Add skl_wm_level_equals()

2016-10-13 Thread Paulo Zanoni
Em Sex, 2016-10-07 às 20:11 -0400, Lyude escreveu:
> Helper we're going to be using for implementing verification of the
> wm
> levels in skl_verify_wm_level().
> 
> Signed-off-by: Lyude 

Reviewed-by: Paulo Zanoni 

> Cc: Maarten Lankhorst 
> Cc: Ville Syrjälä 
> Cc: Paulo Zanoni 
> ---
>  drivers/gpu/drm/i915/intel_drv.h |  2 ++
>  drivers/gpu/drm/i915/intel_pm.c  | 14 ++
>  2 files changed, 16 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index 73a2d16d..3e6e9af 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1761,6 +1761,8 @@ void skl_pipe_wm_get_hw_state(struct drm_crtc
> *crtc,
>  bool intel_can_enable_sagv(struct drm_atomic_state *state);
>  int intel_enable_sagv(struct drm_i915_private *dev_priv);
>  int intel_disable_sagv(struct drm_i915_private *dev_priv);
> +bool skl_wm_level_equals(const struct skl_wm_level *l1,
> +  const struct skl_wm_level *l2);
>  bool skl_ddb_allocation_equals(const struct skl_ddb_allocation *old,
>         const struct skl_ddb_allocation *new,
>         enum pipe pipe);
> diff --git a/drivers/gpu/drm/i915/intel_pm.c
> b/drivers/gpu/drm/i915/intel_pm.c
> index 27a520ce..6af1587 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3853,6 +3853,20 @@ void skl_write_cursor_wm(struct intel_crtc
> *intel_crtc,
>      >plane[pipe][PLANE_CURSOR]);
>  }
>  
> +bool skl_wm_level_equals(const struct skl_wm_level *l1,
> +  const struct skl_wm_level *l2)
> +{
> + if (l1->plane_en != l2->plane_en)
> + return false;
> +
> + /* If both planes aren't enabled, the rest shouldn't matter
> */
> + if (!l1->plane_en)
> + return true;
> +
> + return (l1->plane_res_l == l2->plane_res_l &&
> + l1->plane_res_b == l2->plane_res_b);
> +}
> +
>  static inline bool skl_ddb_entries_overlap(const struct
> skl_ddb_entry *a,
>     const struct
> skl_ddb_entry *b)
>  {


[PATCH 07/10] drm/i915/gen9: Make skl_pipe_wm_get_hw_state() reusable

2016-10-13 Thread Paulo Zanoni
Em Sex, 2016-10-07 às 20:11 -0400, Lyude escreveu:
> There's not much of a reason this should have the locations to read
> out
> the hardware state hardcoded, so allow the caller to specify the
> location and add this function to intel_drv.h. As well, we're going
> to
> need this function to be reusable for the next patch.
> 
> Signed-off-by: Lyude 
> Cc: Maarten Lankhorst 
> Cc: Ville Syrjälä 
> Cc: Paulo Zanoni 
> ---
>  drivers/gpu/drm/i915/intel_drv.h |  2 ++
>  drivers/gpu/drm/i915/intel_pm.c  | 27 +--
>  2 files changed, 19 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index 958dc72..73a2d16d 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1756,6 +1756,8 @@ void ilk_wm_get_hw_state(struct drm_device
> *dev);
>  void skl_wm_get_hw_state(struct drm_device *dev);
>  void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
>    struct skl_ddb_allocation *ddb /* out */);
> +void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc,
> +       struct skl_pipe_wm *out);
>  bool intel_can_enable_sagv(struct drm_atomic_state *state);
>  int intel_enable_sagv(struct drm_i915_private *dev_priv);
>  int intel_disable_sagv(struct drm_i915_private *dev_priv);
> diff --git a/drivers/gpu/drm/i915/intel_pm.c
> b/drivers/gpu/drm/i915/intel_pm.c
> index 9e53ff7..27a520ce 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -4287,15 +4287,13 @@ static inline void
> skl_wm_level_from_reg_val(uint32_t val,
>  PLANE_WM_LINES_MASK;
>  }
>  
> -static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
> +void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc,
> +       struct skl_pipe_wm *out)
>  {
>  struct drm_device *dev = crtc->dev;
>  struct drm_i915_private *dev_priv = to_i915(dev);
> - struct skl_wm_values *hw = _priv->wm.skl_hw;
>  struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> - struct intel_crtc_state *cstate = to_intel_crtc_state(crtc-
> >state);
>  struct intel_plane *intel_plane;
> - struct skl_pipe_wm *active = >wm.skl.optimal;
>  struct skl_plane_wm *wm;
>  enum pipe pipe = intel_crtc->pipe;
>  int level, id, max_level = ilk_wm_max_level(dev);
> @@ -4303,7 +4301,7 @@ static void skl_pipe_wm_get_hw_state(struct
> drm_crtc *crtc)
>  
>  for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
>  id = skl_wm_plane_id(intel_plane);
> - wm = >wm.skl.optimal.planes[id];
> + wm = >planes[id];
>  
>  for (level = 0; level <= max_level; level++) {
>  if (id != PLANE_CURSOR)
> @@ -4325,20 +4323,29 @@ static void skl_pipe_wm_get_hw_state(struct
> drm_crtc *crtc)
>  if (!intel_crtc->active)
>  return;
>  
> - hw->dirty_pipes |= drm_crtc_mask(crtc);
> - active->linetime = I915_READ(PIPE_WM_LINETIME(pipe));
> - intel_crtc->wm.active.skl = *active;
> + out->linetime = I915_READ(PIPE_WM_LINETIME(pipe));
>  }
>  
>  void skl_wm_get_hw_state(struct drm_device *dev)
>  {
>  struct drm_i915_private *dev_priv = to_i915(dev);
> + struct skl_wm_values *hw = _priv->wm.skl_hw;
>  struct skl_ddb_allocation *ddb = _priv->wm.skl_hw.ddb;
>  struct drm_crtc *crtc;
> + struct intel_crtc *intel_crtc;
> + struct intel_crtc_state *cstate;
>  
>  skl_ddb_get_hw_state(dev_priv, ddb);
> - list_for_each_entry(crtc, >mode_config.crtc_list, head)
> - skl_pipe_wm_get_hw_state(crtc);
> + list_for_each_entry(crtc, >mode_config.crtc_list, head)
> {
> + intel_crtc = to_intel_crtc(crtc);
> + cstate = to_intel_crtc_state(crtc->state);
> +
> + skl_pipe_wm_get_hw_state(crtc, 
> >wm.skl.optimal);
> + intel_crtc->wm.active.skl = cstate->wm.skl.optimal;

We're changing how the code behaves regarding intel_crtc-
>wm.active.skl. Previously we would only set it if intel_crtc->active
is true due to that return in skl_pipe_wm_get_hw_state(). Now we're
always setting it.

If this is some sort of fix it probably deserves to be in a separate
commit with a nice commit message.

> +
> + if (!intel_crtc->active)
> + hw->dirty_pipes |= drm_crtc_mask(crtc);

Same here: previously we would not set dirty_pipes in case !intel_crtc-
>active. Now we're doing the opposite. Didn't you mean "if (intel_crtc-
>active)" here?

> + }
>  
>  if (dev_priv->active_crtcs) {
>  /* Fully recompute DDB on first atomic commit */


[PATCH v2 06/10] drm/i915/gen9: Add ddb changes to atomic debug output

2016-10-13 Thread Paulo Zanoni
Em Sex, 2016-10-07 às 20:11 -0400, Lyude escreveu:
> Finally, add some debugging output for ddb changes in the atomic
> debug
> output. This makes it a lot easier to spot bugs from incorrect ddb
> allocations.
> 
> Signed-off-by: Lyude 
> Reviewed-by: Maarten Lankhorst 
> Cc: Ville Syrjälä 
> Cc: Paulo Zanoni 
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 57
> +
>  1 file changed, 57 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c
> b/drivers/gpu/drm/i915/intel_pm.c
> index 5cb537c..9e53ff7 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -4040,6 +4040,61 @@ skl_copy_wm_for_pipe(struct skl_wm_values
> *dst,
>         sizeof(dst->ddb.plane[pipe]));
>  }
>  
> +static void
> +skl_print_wm_changes(const struct drm_atomic_state *state)
> +{
> + const struct drm_device *dev = state->dev;
> + const struct drm_i915_private *dev_priv = to_i915(dev);
> + const struct intel_atomic_state *intel_state =
> + to_intel_atomic_state(state);
> + const struct drm_crtc *crtc;
> + const struct drm_crtc_state *cstate;
> + const struct drm_plane *plane;
> + const struct intel_plane *intel_plane;
> + const struct drm_plane_state *pstate;
> + const struct skl_ddb_allocation *old_ddb = _priv-
> >wm.skl_hw.ddb;
> + const struct skl_ddb_allocation *new_ddb = _state-
> >wm_results.ddb;
> + enum pipe pipe;
> + int id;
> + int i, j;
> +
> + for_each_crtc_in_state(state, crtc, cstate, i) {
> + if (!crtc->state)
> + continue;

Why exactly do we have this check?

Everything else looks good. So with either an explanation or the check
removed in case it's not needed:
Reviewed-by: Paulo Zanoni 

> +
> + pipe = to_intel_crtc(crtc)->pipe;
> +
> + for_each_plane_in_state(state, plane, pstate, j) {
> + const struct skl_ddb_entry *old, *new;
> +
> + intel_plane = to_intel_plane(plane);
> + id = skl_wm_plane_id(intel_plane);
> + old = _ddb->plane[pipe][id];
> + new = _ddb->plane[pipe][id];
> +
> + if (intel_plane->pipe != pipe)
> + continue;
> +
> + if (skl_ddb_entry_equal(old, new))
> + continue;
> +
> + if (id != PLANE_CURSOR) {
> + DRM_DEBUG_ATOMIC("[PLANE:%d:plane
> %d%c] ddb (%d - %d) -> (%d - %d)\n",
> +  plane->base.id, id
> + 1,
> +  pipe_name(pipe),
> +  old->start, old-
> >end,
> +  new->start, new-
> >end);
> + } else {
> + DRM_DEBUG_ATOMIC("[PLANE:%d:cursor
> %c] ddb (%d - %d) -> (%d - %d)\n",
> +  plane->base.id,
> +  pipe_name(pipe),
> +  old->start, old-
> >end,
> +  new->start, new-
> >end);
> + }
> + }
> + }
> +}
> +
>  static int
>  skl_compute_wm(struct drm_atomic_state *state)
>  {
> @@ -4101,6 +4156,8 @@ skl_compute_wm(struct drm_atomic_state *state)
>  intel_cstate->update_wm_pre = true;
>  }
>  
> + skl_print_wm_changes(state);
> +
>  return 0;
>  }
>  


[Intel-gfx] [PATCH v2 05/10] drm/i915/gen9: Get rid of redundant watermark values

2016-10-13 Thread Paulo Zanoni
Em Qui, 2016-10-13 às 17:04 -0300, Paulo Zanoni escreveu:
> Em Qui, 2016-10-13 às 15:39 +0200, Maarten Lankhorst escreveu:
> > 
> > Op 08-10-16 om 02:11 schreef Lyude:
> > > 
> > > 
> > > Now that we've make skl_wm_levels make a little more sense, we
> > > can
> > > remove all of the redundant wm information. Up until now we'd
> > > been
> > > storing two copies of all of the skl watermarks: one being the
> > > skl_pipe_wm structs, the other being the global wm struct in
> > > drm_i915_private containing the raw register values. This is
> > > confusing
> > > and problematic, since it means we're prone to accidentally
> > > letting
> > > the
> > > two copies go out of sync. So, get rid of all of the functions
> > > responsible for computing the register values and just use a
> > > single
> > > helper, skl_write_wm_level(), to convert and write the new
> > > watermarks on
> > > the fly.
> > > 
> > > Changes since v1:
> > > - Fixup skl_write_wm_level()
> > > - Fixup skl_wm_level_from_reg_val()
> > > - Don't forget to copy *active to intel_crtc->wm.active.skl
> > > 
> > > Signed-off-by: Lyude 
> > > Reviewed-by: Maarten Lankhorst  > > >
> > > Cc: Ville Syrjälä 
> > > Cc: Paulo Zanoni 
> > > ---
> > >  drivers/gpu/drm/i915/i915_drv.h      |   2 -
> > >  drivers/gpu/drm/i915/intel_display.c |  14 ++-
> > >  drivers/gpu/drm/i915/intel_drv.h     |   6 +-
> > >  drivers/gpu/drm/i915/intel_pm.c      | 204 -
> > > --
> > > 
> > >  drivers/gpu/drm/i915/intel_sprite.c  |   8 +-
> > >  5 files changed, 90 insertions(+), 144 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/i915_drv.h
> > > b/drivers/gpu/drm/i915/i915_drv.h
> > > index 0287c93..76583b2 100644
> > > --- a/drivers/gpu/drm/i915/i915_drv.h
> > > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > > @@ -1644,8 +1644,6 @@ struct skl_ddb_allocation {
> > >  struct skl_wm_values {
> > >  unsigned dirty_pipes;
> > >  struct skl_ddb_allocation ddb;
> > > - uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
> > > - uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
> > >  };
> > >  
> > >  struct skl_wm_level {
> > > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > > b/drivers/gpu/drm/i915/intel_display.c
> > > index a71d05a..39400a0 100644
> > > --- a/drivers/gpu/drm/i915/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/intel_display.c
> > > @@ -3378,6 +3378,8 @@ static void
> > > skylake_update_primary_plane(struct drm_plane *plane,
> > >  struct intel_crtc *intel_crtc =
> > > to_intel_crtc(crtc_state-
> > > > 
> > > > base.crtc);
> > >  struct drm_framebuffer *fb = plane_state->base.fb;
> > >  const struct skl_wm_values *wm = _priv-
> > > > 
> > > > wm.skl_results;
> > > + const struct skl_plane_wm *p_wm =
> > > + _state->wm.skl.optimal.planes[0];
> > >  int pipe = intel_crtc->pipe;
> > >  u32 plane_ctl;
> > >  unsigned int rotation = plane_state->base.rotation;
> > > @@ -3414,7 +3416,7 @@ static void
> > > skylake_update_primary_plane(struct drm_plane *plane,
> > >  intel_crtc->adjusted_y = src_y;
> > >  
> > >  if (wm->dirty_pipes & drm_crtc_mask(_crtc->base))
> > > - skl_write_plane_wm(intel_crtc, wm, 0);
> > > + skl_write_plane_wm(intel_crtc, p_wm, >ddb,
> > > 0);
> > >  
> > >  I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
> > >  I915_WRITE(PLANE_OFFSET(pipe, 0), (src_y << 16) |
> > > src_x);
> > > @@ -3448,6 +3450,8 @@ static void
> > > skylake_disable_primary_plane(struct drm_plane *primary,
> > >  struct drm_device *dev = crtc->dev;
> > >  struct drm_i915_private *dev_priv = to_i915(dev);
> > >  struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > > + struct intel_crtc_state *cstate =
> > > to_intel_crtc_state(crtc->state);
> > > + const struct skl_plane_wm *p_wm = 
> > > > 
> > > > wm.skl.optimal.planes[0];
> > >  int pipe = intel_crtc->pipe;
> > >

[Intel-gfx] [PATCH v2 05/10] drm/i915/gen9: Get rid of redundant watermark values

2016-10-13 Thread Paulo Zanoni
Em Qui, 2016-10-13 às 15:39 +0200, Maarten Lankhorst escreveu:
> Op 08-10-16 om 02:11 schreef Lyude:
> > 
> > Now that we've make skl_wm_levels make a little more sense, we can
> > remove all of the redundant wm information. Up until now we'd been
> > storing two copies of all of the skl watermarks: one being the
> > skl_pipe_wm structs, the other being the global wm struct in
> > drm_i915_private containing the raw register values. This is
> > confusing
> > and problematic, since it means we're prone to accidentally letting
> > the
> > two copies go out of sync. So, get rid of all of the functions
> > responsible for computing the register values and just use a single
> > helper, skl_write_wm_level(), to convert and write the new
> > watermarks on
> > the fly.
> > 
> > Changes since v1:
> > - Fixup skl_write_wm_level()
> > - Fixup skl_wm_level_from_reg_val()
> > - Don't forget to copy *active to intel_crtc->wm.active.skl
> > 
> > Signed-off-by: Lyude 
> > Reviewed-by: Maarten Lankhorst 
> > Cc: Ville Syrjälä 
> > Cc: Paulo Zanoni 
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h      |   2 -
> >  drivers/gpu/drm/i915/intel_display.c |  14 ++-
> >  drivers/gpu/drm/i915/intel_drv.h     |   6 +-
> >  drivers/gpu/drm/i915/intel_pm.c      | 204 ---
> > 
> >  drivers/gpu/drm/i915/intel_sprite.c  |   8 +-
> >  5 files changed, 90 insertions(+), 144 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h
> > b/drivers/gpu/drm/i915/i915_drv.h
> > index 0287c93..76583b2 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -1644,8 +1644,6 @@ struct skl_ddb_allocation {
> >  struct skl_wm_values {
> >    unsigned dirty_pipes;
> >    struct skl_ddb_allocation ddb;
> > -   uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
> > -   uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
> >  };
> >  
> >  struct skl_wm_level {
> > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index a71d05a..39400a0 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -3378,6 +3378,8 @@ static void
> > skylake_update_primary_plane(struct drm_plane *plane,
> >    struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state-
> > >base.crtc);
> >    struct drm_framebuffer *fb = plane_state->base.fb;
> >    const struct skl_wm_values *wm = _priv-
> > >wm.skl_results;
> > +   const struct skl_plane_wm *p_wm =
> > +   _state->wm.skl.optimal.planes[0];
> >    int pipe = intel_crtc->pipe;
> >    u32 plane_ctl;
> >    unsigned int rotation = plane_state->base.rotation;
> > @@ -3414,7 +3416,7 @@ static void
> > skylake_update_primary_plane(struct drm_plane *plane,
> >    intel_crtc->adjusted_y = src_y;
> >  
> >    if (wm->dirty_pipes & drm_crtc_mask(_crtc->base))
> > -   skl_write_plane_wm(intel_crtc, wm, 0);
> > +   skl_write_plane_wm(intel_crtc, p_wm, >ddb, 0);
> >  
> >    I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
> >    I915_WRITE(PLANE_OFFSET(pipe, 0), (src_y << 16) | src_x);
> > @@ -3448,6 +3450,8 @@ static void
> > skylake_disable_primary_plane(struct drm_plane *primary,
> >    struct drm_device *dev = crtc->dev;
> >    struct drm_i915_private *dev_priv = to_i915(dev);
> >    struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +   struct intel_crtc_state *cstate =
> > to_intel_crtc_state(crtc->state);
> > +   const struct skl_plane_wm *p_wm = 
> > >wm.skl.optimal.planes[0];
> >    int pipe = intel_crtc->pipe;
> >  
> >    /*
> > @@ -3455,7 +3459,8 @@ static void
> > skylake_disable_primary_plane(struct drm_plane *primary,
> >     * plane's visiblity isn't actually changing neither is
> > its watermarks.
> >     */
> >    if (!crtc->primary->state->visible)
> > -   skl_write_plane_wm(intel_crtc, _priv-
> > >wm.skl_results, 0);
> > +   skl_write_plane_wm(intel_crtc, p_wm,
> > +      _priv->wm.skl_results.ddb,
> > 0);
> >  
> >    I915_WRITE(PLANE_CTL(pipe, 0), 0);
> >    I915_WRITE(PLANE_SURF(pipe, 0), 0);
> > @@ -10819,12 +10824,15 @@ static void i9xx_update_cursor(struct
> > drm_crtc *crtc, u32 base,
> >    struct drm_device *dev

[Intel-gfx] [PATCH 04/10] drm/i915/gen9: Cleanup skl_pipe_wm_active_state

2016-10-11 Thread Paulo Zanoni
Em Sex, 2016-10-07 às 20:11 -0400, Lyude escreveu:
> This function is a wreck, let's help it get it's life back together
> and
> cleanup all of the copy pasta here.

s/it's/its/

Idea for your next patch series: rename skl_pipe_wm_active_state()'s
"i" parameter to something more meaningful.

Reviewed-by: Paulo Zanoni 

> 
> (adding Maarten's reviewed-by since this is just a split-up version
> of one
> of the previous patches)
> 
> Signed-off-by: Lyude 
> Reviewed-by: Maarten Lankhorst 
> Cc: Ville Syrjälä 
> Cc: Paulo Zanoni 
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 52 +++--
> 
>  1 file changed, 14 insertions(+), 38 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c
> b/drivers/gpu/drm/i915/intel_pm.c
> index 4c2ebcd..5dbaf12 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -4267,46 +4267,22 @@ static void ilk_optimize_watermarks(struct
> intel_crtc_state *cstate)
>  static void skl_pipe_wm_active_state(uint32_t val,
>       struct skl_pipe_wm *active,
>       bool is_transwm,
> -      bool is_cursor,
>       int i,
>       int level)
>  {
> + struct skl_plane_wm *plane_wm = >planes[i];
>  bool is_enabled = (val & PLANE_WM_EN) != 0;
>  
>  if (!is_transwm) {
> - if (!is_cursor) {
> - active->planes[i].wm[level].plane_en =
> is_enabled;
> - active->planes[i].wm[level].plane_res_b =
> - val & PLANE_WM_BLOCKS_MASK;
> - active->planes[i].wm[level].plane_res_l =
> - (val >> PLANE_WM_LINES_SHIFT) &
> - PLANE_WM_LINES_MASK;
> - } else {
> - active-
> >planes[PLANE_CURSOR].wm[level].plane_en =
> - is_enabled;
> - active-
> >planes[PLANE_CURSOR].wm[level].plane_res_b =
> - val & PLANE_WM_BLOCKS_MASK;
> - active-
> >planes[PLANE_CURSOR].wm[level].plane_res_l =
> - (val >> PLANE_WM_LINES_SHIFT) &
> - PLANE_WM_LINES_MASK;
> - }
> + plane_wm->wm[level].plane_en = is_enabled;
> + plane_wm->wm[level].plane_res_b = val &
> PLANE_WM_BLOCKS_MASK;
> + plane_wm->wm[level].plane_res_l =
> + (val >> PLANE_WM_LINES_SHIFT) &
> PLANE_WM_LINES_MASK;
>  } else {
> - if (!is_cursor) {
> - active->planes[i].trans_wm.plane_en =
> is_enabled;
> - active->planes[i].trans_wm.plane_res_b =
> - val & PLANE_WM_BLOCKS_MASK;
> - active->planes[i].trans_wm.plane_res_l =
> - (val >> PLANE_WM_LINES_SHIFT) &
> - PLANE_WM_LINES_MASK;
> - } else {
> - active-
> >planes[PLANE_CURSOR].trans_wm.plane_en =
> - is_enabled;
> - active-
> >planes[PLANE_CURSOR].trans_wm.plane_res_b =
> - val & PLANE_WM_BLOCKS_MASK;
> - active-
> >planes[PLANE_CURSOR].trans_wm.plane_res_l =
> - (val >> PLANE_WM_LINES_SHIFT) &
> - PLANE_WM_LINES_MASK;
> - }
> + plane_wm->trans_wm.plane_en = is_enabled;
> + plane_wm->trans_wm.plane_res_b = val &
> PLANE_WM_BLOCKS_MASK;
> + plane_wm->trans_wm.plane_res_l =
> + (val >> PLANE_WM_LINES_SHIFT) &
> PLANE_WM_LINES_MASK;
>  }
>  }
>  
> @@ -4345,20 +4321,20 @@ static void skl_pipe_wm_get_hw_state(struct
> drm_crtc *crtc)
>  for (level = 0; level <= max_level; level++) {
>  for (i = 0; i < intel_num_planes(intel_crtc); i++) {
>  temp = hw->plane[pipe][i][level];
> - skl_pipe_wm_active_state(temp, active,
> false,
> - false, i, level);
> + skl_pipe_wm_active_state(temp, active,
> false, i, level);
>  }
>  temp = hw->plane[pipe][PLANE_CURSOR][level];
> - skl_pipe_wm_active_state(temp, active, false, tr

[PATCH v2 03/10] drm/i915/gen9: Make skl_wm_level per-plane

2016-10-11 Thread Paulo Zanoni
Em Sex, 2016-10-07 às 20:11 -0400, Lyude escreveu:
> Having skl_wm_level contain all of the watermarks for each plane is
> annoying since it prevents us from having any sort of object to
> represent a single watermark level, something we take advantage of in
> the next commit to cut down on all of the copy paste code in here.
> 
> Changes since v1:
> - Style nitpicks
> - Fix accidental usage of i vs. PLANE_CURSOR
> - Split out skl_pipe_wm_active_state simplification into separate
> patch
> 
> Signed-off-by: Lyude 

Reviewed-by: Paulo Zanoni 

> Reviewed-by: Maarten Lankhorst 
> Cc: Ville Syrjälä 
> Cc: Paulo Zanoni 
> ---
>  drivers/gpu/drm/i915/i915_drv.h  |   6 +-
>  drivers/gpu/drm/i915/intel_drv.h |   6 +-
>  drivers/gpu/drm/i915/intel_pm.c  | 207 +++
> 
>  3 files changed, 111 insertions(+), 108 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> index e9d035ea..0287c93 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1649,9 +1649,9 @@ struct skl_wm_values {
>  };
>  
>  struct skl_wm_level {
> - bool plane_en[I915_MAX_PLANES];
> - uint16_t plane_res_b[I915_MAX_PLANES];
> - uint8_t plane_res_l[I915_MAX_PLANES];
> + bool plane_en;
> + uint16_t plane_res_b;
> + uint8_t plane_res_l;
>  };
>  
>  /*
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index 35ba282..d684f4f 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -468,9 +468,13 @@ struct intel_pipe_wm {
>  bool sprites_scaled;
>  };
>  
> -struct skl_pipe_wm {
> +struct skl_plane_wm {
>  struct skl_wm_level wm[8];
>  struct skl_wm_level trans_wm;
> +};
> +
> +struct skl_pipe_wm {
> + struct skl_plane_wm planes[I915_MAX_PLANES];
>  uint32_t linetime;
>  };
>  
> diff --git a/drivers/gpu/drm/i915/intel_pm.c
> b/drivers/gpu/drm/i915/intel_pm.c
> index cc5d5e9..4c2ebcd 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3670,67 +3670,52 @@ static int
>  skl_compute_wm_level(const struct drm_i915_private *dev_priv,
>       struct skl_ddb_allocation *ddb,
>       struct intel_crtc_state *cstate,
> +      struct intel_plane *intel_plane,
>       int level,
>       struct skl_wm_level *result)
>  {
>  struct drm_atomic_state *state = cstate->base.state;
>  struct intel_crtc *intel_crtc = to_intel_crtc(cstate-
> >base.crtc);
> - struct drm_plane *plane;
> - struct intel_plane *intel_plane;
> - struct intel_plane_state *intel_pstate;
> + struct drm_plane *plane = _plane->base;
> + struct intel_plane_state *intel_pstate = NULL;
>  uint16_t ddb_blocks;
>  enum pipe pipe = intel_crtc->pipe;
>  int ret;
> + int i = skl_wm_plane_id(intel_plane);
> +
> + if (state)
> + intel_pstate =
> + intel_atomic_get_existing_plane_state(state,
> +       intel_
> plane);
>  
>  /*
> -  * We'll only calculate watermarks for planes that are
> actually
> -  * enabled, so make sure all other planes are set as
> disabled.
> +  * Note: If we start supporting multiple pending atomic
> commits against
> +  * the same planes/CRTC's in the future, plane->state will
> no longer be
> +  * the correct pre-state to use for the calculations here
> and we'll
> +  * need to change where we get the 'unchanged' plane data
> from.
> +  *
> +  * For now this is fine because we only allow one queued
> commit against
> +  * a CRTC.  Even if the plane isn't modified by this
> transaction and we
> +  * don't have a plane lock, we still have the CRTC's lock,
> so we know
> +  * that no other transactions are racing with us to update
> it.
>   */
> - memset(result, 0, sizeof(*result));
> + if (!intel_pstate)
> + intel_pstate = to_intel_plane_state(plane->state);
>  
> - for_each_intel_plane_mask(_priv->drm,
> -   intel_plane,
> -   cstate->base.plane_mask) {
> - int i = skl_wm_plane_id(intel_plane);
> -
> - plane = _plane->base;
> - intel_pstate = NULL;
> - if (state)
> - intel_pstate =
> - intel_ato

[Intel-gfx] [PATCH v2 01/10] drm/i915/skl: Move per-pipe ddb allocations into crtc states

2016-10-11 Thread Paulo Zanoni
Em Sex, 2016-10-07 às 20:11 -0400, Lyude escreveu:
> First part of cleaning up all of the skl watermark code. This moves
> the
> structures for storing the ddb allocations of each pipe into
> intel_crtc_state, along with moving the structures for storing the
> current ddb allocations active on hardware into intel_crtc.
> 
> Changes since v1:
> - Don't replace alloc->start = alloc->end = 0;
> 
> Signed-off-by: Lyude 

Reviewed-by: Paulo Zanoni 

> Reviewed-by: Maarten Lankhorst 
> Cc: Ville Syrjälä 
> Cc: Paulo Zanoni 
> ---
>  drivers/gpu/drm/i915/i915_drv.h      |  1 -
>  drivers/gpu/drm/i915/intel_display.c | 16 ---
>  drivers/gpu/drm/i915/intel_drv.h     |  8 +---
>  drivers/gpu/drm/i915/intel_pm.c      | 40 +++---
> --
>  4 files changed, 30 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> index a219a35..bb2de8d 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1637,7 +1637,6 @@ static inline bool skl_ddb_entry_equal(const
> struct skl_ddb_entry *e1,
>  }
>  
>  struct skl_ddb_allocation {
> - struct skl_ddb_entry pipe[I915_MAX_PIPES];
>  struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
> /* packed/uv */
>  struct skl_ddb_entry
> y_plane[I915_MAX_PIPES][I915_MAX_PLANES];
>  };
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index a366656..17733af 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -14235,12 +14235,11 @@ static void skl_update_crtcs(struct
> drm_atomic_state *state,
>       unsigned int *crtc_vblank_mask)
>  {
>  struct drm_device *dev = state->dev;
> - struct drm_i915_private *dev_priv = to_i915(dev);
>  struct intel_atomic_state *intel_state =
> to_intel_atomic_state(state);
>  struct drm_crtc *crtc;
> + struct intel_crtc *intel_crtc;
>  struct drm_crtc_state *old_crtc_state;
> - struct skl_ddb_allocation *new_ddb = _state-
> >wm_results.ddb;
> - struct skl_ddb_allocation *cur_ddb = _priv-
> >wm.skl_hw.ddb;
> + struct intel_crtc_state *cstate;
>  unsigned int updated = 0;
>  bool progress;
>  enum pipe pipe;
> @@ -14258,12 +14257,14 @@ static void skl_update_crtcs(struct
> drm_atomic_state *state,
>  for_each_crtc_in_state(state, crtc, old_crtc_state,
> i) {
>  bool vbl_wait = false;
>  unsigned int cmask = drm_crtc_mask(crtc);
> - pipe = to_intel_crtc(crtc)->pipe;
> +
> + intel_crtc = to_intel_crtc(crtc);
> + cstate = to_intel_crtc_state(crtc->state);
> + pipe = intel_crtc->pipe;
>  
>  if (updated & cmask || !crtc->state->active)
>  continue;
> - if (skl_ddb_allocation_overlaps(state,
> cur_ddb, new_ddb,
> - pipe))
> + if (skl_ddb_allocation_overlaps(state,
> intel_crtc))
>  continue;
>  
>  updated |= cmask;
> @@ -14274,7 +14275,8 @@ static void skl_update_crtcs(struct
> drm_atomic_state *state,
>   * then we need to wait for a vblank to pass
> for the
>   * new ddb allocation to take effect.
>   */
> - if (!skl_ddb_allocation_equals(cur_ddb,
> new_ddb, pipe) &&
> + if (!skl_ddb_entry_equal(
> >wm.skl.ddb,
> +  _crtc-
> >hw_ddb) &&
>      !crtc->state->active_changed &&
>      intel_state->wm_results.dirty_pipes !=
> updated)
>  vbl_wait = true;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index f48e79a..35ba282 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -496,6 +496,7 @@ struct intel_crtc_wm_state {
>  struct {
>  /* gen9+ only needs 1-step wm programming */
>  struct skl_pipe_wm optimal;
> + struct skl_ddb_entry ddb;
>  
>  /* cached plane data rate */
>  unsigned plane_data_rate[I915_MAX_PLANES];
> @@ -733,6 +734,9 @@ struct intel_

[Intel-gfx] [PATCH 5/6] drm/i915/gen9: Get rid of redundant watermark values

2016-10-05 Thread Paulo Zanoni
Em Qua, 2016-10-05 às 11:33 -0400, Lyude escreveu:
> Now that we've make skl_wm_levels make a little more sense, we can
> remove all of the redundant wm information. Up until now we'd been
> storing two copies of all of the skl watermarks: one being the
> skl_pipe_wm structs, the other being the global wm struct in
> drm_i915_private containing the raw register values. This is
> confusing
> and problematic, since it means we're prone to accidentally letting
> the
> two copies go out of sync. So, get rid of all of the functions
> responsible for computing the register values and just use a single
> helper, skl_write_wm_level(), to convert and write the new watermarks
> on
> the fly.

I like the direction of this patch too, but there are some small
possible problems. See below.


> 
> Signed-off-by: Lyude 
> Cc: Maarten Lankhorst 
> Cc: Ville Syrjälä 
> Cc: Matt Roper 
> ---
>  drivers/gpu/drm/i915/i915_drv.h      |   2 -
>  drivers/gpu/drm/i915/intel_display.c |  14 ++-
>  drivers/gpu/drm/i915/intel_drv.h     |   6 +-
>  drivers/gpu/drm/i915/intel_pm.c      | 203 -
> --
>  drivers/gpu/drm/i915/intel_sprite.c  |   8 +-
>  5 files changed, 88 insertions(+), 145 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> index 0f97d43..63519ac 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1643,8 +1643,6 @@ struct skl_ddb_allocation {
>  struct skl_wm_values {
>  unsigned dirty_pipes;
>  struct skl_ddb_allocation ddb;
> - uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
> - uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
>  };
>  
>  struct skl_wm_level {
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index dd15ae2..c580d3d 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3378,6 +3378,8 @@ static void skylake_update_primary_plane(struct
> drm_plane *plane,
>  struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state-
> >base.crtc);
>  struct drm_framebuffer *fb = plane_state->base.fb;
>  const struct skl_wm_values *wm = _priv->wm.skl_results;
> + const struct skl_plane_wm *p_wm =
> + _state->wm.skl.optimal.planes[0];

I wish someone would do a patch to convert all these hardcoded values
to PLANE_X, and convert "int"s  to "enum plane"s everywhere.


>  int pipe = intel_crtc->pipe;
>  u32 plane_ctl;
>  unsigned int rotation = plane_state->base.rotation;
> @@ -3414,7 +3416,7 @@ static void skylake_update_primary_plane(struct
> drm_plane *plane,
>  intel_crtc->adjusted_y = src_y;
>  
>  if (wm->dirty_pipes & drm_crtc_mask(_crtc->base))
> - skl_write_plane_wm(intel_crtc, wm, 0);
> + skl_write_plane_wm(intel_crtc, p_wm, >ddb, 0);
>  
>  I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
>  I915_WRITE(PLANE_OFFSET(pipe, 0), (src_y << 16) | src_x);
> @@ -3448,6 +3450,8 @@ static void
> skylake_disable_primary_plane(struct drm_plane *primary,
>  struct drm_device *dev = crtc->dev;
>  struct drm_i915_private *dev_priv = to_i915(dev);
>  struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> + struct intel_crtc_state *cstate = to_intel_crtc_state(crtc-
> >state);
> + const struct skl_plane_wm *p_wm = 
> >wm.skl.optimal.planes[0];
>  int pipe = intel_crtc->pipe;
>  
>  /*
> @@ -3455,7 +3459,8 @@ static void
> skylake_disable_primary_plane(struct drm_plane *primary,
>   * plane's visiblity isn't actually changing neither is its
> watermarks.
>   */
>  if (!crtc->primary->state->visible)
> - skl_write_plane_wm(intel_crtc, _priv-
> >wm.skl_results, 0);
> + skl_write_plane_wm(intel_crtc, p_wm,
> +    _priv->wm.skl_results.ddb,
> 0);
>  
>  I915_WRITE(PLANE_CTL(pipe, 0), 0);
>  I915_WRITE(PLANE_SURF(pipe, 0), 0);
> @@ -10819,12 +10824,15 @@ static void i9xx_update_cursor(struct
> drm_crtc *crtc, u32 base,
>  struct drm_device *dev = crtc->dev;
>  struct drm_i915_private *dev_priv = to_i915(dev);
>  struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> + struct intel_crtc_state *cstate = to_intel_crtc_state(crtc-
> >state);
>  const struct skl_wm_values *wm = _priv->wm.skl_results;
> + const struct skl_plane_wm *p_wm =
> + >wm.skl.optimal.planes[PLANE_CURSOR];
>  int pipe = intel_crtc->pipe;
>  uint32_t cntl = 0;
>  
>  if (INTEL_GEN(dev_priv) >= 9 && wm->dirty_pipes &
> drm_crtc_mask(crtc))
> - skl_write_cursor_wm(intel_crtc, wm);
> + skl_write_cursor_wm(intel_crtc, p_wm, >ddb);
>  
>  if (plane_state && plane_state->base.visible) {
>  cntl = MCURSOR_GAMMA_ENABLE;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> 

[Intel-gfx] [PATCH 4/6] drm/i915/gen9: Make skl_wm_level per-plane

2016-10-05 Thread Paulo Zanoni
Em Qua, 2016-10-05 às 11:33 -0400, Lyude escreveu:
> Having skl_wm_level contain all of the watermarks for each plane is
> annoying since it prevents us from having any sort of object to
> represent a single watermark level, something we take advantage of in
> the next commit to cut down on all of the copy paste code in here.

I'd like to start my review pointing that I really like this patch. I
agree the current form is annoying.

See below for some details.


> 
> Signed-off-by: Lyude 
> Cc: Maarten Lankhorst 
> Cc: Ville Syrjälä 
> Cc: Matt Roper 
> ---
>  drivers/gpu/drm/i915/i915_drv.h  |   6 +-
>  drivers/gpu/drm/i915/intel_drv.h |   6 +-
>  drivers/gpu/drm/i915/intel_pm.c  | 208 +--
> 
>  3 files changed, 100 insertions(+), 120 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> index d26e5999..0f97d43 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1648,9 +1648,9 @@ struct skl_wm_values {
>  };
>  
>  struct skl_wm_level {
> - bool plane_en[I915_MAX_PLANES];
> - uint16_t plane_res_b[I915_MAX_PLANES];
> - uint8_t plane_res_l[I915_MAX_PLANES];
> + bool plane_en;
> + uint16_t plane_res_b;
> + uint8_t plane_res_l;
>  };
>  
>  /*
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index 35ba282..d684f4f 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -468,9 +468,13 @@ struct intel_pipe_wm {
>  bool sprites_scaled;
>  };
>  
> -struct skl_pipe_wm {
> +struct skl_plane_wm {
>  struct skl_wm_level wm[8];
>  struct skl_wm_level trans_wm;
> +};
> +
> +struct skl_pipe_wm {
> + struct skl_plane_wm planes[I915_MAX_PLANES];
>  uint32_t linetime;
>  };
>  
> diff --git a/drivers/gpu/drm/i915/intel_pm.c
> b/drivers/gpu/drm/i915/intel_pm.c
> index af96888..250f12d 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3668,67 +3668,52 @@ static int
>  skl_compute_wm_level(const struct drm_i915_private *dev_priv,
>       struct skl_ddb_allocation *ddb,
>       struct intel_crtc_state *cstate,
> +      struct intel_plane *intel_plane,
>       int level,
>       struct skl_wm_level *result)
>  {
>  struct drm_atomic_state *state = cstate->base.state;
>  struct intel_crtc *intel_crtc = to_intel_crtc(cstate-
> >base.crtc);
> - struct drm_plane *plane;
> - struct intel_plane *intel_plane;
> - struct intel_plane_state *intel_pstate;
> + struct drm_plane *plane = _plane->base;
> + struct intel_plane_state *intel_pstate = NULL;
>  uint16_t ddb_blocks;
>  enum pipe pipe = intel_crtc->pipe;
>  int ret;
> + int i = skl_wm_plane_id(intel_plane);
> +
> + if (state)
> + intel_pstate =
> + intel_atomic_get_existing_plane_state(state,
> +       intel_
> plane);
>  
>  /*
> -  * We'll only calculate watermarks for planes that are
> actually
> -  * enabled, so make sure all other planes are set as
> disabled.
> +  * Note: If we start supporting multiple pending atomic
> commits against
> +  * the same planes/CRTC's in the future, plane->state will
> no longer be
> +  * the correct pre-state to use for the calculations here
> and we'll
> +  * need to change where we get the 'unchanged' plane data
> from.
> +  *
> +  * For now this is fine because we only allow one queued
> commit against
> +  * a CRTC.  Even if the plane isn't modified by this
> transaction and we
> +  * don't have a plane lock, we still have the CRTC's lock,
> so we know
> +  * that no other transactions are racing with us to update
> it.
>   */
> - memset(result, 0, sizeof(*result));
> -
> - for_each_intel_plane_mask(_priv->drm,
> -   intel_plane,
> -   cstate->base.plane_mask) {
> - int i = skl_wm_plane_id(intel_plane);
> -
> - plane = _plane->base;
> - intel_pstate = NULL;
> - if (state)
> - intel_pstate =
> - intel_atomic_get_existing_plane_stat
> e(state,
> -     
>   intel_plane);
> + if (!intel_pstate)
> + intel_pstate = to_intel_plane_state(plane->state);
>  
> - /*
> -  * Note: If we start supporting multiple pending
> atomic commits
> -  * against the same planes/CRTC's in the future,
> plane->state
> -  * will no longer be the correct pre-state to use
> for the
> -  * calculations here and we'll need to change where
> we get the
> -   

[Intel-gfx] [PATCH 2/6] drm/i915/skl: Remove linetime from skl_wm_values

2016-10-05 Thread Paulo Zanoni
Em Qua, 2016-10-05 às 11:33 -0400, Lyude escreveu:
> Next part of cleaning up the watermark code for skl. This is easy,
> since
> it seems that we never actually needed to keep track of the linetime
> in
> the skl_wm_values struct anyway.

Reviewed-by: Paulo Zanoni 

> 
> Signed-off-by: Lyude 
> Cc: Maarten Lankhorst 
> Cc: Ville Syrjälä 
> Cc: Matt Roper 
> ---
>  drivers/gpu/drm/i915/i915_drv.h      | 1 -
>  drivers/gpu/drm/i915/intel_display.c | 6 --
>  drivers/gpu/drm/i915/intel_pm.c      | 7 +--
>  3 files changed, 5 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> index 85e541c..d26e5999 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1643,7 +1643,6 @@ struct skl_ddb_allocation {
>  struct skl_wm_values {
>  unsigned dirty_pipes;
>  struct skl_ddb_allocation ddb;
> - uint32_t wm_linetime[I915_MAX_PIPES];
>  uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
>  uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
>  };
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index 17733af..a71d05a 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -14832,6 +14832,8 @@ static void intel_begin_crtc_commit(struct
> drm_crtc *crtc,
>  struct drm_device *dev = crtc->dev;
>  struct drm_i915_private *dev_priv = to_i915(dev);
>  struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> + struct intel_crtc_state *intel_cstate =
> + to_intel_crtc_state(crtc->state);
>  struct intel_crtc_state *old_intel_state =
>  to_intel_crtc_state(old_crtc_state);
>  bool modeset = needs_modeset(crtc->state);
> @@ -14848,13 +14850,13 @@ static void intel_begin_crtc_commit(struct
> drm_crtc *crtc,
>  intel_color_load_luts(crtc->state);
>  }
>  
> - if (to_intel_crtc_state(crtc->state)->update_pipe)
> + if (intel_cstate->update_pipe)
>  intel_update_pipe_config(intel_crtc,
> old_intel_state);
>  else if (INTEL_GEN(dev_priv) >= 9) {
>  skl_detach_scalers(intel_crtc);
>  
>  I915_WRITE(PIPE_WM_LINETIME(pipe),
> -    dev_priv->wm.skl_hw.wm_linetime[pipe]);
> +    intel_cstate->wm.skl.optimal.linetime);
>  }
>  }
>  
> diff --git a/drivers/gpu/drm/i915/intel_pm.c
> b/drivers/gpu/drm/i915/intel_pm.c
> index 0383516..af96888 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3839,8 +3839,6 @@ static void skl_compute_wm_results(struct
> drm_device *dev,
>  temp |= PLANE_WM_EN;
>  
>  r->plane_trans[pipe][PLANE_CURSOR] = temp;
> -
> - r->wm_linetime[pipe] = p_wm->linetime;
>  }
>  
>  static void skl_ddb_entry_write(struct drm_i915_private *dev_priv,
> @@ -4069,7 +4067,6 @@ skl_copy_wm_for_pipe(struct skl_wm_values *dst,
>       struct skl_wm_values *src,
>       enum pipe pipe)
>  {
> - dst->wm_linetime[pipe] = src->wm_linetime[pipe];
>  memcpy(dst->plane[pipe], src->plane[pipe],
>         sizeof(dst->plane[pipe]));
>  memcpy(dst->plane_trans[pipe], src->plane_trans[pipe],
> @@ -4320,8 +4317,6 @@ static void skl_pipe_wm_get_hw_state(struct
> drm_crtc *crtc)
>  
>  max_level = ilk_wm_max_level(dev);
>  
> - hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe));
> -
>  for (level = 0; level <= max_level; level++) {
>  for (i = 0; i < intel_num_planes(intel_crtc); i++)
>  hw->plane[pipe][i][level] =
> @@ -4338,7 +4333,7 @@ static void skl_pipe_wm_get_hw_state(struct
> drm_crtc *crtc)
>  
>  hw->dirty_pipes |= drm_crtc_mask(crtc);
>  
> - active->linetime = hw->wm_linetime[pipe];
> + active->linetime = I915_READ(PIPE_WM_LINETIME(pipe));
>  
>  for (level = 0; level <= max_level; level++) {
>  for (i = 0; i < intel_num_planes(intel_crtc); i++) {


[Intel-gfx] [PATCH 1/6] drm/i915/skl: Move per-pipe ddb allocations into crtc states

2016-10-05 Thread Paulo Zanoni
Em Qua, 2016-10-05 às 11:33 -0400, Lyude escreveu:
> First part of cleaning up all of the skl watermark code. This moves
> the
> structures for storing the ddb allocations of each pipe into
> intel_crtc_state, along with moving the structures for storing the
> current ddb allocations active on hardware into intel_crtc.
> 
> Signed-off-by: Lyude 
> Cc: Maarten Lankhorst 
> Cc: Ville Syrjälä 
> Cc: Matt Roper 
> ---
>  drivers/gpu/drm/i915/i915_drv.h      |  1 -
>  drivers/gpu/drm/i915/intel_display.c | 16 ---
>  drivers/gpu/drm/i915/intel_drv.h     |  8 +---
>  drivers/gpu/drm/i915/intel_pm.c      | 40 +++---
> --
>  4 files changed, 30 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> index f8c66ee..85e541c 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1636,7 +1636,6 @@ static inline bool skl_ddb_entry_equal(const
> struct skl_ddb_entry *e1,
>  }
>  
>  struct skl_ddb_allocation {
> - struct skl_ddb_entry pipe[I915_MAX_PIPES];
>  struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
> /* packed/uv */
>  struct skl_ddb_entry
> y_plane[I915_MAX_PIPES][I915_MAX_PLANES];
>  };
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index a366656..17733af 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -14235,12 +14235,11 @@ static void skl_update_crtcs(struct
> drm_atomic_state *state,
>       unsigned int *crtc_vblank_mask)
>  {
>  struct drm_device *dev = state->dev;
> - struct drm_i915_private *dev_priv = to_i915(dev);
>  struct intel_atomic_state *intel_state =
> to_intel_atomic_state(state);
>  struct drm_crtc *crtc;
> + struct intel_crtc *intel_crtc;
>  struct drm_crtc_state *old_crtc_state;
> - struct skl_ddb_allocation *new_ddb = _state-
> >wm_results.ddb;
> - struct skl_ddb_allocation *cur_ddb = _priv-
> >wm.skl_hw.ddb;
> + struct intel_crtc_state *cstate;
>  unsigned int updated = 0;
>  bool progress;
>  enum pipe pipe;
> @@ -14258,12 +14257,14 @@ static void skl_update_crtcs(struct
> drm_atomic_state *state,
>  for_each_crtc_in_state(state, crtc, old_crtc_state,
> i) {
>  bool vbl_wait = false;
>  unsigned int cmask = drm_crtc_mask(crtc);
> - pipe = to_intel_crtc(crtc)->pipe;
> +
> + intel_crtc = to_intel_crtc(crtc);
> + cstate = to_intel_crtc_state(crtc->state);
> + pipe = intel_crtc->pipe;
>  
>  if (updated & cmask || !crtc->state->active)
>  continue;
> - if (skl_ddb_allocation_overlaps(state,
> cur_ddb, new_ddb,
> - pipe))
> + if (skl_ddb_allocation_overlaps(state,
> intel_crtc))
>  continue;
>  
>  updated |= cmask;
> @@ -14274,7 +14275,8 @@ static void skl_update_crtcs(struct
> drm_atomic_state *state,
>   * then we need to wait for a vblank to pass
> for the
>   * new ddb allocation to take effect.
>   */
> - if (!skl_ddb_allocation_equals(cur_ddb,
> new_ddb, pipe) &&
> + if (!skl_ddb_entry_equal(
> >wm.skl.ddb,
> +  _crtc-
> >hw_ddb) &&
>      !crtc->state->active_changed &&
>      intel_state->wm_results.dirty_pipes !=
> updated)
>  vbl_wait = true;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index f48e79a..35ba282 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -496,6 +496,7 @@ struct intel_crtc_wm_state {
>  struct {
>  /* gen9+ only needs 1-step wm programming */
>  struct skl_pipe_wm optimal;
> + struct skl_ddb_entry ddb;
>  
>  /* cached plane data rate */
>  unsigned plane_data_rate[I915_MAX_PLANES];
> @@ -733,6 +734,9 @@ struct intel_crtc {
>  bool cxsr_allowed;
>  } wm;
>  
> + /* gen9+: ddb allocation currently being used */
> + struct skl_ddb_entry hw_ddb;
> +
>  int scanline_offset;
>  
>  struct {
> @@ -1755,9 +1759,7 @@ bool skl_ddb_allocation_equals(const struct
> skl_ddb_allocation *old,
>         const struct skl_ddb_allocation *new,
>         enum pipe pipe);
>  bool skl_ddb_allocation_overlaps(struct drm_atomic_state *state,
> -  

[Intel-gfx] [PATCH 3/6] drm/i915: Add enable_sagv option

2016-10-05 Thread Paulo Zanoni
Em Qua, 2016-10-05 às 11:33 -0400, Lyude escreveu:
> This option allows us to manually control the SAGV at module load
> time.
> This can be useful in situations such as trying to debug watermark
> changes, since enabled SAGV + incorrect watermarks = total GPU
> annihilation.

I'm not a huge fan of adding options that are only for very limited
debugging situations, especially simple ones that can always just be
re-implemented during debugging sessions such as this one. Anyway, I'm
not opposed to adding the option since it's marked as unsafe anyway,
I'm just stating my general opinion. See more below.


> 
> Signed-off-by: Lyude 
> Cc: Maarten Lankhorst 
> Cc: Ville Syrjälä 
> Cc: Matt Roper 
> ---
>  drivers/gpu/drm/i915/i915_params.c   |  5 +
>  drivers/gpu/drm/i915/i915_params.h   |  1 +
>  drivers/gpu/drm/i915/intel_display.c | 16 +---
>  3 files changed, 19 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_params.c
> b/drivers/gpu/drm/i915/i915_params.c
> index 768ad89..f462cd4 100644
> --- a/drivers/gpu/drm/i915/i915_params.c
> +++ b/drivers/gpu/drm/i915/i915_params.c
> @@ -62,6 +62,7 @@ struct i915_params i915 __read_mostly = {
>  .inject_load_failure = 0,
>  .enable_dpcd_backlight = false,
>  .enable_gvt = false,
> + .enable_sagv = -1,
>  };
>  
>  module_param_named(modeset, i915.modeset, int, 0400);
> @@ -233,3 +234,7 @@ MODULE_PARM_DESC(enable_dpcd_backlight,
>  module_param_named(enable_gvt, i915.enable_gvt, bool, 0400);
>  MODULE_PARM_DESC(enable_gvt,
>  "Enable support for Intel GVT-g graphics virtualization host
> support(default:false)");
> +
> +module_param_named_unsafe(enable_sagv, i915.enable_sagv, int, 0400);
> +MODULE_PARM_DESC(enable_sagv,
> + "Enable the SAGV (gen9+ only)(1=enabled, 0=disabled,
> -1=driver discretion [default])");
> diff --git a/drivers/gpu/drm/i915/i915_params.h
> b/drivers/gpu/drm/i915/i915_params.h
> index 3a0dd78..a7db125 100644
> --- a/drivers/gpu/drm/i915/i915_params.h
> +++ b/drivers/gpu/drm/i915/i915_params.h
> @@ -65,6 +65,7 @@ struct i915_params {
>  bool enable_dp_mst;
>  bool enable_dpcd_backlight;
>  bool enable_gvt;
> + int enable_sagv;
>  };
>  
>  extern struct i915_params i915 __read_mostly;
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index a71d05a..dd15ae2 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -16904,12 +16904,22 @@ intel_modeset_setup_hw_state(struct
> drm_device *dev)
>  pll->on = false;
>  }
>  
> - if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
> + if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
>  vlv_wm_get_hw_state(dev);
> - else if (IS_GEN9(dev))
> + } else if (IS_GEN9(dev)) {
>  skl_wm_get_hw_state(dev);
> - else if (HAS_PCH_SPLIT(dev))
> +
> + if (i915.enable_sagv != -1) {
> + if (i915.enable_sagv)
> + intel_enable_sagv(dev_priv);
> + else
> + intel_disable_sagv(dev_priv);
> +
> + dev_priv->sagv_status =
> I915_SAGV_NOT_CONTROLLED;

Adding this code to the middle of a get_hw_state() if-ladder doesn't
seem to be the best approach. My suggestion would be to create
intel_setup_sagv() (or intel_init_sagv) and then call it from somewhere
(maybe the end of this function?).

Also, I915_SAGV_NOT_CONTROLLED is only used on Skylake. By setting
sagv_status to to you're making i915.enable_sagv behave differently on
SKL compared to "all the other" (aka only KBL now) platforms. It would
probably be better to have unified behavior, maybe by reworking the
I915_SAGV_NOT_CONTROLLED handling or just adding a new flag or
something else.


> + }
> + } else if (HAS_PCH_SPLIT(dev)) {
>  ilk_wm_get_hw_state(dev);
> + }
>  
>  for_each_intel_crtc(dev, crtc) {
>  unsigned long put_domains;


[PATCH 3/3] drm: Move DRM_MODE_OBJECT_* to uapi headers

2016-03-30 Thread Paulo Zanoni
2016-03-30 13:07 GMT-03:00 Emil Velikov :
> On 30 March 2016 at 15:19, Daniel Vetter  wrote:
>> These type defines are officially part of the uapi, but ended up in
>> the wrong headers somehow when we split them all.
>>
>> Cc: Emil Velikov 
>> Signed-off-by: Daniel Vetter 
> The way it was done originally (by Paulo) with commit
> c543188afb7a83e66161c026dc6fd5eb38dc0b63 it seemed deliberate. At the
> same time the libdrm got a different treatment
> 8c75703df0fdf65b3851f8eb5822705638decff3. Would be swell Paulo can
> confirm (re: unintentional or deliberate difference), if he recalls
> any of this :-)
>
> Barring any objections from Paulo

No objections from Paulo. The include/uapi directory didn't even exist
at that time, and I guess I was just trying to make things work,
without any specific coding philosophy in mind.

> Reviewed-by: Emil Velikov 
>
> -Emil
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Paulo Zanoni


[Intel-gfx] [PATCH 11/9] drm/i915: Opt out of vblank disable timer on >gen2

2015-11-19 Thread Paulo Zanoni
2015-11-19 18:06 GMT-02:00 Ville Syrjälä :
> On Thu, Nov 19, 2015 at 05:44:51PM -0200, Paulo Zanoni wrote:
>> 2014-05-26 11:26 GMT-03:00  :
>> > From: Ville Syrjälä 
>> >
>> > Now that the vblank races are plugged, we can opt out of using
>> > the vblank disable timer and just let vblank interrupts get
>> > disabled immediately when the last reference is dropped.
>> >
>> > Gen2 is the exception since it has no hardware frame counter.
>>
>> Hi
>>
>> Remember last week's FBC vblank optimization patch that had an
>> erroneous drm_crtc_vblank_get() instead of drm_crtc_vblank_count()?
>> After I fixed the bug in the patch I realized that it was the
>> unbalanced vblank_get() call that moved PC state residency up.
>>
>> I did some experiments, and on my specific BDW machine, after running
>> "powertop --auto-tune", I get about 15-25% PC7 residency without FBC.
>> If I revert this patch, the number jumps to 40-45%. With FBC, the PC7
>> residency goes from 60-70% to 85-90% when I revert this patch. I'm
>> running just an idle Cinnamon with an open terminal.
>>
>> So, since the commit message lacks more details, what are the
>> downsides of reverting this patch? What are the advantages of opting
>> out of the vblank timer? I see my desktop does tons and tons of vblank
>> get/put calls per second, so the disable timer makes a lot of sense.
>
> "Idle" desktop :(

My first realization of this little problem was when I was
implementing runtime PM :)


>
> Really the immediate disable should save power. Where are these tons of
> vblank get/puts coming from actually?

I'll take a finer look tomorrow, but I assume it's probably some
application redrawing. I see it does calm down sometimes, but that's
not enough to get better PC7 residency.


> I would assume you'd get a handful
> per frame at most, and that when you're actually doing something. On an
> idle system I would expect nothing at all happens during most frames.
>
> Not sure, but I guess it's possible the extra register accesses in the
> get/puts actually cause the display to exit low power states all the time,
> or something.

I tried replacing the register macros with the _FW version and that didn't help.


>
> There's also this note in Bspec (for HSW at least):

I think this not is present on most (all?) gens.


>  "Workaround : Do not enable and unmask this interrupt if the associated
>   pipe is disabled.  Do not leave this interrupt enabled and unmasked
>   after the associated pipe is disabled."
> which we took to mean that having the interrupt masked but enabled is
> fine.

I'm aware of this, but I think the problem is that the resources
drained by the constant enable+disable+enable+disable outweigh the
resources saved by turning off vblanks. Not sure if there's an extra
reason why BSpec asks us to immediately disable vblanks though...

So, to summarize, the main (only?) reason is the BSpec comment?


> But maybe we'd actually have to frob IER too to avoid wasting
> power somehow?

With the interrupt masked on IMR, I don't think IER matters.

>
>> I also wish there was some easy way to check how this patch (or its
>> revert) affect a bunch of different workloads...
>>
>> (Also CCing Chris for insightful comments on performance)
>
> IIRC Chris had a patch to not disable the interrupt immediately when
> the refcount drops to 0, but instead delay the disable until the next
> interrupt actually happens. But I guess it didn't go in? Probably I
> should have reviewed it but didn't. It sounds like a decent idea to
> me in any case for the active use case.
>
>>
>> Thanks,
>> Paulo
>>
>> >
>> > Signed-off-by: Ville Syrjälä 
>> > ---
>> >  drivers/gpu/drm/i915/i915_irq.c | 8 
>> >  1 file changed, 8 insertions(+)
>> >
>> > diff --git a/drivers/gpu/drm/i915/i915_irq.c 
>> > b/drivers/gpu/drm/i915/i915_irq.c
>> > index 28bae6e..4b2e7af 100644
>> > --- a/drivers/gpu/drm/i915/i915_irq.c
>> > +++ b/drivers/gpu/drm/i915/i915_irq.c
>> > @@ -4364,6 +4364,14 @@ void intel_irq_init(struct drm_device *dev)
>> > dev->max_vblank_count = 0xff; /* only 24 bits of frame 
>> > count */
>> > }
>> >
>> > +   /*
>> > +* Opt out of the vblank disable timer on everything except gen2.
>> > +* Gen2 doesn't have a hardware frame counter and so depends on
>> > +* vblank interrupts to produce sane vblank seuquence numbers.
>> > +*/
>> > +   if (!IS_GEN2(dev))
&

[Intel-gfx] [PATCH 11/9] drm/i915: Opt out of vblank disable timer on >gen2

2015-11-19 Thread Paulo Zanoni
2014-05-26 11:26 GMT-03:00  :
> From: Ville Syrjälä 
>
> Now that the vblank races are plugged, we can opt out of using
> the vblank disable timer and just let vblank interrupts get
> disabled immediately when the last reference is dropped.
>
> Gen2 is the exception since it has no hardware frame counter.

Hi

Remember last week's FBC vblank optimization patch that had an
erroneous drm_crtc_vblank_get() instead of drm_crtc_vblank_count()?
After I fixed the bug in the patch I realized that it was the
unbalanced vblank_get() call that moved PC state residency up.

I did some experiments, and on my specific BDW machine, after running
"powertop --auto-tune", I get about 15-25% PC7 residency without FBC.
If I revert this patch, the number jumps to 40-45%. With FBC, the PC7
residency goes from 60-70% to 85-90% when I revert this patch. I'm
running just an idle Cinnamon with an open terminal.

So, since the commit message lacks more details, what are the
downsides of reverting this patch? What are the advantages of opting
out of the vblank timer? I see my desktop does tons and tons of vblank
get/put calls per second, so the disable timer makes a lot of sense.

I also wish there was some easy way to check how this patch (or its
revert) affect a bunch of different workloads...

(Also CCing Chris for insightful comments on performance)

Thanks,
Paulo

>
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/i915_irq.c | 8 
>  1 file changed, 8 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 28bae6e..4b2e7af 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -4364,6 +4364,14 @@ void intel_irq_init(struct drm_device *dev)
> dev->max_vblank_count = 0xff; /* only 24 bits of frame 
> count */
> }
>
> +   /*
> +* Opt out of the vblank disable timer on everything except gen2.
> +* Gen2 doesn't have a hardware frame counter and so depends on
> +* vblank interrupts to produce sane vblank seuquence numbers.
> +*/
> +   if (!IS_GEN2(dev))
> +   dev->vblank_disable_immediate = true;
> +
> if (drm_core_check_feature(dev, DRIVER_MODESET)) {
> dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp;
> dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
> --
> 1.8.5.5
>
> ___
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni


[PATCH 2/5] drm: Add edid_corrupt flag for Displayport Link CTS 4.2.2.6

2015-04-30 Thread Paulo Zanoni
2015-04-22 17:20 GMT-03:00 Alex Deucher :
> On Tue, Apr 21, 2015 at 2:09 PM, Todd Previte  wrote:
>> Displayport compliance test 4.2.2.6 requires that a source device be capable 
>> of
>> detecting a corrupt EDID. The test specification states that the sink device
>> sets up the EDID with an invalid checksum. To do this, the sink sets up an
>> invalid EDID header, expecting the source device to generate the checksum and
>> compare it to the value stored in the last byte of the block data.
>>
>> Unfortunately, the DRM EDID reading and parsing functions are actually too 
>> good
>> in this case; the header is fixed before the checksum is computed and thus 
>> the
>> test never sees the invalid checksum. This results in a failure to pass the
>> compliance test.
>>
>> To correct this issue, when the EDID code detects that the header is invalid,
>> a flag is set to indicate that the EDID is corrupted. In this case, it sets
>> edid_corrupt flag and continues with its fix-up code. This flag is also set 
>> in
>> the case of a more seriously damaged header (fixup score less than the
>> threshold). For consistency, the edid_corrupt flag is also set when the
>> checksum is invalid as well.
>>
>> V2:
>> - Removed the static bool global
>> - Added a bool to the drm_connector struct to reaplce the static one for
>>   holding the status of raw edid header corruption detection
>> - Modified the function signature of the is_valid function to take an
>>   additional parameter to store the corruption detected value
>> - Fixed the other callers of the above is_valid function
>> V3:
>> - Updated the commit message to be more clear about what and why this
>>   patch does what it does.
>> - Added comment in code to clarify the operations there
>> - Removed compliance variable and check_link_status update; those
>>   have been moved to a later patch
>> - Removed variable assignment from the bottom of the test handler
>> V4:
>> - Removed i915 tag from subject line as the patch is not i915-specific
>> V5:
>> - Moved code causing a compilation error to this patch where the variable
>>   is actually declared
>> - Maintained blank lines / spacing so as to not contaminate the patch
>> V6:
>> - Removed extra debug messages
>> - Added documentation to for the added parameter on drm_edid_block_valid
>> - Fixed more whitespace issues in check_link_status
>> - Added a clear of the header_corrupt flag to the end of the test handler
>>   in intel_dp.c
>> - Changed the usage of the new function prototype in several places to use
>>   NULL where it is not needed by compliance testing
>> V7:
>> - Updated to account for long_pulse flag propagation
>> V8:
>> - Removed clearing of header_corrupt flag from the test handler in intel_dp.c
>> - Added clearing of header_corrupt flag in the drm_edid_block_valid function
>> V9:
>> - Renamed header_corrupt flag to edid_corrupt to more accurately reflect its
>>   value and purpose
>> - Updated commit message
>> V10:
>> - Updated for versioning and patch swizzle
>> - Revised the title to more accurately reflect the nature and contents of
>>   the patch
>> - Fixed formatting/whitespace problems
>> - Added set flag when computed checksum is invalid
>>
>> Signed-off-by: Todd Previte 
>> Cc: dri-devel at lists.freedesktop.org
>
> Seems reasonable.
>
> Reviewed-by: Alex Deucher 
Reviewed-by: Paulo Zanoni 
(since I made comments on the previous versions, this is my
documentation that the patch looks fine to me now)

>
>> ---
>>  drivers/gpu/drm/drm_edid.c  | 32 ++--
>>  drivers/gpu/drm/drm_edid_load.c |  7 +--
>>  include/drm/drm_crtc.h  |  8 +++-
>>  3 files changed, 38 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
>> index 53bc7a6..be6713c 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -1041,13 +1041,15 @@ static bool drm_edid_is_zero(const u8 *in_edid, int 
>> length)
>>   * @raw_edid: pointer to raw EDID block
>>   * @block: type of block to validate (0 for base, extension otherwise)
>>   * @print_bad_edid: if true, dump bad EDID blocks to the console
>> + * @edid_corrupt: if true, the header or checksum is invalid
>>   *
>>   * Validate a base or extension EDID block and optionally dump bad blocks to
>>   * the console.
>>   *
>>   * Return: True if the block is valid, false otherwise.
>>   */
>> -b

[PATCH 08/10] drm: Fix for DP CTS test 4.2.2.5 - I2C DEFER handling

2015-04-16 Thread Paulo Zanoni
2015-04-15 12:38 GMT-03:00 Todd Previte :
> For test 4.2.2.5 to pass per the Link CTS Core 1.2 rev1.1 spec, the source
> device must attempt at least 7 times to read the EDID when it receives an
> I2C defer. The normal DRM code makes only 7 retries, regardless of whether
> or not the response is a native defer or an I2C defer. Test 4.2.2.5 fails
> since there are native defers interspersed with the I2C defers which
> results in less than 7 EDID read attempts.
>
> The solution is to add the numer of defers to the retry counter when an I2C
> DEFER is returned such that another read attempt will be made. This situation
> should normally only occur in compliance testing, however, as a worse case
> real-world scenario, it would result in 13 attempts ( 6 native defers, 7 I2C
> defers) for a single transaction to complete. The net result is a slightly
> slower response to an EDID read that shouldn't significantly impact overall
> performance.
>
> V2:
> - Added a check on the number of I2C Defers to limit the number
>   of times that the retries variable will be decremented. This
>   is to address review feedback regarding possible infinite loops
>   from misbehaving sink devices.
> V3:
> - Fixed the limit value to 7 instead of 8 to get the correct retry
>   count.
> - Combined the increment of the defer count into the if-statement
> V4:
> - Removed i915 tag from subject as the patch is not i915-specific
> V5:
> - Updated the for-loop to add the number of i2c defers to the retry
>   counter such that the correct number of retry attempts will be
>   made
>
> Signed-off-by: Todd Previte 
> Cc: dri-devel at lists.freedesktop.org

Reviewed-by: Paulo Zanoni 
(although just counting to 14 probably wouldn't hurt and would make
things simpler)

> ---
>  drivers/gpu/drm/drm_dp_helper.c | 10 --
>  1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
> index 71dcbc6..7f0356e 100644
> --- a/drivers/gpu/drm/drm_dp_helper.c
> +++ b/drivers/gpu/drm/drm_dp_helper.c
> @@ -432,7 +432,7 @@ static u32 drm_dp_i2c_functionality(struct i2c_adapter 
> *adapter)
>   */
>  static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg 
> *msg)
>  {
> -   unsigned int retry;
> +   unsigned int retry, defer_i2c;
> int ret;
>
> /*
> @@ -440,7 +440,7 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, 
> struct drm_dp_aux_msg *msg)
>  * is required to retry at least seven times upon receiving AUX_DEFER
>  * before giving up the AUX transaction.
>  */
> -   for (retry = 0; retry < 7; retry++) {
> +   for (retry = 0, defer_i2c = 0; retry < (7 + defer_i2c); retry++) {
> mutex_lock(>hw_mutex);
> ret = aux->transfer(aux, msg);
> mutex_unlock(>hw_mutex);
> @@ -499,7 +499,13 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, 
> struct drm_dp_aux_msg *msg)
>
> case DP_AUX_I2C_REPLY_DEFER:
> DRM_DEBUG_KMS("I2C defer\n");
> +   /* DP Compliance Test 4.2.2.5 Requirement:
> +* Must have at least 7 retries for I2C defers on the
> +* transaction to pass this test
> +*/
> aux->i2c_defer_count++;
> +   if (defer_i2c < 7)
> +   defer_i2c++;
>     usleep_range(400, 500);
> continue;
>
> --
> 1.9.1
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Paulo Zanoni


[PATCH 05/12] drm: Add supporting structure for Displayport Link CTS test 4.2.2.6

2015-04-16 Thread Paulo Zanoni
> +   if (drm_edid_block_valid(edid + i * EDID_LENGTH, i,
> +print_bad_edid,
> +NULL))
> valid_extensions++;
> }
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 7ca0e18..97224ff 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -4139,7 +4139,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp, 
> bool long_hpd)
>  */
> if (long_hpd) {
> edid_read = drm_get_edid(connector, adapter);
> -   if (!edid_read) {
> +   if (!edid_read || connector->edid_header_corrupt == 1) {
> DRM_DEBUG_DRIVER("Invalid EDID detected\n");
> } else {
> kfree(edid_read);
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index d4e4b82..f7a4a92 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -719,6 +719,11 @@ struct drm_connector {
> int null_edid_counter; /* needed to workaround some HW bugs where we 
> get all 0s */
> unsigned bad_edid_counter;
>
> +   /* Flag for raw EDID header corruption - used in Displayport
> +* compliance testing - * Displayport Link CTS Core 1.2 rev1.1 4.2.2.6
> +*/
> +   bool edid_header_corrupt;
> +
> struct dentry *debugfs_entry;
>
> struct drm_connector_state *state;
> @@ -1443,7 +1448,8 @@ extern void drm_set_preferred_mode(struct drm_connector 
> *connector,
>int hpref, int vpref);
>
>  extern int drm_edid_header_is_valid(const u8 *raw_edid);
> -extern bool drm_edid_block_valid(u8 *raw_edid, int block, bool 
> print_bad_edid);
> +extern bool drm_edid_block_valid(u8 *raw_edid, int block, bool 
> print_bad_edid,
> +bool *header_corrupt);
>  extern bool drm_edid_is_valid(struct edid *edid);
>
>  extern struct drm_tile_group *drm_mode_create_tile_group(struct drm_device 
> *dev,
> --
> 1.9.1
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Paulo Zanoni


[Intel-gfx] [PATCH 05/12] drm: Add supporting structure for Displayport Link CTS test 4.2.2.6

2015-04-15 Thread Paulo Zanoni
did_header_corrupt = 0;

I don't think it makes sense to clear this inside i915.ko. We're
adding the feature to drm.ko, so It makes sense to clear it there.

Isn't it possible to just clear it inside drm_edid_block_valid()?
Something like:

if (score == 8) {
if (header_corrupt)
*header_corrupt = 0;
} else if (score >= edid_fixup) {
... etc ...
}
}

If not, why?


>  }
>
>  static int
> @@ -4136,7 +4140,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp, 
> bool long_hpd)
>  */
> if (long_hpd) {
> edid_read = drm_get_edid(connector, adapter);
> -   if (!edid_read) {
> +   if (!edid_read || connector->edid_header_corrupt == 1) {
> DRM_DEBUG_DRIVER("Invalid EDID detected\n");
> } else {
> kfree(edid_read);
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index d4e4b82..f7a4a92 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -719,6 +719,11 @@ struct drm_connector {
> int null_edid_counter; /* needed to workaround some HW bugs where we 
> get all 0s */
> unsigned bad_edid_counter;
>
> +   /* Flag for raw EDID header corruption - used in Displayport
> +* compliance testing - * Displayport Link CTS Core 1.2 rev1.1 4.2.2.6
> +*/
> +   bool edid_header_corrupt;
> +
> struct dentry *debugfs_entry;
>
> struct drm_connector_state *state;
> @@ -1443,7 +1448,8 @@ extern void drm_set_preferred_mode(struct drm_connector 
> *connector,
>int hpref, int vpref);
>
>  extern int drm_edid_header_is_valid(const u8 *raw_edid);
> -extern bool drm_edid_block_valid(u8 *raw_edid, int block, bool 
> print_bad_edid);
> +extern bool drm_edid_block_valid(u8 *raw_edid, int block, bool 
> print_bad_edid,
> +bool *header_corrupt);
>  extern bool drm_edid_is_valid(struct edid *edid);
>
>  extern struct drm_tile_group *drm_mode_create_tile_group(struct drm_device 
> *dev,
> --
> 1.9.1
>
> ___
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni


[PATCH 06/13] drm: Add supporting structure for Displayport Link CTS test 4.2.2.6

2015-04-13 Thread Paulo Zanoni
a998x_priv *priv)
> if (read_edid_block(priv, block, 0))
> goto fail;
>
> -   if (!drm_edid_block_valid(block, 0, print_bad_edid))
> +   if (!drm_edid_block_valid(block, 0, print_bad_edid, NULL))
> goto fail;
>
> /* if there's no extensions, we're done */
> @@ -1123,7 +1123,7 @@ static uint8_t *do_get_edid(struct tda998x_priv *priv)
> if (read_edid_block(priv, ext_block, j))
> goto fail;
>
> -   if (!drm_edid_block_valid(ext_block, j, print_bad_edid))
> +   if (!drm_edid_block_valid(ext_block, j, print_bad_edid, NULL))
> goto fail;
>
> valid_extensions++;
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index e1d6e79..77b6b15 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -3922,7 +3922,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
>  * 4.2.2.1 - EDID read required for all HPD events
>   */
>  edid_read = drm_get_edid(connector, adapter);
> -if (!edid_read) {
> +if (!edid_read || connector->edid_header_corrupt == 1) {
>  DRM_DEBUG_DRIVER("Invalid EDID detected\n");
>  }
>
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 0261417..e31a4b3 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -719,6 +719,11 @@ struct drm_connector {
> int null_edid_counter; /* needed to workaround some HW bugs where we 
> get all 0s */
> unsigned bad_edid_counter;
>
> +   /* Flag for raw EDID header corruption - used in Displayport 
> compliance testing
> +* Displayport Link CTS Core 1.2 rev1.1 4.2.2.6
> +*/
> +   bool edid_header_corrupt;
> +
> struct dentry *debugfs_entry;
>
>     struct drm_connector_state *state;
> @@ -1436,7 +1441,8 @@ extern void drm_set_preferred_mode(struct drm_connector 
> *connector,
>int hpref, int vpref);
>
>  extern int drm_edid_header_is_valid(const u8 *raw_edid);
> -extern bool drm_edid_block_valid(u8 *raw_edid, int block, bool 
> print_bad_edid);
> +extern bool drm_edid_block_valid(u8 *raw_edid, int block, bool 
> print_bad_edid, bool *header_corrupt);
> +
>  extern bool drm_edid_is_valid(struct edid *edid);
>
>  extern struct drm_tile_group *drm_mode_create_tile_group(struct drm_device 
> *dev,
> --
> 1.9.1
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Paulo Zanoni


[Intel-gfx] [PATCH 4/9] drm/i915: Add check for corrupt raw EDID header for Displayport compliance testing

2015-04-08 Thread Paulo Zanoni
2015-04-08 18:43 GMT-03:00 Todd Previte :
>
>
> On 4/8/2015 9:51 AM, Paulo Zanoni wrote:
>>
>> 2015-03-31 14:15 GMT-03:00 Todd Previte :
>>>
>>> Displayport compliance test 4.2.2.6 requires that a source device be
>>> capable of detecting
>>> a corrupt EDID. To do this, the test sets up an invalid EDID header to be
>>> read by the source
>>> device. Unfortunately, the DRM EDID reading and parsing functions are
>>> actually too good in
>>> this case and prevent the source from reading the corrupted EDID. The
>>> result is a failed
>>> compliance test.
>>>
>>> In order to successfully pass the test, the raw EDID header must be
>>> checked on each read
>>> to see if has been "corrupted". If an invalid raw header is detected, a
>>> flag is set that
>>> allows the compliance testing code to acknowledge that fact and react
>>> appropriately. The
>>> flag is automatically cleared on read.
>>>
>>> This code is designed to expressly work for compliance testing without
>>> disrupting normal
>>> operations for EDID reading and parsing.
>>>
>>> Signed-off-by: Todd Previte 
>>> Cc: dri-devel at lists.freedesktop.org
>>> ---
>>>   drivers/gpu/drm/drm_edid.c   | 33 +
>>>   drivers/gpu/drm/i915/intel_dp.c  | 17 +
>>>   drivers/gpu/drm/i915/intel_drv.h |  1 +
>>>   include/drm/drm_edid.h   |  5 +
>>>   4 files changed, 56 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
>>> index 53bc7a6..3d4f473 100644
>>> --- a/drivers/gpu/drm/drm_edid.c
>>> +++ b/drivers/gpu/drm/drm_edid.c
>>> @@ -990,6 +990,32 @@ static const u8 edid_header[] = {
>>>  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
>>>   };
>>>
>>> +
>>> +/* Flag for EDID corruption testing
>>> + * Displayport Link CTS Core 1.2 rev1.1 - 4.2.2.6
>>> + */
>>> +static bool raw_edid_header_corrupted;
>>
>> A static variable like this is not a good design, especially for a
>> module like drm.ko. If you really need this, please store it inside
>> some struct. But see below first.
>
> Per our discussion this morning, I concur. This has been removed in favor of
> a different solution that uses a new boolean flag in the drm_connector
> struct.
>
> Capturing more of the discussion here, the static boolean was a bad idea to
> begin with and needed to be removed. One solution was to make the flag
> non-static and non-clear-on-read, then add a separate clear() function. But
> it still had the problem of potential misuse other places in the code. The
> current solution (which will be posted with V5) modifies the is_valid()
> function and adds a flag in the drm_connector struct that can be used to
> detect this low-level header corruption.
>
>
>>
>>> +
>>> +/**
>>> + * drm_raw_edid_header_valid - check to see if the raw header is
>>> + * corrupt or not. Used solely for Displayport compliance
>>> + * testing and required by Link CTS Core 1.2 rev1.1 4.2.2.6.
>>> + * @raw_edid: pointer to raw base EDID block
>>> + *
>>> + * Indicates whether the original EDID header as read from the
>>> + * device was corrupt or not. Clears on read.
>>> + *
>>> + * Return: true if the raw header was corrupt, otherwise false
>>> + */
>>> +bool drm_raw_edid_header_corrupt(void)
>>> +{
>>> +   bool corrupted = raw_edid_header_corrupted;
>>> +
>>> +   raw_edid_header_corrupted = 0;
>>> +   return corrupted;
>>> +}
>>> +EXPORT_SYMBOL(drm_raw_edid_header_corrupt);
>>> +
>>>   /**
>>>* drm_edid_header_is_valid - sanity check the header of the base EDID
>>> block
>>>* @raw_edid: pointer to raw base EDID block
>>> @@ -1006,6 +1032,13 @@ int drm_edid_header_is_valid(const u8 *raw_edid)
>>>  if (raw_edid[i] == edid_header[i])
>>>  score++;
>>>
>>> +   if (score != 8) {
>>> +   /* Log and set flag here for EDID corruption testing
>>> +* Displayport Link CTS Core 1.2 rev1.1 - 4.2.2.6
>>> +*/
>>> +   DRM_DEBUG_DRIVER("Raw EDID header invalid\n");
>>> +   raw_edid_header_corrupted = 1;
>>> +   }
>>
>> The problem is that here

[Intel-gfx] [PATCH 4/9] drm/i915: Add check for corrupt raw EDID header for Displayport compliance testing

2015-04-08 Thread Paulo Zanoni
c;
> +   struct edid *edid_read = NULL;
> +
> u8 sink_irq_vector;
> u8 link_status[DP_LINK_STATUS_SIZE];
>
> @@ -3912,6 +3919,16 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
> return;
> }
>
> +   /* Compliance testing requires an EDID read for all HPD events
> +* Link CTS Core 1.2 rev 1.1: Test 4.2.2.1
> +* Flag set here will be handled in the EDID test function
> +*/
> +   edid_read = drm_get_edid(connector, adapter);
> +   if (!edid_read || drm_raw_edid_header_corrupt() == 1) {
> +   DRM_DEBUG_DRIVER("EDID invalid, setting flag\n");
> +   intel_dp->compliance_edid_invalid = 1;
> +   }

I see that on the next patch you also add a drm_get_edid() call, so we
have apparently added 2 calls for the edid test. Do we really need
both? Why is this one needed? Why is that one needed?

Also, some more ideas:

I also thought that we already automatically issued get_edid() calls
on the normal hotplug code path, so it would be a "third" call on the
codepath for the test. Can't we just rely on this one?

Another idea would be: instead of getting the edid from inside the
Kernel, we could try to get it from the user-space, using the
GetResources/GetConnector IOCTLs, and also maybe look at the EDID
properties to possibly validate the EDID (in case that edid did not
get "fixed" by the Kernel). The nice thing about this is that it would
make the test be more like a real driver usage. Do you see any
possible problems with this approach?

> +
> /* Try to read the source of the interrupt */
> if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
> intel_dp_get_sink_irq(intel_dp, _irq_vector)) {
> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
> b/drivers/gpu/drm/i915/intel_drv.h
> index e7b62be..42e4251 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -651,6 +651,7 @@ struct intel_dp {
> /* Displayport compliance testing */
> unsigned long compliance_test_type;
> bool compliance_testing_active;
> +   bool compliance_edid_invalid;
>  };
>
>  struct intel_digital_port {
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 87d85e8..8a7eb22 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -388,4 +388,9 @@ struct edid *drm_do_get_edid(struct drm_connector 
> *connector,
>   size_t len),
> void *data);
>
> +/* Check for corruption in raw EDID header - Displayport compliance
> +  * Displayport Link CTS Core 1.2 rev1.1 - 4.2.2.6
> + */
> +bool drm_raw_edid_header_corrupt(void);
> +
>  #endif /* __DRM_EDID_H__ */
> --
> 1.9.1
>
> ___
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni


[PATCH 07/11] drm/i915: Fix for DP CTS test 4.2.2.5 - I2C DEFER handling

2015-04-07 Thread Paulo Zanoni
2015-04-06 23:11 GMT-03:00 Todd Previte :
> For test 4.2.2.5 to pass per the Link CTS Core 1.2 rev1.1 spec, the source
> device must attempt at least 7 times to read the EDID when it receives an
> I2C defer. The normal DRM code makes only 7 retries, regardless of whether
> or not the response is a native defer or an I2C defer. Test 4.2.2.5 fails
> since there are native defers interspersed with the I2C defers which
> results in less than 7 EDID read attempts.
>
> The solution is to decrement the retry counter when an I2C DEFER is returned
> such that another read attempt will be made. This situation should normally
> only occur in compliance testing, however, as a worse case real-world
> scenario, it would result in 13 attempts ( 6 native defers, 7 I2C defers)
> for a single transaction to complete. The net result is a slightly slower
> response to an EDID read that shouldn't significantly impact overall
> performance.
>
> V2:
> - Added a check on the number of I2C Defers to limit the number
>   of times that the retries variable will be decremented. This
>   is to address review feedback regarding possible infinite loops
>   from misbehaving sink devices.
>
> Signed-off-by: Todd Previte 
> Cc: dri-devel at lists.freedesktop.org
> ---
>  drivers/gpu/drm/drm_dp_helper.c | 6 ++
>  1 file changed, 6 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
> index 79968e3..23025cf 100644
> --- a/drivers/gpu/drm/drm_dp_helper.c
> +++ b/drivers/gpu/drm/drm_dp_helper.c
> @@ -469,6 +469,12 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, 
> struct drm_dp_aux_msg *msg)
> case DP_AUX_I2C_REPLY_DEFER:
> DRM_DEBUG_KMS("I2C defer\n");
> aux->i2c_defer_count++;
> +   /* DP Compliance Test 4.2.2.5 Requirement:
> +* Must have at least 7 retries for I2C defers on the
> +* transaction to pass this test
> +*/
> +   if (aux->i2c_defer_count < 8)

I don't think this is the way to go. During normal
(non-compliance-testing) operation we never zero i2c_defer_count, so
we can't expect this to work, since we may start drm_dp_i2c_do_msg
with a i2c_defer_count value different than zero. Also, during i915.ko
DP compliance we only zero i2c_defer_count at the very beginning of
each test, not at every aux transaction, and I really think we need a
solution that is not specific to compliance testing.


> +   retry--;
> usleep_range(400, 500);
> continue;
>
> --
> 1.9.1
>
> _______
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Paulo Zanoni


[PATCH 7/9] drm/i915: Fix for DP CTS test 4.2.2.5 - I2C DEFER handling

2015-04-06 Thread Paulo Zanoni
2015-03-31 14:15 GMT-03:00 Todd Previte :
> For test 4.2.2.5 to pass per the Link CTS Core 1.2 rev1.1 spec, the source
> device must attempt at least 7 times to read the EDID when it receives an
> I2C defer. The normal DRM code makes only 7 retries, regardless of whether
> or not the response is a native defer or an I2C defer. Test 4.2.2.5 fails
> since there are native defers interspersed with the I2C defers which
> results in less than 7 EDID read attempts.
>
> The solution is to decrement the retry counter when an I2C DEFER is returned
> such that another read attempt will be made. This situation should normally
> only occur in compliance testing, however, as a worse case real-world
> scenario, it would result in 13 attempts ( 6 native defers, 7 I2C defers)
> for a single transaction to complete. The net result is a slightly slower
> response to an EDID read that shouldn't significantly impact overall
> performance.
>
> Signed-off-by: Todd Previte 
> Cc: dri-devel at lists.freedesktop.org
> ---
>  drivers/gpu/drm/drm_dp_helper.c | 5 +
>  1 file changed, 5 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
> index 79968e3..0539758 100644
> --- a/drivers/gpu/drm/drm_dp_helper.c
> +++ b/drivers/gpu/drm/drm_dp_helper.c
> @@ -469,6 +469,11 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, 
> struct drm_dp_aux_msg *msg)
> case DP_AUX_I2C_REPLY_DEFER:
> DRM_DEBUG_KMS("I2C defer\n");
> aux->i2c_defer_count++;
> +   /* DP Compliance Test 4.2.2.5 Requirement:
> +* Must have at least 7 retries for I2C defers on the
> +* transaction to pass this test
> +*/
> +   retry--;

I wouldn't be surprised if someone discovers a monitor or some sort of
dongle that keeps sending I2C defer errors forever, keeping us in an
infinite loop. Shouldn't we count each error in separate? Or maybe
just loop up to 14 times, in case that doesn't violate any spec (I
didn't check)?


> usleep_range(400, 500);
> continue;
>
> --
> 1.9.1
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Paulo Zanoni


[Intel-gfx] [PATCH 9/9] drm: Fix the 'native defer' message in drm_dp_i2c_do_msg()

2015-04-06 Thread Paulo Zanoni
2015-03-31 14:15 GMT-03:00 Todd Previte :
> The debug message is missing a newline at the end and it makes the
> logs hard to read when a device defers a lot. Simple 2-character fix
> adds the newline at the end.
>
> Signed-off-by: Todd Previte 
> Cc: dri-devel at lists.freedesktop.org

Why in some logs there is in fact a newline, such as here:
https://bugs.freedesktop.org/attachment.cgi?id=110049 ?

Anyway, it looks correct, so:
Reviewed-by: Paulo Zanoni 

> ---
>  drivers/gpu/drm/drm_dp_helper.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
> index 0539758..281bb67 100644
> --- a/drivers/gpu/drm/drm_dp_helper.c
> +++ b/drivers/gpu/drm/drm_dp_helper.c
> @@ -433,7 +433,7 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, 
> struct drm_dp_aux_msg *msg)
> return -EREMOTEIO;
>
> case DP_AUX_NATIVE_REPLY_DEFER:
> -   DRM_DEBUG_KMS("native defer");
> +   DRM_DEBUG_KMS("native defer\n");
> /*
>  * We could check for I2C bit rate capabilities and if
>  * available adjust this interval. We could also be
> --
> 1.9.1
>
> ___
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni


[Intel-gfx] [PATCH] gpu: drm: i915: intel_display.c: Remove unused function

2014-12-08 Thread Paulo Zanoni
2014-12-08 12:17 GMT-02:00 Daniel Vetter :
> On Mon, Dec 08, 2014 at 10:32:49AM -0200, Paulo Zanoni wrote:
>> 2014-12-08 6:42 GMT-02:00 Daniel Vetter :
>> > On Sun, Dec 07, 2014 at 07:29:17PM +0100, Rickard Strandqvist wrote:
>> >> Remove the function intel_output_name() that is not used anywhere.
>> >>
>> >> This was partially found by using a static code analysis program called 
>> >> cppcheck.
>> >>
>> >> Signed-off-by: Rickard Strandqvist > >> spectrumdigital.se>
>> >
>> > Queued for 3.20, thanks for the patch.
>>
>> This function was created for the "DDI personality" patches. We merged
>> the function but never ended up merging the patch containing the
>> callers...
>
> Oops, I've thought this is a renmant from the very first days of kms that
> somehow stuck around. That's what I get for once not using git blame
> excessively :( Want me to drop the patch again?

I am not opposed to the removal of an unused function: I understand
the value in the removal, and I also understand the reasons to keep
it. I was just pointing the reason of why we got here: we merged patch
1/2 but ended up never merging patch 2/2 because we always spot some
additional work required and it's a very low priority bug. If this
function is removed, the next person to try to ressurrect the ddi
personality patch can quickly resurrect it or even write a new
implementation from scratch. It is your decision :)


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



-- 
Paulo Zanoni


[Intel-gfx] [PATCH] gpu: drm: i915: intel_display.c: Remove unused function

2014-12-08 Thread Paulo Zanoni
2014-12-08 6:42 GMT-02:00 Daniel Vetter :
> On Sun, Dec 07, 2014 at 07:29:17PM +0100, Rickard Strandqvist wrote:
>> Remove the function intel_output_name() that is not used anywhere.
>>
>> This was partially found by using a static code analysis program called 
>> cppcheck.
>>
>> Signed-off-by: Rickard Strandqvist > spectrumdigital.se>
>
> Queued for 3.20, thanks for the patch.

This function was created for the "DDI personality" patches. We merged
the function but never ended up merging the patch containing the
callers...

> -Daniel
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch
> ___
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni


[RFC 7/7] drm: make the callers of drm_wait_vblank() allocate the memory

2014-11-19 Thread Paulo Zanoni
From: Paulo Zanoni <paulo.r.zan...@intel.com>

This way, the Kernel users will be able to fully control the lifetime
of struct drm_vblank_wait_item, and they will also be able to wrap it
to store their own information. As a result, one less memory
allocation will happen, and the Kernel codepath will not set all those
drm_pending_vblank_event struct fields.

Signed-off-by: Paulo Zanoni 
---
 drivers/gpu/drm/drm_irq.c   | 92 -
 drivers/gpu/drm/i915/i915_debugfs.c | 11 ++---
 include/drm/drmP.h  |  2 +-
 3 files changed, 57 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index dd091c3..5fa5431 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -1402,36 +1402,26 @@ static void drm_vblank_event_work_func(struct 
work_struct *work)

 static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
  union drm_wait_vblank *vblwait,
- struct drm_file *file_priv,
  bool callback_from_work,
- drm_vblank_callback_t callback)
+ drm_vblank_callback_t callback,
+ struct drm_vblank_wait_item *item)
 {
struct drm_vblank_crtc *vblank = >vblank[pipe];
-   struct drm_pending_vblank_event *e;
struct timeval now;
unsigned long flags;
unsigned int seq;
int ret;

-   e = kzalloc(sizeof *e, GFP_KERNEL);
-   if (e == NULL) {
-   ret = -ENOMEM;
+   if (WARN_ON(!item)) {
+   ret = -EINVAL;
goto err_put;
}

-   e->item.pipe = pipe;
-   e->base.pid = current->pid;
-   e->event.base.type = DRM_EVENT_VBLANK;
-   e->event.base.length = sizeof e->event;
-   e->event.user_data = vblwait->request.signal;
-   e->base.event = >event.base;
-   e->base.file_priv = file_priv;
-   e->base.destroy = (void (*) (struct drm_pending_event *)) kfree;
-   e->item.from_user_space = true;
-   e->item.callback = callback;
-   e->item.callback_from_work = callback_from_work;
+   item->pipe = pipe;
+   item->callback = callback;
+   item->callback_from_work = callback_from_work;
if (callback_from_work)
-   INIT_WORK(>item.callback_work, drm_vblank_event_work_func);
+   INIT_WORK(>callback_work, drm_vblank_event_work_func);

spin_lock_irqsave(>event_lock, flags);

@@ -1447,15 +1437,6 @@ static int drm_queue_vblank_event(struct drm_device 
*dev, int pipe,
goto err_unlock;
}

-   if (file_priv) {
-   if (file_priv->event_space < sizeof e->event) {
-   ret = -EBUSY;
-   goto err_unlock;
-   }
-
-   file_priv->event_space -= sizeof e->event;
-   }
-
seq = drm_vblank_count_and_time(dev, pipe, );

if ((vblwait->request.type & _DRM_VBLANK_NEXTONMISS) &&
@@ -1470,14 +1451,14 @@ static int drm_queue_vblank_event(struct drm_device 
*dev, int pipe,
trace_drm_vblank_event_queued(current->pid, pipe,
  vblwait->request.sequence);

-   e->item.wanted_seq = vblwait->request.sequence;
+   item->wanted_seq = vblwait->request.sequence;
if ((seq - vblwait->request.sequence) <= (1 << 23)) {
drm_vblank_put(dev, pipe);
-   drm_wait_vblank_callback(dev, >item, seq, , false);
+   drm_wait_vblank_callback(dev, item, seq, , false);
vblwait->reply.sequence = seq;
} else {
/* drm_handle_vblank_events will call drm_vblank_put */
-   list_add_tail(>item.link, >vblank_event_list);
+   list_add_tail(>link, >vblank_event_list);
vblwait->reply.sequence = vblwait->request.sequence;
}

@@ -1487,7 +1468,6 @@ static int drm_queue_vblank_event(struct drm_device *dev, 
int pipe,

 err_unlock:
spin_unlock_irqrestore(>event_lock, flags);
-   kfree(e);
 err_put:
drm_vblank_put(dev, pipe);
return ret;
@@ -1509,9 +1489,9 @@ err_put:
  */
 static int __drm_wait_vblank(struct drm_device *dev,
 union drm_wait_vblank *vblwait,
-struct drm_file *file_priv,
 bool callback_from_work,
-drm_vblank_callback_t callback)
+drm_vblank_callback_t callback,
+struct drm_vblank_wait_item *item)
 {
struct drm_vblank_crtc *vblank;
int ret;
@@ -1566,8 +1546,9 @@ static int __drm_wait_vblank(struct drm_device *dev,
/* 

[RFC 6/7] drm: make vblank_event_list handle drm_vblank_wait_item types

2014-11-19 Thread Paulo Zanoni
From: Paulo Zanoni <paulo.r.zan...@intel.com>

Which means the list doesn't really need to know if the event is from
user space or kernel space.

The only place here where we have to break the abstraction is at
drm_fops, when we're releasing all the events associated with a
file_priv. Here we introduced item.from_user_space, that needs to be
checked before we transform the item pointer into the appropriate
drm_pending_vblank_event pointer. Other strategies to solve this
problem - instead of adding item->from_user_space - would be to: (i)
store a copy of the file_priv pointer in the drm_vblank_wait_item
structure, but then we'd also need a custom destroy() function; or
(ii) add file_priv->pending_event_list, but then we'd have to keep all
the user space items in sync with dev->vblank_event_list, which could
lead to complicated code.

Signed-off-by: Paulo Zanoni 
---
 drivers/gpu/drm/drm_fops.c | 15 +++
 drivers/gpu/drm/drm_irq.c  | 33 +
 include/drm/drmP.h |  4 +++-
 3 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 47c5e58..fbdbde2 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -280,18 +280,25 @@ static void drm_events_release(struct drm_file *file_priv)
 {
struct drm_device *dev = file_priv->minor->dev;
struct drm_pending_event *e, *et;
-   struct drm_pending_vblank_event *v, *vt;
+   struct drm_vblank_wait_item *i, *it;
unsigned long flags;

spin_lock_irqsave(>event_lock, flags);

/* Remove pending flips */
-   list_for_each_entry_safe(v, vt, >vblank_event_list, base.link)
+   list_for_each_entry_safe(i, it, >vblank_event_list, link) {
+   struct drm_pending_vblank_event *v;
+
+   if (!i->from_user_space)
+   continue;
+
+   v = container_of(i, struct drm_pending_vblank_event, item);
if (v->base.file_priv == file_priv) {
-   list_del(>base.link);
-   drm_vblank_put(dev, v->item.pipe);
+   list_del(>link);
+   drm_vblank_put(dev, i->pipe);
v->base.destroy(>base);
}
+   }

/* Remove unconsumed events */
list_for_each_entry_safe(e, et, _priv->event_list, link) {
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 4c03240..dd091c3 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -1144,7 +1144,7 @@ static void drm_wait_vblank_callback(struct drm_device 
*dev,
 void drm_vblank_off(struct drm_device *dev, int crtc)
 {
struct drm_vblank_crtc *vblank = >vblank[crtc];
-   struct drm_pending_vblank_event *e, *t;
+   struct drm_vblank_wait_item *i, *t;
struct timeval now;
unsigned long irqflags;
unsigned int seq;
@@ -1171,15 +1171,15 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
/* Send any queued vblank events, lest the natives grow disquiet */
seq = drm_vblank_count_and_time(dev, crtc, );

-   list_for_each_entry_safe(e, t, >vblank_event_list, base.link) {
-   if (e->item.pipe != crtc)
+   list_for_each_entry_safe(i, t, >vblank_event_list, link) {
+   if (i->pipe != crtc)
continue;
DRM_DEBUG("Sending premature vblank event on disable: \
  wanted %d, current %d\n",
- e->item.wanted_seq, seq);
-   list_del(>base.link);
-   drm_vblank_put(dev, e->item.pipe);
-   drm_wait_vblank_callback(dev, >item, seq, , true);
+i->wanted_seq, seq);
+   list_del(>link);
+   drm_vblank_put(dev, i->pipe);
+   drm_wait_vblank_callback(dev, i, seq, , true);
}
spin_unlock_irqrestore(>event_lock, irqflags);
 }
@@ -1427,6 +1427,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, 
int pipe,
e->base.event = >event.base;
e->base.file_priv = file_priv;
e->base.destroy = (void (*) (struct drm_pending_event *)) kfree;
+   e->item.from_user_space = true;
e->item.callback = callback;
e->item.callback_from_work = callback_from_work;
if (callback_from_work)
@@ -1476,7 +1477,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, 
int pipe,
vblwait->reply.sequence = seq;
} else {
/* drm_handle_vblank_events will call drm_vblank_put */
-   list_add_tail(>base.link, >vblank_event_list);
+   list_add_tail(>item.link, >vblank_event_list);
vblwait->reply.sequence = vblwait->request.sequence;
}

@@ 

[RFC 5/7] drm: change the drm vblank callback item type

2014-11-19 Thread Paulo Zanoni
From: Paulo Zanoni <paulo.r.zan...@intel.com>

Now that we have created drm_vblank_wait_item, let's use it as the
type passed. In the future, callers will have to use container_of to
find our their original allocated structure, just like we're doing
with the send_vblank_event() callback.

Signed-off-by: Paulo Zanoni 
---
 drivers/gpu/drm/drm_irq.c   | 40 ++---
 drivers/gpu/drm/i915/i915_debugfs.c |  4 +++-
 include/drm/drmP.h  |  4 +++-
 3 files changed, 26 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index a82e5ca..4c03240 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -881,10 +881,13 @@ u32 drm_vblank_count_and_time(struct drm_device *dev, int 
crtc,
 EXPORT_SYMBOL(drm_vblank_count_and_time);

 static void send_vblank_event(struct drm_device *dev,
-   struct drm_pending_vblank_event *e,
+   struct drm_vblank_wait_item *item,
unsigned long seq, struct timeval *now,
bool premature)
 {
+   struct drm_pending_vblank_event *e =
+   container_of(item, struct drm_pending_vblank_event, item);
+
WARN_ON_SMP(!spin_is_locked(>event_lock));
e->event.sequence = seq;
e->event.tv_sec = now->tv_sec;
@@ -919,7 +922,7 @@ void drm_send_vblank_event(struct drm_device *dev, int crtc,
now = get_drm_timestamp();
}
e->item.pipe = crtc;
-   send_vblank_event(dev, e, seq, , false);
+   send_vblank_event(dev, >item, seq, , false);
 }
 EXPORT_SYMBOL(drm_send_vblank_event);

@@ -1109,18 +1112,18 @@ void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
 EXPORT_SYMBOL(drm_crtc_wait_one_vblank);

 static void drm_wait_vblank_callback(struct drm_device *dev,
-struct drm_pending_vblank_event *e,
+struct drm_vblank_wait_item *item,
 unsigned long seq, struct timeval *now,
 bool premature)
 {
-   if (e->item.callback_from_work) {
-   e->item.callback_args.dev = dev;
-   e->item.callback_args.seq = seq;
-   e->item.callback_args.now = now;
-   e->item.callback_args.premature = premature;
-   schedule_work(>item.callback_work);
+   if (item->callback_from_work) {
+   item->callback_args.dev = dev;
+   item->callback_args.seq = seq;
+   item->callback_args.now = now;
+   item->callback_args.premature = premature;
+   schedule_work(>callback_work);
} else {
-   e->item.callback(dev, e, seq, now, premature);
+   item->callback(dev, item, seq, now, premature);
}
 }

@@ -1176,7 +1179,7 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
  e->item.wanted_seq, seq);
list_del(>base.link);
drm_vblank_put(dev, e->item.pipe);
-   drm_wait_vblank_callback(dev, e, seq, , true);
+   drm_wait_vblank_callback(dev, >item, seq, , true);
}
spin_unlock_irqrestore(>event_lock, irqflags);
 }
@@ -1390,14 +1393,11 @@ int drm_modeset_ctl(struct drm_device *dev, void *data,

 static void drm_vblank_event_work_func(struct work_struct *work)
 {
-   struct drm_pending_vblank_event *e =
-   container_of(work, struct drm_pending_vblank_event,
-item.callback_work);
+   struct drm_vblank_wait_item *item =
+   container_of(work, struct drm_vblank_wait_item, callback_work);

-   e->item.callback(e->item.callback_args.dev, e,
-e->item.callback_args.seq,
-e->item.callback_args.now,
-e->item.callback_args.premature);
+   item->callback(item->callback_args.dev, item, item->callback_args.seq,
+  item->callback_args.now, item->callback_args.premature);
 }

 static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
@@ -1472,7 +1472,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, 
int pipe,
e->item.wanted_seq = vblwait->request.sequence;
if ((seq - vblwait->request.sequence) <= (1 << 23)) {
drm_vblank_put(dev, pipe);
-   drm_wait_vblank_callback(dev, e, seq, , false);
+   drm_wait_vblank_callback(dev, >item, seq, , false);
vblwait->reply.sequence = seq;
} else {
/* drm_handle_vblank_events will call drm_vblank_put */
@@ -1654,7 +1654,7 @@ static void drm_handle_vblank_events(struct drm_device 
*dev, int crtc)

list_del(>base.link);
drm_vblank_put(dev, e->

[RFC 4/7] drm: add wanted_seq to drm_vblank_wait_item

2014-11-19 Thread Paulo Zanoni
From: Paulo Zanoni <paulo.r.zan...@intel.com>

Store the wanted sequence in the wait_item instead of storing it in
the event structure that is eventually going to be sent to user space.
The plan is to make Kernel vblank wait items not have the user space
event, so we need to store the wanted sequence number somewhere.

It is not a problem that we're not filling e->event.sequence inside
drm_queue_vblank_event: we set the value again inside
send_vblank_event().

Signed-off-by: Paulo Zanoni 
---
 drivers/gpu/drm/drm_irq.c | 8 
 include/drm/drmP.h| 1 +
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 7dcbbdb..a82e5ca 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -1173,7 +1173,7 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
continue;
DRM_DEBUG("Sending premature vblank event on disable: \
  wanted %d, current %d\n",
- e->event.sequence, seq);
+ e->item.wanted_seq, seq);
list_del(>base.link);
drm_vblank_put(dev, e->item.pipe);
drm_wait_vblank_callback(dev, e, seq, , true);
@@ -1469,7 +1469,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, 
int pipe,
trace_drm_vblank_event_queued(current->pid, pipe,
  vblwait->request.sequence);

-   e->event.sequence = vblwait->request.sequence;
+   e->item.wanted_seq = vblwait->request.sequence;
if ((seq - vblwait->request.sequence) <= (1 << 23)) {
drm_vblank_put(dev, pipe);
drm_wait_vblank_callback(dev, e, seq, , false);
@@ -1646,11 +1646,11 @@ static void drm_handle_vblank_events(struct drm_device 
*dev, int crtc)
list_for_each_entry_safe(e, t, >vblank_event_list, base.link) {
if (e->item.pipe != crtc)
continue;
-   if ((seq - e->event.sequence) > (1<<23))
+   if ((seq - e->item.wanted_seq) > (1<<23))
continue;

DRM_DEBUG("vblank event on %d, current %d\n",
- e->event.sequence, seq);
+ e->item.wanted_seq, seq);

list_del(>base.link);
drm_vblank_put(dev, e->item.pipe);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index b8bc55a..dcec05b 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -667,6 +667,7 @@ typedef void (*drm_vblank_callback_t)(struct drm_device 
*dev,

 struct drm_vblank_wait_item {
int pipe;
+   unsigned int wanted_seq;

drm_vblank_callback_t callback;
bool callback_from_work;
-- 
2.1.1



[RFC 3/7] drm: introduce struct drm_vblank_wait_item

2014-11-19 Thread Paulo Zanoni
From: Paulo Zanoni <paulo.r.zan...@intel.com>

It's supposed to contain all the information that is required for both
kernel and user space vblank wait items, but not hold any information
required by just one of them.

For now, we just moved the struct members from one place to another,
but the long term goal is that most of the drm.ko code will only
handle "struct drm_vblank_wait_item", not knowing anything else. This
will allow the callers to wrap this struct in their own private
structures. This will happen in the next patches.

Signed-off-by: Paulo Zanoni 
---
 drivers/gpu/drm/drm_fops.c |  2 +-
 drivers/gpu/drm/drm_irq.c  | 42 ++
 include/drm/drmP.h | 10 +++---
 3 files changed, 30 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 91e1105..47c5e58 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -289,7 +289,7 @@ static void drm_events_release(struct drm_file *file_priv)
list_for_each_entry_safe(v, vt, >vblank_event_list, base.link)
if (v->base.file_priv == file_priv) {
list_del(>base.link);
-   drm_vblank_put(dev, v->pipe);
+   drm_vblank_put(dev, v->item.pipe);
v->base.destroy(>base);
}

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 099aef1..7dcbbdb 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -893,7 +893,7 @@ static void send_vblank_event(struct drm_device *dev,
list_add_tail(>base.link,
  >base.file_priv->event_list);
wake_up_interruptible(>base.file_priv->event_wait);
-   trace_drm_vblank_event_delivered(e->base.pid, e->pipe,
+   trace_drm_vblank_event_delivered(e->base.pid, e->item.pipe,
 e->event.sequence);
 }

@@ -918,7 +918,7 @@ void drm_send_vblank_event(struct drm_device *dev, int crtc,

now = get_drm_timestamp();
}
-   e->pipe = crtc;
+   e->item.pipe = crtc;
send_vblank_event(dev, e, seq, , false);
 }
 EXPORT_SYMBOL(drm_send_vblank_event);
@@ -1113,14 +1113,14 @@ static void drm_wait_vblank_callback(struct drm_device 
*dev,
 unsigned long seq, struct timeval *now,
 bool premature)
 {
-   if (e->callback_from_work) {
-   e->callback_args.dev = dev;
-   e->callback_args.seq = seq;
-   e->callback_args.now = now;
-   e->callback_args.premature = premature;
-   schedule_work(>callback_work);
+   if (e->item.callback_from_work) {
+   e->item.callback_args.dev = dev;
+   e->item.callback_args.seq = seq;
+   e->item.callback_args.now = now;
+   e->item.callback_args.premature = premature;
+   schedule_work(>item.callback_work);
} else {
-   e->callback(dev, e, seq, now, premature);
+   e->item.callback(dev, e, seq, now, premature);
}
 }

@@ -1169,13 +1169,13 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
seq = drm_vblank_count_and_time(dev, crtc, );

list_for_each_entry_safe(e, t, >vblank_event_list, base.link) {
-   if (e->pipe != crtc)
+   if (e->item.pipe != crtc)
continue;
DRM_DEBUG("Sending premature vblank event on disable: \
  wanted %d, current %d\n",
  e->event.sequence, seq);
list_del(>base.link);
-   drm_vblank_put(dev, e->pipe);
+   drm_vblank_put(dev, e->item.pipe);
drm_wait_vblank_callback(dev, e, seq, , true);
}
spin_unlock_irqrestore(>event_lock, irqflags);
@@ -1392,10 +1392,12 @@ static void drm_vblank_event_work_func(struct 
work_struct *work)
 {
struct drm_pending_vblank_event *e =
container_of(work, struct drm_pending_vblank_event,
-callback_work);
+item.callback_work);

-   e->callback(e->callback_args.dev, e, e->callback_args.seq,
-   e->callback_args.now, e->callback_args.premature);
+   e->item.callback(e->item.callback_args.dev, e,
+e->item.callback_args.seq,
+e->item.callback_args.now,
+e->item.callback_args.premature);
 }

 static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
@@ -1417,7 +1419,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, 
int pipe,
goto err_put;
}

-   e->pi

[RFC 2/7] drm: allow drm_wait_vblank_kernel() callback from workqueues

2014-11-19 Thread Paulo Zanoni
From: Paulo Zanoni <paulo.r.zan...@intel.com>

This is going to be needed by i915.ko, and I guess other drivers could
use it too.

Signed-off-by: Paulo Zanoni 
---
 drivers/gpu/drm/drm_irq.c   | 46 -
 drivers/gpu/drm/i915/i915_debugfs.c | 45 
 include/drm/drmP.h  | 11 -
 3 files changed, 86 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index f031f77..099aef1 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -1108,6 +1108,22 @@ void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
 }
 EXPORT_SYMBOL(drm_crtc_wait_one_vblank);

+static void drm_wait_vblank_callback(struct drm_device *dev,
+struct drm_pending_vblank_event *e,
+unsigned long seq, struct timeval *now,
+bool premature)
+{
+   if (e->callback_from_work) {
+   e->callback_args.dev = dev;
+   e->callback_args.seq = seq;
+   e->callback_args.now = now;
+   e->callback_args.premature = premature;
+   schedule_work(>callback_work);
+   } else {
+   e->callback(dev, e, seq, now, premature);
+   }
+}
+
 /**
  * drm_vblank_off - disable vblank events on a CRTC
  * @dev: DRM device
@@ -1160,7 +1176,7 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
  e->event.sequence, seq);
list_del(>base.link);
drm_vblank_put(dev, e->pipe);
-   e->callback(dev, e, seq, , true);
+   drm_wait_vblank_callback(dev, e, seq, , true);
}
spin_unlock_irqrestore(>event_lock, irqflags);
 }
@@ -1372,9 +1388,20 @@ int drm_modeset_ctl(struct drm_device *dev, void *data,
return 0;
 }

+static void drm_vblank_event_work_func(struct work_struct *work)
+{
+   struct drm_pending_vblank_event *e =
+   container_of(work, struct drm_pending_vblank_event,
+callback_work);
+
+   e->callback(e->callback_args.dev, e, e->callback_args.seq,
+   e->callback_args.now, e->callback_args.premature);
+}
+
 static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
  union drm_wait_vblank *vblwait,
  struct drm_file *file_priv,
+ bool callback_from_work,
  drm_vblank_callback_t callback)
 {
struct drm_vblank_crtc *vblank = >vblank[pipe];
@@ -1399,6 +1426,9 @@ static int drm_queue_vblank_event(struct drm_device *dev, 
int pipe,
e->base.file_priv = file_priv;
e->base.destroy = (void (*) (struct drm_pending_event *)) kfree;
e->callback = callback;
+   e->callback_from_work = callback_from_work;
+   if (callback_from_work)
+   INIT_WORK(>callback_work, drm_vblank_event_work_func);

spin_lock_irqsave(>event_lock, flags);

@@ -1440,7 +1470,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, 
int pipe,
e->event.sequence = vblwait->request.sequence;
if ((seq - vblwait->request.sequence) <= (1 << 23)) {
drm_vblank_put(dev, pipe);
-   e->callback(dev, e, seq, , false);
+   drm_wait_vblank_callback(dev, e, seq, , false);
vblwait->reply.sequence = seq;
} else {
/* drm_handle_vblank_events will call drm_vblank_put */
@@ -1477,6 +1507,7 @@ err_put:
 static int __drm_wait_vblank(struct drm_device *dev,
 union drm_wait_vblank *vblwait,
 struct drm_file *file_priv,
+bool callback_from_work,
 drm_vblank_callback_t callback)
 {
struct drm_vblank_crtc *vblank;
@@ -1533,7 +1564,7 @@ static int __drm_wait_vblank(struct drm_device *dev,
 * drm_vblank_put will be called asynchronously
 */
return drm_queue_vblank_event(dev, crtc, vblwait, file_priv,
- callback);
+ callback_from_work, callback);
}

if ((flags & _DRM_VBLANK_NEXTONMISS) &&
@@ -1573,10 +1604,12 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void 
*data,
 {
union drm_wait_vblank *vblwait = data;

-   return __drm_wait_vblank(dev, vblwait, file_priv, send_vblank_event);
+   return __drm_wait_vblank(dev, vblwait, file_priv, false,
+send_vblank_event);
 }

 int drm_wait_vblank_kernel(struct drm_crtc *crtc, int count, bool absolute,
+  bool callback_from_work,
  

[RFC 1/7] drm: allow the drivers to call the vblank IOCTL internally

2014-11-19 Thread Paulo Zanoni
From: Paulo Zanoni <paulo.r.zan...@intel.com>

The i915.ko driver needs a way to schedule certain functions to run
after some amount of vblanks. There are many different pieces of the
driver which could benefit from that.

Since what we want is essentially the vblank ioctl, this patch does
the minimum change required to allow this ioctl to be called
internally.  The noticeable thing here is that the drivers pass a
callback function, which is called by drm.ko after the specified
amount of vblanks passes.

The great benefit of this minimal change is that all the code
responsible for taking care of properly emptying the queues (e.g.,
when the CRTC is disabled) is already there, so we don't need to
rewrite it.

The current wait vblank IOCTL is now implemented on top of these
changes, and it provides its own callback: send_vblank_event().

Signed-off-by: Paulo Zanoni 
---
 drivers/gpu/drm/drm_ioctl.c |  2 +-
 drivers/gpu/drm/drm_irq.c   | 65 +
 drivers/gpu/drm/i915/i915_debugfs.c | 62 +++
 include/drm/drmP.h  | 13 ++--
 4 files changed, 125 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 00587a1..fb35173 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -578,7 +578,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_legacy_sg_alloc, 
DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_legacy_sg_free, 
DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),

-   DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED),
+   DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank_ioctl, 
DRM_UNLOCKED),

DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 0e47df4..f031f77 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -882,7 +882,8 @@ EXPORT_SYMBOL(drm_vblank_count_and_time);

 static void send_vblank_event(struct drm_device *dev,
struct drm_pending_vblank_event *e,
-   unsigned long seq, struct timeval *now)
+   unsigned long seq, struct timeval *now,
+   bool premature)
 {
WARN_ON_SMP(!spin_is_locked(>event_lock));
e->event.sequence = seq;
@@ -918,7 +919,7 @@ void drm_send_vblank_event(struct drm_device *dev, int crtc,
now = get_drm_timestamp();
}
e->pipe = crtc;
-   send_vblank_event(dev, e, seq, );
+   send_vblank_event(dev, e, seq, , false);
 }
 EXPORT_SYMBOL(drm_send_vblank_event);

@@ -1159,7 +1160,7 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
  e->event.sequence, seq);
list_del(>base.link);
drm_vblank_put(dev, e->pipe);
-   send_vblank_event(dev, e, seq, );
+   e->callback(dev, e, seq, , true);
}
spin_unlock_irqrestore(>event_lock, irqflags);
 }
@@ -1373,7 +1374,8 @@ int drm_modeset_ctl(struct drm_device *dev, void *data,

 static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
  union drm_wait_vblank *vblwait,
- struct drm_file *file_priv)
+ struct drm_file *file_priv,
+ drm_vblank_callback_t callback)
 {
struct drm_vblank_crtc *vblank = >vblank[pipe];
struct drm_pending_vblank_event *e;
@@ -1396,6 +1398,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, 
int pipe,
e->base.event = >event.base;
e->base.file_priv = file_priv;
e->base.destroy = (void (*) (struct drm_pending_event *)) kfree;
+   e->callback = callback;

spin_lock_irqsave(>event_lock, flags);

@@ -1411,12 +1414,15 @@ static int drm_queue_vblank_event(struct drm_device 
*dev, int pipe,
goto err_unlock;
}

-   if (file_priv->event_space < sizeof e->event) {
-   ret = -EBUSY;
-   goto err_unlock;
+   if (file_priv) {
+   if (file_priv->event_space < sizeof e->event) {
+   ret = -EBUSY;
+   goto err_unlock;
+   }
+
+   file_priv->event_space -= sizeof e->event;
}

-   file_priv->event_space -= sizeof e->event;
seq = drm_vblank_count_and_time(dev, pipe, );

if ((vblwait->request.type & _DRM_VBLANK_NEXTONMISS) &&
@@ -1434,7 +1440,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, 
int pipe,
e->event.sequence = vblwait->request.sequence;
if ((seq - vblwait->request.sequence) <= (1 << 23)) {
drm_vblank_put(dev, pipe);
-   send_vblan

[RFC] drm: add a mechanism for drivers to schedule vblank callbacks

2014-11-19 Thread Paulo Zanoni
From: Paulo Zanoni <paulo.r.zan...@intel.com>

The drivers need a way to schedule functions to be ran after a certain
number of vblanks. The i915.ko driver has plenty of examples where
this could be used, such as for unpinning buffers after a modeset.
Since the vblank wait IOCTL does basically what we want, but for the
user space, in this patch we add a new list of vblank events
(dev->vblank_kernel_list) and handle it exactly like we handle the
user space events.

Signed-off-by: Paulo Zanoni 
---
 drivers/gpu/drm/drm_drv.c   |   1 +
 drivers/gpu/drm/drm_irq.c   | 106 ++--
 drivers/gpu/drm/i915/i915_debugfs.c |  81 +++
 include/drm/drmP.h  |  22 
 4 files changed, 206 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 2e5c7d9..b5ae6c8 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -557,6 +557,7 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver,
INIT_LIST_HEAD(>vmalist);
INIT_LIST_HEAD(>maplist);
INIT_LIST_HEAD(>vblank_event_list);
+   INIT_LIST_HEAD(>vblank_kernel_list);

spin_lock_init(>buf_lock);
spin_lock_init(>event_lock);
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 0e47df4..6e04035 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -1107,6 +1107,13 @@ void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
 }
 EXPORT_SYMBOL(drm_crtc_wait_one_vblank);

+static void send_kernel_vblank_event(struct drm_kernel_vblank_item *item)
+{
+   if (item->callback_from_work)
+   schedule_work(>work);
+   else
+   item->callback(item);
+}
 /**
  * drm_vblank_off - disable vblank events on a CRTC
  * @dev: DRM device
@@ -1124,7 +1131,8 @@ EXPORT_SYMBOL(drm_crtc_wait_one_vblank);
 void drm_vblank_off(struct drm_device *dev, int crtc)
 {
struct drm_vblank_crtc *vblank = >vblank[crtc];
-   struct drm_pending_vblank_event *e, *t;
+   struct drm_pending_vblank_event *e, *et;
+   struct drm_kernel_vblank_item *i, *it;
struct timeval now;
unsigned long irqflags;
unsigned int seq;
@@ -1151,7 +1159,7 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
/* Send any queued vblank events, lest the natives grow disquiet */
seq = drm_vblank_count_and_time(dev, crtc, );

-   list_for_each_entry_safe(e, t, >vblank_event_list, base.link) {
+   list_for_each_entry_safe(e, et, >vblank_event_list, base.link) {
if (e->pipe != crtc)
continue;
DRM_DEBUG("Sending premature vblank event on disable: \
@@ -1161,6 +1169,21 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
drm_vblank_put(dev, e->pipe);
send_vblank_event(dev, e, seq, );
}
+
+   list_for_each_entry_safe(i, it, >vblank_kernel_list, link) {
+   int pipe = drm_crtc_index(i->crtc);
+
+   if (pipe != crtc)
+   continue;
+
+   DRM_DEBUG("Sending premature kernel vblank event on disable: \
+ wanted %d, current %d\n",
+ i->target_seq, seq);
+   i->premature = true;
+   list_del(>link);
+   drm_vblank_put(dev, pipe);
+   send_kernel_vblank_event(i);
+   }
spin_unlock_irqrestore(>event_lock, irqflags);
 }
 EXPORT_SYMBOL(drm_vblank_off);
@@ -1560,9 +1583,68 @@ done:
return ret;
 }

+static void drm_kernel_vblank_work_func(struct work_struct *work)
+{
+   struct drm_kernel_vblank_item *item =
+   container_of(work, struct drm_kernel_vblank_item, work);
+
+   item->callback(item);
+}
+
+int drm_wait_vblank_kernel(struct drm_kernel_vblank_item *item)
+{
+   struct drm_crtc *crtc = item->crtc;
+   struct drm_device *dev = crtc->dev;
+   int pipe = drm_crtc_index(crtc);
+   struct drm_vblank_crtc *vblank = >vblank[pipe];
+   unsigned int seq;
+   unsigned long irqflags;
+   int ret = 0;
+
+   if (!dev->irq_enabled)
+   return -EINVAL;
+
+   if (item->callback_from_work)
+   INIT_WORK(>work, drm_kernel_vblank_work_func);
+
+   ret = drm_vblank_get(dev, pipe);
+   if (ret) {
+   DRM_DEBUG("failed to acquire vblank counter, %d\n", ret);
+   return ret;
+   }
+
+   seq = drm_vblank_count(dev, pipe);
+   if (!item->absolute)
+   item->target_seq += seq;
+
+   spin_lock_irqsave(>event_lock, irqflags);
+
+   if (!vblank->enabled) {
+   ret = -EINVAL;
+   goto out;
+   }
+
+   if (seq - item->target_seq <= (1 << 23)) {
+   drm_vblan

[RFC 0/7+1] Add in-kernel vblank delaying mechanism

2014-11-19 Thread Paulo Zanoni
From: Paulo Zanoni <paulo.r.zan...@intel.com>

Hi

---
TL;DR summary:
I wrote patches. Help me choose the best implementation and interface.
---

So the i915.ko driver could use some mechanism to run functions after a given
number of vblanks. Implementations for this mechanism were already proposed in
the past (by Chris Wilson and others), but they were i915-specific instead of a
generic drm.ko implementation. We even had patches that make use of this new
mechanism.

Since this is very similar to the vblank IOCTL we currently have, but with the
caller being a Kernel module instead of user space, I decided to write an
implementation that tries to reuse the current IOCTL infrastructure.

In the first patch we add all the necessary code to allow the modules to call
the vblank ioctl from Kernel space: they provide a callback function that is
going to be called instead of the traditional send_vblank_event(), which means
the Kernel callers don't have to deal with the file descriptors and DRM events.

In the second patch we add a simple extension of the feature, to allow the
drivers to have their callbacks called in a non-atomic context.

In all the other subsequent patches we rework the underlying code so that
the common aspects between the user space vblank IOCTL and the Kernel interface
are all stored in a single structure (struct drm_vblank_wait_item), and then
anything that is specific to the different users is stored in a structure that
contains struct drm_vblank_wait_item. This way, most of the drm.ko code only
needs to deal with struct drm_vblank_wait_item, not really knowing how it is
wrapped. The advantage of this rework is that it reduces the number of memory
allocations needed in some cases (from 2 to 1) and it also reduces the amount of
memory used on each allocation.

But while this all sounds nice in the above description, I had the feeling that
this adds a lot of complexity and makes the code not-so-beautiful. If we ever
need more extensions/options to this feature, we're going to have to untangle
the code even more from the IOCTL part. We also have a small "abstraction break"
in change introduced in patch 6. And there's the risk that some of the reworks
may have added a regression somewhere.

Based on that, I decided to also provide an alternative implementation. In this
implementation we add a new dev->vblank_kernel_list instead of reusing
dev->vblank_event_list, and add new code to handle that this. This new code is
completely based on the code that handles dev->vblank_kernel_list, so there's
some duplication here. On the other hand, since the in-Kernel infrastructure is
not tied to the IOCTL structure, we can very easily grow and adapt the Kernel
code without having to fight against the IOCTL code. And the risk of regressions
is greatly reduced.

The second difference of this alternative implementation is the signature of the
drm_wait_vblank_kernel() function. While it could be exactly the same as the one
used in the other series, I decided to make it different so we can also choose
which one to use. In the 7-patch series implementation, all the user needs to do
is to allocate the structure, and call the function, properly setting all its
arguments. Then the function is responsible for parsing the arguments and
populating the structure based on that. On the alternative implementation, the
user has to fill the structure with the appropriate arguments, and then call
drm_wait_vblank_kernel() passing just the allocated structure as an argument.

If you notice, you will see that these patches add a new debugfs file to
i915.ko. This file is just a very simple example user of the new interface,
which I used while developing. If you have difficulty understanding the new
interface, please also look at the i915/i915_debugfs.c diff. Of course, I plan
to exclude this debugfs interface from the final to-be-merged patches.

So, in summary, we have a few things we need to discuss:

 1. Which implementation to use?

   a. Just the 2 first patches of the 7-patch series?
  Pros:
- the Kernel users basically call the vblank IOCTL
- the code changes are minimal
 Cons:
- The amount of memory allocations and memory space consumed is not
  optimal

   b. The full 7-patch series?
  Pros:
- The same backend is used for both the Kernel and IOCTL.
  Cons:
- The code gets more complex.
- Extending the Kernel interface can get complicated due to the fact
  that it shares code with the IOCTL interface.
- I didn't really like this solution.

   c. The alternative implementation I wrote?
  Pros:
- It's independent from the IOCTL code, making further patches easier.
  Cons:
- There is some duplicated code.

   d. Something totally different from these alternatives?

 2. How should the driver interface look like?

   a. All the possibilities are passed through the function call, so the drm.k

[Intel-gfx] [PATCH v4 2/5] drm/i915: create a prepare phase for sprite plane updates

2014-10-30 Thread Paulo Zanoni
2014-10-24 11:51 GMT-02:00 Gustavo Padovan :
> From: Gustavo Padovan 
>
> take out pin_fb code so the commit phase can't fail anymore.
>

According to my bisection results, this is the first bad commit of
https://bugs.freedesktop.org/show_bug.cgi?id=85634.


> Signed-off-by: Gustavo Padovan 
> Reviewed-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/intel_sprite.c | 63 
> +++--
>  1 file changed, 40 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
> b/drivers/gpu/drm/i915/intel_sprite.c
> index 2c060ad..3631b0e 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -1192,34 +1192,18 @@ intel_check_sprite_plane(struct drm_plane *plane,
>  }
>
>  static int
> -intel_commit_sprite_plane(struct drm_plane *plane,
> - struct intel_plane_state *state)
> +intel_prepare_sprite_plane(struct drm_plane *plane,
> +  struct intel_plane_state *state)
>  {
> struct drm_device *dev = plane->dev;
> struct drm_crtc *crtc = state->crtc;
> struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -   struct intel_plane *intel_plane = to_intel_plane(plane);
> enum pipe pipe = intel_crtc->pipe;
> struct drm_framebuffer *fb = state->fb;
> -   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 crtc_x, crtc_y;
> -   unsigned int crtc_w, crtc_h;
> -   uint32_t src_x, src_y, src_w, src_h;
> -   struct drm_rect *dst = >dst;
> -   const struct drm_rect *clip = >clip;
> -   bool primary_enabled;
> +   struct drm_i915_gem_object *obj = intel_fb_obj(fb);
> +   struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb);
> int ret;
>
> -   /*
> -* If the sprite is completely covering the primary plane,
> -* we can disable the primary and save power.
> -*/
> -   primary_enabled = !drm_rect_equals(dst, clip) || 
> colorkey_enabled(intel_plane);
> -   WARN_ON(!primary_enabled && !state->visible && intel_crtc->active);
> -
> -
> if (old_obj != obj) {
> mutex_lock(>struct_mutex);
>
> @@ -1238,6 +1222,36 @@ intel_commit_sprite_plane(struct drm_plane *plane,
> return ret;
> }
>
> +   return 0;
> +}
> +
> +static void
> +intel_commit_sprite_plane(struct drm_plane *plane,
> + struct intel_plane_state *state)
> +{
> +   struct drm_device *dev = plane->dev;
> +   struct drm_crtc *crtc = state->crtc;
> +   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +   struct intel_plane *intel_plane = to_intel_plane(plane);
> +   enum pipe pipe = intel_crtc->pipe;
> +   struct drm_framebuffer *fb = state->fb;
> +   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 crtc_x, crtc_y;
> +   unsigned int crtc_w, crtc_h;
> +   uint32_t src_x, src_y, src_w, src_h;
> +   struct drm_rect *dst = >dst;
> +   const struct drm_rect *clip = >clip;
> +   bool primary_enabled;
> +
> +   /*
> +* If the sprite is completely covering the primary plane,
> +* we can disable the primary and save power.
> +*/
> +   primary_enabled = !drm_rect_equals(dst, clip) || 
> colorkey_enabled(intel_plane);
> +   WARN_ON(!primary_enabled && !state->visible && intel_crtc->active);
> +
> intel_plane->crtc_x = state->orig_dst.x1;
> intel_plane->crtc_y = state->orig_dst.y1;
> intel_plane->crtc_w = drm_rect_width(>orig_dst);
> @@ -1298,8 +1312,6 @@ intel_commit_sprite_plane(struct drm_plane *plane,
> intel_unpin_fb_obj(old_obj);
> mutex_unlock(>struct_mutex);
> }
> -
> -   return 0;
>  }
>
>  static int
> @@ -1339,7 +1351,12 @@ intel_update_plane(struct drm_plane *plane, struct 
> drm_crtc *crtc,
> if (ret)
> return ret;
>
> -   return intel_commit_sprite_plane(plane, );
> +   ret = intel_prepare_sprite_plane(plane, );
> +   if (ret)
> +   return ret;
> +
> +   intel_commit_sprite_plane(plane, );
> +   return 0;
>  }
>
>  static int
> --
> 1.9.3
>
> ___
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni


[Intel-gfx] [PATCH 02/10] drm/i915: Add counters in the drm_dp_aux struct for I2C NACKs and DEFERs

2014-10-21 Thread Paulo Zanoni
2014-10-09 12:38 GMT-03:00 Todd Previte :
> These counters are used for Displayort complinace testing to detect error 
> conditions
> when executing certain compliance tests. Currently these are used in the EDID 
> tests
> to determine if the video mode needs to be set to the preferred mode or the 
> failsafe
> mode.
>
> Cc: dri-devel at lists.freedesktop.org

I see that this patch and a few others in your series still have
unaddressed/unanswered review comments, given on the first time you
sent the patches. Please take a look at them.

> Signed-off-by: Todd Previte 
> ---
>  drivers/gpu/drm/drm_dp_helper.c | 2 ++
>  include/drm/drm_dp_helper.h | 1 +
>  2 files changed, 3 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
> index 08e33b8..8353051 100644
> --- a/drivers/gpu/drm/drm_dp_helper.c
> +++ b/drivers/gpu/drm/drm_dp_helper.c
> @@ -654,10 +654,12 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, 
> struct drm_dp_aux_msg *msg)
>
> case DP_AUX_I2C_REPLY_NACK:
> DRM_DEBUG_KMS("I2C nack\n");
> +   aux->i2c_nack_count++;
> return -EREMOTEIO;
>
> case DP_AUX_I2C_REPLY_DEFER:
> DRM_DEBUG_KMS("I2C defer\n");
> +   aux->i2c_defer_count++;
> usleep_range(400, 500);
> continue;
>
> diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> index 8edeed0..45f3ee8 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -551,6 +551,7 @@ struct drm_dp_aux {
> struct mutex hw_mutex;
> ssize_t (*transfer)(struct drm_dp_aux *aux,
> struct drm_dp_aux_msg *msg);
> +   uint8_t i2c_nack_count, i2c_defer_count;
>  };
>
>  ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset,
> --
> 1.9.1
>
> _______
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni


[PATCH] drm: Drop grab fpriv->fbs_lock in drm_fb_release

2014-09-24 Thread Paulo Zanoni
2014-09-24 16:55 GMT-03:00 Daniel Vetter :
> Paulo Zanoni reported a lockdep splat with a locking inversion between
> fpriv->fbs_lock and the modeset locks. This issue was introduced in
>
> commit f2b50c1161590c3bcdbf3455fe4c575f1c1bd293
> Author: Daniel Vetter 
> Date:   Fri Sep 12 17:07:32 2014 +0200
>
> drm: Fixup locking for universal cursor planes
>
> This here is actually one of the rare cases where lockdep hits a false
> positive: The deadlock only happens in drm_fb_release, which cleans up
> the file private structure when all the references are gone. So the
> locking is the very last one and no one else can deadlock. It also
> doesn't protect anything at all, since all ioctls are guaranteed to
> have returned at this point - otherwise they'd still hold a reference
> on the file.
>
> So let's just drop it and replace it with a big comment.
>
> Cc: David Herrmann 
> Cc: Matt Roper 
> Cc: Paulo Zanoni 
> Reported-by: Paulo Zanoni 
> Signed-off-by: Daniel Vetter 

Apparently, it fixes the problem I was seeing while running
igt/pm_rpm. It was not 100% reproducible, but it seems to be gone.

Smoke-tested-by: Paulo Zanoni 
Testcase: igt/pm_rpm

> ---
>  drivers/gpu/drm/drm_crtc.c | 12 ++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index b7021069b078..e79c8d3700d8 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -3400,7 +3400,16 @@ void drm_fb_release(struct drm_file *priv)
> struct drm_device *dev = priv->minor->dev;
> struct drm_framebuffer *fb, *tfb;
>
> -   mutex_lock(>fbs_lock);
> +   /*
> +* When the file gets released that means no one else can access the 
> fb
> +* list any more, so no need to grab fpriv->fbs_lock. And we need to 
> to
> +* avoid upsetting lockdep since the universal cursor code adds a
> +* framebuffer while holding mutex locks.
> +*
> +* Note that a real deadlock between fpriv->fbs_lock and the modeset
> +* locks is impossible here since no one else but this function can 
> get
> +* at it any more.
> +*/
> list_for_each_entry_safe(fb, tfb, >fbs, filp_head) {
>
> mutex_lock(>mode_config.fb_lock);
> @@ -3413,7 +3422,6 @@ void drm_fb_release(struct drm_file *priv)
>     /* This will also drop the fpriv->fbs reference. */
> drm_framebuffer_remove(fb);
> }
> -   mutex_unlock(>fbs_lock);
>  }
>
>  /**
> --
> 2.1.0
>



-- 
Paulo Zanoni


[Intel-gfx] [PATCH 09/11] i915: add DP 1.2 MST support (v0.6)

2014-07-22 Thread Paulo Zanoni
2014-06-05 1:01 GMT-03:00 Dave Airlie :
> From: Dave Airlie 
>
> This adds DP 1.2 MST support on Haswell systems.

Hi

It looks like drm-intel-nightly now includes this patch. It actually
includes v7, but I couldn't find it on my mail dirs.

Just by booting the machine with this patch, I get:

[   11.013593] [ cut here ]
[   11.013627] WARNING: CPU: 1 PID: 389 at
drivers/gpu/drm/i915/intel_fbdev.c:383
intel_fb_initial_config+0x3ca/0x660 [i915]()
[   11.013629] Modules linked in: i2c_designware_platform i915(+)
i2c_designware_core i2c_algo_bit drm_kms_helper drm sg sd_mod ahci
ehci_pci libahci ehci_hcd e1000e xhci_hcd sdhci_acpi sdhci
[   11.013651] CPU: 1 PID: 389 Comm: udevd Not tainted
3.16.0-rc6.1407221626+ #673
[   11.013654] Hardware name: Intel Corporation Shark Bay Client
platform/WhiteTip Mountain 1, BIOS HSWLPTU1.86C.0137.R00.1403031632
03/03/2014
[   11.013656]  0009 88009d14b790 816b6a61

[   11.013662]  88009d14b7c8 81075d88 8801483db10b
880148279400
[   11.013667]  88009d0caf00 0003 0003
88009d14b7d8
[   11.013672] Call Trace:
[   11.013680]  [] dump_stack+0x4d/0x66
[   11.013686]  [] warn_slowpath_common+0x78/0xa0
[   11.013690]  [] warn_slowpath_null+0x15/0x20
[   11.013714]  [] intel_fb_initial_config+0x3ca/0x660 [i915]
[   11.013724]  [] drm_setup_crtcs+0x17f/0x830
[drm_kms_helper]
[   11.013729]  [] ? trace_hardirqs_on_caller+0x15d/0x200
[   11.013736]  []
drm_fb_helper_initial_config+0x19a/0x4d0 [drm_kms_helper]
[   11.013740]  [] ? trace_hardirqs_on_caller+0x15d/0x200
[   11.013762]  [] intel_fbdev_initial_config+0x1a/0x20 [i915]
[   11.013789]  [] i915_driver_load+0x111b/0x1130 [i915]
[   11.013803]  [] drm_dev_register+0xa5/0x100 [drm]
[   11.013815]  [] drm_get_pci_dev+0x88/0x1f0 [drm]
[   11.013834]  [] i915_pci_probe+0x36/0x50 [i915]
[   11.013839]  [] local_pci_probe+0x3d/0xa0
[   11.013843]  [] ? pci_match_device+0xe5/0x110
[   11.013847]  [] pci_device_probe+0xc9/0x120
[   11.013853]  [] driver_probe_device+0x89/0x250
[   11.013857]  [] __driver_attach+0x8b/0x90
[   11.013879]  [] ? __device_attach+0x40/0x40
[   11.013883]  [] bus_for_each_dev+0x63/0xa0
[   11.013888]  [] driver_attach+0x19/0x20
[   11.013892]  [] bus_add_driver+0x178/0x230
[   11.013896]  [] driver_register+0x5f/0xf0
[   11.013899]  [] __pci_register_driver+0x58/0x60
[   11.013911]  [] drm_pci_init+0xfa/0x130 [drm]
[   11.013915]  [] ? trace_hardirqs_on+0xd/0x10
[   11.013918]  [] ? 0xa0221fff
[   11.013937]  [] i915_init+0x89/0x90 [i915]
[   11.013942]  [] do_one_initcall+0x98/0x1f0
[   11.013947]  [] ? __vunmap+0xa2/0x100
[   11.013952]  [] load_module+0x1bea/0x22d0
[   11.013956]  [] ? symbol_put_addr+0x40/0x40
[   11.013960]  [] ? copy_module_from_fd.isra.49+0x119/0x170
[   11.013965]  [] SyS_finit_module+0x76/0x80
[   11.013970]  [] system_call_fastpath+0x16/0x1b
[   11.013973] ---[ end trace e4d35cd76b2fc39f ]---

This is the WARN that makes the code print
[drm:intel_fb_initial_config] connector HDMI-A-2 has no encoder or
crtc, skipping


Then, if I do a normal S3 suspend/resume cycle with the desktop
enabled and everything running, I get:

[   32.431306] [ cut here ]
[   32.431341] WARNING: CPU: 2 PID: 3200 at
drivers/gpu/drm/i915/intel_pm.c:4979
intel_suspend_gt_powersave+0x49/0x50 [i915]()
[   32.431370] Modules linked in: fuse intel_rapl x86_pkg_temp_thermal
intel_powerclamp serio_raw i2c_i801 i2c_designware_platform
i2c_designware_core i915 i2c_algo_bit drm_kms_helper drm mei_me mei sg
sd_mod ehci_pci ehci_hcd ahci libahci e1000e xhci_hcd sdhci_acpi sdhci
[   32.431373] CPU: 2 PID: 3200 Comm: kworker/u16:14 Tainted: G
W 3.16.0-rc6.1407221626+ #673
[   32.431375] Hardware name: Intel Corporation Shark Bay Client
platform/WhiteTip Mountain 1, BIOS HSWLPTU1.86C.0137.R00.1403031632
03/03/2014
[   32.431379] Workqueue: events_unbound async_run_entry_fn
[   32.431383]  0009 88009d1f3be8 816b6a61

[   32.431386]  88009d1f3c20 81075d88 88014861

[   32.431390]  88014861 88009d86e758 81a5d47a
88009d1f3c30
[   32.431390] Call Trace:
[   32.431396]  [] dump_stack+0x4d/0x66
[   32.431399]  [] warn_slowpath_common+0x78/0xa0
[   32.431402]  [] warn_slowpath_null+0x15/0x20
[   32.431413]  [] intel_suspend_gt_powersave+0x49/0x50 [i915]
[   32.431422]  [] i915_drm_freeze+0x96/0x190 [i915]
[   32.431430]  [] i915_pm_suspend+0x2a/0x50 [i915]
[   32.431434]  [] pci_pm_suspend+0x71/0x160
[   32.431437]  [] ? pci_pm_freeze+0xe0/0xe0
[   32.431440]  [] dpm_run_callback+0x3a/0x130
[   32.431443]  [] __device_suspend+0xf0/0x2f0
[   32.431445]  [] async_suspend+0x1a/0xa0
[   32.431448]  [] async_run_entry_fn+0x34/0x120
[   32.431451]  [] process_one_work+0x1cf/0x550
[   32.431454]  [] ? process_one_work+0x16f/0x550
[   32.431457]  [] worker_thread+0x63/0x540
[   32.431461]  [] 

[Intel-gfx] [PATCH] drm/i915/dp: Allow for 5.4Gbps for Haswell.

2014-02-27 Thread Paulo Zanoni
2014-02-27 15:21 GMT-03:00 Keith Packard :
> Ville Syrj?l?  writes:
>
>> Todd already implemented 5.4Gbps support a while back. So it seems your
>> tree is a bit out of date.
>
> I didn't find it on drm-intel-fixes-2014-02-14; can you explain which
> tree it is present in?

It's on the drm-intel-next-queued branch. Please notice we recently
moved the tree from freedesktop.org/~danvet/drm-intel to
freedesktop.org/drm-intel.

http://cgit.freedesktop.org/drm-intel/commit/?h=drm-intel-next-queued=06ea66b6bb445043dc25a9626254d5c130093199


>
> --
> keith.packard at intel.com
>
> ___
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Paulo Zanoni


[PATCH 13/19] drm: do not steal the display if we have a master

2013-11-27 Thread Paulo Zanoni
From: Paulo Zanoni <paulo.r.zan...@intel.com>

Sometimes we want to disable all the screens on a system, because that
will allow the graphics card to be put into low-power states. The
problem is that, for example, while all screens are disabled, if we
get a hotplug interrupt, fbcon will decide to set a mode instead of
keeping everything disabled, which will remove us from our low power
states.

Let's assume that if there's a DRM master, it will be able to do
whatever is appropriate when we get the hotplug.

This problem can be reproduced by the runtime PM test program from
intel-gpu-tools: we disable all the screens so the graphics device can
be put into D3, then something triggers a hotplug interrupt, fbcon
sets a mode and breaks our test suite. The problem can be reproduced
more easily by the "i2c" subtest.

Other approaches considered for the problem:
- Return "false" if "bound == 0" and the caller of
  drm_fb_helper_is_bound is a hotplug handler. This would break
  the case where the machine boots with no outputs connected, then
  the user plugs a monitor.
- Add a new IOCTL to force fbcon to not set modes. This would keep
  all the current applications behaving the same, but adding a new
  IOCTL is not always the greatest idea.
- Return false only if "dev->primary->master && bound == 0". This
  was my first implementation, but Chris suggested we should do
  the check irrespective of the "bound" variable.

Thanks to Daniel Vetter for the investigation, ideas and the
implementation of the hotplug alternative.

v2: - Do the check first, irrespective of "bound".
- Cc dri-devel

Cc: dri-devel at lists.freedesktop.org
Credits-to: Daniel Vetter 
Signed-off-by: Paulo Zanoni 
---
 drivers/gpu/drm/drm_fb_helper.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 0a19401..98a0363 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -359,6 +359,11 @@ static bool drm_fb_helper_is_bound(struct drm_fb_helper 
*fb_helper)
struct drm_crtc *crtc;
int bound = 0, crtcs_bound = 0;

+   /* Sometimes user space wants everything disabled, so don't steal the
+* display if there's a master. */
+   if (dev->primary->master)
+   return false;
+
list_for_each_entry(crtc, >mode_config.crtc_list, head) {
if (crtc->fb)
crtcs_bound++;
@@ -368,6 +373,7 @@ static bool drm_fb_helper_is_bound(struct drm_fb_helper 
*fb_helper)

if (bound < crtcs_bound)
return false;
+
return true;
 }

-- 
1.8.3.1



[PATCH] drm/sysfs: Do not drop device reference twice

2013-10-30 Thread Paulo Zanoni
2013/10/30 Thierry Reding :
> device_unregister() already drops its reference to the struct device, so
> explicitly calling put_device() before device_unregister() can cause the
> device to have been freed before it can be unregistered.
>
> Signed-off-by: Thierry Reding 

I started investigating this problem yesterday and reached the same
conclusion. The connector path can be easily reproduced on i915.ko:
get a machine that has an eDP panel, physically disconnect the panel,
boot the machine, "modprobe i915" and watch the segfault.

Reviewed-by: Paulo Zanoni 
Tested-by: Paulo Zanoni 

I didn't really bisect, but I believe this is probably a regression
from "drm/sysfs: sort out minor and connector device object
lifetimes".

And kudos to whoever invented CONFIG_DEBUG_KOBJECT :)

> ---
>  drivers/gpu/drm/drm_sysfs.c | 2 --
>  1 file changed, 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> index dae42c7..db1c8f9 100644
> --- a/drivers/gpu/drm/drm_sysfs.c
> +++ b/drivers/gpu/drm/drm_sysfs.c
> @@ -439,7 +439,6 @@ err_out_files:
> device_remove_file(connector->kdev, _attrs_opt1[i]);
> for (i = 0; i < attr_cnt; i++)
> device_remove_file(connector->kdev, _attrs[i]);
> -   put_device(connector->kdev);
> device_unregister(connector->kdev);
>
>  out:
> @@ -472,7 +471,6 @@ void drm_sysfs_connector_remove(struct drm_connector 
> *connector)
> for (i = 0; i < ARRAY_SIZE(connector_attrs); i++)
> device_remove_file(connector->kdev, _attrs[i]);
> sysfs_remove_bin_file(>kdev->kobj, _attr);
> -   put_device(connector->kdev);
> device_unregister(connector->kdev);
> connector->kdev = NULL;
>  }
> --
> 1.8.4
>
> _______
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Paulo Zanoni


Re: [PATCH 3/5] tty/vt: add con_bind and con_unbind functions

2013-10-08 Thread Paulo Zanoni
2013/10/1 Ville Syrjälä ville.syrj...@linux.intel.com:
 On Thu, Sep 26, 2013 at 08:06:00PM -0300, Paulo Zanoni wrote:
 From: Paulo Zanoni paulo.r.zan...@intel.com

 The consoles who need to do something when unbinding or binding can
 optionally implement these functions.

 The current problem I'm trying to solve is that when i915+fbcon is
 loaded on Haswell, if we disable the power well (to save power) the
 VGA interface gets completely disabled, so when we unbind fbcon we
 need to restore the VGA interface to allow vgacon to work.

 We don't need to make it work. No one else does, and in the general case
 it's even impossible since on some hardware that would definitely
 corrupt the state that the real driver is attempting to use. The only
 case where it might be nice to restore vgacon is on i915 unload, but no
 one else does that either AFAIK, so I would not waste any cycles on
 attempting that.

I don't understand your point. Without patches 3-4-5, module_reload
doesn't work at all if the power well is disabled: we need these
patches to fix it. The plan is not to restore everything to make
vgacon actually work, the plan is just to prevent it from breaking
module_reload.




 Signed-off-by: Paulo Zanoni paulo.r.zan...@intel.com
 ---
  drivers/tty/vt/vt.c | 6 ++
  include/linux/console.h | 2 ++
  2 files changed, 8 insertions(+)

 diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
 index 9a8e8c5..beb5986 100644
 --- a/drivers/tty/vt/vt.c
 +++ b/drivers/tty/vt/vt.c
 @@ -3014,6 +3014,9 @@ static int do_bind_con_driver(const struct consw *csw, 
 int first, int last,
   if (retval)
   goto err;

 + if (csw-con_bind)
 + csw-con_bind();
 +
   if (!(con_driver-flag  CON_DRIVER_FLAG_INIT)) {
   csw-con_startup();
   con_driver-flag |= CON_DRIVER_FLAG_INIT;
 @@ -3152,6 +3155,9 @@ int do_unbind_con_driver(const struct consw *csw, int 
 first, int last, int deflt
   if (!con_is_bound(csw))
   goto err;

 + if (csw-con_unbind)
 + csw-con_unbind();
 +
   first = max(first, con_driver-first);
   last = min(last, con_driver-last);

 diff --git a/include/linux/console.h b/include/linux/console.h
 index 7571a16..5cd2c35 100644
 --- a/include/linux/console.h
 +++ b/include/linux/console.h
 @@ -65,6 +65,8 @@ struct consw {
* Restore the console to its pre-debug state as closely as possible.
*/
   int (*con_debug_leave)(struct vc_data *);
 + void(*con_bind)(void);
 + void(*con_unbind)(void);
  };

  extern const struct consw *conswitchp;
 --
 1.8.3.1

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

 --
 Ville Syrjälä
 Intel OTC



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


[PATCH 0/5] module_reload fixes

2013-09-26 Thread Paulo Zanoni
From: Paulo Zanoni paulo.r.zan...@intel.com

Hi

These patches allow us to run the module_reload script from intel-gpu-tools on
Haswell. The script basically just removes i915.ko and loads it again.

There's a memory corruption fix and also the fix for fd.o #67813.  Notice that
the first patch fixes the case where we boot eDP+something, while patches 3-5
fix the case where we boot eDP-only.

I couldn't find MAINTAINERS entries for vt.c or fbcon.c, but I heard the
dri-devel list is a good place for such patches. Please tell me if I missed some
mailing list.

Cheers,
Paulo


Paulo Zanoni (5):
  drm/i915: redisable VGA when we disable the power well
  drm/i915: destroy connector sysfs files earlier
  tty/vt: add con_bind and con_unbind functions
  console/fbcon: implement con_bind and con_unbind
  drm/i915: put/get the power well at the FB bind/unbind functions

 drivers/gpu/drm/i915/intel_crt.c |  1 -
 drivers/gpu/drm/i915/intel_display.c |  7 ++-
 drivers/gpu/drm/i915/intel_dp.c  |  1 -
 drivers/gpu/drm/i915/intel_drv.h |  2 ++
 drivers/gpu/drm/i915/intel_dsi.c |  1 -
 drivers/gpu/drm/i915/intel_dvo.c |  1 -
 drivers/gpu/drm/i915/intel_fb.c  | 23 +++
 drivers/gpu/drm/i915/intel_hdmi.c|  1 -
 drivers/gpu/drm/i915/intel_lvds.c|  1 -
 drivers/gpu/drm/i915/intel_pm.c  |  6 ++
 drivers/gpu/drm/i915/intel_sdvo.c|  7 +--
 drivers/gpu/drm/i915/intel_tv.c  |  1 -
 drivers/tty/vt/vt.c  |  6 ++
 drivers/video/console/fbcon.c| 26 ++
 include/linux/console.h  |  2 ++
 include/linux/fb.h   |  4 
 16 files changed, 80 insertions(+), 10 deletions(-)

-- 
1.8.3.1

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


[PATCH 1/5] drm/i915: redisable VGA when we disable the power well

2013-09-26 Thread Paulo Zanoni
From: Paulo Zanoni paulo.r.zan...@intel.com

VGA whack-a-mole!

We need VGA to be disabled whenever our driver is working. So even
without reproducible bugs this patch makes sense, but we do have a bug
solved by this patch.

If you boot a Haswell machine with eDP+HDMI, then kill your display
manager and run:
echo 0  /sys/class/vtconsole/vtcon1/bind
you'll get thousands of unclaimed register messages. Notice that
since we have eDP+HDMI, the power well is *enabled* when we run the
command, but if you look at dmesg you'll see that at some point during
the boot we disabled it and then reenabled it. This patch solves this
problem.

I didn't do a deep analysis of the problem, but I guess vgacon gets
seriously confused when it sees that the VGA plane is enabled.

Besides the command above, this problem can also be reproduced by the
module_reload test from intel-gpu-tools.

Fixes regression introduced by:
commit bf51d5e2cda5d36d98e4b46ac7fca9461e512c41
Author: Paulo Zanoni paulo.r.zan...@intel.com
drm/i915: switch disable_power_well default value to 1

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67813
Signed-off-by: Paulo Zanoni paulo.r.zan...@intel.com
---
 drivers/gpu/drm/i915/intel_display.c | 2 +-
 drivers/gpu/drm/i915/intel_drv.h | 1 +
 drivers/gpu/drm/i915/intel_pm.c  | 6 ++
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 665fa8f..065ffed 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10232,7 +10232,7 @@ static void intel_init_quirks(struct drm_device *dev)
 }
 
 /* Disable the VGA plane that we never use */
-static void i915_disable_vga(struct drm_device *dev)
+void i915_disable_vga(struct drm_device *dev)
 {
struct drm_i915_private *dev_priv = dev-dev_private;
u8 sr1;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index a17a86a..e63646a 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -678,6 +678,7 @@ void
 ironlake_check_encoder_dotclock(const struct intel_crtc_config *pipe_config,
int dotclock);
 bool intel_crtc_active(struct drm_crtc *crtc);
+void i915_disable_vga(struct drm_device *dev);
 void i915_disable_vga_mem(struct drm_device *dev);
 
 
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 2ac1c2f..7a8af95 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5329,6 +5329,12 @@ static void __intel_set_power_well(struct drm_device 
*dev, bool enable)
if (wait_for((I915_READ(HSW_PWR_WELL_DRIVER) 
  HSW_PWR_WELL_STATE_ENABLED), 20))
DRM_ERROR(Timeout enabling power well\n);
+
+   if (I915_READ(i915_vgacntrl_reg(dev)) !=
+   VGA_DISP_DISABLE) {
+   i915_disable_vga(dev);
+   i915_disable_vga_mem(dev);
+   }
}
} else {
if (enable_requested) {
-- 
1.8.3.1

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


[PATCH 2/5] drm/i915: destroy connector sysfs files earlier

2013-09-26 Thread Paulo Zanoni
From: Paulo Zanoni paulo.r.zan...@intel.com

For some reason, every single time I try to run module_reload
something tries to read the connector sysfs files. This happens
after we destroy the encoders and before we destroy the connectors, so
when the sysfs read triggers the connector detect() function,
intel_conector-encoder points to memory that was already freed.

The bad backtrace is just:
[8163ca9a] dump_stack+0x54/0x74
[a00c2c8e] intel_dp_detect+0x1e/0x4b0 [i915]
[a001913d] status_show+0x3d/0x80 [drm]
[813d5340] dev_attr_show+0x20/0x60
[81221f50] ? sysfs_read_file+0x80/0x1b0
[81221f79] sysfs_read_file+0xa9/0x1b0
[811aaf1e] vfs_read+0x9e/0x170
[811aba4c] SyS_read+0x4c/0xa0
[8164e392] system_call_fastpath+0x16/0x1b

But if you add tons of memory checking debug options to your Kernel
you'll also see:
 - general protection fault: 
 - BUG kmalloc-4096 (Tainted: G  D W   ): Poison overwritten
 - INFO: Allocated in intel_ddi_init+0x65/0x270 [i915]
 - INFO: Freed in intel_dp_encoder_destroy+0x69/0xb0 [i915]
Among a bunch of other error messages.

So this commit just destroys the sysfs files before both the encoder
and connectors are freed.

Signed-off-by: Paulo Zanoni paulo.r.zan...@intel.com
---
 drivers/gpu/drm/i915/intel_crt.c | 1 -
 drivers/gpu/drm/i915/intel_display.c | 5 +
 drivers/gpu/drm/i915/intel_dp.c  | 1 -
 drivers/gpu/drm/i915/intel_dsi.c | 1 -
 drivers/gpu/drm/i915/intel_dvo.c | 1 -
 drivers/gpu/drm/i915/intel_hdmi.c| 1 -
 drivers/gpu/drm/i915/intel_lvds.c| 1 -
 drivers/gpu/drm/i915/intel_sdvo.c| 7 +--
 drivers/gpu/drm/i915/intel_tv.c  | 1 -
 9 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 0263629..942b9ac 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -677,7 +677,6 @@ intel_crt_detect(struct drm_connector *connector, bool 
force)
 
 static void intel_crt_destroy(struct drm_connector *connector)
 {
-   drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
kfree(connector);
 }
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 065ffed..793061f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10726,6 +10726,7 @@ void intel_modeset_cleanup(struct drm_device *dev)
 {
struct drm_i915_private *dev_priv = dev-dev_private;
struct drm_crtc *crtc;
+   struct drm_connector *connector;
 
/*
 * Interrupts and polling as the first thing to avoid creating havoc.
@@ -10768,6 +10769,10 @@ void intel_modeset_cleanup(struct drm_device *dev)
/* destroy backlight, if any, before the connectors */
intel_panel_destroy_backlight(dev);
 
+   /* destroy the sysfs files before encoders/connectors */
+   list_for_each_entry(connector, dev-mode_config.connector_list, head)
+   drm_sysfs_connector_remove(connector);
+
drm_mode_config_cleanup(dev);
 
intel_cleanup_overlay(dev);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 95a3159..7bdbb36 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3139,7 +3139,6 @@ intel_dp_connector_destroy(struct drm_connector 
*connector)
if (connector-connector_type == DRM_MODE_CONNECTOR_eDP)
intel_panel_fini(intel_connector-panel);
 
-   drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
kfree(connector);
 }
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 674fd49..9a2fdd2 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -504,7 +504,6 @@ static void intel_dsi_destroy(struct drm_connector 
*connector)
 
DRM_DEBUG_KMS(\n);
intel_panel_fini(intel_connector-panel);
-   drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
kfree(connector);
 }
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index 91287d1..1b64145 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -367,7 +367,6 @@ static int intel_dvo_get_modes(struct drm_connector 
*connector)
 
 static void intel_dvo_destroy(struct drm_connector *connector)
 {
-   drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
kfree(connector);
 }
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
b/drivers/gpu/drm/i915/intel_hdmi.c
index 6004f9c..4f4d346 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1181,7 +1181,6 @@ static void intel_hdmi_post_disable(struct intel_encoder 
*encoder)
 
 static void intel_hdmi_destroy(struct drm_connector

[PATCH 3/5] tty/vt: add con_bind and con_unbind functions

2013-09-26 Thread Paulo Zanoni
From: Paulo Zanoni paulo.r.zan...@intel.com

The consoles who need to do something when unbinding or binding can
optionally implement these functions.

The current problem I'm trying to solve is that when i915+fbcon is
loaded on Haswell, if we disable the power well (to save power) the
VGA interface gets completely disabled, so when we unbind fbcon we
need to restore the VGA interface to allow vgacon to work.

Signed-off-by: Paulo Zanoni paulo.r.zan...@intel.com
---
 drivers/tty/vt/vt.c | 6 ++
 include/linux/console.h | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 9a8e8c5..beb5986 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -3014,6 +3014,9 @@ static int do_bind_con_driver(const struct consw *csw, 
int first, int last,
if (retval)
goto err;
 
+   if (csw-con_bind)
+   csw-con_bind();
+
if (!(con_driver-flag  CON_DRIVER_FLAG_INIT)) {
csw-con_startup();
con_driver-flag |= CON_DRIVER_FLAG_INIT;
@@ -3152,6 +3155,9 @@ int do_unbind_con_driver(const struct consw *csw, int 
first, int last, int deflt
if (!con_is_bound(csw))
goto err;
 
+   if (csw-con_unbind)
+   csw-con_unbind();
+
first = max(first, con_driver-first);
last = min(last, con_driver-last);
 
diff --git a/include/linux/console.h b/include/linux/console.h
index 7571a16..5cd2c35 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -65,6 +65,8 @@ struct consw {
 * Restore the console to its pre-debug state as closely as possible.
 */
int (*con_debug_leave)(struct vc_data *);
+   void(*con_bind)(void);
+   void(*con_unbind)(void);
 };
 
 extern const struct consw *conswitchp;
-- 
1.8.3.1

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


[PATCH 4/5] console/fbcon: implement con_bind and con_unbind

2013-09-26 Thread Paulo Zanoni
From: Paulo Zanoni paulo.r.zan...@intel.com

And create fb_bind and fb_unbind fb_ops that the drivers can
implement.

The current problem I'm trying to solve is that when i915+fbcon is
loaded on Haswell, if we disable the power well (to save power) the
VGA interface gets completely disabled, so when we unbind fbcon we
need to restore the VGA interface to allow vgacon to work.

Signed-off-by: Paulo Zanoni paulo.r.zan...@intel.com
---
 drivers/video/console/fbcon.c | 26 ++
 include/linux/fb.h|  4 
 2 files changed, 30 insertions(+)

diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index cd8a802..68d316a 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -3298,6 +3298,30 @@ done:
return ret;
 }
 
+static void fbcon_con_bind(void)
+{
+   struct fb_info *info = NULL;
+
+   info = registered_fb[info_idx];
+   if (!info)
+   return;
+
+   if (info-fbops-fb_bind)
+   info-fbops-fb_bind(info);
+}
+
+static void fbcon_con_unbind(void)
+{
+   struct fb_info *info = NULL;
+
+   info = registered_fb[info_idx];
+   if (!info)
+   return;
+
+   if (info-fbops-fb_unbind)
+   info-fbops-fb_unbind(info);
+}
+
 /*
  *  The console `switch' structure for the frame buffer based console
  */
@@ -3328,6 +3352,8 @@ static const struct consw fb_con = {
.con_resize = fbcon_resize,
.con_debug_enter= fbcon_debug_enter,
.con_debug_leave= fbcon_debug_leave,
+   .con_bind   = fbcon_con_bind,
+   .con_unbind = fbcon_con_unbind,
 };
 
 static struct notifier_block fbcon_event_notifier = {
diff --git a/include/linux/fb.h b/include/linux/fb.h
index ffac70a..8074bd5 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -304,6 +304,10 @@ struct fb_ops {
/* called at KDB enter and leave time to prepare the console */
int (*fb_debug_enter)(struct fb_info *info);
int (*fb_debug_leave)(struct fb_info *info);
+
+   /* called when binding/unbinding */
+   void  (*fb_bind)(struct fb_info *info);
+   void  (*fb_unbind)(struct fb_info *info);
 };
 
 #ifdef CONFIG_FB_TILEBLITTING
-- 
1.8.3.1

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


[PATCH 5/5] drm/i915: put/get the power well at the FB bind/unbind functions

2013-09-26 Thread Paulo Zanoni
From: Paulo Zanoni paulo.r.zan...@intel.com

If we run the following command on Haswell when the power well is
disabled:
echo 0  /sys/class/vtconsole/vtcon1/bind
then we'll get thousands of consecutive interrupts because something
is trying to touch registers that are on the disabled power well. So
before we unbind the console, we need to enable the power well to make
the VGA interface work correctly. With this, whoever is using it
doesn't trigger interrupts on i915.ko.

Fixes regression introduced by:
commit bf51d5e2cda5d36d98e4b46ac7fca9461e512c41
Author: Paulo Zanoni paulo.r.zan...@intel.com
drm/i915: switch disable_power_well default value to 1

Besides the command above, the module_reload test from
intel-gpu-tools can also be used to reproduce the bug fixed by this
patch.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67813
Signed-off-by: Paulo Zanoni paulo.r.zan...@intel.com
---
 drivers/gpu/drm/i915/intel_drv.h |  1 +
 drivers/gpu/drm/i915/intel_fb.c  | 23 +++
 2 files changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index e63646a..a643c48 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -113,6 +113,7 @@ struct intel_fbdev {
struct intel_framebuffer ifb;
struct list_head fbdev_list;
struct drm_display_mode *our_mode;
+   bool first_bind_done;
 };
 
 struct intel_encoder {
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index d883b77..8c6ed1c 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -43,6 +43,27 @@
 #include drm/i915_drm.h
 #include i915_drv.h
 
+static void intel_fb_bind(struct fb_info *info)
+{
+   struct drm_fb_helper *drm_helper = info-par;
+   struct drm_device *dev = drm_helper-dev;
+   struct intel_fbdev *ifbdev =
+   container_of(drm_helper, struct intel_fbdev, helper);
+
+   if (ifbdev-first_bind_done)
+   intel_display_power_put(dev, POWER_DOMAIN_VGA);
+   else
+   ifbdev-first_bind_done = true;
+}
+
+static void intel_fb_unbind(struct fb_info *info)
+{
+   struct drm_fb_helper *fb_helper = info-par;
+   struct drm_device *dev = fb_helper-dev;
+
+   intel_display_power_get(dev, POWER_DOMAIN_VGA);
+}
+
 static struct fb_ops intelfb_ops = {
.owner = THIS_MODULE,
.fb_check_var = drm_fb_helper_check_var,
@@ -55,6 +76,8 @@ static struct fb_ops intelfb_ops = {
.fb_setcmap = drm_fb_helper_setcmap,
.fb_debug_enter = drm_fb_helper_debug_enter,
.fb_debug_leave = drm_fb_helper_debug_leave,
+   .fb_bind = intel_fb_bind,
+   .fb_unbind = intel_fb_unbind,
 };
 
 static int intelfb_create(struct drm_fb_helper *helper,
-- 
1.8.3.1

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


[PATCH 2/2] drm/i915: add fast boot support for Haswell

2013-08-20 Thread Paulo Zanoni
see "unclaimed register" errors when booting with HDMI + eDP.
The problem is that we try to read disabled LINK_M/LINK_N registers
due to the power well disabled, so we get the error messages. I also
once saw a "pipe state mismatch" error, but I can't find a way to
reproduce it now. I'm also not sure whether VGA will really work since
we don't touch intel_crt.c (I can't test it for now). When testing the
patches, please always check dmesg for errors or warns, we should have
none. It looks to me that enabling fastboot on Haswell won't be so
simple due to these error messages I'm seeing. You should probably
convince Jesse to fix these problems :)

Thanks for the patches,
Paulo


> +   } else if (temp == PORT_CLK_SEL_SPLL) {
> +   u32 val;
> +
> +   val = I915_READ(PORT_CLK_SEL_SPLL);
> +
> +   switch (val & SPLL_PLL_FREQ_MASK) {
> +   case SPLL_PLL_FREQ_810MHz:
> +   pipe_config->port_clock = 81;
> +   break;
> +   case SPLL_PLL_FREQ_1350MHz:
> +   pipe_config->port_clock = 135;
> +   break;
> +   default:
> +   WARN(1, "Invalid pll freq %d\n",
> +val & SPLL_PLL_FREQ_MASK);
> +   return;
> +   }
> +   } else {
> +   WARN(1, "Invalid clock selection %d\n", temp);
> +   return;
> +   }
> +}
> +
>  static void intel_ddi_get_config(struct intel_encoder *encoder,
>  struct intel_crtc_config *pipe_config)
>  {
> @@ -1265,6 +1333,8 @@ static void intel_ddi_get_config(struct intel_encoder 
> *encoder,
> flags |= DRM_MODE_FLAG_NVSYNC;
>
> pipe_config->adjusted_mode.flags |= flags;
> +
> +   intel_ddi_get_clock(encoder, pipe_config);
>  }
>
>  static void intel_ddi_destroy(struct drm_encoder *encoder)
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index e0069f4..1c6a3d2 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -9579,6 +9579,7 @@ static void intel_init_display(struct drm_device *dev)
>
> if (HAS_DDI(dev)) {
> dev_priv->display.get_pipe_config = haswell_get_pipe_config;
> +   dev_priv->display.get_clock = ironlake_crtc_clock_get;
> dev_priv->display.crtc_mode_set = haswell_crtc_mode_set;
> dev_priv->display.crtc_enable = haswell_crtc_enable;
> dev_priv->display.crtc_disable = haswell_crtc_disable;
> --
> 1.8.3
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Paulo Zanoni


Re: [PATCH 2/2] drm/i915: add fast boot support for Haswell

2013-08-20 Thread Paulo Zanoni
 fastboot on Haswell won't be so
simple due to these error messages I'm seeing. You should probably
convince Jesse to fix these problems :)

Thanks for the patches,
Paulo


 +   } else if (temp == PORT_CLK_SEL_SPLL) {
 +   u32 val;
 +
 +   val = I915_READ(PORT_CLK_SEL_SPLL);
 +
 +   switch (val  SPLL_PLL_FREQ_MASK) {
 +   case SPLL_PLL_FREQ_810MHz:
 +   pipe_config-port_clock = 81;
 +   break;
 +   case SPLL_PLL_FREQ_1350MHz:
 +   pipe_config-port_clock = 135;
 +   break;
 +   default:
 +   WARN(1, Invalid pll freq %d\n,
 +val  SPLL_PLL_FREQ_MASK);
 +   return;
 +   }
 +   } else {
 +   WARN(1, Invalid clock selection %d\n, temp);
 +   return;
 +   }
 +}
 +
  static void intel_ddi_get_config(struct intel_encoder *encoder,
  struct intel_crtc_config *pipe_config)
  {
 @@ -1265,6 +1333,8 @@ static void intel_ddi_get_config(struct intel_encoder 
 *encoder,
 flags |= DRM_MODE_FLAG_NVSYNC;

 pipe_config-adjusted_mode.flags |= flags;
 +
 +   intel_ddi_get_clock(encoder, pipe_config);
  }

  static void intel_ddi_destroy(struct drm_encoder *encoder)
 diff --git a/drivers/gpu/drm/i915/intel_display.c 
 b/drivers/gpu/drm/i915/intel_display.c
 index e0069f4..1c6a3d2 100644
 --- a/drivers/gpu/drm/i915/intel_display.c
 +++ b/drivers/gpu/drm/i915/intel_display.c
 @@ -9579,6 +9579,7 @@ static void intel_init_display(struct drm_device *dev)

 if (HAS_DDI(dev)) {
 dev_priv-display.get_pipe_config = haswell_get_pipe_config;
 +   dev_priv-display.get_clock = ironlake_crtc_clock_get;
 dev_priv-display.crtc_mode_set = haswell_crtc_mode_set;
 dev_priv-display.crtc_enable = haswell_crtc_enable;
 dev_priv-display.crtc_disable = haswell_crtc_disable;
 --
 1.8.3

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



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


[PATCH 11/11] drm/i915: Hook PSR functionality

2013-06-28 Thread Paulo Zanoni
2013/6/26 Rodrigo Vivi :
> PSR must be enabled after transcoder and port are running.
> And it is only available for HSW.
>
> v2: move enable/disable to intel_ddi
> v3: The spec suggests PSR should be disabled even before backlight (by 
> pzanoni)
> v4: also disabling and enabling whenever panel is disabled/enabled.
> v5: make it last patch to avoid breaking whenever bisecting. So calling for
> update and force exit came to this patch along with enable/disable calls.
>
> CC: Paulo Zanoni 
> Signed-off-by: Rodrigo Vivi 
> ---
>  drivers/gpu/drm/i915/i915_gem.c  | 2 ++
>  drivers/gpu/drm/i915/intel_ddi.c | 2 ++
>  drivers/gpu/drm/i915/intel_display.c | 1 +
>  drivers/gpu/drm/i915/intel_dp.c  | 2 ++
>  4 files changed, 7 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index c68b90f..f2e135b 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -3786,6 +3786,8 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
> goto unlock;
> }
>
> +   intel_edp_psr_force_exit(dev);
> +
> /* Count all active objects as busy, even if they are currently not 
> used
>  * by the gpu. Users of this interface expect objects to eventually
>  * become non-busy without any further actions, therefore emit any
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c 
> b/drivers/gpu/drm/i915/intel_ddi.c
> index 324211a..4211925 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1117,6 +1117,7 @@ static void intel_enable_ddi(struct intel_encoder 
> *intel_encoder)
> intel_dp_stop_link_train(intel_dp);
>
> ironlake_edp_backlight_on(intel_dp);
> +   intel_edp_psr_enable(intel_dp);
> }
>
> if (intel_crtc->eld_vld && type != INTEL_OUTPUT_EDP) {
> @@ -1147,6 +1148,7 @@ static void intel_disable_ddi(struct intel_encoder 
> *intel_encoder)
> if (type == INTEL_OUTPUT_EDP) {
> struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
>
> +   intel_edp_psr_disable(intel_dp);
> ironlake_edp_backlight_off(intel_dp);
> }
>  }
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index 6fafa43..5bbfed0 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2236,6 +2236,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
> }
>
> intel_update_fbc(dev);
> +   intel_edp_psr_update(dev);
> mutex_unlock(>struct_mutex);
>
> intel_crtc_update_sarea_pos(crtc, x, y);
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 9986484..019b1ff 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -1668,6 +1668,7 @@ static void intel_disable_dp(struct intel_encoder 
> *encoder)
> /* Make sure the panel is off before trying to change the mode. But 
> also
>  * ensure that we have vdd while we switch off the panel. */
> ironlake_edp_panel_vdd_on(intel_dp);
> +   intel_edp_psr_disable(intel_dp);
> ironlake_edp_backlight_off(intel_dp);
> intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> ironlake_edp_panel_off(intel_dp);
> @@ -1708,6 +1709,7 @@ static void intel_enable_dp(struct intel_encoder 
> *encoder)
> intel_dp_complete_link_train(intel_dp);
> intel_dp_stop_link_train(intel_dp);
> ironlake_edp_backlight_on(intel_dp);
> +   intel_edp_psr_enable(intel_dp);
>
> if (IS_VALLEYVIEW(dev)) {
> struct intel_digital_port *dport =

Functions intel_enable_dp and intel_disable_dp are not used on
Haswell, so I guess we don't need those calls, right?

> --
> 1.8.1.4
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Paulo Zanoni


Re: [PATCH 11/11] drm/i915: Hook PSR functionality

2013-06-28 Thread Paulo Zanoni
2013/6/26 Rodrigo Vivi rodrigo.v...@gmail.com:
 PSR must be enabled after transcoder and port are running.
 And it is only available for HSW.

 v2: move enable/disable to intel_ddi
 v3: The spec suggests PSR should be disabled even before backlight (by 
 pzanoni)
 v4: also disabling and enabling whenever panel is disabled/enabled.
 v5: make it last patch to avoid breaking whenever bisecting. So calling for
 update and force exit came to this patch along with enable/disable calls.

 CC: Paulo Zanoni paulo.r.zan...@intel.com
 Signed-off-by: Rodrigo Vivi rodrigo.v...@gmail.com
 ---
  drivers/gpu/drm/i915/i915_gem.c  | 2 ++
  drivers/gpu/drm/i915/intel_ddi.c | 2 ++
  drivers/gpu/drm/i915/intel_display.c | 1 +
  drivers/gpu/drm/i915/intel_dp.c  | 2 ++
  4 files changed, 7 insertions(+)

 diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
 index c68b90f..f2e135b 100644
 --- a/drivers/gpu/drm/i915/i915_gem.c
 +++ b/drivers/gpu/drm/i915/i915_gem.c
 @@ -3786,6 +3786,8 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
 goto unlock;
 }

 +   intel_edp_psr_force_exit(dev);
 +
 /* Count all active objects as busy, even if they are currently not 
 used
  * by the gpu. Users of this interface expect objects to eventually
  * become non-busy without any further actions, therefore emit any
 diff --git a/drivers/gpu/drm/i915/intel_ddi.c 
 b/drivers/gpu/drm/i915/intel_ddi.c
 index 324211a..4211925 100644
 --- a/drivers/gpu/drm/i915/intel_ddi.c
 +++ b/drivers/gpu/drm/i915/intel_ddi.c
 @@ -1117,6 +1117,7 @@ static void intel_enable_ddi(struct intel_encoder 
 *intel_encoder)
 intel_dp_stop_link_train(intel_dp);

 ironlake_edp_backlight_on(intel_dp);
 +   intel_edp_psr_enable(intel_dp);
 }

 if (intel_crtc-eld_vld  type != INTEL_OUTPUT_EDP) {
 @@ -1147,6 +1148,7 @@ static void intel_disable_ddi(struct intel_encoder 
 *intel_encoder)
 if (type == INTEL_OUTPUT_EDP) {
 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);

 +   intel_edp_psr_disable(intel_dp);
 ironlake_edp_backlight_off(intel_dp);
 }
  }
 diff --git a/drivers/gpu/drm/i915/intel_display.c 
 b/drivers/gpu/drm/i915/intel_display.c
 index 6fafa43..5bbfed0 100644
 --- a/drivers/gpu/drm/i915/intel_display.c
 +++ b/drivers/gpu/drm/i915/intel_display.c
 @@ -2236,6 +2236,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 }

 intel_update_fbc(dev);
 +   intel_edp_psr_update(dev);
 mutex_unlock(dev-struct_mutex);

 intel_crtc_update_sarea_pos(crtc, x, y);
 diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
 index 9986484..019b1ff 100644
 --- a/drivers/gpu/drm/i915/intel_dp.c
 +++ b/drivers/gpu/drm/i915/intel_dp.c
 @@ -1668,6 +1668,7 @@ static void intel_disable_dp(struct intel_encoder 
 *encoder)
 /* Make sure the panel is off before trying to change the mode. But 
 also
  * ensure that we have vdd while we switch off the panel. */
 ironlake_edp_panel_vdd_on(intel_dp);
 +   intel_edp_psr_disable(intel_dp);
 ironlake_edp_backlight_off(intel_dp);
 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
 ironlake_edp_panel_off(intel_dp);
 @@ -1708,6 +1709,7 @@ static void intel_enable_dp(struct intel_encoder 
 *encoder)
 intel_dp_complete_link_train(intel_dp);
 intel_dp_stop_link_train(intel_dp);
 ironlake_edp_backlight_on(intel_dp);
 +   intel_edp_psr_enable(intel_dp);

 if (IS_VALLEYVIEW(dev)) {
 struct intel_digital_port *dport =

Functions intel_enable_dp and intel_disable_dp are not used on
Haswell, so I guess we don't need those calls, right?

 --
 1.8.1.4

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



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


[PATCH 0/4] drm/edid: Recognize 60Hz and 59.94Hz CEA modes

2013-04-17 Thread Paulo Zanoni
2013/4/17  :
> This series attempts to make our CEA mode matching recognize both the
> 60Hz and 59.94Hz variants of the modes (and similarly for 24/23.97,
> 30/29.97, etc.).
>
> The benefits should include:
> - Send the correct VIC in the AVI infoframe
> - Pick the correct RGB quantization range in automatic mode

Everything looks correct, but I really didn't test anything. If you
apply my comments from patch 2, then you have "Reviewed-by: Paulo
Zanoni " for all the 4 patches.

Optional bikeshedding: you could add a follow-up patch fixing the
comments inside edid_cea_modes to reflect the correct Hz used,
replacing, for example, "AxB at 60Hz" with "AxB at 59.94Hz". But I can
certainly live without this :)

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



--
Paulo Zanoni


[PATCH 2/4] drm: Add drm_mode_equal_no_clocks()

2013-04-17 Thread Paulo Zanoni
Hi

2013/4/17  :
> From: Ville Syrj?l? 
>
> drm_mode_equal_no_clocks() is like drm_mode_equal() except it doesn't
> compare the clock or vrefresh values. drm_mode_equal() is now
> implemented by first doing the clock checks, and then calling
> drm_mode_equal_no_clocks().
>
> Signed-off-by: Ville Syrj?l? 
> ---
>  drivers/gpu/drm/drm_modes.c | 20 +++-
>  include/drm/drm_crtc.h  |  1 +
>  2 files changed, 20 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> index 04fa6f1..db85d0b9 100644
> --- a/drivers/gpu/drm/drm_modes.c
> +++ b/drivers/gpu/drm/drm_modes.c
> @@ -848,6 +848,24 @@ bool drm_mode_equal(const struct drm_display_mode 
> *mode1, const struct drm_displ
> } else if (mode1->clock != mode2->clock)
> return false;
>
> +   return drm_mode_equal_no_clocks(mode1, mode2);
> +}

EXPORT_SYMBOL(drm_mode_equal) is gone. I'd also add a newline here.

> +/**
> + * drm_mode_equal_no_clocks - test modes for equality
> + * @mode1: first mode
> + * @mode2: second mode
> + *
> + * LOCKING:
> + * None.
> + *
> + * Check to see if @mode1 and @mode2 are equivalent, but
> + * don't check the pixel clocks.
> + *
> + * RETURNS:
> + * True if the modes are equal, false otherwise.
> + */
> +bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1, const 
> struct drm_display_mode *mode2)
> +{
> if (mode1->hdisplay == mode2->hdisplay &&
> mode1->hsync_start == mode2->hsync_start &&
> mode1->hsync_end == mode2->hsync_end &&
> @@ -863,7 +881,7 @@ bool drm_mode_equal(const struct drm_display_mode *mode1, 
> const struct drm_displ
>
> return false;
>  }
> -EXPORT_SYMBOL(drm_mode_equal);
> +EXPORT_SYMBOL(drm_mode_equal_no_clocks);
>
>  /**
>   * drm_mode_validate_size - make sure modes adhere to size constraints
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index b85575b..836438d 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -922,6 +922,7 @@ 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(const struct drm_display_mode *mode1, const 
> struct drm_display_mode *mode2);
> +extern bool drm_mode_equal_no_clocks(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);
>
> --
> 1.8.1.5
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel



--
Paulo Zanoni


Re: [PATCH 2/4] drm: Add drm_mode_equal_no_clocks()

2013-04-17 Thread Paulo Zanoni
Hi

2013/4/17  ville.syrj...@linux.intel.com:
 From: Ville Syrjälä ville.syrj...@linux.intel.com

 drm_mode_equal_no_clocks() is like drm_mode_equal() except it doesn't
 compare the clock or vrefresh values. drm_mode_equal() is now
 implemented by first doing the clock checks, and then calling
 drm_mode_equal_no_clocks().

 Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com
 ---
  drivers/gpu/drm/drm_modes.c | 20 +++-
  include/drm/drm_crtc.h  |  1 +
  2 files changed, 20 insertions(+), 1 deletion(-)

 diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
 index 04fa6f1..db85d0b9 100644
 --- a/drivers/gpu/drm/drm_modes.c
 +++ b/drivers/gpu/drm/drm_modes.c
 @@ -848,6 +848,24 @@ bool drm_mode_equal(const struct drm_display_mode 
 *mode1, const struct drm_displ
 } else if (mode1-clock != mode2-clock)
 return false;

 +   return drm_mode_equal_no_clocks(mode1, mode2);
 +}

EXPORT_SYMBOL(drm_mode_equal) is gone. I'd also add a newline here.

 +/**
 + * drm_mode_equal_no_clocks - test modes for equality
 + * @mode1: first mode
 + * @mode2: second mode
 + *
 + * LOCKING:
 + * None.
 + *
 + * Check to see if @mode1 and @mode2 are equivalent, but
 + * don't check the pixel clocks.
 + *
 + * RETURNS:
 + * True if the modes are equal, false otherwise.
 + */
 +bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1, const 
 struct drm_display_mode *mode2)
 +{
 if (mode1-hdisplay == mode2-hdisplay 
 mode1-hsync_start == mode2-hsync_start 
 mode1-hsync_end == mode2-hsync_end 
 @@ -863,7 +881,7 @@ bool drm_mode_equal(const struct drm_display_mode *mode1, 
 const struct drm_displ

 return false;
  }
 -EXPORT_SYMBOL(drm_mode_equal);
 +EXPORT_SYMBOL(drm_mode_equal_no_clocks);

  /**
   * drm_mode_validate_size - make sure modes adhere to size constraints
 diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
 index b85575b..836438d 100644
 --- a/include/drm/drm_crtc.h
 +++ b/include/drm/drm_crtc.h
 @@ -922,6 +922,7 @@ 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(const struct drm_display_mode *mode1, const 
 struct drm_display_mode *mode2);
 +extern bool drm_mode_equal_no_clocks(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);

 --
 1.8.1.5

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



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


Re: [PATCH 0/4] drm/edid: Recognize 60Hz and 59.94Hz CEA modes

2013-04-17 Thread Paulo Zanoni
2013/4/17  ville.syrj...@linux.intel.com:
 This series attempts to make our CEA mode matching recognize both the
 60Hz and 59.94Hz variants of the modes (and similarly for 24/23.97,
 30/29.97, etc.).

 The benefits should include:
 - Send the correct VIC in the AVI infoframe
 - Pick the correct RGB quantization range in automatic mode

Everything looks correct, but I really didn't test anything. If you
apply my comments from patch 2, then you have Reviewed-by: Paulo
Zanoni paulo.r.zan...@intel.com for all the 4 patches.

Optional bikeshedding: you could add a follow-up patch fixing the
comments inside edid_cea_modes to reflect the correct Hz used,
replacing, for example, AxB@60Hz with AxB@59.94Hz. But I can
certainly live without this :)

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



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


[Intel-gfx] [PATCH 0/8] Enable eDP PSR functionality at HSW - v3

2013-02-28 Thread Paulo Zanoni
Hi

2013/2/25 Rodrigo Vivi :
> PSR is an eDP feature that allows power saving even with static image at eDP 
> screen.
>
> v3: Accepted many suggestions that I received at v2 review, fixing, cleaning 
> and improving the code.
>
> v2: Main differences in this v2:
> - Created vbt struct to get i915 dev_priv more organized and to avoid adding 
> more stuff into it.
> - migrated hsw macros to use transcoder instead of pipes than I could address 
> eDP
> - remove patch that was only adding edp psr registers and added them on demand
>
> v1:
> Shobit Kumar has implemented this patch series some time ago, but had no eDP 
> panel with PSR capability to test them.
>
> I could test and verify that this series fully identify PSR capability and 
> enables it at HSW.
> I also verified that it saves from 0.5-1W but only when in blank screen. It 
> seems it is not really entering in sleeping mode with static image at eDP 
> screen yet.

What do you mean with "blank screen"? It seems we disable PSR before
blanking the screen, so the 0.5-1W saving could be from the backlight.
Did you try masking more bits on the SRD_DEBUG register to see if it
enters PSR more easily? The first test I'd try would be to set 1 to
all those mask regs and see what happens (maybe we'll enter PSR and
never ever leave it again?).

>
> Please accept this series as the first part of PSR enabling while we continue 
> working to improve its functionality.
>
> Rodrigo Vivi (5):
>   drm/i915: Organize VBT stuff inside drm_i915_private
>   drm/i915: Use cpu_transcoder for HSW_TVIDEO_DIP_* instead of pipe
>   drm/i915: Enable/Disable PSR
>   drm/i915: Added debugfs support for PSR Status
>   drm/i915: Hook PSR functionality
>
> Shobhit Kumar (3):
>   drm/i915: Added SDP and VSC structures for handling PSR for eDP
>   drm/i915: Read the EDP DPCD and PSR Capability
>   drm/i915: VBT Parsing for the PSR Feature Block for HSW
>
>  drivers/gpu/drm/i915/i915_debugfs.c  |  92 
>  drivers/gpu/drm/i915/i915_dma.c  |   8 +-
>  drivers/gpu/drm/i915/i915_drv.h  |  63 ++-
>  drivers/gpu/drm/i915/i915_reg.h  |  82 --
>  drivers/gpu/drm/i915/intel_bios.c| 126 +
>  drivers/gpu/drm/i915/intel_bios.h|  20 +++-
>  drivers/gpu/drm/i915/intel_crt.c |   4 +-
>  drivers/gpu/drm/i915/intel_ddi.c |   2 +
>  drivers/gpu/drm/i915/intel_display.c |  16 +--
>  drivers/gpu/drm/i915/intel_dp.c  | 208 
> ++-
>  drivers/gpu/drm/i915/intel_drv.h |   4 +
>  drivers/gpu/drm/i915/intel_hdmi.c|  13 ++-
>  drivers/gpu/drm/i915/intel_lvds.c|  20 ++--
>  drivers/gpu/drm/i915/intel_sdvo.c|   6 +-
>  drivers/gpu/drm/i915/intel_tv.c  |   8 +-
>  include/drm/drm_dp_helper.h  |  22 
>  16 files changed, 569 insertions(+), 125 deletions(-)
>
> --
> 1.8.1.2
>
> ___
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni


[Intel-gfx] [PATCH 8/8] drm/i915: Hook PSR functionality

2013-02-28 Thread Paulo Zanoni
Hi

2013/2/25 Rodrigo Vivi :
> PSR must be enabled after transcoder and port are running.
> And it is only available for HSW.
>
> v2: move enable/disable to intel_ddi
>
> Signed-off-by: Rodrigo Vivi 
> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c 
> b/drivers/gpu/drm/i915/intel_ddi.c
> index 816c45c..bbfdcfd 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1321,6 +1321,7 @@ static void intel_enable_ddi(struct intel_encoder 
> *intel_encoder)
> struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
>
> ironlake_edp_backlight_on(intel_dp);
> +   intel_edp_enable_psr(intel_dp);
> }
>
> if (intel_crtc->eld_vld) {
> @@ -1345,6 +1346,7 @@ static void intel_disable_ddi(struct intel_encoder 
> *intel_encoder)
> struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
>
> ironlake_edp_backlight_off(intel_dp);
> +   intel_edp_disable_psr(intel_dp);

The spec suggests PSR should be disabled even before backlight (it
also suggests audio should be disabled before backlight, and I notice
this seems to be wrong in our code).

> }
>
> tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
> --
> 1.8.1.2
>
> ___
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni


[Intel-gfx] [PATCH 7/8] drm/i915: Added debugfs support for PSR Status

2013-02-28 Thread Paulo Zanoni
d(struct file *filp,
>  char __user *ubuf,
> @@ -2249,6 +2340,7 @@ static struct drm_info_list i915_debugfs_list[] = {
> {"i915_swizzle_info", i915_swizzle_info, 0},
> {"i915_ppgtt_info", i915_ppgtt_info, 0},
> {"i915_dpio", i915_dpio_info, 0},
> +   {"i915_edp_psr_status", i915_edp_psr_status, 0},
>  };
>  #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 1e31f23..1f7e666 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -1615,6 +1615,30 @@
>
>  #define EDP_PSR_STATUS_CTL 0x64840
>  #define   EDP_PSR_STATUS_STATE_MASK(7<<29)
> +#define   EDP_PSR_STATUS_STATE_IDLE(0<<29)
> +#define   EDP_PSR_STATUS_STATE_SRDONACK(1<<29)
> +#define   EDP_PSR_STATUS_STATE_SRDENT  (2<<29)
> +#define   EDP_PSR_STATUS_STATE_BUFOFF  (3<<29)
> +#define   EDP_PSR_STATUS_STATE_BUFON   (4<<29)
> +#define   EDP_PSR_STATUS_STATE_AUXACK  (5<<29)
> +#define   EDP_PSR_STATUS_STATE_SRDOFFACK   (6<<29)
> +#define   EDP_PSR_STATUS_LINK_MASK (3<<29)
> +#define   EDP_PSR_STATUS_LINK_FULL_OFF (0<<29)
> +#define   EDP_PSR_STATUS_LINK_FULL_ON  (1<<29)
> +#define   EDP_PSR_STATUS_LINK_STANDBY  (2<<29)

The 4 lines above are wrong. It's (x<<26).

> +#define   EDP_PSR_STATUS_MAX_SLEEP_TIMER_SHIFT 20
> +#define   EDP_PSR_STATUS_MAX_SLEEP_TIMER_MASK  0x1f
> +#define   EDP_PSR_STATUS_COUNT_SHIFT   16
> +#define   EDP_PSR_STATUS_COUNT_MASK0xf
> +#define   EDP_PSR_STATUS_AUX_ERROR (1<<15)
> +#define   EDP_PSR_STATUS_AUX_SENDING   (1<<12)
> +#define   EDP_PSR_STATUS_SENDING_IDLE  (1<<9)
> +#define   EDP_PSR_STATUS_SENDING_TP2_TP3   (1<<8)
> +#define   EDP_PSR_STATUS_SENDING_TP1   (1<<4)
> +#define   EDP_PSR_STATUS_IDLE_MASK 0xf
> +
> +#define EDP_PSR_PERF_CNT   0x64844
> +#define   EDP_PSR_PERF_CNT_MASK0xff
>
>  #define EDP_PSR_DEBUG_CTL  0x64860
>  #define   EDP_PSR_DEBUG_MASK_MEMUP (1<<26)
> --
> 1.8.1.2
>
> ___
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni


[Intel-gfx] [git pull] drm merge for 3.9-rc1

2013-02-28 Thread Paulo Zanoni
Hi

2013/2/28 Sedat Dilek :
> On Thu, Feb 28, 2013 at 6:12 PM, Sedat Dilek  wrote:
>> On Thu, Feb 28, 2013 at 3:31 PM, Paulo Zanoni  wrote:
>>> Hi
>>>
>>> 2013/2/28 Chris Wilson :
>>>> On Thu, Feb 28, 2013 at 12:06:28AM +0100, Sedat Dilek wrote:
>>>>> On Wed, Feb 27, 2013 at 11:36 PM, Sedat Dilek  
>>>>> wrote:
>>>>> > Hi,
>>>>> >
>>>>> > I am seeing this also on Linux-Next.
>>>>> >
>>>>> > /var/log/kern.log:Feb 27 22:52:35 fambox kernel: [   28.202381]
>>>>> > [drm:intel_dp_aux_wait_done] *ERROR* dp aux hw did not signal timeout
>>>>> > (has irq: 1)!
>>>>> > /var/log/kern.log:Feb 27 22:52:35 fambox kernel: [   28.210588]
>>>>> > [drm:intel_dp_aux_wait_done] *ERROR* dp aux hw did not signal timeout
>>>>> > (has irq: 1)!
>>>>> >
>>>>> > /var/log/kern.log.1:Feb 22 07:36:04 fambox kernel: [   27.408280]
>>>>> > [drm:intel_dp_aux_wait_done] *ERROR* dp aux hw did not signal timeout
>>>>> > (has irq: 1)!
>>>>> >
>>>>> > This seems to be hard reproducible...
>>>>> > Laptop-LCD... Sandybridge Mobile-GT2.
>>>>> >
>>>>> > Is there a way to force the error?
>>>>> >
>>>>> > Possible patch see [1].
>>>>> >
>>>>> > - Sedat -
>>>>> >
>>>>> > [1] https://patchwork.kernel.org/patch/2192721/
>>>>
>>>> That was:
>>>>
>>>> +   if (!done) {
>>>> +   status = I915_READ_NOTRACE(ch_ctl);
>>>> +   DRM_ERROR("dp aux hw did not signal timeout (has irq:
>>>> %i), status=%08x!\n",
>>>> + has_aux_irq, status);
>>>> +   }
>>>>
>>>> You applied
>>>>
>>>> +   if (!done) {
>>>> +   status = I915_READ_NOTRACE(ch_ctl);
>>>> +   DRM_ERROR("dp aux hw did not signal timeout (has irq:
>>>> %i), status=%08x!\n",
>>>> + has_aux_irq, status);
>>>> +   {
>>>
>>> In addition to this, after the problem happens can you please dump the
>>> registers 0x44008 (DEIIR) and 0xC4008 (SDEIIR)? You can do this either
>>> by running intel-reg-read (from intel-gpu-tools) or by changing the
>>> DRM_ERROR above to also print the result of I915_READ(0x44008) and
>>> I915_READ(0xC4008).
>>>
>>
>> Do I need a specific version of intel-gpu-tools?
>> Ubuntu/precise has v1.2 in its archives - sufficient?
>> Note: The error was twice after dozenz of Linux-Next kernel builds.
>>
>> - Sedat -
>>
>> [1] http://packages.ubuntu.com/precise/intel-gpu-tools
>>
>
> Installed intel-gpu-tools.
>
> # intel_reg_read
> Usage: intel_reg_read [-f | addr]
>  -f : read back full range of registers.
>   WARNING! This could be danger to hang the machine!
>  addr : in 0x format
>
> # intel_reg_read 0x44008
> Couldn't map MMIO region: Resource temporarily unavailable
>
> [  368.281707] intel_reg_read:3657 conflicting memory types
> f000-f040 uncached-minus<->write-combining
> [  381.521912] intel_reg_read:3658 conflicting memory types
> f000-f040 uncached-minus<->write-combining
> [  401.136291] intel_reg_read:3659 conflicting memory types
> f000-f040 uncached-minus<->write-combining
>
> Wrong i-g-t version? Missing enabled kernel-config option? Boot with
> i915 debug enabled?

Just build the version from git and it should work
(http://cgit.freedesktop.org/xorg/app/intel-gpu-tools/).

>
> - Sedat -
>
>>> If you conclude that the value of 0x44008 is 0x0 while the value of
>>> 0xC4008 is not, then this patch should help:
>>> https://patchwork.kernel.org/patch/2177841/
>>>
>>>>
>>>> That second '{' is the source of the compile error.
>>>> -Chris
>>>>
>>>> --
>>>> Chris Wilson, Intel Open Source Technology Centre
>>>> ___
>>>> Intel-gfx mailing list
>>>> Intel-gfx at lists.freedesktop.org
>>>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>>>
>>>
>>>
>>> --
>>> Paulo Zanoni



-- 
Paulo Zanoni


[Intel-gfx] [PATCH 6/8] drm/i915: Enable/Disable PSR

2013-02-28 Thread Paulo Zanoni
; i += 4) {
>> + I915_WRITE(data_reg + i, *data);
>> + data++;
>> + }
>> + /* Write every possible data byte to force correct ECC calculation. */
>> + for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
>> + I915_WRITE(data_reg + i, 0);
>> + mmiowb();
>> +
>> + val |= VIDEO_DIP_ENABLE_VSC_HSW;
>> + I915_WRITE(ctl_reg, val);
>> + POSTING_READ(ctl_reg);
>> +}
>> +
>> +void intel_edp_enable_psr(struct intel_dp* intel_dp)
>> +{
>> + struct drm_device *dev = intel_dp_to_dev(intel_dp);
>> + struct drm_i915_private *dev_priv = dev->dev_private;
>> + struct edp_vsc_psr psr_vsc;
>> + int msg_size = 5;   /* Header(4) + Message(1) */
>> +
>> + if (!is_edp_psr(intel_dp) || intel_edp_is_psr_enabled(intel_dp))
>> + return;
>> +
>> + /* Prepare VSC packet as per EDP 1.3 spec, Table 3.10 */
>> + memset(_vsc, 0, sizeof(psr_vsc));
>> + psr_vsc.sdp_header.id = 0;
>> + psr_vsc.sdp_header.type = 0x7;
>> + psr_vsc.sdp_header.revision = 0x2;
>> + psr_vsc.sdp_header.valid_payload_bytes = 0x8;
>> +
>> + intel_edp_write_vsc_psr(intel_dp, _vsc);
>> +
>> + /* Enable PSR in sink by setting bit 0 in DPCD config reg
>> +  * along with the transmitter state during PSR active
>> +  * Transmitter state later can be ready from VBT. As of now
>> +  * program the full link down
>> +  *
>> +  */
>> + intel_dp_aux_native_write_1(intel_dp, DP_PSR_EN_CFG,
>> + DP_PSR_ENABLE);
>> +
>> + /* Setup AUX registers */
>> + /* Write command on DPCD 0x0600 */
>> + I915_WRITE(EDP_PSR_AUX_DATA1, 0x8006);
>> +
>> + /* Set the state to normal operation D0 in DPCD 0x0600 */
>> + I915_WRITE(EDP_PSR_AUX_DATA2, 0x0100);
>> +
>> + I915_WRITE(EDP_PSR_AUX_CTL,
>> +msg_size << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT |
>> +I915_READ(DPA_AUX_CH_CTL));
>
> Would it be possible to make this stuff a bit more like the normal
> aux stuff? Maybe even share some code to set up the data? But then
> again it's just these few writes here, so I'm not sure it's worth
> the effort.
>
>> +
>> + /* Enable PSR on the host */
>> + intel_edp_psr_enable_src(intel_dp);
>> +
>> + /* WA: FBC/PSR Underrun/Corruption Workaround */
>> + I915_WRITE(HSW_FBC_CONTROL, ~FBC_CTL_EN);
>
> Are we expecting that BIOS left FBC enabled? Shouldn't we then disable
> it during resume?
>
>> +
>> + /* WA: Continuous PSR exit Workaround */
>> + I915_WRITE(EDP_PSR_DEBUG_CTL, EDP_PSR_DEBUG_MASK_MEMUP);
>
> Shouldn't this be done before enabling PSR?
>
>> + I915_WRITE(GEN6_PMINTRMSK, 0x);
>
> I can't find anything about this in bspec or WA db.
>
>> +}
>> +
>> +void intel_edp_disable_psr(struct intel_dp* intel_dp)
>> +{
>> + struct drm_device *dev = intel_dp_to_dev(intel_dp);
>> + struct drm_i915_private *dev_priv = dev->dev_private;
>> + struct intel_crtc *intel_crtc = 
>> to_intel_crtc(intel_dp_to_crtc(intel_dp));
>> + uint32_t reg = HSW_TVIDEO_DIP_CTL(intel_crtc->cpu_transcoder);
>> + uint32_t val;
>> +
>> + if (!intel_edp_is_psr_enabled(intel_dp))
>> + return;
>> +
>> + val = I915_READ(EDP_PSR_CTL);
>> + I915_WRITE(EDP_PSR_CTL, val & ~EDP_PSR_ENABLE);
>> +
>> + /* Wait till PSR is idle */
>> + if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL) &
>> +EDP_PSR_STATUS_STATE_MASK) == 0, 2000, 10))
>> + DRM_ERROR("Timed out waiting for PSR Idle State\n");
>> +
>> + intel_wait_for_vblank(dev, intel_crtc->pipe);
>> +
>> + val = I915_READ(reg);
>> + I915_WRITE(reg, val & ~VIDEO_DIP_ENABLE_VSC_HSW);
>> +}
>> +
>>  static void intel_enable_dp(struct intel_encoder *encoder)
>>  {
>>   struct intel_dp *intel_dp = enc_to_intel_dp(>base);
>> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
>> b/drivers/gpu/drm/i915/intel_drv.h
>> index 865ede6..cfda739 100644
>> --- a/drivers/gpu/drm/i915/intel_drv.h
>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>> @@ -696,4 +696,7 @@ extern bool
>>  intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
>>  extern void intel_ddi_fdi_disable(struct drm_crtc *crtc);
>>
>> +extern void intel_edp_enable_psr(struct intel_dp* intel_dp);
>> +extern void intel_edp_disable_psr(struct intel_dp* intel_dp);
>> +
>>  #endif /* __INTEL_DRV_H__ */
>> --
>> 1.8.1.2
>>
>> ___
>> dri-devel mailing list
>> dri-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
> --
> Ville Syrj?l?
> Intel OTC
> ___
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni


[PATCH 6/8] drm/i915: Enable/Disable PSR

2013-02-28 Thread Paulo Zanoni
t drm_i915_private *dev_priv = dev->dev_private;
> +   struct edp_vsc_psr psr_vsc;
> +   int msg_size = 5;   /* Header(4) + Message(1) */
> +
> +   if (!is_edp_psr(intel_dp) || intel_edp_is_psr_enabled(intel_dp))

Is it possible to have intel_edp_is_psr_enable here? If not, maybe WARN it.

> +   return;
> +
> +   /* Prepare VSC packet as per EDP 1.3 spec, Table 3.10 */
> +   memset(_vsc, 0, sizeof(psr_vsc));
> +   psr_vsc.sdp_header.id = 0;
> +   psr_vsc.sdp_header.type = 0x7;
> +   psr_vsc.sdp_header.revision = 0x2;
> +   psr_vsc.sdp_header.valid_payload_bytes = 0x8;
> +
> +   intel_edp_write_vsc_psr(intel_dp, _vsc);
> +
> +   /* Enable PSR in sink by setting bit 0 in DPCD config reg
> +* along with the transmitter state during PSR active
> +* Transmitter state later can be ready from VBT. As of now
> +* program the full link down

This comment is probably missing a few periods.

> +*
> +*/
> +   intel_dp_aux_native_write_1(intel_dp, DP_PSR_EN_CFG,
> +   DP_PSR_ENABLE);
> +
> +   /* Setup AUX registers */
> +   /* Write command on DPCD 0x0600 */
> +   I915_WRITE(EDP_PSR_AUX_DATA1, 0x8006);
> +
> +   /* Set the state to normal operation D0 in DPCD 0x0600 */
> +   I915_WRITE(EDP_PSR_AUX_DATA2, 0x0100);

I see the lines above match our spec, but I still think Jani's comment
from patch "drm/i915: Setup EDP PSR AUX Registers" is applicable here.

> +
> +   I915_WRITE(EDP_PSR_AUX_CTL,
> +  msg_size << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT |
> +  I915_READ(DPA_AUX_CH_CTL));

I don't think this is safe, especially since we're not erasing the
original msg size bits from DPA_AUX_CH_CTL. I think we should try to
set all the bits of this register without reading DPA_AUX_CH_CTL
(maybe extract some code from intel_dp_aux_ch into new functions and
call from both here and intel_dp_aux_ch).

Also, I still think you should patch intel_dp_aux_ch to put a WARN in
case EDP_PSR_CTL bit 31 is 1.

> +
> +   /* Enable PSR on the host */
> +   intel_edp_psr_enable_src(intel_dp);
> +
> +   /* WA: FBC/PSR Underrun/Corruption Workaround */
> +   I915_WRITE(HSW_FBC_CONTROL, ~FBC_CTL_EN);

This FBC WA won't be needed on real world Hardware.

> +
> +   /* WA: Continuous PSR exit Workaround */
> +   I915_WRITE(EDP_PSR_DEBUG_CTL, EDP_PSR_DEBUG_MASK_MEMUP);
> +   I915_WRITE(GEN6_PMINTRMSK, 0x);

All they ask is to "disabled unused interrupts", not "disable all interrupts".

> +}
> +
> +void intel_edp_disable_psr(struct intel_dp* intel_dp)
> +{
> +   struct drm_device *dev = intel_dp_to_dev(intel_dp);
> +   struct drm_i915_private *dev_priv = dev->dev_private;
> +   struct intel_crtc *intel_crtc = 
> to_intel_crtc(intel_dp_to_crtc(intel_dp));
> +   uint32_t reg = HSW_TVIDEO_DIP_CTL(intel_crtc->cpu_transcoder);
> +   uint32_t val;
> +
> +   if (!intel_edp_is_psr_enabled(intel_dp))

Is this possible? Should we WARN here?

> +   return;
> +
> +   val = I915_READ(EDP_PSR_CTL);
> +   I915_WRITE(EDP_PSR_CTL, val & ~EDP_PSR_ENABLE);
> +
> +   /* Wait till PSR is idle */
> +   if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL) &
> +  EDP_PSR_STATUS_STATE_MASK) == 0, 2000, 10))

Some big sleeps here. Can't we make them faster?

> +   DRM_ERROR("Timed out waiting for PSR Idle State\n");
> +
> +   intel_wait_for_vblank(dev, intel_crtc->pipe);
> +
> +   val = I915_READ(reg);
> +   I915_WRITE(reg, val & ~VIDEO_DIP_ENABLE_VSC_HSW);

So, based on this and on the spec, it means the HW will automagically
do the link training for us if it's needed?

> +}
> +
>  static void intel_enable_dp(struct intel_encoder *encoder)
>  {
> struct intel_dp *intel_dp = enc_to_intel_dp(>base);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
> b/drivers/gpu/drm/i915/intel_drv.h
> index 865ede6..cfda739 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -696,4 +696,7 @@ extern bool
>  intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
>  extern void intel_ddi_fdi_disable(struct drm_crtc *crtc);
>
> +extern void intel_edp_enable_psr(struct intel_dp* intel_dp);
> +extern void intel_edp_disable_psr(struct intel_dp* intel_dp);
> +
>  #endif /* __INTEL_DRV_H__ */
> --
> 1.8.1.2
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Paulo Zanoni


[Intel-gfx] [git pull] drm merge for 3.9-rc1

2013-02-28 Thread Paulo Zanoni
Hi

2013/2/28 Chris Wilson :
> On Thu, Feb 28, 2013 at 12:06:28AM +0100, Sedat Dilek wrote:
>> On Wed, Feb 27, 2013 at 11:36 PM, Sedat Dilek  
>> wrote:
>> > Hi,
>> >
>> > I am seeing this also on Linux-Next.
>> >
>> > /var/log/kern.log:Feb 27 22:52:35 fambox kernel: [   28.202381]
>> > [drm:intel_dp_aux_wait_done] *ERROR* dp aux hw did not signal timeout
>> > (has irq: 1)!
>> > /var/log/kern.log:Feb 27 22:52:35 fambox kernel: [   28.210588]
>> > [drm:intel_dp_aux_wait_done] *ERROR* dp aux hw did not signal timeout
>> > (has irq: 1)!
>> >
>> > /var/log/kern.log.1:Feb 22 07:36:04 fambox kernel: [   27.408280]
>> > [drm:intel_dp_aux_wait_done] *ERROR* dp aux hw did not signal timeout
>> > (has irq: 1)!
>> >
>> > This seems to be hard reproducible...
>> > Laptop-LCD... Sandybridge Mobile-GT2.
>> >
>> > Is there a way to force the error?
>> >
>> > Possible patch see [1].
>> >
>> > - Sedat -
>> >
>> > [1] https://patchwork.kernel.org/patch/2192721/
>
> That was:
>
> +   if (!done) {
> +   status = I915_READ_NOTRACE(ch_ctl);
> +   DRM_ERROR("dp aux hw did not signal timeout (has irq:
> %i), status=%08x!\n",
> + has_aux_irq, status);
> +   }
>
> You applied
>
> +   if (!done) {
> +   status = I915_READ_NOTRACE(ch_ctl);
> +   DRM_ERROR("dp aux hw did not signal timeout (has irq:
> %i), status=%08x!\n",
> + has_aux_irq, status);
> +   {

In addition to this, after the problem happens can you please dump the
registers 0x44008 (DEIIR) and 0xC4008 (SDEIIR)? You can do this either
by running intel-reg-read (from intel-gpu-tools) or by changing the
DRM_ERROR above to also print the result of I915_READ(0x44008) and
I915_READ(0xC4008).

If you conclude that the value of 0x44008 is 0x0 while the value of
0xC4008 is not, then this patch should help:
https://patchwork.kernel.org/patch/2177841/

>
> That second '{' is the source of the compile error.
> -Chris
>
> --
> Chris Wilson, Intel Open Source Technology Centre
> ___
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni


Re: [Intel-gfx] [git pull] drm merge for 3.9-rc1

2013-02-28 Thread Paulo Zanoni
Hi

2013/2/28 Chris Wilson ch...@chris-wilson.co.uk:
 On Thu, Feb 28, 2013 at 12:06:28AM +0100, Sedat Dilek wrote:
 On Wed, Feb 27, 2013 at 11:36 PM, Sedat Dilek sedat.di...@gmail.com wrote:
  Hi,
 
  I am seeing this also on Linux-Next.
 
  /var/log/kern.log:Feb 27 22:52:35 fambox kernel: [   28.202381]
  [drm:intel_dp_aux_wait_done] *ERROR* dp aux hw did not signal timeout
  (has irq: 1)!
  /var/log/kern.log:Feb 27 22:52:35 fambox kernel: [   28.210588]
  [drm:intel_dp_aux_wait_done] *ERROR* dp aux hw did not signal timeout
  (has irq: 1)!
 
  /var/log/kern.log.1:Feb 22 07:36:04 fambox kernel: [   27.408280]
  [drm:intel_dp_aux_wait_done] *ERROR* dp aux hw did not signal timeout
  (has irq: 1)!
 
  This seems to be hard reproducible...
  Laptop-LCD... Sandybridge Mobile-GT2.
 
  Is there a way to force the error?
 
  Possible patch see [1].
 
  - Sedat -
 
  [1] https://patchwork.kernel.org/patch/2192721/

 That was:

 +   if (!done) {
 +   status = I915_READ_NOTRACE(ch_ctl);
 +   DRM_ERROR(dp aux hw did not signal timeout (has irq:
 %i), status=%08x!\n,
 + has_aux_irq, status);
 +   }

 You applied

 +   if (!done) {
 +   status = I915_READ_NOTRACE(ch_ctl);
 +   DRM_ERROR(dp aux hw did not signal timeout (has irq:
 %i), status=%08x!\n,
 + has_aux_irq, status);
 +   {

In addition to this, after the problem happens can you please dump the
registers 0x44008 (DEIIR) and 0xC4008 (SDEIIR)? You can do this either
by running intel-reg-read (from intel-gpu-tools) or by changing the
DRM_ERROR above to also print the result of I915_READ(0x44008) and
I915_READ(0xC4008).

If you conclude that the value of 0x44008 is 0x0 while the value of
0xC4008 is not, then this patch should help:
https://patchwork.kernel.org/patch/2177841/


 That second '{' is the source of the compile error.
 -Chris

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



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


Re: [PATCH 6/8] drm/i915: Enable/Disable PSR

2013-02-28 Thread Paulo Zanoni
, DP_PSR_EN_CFG,
 +   DP_PSR_ENABLE);
 +
 +   /* Setup AUX registers */
 +   /* Write command on DPCD 0x0600 */
 +   I915_WRITE(EDP_PSR_AUX_DATA1, 0x8006);
 +
 +   /* Set the state to normal operation D0 in DPCD 0x0600 */
 +   I915_WRITE(EDP_PSR_AUX_DATA2, 0x0100);

I see the lines above match our spec, but I still think Jani's comment
from patch drm/i915: Setup EDP PSR AUX Registers is applicable here.

 +
 +   I915_WRITE(EDP_PSR_AUX_CTL,
 +  msg_size  DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT |
 +  I915_READ(DPA_AUX_CH_CTL));

I don't think this is safe, especially since we're not erasing the
original msg size bits from DPA_AUX_CH_CTL. I think we should try to
set all the bits of this register without reading DPA_AUX_CH_CTL
(maybe extract some code from intel_dp_aux_ch into new functions and
call from both here and intel_dp_aux_ch).

Also, I still think you should patch intel_dp_aux_ch to put a WARN in
case EDP_PSR_CTL bit 31 is 1.

 +
 +   /* Enable PSR on the host */
 +   intel_edp_psr_enable_src(intel_dp);
 +
 +   /* WA: FBC/PSR Underrun/Corruption Workaround */
 +   I915_WRITE(HSW_FBC_CONTROL, ~FBC_CTL_EN);

This FBC WA won't be needed on real world Hardware.

 +
 +   /* WA: Continuous PSR exit Workaround */
 +   I915_WRITE(EDP_PSR_DEBUG_CTL, EDP_PSR_DEBUG_MASK_MEMUP);
 +   I915_WRITE(GEN6_PMINTRMSK, 0x);

All they ask is to disabled unused interrupts, not disable all interrupts.

 +}
 +
 +void intel_edp_disable_psr(struct intel_dp* intel_dp)
 +{
 +   struct drm_device *dev = intel_dp_to_dev(intel_dp);
 +   struct drm_i915_private *dev_priv = dev-dev_private;
 +   struct intel_crtc *intel_crtc = 
 to_intel_crtc(intel_dp_to_crtc(intel_dp));
 +   uint32_t reg = HSW_TVIDEO_DIP_CTL(intel_crtc-cpu_transcoder);
 +   uint32_t val;
 +
 +   if (!intel_edp_is_psr_enabled(intel_dp))

Is this possible? Should we WARN here?

 +   return;
 +
 +   val = I915_READ(EDP_PSR_CTL);
 +   I915_WRITE(EDP_PSR_CTL, val  ~EDP_PSR_ENABLE);
 +
 +   /* Wait till PSR is idle */
 +   if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL) 
 +  EDP_PSR_STATUS_STATE_MASK) == 0, 2000, 10))

Some big sleeps here. Can't we make them faster?

 +   DRM_ERROR(Timed out waiting for PSR Idle State\n);
 +
 +   intel_wait_for_vblank(dev, intel_crtc-pipe);
 +
 +   val = I915_READ(reg);
 +   I915_WRITE(reg, val  ~VIDEO_DIP_ENABLE_VSC_HSW);

So, based on this and on the spec, it means the HW will automagically
do the link training for us if it's needed?

 +}
 +
  static void intel_enable_dp(struct intel_encoder *encoder)
  {
 struct intel_dp *intel_dp = enc_to_intel_dp(encoder-base);
 diff --git a/drivers/gpu/drm/i915/intel_drv.h 
 b/drivers/gpu/drm/i915/intel_drv.h
 index 865ede6..cfda739 100644
 --- a/drivers/gpu/drm/i915/intel_drv.h
 +++ b/drivers/gpu/drm/i915/intel_drv.h
 @@ -696,4 +696,7 @@ extern bool
  intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
  extern void intel_ddi_fdi_disable(struct drm_crtc *crtc);

 +extern void intel_edp_enable_psr(struct intel_dp* intel_dp);
 +extern void intel_edp_disable_psr(struct intel_dp* intel_dp);
 +
  #endif /* __INTEL_DRV_H__ */
 --
 1.8.1.2

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



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


Re: [Intel-gfx] [PATCH 6/8] drm/i915: Enable/Disable PSR

2013-02-28 Thread Paulo Zanoni
  DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT |
 +I915_READ(DPA_AUX_CH_CTL));

 Would it be possible to make this stuff a bit more like the normal
 aux stuff? Maybe even share some code to set up the data? But then
 again it's just these few writes here, so I'm not sure it's worth
 the effort.

 +
 + /* Enable PSR on the host */
 + intel_edp_psr_enable_src(intel_dp);
 +
 + /* WA: FBC/PSR Underrun/Corruption Workaround */
 + I915_WRITE(HSW_FBC_CONTROL, ~FBC_CTL_EN);

 Are we expecting that BIOS left FBC enabled? Shouldn't we then disable
 it during resume?

 +
 + /* WA: Continuous PSR exit Workaround */
 + I915_WRITE(EDP_PSR_DEBUG_CTL, EDP_PSR_DEBUG_MASK_MEMUP);

 Shouldn't this be done before enabling PSR?

 + I915_WRITE(GEN6_PMINTRMSK, 0x);

 I can't find anything about this in bspec or WA db.

 +}
 +
 +void intel_edp_disable_psr(struct intel_dp* intel_dp)
 +{
 + struct drm_device *dev = intel_dp_to_dev(intel_dp);
 + struct drm_i915_private *dev_priv = dev-dev_private;
 + struct intel_crtc *intel_crtc = 
 to_intel_crtc(intel_dp_to_crtc(intel_dp));
 + uint32_t reg = HSW_TVIDEO_DIP_CTL(intel_crtc-cpu_transcoder);
 + uint32_t val;
 +
 + if (!intel_edp_is_psr_enabled(intel_dp))
 + return;
 +
 + val = I915_READ(EDP_PSR_CTL);
 + I915_WRITE(EDP_PSR_CTL, val  ~EDP_PSR_ENABLE);
 +
 + /* Wait till PSR is idle */
 + if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL) 
 +EDP_PSR_STATUS_STATE_MASK) == 0, 2000, 10))
 + DRM_ERROR(Timed out waiting for PSR Idle State\n);
 +
 + intel_wait_for_vblank(dev, intel_crtc-pipe);
 +
 + val = I915_READ(reg);
 + I915_WRITE(reg, val  ~VIDEO_DIP_ENABLE_VSC_HSW);
 +}
 +
  static void intel_enable_dp(struct intel_encoder *encoder)
  {
   struct intel_dp *intel_dp = enc_to_intel_dp(encoder-base);
 diff --git a/drivers/gpu/drm/i915/intel_drv.h 
 b/drivers/gpu/drm/i915/intel_drv.h
 index 865ede6..cfda739 100644
 --- a/drivers/gpu/drm/i915/intel_drv.h
 +++ b/drivers/gpu/drm/i915/intel_drv.h
 @@ -696,4 +696,7 @@ extern bool
  intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
  extern void intel_ddi_fdi_disable(struct drm_crtc *crtc);

 +extern void intel_edp_enable_psr(struct intel_dp* intel_dp);
 +extern void intel_edp_disable_psr(struct intel_dp* intel_dp);
 +
  #endif /* __INTEL_DRV_H__ */
 --
 1.8.1.2

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

 --
 Ville Syrjälä
 Intel OTC
 ___
 Intel-gfx mailing list
 intel-...@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/intel-gfx



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


Re: [Intel-gfx] [git pull] drm merge for 3.9-rc1

2013-02-28 Thread Paulo Zanoni
Hi

2013/2/28 Sedat Dilek sedat.di...@gmail.com:
 On Thu, Feb 28, 2013 at 6:12 PM, Sedat Dilek sedat.di...@gmail.com wrote:
 On Thu, Feb 28, 2013 at 3:31 PM, Paulo Zanoni przan...@gmail.com wrote:
 Hi

 2013/2/28 Chris Wilson ch...@chris-wilson.co.uk:
 On Thu, Feb 28, 2013 at 12:06:28AM +0100, Sedat Dilek wrote:
 On Wed, Feb 27, 2013 at 11:36 PM, Sedat Dilek sedat.di...@gmail.com 
 wrote:
  Hi,
 
  I am seeing this also on Linux-Next.
 
  /var/log/kern.log:Feb 27 22:52:35 fambox kernel: [   28.202381]
  [drm:intel_dp_aux_wait_done] *ERROR* dp aux hw did not signal timeout
  (has irq: 1)!
  /var/log/kern.log:Feb 27 22:52:35 fambox kernel: [   28.210588]
  [drm:intel_dp_aux_wait_done] *ERROR* dp aux hw did not signal timeout
  (has irq: 1)!
 
  /var/log/kern.log.1:Feb 22 07:36:04 fambox kernel: [   27.408280]
  [drm:intel_dp_aux_wait_done] *ERROR* dp aux hw did not signal timeout
  (has irq: 1)!
 
  This seems to be hard reproducible...
  Laptop-LCD... Sandybridge Mobile-GT2.
 
  Is there a way to force the error?
 
  Possible patch see [1].
 
  - Sedat -
 
  [1] https://patchwork.kernel.org/patch/2192721/

 That was:

 +   if (!done) {
 +   status = I915_READ_NOTRACE(ch_ctl);
 +   DRM_ERROR(dp aux hw did not signal timeout (has irq:
 %i), status=%08x!\n,
 + has_aux_irq, status);
 +   }

 You applied

 +   if (!done) {
 +   status = I915_READ_NOTRACE(ch_ctl);
 +   DRM_ERROR(dp aux hw did not signal timeout (has irq:
 %i), status=%08x!\n,
 + has_aux_irq, status);
 +   {

 In addition to this, after the problem happens can you please dump the
 registers 0x44008 (DEIIR) and 0xC4008 (SDEIIR)? You can do this either
 by running intel-reg-read (from intel-gpu-tools) or by changing the
 DRM_ERROR above to also print the result of I915_READ(0x44008) and
 I915_READ(0xC4008).


 Do I need a specific version of intel-gpu-tools?
 Ubuntu/precise has v1.2 in its archives - sufficient?
 Note: The error was twice after dozenz of Linux-Next kernel builds.

 - Sedat -

 [1] http://packages.ubuntu.com/precise/intel-gpu-tools


 Installed intel-gpu-tools.

 # intel_reg_read
 Usage: intel_reg_read [-f | addr]
  -f : read back full range of registers.
   WARNING! This could be danger to hang the machine!
  addr : in 0x format

 # intel_reg_read 0x44008
 Couldn't map MMIO region: Resource temporarily unavailable

 [  368.281707] intel_reg_read:3657 conflicting memory types
 f000-f040 uncached-minus-write-combining
 [  381.521912] intel_reg_read:3658 conflicting memory types
 f000-f040 uncached-minus-write-combining
 [  401.136291] intel_reg_read:3659 conflicting memory types
 f000-f040 uncached-minus-write-combining

 Wrong i-g-t version? Missing enabled kernel-config option? Boot with
 i915 debug enabled?

Just build the version from git and it should work
(http://cgit.freedesktop.org/xorg/app/intel-gpu-tools/).


 - Sedat -

 If you conclude that the value of 0x44008 is 0x0 while the value of
 0xC4008 is not, then this patch should help:
 https://patchwork.kernel.org/patch/2177841/


 That second '{' is the source of the compile error.
 -Chris

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



 --
 Paulo Zanoni



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


Re: [Intel-gfx] [PATCH 7/8] drm/i915: Added debugfs support for PSR Status

2013-02-28 Thread Paulo Zanoni
   EDP_PSR_STATUS_STATE_SRDONACK(129)
 +#define   EDP_PSR_STATUS_STATE_SRDENT  (229)
 +#define   EDP_PSR_STATUS_STATE_BUFOFF  (329)
 +#define   EDP_PSR_STATUS_STATE_BUFON   (429)
 +#define   EDP_PSR_STATUS_STATE_AUXACK  (529)
 +#define   EDP_PSR_STATUS_STATE_SRDOFFACK   (629)
 +#define   EDP_PSR_STATUS_LINK_MASK (329)
 +#define   EDP_PSR_STATUS_LINK_FULL_OFF (029)
 +#define   EDP_PSR_STATUS_LINK_FULL_ON  (129)
 +#define   EDP_PSR_STATUS_LINK_STANDBY  (229)

The 4 lines above are wrong. It's (x26).

 +#define   EDP_PSR_STATUS_MAX_SLEEP_TIMER_SHIFT 20
 +#define   EDP_PSR_STATUS_MAX_SLEEP_TIMER_MASK  0x1f
 +#define   EDP_PSR_STATUS_COUNT_SHIFT   16
 +#define   EDP_PSR_STATUS_COUNT_MASK0xf
 +#define   EDP_PSR_STATUS_AUX_ERROR (115)
 +#define   EDP_PSR_STATUS_AUX_SENDING   (112)
 +#define   EDP_PSR_STATUS_SENDING_IDLE  (19)
 +#define   EDP_PSR_STATUS_SENDING_TP2_TP3   (18)
 +#define   EDP_PSR_STATUS_SENDING_TP1   (14)
 +#define   EDP_PSR_STATUS_IDLE_MASK 0xf
 +
 +#define EDP_PSR_PERF_CNT   0x64844
 +#define   EDP_PSR_PERF_CNT_MASK0xff

  #define EDP_PSR_DEBUG_CTL  0x64860
  #define   EDP_PSR_DEBUG_MASK_MEMUP (126)
 --
 1.8.1.2

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



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


Re: [Intel-gfx] [PATCH 8/8] drm/i915: Hook PSR functionality

2013-02-28 Thread Paulo Zanoni
Hi

2013/2/25 Rodrigo Vivi rodrigo.v...@gmail.com:
 PSR must be enabled after transcoder and port are running.
 And it is only available for HSW.

 v2: move enable/disable to intel_ddi

 Signed-off-by: Rodrigo Vivi rodrigo.v...@gmail.com
 ---
  drivers/gpu/drm/i915/intel_ddi.c | 2 ++
  1 file changed, 2 insertions(+)

 diff --git a/drivers/gpu/drm/i915/intel_ddi.c 
 b/drivers/gpu/drm/i915/intel_ddi.c
 index 816c45c..bbfdcfd 100644
 --- a/drivers/gpu/drm/i915/intel_ddi.c
 +++ b/drivers/gpu/drm/i915/intel_ddi.c
 @@ -1321,6 +1321,7 @@ static void intel_enable_ddi(struct intel_encoder 
 *intel_encoder)
 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);

 ironlake_edp_backlight_on(intel_dp);
 +   intel_edp_enable_psr(intel_dp);
 }

 if (intel_crtc-eld_vld) {
 @@ -1345,6 +1346,7 @@ static void intel_disable_ddi(struct intel_encoder 
 *intel_encoder)
 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);

 ironlake_edp_backlight_off(intel_dp);
 +   intel_edp_disable_psr(intel_dp);

The spec suggests PSR should be disabled even before backlight (it
also suggests audio should be disabled before backlight, and I notice
this seems to be wrong in our code).

 }

 tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
 --
 1.8.1.2

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



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


Re: [Intel-gfx] [PATCH 0/8] Enable eDP PSR functionality at HSW - v3

2013-02-28 Thread Paulo Zanoni
Hi

2013/2/25 Rodrigo Vivi rodrigo.v...@gmail.com:
 PSR is an eDP feature that allows power saving even with static image at eDP 
 screen.

 v3: Accepted many suggestions that I received at v2 review, fixing, cleaning 
 and improving the code.

 v2: Main differences in this v2:
 - Created vbt struct to get i915 dev_priv more organized and to avoid adding 
 more stuff into it.
 - migrated hsw macros to use transcoder instead of pipes than I could address 
 eDP
 - remove patch that was only adding edp psr registers and added them on demand

 v1:
 Shobit Kumar has implemented this patch series some time ago, but had no eDP 
 panel with PSR capability to test them.

 I could test and verify that this series fully identify PSR capability and 
 enables it at HSW.
 I also verified that it saves from 0.5-1W but only when in blank screen. It 
 seems it is not really entering in sleeping mode with static image at eDP 
 screen yet.

What do you mean with blank screen? It seems we disable PSR before
blanking the screen, so the 0.5-1W saving could be from the backlight.
Did you try masking more bits on the SRD_DEBUG register to see if it
enters PSR more easily? The first test I'd try would be to set 1 to
all those mask regs and see what happens (maybe we'll enter PSR and
never ever leave it again?).


 Please accept this series as the first part of PSR enabling while we continue 
 working to improve its functionality.

 Rodrigo Vivi (5):
   drm/i915: Organize VBT stuff inside drm_i915_private
   drm/i915: Use cpu_transcoder for HSW_TVIDEO_DIP_* instead of pipe
   drm/i915: Enable/Disable PSR
   drm/i915: Added debugfs support for PSR Status
   drm/i915: Hook PSR functionality

 Shobhit Kumar (3):
   drm/i915: Added SDP and VSC structures for handling PSR for eDP
   drm/i915: Read the EDP DPCD and PSR Capability
   drm/i915: VBT Parsing for the PSR Feature Block for HSW

  drivers/gpu/drm/i915/i915_debugfs.c  |  92 
  drivers/gpu/drm/i915/i915_dma.c  |   8 +-
  drivers/gpu/drm/i915/i915_drv.h  |  63 ++-
  drivers/gpu/drm/i915/i915_reg.h  |  82 --
  drivers/gpu/drm/i915/intel_bios.c| 126 +
  drivers/gpu/drm/i915/intel_bios.h|  20 +++-
  drivers/gpu/drm/i915/intel_crt.c |   4 +-
  drivers/gpu/drm/i915/intel_ddi.c |   2 +
  drivers/gpu/drm/i915/intel_display.c |  16 +--
  drivers/gpu/drm/i915/intel_dp.c  | 208 
 ++-
  drivers/gpu/drm/i915/intel_drv.h |   4 +
  drivers/gpu/drm/i915/intel_hdmi.c|  13 ++-
  drivers/gpu/drm/i915/intel_lvds.c|  20 ++--
  drivers/gpu/drm/i915/intel_sdvo.c|   6 +-
  drivers/gpu/drm/i915/intel_tv.c  |   8 +-
  include/drm/drm_dp_helper.h  |  22 
  16 files changed, 569 insertions(+), 125 deletions(-)

 --
 1.8.1.2

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



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


[Intel-gfx] [PATCH 3/8] drm/i915: Added SDP and VSC structures for handling PSR for eDP

2013-02-27 Thread Paulo Zanoni
Hi

2013/2/25 Rodrigo Vivi :
> From: Shobhit Kumar 
>
> Signed-off-by: Sateesh Kavuri 
>
> v2: Modified and corrected the structures to be more in line for
> kernel coding guidelines and rebased the code on Paulo's DP patchset
>
> Signed-off-by: Shobhit Kumar 
>
> v3: removing unecessary identation at DP_RECEIVER_CAP_SIZE
> v4: moving them to include/drm/drm_dp_helper.h and also already
> icluding EDP_PSR_RECEIVER_CAP_SIZE to add everything needed
> for PSR at once at drm_dp_helper.h
>
> Signed-off-by: Rodrigo Vivi 

I'd group all Signed-off-by tags at the bottom :)

> ---
>  include/drm/drm_dp_helper.h | 22 ++
>  1 file changed, 22 insertions(+)
>
> diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> index e8e1417..06c5060 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -343,12 +343,34 @@ u8 drm_dp_get_adjust_request_pre_emphasis(u8 
> link_status[DP_LINK_STATUS_SIZE],
>   int lane);
>
>  #define DP_RECEIVER_CAP_SIZE   0xf
> +#define EDP_PSR_RECEIVER_CAP_SIZE  2

I know I'll sound annoying, but my OCD will kill me if I don't tell
you that the line above uses tab and you use spaces.

> +
>  void drm_dp_link_train_clock_recovery_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]);
>  void drm_dp_link_train_channel_eq_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]);
>
>  u8 drm_dp_link_rate_to_bw_code(int link_rate);
>  int drm_dp_bw_code_to_link_rate(u8 link_bw);
>
> +/* SDP header as per eDP 1.3 spec, section 3.6 */
> +struct edp_sdp_header {
> +   u8 id;
> +   u8 type;
> +   u8 revision;
> +   u8 valid_payload_bytes;
> +} __attribute__((packed));

I think Jani's suggestion on the previous review still applies. How
about something like the following?

u8 id;
u8 type;
u8 hb2; /* 7:5 reserved, 4:0 revision number */
u8 hb3; /* 7:5 reserved, 4:0 number of valid data bytes */

And then something like this:
#define EDP_SDP_HEADER_REVISION_MASK 0x1F
#define EDP_SDP_HEADER_VALID_PAYLOAD_BYTES 0x1F

Also, checkpath.pl complains:
WARNING: __packed is preferred over __attribute__((packed))

> +
> +/* SDP VSC header as per eDP 1.3 spec, section 3.6 */
> +struct edp_vsc_psr {
> +   struct edp_sdp_header sdp_header;

Where's DB0? Its description is on DP spec version 1.2, chapter 2.2.5.6

> +   u8 DB1; /* 0 - PSR State; 1 - Update RFB; 2 - CRC Valid*/
> +   u8 DB2; /* CRC value bits 7:0 of the R or Cr component */
> +   u8 DB3; /* CRC value bits 15:8 of the R or Cr component */
> +   u8 DB4; /* CRC value bits 7:0 of the G or Y component */
> +   u8 DB5; /* CRC value bits 15:8 of the G or Y component */
> +   u8 DB6; /* CRC value bits 7:0 of the B or Cb component */
> +   u8 DB7; /* CRC value bits 15:8 of the B or Cb component */
> +} __attribute__((packed));

And here some more defines to access the individual byte fields would
be cool, like:

#define EDP_VSC_PSR_STATE_ACTIVE 1
#define EDP_VSC_PSR_RFB_UPDATE (1 << 1)
etc.

> +
>  static inline int
>  drm_dp_max_link_rate(u8 dpcd[DP_RECEIVER_CAP_SIZE])
>  {
> --
> 1.8.1.2
>
> ___
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni


[Intel-gfx] [PATCH 2/8] drm/i915: Use cpu_transcoder for HSW_TVIDEO_DIP_* instead of pipe

2013-02-27 Thread Paulo Zanoni
Hi

2013/2/25 Rodrigo Vivi :
> While old platforms had 3 transcoders and 3 pipes (1:1), HSW has
> 4 transcoders and 3 pipes.
> These regs were being used only by HDMI code where pipe is always the same
> thing as cpu_transcoder.
> This patch allow us to use them for DP, specially for TRANSCODER_EDP.
>
> v2: Adding HSW_TVIDEO_DIP_VSC_DATA to transmit vsc to eDP.
>
> Signed-off-by: Rodrigo Vivi 

Reviewed-by: Paulo Zanoni 

> ---
>  drivers/gpu/drm/i915/i915_reg.h   | 18 ++
>  drivers/gpu/drm/i915/intel_hdmi.c | 13 +++--
>  2 files changed, 17 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 527b664..b715ecd 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -3754,14 +3754,16 @@
>  #define HSW_VIDEO_DIP_VSC_ECC_B0x61344
>  #define HSW_VIDEO_DIP_GCP_B0x61210
>
> -#define HSW_TVIDEO_DIP_CTL(pipe) \
> -_PIPE(pipe, HSW_VIDEO_DIP_CTL_A, HSW_VIDEO_DIP_CTL_B)
> -#define HSW_TVIDEO_DIP_AVI_DATA(pipe) \
> -_PIPE(pipe, HSW_VIDEO_DIP_AVI_DATA_A, HSW_VIDEO_DIP_AVI_DATA_B)
> -#define HSW_TVIDEO_DIP_SPD_DATA(pipe) \
> -_PIPE(pipe, HSW_VIDEO_DIP_SPD_DATA_A, HSW_VIDEO_DIP_SPD_DATA_B)
> -#define HSW_TVIDEO_DIP_GCP(pipe) \
> -   _PIPE(pipe, HSW_VIDEO_DIP_GCP_A, HSW_VIDEO_DIP_GCP_B)
> +#define HSW_TVIDEO_DIP_CTL(trans) \
> +_TRANSCODER(trans, HSW_VIDEO_DIP_CTL_A, HSW_VIDEO_DIP_CTL_B)
> +#define HSW_TVIDEO_DIP_AVI_DATA(trans) \
> +_TRANSCODER(trans, HSW_VIDEO_DIP_AVI_DATA_A, 
> HSW_VIDEO_DIP_AVI_DATA_B)
> +#define HSW_TVIDEO_DIP_SPD_DATA(trans) \
> +_TRANSCODER(trans, HSW_VIDEO_DIP_SPD_DATA_A, 
> HSW_VIDEO_DIP_SPD_DATA_B)
> +#define HSW_TVIDEO_DIP_GCP(trans) \
> +   _TRANSCODER(trans, HSW_VIDEO_DIP_GCP_A, HSW_VIDEO_DIP_GCP_B)
> +#define HSW_TVIDEO_DIP_VSC_DATA(trans) \
> +_TRANSCODER(trans, HSW_VIDEO_DIP_VSC_DATA_A, 
> HSW_VIDEO_DIP_VSC_DATA_B)
>
>  #define _TRANS_HTOTAL_B  0xe1000
>  #define _TRANS_HBLANK_B  0xe1004
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
> b/drivers/gpu/drm/i915/intel_hdmi.c
> index 5a6138c..26290c1 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -120,13 +120,14 @@ static u32 hsw_infoframe_enable(struct dip_infoframe 
> *frame)
> }
>  }
>
> -static u32 hsw_infoframe_data_reg(struct dip_infoframe *frame, enum pipe 
> pipe)
> +static u32 hsw_infoframe_data_reg(struct dip_infoframe *frame,
> + enum transcoder cpu_transcoder)
>  {
> switch (frame->type) {
> case DIP_TYPE_AVI:
> -   return HSW_TVIDEO_DIP_AVI_DATA(pipe);
> +   return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder);
> case DIP_TYPE_SPD:
> -   return HSW_TVIDEO_DIP_SPD_DATA(pipe);
> +   return HSW_TVIDEO_DIP_SPD_DATA(cpu_transcoder);
> default:
> DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type);
> return 0;
> @@ -293,8 +294,8 @@ static void hsw_write_infoframe(struct drm_encoder 
> *encoder,
> struct drm_device *dev = encoder->dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
> -   u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->pipe);
> -   u32 data_reg = hsw_infoframe_data_reg(frame, intel_crtc->pipe);
> +   u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->cpu_transcoder);
> +   u32 data_reg = hsw_infoframe_data_reg(frame, 
> intel_crtc->cpu_transcoder);
> unsigned int i, len = DIP_HEADER_SIZE + frame->len;
> u32 val = I915_READ(ctl_reg);
>
> @@ -568,7 +569,7 @@ static void hsw_set_infoframes(struct drm_encoder 
> *encoder,
> struct drm_i915_private *dev_priv = encoder->dev->dev_private;
> struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
> struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
> -   u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc->pipe);
> +   u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc->cpu_transcoder);
> u32 val = I915_READ(reg);
>
> assert_hdmi_port_disabled(intel_hdmi);
> --
> 1.8.1.2
>
> ___
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni


Re: [Intel-gfx] [PATCH 2/8] drm/i915: Use cpu_transcoder for HSW_TVIDEO_DIP_* instead of pipe

2013-02-27 Thread Paulo Zanoni
Hi

2013/2/25 Rodrigo Vivi rodrigo.v...@gmail.com:
 While old platforms had 3 transcoders and 3 pipes (1:1), HSW has
 4 transcoders and 3 pipes.
 These regs were being used only by HDMI code where pipe is always the same
 thing as cpu_transcoder.
 This patch allow us to use them for DP, specially for TRANSCODER_EDP.

 v2: Adding HSW_TVIDEO_DIP_VSC_DATA to transmit vsc to eDP.

 Signed-off-by: Rodrigo Vivi rodrigo.v...@gmail.com

Reviewed-by: Paulo Zanoni paulo.r.zan...@intel.com

 ---
  drivers/gpu/drm/i915/i915_reg.h   | 18 ++
  drivers/gpu/drm/i915/intel_hdmi.c | 13 +++--
  2 files changed, 17 insertions(+), 14 deletions(-)

 diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
 index 527b664..b715ecd 100644
 --- a/drivers/gpu/drm/i915/i915_reg.h
 +++ b/drivers/gpu/drm/i915/i915_reg.h
 @@ -3754,14 +3754,16 @@
  #define HSW_VIDEO_DIP_VSC_ECC_B0x61344
  #define HSW_VIDEO_DIP_GCP_B0x61210

 -#define HSW_TVIDEO_DIP_CTL(pipe) \
 -_PIPE(pipe, HSW_VIDEO_DIP_CTL_A, HSW_VIDEO_DIP_CTL_B)
 -#define HSW_TVIDEO_DIP_AVI_DATA(pipe) \
 -_PIPE(pipe, HSW_VIDEO_DIP_AVI_DATA_A, HSW_VIDEO_DIP_AVI_DATA_B)
 -#define HSW_TVIDEO_DIP_SPD_DATA(pipe) \
 -_PIPE(pipe, HSW_VIDEO_DIP_SPD_DATA_A, HSW_VIDEO_DIP_SPD_DATA_B)
 -#define HSW_TVIDEO_DIP_GCP(pipe) \
 -   _PIPE(pipe, HSW_VIDEO_DIP_GCP_A, HSW_VIDEO_DIP_GCP_B)
 +#define HSW_TVIDEO_DIP_CTL(trans) \
 +_TRANSCODER(trans, HSW_VIDEO_DIP_CTL_A, HSW_VIDEO_DIP_CTL_B)
 +#define HSW_TVIDEO_DIP_AVI_DATA(trans) \
 +_TRANSCODER(trans, HSW_VIDEO_DIP_AVI_DATA_A, 
 HSW_VIDEO_DIP_AVI_DATA_B)
 +#define HSW_TVIDEO_DIP_SPD_DATA(trans) \
 +_TRANSCODER(trans, HSW_VIDEO_DIP_SPD_DATA_A, 
 HSW_VIDEO_DIP_SPD_DATA_B)
 +#define HSW_TVIDEO_DIP_GCP(trans) \
 +   _TRANSCODER(trans, HSW_VIDEO_DIP_GCP_A, HSW_VIDEO_DIP_GCP_B)
 +#define HSW_TVIDEO_DIP_VSC_DATA(trans) \
 +_TRANSCODER(trans, HSW_VIDEO_DIP_VSC_DATA_A, 
 HSW_VIDEO_DIP_VSC_DATA_B)

  #define _TRANS_HTOTAL_B  0xe1000
  #define _TRANS_HBLANK_B  0xe1004
 diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
 b/drivers/gpu/drm/i915/intel_hdmi.c
 index 5a6138c..26290c1 100644
 --- a/drivers/gpu/drm/i915/intel_hdmi.c
 +++ b/drivers/gpu/drm/i915/intel_hdmi.c
 @@ -120,13 +120,14 @@ static u32 hsw_infoframe_enable(struct dip_infoframe 
 *frame)
 }
  }

 -static u32 hsw_infoframe_data_reg(struct dip_infoframe *frame, enum pipe 
 pipe)
 +static u32 hsw_infoframe_data_reg(struct dip_infoframe *frame,
 + enum transcoder cpu_transcoder)
  {
 switch (frame-type) {
 case DIP_TYPE_AVI:
 -   return HSW_TVIDEO_DIP_AVI_DATA(pipe);
 +   return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder);
 case DIP_TYPE_SPD:
 -   return HSW_TVIDEO_DIP_SPD_DATA(pipe);
 +   return HSW_TVIDEO_DIP_SPD_DATA(cpu_transcoder);
 default:
 DRM_DEBUG_DRIVER(unknown info frame type %d\n, frame-type);
 return 0;
 @@ -293,8 +294,8 @@ static void hsw_write_infoframe(struct drm_encoder 
 *encoder,
 struct drm_device *dev = encoder-dev;
 struct drm_i915_private *dev_priv = dev-dev_private;
 struct intel_crtc *intel_crtc = to_intel_crtc(encoder-crtc);
 -   u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc-pipe);
 -   u32 data_reg = hsw_infoframe_data_reg(frame, intel_crtc-pipe);
 +   u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc-cpu_transcoder);
 +   u32 data_reg = hsw_infoframe_data_reg(frame, 
 intel_crtc-cpu_transcoder);
 unsigned int i, len = DIP_HEADER_SIZE + frame-len;
 u32 val = I915_READ(ctl_reg);

 @@ -568,7 +569,7 @@ static void hsw_set_infoframes(struct drm_encoder 
 *encoder,
 struct drm_i915_private *dev_priv = encoder-dev-dev_private;
 struct intel_crtc *intel_crtc = to_intel_crtc(encoder-crtc);
 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
 -   u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc-pipe);
 +   u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc-cpu_transcoder);
 u32 val = I915_READ(reg);

 assert_hdmi_port_disabled(intel_hdmi);
 --
 1.8.1.2

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



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


Re: [Intel-gfx] [PATCH 3/8] drm/i915: Added SDP and VSC structures for handling PSR for eDP

2013-02-27 Thread Paulo Zanoni
Hi

2013/2/25 Rodrigo Vivi rodrigo.v...@gmail.com:
 From: Shobhit Kumar shobhit.ku...@intel.com

 Signed-off-by: Sateesh Kavuri sateesh.kav...@intel.com

 v2: Modified and corrected the structures to be more in line for
 kernel coding guidelines and rebased the code on Paulo's DP patchset

 Signed-off-by: Shobhit Kumar shobhit.ku...@intel.com

 v3: removing unecessary identation at DP_RECEIVER_CAP_SIZE
 v4: moving them to include/drm/drm_dp_helper.h and also already
 icluding EDP_PSR_RECEIVER_CAP_SIZE to add everything needed
 for PSR at once at drm_dp_helper.h

 Signed-off-by: Rodrigo Vivi rodrigo.v...@gmail.com

I'd group all Signed-off-by tags at the bottom :)

 ---
  include/drm/drm_dp_helper.h | 22 ++
  1 file changed, 22 insertions(+)

 diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
 index e8e1417..06c5060 100644
 --- a/include/drm/drm_dp_helper.h
 +++ b/include/drm/drm_dp_helper.h
 @@ -343,12 +343,34 @@ u8 drm_dp_get_adjust_request_pre_emphasis(u8 
 link_status[DP_LINK_STATUS_SIZE],
   int lane);

  #define DP_RECEIVER_CAP_SIZE   0xf
 +#define EDP_PSR_RECEIVER_CAP_SIZE  2

I know I'll sound annoying, but my OCD will kill me if I don't tell
you that the line above uses tab and you use spaces.

 +
  void drm_dp_link_train_clock_recovery_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]);
  void drm_dp_link_train_channel_eq_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]);

  u8 drm_dp_link_rate_to_bw_code(int link_rate);
  int drm_dp_bw_code_to_link_rate(u8 link_bw);

 +/* SDP header as per eDP 1.3 spec, section 3.6 */
 +struct edp_sdp_header {
 +   u8 id;
 +   u8 type;
 +   u8 revision;
 +   u8 valid_payload_bytes;
 +} __attribute__((packed));

I think Jani's suggestion on the previous review still applies. How
about something like the following?

u8 id;
u8 type;
u8 hb2; /* 7:5 reserved, 4:0 revision number */
u8 hb3; /* 7:5 reserved, 4:0 number of valid data bytes */

And then something like this:
#define EDP_SDP_HEADER_REVISION_MASK 0x1F
#define EDP_SDP_HEADER_VALID_PAYLOAD_BYTES 0x1F

Also, checkpath.pl complains:
WARNING: __packed is preferred over __attribute__((packed))

 +
 +/* SDP VSC header as per eDP 1.3 spec, section 3.6 */
 +struct edp_vsc_psr {
 +   struct edp_sdp_header sdp_header;

Where's DB0? Its description is on DP spec version 1.2, chapter 2.2.5.6

 +   u8 DB1; /* 0 - PSR State; 1 - Update RFB; 2 - CRC Valid*/
 +   u8 DB2; /* CRC value bits 7:0 of the R or Cr component */
 +   u8 DB3; /* CRC value bits 15:8 of the R or Cr component */
 +   u8 DB4; /* CRC value bits 7:0 of the G or Y component */
 +   u8 DB5; /* CRC value bits 15:8 of the G or Y component */
 +   u8 DB6; /* CRC value bits 7:0 of the B or Cb component */
 +   u8 DB7; /* CRC value bits 15:8 of the B or Cb component */
 +} __attribute__((packed));

And here some more defines to access the individual byte fields would
be cool, like:

#define EDP_VSC_PSR_STATE_ACTIVE 1
#define EDP_VSC_PSR_RFB_UPDATE (1  1)
etc.

 +
  static inline int
  drm_dp_max_link_rate(u8 dpcd[DP_RECEIVER_CAP_SIZE])
  {
 --
 1.8.1.2

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



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


[PATCH] drm: don't add inferred modes for monitors that don't support them

2013-02-15 Thread Paulo Zanoni
From: Paulo Zanoni <paulo.r.zan...@intel.com>

If bit 0 of the features byte (0x18) is set to 0, then, according to
the EDID spec, "the display is non-continuous frequency (multi-mode)
and is only specified to accept the video timing formats that are
listed in Base EDID and certain Extension Blocks".

For more information, please see the EDID spec, check the notes of the
table that explains the "Feature Support" byte (18h) and also the
notes on the tables of the section that explains "Display Range Limits
& Additional Timing Description Definition (tag #FDh)".

Cc: Adam Jackson 
Cc: stable at vger.kernel.org
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=45729
Signed-off-by: Paulo Zanoni 
---
 drivers/gpu/drm/drm_edid.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

I still need to ask some specific people to test the patch, but I
believe it is correct.

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index a3a3b61..6a003b6 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2053,7 +2053,8 @@ int drm_add_edid_modes(struct drm_connector *connector, 
struct edid *edid)
num_modes += add_cvt_modes(connector, edid);
num_modes += add_standard_modes(connector, edid);
num_modes += add_established_modes(connector, edid);
-   num_modes += add_inferred_modes(connector, edid);
+   if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)
+   num_modes += add_inferred_modes(connector, edid);
num_modes += add_cea_modes(connector, edid);

if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
-- 
1.7.10.4



[PATCH] drm: don't add inferred modes for monitors that don't support them

2013-02-15 Thread Paulo Zanoni
From: Paulo Zanoni paulo.r.zan...@intel.com

If bit 0 of the features byte (0x18) is set to 0, then, according to
the EDID spec, the display is non-continuous frequency (multi-mode)
and is only specified to accept the video timing formats that are
listed in Base EDID and certain Extension Blocks.

For more information, please see the EDID spec, check the notes of the
table that explains the Feature Support byte (18h) and also the
notes on the tables of the section that explains Display Range Limits
 Additional Timing Description Definition (tag #FDh).

Cc: Adam Jackson a...@redhat.com
Cc: sta...@vger.kernel.org
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=45729
Signed-off-by: Paulo Zanoni paulo.r.zan...@intel.com
---
 drivers/gpu/drm/drm_edid.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

I still need to ask some specific people to test the patch, but I
believe it is correct.

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index a3a3b61..6a003b6 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2053,7 +2053,8 @@ int drm_add_edid_modes(struct drm_connector *connector, 
struct edid *edid)
num_modes += add_cvt_modes(connector, edid);
num_modes += add_standard_modes(connector, edid);
num_modes += add_established_modes(connector, edid);
-   num_modes += add_inferred_modes(connector, edid);
+   if (edid-features  DRM_EDID_FEATURE_DEFAULT_GTF)
+   num_modes += add_inferred_modes(connector, edid);
num_modes += add_cea_modes(connector, edid);
 
if (quirks  (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
-- 
1.7.10.4

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


[PATCH 7/9] drm/i915: Enable/Disable PSR on HSW

2013-01-31 Thread Paulo Zanoni
  psr_vsc.sdp_header.type = 0x7;
> +   psr_vsc.sdp_header.revision = 0x2;
> +   psr_vsc.sdp_header.valid_payload_bytes = 0x8;
> +
> +   /* As per eDP spec, wait for vblank to send SDP VSC packet */
> +   intel_wait_for_vblank(dev, intel_crtc->pipe);
> +
> +   /* Load the VSC DIP packet */
> +   for(i = 0; i < vsc_len; i += 4)
> +   I915_WRITE((reg + i), vsc_data[i]);

How about reusing hsw_write_infoframe from intel_hdmi.c somehow? It
implements all the "restrictions" we need to respect.

> +
> +#if 0
> +   /* TBD:
> +* We might not have to do explicitely as hardware will take 
> care of this */
> +   /* Enable the DIP register */
> +   val = I915_READ(VIDEO_DIP_CTL_EDP);
> +   I915_WRITE(VIDEO_DIP_CTL_EDP, val | VIDEOP_DIP_VSC);
> +#endif

Hardware will take care of this? You mean the BIOS? Please try to
configure your BIOS to not configure the panel (make it boot on an
external monitor, not on the panel) and then try to boot your machine,
check if PSR still works after our driver loads. Also, please try to
reuse hsw_set_infoframes instead of the code above, if applicable.
Also, I'm not sure we want to add "#if 0"ed code.


> +   /* Enable PSR in sink by setting bit 0 in DPCD config reg
> +* along with the transmitter state during PSR active
> +* Transmitter state later can be ready from VBT. As of now
> +* program the full link down
> +*
> +*/
> +   intel_dp_aux_native_write_1(intel_dp, DP_PSR_EN_CFG,
> +   DP_PSR_ENABLE &
> +   ~DP_PSR_MAIN_LINK_ACTIVE);
> +
> +   /* Enable PSR on the host */
> +   intel_edp_psr_enable_src(intel_dp);
> +   }
> +}
> +
> +void intel_edp_disable_psr(struct intel_dp* intel_dp)
> +{
> +   struct drm_device *dev = intel_dp_to_dev(intel_dp);
> +   struct drm_i915_private *dev_priv = dev->dev_private;
> +   struct intel_crtc *intel_crtc = 
> to_intel_crtc(intel_dp_to_crtc(intel_dp));
> +   uint32_t val;
> +   if (!intel_edp_is_psr_enabled(intel_dp))
> +   return;
> +
> +   val = I915_READ(EDP_PSR_CTL);
> +   I915_WRITE(EDP_PSR_CTL, (val & ~EDP_PSR_ENABLE));
> +
> +   /* Wait till PSR is idle */
> +   if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL) & EDP_PSR_STATUS_MASK) 
> == 0, 2000, 10))
> +   DRM_ERROR("Timed out waiting for PSR Idle State\n");
> +
> +   intel_wait_for_vblank(dev, intel_crtc->pipe);

Where is this vblank wait documented?

> +
> +#if 0
> +   /* TBD:
> +* Following is not yet confirmed from H/W team.
> +* As per last discussion we do not need to disable
> +* VSC DIP explicitely. Just maintaining the code in
> +* case we have to do this later at some point
> +*/
> +
> +   /* Disable VSC DIP */
> +   val = I915_READ(VIDEO_DIP_CTL_EDP);
> +   I915_WRITE(VIDEO_DIP_CTL_EDP, val & ~VIDEOP_DIP_VSC);
> +#endif

I'd vote to disable and also try to reuse the functions inside
intel_hdmi.c for this.

> +}
> +
>  static void intel_enable_dp(struct intel_encoder *encoder)
>  {
> struct intel_dp *intel_dp = enc_to_intel_dp(>base);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
> b/drivers/gpu/drm/i915/intel_drv.h
> index 3fa2dd0..2f48e5c 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -692,4 +692,7 @@ extern bool
>  intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
>  extern void intel_ddi_fdi_disable(struct drm_crtc *crtc);
>
> +extern void intel_edp_enable_psr(struct intel_dp* intel_dp);
> +extern void intel_edp_disable_psr(struct intel_dp* intel_dp);
> +
>  #endif /* __INTEL_DRV_H__ */
> --
> 1.7.11.7
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Paulo Zanoni


[PATCH 5/9] drm/i915: Setup EDP PSR AUX Registers

2013-01-31 Thread Paulo Zanoni
P input clock at 450Mhz 
> */
> -   } else if (HAS_PCH_SPLIT(dev))
> -   aux_clock_divider = DIV_ROUND_UP(intel_pch_rawclk(dev), 2);
> -   else
> -   aux_clock_divider = intel_hrawclk(dev) / 2;
> +   aux_clock_divider = get_aux_clock_divider(intel_dp);
>
> if (IS_GEN6(dev))
> precharge = 3;
> @@ -1440,6 +1449,46 @@ static bool is_edp_psr(struct intel_dp *intel_dp)
> return (is_edp(intel_dp) && (intel_dp->psr_dpcd[0] & 0x1));
>  }
>
> +static void intel_edp_psr_setup(struct intel_dp *intel_dp)
> +{
> +   struct drm_device *dev = intel_dp_to_dev(intel_dp);
> +   struct drm_i915_private *dev_priv = dev->dev_private;
> +   uint32_t aux_clock_divider;
> +   int precharge = 0x3;
> +   int msg_size = 5;   /* Header(4) + Message(1) */
> +
> +   /* No need to setup if already done as these setting are persistent
> +* until power states are entered */
> +   if (intel_dp->psr_setup)
> +   return;
> +
> +   /* Setup AUX registers */
> +   /* Write command on DPCD 0x0600 */
> +   I915_WRITE(EDP_PSR_AUX_DATA1, 0x8006);
> +
> +   /* Set the state to normal operation D0 in DPCD 0x0600 */
> +   I915_WRITE(EDP_PSR_AUX_DATA2, 0x0100);
> +
> +   aux_clock_divider = get_aux_clock_divider(intel_dp);
> +
> +   I915_WRITE(EDP_PSR_AUX_CTL,
> +  DP_AUX_CH_CTL_TIME_OUT_400us |
> +  (msg_size << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
> +  (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) |
> +  (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT));

On DP_AUX_CH the message "goes" after we write 1 to bit 31. And then
we wait for the "done" bit. How does it work here?

Also, on DP_AUX_CH we try at least 5 times. Shouldn't we do this here too?

> +
> +   /* Setup the debug register */
> +   I915_WRITE(EDP_PSR_DEBUG_CTL, I915_READ(EDP_PSR_DEBUG_CTL) |
> +   EDP_PSR_DEBUG_MASK_MEMUP |
> +   EDP_PSR_DEBUG_MASK_HPD);

Why?

> +
> +   /* This flag can be made to 0 from pm code so as to reinitialize the
> +* AUX register in case of power states, returning from which will not
> +* maintain the AUX register settings
> +*/
> +   intel_dp->psr_setup = 1;
> +}
> +
>  static void intel_enable_dp(struct intel_encoder *encoder)
>  {
> struct intel_dp *intel_dp = enc_to_intel_dp(>base);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
> b/drivers/gpu/drm/i915/intel_drv.h
> index d4b3bac..3fa2dd0 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -383,6 +383,7 @@ struct intel_dp {
> int backlight_on_delay;
> int backlight_off_delay;
> struct delayed_work panel_vdd_work;
> +   uint8_t psr_setup;

bool psr_setup_done ?

> bool want_panel_vdd;
> struct intel_connector *attached_connector;
>  };
> --
> 1.7.11.7
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Paulo Zanoni


[Intel-gfx] [PATCH 2/9] drm/i915: Use cpu_transcoder for HSW_TVIDEO_DIP_* instead of pipe

2013-01-31 Thread Paulo Zanoni
66,7 @@ static void hsw_set_infoframes(struct drm_encoder 
>> *encoder,
>>   struct drm_i915_private *dev_priv = encoder->dev->dev_private;
>>   struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
>>   struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
>> - u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc->pipe);
>> + u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc->cpu_transcoder);
>>   u32 val = I915_READ(reg);
>>
>>   assert_hdmi_port_disabled(intel_hdmi);
>> --
>> 1.7.11.7
>>
>> ___
>> Intel-gfx mailing list
>> Intel-gfx at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Paulo Zanoni


[Intel-gfx] [PATCH 2/9] drm/i915: Use cpu_transcoder for HSW_TVIDEO_DIP_* instead of pipe

2013-01-31 Thread Paulo Zanoni
Hi

2013/1/30 Rodrigo Vivi :
> While old platforms had 3 transcoders and 3 pipes (1:1), HSW has 4 
> transcoders and 3 pipes. To avoid future mistakes transcoders must be used 
> here instead of pipes even though it is working right now by coincidence.

Not by coincidence: these regs are currently only used by HDMI code
and HDMI code never uses TRANSCODER_EDP, so using "pipe" instead of
cpu_transcoder" is correct, since on HDMI pipe is always the same
thing as cpu_transcoder. Now that we're going to start to use these
registers for DP your patch is needed.

My only complaint about this patch (besides the sentence above) would
be due to using more than 80 columns, both on the commit message and
coding :)

Reviewed-by: Paulo Zanoni 

>
> Signed-off-by: Rodrigo Vivi 
> ---
>  drivers/gpu/drm/i915/i915_reg.h   | 16 
>  drivers/gpu/drm/i915/intel_hdmi.c | 12 ++--
>  2 files changed, 14 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 2521617..7bb3134 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -3742,14 +3742,14 @@
>  #define HSW_VIDEO_DIP_VSC_ECC_B0x61344
>  #define HSW_VIDEO_DIP_GCP_B0x61210
>
> -#define HSW_TVIDEO_DIP_CTL(pipe) \
> -_PIPE(pipe, HSW_VIDEO_DIP_CTL_A, HSW_VIDEO_DIP_CTL_B)
> -#define HSW_TVIDEO_DIP_AVI_DATA(pipe) \
> -_PIPE(pipe, HSW_VIDEO_DIP_AVI_DATA_A, HSW_VIDEO_DIP_AVI_DATA_B)
> -#define HSW_TVIDEO_DIP_SPD_DATA(pipe) \
> -_PIPE(pipe, HSW_VIDEO_DIP_SPD_DATA_A, HSW_VIDEO_DIP_SPD_DATA_B)
> -#define HSW_TVIDEO_DIP_GCP(pipe) \
> -   _PIPE(pipe, HSW_VIDEO_DIP_GCP_A, HSW_VIDEO_DIP_GCP_B)
> +#define HSW_TVIDEO_DIP_CTL(trans) \
> +_TRANSCODER(trans, HSW_VIDEO_DIP_CTL_A, HSW_VIDEO_DIP_CTL_B)
> +#define HSW_TVIDEO_DIP_AVI_DATA(trans) \
> +_TRANSCODER(trans, HSW_VIDEO_DIP_AVI_DATA_A, 
> HSW_VIDEO_DIP_AVI_DATA_B)
> +#define HSW_TVIDEO_DIP_SPD_DATA(trans) \
> +_TRANSCODER(trans, HSW_VIDEO_DIP_SPD_DATA_A, 
> HSW_VIDEO_DIP_SPD_DATA_B)
> +#define HSW_TVIDEO_DIP_GCP(trans) \
> +   _TRANSCODER(trans, HSW_VIDEO_DIP_GCP_A, HSW_VIDEO_DIP_GCP_B)
>
>  #define _TRANS_HTOTAL_B  0xe1000
>  #define _TRANS_HBLANK_B  0xe1004
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
> b/drivers/gpu/drm/i915/intel_hdmi.c
> index d53b731..ab95e05 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -120,13 +120,13 @@ static u32 hsw_infoframe_enable(struct dip_infoframe 
> *frame)
> }
>  }
>
> -static u32 hsw_infoframe_data_reg(struct dip_infoframe *frame, enum pipe 
> pipe)
> +static u32 hsw_infoframe_data_reg(struct dip_infoframe *frame, enum 
> transcoder cpu_transcoder)
>  {
> switch (frame->type) {
> case DIP_TYPE_AVI:
> -   return HSW_TVIDEO_DIP_AVI_DATA(pipe);
> +   return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder);
> case DIP_TYPE_SPD:
> -   return HSW_TVIDEO_DIP_SPD_DATA(pipe);
> +   return HSW_TVIDEO_DIP_SPD_DATA(cpu_transcoder);
> default:
> DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type);
> return 0;
> @@ -293,8 +293,8 @@ static void hsw_write_infoframe(struct drm_encoder 
> *encoder,
> struct drm_device *dev = encoder->dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
> -   u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->pipe);
> -   u32 data_reg = hsw_infoframe_data_reg(frame, intel_crtc->pipe);
> +   u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->cpu_transcoder);
> +   u32 data_reg = hsw_infoframe_data_reg(frame, 
> intel_crtc->cpu_transcoder);
> unsigned int i, len = DIP_HEADER_SIZE + frame->len;
> u32 val = I915_READ(ctl_reg);
>
> @@ -566,7 +566,7 @@ static void hsw_set_infoframes(struct drm_encoder 
> *encoder,
> struct drm_i915_private *dev_priv = encoder->dev->dev_private;
> struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
> struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
> -   u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc->pipe);
> +   u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc->cpu_transcoder);
> u32 val = I915_READ(reg);
>
> assert_hdmi_port_disabled(intel_hdmi);
> --
> 1.7.11.7
>
> ___
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni


Re: [Intel-gfx] [PATCH 2/9] drm/i915: Use cpu_transcoder for HSW_TVIDEO_DIP_* instead of pipe

2013-01-31 Thread Paulo Zanoni
Hi

2013/1/30 Rodrigo Vivi rodrigo.v...@gmail.com:
 While old platforms had 3 transcoders and 3 pipes (1:1), HSW has 4 
 transcoders and 3 pipes. To avoid future mistakes transcoders must be used 
 here instead of pipes even though it is working right now by coincidence.

Not by coincidence: these regs are currently only used by HDMI code
and HDMI code never uses TRANSCODER_EDP, so using pipe instead of
cpu_transcoder is correct, since on HDMI pipe is always the same
thing as cpu_transcoder. Now that we're going to start to use these
registers for DP your patch is needed.

My only complaint about this patch (besides the sentence above) would
be due to using more than 80 columns, both on the commit message and
coding :)

Reviewed-by: Paulo Zanoni paulo.r.zan...@intel.com


 Signed-off-by: Rodrigo Vivi rodrigo.v...@gmail.com
 ---
  drivers/gpu/drm/i915/i915_reg.h   | 16 
  drivers/gpu/drm/i915/intel_hdmi.c | 12 ++--
  2 files changed, 14 insertions(+), 14 deletions(-)

 diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
 index 2521617..7bb3134 100644
 --- a/drivers/gpu/drm/i915/i915_reg.h
 +++ b/drivers/gpu/drm/i915/i915_reg.h
 @@ -3742,14 +3742,14 @@
  #define HSW_VIDEO_DIP_VSC_ECC_B0x61344
  #define HSW_VIDEO_DIP_GCP_B0x61210

 -#define HSW_TVIDEO_DIP_CTL(pipe) \
 -_PIPE(pipe, HSW_VIDEO_DIP_CTL_A, HSW_VIDEO_DIP_CTL_B)
 -#define HSW_TVIDEO_DIP_AVI_DATA(pipe) \
 -_PIPE(pipe, HSW_VIDEO_DIP_AVI_DATA_A, HSW_VIDEO_DIP_AVI_DATA_B)
 -#define HSW_TVIDEO_DIP_SPD_DATA(pipe) \
 -_PIPE(pipe, HSW_VIDEO_DIP_SPD_DATA_A, HSW_VIDEO_DIP_SPD_DATA_B)
 -#define HSW_TVIDEO_DIP_GCP(pipe) \
 -   _PIPE(pipe, HSW_VIDEO_DIP_GCP_A, HSW_VIDEO_DIP_GCP_B)
 +#define HSW_TVIDEO_DIP_CTL(trans) \
 +_TRANSCODER(trans, HSW_VIDEO_DIP_CTL_A, HSW_VIDEO_DIP_CTL_B)
 +#define HSW_TVIDEO_DIP_AVI_DATA(trans) \
 +_TRANSCODER(trans, HSW_VIDEO_DIP_AVI_DATA_A, 
 HSW_VIDEO_DIP_AVI_DATA_B)
 +#define HSW_TVIDEO_DIP_SPD_DATA(trans) \
 +_TRANSCODER(trans, HSW_VIDEO_DIP_SPD_DATA_A, 
 HSW_VIDEO_DIP_SPD_DATA_B)
 +#define HSW_TVIDEO_DIP_GCP(trans) \
 +   _TRANSCODER(trans, HSW_VIDEO_DIP_GCP_A, HSW_VIDEO_DIP_GCP_B)

  #define _TRANS_HTOTAL_B  0xe1000
  #define _TRANS_HBLANK_B  0xe1004
 diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
 b/drivers/gpu/drm/i915/intel_hdmi.c
 index d53b731..ab95e05 100644
 --- a/drivers/gpu/drm/i915/intel_hdmi.c
 +++ b/drivers/gpu/drm/i915/intel_hdmi.c
 @@ -120,13 +120,13 @@ static u32 hsw_infoframe_enable(struct dip_infoframe 
 *frame)
 }
  }

 -static u32 hsw_infoframe_data_reg(struct dip_infoframe *frame, enum pipe 
 pipe)
 +static u32 hsw_infoframe_data_reg(struct dip_infoframe *frame, enum 
 transcoder cpu_transcoder)
  {
 switch (frame-type) {
 case DIP_TYPE_AVI:
 -   return HSW_TVIDEO_DIP_AVI_DATA(pipe);
 +   return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder);
 case DIP_TYPE_SPD:
 -   return HSW_TVIDEO_DIP_SPD_DATA(pipe);
 +   return HSW_TVIDEO_DIP_SPD_DATA(cpu_transcoder);
 default:
 DRM_DEBUG_DRIVER(unknown info frame type %d\n, frame-type);
 return 0;
 @@ -293,8 +293,8 @@ static void hsw_write_infoframe(struct drm_encoder 
 *encoder,
 struct drm_device *dev = encoder-dev;
 struct drm_i915_private *dev_priv = dev-dev_private;
 struct intel_crtc *intel_crtc = to_intel_crtc(encoder-crtc);
 -   u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc-pipe);
 -   u32 data_reg = hsw_infoframe_data_reg(frame, intel_crtc-pipe);
 +   u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc-cpu_transcoder);
 +   u32 data_reg = hsw_infoframe_data_reg(frame, 
 intel_crtc-cpu_transcoder);
 unsigned int i, len = DIP_HEADER_SIZE + frame-len;
 u32 val = I915_READ(ctl_reg);

 @@ -566,7 +566,7 @@ static void hsw_set_infoframes(struct drm_encoder 
 *encoder,
 struct drm_i915_private *dev_priv = encoder-dev-dev_private;
 struct intel_crtc *intel_crtc = to_intel_crtc(encoder-crtc);
 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
 -   u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc-pipe);
 +   u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc-cpu_transcoder);
 u32 val = I915_READ(reg);

 assert_hdmi_port_disabled(intel_hdmi);
 --
 1.7.11.7

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



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


Re: [PATCH 5/9] drm/i915: Setup EDP PSR AUX Registers

2013-01-31 Thread Paulo Zanoni
 bool is_edp_psr(struct intel_dp *intel_dp)
 return (is_edp(intel_dp)  (intel_dp-psr_dpcd[0]  0x1));
  }

 +static void intel_edp_psr_setup(struct intel_dp *intel_dp)
 +{
 +   struct drm_device *dev = intel_dp_to_dev(intel_dp);
 +   struct drm_i915_private *dev_priv = dev-dev_private;
 +   uint32_t aux_clock_divider;
 +   int precharge = 0x3;
 +   int msg_size = 5;   /* Header(4) + Message(1) */
 +
 +   /* No need to setup if already done as these setting are persistent
 +* until power states are entered */
 +   if (intel_dp-psr_setup)
 +   return;
 +
 +   /* Setup AUX registers */
 +   /* Write command on DPCD 0x0600 */
 +   I915_WRITE(EDP_PSR_AUX_DATA1, 0x8006);
 +
 +   /* Set the state to normal operation D0 in DPCD 0x0600 */
 +   I915_WRITE(EDP_PSR_AUX_DATA2, 0x0100);
 +
 +   aux_clock_divider = get_aux_clock_divider(intel_dp);
 +
 +   I915_WRITE(EDP_PSR_AUX_CTL,
 +  DP_AUX_CH_CTL_TIME_OUT_400us |
 +  (msg_size  DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
 +  (precharge  DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) |
 +  (aux_clock_divider  DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT));

On DP_AUX_CH the message goes after we write 1 to bit 31. And then
we wait for the done bit. How does it work here?

Also, on DP_AUX_CH we try at least 5 times. Shouldn't we do this here too?

 +
 +   /* Setup the debug register */
 +   I915_WRITE(EDP_PSR_DEBUG_CTL, I915_READ(EDP_PSR_DEBUG_CTL) |
 +   EDP_PSR_DEBUG_MASK_MEMUP |
 +   EDP_PSR_DEBUG_MASK_HPD);

Why?

 +
 +   /* This flag can be made to 0 from pm code so as to reinitialize the
 +* AUX register in case of power states, returning from which will not
 +* maintain the AUX register settings
 +*/
 +   intel_dp-psr_setup = 1;
 +}
 +
  static void intel_enable_dp(struct intel_encoder *encoder)
  {
 struct intel_dp *intel_dp = enc_to_intel_dp(encoder-base);
 diff --git a/drivers/gpu/drm/i915/intel_drv.h 
 b/drivers/gpu/drm/i915/intel_drv.h
 index d4b3bac..3fa2dd0 100644
 --- a/drivers/gpu/drm/i915/intel_drv.h
 +++ b/drivers/gpu/drm/i915/intel_drv.h
 @@ -383,6 +383,7 @@ struct intel_dp {
 int backlight_on_delay;
 int backlight_off_delay;
 struct delayed_work panel_vdd_work;
 +   uint8_t psr_setup;

bool psr_setup_done ?

 bool want_panel_vdd;
 struct intel_connector *attached_connector;
  };
 --
 1.7.11.7

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



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


  1   2   3   >