diff mbox series

[09/22] drm/i915/audio: Read ELD buffer size from hardware

Message ID 20221011170011.17198-10-ville.syrjala@linux.intel.com (mailing list archive)
State New, archived
Headers show
Series drm/i915: ELD precompute and readout | expand

Commit Message

Ville Syrjälä Oct. 11, 2022, 4:59 p.m. UTC
From: Ville Syrjälä <ville.syrjala@linux.intel.com>

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...

Cc: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Cc: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Cc: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_audio.c | 49 ++++++++++++++++++----
 1 file changed, 42 insertions(+), 7 deletions(-)

Comments

Jani Nikula Oct. 12, 2022, 2:41 p.m. UTC | #1
On Tue, 11 Oct 2022, Ville Syrjala <ville.syrjala@linux.intel.com> wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> 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...
>
> Cc: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
> Cc: Kai Vehmanen <kai.vehmanen@linux.intel.com>
> Cc: Takashi Iwai <tiwai@suse.de>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Reviewed-by: Jani Nikula <jani.nikula@intel.com>

> ---
>  drivers/gpu/drm/i915/display/intel_audio.c | 49 ++++++++++++++++++----
>  1 file changed, 42 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c
> index 3f328913fc90..abca5f23673a 100644
> --- a/drivers/gpu/drm/i915/display/intel_audio.c
> +++ b/drivers/gpu/drm/i915/display/intel_audio.c
> @@ -304,6 +304,15 @@ static int audio_config_hdmi_get_n(const struct intel_crtc_state *crtc_state,
>  	return 0;
>  }
>  
> +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 +338,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 +452,16 @@ hsw_audio_config_update(struct intel_encoder *encoder,
>  		hsw_hdmi_audio_config_update(encoder, crtc_state);
>  }
>  
> +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 +635,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 +679,19 @@ static void ilk_audio_regs_init(struct drm_i915_private *i915,
>  	}
>  }
>  
> +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,
>  				    const struct intel_crtc_state *old_crtc_state,
>  				    const struct drm_connector_state *old_conn_state)
> @@ -732,9 +766,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));
Jani Nikula Oct. 12, 2022, 2:46 p.m. UTC | #2
On Wed, 12 Oct 2022, Jani Nikula <jani.nikula@linux.intel.com> wrote:
> On Tue, 11 Oct 2022, Ville Syrjala <ville.syrjala@linux.intel.com> wrote:
>> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>>
>> 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...
>>
>> Cc: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
>> Cc: Kai Vehmanen <kai.vehmanen@linux.intel.com>
>> Cc: Takashi Iwai <tiwai@suse.de>
>> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> Reviewed-by: Jani Nikula <jani.nikula@intel.com>

Might add comments above the *_eld_buffer_size() functions to indicate
they return the buffer size in dwords, not bytes which would be the
obvious thing.

>
>> ---
>>  drivers/gpu/drm/i915/display/intel_audio.c | 49 ++++++++++++++++++----
>>  1 file changed, 42 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c
>> index 3f328913fc90..abca5f23673a 100644
>> --- a/drivers/gpu/drm/i915/display/intel_audio.c
>> +++ b/drivers/gpu/drm/i915/display/intel_audio.c
>> @@ -304,6 +304,15 @@ static int audio_config_hdmi_get_n(const struct intel_crtc_state *crtc_state,
>>  	return 0;
>>  }
>>  
>> +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 +338,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 +452,16 @@ hsw_audio_config_update(struct intel_encoder *encoder,
>>  		hsw_hdmi_audio_config_update(encoder, crtc_state);
>>  }
>>  
>> +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 +635,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 +679,19 @@ static void ilk_audio_regs_init(struct drm_i915_private *i915,
>>  	}
>>  }
>>  
>> +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,
>>  				    const struct intel_crtc_state *old_crtc_state,
>>  				    const struct drm_connector_state *old_conn_state)
>> @@ -732,9 +766,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));
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c
index 3f328913fc90..abca5f23673a 100644
--- a/drivers/gpu/drm/i915/display/intel_audio.c
+++ b/drivers/gpu/drm/i915/display/intel_audio.c
@@ -304,6 +304,15 @@  static int audio_config_hdmi_get_n(const struct intel_crtc_state *crtc_state,
 	return 0;
 }
 
+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 +338,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 +452,16 @@  hsw_audio_config_update(struct intel_encoder *encoder,
 		hsw_hdmi_audio_config_update(encoder, crtc_state);
 }
 
+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 +635,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 +679,19 @@  static void ilk_audio_regs_init(struct drm_i915_private *i915,
 	}
 }
 
+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,
 				    const struct intel_crtc_state *old_crtc_state,
 				    const struct drm_connector_state *old_conn_state)
@@ -732,9 +766,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));