Commit 1c0ab71a authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915/audio: Read ELD buffer size from hardware

We currently read the ELD buffer size from hardware on g4x,
but on ilk+ we just hardcode it to 84 bytes. Let's unify
this and just do the hardware readout on all platforms,
in case the size changes in the future or something.

TODO: should perhaps do the readout during driver init and
stash the results somewhere so that we could check that the
connector's ELD actually fits and not even try to enable audio
in that case...

v2: Document the size is in dwords (Jani)

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-10-ville.syrjala@linux.intel.com
parent 6e22c35d
...@@ -304,6 +304,16 @@ static int audio_config_hdmi_get_n(const struct intel_crtc_state *crtc_state, ...@@ -304,6 +304,16 @@ static int audio_config_hdmi_get_n(const struct intel_crtc_state *crtc_state,
return 0; return 0;
} }
/* ELD buffer size in dwords */
static int g4x_eld_buffer_size(struct drm_i915_private *i915)
{
u32 tmp;
tmp = intel_de_read(i915, G4X_AUD_CNTL_ST);
return REG_FIELD_GET(G4X_ELD_BUFFER_SIZE_MASK, tmp);
}
static void g4x_audio_codec_disable(struct intel_encoder *encoder, static void g4x_audio_codec_disable(struct intel_encoder *encoder,
const struct intel_crtc_state *old_crtc_state, const struct intel_crtc_state *old_crtc_state,
const struct drm_connector_state *old_conn_state) const struct drm_connector_state *old_conn_state)
...@@ -329,10 +339,11 @@ static void g4x_audio_codec_enable(struct intel_encoder *encoder, ...@@ -329,10 +339,11 @@ static void g4x_audio_codec_enable(struct intel_encoder *encoder,
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);
len = REG_FIELD_GET(G4X_ELD_BUFFER_SIZE_MASK, tmp);
intel_de_write(i915, G4X_AUD_CNTL_ST, tmp); intel_de_write(i915, G4X_AUD_CNTL_ST, tmp);
len = g4x_eld_buffer_size(i915);
len = min(drm_eld_size(eld) / 4, len); len = min(drm_eld_size(eld) / 4, len);
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));
...@@ -442,6 +453,17 @@ hsw_audio_config_update(struct intel_encoder *encoder, ...@@ -442,6 +453,17 @@ hsw_audio_config_update(struct intel_encoder *encoder,
hsw_hdmi_audio_config_update(encoder, crtc_state); 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, static void hsw_audio_codec_disable(struct intel_encoder *encoder,
const struct intel_crtc_state *old_crtc_state, const struct intel_crtc_state *old_crtc_state,
const struct drm_connector_state *old_conn_state) const struct drm_connector_state *old_conn_state)
...@@ -615,9 +637,10 @@ static void hsw_audio_codec_enable(struct intel_encoder *encoder, ...@@ -615,9 +637,10 @@ 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);
/* Up to 84 bytes of hw ELD buffer */ len = hsw_eld_buffer_size(i915, cpu_transcoder);
len = min(drm_eld_size(eld), 84); len = min(drm_eld_size(eld) / 4, len);
for (i = 0; i < len / 4; 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));
...@@ -658,6 +681,20 @@ static void ilk_audio_regs_init(struct drm_i915_private *i915, ...@@ -658,6 +681,20 @@ static void ilk_audio_regs_init(struct drm_i915_private *i915,
} }
} }
/* ELD buffer size in dwords */
static int ilk_eld_buffer_size(struct drm_i915_private *i915,
enum pipe pipe)
{
struct ilk_audio_regs regs;
u32 tmp;
ilk_audio_regs_init(i915, pipe, &regs);
tmp = intel_de_read(i915, regs.aud_cntl_st);
return REG_FIELD_GET(IBX_ELD_BUFFER_SIZE_MASK, tmp);
}
static void ilk_audio_codec_disable(struct intel_encoder *encoder, static void ilk_audio_codec_disable(struct intel_encoder *encoder,
const struct intel_crtc_state *old_crtc_state, const struct intel_crtc_state *old_crtc_state,
const struct drm_connector_state *old_conn_state) const struct drm_connector_state *old_conn_state)
...@@ -732,9 +769,10 @@ static void ilk_audio_codec_enable(struct intel_encoder *encoder, ...@@ -732,9 +769,10 @@ 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);
/* Up to 84 bytes of hw ELD buffer */ len = ilk_eld_buffer_size(i915, pipe);
len = min(drm_eld_size(eld), 84); len = min(drm_eld_size(eld) / 4, len);
for (i = 0; i < len / 4; 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));
......
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