diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2022-10-26 20:01:44 +0300 |
---|---|---|
committer | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2022-10-27 20:19:22 +0300 |
commit | 1c0ab71acc83091f55f9c9091f9959d5be565dff (patch) | |
tree | 9fc52d57d73ed9c7a7412b41f79dbb54a97a3632 /drivers/gpu | |
parent | 6e22c35ddaa19dcaa57bf9bfb4ca747ee7ce98a6 (diff) | |
download | linux-1c0ab71acc83091f55f9c9091f9959d5be565dff.tar.xz |
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: 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-10-ville.syrjala@linux.intel.com
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_audio.c | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index 7867eb670560..60b44bcaa0e4 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -304,6 +304,16 @@ static int audio_config_hdmi_get_n(const struct intel_crtc_state *crtc_state, 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, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) @@ -329,10 +339,11 @@ static void g4x_audio_codec_enable(struct intel_encoder *encoder, tmp = intel_de_read(i915, G4X_AUD_CNTL_ST); 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); + len = g4x_eld_buffer_size(i915); len = min(drm_eld_size(eld) / 4, len); + for (i = 0; i < len; i++) intel_de_write(i915, G4X_HDMIW_HDMIEDID, *((const u32 *)eld + i)); @@ -442,6 +453,17 @@ 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) @@ -615,9 +637,10 @@ 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); - /* Up to 84 bytes of hw ELD buffer */ - len = min(drm_eld_size(eld), 84); - for (i = 0; i < len / 4; i++) + len = hsw_eld_buffer_size(i915, cpu_transcoder); + len = min(drm_eld_size(eld) / 4, len); + + for (i = 0; i < len; i++) intel_de_write(i915, HSW_AUD_EDID_DATA(cpu_transcoder), *((const u32 *)eld + i)); @@ -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, ®s); + + 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, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) @@ -732,9 +769,10 @@ static void ilk_audio_codec_enable(struct intel_encoder *encoder, tmp &= ~IBX_ELD_ADDRESS_MASK; intel_de_write(i915, regs.aud_cntl_st, tmp); - /* Up to 84 bytes of hw ELD buffer */ - len = min(drm_eld_size(eld), 84); - for (i = 0; i < len / 4; i++) + len = ilk_eld_buffer_size(i915, pipe); + len = min(drm_eld_size(eld) / 4, len); + + for (i = 0; i < len; i++) intel_de_write(i915, regs.hdmiw_hdmiedid, *((const u32 *)eld + i)); |