summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2022-10-26 20:01:45 +0300
committerVille Syrjälä <ville.syrjala@linux.intel.com>2022-10-27 20:19:26 +0300
commit0234cda2ceb9b90da55e3bc43dfda451b152acb1 (patch)
tree2ba7f10dc70598807ea07f8c6ad06f4d6be31fbb /drivers/gpu
parent1c0ab71acc83091f55f9c9091f9959d5be565dff (diff)
downloadlinux-0234cda2ceb9b90da55e3bc43dfda451b152acb1.tar.xz
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: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20221026170150.2654-11-ville.syrjala@linux.intel.com
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/display/intel_audio.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c
index 60b44bcaa0e4..56f0d8af313e 100644
--- a/drivers/gpu/drm/i915/display/intel_audio.c
+++ b/drivers/gpu/drm/i915/display/intel_audio.c
@@ -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_connector *connector = conn_state->connector;
const u8 *eld = connector->eld;
+ int eld_buffer_size, len, i;
u32 tmp;
- int len, i;
tmp = intel_de_read(i915, G4X_AUD_CNTL_ST);
tmp &= ~(G4X_ELD_VALID | G4X_ELD_ADDRESS_MASK);
intel_de_write(i915, G4X_AUD_CNTL_ST, tmp);
- len = g4x_eld_buffer_size(i915);
- len = min(drm_eld_size(eld) / 4, len);
+ eld_buffer_size = g4x_eld_buffer_size(i915);
+ len = min(drm_eld_size(eld) / 4, eld_buffer_size);
for (i = 0; i < len; i++)
intel_de_write(i915, G4X_HDMIW_HDMIEDID,
*((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 |= G4X_ELD_VALID;
@@ -610,8 +615,8 @@ static void hsw_audio_codec_enable(struct intel_encoder *encoder,
struct drm_connector *connector = conn_state->connector;
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
const u8 *eld = connector->eld;
+ int eld_buffer_size, len, i;
u32 tmp;
- int len, i;
mutex_lock(&i915->display.audio.mutex);
@@ -637,12 +642,18 @@ static void hsw_audio_codec_enable(struct intel_encoder *encoder,
tmp &= ~IBX_ELD_ADDRESS_MASK;
intel_de_write(i915, HSW_AUD_DIP_ELD_CTRL(cpu_transcoder), tmp);
- len = hsw_eld_buffer_size(i915, cpu_transcoder);
- len = min(drm_eld_size(eld) / 4, len);
+ eld_buffer_size = hsw_eld_buffer_size(i915, cpu_transcoder);
+ len = min(drm_eld_size(eld) / 4, eld_buffer_size);
for (i = 0; i < len; i++)
intel_de_write(i915, HSW_AUD_EDID_DATA(cpu_transcoder),
*((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 */
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,
enum pipe pipe = crtc->pipe;
enum port port = encoder->port;
const u8 *eld = connector->eld;
+ int eld_buffer_size, len, i;
struct ilk_audio_regs regs;
- int len, i;
u32 tmp;
if (drm_WARN_ON(&i915->drm, port == PORT_A))
@@ -769,12 +780,17 @@ static void ilk_audio_codec_enable(struct intel_encoder *encoder,
tmp &= ~IBX_ELD_ADDRESS_MASK;
intel_de_write(i915, regs.aud_cntl_st, tmp);
- len = ilk_eld_buffer_size(i915, pipe);
- len = min(drm_eld_size(eld) / 4, len);
+ eld_buffer_size = ilk_eld_buffer_size(i915, pipe);
+ len = min(drm_eld_size(eld) / 4, eld_buffer_size);
for (i = 0; i < len; i++)
intel_de_write(i915, regs.hdmiw_hdmiedid,
*((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 */
tmp = intel_de_read(i915, regs.aud_cntrl_st2);