Commit 68470541 authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915/audio: Don't program the hardware ELD buffer on hsw+

Since we use the audio component to transfer the ELD to the audio
driver on hsw+ platforms there is no point in even programming
the hardware ELD buffer. Stop doing so.

The one slight caveat here is that this is not strictly legal
according to the HDA spec. PD=1;ELD=0 is only documented as
an intermediate state during modeset. But if there is no hardware
that depends on that then I guess we're fine. Or we could
perhaps set ELD=1 without actually programming the buffer?

Note that the bspec sequence of PD=0;ELD=0 -> PD=1;ELD=0 ->
PD=1;ELD=1 is also not strictly correct according to the HDA
spec, as the only documented transition from PD=0;ELD=0 is
straight to PD=1;ELD=1.

Additionally on hsw/bdw the hardware buffer is tied in with the
dedicated display HDA controller's power state, so currently
we mostly fail at proramming the buffer anyway. When the HDA
side is not sufficiently powered up the ELD address bits get
stuck and the ELD data register accesses go nowhere.

Cc: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Cc: Takashi Iwai <tiwai@suse.de>
References: https://lore.kernel.org/intel-gfx/20221012104936.30911-1-ville.syrjala@linux.intel.com/Reviewed-by: default avatarKai Vehmanen <kai.vehmanen@linux.intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230124144628.4649-3-ville.syrjala@linux.intel.com
parent 343cb0f9
......@@ -459,17 +459,6 @@ hsw_audio_config_update(struct intel_encoder *encoder,
hsw_hdmi_audio_config_update(encoder, crtc_state);
}
/* ELD buffer size in dwords */
static int hsw_eld_buffer_size(struct drm_i915_private *i915,
enum transcoder cpu_transcoder)
{
u32 tmp;
tmp = intel_de_read(i915, HSW_AUD_DIP_ELD_CTRL(cpu_transcoder));
return REG_FIELD_GET(IBX_ELD_BUFFER_SIZE_MASK, tmp);
}
static void hsw_audio_codec_disable(struct intel_encoder *encoder,
const struct intel_crtc_state *old_crtc_state,
const struct drm_connector_state *old_conn_state)
......@@ -618,10 +607,7 @@ static void hsw_audio_codec_enable(struct intel_encoder *encoder,
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_connector *connector = conn_state->connector;
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
const u32 *eld = (const u32 *)connector->eld;
int eld_buffer_size, len, i;
mutex_lock(&i915->display.audio.mutex);
......@@ -639,25 +625,10 @@ static void hsw_audio_codec_enable(struct intel_encoder *encoder,
intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD,
AUDIO_ELD_VALID(cpu_transcoder), 0);
/* Reset ELD address */
intel_de_rmw(i915, HSW_AUD_DIP_ELD_CTRL(cpu_transcoder),
IBX_ELD_ADDRESS_MASK, 0);
eld_buffer_size = hsw_eld_buffer_size(i915, cpu_transcoder);
len = min(drm_eld_size(connector->eld) / 4, eld_buffer_size);
for (i = 0; i < len; i++)
intel_de_write(i915, HSW_AUD_EDID_DATA(cpu_transcoder), eld[i]);
for (; i < eld_buffer_size; i++)
intel_de_write(i915, HSW_AUD_EDID_DATA(cpu_transcoder), 0);
drm_WARN_ON(&i915->drm,
(intel_de_read(i915, HSW_AUD_DIP_ELD_CTRL(cpu_transcoder)) &
IBX_ELD_ADDRESS_MASK) != 0);
/* ELD valid */
intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD,
0, AUDIO_ELD_VALID(cpu_transcoder));
/*
* The audio componenent is used to convey the ELD
* instead using of the hardware ELD buffer.
*/
/* Enable timestamps */
hsw_audio_config_update(encoder, crtc_state);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment