[Intel-gfx] [PATCH] drm/i915: eDP Panel Power sequencing

2015-05-03 Thread Vandana Kannan
Changes based on future platform readiness patches related to
HAS_PCH_SPLIT(). Use HAS_GMCH_DISPLAY() instead of HAS_PCH_SPLIT.
BXT does not have PP_DIV register. Making changes to handle this.
Second set of PPS registers have been defined but will be used when VBT
provides a selection between the 2 sets of registers.

v2:
[Jani] Added 2nd set of PPS registers and the macro
Jani's review comments
- remove reference in i915_suspend.c
- Use BXT PP macro
Squashing all PPS related patches into one.

Signed-off-by: Vandana Kannan 
Signed-off-by: A.Sunil Kamath 
---
 drivers/gpu/drm/i915/i915_reg.h | 13 
 drivers/gpu/drm/i915/intel_dp.c | 69 +
 2 files changed, 69 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 36805b6..e8d93ea 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6315,6 +6315,8 @@ enum skl_disp_power_wells {
 #define PCH_PP_CONTROL 0xc7204
 #define  PANEL_UNLOCK_REGS (0xabcd << 16)
 #define  PANEL_UNLOCK_MASK (0x << 16)
+#define  BXT_POWER_CYCLE_DELAY_MASK(0x1f0)
+#define  BXT_POWER_CYCLE_DELAY_SHIFT   4
 #define  EDP_FORCE_VDD (1 << 3)
 #define  EDP_BLC_ENABLE(1 << 2)
 #define  PANEL_POWER_RESET (1 << 1)
@@ -6343,6 +6345,17 @@ enum skl_disp_power_wells {
 #define  PANEL_POWER_CYCLE_DELAY_MASK  (0x1f)
 #define  PANEL_POWER_CYCLE_DELAY_SHIFT 0
 
+/* BXT PPS changes - 2nd set of PPS registers */
+#define _BXT_PP_STATUS20xc7300
+#define _BXT_PP_CONTROL2   0xc7304
+#define _BXT_PP_ON_DELAYS2 0xc7308
+#define _BXT_PP_OFF_DELAYS20xc730c
+
+#define BXT_PP_STATUS(n)   ((!n) ? PCH_PP_STATUS : _BXT_PP_STATUS2)
+#define BXT_PP_CONTROL(n)  ((!n) ? PCH_PP_CONTROL : _BXT_PP_CONTROL2)
+#define BXT_PP_ON_DELAYS(n)((!n) ? PCH_PP_ON_DELAYS : _BXT_PP_ON_DELAYS2)
+#define BXT_PP_OFF_DELAYS(n)   ((!n) ? PCH_PP_OFF_DELAYS : _BXT_PP_OFF_DELAYS2)
+
 #define PCH_DP_B   0xe4100
 #define PCH_DPB_AUX_CH_CTL 0xe4110
 #define PCH_DPB_AUX_CH_DATA1   0xe4114
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 937ba31..fd91006 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -559,7 +559,9 @@ static u32 _pp_ctrl_reg(struct intel_dp *intel_dp)
 {
struct drm_device *dev = intel_dp_to_dev(intel_dp);
 
-   if (HAS_PCH_SPLIT(dev))
+   if (IS_BROXTON(dev))
+   return BXT_PP_CONTROL(0);
+   else if (HAS_PCH_SPLIT(dev))
return PCH_PP_CONTROL;
else
return VLV_PIPE_PP_CONTROL(vlv_power_sequencer_pipe(intel_dp));
@@ -569,7 +571,9 @@ static u32 _pp_stat_reg(struct intel_dp *intel_dp)
 {
struct drm_device *dev = intel_dp_to_dev(intel_dp);
 
-   if (HAS_PCH_SPLIT(dev))
+   if (IS_BROXTON(dev))
+   return BXT_PP_STATUS(0);
+   else if (HAS_PCH_SPLIT(dev))
return PCH_PP_STATUS;
else
return VLV_PIPE_PP_STATUS(vlv_power_sequencer_pipe(intel_dp));
@@ -4954,8 +4958,8 @@ intel_dp_init_panel_power_sequencer(struct drm_device 
*dev,
struct drm_i915_private *dev_priv = dev->dev_private;
struct edp_power_seq cur, vbt, spec,
*final = &intel_dp->pps_delays;
-   u32 pp_on, pp_off, pp_div, pp;
-   int pp_ctrl_reg, pp_on_reg, pp_off_reg, pp_div_reg;
+   u32 pp_on, pp_off, pp_div = 0, pp_ctl = 0, pp;
+   int pp_ctrl_reg, pp_on_reg, pp_off_reg, pp_div_reg = 0;
 
lockdep_assert_held(&dev_priv->pps_mutex);
 
@@ -4963,7 +4967,16 @@ intel_dp_init_panel_power_sequencer(struct drm_device 
*dev,
if (final->t11_t12 != 0)
return;
 
-   if (HAS_PCH_SPLIT(dev)) {
+   if (IS_BROXTON(dev)) {
+   /*
+* TODO: BXT has 2 sets of PPS registers.
+* Correct Register for Broxton need to be identified
+* using VBT. hardcoding for now
+*/
+   pp_ctrl_reg = BXT_PP_CONTROL(0);
+   pp_on_reg = BXT_PP_ON_DELAYS(0);
+   pp_off_reg = BXT_PP_OFF_DELAYS(0);
+   } else if (HAS_PCH_SPLIT(dev)) {
pp_ctrl_reg = PCH_PP_CONTROL;
pp_on_reg = PCH_PP_ON_DELAYS;
pp_off_reg = PCH_PP_OFF_DELAYS;
@@ -4984,7 +4997,10 @@ intel_dp_init_panel_power_sequencer(struct drm_device 
*dev,
 
pp_on = I915_READ(pp_on_reg);
pp_off = I915_READ(pp_off_reg);
-   pp_div = I915_READ(pp_div_reg);
+   if (!IS_BROXTON(dev))
+   pp_div = I915_READ(pp_div_reg);
+   else
+   pp_ctl = I915_READ(pp_ctrl_reg);
 
/* Pull timing values out of registers */
cur.t1_t3 = (pp_on & PANEL_POWER_UP_DELAY_MASK) >>
@@ -4999,7 +5015,11 @@ intel_dp_init_panel_power_sequencer(struct drm_device 
*dev,
cur.t10 = (pp_off & PANEL_POWER_DOWN_DELAY_M

Re: [Intel-gfx] [PATCH 3/3] drm/i915: eDP Panel Power sequencing add PPS reg set

2015-05-03 Thread Kannan, Vandana



On 4/30/2015 4:53 PM, Jani Nikula wrote:

On Thu, 30 Apr 2015, Imre Deak  wrote:

On to, 2015-04-30 at 13:07 +0530, Vandana Kannan wrote:

Second set of PPS registers have been defined but will be used when VBT
provides a selection between the 2 sets of registers.

Signed-off-by: Vandana Kannan 
Signed-off-by: A.Sunil Kamath 
---
  drivers/gpu/drm/i915/i915_reg.h | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 580f5cb..199a1747 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6345,6 +6345,12 @@ enum skl_disp_power_wells {
  #define  PANEL_POWER_CYCLE_DELAY_MASK (0x1f)
  #define  PANEL_POWER_CYCLE_DELAY_SHIFT0

+/* BXT PPS changes - 2nd set of PPS registers */
+#define BXT_PP_STATUS2 0xc7300
+#define BXT_PP_CONTROL20xc7304
+#define BXT_PP_ON_DELAYS2  0xc7308
+#define BXT_PP_OFF_DELAYS2 0xc730c
+


Can we add these in the (future) patch which takes them into use?


See my review comment, we should use them off the bat.

BR,
Jani.


Agree with all your review comments.
I've made the changes and will be resending the patch today.

- Vandana



  #define PCH_DP_B  0xe4100
  #define PCH_DPB_AUX_CH_CTL0xe4110
  #define PCH_DPB_AUX_CH_DATA1  0xe4114



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



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


Re: [Intel-gfx] [PATCH v3] drm/i915: Setup static bias for GPU

2015-05-03 Thread Deepak S



On Wednesday 29 April 2015 02:59 PM, Ville Syrjälä wrote:

On Wed, Apr 29, 2015 at 08:36:24AM +0530, deepa...@linux.intel.com wrote:

From: Deepak S 

Based on the spec, Setting up static BIAS for GPU to improve the
rps performace.

v2: rename reg defn to match spec. (Ville)

v3: Updated bias setting for chv (Deepak)

Signed-off-by: Deepak S 

Matches the spec. Whether the chosen bias is really the best, I can't
really say. But favoring the GPU does seem like a sensible idea if we
want to keep the UI stuff fluid enough while there's some CPU heavy
tasks running at the same time.

Reviewed-by: Ville Syrjälä 


Thanks Ville for reviewing,
Yes our aim is to keep user experience smooth.


---
  drivers/gpu/drm/i915/i915_reg.h |  6 ++
  drivers/gpu/drm/i915/intel_pm.c | 12 
  2 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 36805b6..048987e 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -670,6 +670,12 @@ enum skl_disp_power_wells {
  #define   FB_FMAX_VMIN_FREQ_LO_SHIFT  27
  #define   FB_FMAX_VMIN_FREQ_LO_MASK   0xf800
  
+#define VLV_TURBO_SOC_OVERRIDE	0x04

+#defineVLV_OVERRIDE_EN 1
+#defineVLV_SOC_TDP_EN  (1 << 1)
+#defineVLV_BIAS_CPU_125_SOC_875 (6 << 2)
+#defineCHV_BIAS_CPU_50_SOC_50 (3 << 2)
+
  #define VLV_CZ_CLOCK_TO_MILLI_SEC 10
  
  /* vlv2 north clock has */

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 78c89ff..3689d0e 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5065,6 +5065,12 @@ static void cherryview_enable_rps(struct drm_device *dev)
   GEN6_RP_UP_BUSY_AVG |
   GEN6_RP_DOWN_IDLE_AVG);
  
+	/* Setting Fixed Bias */

+   val = VLV_OVERRIDE_EN |
+ VLV_SOC_TDP_EN |
+ CHV_BIAS_CPU_50_SOC_50;
+   vlv_punit_write(dev_priv, VLV_TURBO_SOC_OVERRIDE, val);
+
val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
  
  	/* RPS code assumes GPLL is used */

@@ -5149,6 +5155,12 @@ static void valleyview_enable_rps(struct drm_device *dev)
  
  	I915_WRITE(GEN6_RC_CONTROL, rc6_mode);
  
+	/* Setting Fixed Bias */

+   val = VLV_OVERRIDE_EN |
+ VLV_SOC_TDP_EN |
+ VLV_BIAS_CPU_125_SOC_875;
+   vlv_punit_write(dev_priv, VLV_TURBO_SOC_OVERRIDE, val);
+
val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
  
  	/* RPS code assumes GPLL is used */

--
1.9.1


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


Re: [Intel-gfx] [PATCH] drm: Defer disabling the vblank IRQ until the next interrupt (for instant-off)

2015-05-03 Thread Mario Kleiner



On 04/15/2015 03:03 AM, Mario Kleiner wrote:

On 04/02/2015 01:34 PM, Chris Wilson wrote:

On vblank instant-off systems, we can get into a situation where the cost
of enabling and disabling the vblank IRQ around a drmWaitVblank query
dominates. However, we know that if the user wants the current vblank
counter, they are also very likely to immediately queue a vblank wait
and so we can keep the interrupt around and only turn it off if we have
no further vblank requests in the interrupt interval.

After vblank event delivery there is a shadow of one vblank where the
interrupt is kept alive for the user to query and queue another vblank
event. Similarly, if the user is using blocking drmWaitVblanks, the
interrupt will be disabled on the IRQ following the wait completion.
However, if the user is simply querying the current vblank counter and
timestamp, the interrupt will be disabled after every IRQ and the user
will enabled it again on the first query following the IRQ.

Testcase: igt/kms_vblank
Signed-off-by: Chris Wilson 
Cc: Ville Syrjälä 
Cc: Daniel Vetter 
Cc: Michel Dänzer 
Cc: Laurent Pinchart 
Cc: Dave Airlie ,
Cc: Mario Kleiner 
---
  drivers/gpu/drm/drm_irq.c | 15 +--
  1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index c8a34476570a..6f5dc18779e2 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -1091,9 +1091,9 @@ void drm_vblank_put(struct drm_device *dev, int
crtc)
  if (atomic_dec_and_test(&vblank->refcount)) {
  if (drm_vblank_offdelay == 0)
  return;
-else if (dev->vblank_disable_immediate || drm_vblank_offdelay
< 0)
+else if (drm_vblank_offdelay < 0)
  vblank_disable_fn((unsigned long)vblank);
-else
+else if (!dev->vblank_disable_immediate)
  mod_timer(&vblank->disable_timer,
jiffies + ((drm_vblank_offdelay * HZ)/1000));
  }
@@ -1697,6 +1697,17 @@ bool drm_handle_vblank(struct drm_device *dev,
int crtc)

  spin_lock_irqsave(&dev->event_lock, irqflags);



You could move the code before the spin_lock_irqsave(&dev->event_lock,
irqflags); i think it doesn't need that lock?


+if (dev->vblank_disable_immediate &&
!atomic_read(&vblank->refcount)) {


Also check for (drm_vblank_offdelay > 0) to make sure we have a way out
of instant disable here, and the same meaning of of drm_vblank_offdelay
like we have in the current implementation.

This hunk ...


+unsigned long vbl_lock_irqflags;
+
+spin_lock_irqsave(&dev->vbl_lock, vbl_lock_irqflags);
+if (atomic_read(&vblank->refcount) == 0 && vblank->enabled) {
+DRM_DEBUG("disabling vblank on crtc %d\n", crtc);
+vblank_disable_and_save(dev, crtc);
+}
+spin_unlock_irqrestore(&dev->vbl_lock, vbl_lock_irqflags);


... is the same as a call to vblank_disable_fn((unsigned long) vblank);
Maybe replace by that call?

You could also return here already, as the code below will just take a
lock, realize vblanks are now disabled and then release the locks and exit.


+}
+
  /* Need timestamp lock to prevent concurrent execution with
   * vblank enable/disable, as this would cause inconsistent
   * or corrupted timestamps and vblank counts.



I think the logic itself is fine and at least basic testing of the patch
on a Intel HD Ironlake didn't show problems, so with the above taken
into account it would have my slightly uneasy reviewed-by.

One thing that worries me a little bit about the disable inside vblank
irq are the potential races between the disable code and the display
engine which could cause really bad off-by-one errors for clients on a
imperfect driver. These races can only happen if vblank enable or
disable happens close to or inside the vblank. This approach lets the
instant disable happen exactly inside vblank when there is the highest
chance of triggering that condition.

This doesn't seem to be a problem for intel kms, but other drivers don't
have instant disable yet, so we don't know how well we could do it
there. Additionally things like dynamic power management tend to operate
inside vblank, sometimes with "funny" side effects to other stuff, e.g.,
dpm on AMD, as i remember from some long debug session with Michel and
Alex last summer where dpm played a role. Therefore it seems more safe
to me to avoid actions inside vblank that could be done outside. E.g.,
instead of doing the disable inside the vblank irq one could maybe just
schedule an exact timer to do the disable a few milliseconds later in
the middle of active scanout to avoid these potential issues?

-mario


After testing this, one more thing that would make sense is to move the 
disable block at the end of drm_handle_vblank() instead of at the top.


Turns out that if high precision timestaming is disabled or doesn't work 
for some reason (as can be simulated by echo 0 > 
/sys/module/drm/par

Re: [Intel-gfx] [PATCH] drm/vblank: Fixup and document timestamp update/read barriers

2015-05-03 Thread Mario Kleiner

On 04/16/2015 03:03 PM, Daniel Vetter wrote:

On Thu, Apr 16, 2015 at 08:30:55AM -0400, Peter Hurley wrote:

On 04/15/2015 01:31 PM, Daniel Vetter wrote:

On Wed, Apr 15, 2015 at 09:00:04AM -0400, Peter Hurley wrote:

Hi Daniel,

On 04/15/2015 03:17 AM, Daniel Vetter wrote:

This was a bit too much cargo-culted, so lets make it solid:
- vblank->count doesn't need to be an atomic, writes are always done
   under the protection of dev->vblank_time_lock. Switch to an unsigned
   long instead and update comments. Note that atomic_read is just a
   normal read of a volatile variable, so no need to audit all the
   read-side access specifically.

- The barriers for the vblank counter seqlock weren't complete: The
   read-side was missing the first barrier between the counter read and
   the timestamp read, it only had a barrier between the ts and the
   counter read. We need both.

- Barriers weren't properly documented. Since barriers only work if
   you have them on boths sides of the transaction it's prudent to
   reference where the other side is. To avoid duplicating the
   write-side comment 3 times extract a little store_vblank() helper.
   In that helper also assert that we do indeed hold
   dev->vblank_time_lock, since in some cases the lock is acquired a
   few functions up in the callchain.

Spotted while reviewing a patch from Chris Wilson to add a fastpath to
the vblank_wait ioctl.

Cc: Chris Wilson 
Cc: Mario Kleiner 
Cc: Ville Syrjälä 
Cc: Michel Dänzer 
Signed-off-by: Daniel Vetter 
---
  drivers/gpu/drm/drm_irq.c | 92 ---
  include/drm/drmP.h|  8 +++--
  2 files changed, 54 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index c8a34476570a..23bfbc61a494 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -74,6 +74,33 @@ module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 
0600);
  module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 
0600);
  module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600);

+static void store_vblank(struct drm_device *dev, int crtc,
+unsigned vblank_count_inc,
+struct timeval *t_vblank)
+{
+   struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
+   u32 tslot;
+
+   assert_spin_locked(&dev->vblank_time_lock);
+
+   if (t_vblank) {
+   tslot = vblank->count + vblank_count_inc;
+   vblanktimestamp(dev, crtc, tslot) = *t_vblank;
+   }
+
+   /*
+* vblank timestamp updates are protected on the write side with
+* vblank_time_lock, but on the read side done locklessly using a
+* sequence-lock on the vblank counter. Ensure correct ordering using
+* memory barrriers. We need the barrier both before and also after the
+* counter update to synchronize with the next timestamp write.
+* The read-side barriers for this are in drm_vblank_count_and_time.
+*/
+   smp_wmb();
+   vblank->count += vblank_count_inc;
+   smp_wmb();


The comment and the code are each self-contradictory.

If vblank->count writes are always protected by vblank_time_lock (something I
did not verify but that the comment above asserts), then the trailing write
barrier is not required (and the assertion that it is in the comment is 
incorrect).

A spin unlock operation is always a write barrier.


Hm yeah. Otoh to me that's bordering on "code too clever for my own good".
That the spinlock is held I can assure. That no one goes around and does
multiple vblank updates (because somehow that code raced with the hw
itself) I can't easily assure with a simple assert or something similar.
It's not the case right now, but that can changes.


The algorithm would be broken if multiple updates for the same vblank
count were allowed; that's why it checks to see if the vblank count has
not advanced before storing a new timestamp.

Otherwise, the read side would not be able to determine that the
timestamp is valid by double-checking that the vblank count has not
changed.

And besides, even if the code looped without dropping the spinlock,
the correct write order would still be observed because it would still
be executing on the same cpu.

My objection to the write memory barrier is not about optimization;
it's about correct code.


Well diff=0 is not allowed, I guess I could enforce this with some
WARN_ON. And I still think my point of non-local correctness is solid.
With the smp_wmb() removed the following still works correctly:

spin_lock(vblank_time_lock);
store_vblank(dev, crtc, 1, ts1);
spin_unlock(vblank_time_lock);

spin_lock(vblank_time_lock);
store_vblank(dev, crtc, 1, ts2);
spin_unlock(vblank_time_lock);

But with the smp_wmb(); removed the following would be broken:

spin_lock(vblank_time_lock);
store_vblank(dev, crtc, 1, ts1);
store_vblank(dev, crtc, 1, ts2);
spin_unlock(vblank_tim

Re: [Intel-gfx] [PATCH-V3 1/2] drm/i915/audio: add codec wakeup override enabled/disable callback

2015-05-03 Thread Lu, Han
Hi Takashi,

Our target is to apply the patches into intel-drm-nightly tree, It will be 
great if you can help merge the patches into your tree. However I get a 
negative test result on BYT platform auto test, I'll confirm if it's caused by 
my patches, so please do not merge now and I'll give you feedback ASAP. Thanks.

Hi Jani,

Is it OK to merge both patches onto Takashi's tree? In case you may would like 
to merge the patches also, I'm not sure if there will be conflict or 
something...

BR,
Han Lu

> -Original Message-
> From: Takashi Iwai [mailto:ti...@suse.de]
> Sent: Thursday, April 30, 2015 10:21 PM
> To: Lu, Han
> Cc: Vetter, Daniel; Nikula, Jani; Yang, Libin; Lin, Mengdong; intel-
> g...@lists.freedesktop.org
> Subject: Re: [PATCH-V3 1/2] drm/i915/audio: add codec wakeup override
> enabled/disable callback
> 
> At Wed, 29 Apr 2015 17:49:25 +0800,
> han...@intel.com wrote:
> >
> > From: "Lu, Han" 
> >
> > Add support for enabling codec wakeup override signal to allow
> > re-enumeration of the controller on SKL after resume from low power
> state.
> >
> > v3 by Jani: Simplify to only support toggling the appropriate chicken bit.
> >
> > Signed-off-by: Lu, Han 
> > Signed-off-by: Jani Nikula 
> 
> The patch series look OK to me.
> But who will merge these?
> 
> I can merge these two patches to a branch so that it can be shared between
> sound and i915 trees.  Of course, only when I get ack about the first patch.
> 
> 
> thanks,
> 
> Takashi
> 
> >
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h
> > b/drivers/gpu/drm/i915/i915_reg.h index 36805b6..435c372 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -6881,6 +6881,9 @@ enum skl_disp_power_wells {
> >  #define   AUDIO_CP_READY(trans)((1 << 1) << ((trans) * 4))
> >  #define   AUDIO_ELD_VALID(trans)   ((1 << 0) << ((trans) * 4))
> >
> > +#define HSW_AUD_CHICKENBIT 0x65f10
> > +#define   SKL_AUD_CODEC_WAKE_SIGNAL(1 << 15)
> > +
> >  /* HSW Power Wells */
> >  #define HSW_PWR_WELL_BIOS  0x45400 /* CTL1 */
> >  #define HSW_PWR_WELL_DRIVER0x45404 /* CTL2 */
> > diff --git a/drivers/gpu/drm/i915/intel_audio.c
> > b/drivers/gpu/drm/i915/intel_audio.c
> > index f72e93a..ceb2328 100644
> > --- a/drivers/gpu/drm/i915/intel_audio.c
> > +++ b/drivers/gpu/drm/i915/intel_audio.c
> > @@ -474,6 +474,32 @@ static void
> i915_audio_component_put_power(struct device *dev)
> > intel_display_power_put(dev_to_i915(dev),
> POWER_DOMAIN_AUDIO);  }
> >
> > +static void i915_audio_component_codec_wake_override(struct device
> *dev,
> > +bool enable)
> > +{
> > +   struct drm_i915_private *dev_priv = dev_to_i915(dev);
> > +   u32 tmp;
> > +
> > +   if (!IS_SKYLAKE(dev_priv))
> > +   return;
> > +
> > +   /*
> > +* Enable/disable generating the codec wake signal, overriding the
> > +* internal logic to generate the codec wake to controller.
> > +*/
> > +   tmp = I915_READ(HSW_AUD_CHICKENBIT);
> > +   tmp &= ~SKL_AUD_CODEC_WAKE_SIGNAL;
> > +   I915_WRITE(HSW_AUD_CHICKENBIT, tmp);
> > +   usleep_range(1000, 1500);
> > +
> > +   if (enable) {
> > +   tmp = I915_READ(HSW_AUD_CHICKENBIT);
> > +   tmp |= SKL_AUD_CODEC_WAKE_SIGNAL;
> > +   I915_WRITE(HSW_AUD_CHICKENBIT, tmp);
> > +   usleep_range(1000, 1500);
> > +   }
> > +}
> > +
> >  /* Get CDCLK in kHz  */
> >  static int i915_audio_component_get_cdclk_freq(struct device *dev)  {
> > @@ -495,6 +521,7 @@ static const struct i915_audio_component_ops
> i915_audio_component_ops = {
> > .owner  = THIS_MODULE,
> > .get_power  = i915_audio_component_get_power,
> > .put_power  = i915_audio_component_put_power,
> > +   .codec_wake_override =
> i915_audio_component_codec_wake_override,
> > .get_cdclk_freq = i915_audio_component_get_cdclk_freq,
> >  };
> >
> > diff --git a/include/drm/i915_component.h
> > b/include/drm/i915_component.h index 3e2f22e..c9a8b64 100644
> > --- a/include/drm/i915_component.h
> > +++ b/include/drm/i915_component.h
> > @@ -31,6 +31,7 @@ struct i915_audio_component {
> > struct module *owner;
> > void (*get_power)(struct device *);
> > void (*put_power)(struct device *);
> > +   void (*codec_wake_override)(struct device *, bool enable);
> > int (*get_cdclk_freq)(struct device *);
> > } *ops;
> >  };
> > --
> > 1.9.1
> >
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx