From: han.lu@intel.com
To: daniel.vetter@intel.com, tiwai@suse.de, jani.nikula@intel.com,
libin.yang@intel.com, mengdong.lin@intel.com,
intel-gfx@lists.freedesktop.org
Cc: "Lu, Han" <han.lu@intel.com>
Subject: [PATCH-V2 1/2] drm/i915: add callback to enable/disable codec wakeup
Date: Tue, 28 Apr 2015 18:38:46 +0800 [thread overview]
Message-ID: <1430217527-19937-1-git-send-email-han.lu@intel.com> (raw)
From: "Lu, Han" <han.lu@intel.com>
In SKL, HDMI/DP codec and PCH HD Audio Controller are in different
power wells, so it's necessary to reset display audio codecs when
power well on, otherwise display audio codecs will disappear when
resume from low power state.
The reset step when power on is:
enable codec wakeup -> azx_init_chip() -> disable codec wakeup
The callback is defined in drivers/gpu/drm/i915/.
The caller is in sound/pci/hda/.
Signed-off-by: Lu, Han <han.lu@intel.com>
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f3c77ca..efcf900 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1143,6 +1143,11 @@ struct i915_power_domains {
struct i915_power_well *power_wells;
};
+struct i915_audio_priv {
+ struct mutex lock;
+ int audio_power_cnt;
+};
+
#define MAX_L3_SLICES 2
struct intel_l3_parity {
u32 *remap_info[MAX_L3_SLICES];
@@ -1757,6 +1762,8 @@ struct drm_i915_private {
/* hda/i915 audio component */
bool audio_component_registered;
+ struct i915_audio_priv audio_priv;
+
uint32_t hw_context_size;
struct list_head context_list;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 36805b6..efdccaf 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 AUD_CODEC_WAKE_SIGNAL (1 << 15)
+
/* HSW Power Wells */
#define HSW_PWR_WELL_BIOS 0x45400 /* CTL1 */
#define HSW_PWR_WELL_DRIVER 0x45404 /* CTL2 */
diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c
index f72e93a..e0cf2b9 100644
--- a/drivers/gpu/drm/i915/intel_audio.c
+++ b/drivers/gpu/drm/i915/intel_audio.c
@@ -448,6 +448,9 @@ void intel_audio_codec_disable(struct intel_encoder *encoder)
void intel_init_audio(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+ struct i915_audio_priv *audio_priv = &dev_priv->audio_priv;
+
+ mutex_init(&audio_priv->lock);
if (IS_G4X(dev)) {
dev_priv->display.audio_codec_enable = g4x_audio_codec_enable;
@@ -474,6 +477,60 @@ 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_enable_codec_wakeup(struct device *dev)
+{
+ struct drm_i915_private *dev_priv = dev_to_i915(dev);
+ struct i915_audio_priv *audio_priv = &dev_priv->audio_priv;
+ u32 tmp;
+
+ if (!IS_SKYLAKE(dev_priv->dev))
+ return;
+
+ mutex_lock(&audio_priv->lock);
+
+ /* SKL need reset the CHICKENBIT bit 15 after power on codec */
+ if (audio_priv->audio_power_cnt == 0) {
+ tmp = I915_READ(HSW_AUD_CHICKENBIT);
+ tmp &= ~AUD_CODEC_WAKE_SIGNAL;
+ I915_WRITE(HSW_AUD_CHICKENBIT, tmp);
+ mdelay(1);
+
+ tmp = I915_READ(HSW_AUD_CHICKENBIT);
+ tmp |= AUD_CODEC_WAKE_SIGNAL;
+ I915_WRITE(HSW_AUD_CHICKENBIT, tmp);
+ mdelay(1);
+ }
+
+ audio_priv->audio_power_cnt++;
+
+ mutex_unlock(&audio_priv->lock);
+}
+
+static void i915_audio_component_disable_codec_wakeup(struct device *dev)
+{
+ struct drm_i915_private *dev_priv = dev_to_i915(dev);
+ struct i915_audio_priv *audio_priv = &dev_priv->audio_priv;
+ u32 tmp;
+
+ if (!IS_SKYLAKE(dev_priv->dev))
+ return;
+
+ mutex_lock(&audio_priv->lock);
+
+ audio_priv->audio_power_cnt--;
+ if (audio_priv->audio_power_cnt < 0)
+ dev_warn(dev, "audio_power_cnt(%d) < 0\n",
+ audio_priv->audio_power_cnt);
+
+ /* SKL need clear the CHICKENBIT bit 15 after codec detected */
+ tmp = I915_READ(HSW_AUD_CHICKENBIT);
+ tmp &= ~AUD_CODEC_WAKE_SIGNAL;
+ I915_WRITE(HSW_AUD_CHICKENBIT, tmp);
+ mdelay(1);
+
+ mutex_unlock(&audio_priv->lock);
+}
+
/* Get CDCLK in kHz */
static int i915_audio_component_get_cdclk_freq(struct device *dev)
{
@@ -495,6 +552,8 @@ 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,
+ .enable_codec_wakeup = i915_audio_component_enable_codec_wakeup,
+ .disable_codec_wakeup = i915_audio_component_disable_codec_wakeup,
.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..1d57aae 100644
--- a/include/drm/i915_component.h
+++ b/include/drm/i915_component.h
@@ -31,6 +31,8 @@ struct i915_audio_component {
struct module *owner;
void (*get_power)(struct device *);
void (*put_power)(struct device *);
+ void (*enable_codec_wakeup)(struct device *);
+ void (*disable_codec_wakeup)(struct device *);
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
next reply other threads:[~2015-04-28 10:39 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-28 10:38 han.lu [this message]
2015-04-28 10:38 ` [PATCH-V2 2/2] ALSA:hda - reset display codec when power on han.lu
2015-04-28 14:57 ` shuang.he
2015-04-28 14:21 ` [PATCH-V2 1/2] drm/i915: add callback to enable/disable codec wakeup Jani Nikula
2015-04-29 9:41 ` Lu, Han
2015-05-04 15:07 ` Daniel Vetter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1430217527-19937-1-git-send-email-han.lu@intel.com \
--to=han.lu@intel.com \
--cc=daniel.vetter@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=jani.nikula@intel.com \
--cc=libin.yang@intel.com \
--cc=mengdong.lin@intel.com \
--cc=tiwai@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox