Commit 0234cda2 authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915/audio: Make sure we write the whole ELD buffer

Currently we only write as many dwords into the hardware
ELD buffers as drm_eld_size() tells us. That could mean the
remainder of the hardware buffer is left with whatever
stale garbage it had before, which doesn't seem entirely
great. Let's zero out the remainder of the buffer in case
the provided ELD doesn't fill it fully.

We can also sanity check out idea of the hardware ELD buffer's
size by making sure the address wrapped back to zero once
we wrote the entire buffer.

Cc: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Cc: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Cc: Takashi Iwai <tiwai@suse.de>
Reviewed-by: default avatarJani Nikula <jani.nikula@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/20221026170150.2654-11-ville.syrjala@linux.intel.com
parent 1c0ab71a
...@@ -334,19 +334,24 @@ static void g4x_audio_codec_enable(struct intel_encoder *encoder, ...@@ -334,19 +334,24 @@ static void g4x_audio_codec_enable(struct intel_encoder *encoder,
struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct drm_connector *connector = conn_state->connector; struct drm_connector *connector = conn_state->connector;
const u8 *eld = connector->eld; const u8 *eld = connector->eld;
int eld_buffer_size, len, i;
u32 tmp; u32 tmp;
int len, i;
tmp = intel_de_read(i915, G4X_AUD_CNTL_ST); tmp = intel_de_read(i915, G4X_AUD_CNTL_ST);
tmp &= ~(G4X_ELD_VALID | G4X_ELD_ADDRESS_MASK); tmp &= ~(G4X_ELD_VALID | G4X_ELD_ADDRESS_MASK);
intel_de_write(i915, G4X_AUD_CNTL_ST, tmp); intel_de_write(i915, G4X_AUD_CNTL_ST, tmp);
len = g4x_eld_buffer_size(i915); eld_buffer_size = g4x_eld_buffer_size(i915);
len = min(drm_eld_size(eld) / 4, len); len = min(drm_eld_size(eld) / 4, eld_buffer_size);
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
intel_de_write(i915, G4X_HDMIW_HDMIEDID, intel_de_write(i915, G4X_HDMIW_HDMIEDID,
*((const u32 *)eld + i)); *((const u32 *)eld + i));
for (; i < eld_buffer_size; i++)
intel_de_write(i915, G4X_HDMIW_HDMIEDID, 0);
drm_WARN_ON(&i915->drm,
(intel_de_read(i915, G4X_AUD_CNTL_ST) & G4X_ELD_ADDRESS_MASK) != 0);
tmp = intel_de_read(i915, G4X_AUD_CNTL_ST); tmp = intel_de_read(i915, G4X_AUD_CNTL_ST);
tmp |= G4X_ELD_VALID; tmp |= G4X_ELD_VALID;
...@@ -610,8 +615,8 @@ static void hsw_audio_codec_enable(struct intel_encoder *encoder, ...@@ -610,8 +615,8 @@ static void hsw_audio_codec_enable(struct intel_encoder *encoder,
struct drm_connector *connector = conn_state->connector; struct drm_connector *connector = conn_state->connector;
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
const u8 *eld = connector->eld; const u8 *eld = connector->eld;
int eld_buffer_size, len, i;
u32 tmp; u32 tmp;
int len, i;
mutex_lock(&i915->display.audio.mutex); mutex_lock(&i915->display.audio.mutex);
...@@ -637,12 +642,18 @@ static void hsw_audio_codec_enable(struct intel_encoder *encoder, ...@@ -637,12 +642,18 @@ static void hsw_audio_codec_enable(struct intel_encoder *encoder,
tmp &= ~IBX_ELD_ADDRESS_MASK; tmp &= ~IBX_ELD_ADDRESS_MASK;
intel_de_write(i915, HSW_AUD_DIP_ELD_CTRL(cpu_transcoder), tmp); intel_de_write(i915, HSW_AUD_DIP_ELD_CTRL(cpu_transcoder), tmp);
len = hsw_eld_buffer_size(i915, cpu_transcoder); eld_buffer_size = hsw_eld_buffer_size(i915, cpu_transcoder);
len = min(drm_eld_size(eld) / 4, len); len = min(drm_eld_size(eld) / 4, eld_buffer_size);
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
intel_de_write(i915, HSW_AUD_EDID_DATA(cpu_transcoder), intel_de_write(i915, HSW_AUD_EDID_DATA(cpu_transcoder),
*((const u32 *)eld + i)); *((const u32 *)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 */ /* ELD valid */
tmp = intel_de_read(i915, HSW_AUD_PIN_ELD_CP_VLD); tmp = intel_de_read(i915, HSW_AUD_PIN_ELD_CP_VLD);
...@@ -741,8 +752,8 @@ static void ilk_audio_codec_enable(struct intel_encoder *encoder, ...@@ -741,8 +752,8 @@ static void ilk_audio_codec_enable(struct intel_encoder *encoder,
enum pipe pipe = crtc->pipe; enum pipe pipe = crtc->pipe;
enum port port = encoder->port; enum port port = encoder->port;
const u8 *eld = connector->eld; const u8 *eld = connector->eld;
int eld_buffer_size, len, i;
struct ilk_audio_regs regs; struct ilk_audio_regs regs;
int len, i;
u32 tmp; u32 tmp;
if (drm_WARN_ON(&i915->drm, port == PORT_A)) if (drm_WARN_ON(&i915->drm, port == PORT_A))
...@@ -769,12 +780,17 @@ static void ilk_audio_codec_enable(struct intel_encoder *encoder, ...@@ -769,12 +780,17 @@ static void ilk_audio_codec_enable(struct intel_encoder *encoder,
tmp &= ~IBX_ELD_ADDRESS_MASK; tmp &= ~IBX_ELD_ADDRESS_MASK;
intel_de_write(i915, regs.aud_cntl_st, tmp); intel_de_write(i915, regs.aud_cntl_st, tmp);
len = ilk_eld_buffer_size(i915, pipe); eld_buffer_size = ilk_eld_buffer_size(i915, pipe);
len = min(drm_eld_size(eld) / 4, len); len = min(drm_eld_size(eld) / 4, eld_buffer_size);
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
intel_de_write(i915, regs.hdmiw_hdmiedid, intel_de_write(i915, regs.hdmiw_hdmiedid,
*((const u32 *)eld + i)); *((const u32 *)eld + i));
for (; i < eld_buffer_size; i++)
intel_de_write(i915, regs.hdmiw_hdmiedid, 0);
drm_WARN_ON(&i915->drm,
(intel_de_read(i915, regs.aud_cntl_st) & IBX_ELD_ADDRESS_MASK) != 0);
/* ELD valid */ /* ELD valid */
tmp = intel_de_read(i915, regs.aud_cntrl_st2); tmp = intel_de_read(i915, regs.aud_cntrl_st2);
......
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