drm/i915: hdmi/dp audio rework
Subsystems (2)
PATCH 1/18 drm/i915: add new intel audio file to group DP/HDMI audio
In reply to Jani NikulaIn preparation for some additional cleanup. No functional changes.
--- drivers/gpu/drm/i915/Makefile | 3 +- drivers/gpu/drm/i915/intel_audio.c | 352 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 321 +------------------------------- drivers/gpu/drm/i915/intel_drv.h | 8 +- 4 files changed, 363 insertions(+), 321 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_audio.c
drivers/gpu/drm/i915/Makefile +2 -1
@@ -43,7 +43,8 @@ i915-y += intel_renderstate_gen6.o \ intel_renderstate_gen8.o # modesetting core code -i915-y += intel_bios.o \ +i915-y += intel_audio.o \ + intel_bios.o \ intel_display.o \ intel_frontbuffer.o \ intel_modes.o \
drivers/gpu/drm/i915/intel_audio.c new file +352 -0
352 lines not on this page · raw message
drivers/gpu/drm/i915/intel_display.c +3 -318
363 lines not on this page · raw message
drivers/gpu/drm/i915/intel_drv.h +6 -2
@@ -839,6 +839,11 @@ void intel_frontbuffer_flip(struct drm_device *dev,void intel_fb_obj_flush (struct drm_i915_gem_object *obj,bool retire); +/* intel_audio.c */ +void intel_init_audio (struct drm_device *dev); +void intel_write_eld (struct drm_encoder *encoder, +struct drm_display_mode *mode); +/* intel_display.c */ const char *intel_output_name (int output);bool intel_has_pending_fb_unpin (struct drm_device *dev);
@@ -864,6 +869,7 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, struct drm_file *file_priv);enum transcoder intel_pipe_to_cpu_transcoder (struct drm_i915_private *dev_priv,enum pipe pipe); +bool intel_pipe_has_type (struct drm_crtc *crtc,int type);static inline void intel_wait_for_vblank (struct drm_device *dev,int pipe) {
@@ -915,8 +921,6 @@ void assert_fdi_rx_pll(struct drm_i915_private *dev_priv,void assert_pipe (struct drm_i915_private *dev_priv,enum pipe pipe,bool state);#define assert_pipe_enabled (d, p) assert_pipe(d, p, true)#define assert_pipe_disabled (d, p) assert_pipe(d, p, false) -void intel_write_eld (struct drm_encoder *encoder, -struct drm_display_mode *mode); unsigned long intel_gen4_compute_page_offset(int *x, int *y, unsigned int tiling_mode, unsigned int bpp,
Signature · 6 lines
1.9.1 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
cover drm/i915: hdmi/dp audio rework
So I set out to split out the audio stuff into its own file, doing some cleanups and maybe fixing a bug or two along the way. Here's the first 18 patches. ;)
There's still some issues with vblank waits that need to be revisited, but I wanted to get early feedback anyway. So disregard those bits for now. Everything else should be close to ready.
This has only gotten light testing, in particular no testing over DP audio yet because I don't have a sink that supports it. Also no testing on hsw/bdw yet.
BR,
Jani.
Jani Nikula (18):
drm/i915: add new intel audio file to group DP/HDMI audio drm/i915/audio: constify hdmi audio clock struct drm/i915/audio: beat some sense into the variable types and names drm/i915: pass intel_encoder to intel_write_eld drm/i915/audio: pass intel_encoder on to platform specific ELD
functions
drm/i915/audio: set ELD Conn_Type at one place drm/i915/ddi: write ELD where it's supposed to be done drm/i915: introduce intel_audio_codec_{enable,disable} drm/i915/audio: remove misleading checks for !eld[0] drm/i915: clean up and clarify audio related register defines drm/i915: rewrite hsw/bdw audio codec enable/disable sequences drm/i915/audio: rewrite vlv/chv and gen 5-7 audio codec enable
sequence
drm/i915/audio: add vlv/chv/gen5-7 audio codec disable sequence drm/i915: enable audio codec after port
drm/i915/audio: add audio codec disable on g4x drm/i915/audio: add audio codec enable debug log for g4x drm/i915: make pipe/port based audio valid accessors easier to use drm/i915/audio: add DOC comment describing HDA over HDMI/DP
drivers/gpu/drm/i915/Makefile | 3 +- drivers/gpu/drm/i915/i915_drv.h | 9 +- drivers/gpu/drm/i915/i915_reg.h | 181 +++++++-------- drivers/gpu/drm/i915/intel_audio.c | 435 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_ddi.c | 26 +-- drivers/gpu/drm/i915/intel_display.c | 321 +------------------------- drivers/gpu/drm/i915/intel_dp.c | 17 +- drivers/gpu/drm/i915/intel_drv.h | 8 +- drivers/gpu/drm/i915/intel_hdmi.c | 19 +- 9 files changed, 564 insertions(+), 455 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_audio.c
Signature · 1 line
1.9.1
PATCH 3/18 drm/i915/audio: beat some sense into the variable types and names
Most importantly, "i" need not be the universal variable used for everything. No functional changes.
--- drivers/gpu/drm/i915/intel_audio.c | 115 ++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 58 deletions(-)
drivers/gpu/drm/i915/intel_audio.c +57 -58
@@ -73,20 +73,21 @@ static bool intel_eld_uptodate(struct drm_connector *connector, {struct drm_i915_private *dev_priv = connector->dev->dev_private;uint8_t *eld = connector->eld; -uint32_t i; +uint32_t tmp; +int i; - i =I915_READ (reg_eldv); - i &= bits_eldv; + tmp =I915_READ (reg_eldv); + tmp &= bits_eldv;if (!eld[0 ]) -return !i; +return !tmp; -if (!i) +if (!tmp)return false; - i =I915_READ (reg_elda); - i &= ~bits_elda; -I915_WRITE (reg_elda, i); + tmp =I915_READ (reg_elda); + tmp &= ~bits_elda; +I915_WRITE (reg_elda, tmp);for (i =0 ; i < eld[2 ]; i++)if (I915_READ (reg_edid) != *((uint32_t *)eld + i))
@@ -102,12 +103,11 @@ static void g4x_write_eld(struct drm_connector *connector,struct drm_i915_private *dev_priv = connector->dev->dev_private;uint8_t *eld = connector->eld;uint32_t eldv; -uint32_t len; -uint32_t i; - - i =I915_READ (G4X_AUD_VID_DID ); +uint32_t tmp; +int len, i; -if (i ==INTEL_AUDIO_DEVBLC || i ==INTEL_AUDIO_DEVCL ) + tmp =I915_READ (G4X_AUD_VID_DID ); +if (tmp ==INTEL_AUDIO_DEVBLC || tmp ==INTEL_AUDIO_DEVCL ) eldv =G4X_ELDV_DEVCL_DEVBLC ;else eldv =G4X_ELDV_DEVCTG ;
@@ -118,22 +118,22 @@ static void g4x_write_eld(struct drm_connector *connector, G4X_HDMIW_HDMIEDID))return ; - i =I915_READ (G4X_AUD_CNTL_ST ); - i &= ~(eldv |G4X_ELD_ADDR ); - len = (i >>9 ) &0x1f ;/* ELD buffer size */ -I915_WRITE (G4X_AUD_CNTL_ST , i); + tmp =I915_READ (G4X_AUD_CNTL_ST ); + tmp &= ~(eldv |G4X_ELD_ADDR ); + len = (tmp >>9 ) &0x1f ;/* ELD buffer size */ +I915_WRITE (G4X_AUD_CNTL_ST , tmp);if (!eld[0 ])return ; - len =min_t (uint8_t, eld[2 ], len); + len =min_t (int, eld[2 ], len);DRM_DEBUG_DRIVER ("ELD size %d\n" , len);for (i =0 ; i < len; i++)I915_WRITE (G4X_HDMIW_HDMIEDID , *((uint32_t *)eld + i)); - i =I915_READ (G4X_AUD_CNTL_ST ); - i |= eldv; -I915_WRITE (G4X_AUD_CNTL_ST , i); + tmp =I915_READ (G4X_AUD_CNTL_ST ); + tmp |= eldv; +I915_WRITE (G4X_AUD_CNTL_ST , tmp); } static void haswell_write_eld(struct drm_connector *connector,
@@ -143,11 +143,10 @@ static void haswell_write_eld(struct drm_connector *connector,struct drm_i915_private *dev_priv = connector->dev->dev_private;uint8_t *eld = connector->eld;uint32_t eldv; -uint32_t i; -int len; -int pipe =to_intel_crtc (crtc)->pipe; -int tmp; - +uint32_t tmp; +int len, i; +enum pipe pipe =to_intel_crtc (crtc)->pipe; +enum port port;int hdmiw_hdmiedid =HSW_AUD_EDID_DATA (pipe);int aud_cntl_st =HSW_AUD_DIP_ELD_CTRL (pipe);int aud_config =HSW_AUD_CFG (pipe);
@@ -195,28 +194,27 @@ static void haswell_write_eld(struct drm_connector *connector, hdmiw_hdmiedid))return ; - i =I915_READ (aud_cntrl_st2); - i &= ~eldv; -I915_WRITE (aud_cntrl_st2, i); + tmp =I915_READ (aud_cntrl_st2); + tmp &= ~eldv; +I915_WRITE (aud_cntrl_st2, tmp);if (!eld[0 ])return ; - i =I915_READ (aud_cntl_st); - i &= ~IBX_ELD_ADDRESS ; -I915_WRITE (aud_cntl_st, i); - i = (i >>29 ) &DIP_PORT_SEL_MASK ;/* DIP_Port_Select, 0x1 = PortB */ -DRM_DEBUG_DRIVER ("port num:%d\n" , i); + tmp =I915_READ (aud_cntl_st); + tmp &= ~IBX_ELD_ADDRESS ; +I915_WRITE (aud_cntl_st, tmp); + port = (tmp >>29 ) &DIP_PORT_SEL_MASK ;/* DIP_Port_Select, 0x1 = PortB */ +DRM_DEBUG_DRIVER ("port num:%d\n" , port); - len =min_t (uint8_t, eld[2 ],21 );/* 84 bytes of hw ELD buffer */ + len =min_t (int, eld[2 ],21 );/* 84 bytes of hw ELD buffer */ DRM_DEBUG_DRIVER ("ELD size %d\n" , len);for (i =0 ; i < len; i++)I915_WRITE (hdmiw_hdmiedid, *((uint32_t *)eld + i)); - i =I915_READ (aud_cntrl_st2); - i |= eldv; -I915_WRITE (aud_cntrl_st2, i); - + tmp =I915_READ (aud_cntrl_st2); + tmp |= eldv; +I915_WRITE (aud_cntrl_st2, tmp); } static void ironlake_write_eld(struct drm_connector *connector,
@@ -226,13 +224,14 @@ static void ironlake_write_eld(struct drm_connector *connector,struct drm_i915_private *dev_priv = connector->dev->dev_private;uint8_t *eld = connector->eld;uint32_t eldv; -uint32_t i; -int len; +uint32_t tmp; +int len, i;int hdmiw_hdmiedid;int aud_config;int aud_cntl_st;int aud_cntrl_st2; -int pipe =to_intel_crtc (crtc)->pipe; +enum pipe pipe =to_intel_crtc (crtc)->pipe; +enum port port;if (HAS_PCH_IBX (connector->dev)) { hdmiw_hdmiedid =IBX_HDMIW_HDMIEDID (pipe);
@@ -259,22 +258,22 @@ static void ironlake_write_eld(struct drm_connector *connector, intel_encoder =intel_attached_encoder (connector); intel_dig_port =enc_to_dig_port (&intel_encoder->base); - i = intel_dig_port->port; + port = intel_dig_port->port; }else { - i =I915_READ (aud_cntl_st); - i = (i >>29 ) &DIP_PORT_SEL_MASK ; + tmp =I915_READ (aud_cntl_st); + port = (tmp >>29 ) &DIP_PORT_SEL_MASK ;/* DIP_Port_Select, 0x1 = PortB */ } -if (!i) { +if (!port) {DRM_DEBUG_DRIVER ("Audio directed to unknown port\n" );/* operate blindly on all ports */ eldv =IBX_ELD_VALIDB ; eldv |=IBX_ELD_VALIDB <<4 ; eldv |=IBX_ELD_VALIDB <<8 ; }else { -DRM_DEBUG_DRIVER ("ELD on port %c\n" ,port_name (i)); - eldv =IBX_ELD_VALIDB << ((i -1 ) *4 ); +DRM_DEBUG_DRIVER ("ELD on port %c\n" ,port_name (port)); + eldv =IBX_ELD_VALIDB << ((port -1 ) *4 ); }if (intel_pipe_has_type (crtc,INTEL_OUTPUT_DISPLAYPORT )) {
@@ -291,25 +290,25 @@ static void ironlake_write_eld(struct drm_connector *connector, hdmiw_hdmiedid))return ; - i =I915_READ (aud_cntrl_st2); - i &= ~eldv; -I915_WRITE (aud_cntrl_st2, i); + tmp =I915_READ (aud_cntrl_st2); + tmp &= ~eldv; +I915_WRITE (aud_cntrl_st2, tmp);if (!eld[0 ])return ; - i =I915_READ (aud_cntl_st); - i &= ~IBX_ELD_ADDRESS ; -I915_WRITE (aud_cntl_st, i); + tmp =I915_READ (aud_cntl_st); + tmp &= ~IBX_ELD_ADDRESS ; +I915_WRITE (aud_cntl_st, tmp); - len =min_t (uint8_t, eld[2 ],21 );/* 84 bytes of hw ELD buffer */ + len =min_t (int, eld[2 ],21 );/* 84 bytes of hw ELD buffer */ DRM_DEBUG_DRIVER ("ELD size %d\n" , len);for (i =0 ; i < len; i++)I915_WRITE (hdmiw_hdmiedid, *((uint32_t *)eld + i)); - i =I915_READ (aud_cntrl_st2); - i |= eldv; -I915_WRITE (aud_cntrl_st2, i); + tmp =I915_READ (aud_cntrl_st2); + tmp |= eldv; +I915_WRITE (aud_cntrl_st2, tmp); } void intel_write_eld(struct drm_encoder *encoder,
Signature · 1 line
1.9.1
PATCH 5/18 drm/i915/audio: pass intel_encoder on to platform specific ELD functions
In reply to Jani NikulaThis will simplify things later on. No functional changes.
--- drivers/gpu/drm/i915/i915_drv.h | 4 ++-- drivers/gpu/drm/i915/intel_audio.c | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-)
drivers/gpu/drm/i915/i915_drv.h +2 -2
@@ -434,6 +434,7 @@ struct drm_i915_error_state { };struct intel_connector ; +struct intel_encoder ;struct intel_crtc_config ;struct intel_plane_config ;struct intel_crtc ;
@@ -483,7 +484,7 @@ struct drm_i915_display_funcs {void (*crtc_disable)(struct drm_crtc *crtc);void (*off)(struct drm_crtc *crtc);void (*write_eld)(struct drm_connector *connector, -struct drm_crtc *crtc, +struct intel_encoder *encoder,struct drm_display_mode *mode);void (*fdi_link_train)(struct drm_crtc *crtc);void (*init_clock_gating)(struct drm_device *dev);
@@ -2784,7 +2785,6 @@ static inline bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter)extern void intel_i2c_reset (struct drm_device *dev);/* intel_opregion.c */ -struct intel_encoder ;#ifdef CONFIG_ACPI extern int intel_opregion_setup (struct drm_device *dev);extern void intel_opregion_init (struct drm_device *dev);
drivers/gpu/drm/i915/intel_audio.c +7 -7
@@ -97,7 +97,7 @@ static bool intel_eld_uptodate(struct drm_connector *connector, }static void g4x_write_eld (struct drm_connector *connector, -struct drm_crtc *crtc, +struct intel_encoder *encoder,struct drm_display_mode *mode) {struct drm_i915_private *dev_priv = connector->dev->dev_private;
@@ -137,10 +137,11 @@ static void g4x_write_eld(struct drm_connector *connector, }static void haswell_write_eld (struct drm_connector *connector, -struct drm_crtc *crtc, +struct intel_encoder *encoder,struct drm_display_mode *mode) {struct drm_i915_private *dev_priv = connector->dev->dev_private; +struct drm_crtc *crtc = encoder->base.crtc;uint8_t *eld = connector->eld;uint32_t eldv;uint32_t tmp;
@@ -218,10 +219,11 @@ static void haswell_write_eld(struct drm_connector *connector, }static void ironlake_write_eld (struct drm_connector *connector, -struct drm_crtc *crtc, +struct intel_encoder *encoder,struct drm_display_mode *mode) {struct drm_i915_private *dev_priv = connector->dev->dev_private; +struct drm_crtc *crtc = encoder->base.crtc;uint8_t *eld = connector->eld;uint32_t eldv;uint32_t tmp;
@@ -253,11 +255,9 @@ static void ironlake_write_eld(struct drm_connector *connector,DRM_DEBUG_DRIVER ("ELD on pipe %c\n" ,pipe_name (pipe));if (IS_VALLEYVIEW (connector->dev)) { -struct intel_encoder *intel_encoder;struct intel_digital_port *intel_dig_port; - intel_encoder =intel_attached_encoder (connector); - intel_dig_port =enc_to_dig_port (&intel_encoder->base); + intel_dig_port =enc_to_dig_port (&encoder->base); port = intel_dig_port->port; }else { tmp =I915_READ (aud_cntl_st);
@@ -333,7 +333,7 @@ void intel_write_eld(struct intel_encoder *intel_encoder) connector->eld[6 ] =drm_av_sync_delay (connector, mode) /2 ;if (dev_priv->display.write_eld) - dev_priv->display.write_eld (connector, encoder->crtc, mode); + dev_priv->display.write_eld (connector, intel_encoder, mode); }/* Set up chip specific audio functions */
Signature · 1 line
1.9.1
PATCH 8/18 drm/i915: introduce intel_audio_codec_{enable, disable}
In reply to Jani NikulaIntroduce functions to enable/disable the audio codec, incorporating the ELD setup within enable. The disable is initially limited to HSW, covering exactly what was done previously.
The only functional difference is that ELD valid is no longer set if there is no connector with ELD, which should be the right thing to do anyway. Otherwise the sequence remains the same, with warts and all, in preparation for applying more sanity.
--- drivers/gpu/drm/i915/i915_drv.h | 7 ++-- drivers/gpu/drm/i915/intel_audio.c | 69 +++++++++++++++++++++++++++----------- drivers/gpu/drm/i915/intel_ddi.c | 17 ++-------- drivers/gpu/drm/i915/intel_dp.c | 2 +- drivers/gpu/drm/i915/intel_drv.h | 3 +- drivers/gpu/drm/i915/intel_hdmi.c | 2 +- 6 files changed, 59 insertions(+), 41 deletions(-)
drivers/gpu/drm/i915/i915_drv.h +4 -3
@@ -483,9 +483,10 @@ struct drm_i915_display_funcs {void (*crtc_enable)(struct drm_crtc *crtc);void (*crtc_disable)(struct drm_crtc *crtc);void (*off)(struct drm_crtc *crtc); -void (*write_eld)(struct drm_connector *connector, -struct intel_encoder *encoder, -struct drm_display_mode *mode); +void (*audio_codec_enable)(struct drm_connector *connector, +struct intel_encoder *encoder, +struct drm_display_mode *mode); +void (*audio_codec_disable)(struct intel_encoder *encoder);void (*fdi_link_train)(struct drm_crtc *crtc);void (*init_clock_gating)(struct drm_device *dev); int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc,
drivers/gpu/drm/i915/intel_audio.c +49 -20
105 lines not on this page · raw message
drivers/gpu/drm/i915/intel_ddi.c +2 -15
@@ -1186,12 +1186,10 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)struct drm_encoder *encoder = &intel_encoder->base;struct drm_crtc *crtc = encoder->crtc;struct intel_crtc *intel_crtc =to_intel_crtc (crtc); -int pipe = intel_crtc->pipe;struct drm_device *dev = encoder->dev;struct drm_i915_private *dev_priv = dev->dev_private;enum port port =intel_ddi_get_encoder_port (intel_encoder);int type = intel_encoder->type; -uint32_t tmp;if (type ==INTEL_OUTPUT_HDMI ) { struct intel_digital_port *intel_dig_port =
@@ -1216,11 +1214,7 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)if (intel_crtc->config.has_audio) {intel_display_power_get (dev_priv,POWER_DOMAIN_AUDIO ); -intel_write_eld (intel_encoder); - - tmp =I915_READ (HSW_AUD_PIN_ELD_CP_VLD ); - tmp |= ((AUDIO_OUTPUT_ENABLE_A |AUDIO_ELD_VALID_A ) << (pipe *4 )); -I915_WRITE (HSW_AUD_PIN_ELD_CP_VLD , tmp); +intel_audio_codec_enable (intel_encoder); } }
@@ -1229,19 +1223,12 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder)struct drm_encoder *encoder = &intel_encoder->base;struct drm_crtc *crtc = encoder->crtc;struct intel_crtc *intel_crtc =to_intel_crtc (crtc); -int pipe = intel_crtc->pipe;int type = intel_encoder->type;struct drm_device *dev = encoder->dev;struct drm_i915_private *dev_priv = dev->dev_private; -uint32_t tmp; -/* We can't touch HSW_AUD_PIN_ELD_CP_VLD uncionditionally because this -* register is part of the power well on Haswell. */ if (intel_crtc->config.has_audio) { - tmp =I915_READ (HSW_AUD_PIN_ELD_CP_VLD ); - tmp &= ~((AUDIO_OUTPUT_ENABLE_A |AUDIO_ELD_VALID_A ) << - (pipe *4 )); -I915_WRITE (HSW_AUD_PIN_ELD_CP_VLD , tmp); +intel_audio_codec_disable (intel_encoder);intel_display_power_put (dev_priv,POWER_DOMAIN_AUDIO ); }
drivers/gpu/drm/i915/intel_dp.c +1 -1
@@ -1250,7 +1250,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder)DRM_DEBUG_DRIVER ("Enabling DP audio on pipe %c\n" ,pipe_name (crtc->pipe)); intel_dp->DP |=DP_AUDIO_OUTPUT_ENABLE ; -intel_write_eld (encoder); +intel_audio_codec_enable (encoder); }/* Split out the IBX/CPU vs CPT settings */
drivers/gpu/drm/i915/intel_drv.h +2 -1
@@ -841,7 +841,8 @@ void intel_fb_obj_flush(struct drm_i915_gem_object *obj, bool retire);/* intel_audio.c */ void intel_init_audio (struct drm_device *dev); -void intel_write_eld (struct intel_encoder *encoder); +void intel_audio_codec_enable (struct intel_encoder *encoder); +void intel_audio_codec_disable (struct intel_encoder *encoder);/* intel_display.c */ const char *intel_output_name (int output);
drivers/gpu/drm/i915/intel_hdmi.c +1 -1
@@ -666,7 +666,7 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder)DRM_DEBUG_DRIVER ("Enabling HDMI audio on pipe %c\n" ,pipe_name (crtc->pipe)); hdmi_val |=SDVO_AUDIO_ENABLE ; -intel_write_eld (encoder); +intel_audio_codec_enable (encoder); }if (HAS_PCH_CPT (dev))
Signature · 1 line
1.9.1
PATCH 2/18 drm/i915/audio: constify hdmi audio clock struct
In reply to Jani NikulaConst is good.
--- drivers/gpu/drm/i915/intel_audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/i915/intel_audio.c +1 -1
@@ -28,7 +28,7 @@#include "intel_drv.h" #include "i915_drv.h" -static struct { +static const struct {int clock;u32 config; } hdmi_audio_clock[] = {
Signature · 1 line
1.9.1
PATCH 6/18 drm/i915/audio: set ELD Conn_Type at one place
In reply to Jani NikulaKeep the driver modifications to ELD together. This also sets the Conn_Type for G4X DP which wasn't done before.
Clean up the debugs while at it; this is all obvious from the connector name.
--- drivers/gpu/drm/i915/intel_audio.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)
drivers/gpu/drm/i915/intel_audio.c +9 -10
@@ -181,13 +181,10 @@ static void haswell_write_eld(struct drm_connector *connector, eldv =AUDIO_ELD_VALID_A << (pipe *4 ); -if (intel_pipe_has_type (crtc,INTEL_OUTPUT_DISPLAYPORT )) { -DRM_DEBUG_DRIVER ("ELD: DisplayPort detected\n" ); - eld[5 ] |= (1 <<2 );/* Conn_Type, 0x1 = DisplayPort */ +if (intel_pipe_has_type (crtc,INTEL_OUTPUT_DISPLAYPORT ))I915_WRITE (aud_config,AUD_CONFIG_N_VALUE_INDEX );/* 0x1 = DP */ - }else { +else I915_WRITE (aud_config,audio_config_hdmi_pixel_clock (mode)); - } if (intel_eld_uptodate(connector, aud_cntrl_st2, eldv,
@@ -276,13 +273,10 @@ static void ironlake_write_eld(struct drm_connector *connector, eldv =IBX_ELD_VALIDB << ((port -1 ) *4 ); } -if (intel_pipe_has_type (crtc,INTEL_OUTPUT_DISPLAYPORT )) { -DRM_DEBUG_DRIVER ("ELD: DisplayPort detected\n" ); - eld[5 ] |= (1 <<2 );/* Conn_Type, 0x1 = DisplayPort */ +if (intel_pipe_has_type (crtc,INTEL_OUTPUT_DISPLAYPORT ))I915_WRITE (aud_config,AUD_CONFIG_N_VALUE_INDEX );/* 0x1 = DP */ - }else { +else I915_WRITE (aud_config,audio_config_hdmi_pixel_clock (mode)); - } if (intel_eld_uptodate(connector, aud_cntrl_st2, eldv,
@@ -330,6 +324,11 @@ void intel_write_eld(struct intel_encoder *intel_encoder) connector->encoder->base.id, connector->encoder->name); +/* ELD Conn_Type */ + connector->eld[5 ] &= (3 <<2 ); +if (intel_pipe_has_type (encoder->crtc,INTEL_OUTPUT_DISPLAYPORT )) + connector->eld[5 ] |= (1 <<2 ); + connector->eld[6 ] =drm_av_sync_delay (connector, mode) /2 ;if (dev_priv->display.write_eld)
Signature · 1 line
1.9.1
PATCH 4/18 drm/i915: pass intel_encoder to intel_write_eld
In reply to Jani NikulaEverything else can be derived from that. No functional changes.
--- drivers/gpu/drm/i915/intel_audio.c | 9 +++++---- drivers/gpu/drm/i915/intel_ddi.c | 2 +- drivers/gpu/drm/i915/intel_dp.c | 2 +- drivers/gpu/drm/i915/intel_drv.h | 3 +-- drivers/gpu/drm/i915/intel_hdmi.c | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-)
drivers/gpu/drm/i915/intel_audio.c +5 -4
@@ -311,10 +311,11 @@ static void ironlake_write_eld(struct drm_connector *connector,I915_WRITE (aud_cntrl_st2, tmp); } -void intel_write_eld (struct drm_encoder *encoder, -struct drm_display_mode *mode) +void intel_write_eld (struct intel_encoder *intel_encoder) { -struct drm_crtc *crtc = encoder->crtc; +struct drm_encoder *encoder = &intel_encoder->base; +struct intel_crtc *crtc =to_intel_crtc (encoder->crtc); +struct drm_display_mode *mode = &crtc->config.adjusted_mode;struct drm_connector *connector;struct drm_device *dev = encoder->dev;struct drm_i915_private *dev_priv = dev->dev_private;
@@ -332,7 +333,7 @@ void intel_write_eld(struct drm_encoder *encoder, connector->eld[6 ] =drm_av_sync_delay (connector, mode) /2 ;if (dev_priv->display.write_eld) - dev_priv->display.write_eld (connector, crtc, mode); + dev_priv->display.write_eld (connector, encoder->crtc, mode); }/* Set up chip specific audio functions */
drivers/gpu/drm/i915/intel_ddi.c +1 -1
@@ -1126,7 +1126,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)/* write eld */ DRM_DEBUG_DRIVER ("DDI audio: write eld information\n" ); -intel_write_eld (encoder, &crtc->config.adjusted_mode); +intel_write_eld (intel_encoder); }if (type ==INTEL_OUTPUT_EDP ) {
drivers/gpu/drm/i915/intel_dp.c +1 -1
@@ -1250,7 +1250,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder)DRM_DEBUG_DRIVER ("Enabling DP audio on pipe %c\n" ,pipe_name (crtc->pipe)); intel_dp->DP |=DP_AUDIO_OUTPUT_ENABLE ; -intel_write_eld (&encoder->base, adjusted_mode); +intel_write_eld (encoder); }/* Split out the IBX/CPU vs CPT settings */
drivers/gpu/drm/i915/intel_drv.h +1 -2
@@ -841,8 +841,7 @@ void intel_fb_obj_flush(struct drm_i915_gem_object *obj, bool retire);/* intel_audio.c */ void intel_init_audio (struct drm_device *dev); -void intel_write_eld (struct drm_encoder *encoder, -struct drm_display_mode *mode); +void intel_write_eld (struct intel_encoder *encoder);/* intel_display.c */ const char *intel_output_name (int output);
drivers/gpu/drm/i915/intel_hdmi.c +1 -1
@@ -666,7 +666,7 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder)DRM_DEBUG_DRIVER ("Enabling HDMI audio on pipe %c\n" ,pipe_name (crtc->pipe)); hdmi_val |=SDVO_AUDIO_ENABLE ; -intel_write_eld (&encoder->base, adjusted_mode); +intel_write_eld (encoder); }if (HAS_PCH_CPT (dev))
Signature · 1 line
1.9.1
PATCH 7/18 drm/i915/ddi: write ELD where it's supposed to be done
In reply to Jani NikulaThe audio programming sequence states that the ELD must be written and enabled after the pipe is ready. Indeed, this should clarify the situation with
commit c79057922ed6c2c6df1214e6ab4414fea1b23db2
Author: Daniel Vetter <[email protected]> Date: Wed Apr 16 16:56:09 2014 +0200
drm/i915: Remove vblank wait from haswell_write_eld
and Ville's review of it [1].
Moreover, we should not touch the relevant registers before we get the audio power domain.
[1] http://mid.gmane.org/[email protected]
--- drivers/gpu/drm/i915/intel_audio.c | 2 -- drivers/gpu/drm/i915/intel_ddi.c | 11 ++--------- 2 files changed, 2 insertions(+), 11 deletions(-)
drivers/gpu/drm/i915/intel_audio.c +0 -2
@@ -160,8 +160,6 @@ static void haswell_write_eld(struct drm_connector *connector,I915_WRITE (aud_cntrl_st2, tmp);POSTING_READ (aud_cntrl_st2); -assert_pipe_disabled (dev_priv,to_intel_crtc (crtc)->pipe); -/* Set ELD valid state */ tmp =I915_READ (aud_cntrl_st2);DRM_DEBUG_DRIVER ("HDMI audio: pin eld vld status=0x%08x\n" , tmp);
drivers/gpu/drm/i915/intel_ddi.c +2 -9
@@ -1120,15 +1120,6 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)enum port port =intel_ddi_get_encoder_port (intel_encoder);int type = intel_encoder->type; -if (crtc->config.has_audio) { -DRM_DEBUG_DRIVER ("Audio on pipe %c on DDI\n" , -pipe_name (crtc->pipe)); - -/* write eld */ -DRM_DEBUG_DRIVER ("DDI audio: write eld information\n" ); -intel_write_eld (intel_encoder); - } -if (type ==INTEL_OUTPUT_EDP ) {struct intel_dp *intel_dp =enc_to_intel_dp (encoder);intel_edp_panel_on (intel_dp);
@@ -1225,6 +1216,8 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)if (intel_crtc->config.has_audio) {intel_display_power_get (dev_priv,POWER_DOMAIN_AUDIO ); +intel_write_eld (intel_encoder); + tmp =I915_READ (HSW_AUD_PIN_ELD_CP_VLD ); tmp |= ((AUDIO_OUTPUT_ENABLE_A |AUDIO_ELD_VALID_A ) << (pipe *4 ));I915_WRITE (HSW_AUD_PIN_ELD_CP_VLD , tmp);
Signature · 1 line
1.9.1
PATCH 9/18 drm/i915/audio: remove misleading checks for !eld[0]
In reply to Jani NikulaWe'll never end up in the hooks with eld[0] unset, as that's checked by drm_select_eld().
--- drivers/gpu/drm/i915/intel_audio.c | 12 ------------ 1 file changed, 12 deletions(-)
drivers/gpu/drm/i915/intel_audio.c +0 -12
@@ -79,9 +79,6 @@ static bool intel_eld_uptodate(struct drm_connector *connector, tmp =I915_READ (reg_eldv); tmp &= bits_eldv; -if (!eld[0 ]) -return !tmp; -if (!tmp)return false;
@@ -123,9 +120,6 @@ static void g4x_audio_codec_enable(struct drm_connector *connector, len = (tmp >>9 ) &0x1f ;/* ELD buffer size */ I915_WRITE (G4X_AUD_CNTL_ST , tmp); -if (!eld[0 ]) -return ; - len =min_t (int, eld[2 ], len);DRM_DEBUG_DRIVER ("ELD size %d\n" , len);for (i =0 ; i < len; i++)
@@ -207,9 +201,6 @@ static void hsw_audio_codec_enable(struct drm_connector *connector, tmp &= ~eldv;I915_WRITE (aud_cntrl_st2, tmp); -if (!eld[0 ]) -return ; - tmp =I915_READ (aud_cntl_st); tmp &= ~IBX_ELD_ADDRESS ;I915_WRITE (aud_cntl_st, tmp);
@@ -304,9 +295,6 @@ static void ilk_audio_codec_enable(struct drm_connector *connector, tmp &= ~eldv;I915_WRITE (aud_cntrl_st2, tmp); -if (!eld[0 ]) -return ; - tmp =I915_READ (aud_cntl_st); tmp &= ~IBX_ELD_ADDRESS ;I915_WRITE (aud_cntl_st, tmp);
Signature · 1 line
1.9.1
PATCH 10/18 drm/i915: clean up and clarify audio related register defines
In reply to Jani NikulaMake audio related register defines conform to existing style: Add _MASK where relevant, indent the defines for register contents, don't indent the defines for register addresses, prefix pipe specific register address defines with underscores, drop self explanatory comments.
No functional changes.
--- drivers/gpu/drm/i915/i915_reg.h | 165 +++++++++++++++++++------------------ drivers/gpu/drm/i915/intel_audio.c | 12 +-- 2 files changed, 89 insertions(+), 88 deletions(-)
drivers/gpu/drm/i915/i915_reg.h +83 -82
@@ -5950,57 +5950,58 @@ enum punit_power_well {#define GEN8_CENTROID_PIXEL_OPT_DIS (1<<8)#define GEN8_SAMPLER_POWER_BYPASS_DIS (1<<1) +/* Audio */ #define G4X_AUD_VID_DID (dev_priv->info.display_mmio_offset + 0x62020) -#define INTEL_AUDIO_DEVCL 0x808629FB -#define INTEL_AUDIO_DEVBLC 0x80862801 -#define INTEL_AUDIO_DEVCTG 0x80862802 +#define INTEL_AUDIO_DEVCL 0x808629FB +#define INTEL_AUDIO_DEVBLC 0x80862801 +#define INTEL_AUDIO_DEVCTG 0x80862802#define G4X_AUD_CNTL_ST 0x620B4 -#define G4X_ELDV_DEVCL_DEVBLC (1 << 13) -#define G4X_ELDV_DEVCTG (1 << 14) -#define G4X_ELD_ADDR (0xf << 5) -#define G4X_ELD_ACK (1 << 4) +#define G4X_ELDV_DEVCL_DEVBLC (1 << 13) +#define G4X_ELDV_DEVCTG (1 << 14) +#define G4X_ELD_ADDR_MASK (0xf << 5) +#define G4X_ELD_ACK (1 << 4)#define G4X_HDMIW_HDMIEDID 0x6210C -#define IBX_HDMIW_HDMIEDID_A 0xE2050 -#define IBX_HDMIW_HDMIEDID_B 0xE2150 +#define _IBX_HDMIW_HDMIEDID_A 0xE2050 +#define _IBX_HDMIW_HDMIEDID_B 0xE2150#define IBX_HDMIW_HDMIEDID (pipe) _PIPE(pipe, \ - IBX_HDMIW_HDMIEDID_A, \ - IBX_HDMIW_HDMIEDID_B) -#define IBX_AUD_CNTL_ST_A 0xE20B4 -#define IBX_AUD_CNTL_ST_B 0xE21B4 + _IBX_HDMIW_HDMIEDID_A, \ + _IBX_HDMIW_HDMIEDID_B) +#define _IBX_AUD_CNTL_ST_A 0xE20B4 +#define _IBX_AUD_CNTL_ST_B 0xE21B4#define IBX_AUD_CNTL_ST (pipe) _PIPE(pipe, \ - IBX_AUD_CNTL_ST_A, \ - IBX_AUD_CNTL_ST_B) -#define IBX_ELD_BUFFER_SIZE (0x1f << 10) -#define IBX_ELD_ADDRESS (0x1f << 5) -#define IBX_ELD_ACK (1 << 4) + _IBX_AUD_CNTL_ST_A, \ + _IBX_AUD_CNTL_ST_B) +#define IBX_ELD_BUFFER_SIZE_MASK (0x1f << 10) +#define IBX_ELD_ADDRESS_MASK (0x1f << 5) +#define IBX_ELD_ACK (1 << 4)#define IBX_AUD_CNTL_ST2 0xE20C0 -#define IBX_ELD_VALIDB (1 << 0) -#define IBX_CP_READYB (1 << 1) +#define IBX_ELD_VALIDB (1 << 0) +#define IBX_CP_READYB (1 << 1) -#define CPT_HDMIW_HDMIEDID_A 0xE5050 -#define CPT_HDMIW_HDMIEDID_B 0xE5150 +#define _CPT_HDMIW_HDMIEDID_A 0xE5050 +#define _CPT_HDMIW_HDMIEDID_B 0xE5150#define CPT_HDMIW_HDMIEDID (pipe) _PIPE(pipe, \ - CPT_HDMIW_HDMIEDID_A, \ - CPT_HDMIW_HDMIEDID_B) -#define CPT_AUD_CNTL_ST_A 0xE50B4 -#define CPT_AUD_CNTL_ST_B 0xE51B4 + _CPT_HDMIW_HDMIEDID_A, \ + _CPT_HDMIW_HDMIEDID_B) +#define _CPT_AUD_CNTL_ST_A 0xE50B4 +#define _CPT_AUD_CNTL_ST_B 0xE51B4#define CPT_AUD_CNTL_ST (pipe) _PIPE(pipe, \ - CPT_AUD_CNTL_ST_A, \ - CPT_AUD_CNTL_ST_B) + _CPT_AUD_CNTL_ST_A, \ + _CPT_AUD_CNTL_ST_B)#define CPT_AUD_CNTRL_ST2 0xE50C0 -#define VLV_HDMIW_HDMIEDID_A (VLV_DISPLAY_BASE + 0x62050) -#define VLV_HDMIW_HDMIEDID_B (VLV_DISPLAY_BASE + 0x62150) +#define _VLV_HDMIW_HDMIEDID_A (VLV_DISPLAY_BASE + 0x62050) +#define _VLV_HDMIW_HDMIEDID_B (VLV_DISPLAY_BASE + 0x62150)#define VLV_HDMIW_HDMIEDID (pipe) _PIPE(pipe, \ - VLV_HDMIW_HDMIEDID_A, \ - VLV_HDMIW_HDMIEDID_B) -#define VLV_AUD_CNTL_ST_A (VLV_DISPLAY_BASE + 0x620B4) -#define VLV_AUD_CNTL_ST_B (VLV_DISPLAY_BASE + 0x621B4) + _VLV_HDMIW_HDMIEDID_A, \ + _VLV_HDMIW_HDMIEDID_B) +#define _VLV_AUD_CNTL_ST_A (VLV_DISPLAY_BASE + 0x620B4) +#define _VLV_AUD_CNTL_ST_B (VLV_DISPLAY_BASE + 0x621B4)#define VLV_AUD_CNTL_ST (pipe) _PIPE(pipe, \ - VLV_AUD_CNTL_ST_A, \ - VLV_AUD_CNTL_ST_B) + _VLV_AUD_CNTL_ST_A, \ + _VLV_AUD_CNTL_ST_B)#define VLV_AUD_CNTL_ST2 (VLV_DISPLAY_BASE + 0x620C0)/* These are the 4 32-bit write offset registers for each stream
@@ -6009,28 +6010,28 @@ enum punit_power_well {*/ #define GEN7_SO_WRITE_OFFSET (n) (0x5280 + (n) * 4) -#define IBX_AUD_CONFIG_A 0xe2000 -#define IBX_AUD_CONFIG_B 0xe2100 +#define _IBX_AUD_CONFIG_A 0xe2000 +#define _IBX_AUD_CONFIG_B 0xe2100#define IBX_AUD_CFG (pipe) _PIPE(pipe, \ - IBX_AUD_CONFIG_A, \ - IBX_AUD_CONFIG_B) -#define CPT_AUD_CONFIG_A 0xe5000 -#define CPT_AUD_CONFIG_B 0xe5100 + _IBX_AUD_CONFIG_A, \ + _IBX_AUD_CONFIG_B) +#define _CPT_AUD_CONFIG_A 0xe5000 +#define _CPT_AUD_CONFIG_B 0xe5100#define CPT_AUD_CFG (pipe) _PIPE(pipe, \ - CPT_AUD_CONFIG_A, \ - CPT_AUD_CONFIG_B) -#define VLV_AUD_CONFIG_A (VLV_DISPLAY_BASE + 0x62000) -#define VLV_AUD_CONFIG_B (VLV_DISPLAY_BASE + 0x62100) + _CPT_AUD_CONFIG_A, \ + _CPT_AUD_CONFIG_B) +#define _VLV_AUD_CONFIG_A (VLV_DISPLAY_BASE + 0x62000) +#define _VLV_AUD_CONFIG_B (VLV_DISPLAY_BASE + 0x62100)#define VLV_AUD_CFG (pipe) _PIPE(pipe, \ - VLV_AUD_CONFIG_A, \ - VLV_AUD_CONFIG_B) + _VLV_AUD_CONFIG_A, \ + _VLV_AUD_CONFIG_B)#define AUD_CONFIG_N_VALUE_INDEX (1 << 29)#define AUD_CONFIG_N_PROG_ENABLE (1 << 28)#define AUD_CONFIG_UPPER_N_SHIFT 20 -#define AUD_CONFIG_UPPER_N_VALUE (0xff << 20) +#define AUD_CONFIG_UPPER_N_MASK (0xff << 20)#define AUD_CONFIG_LOWER_N_SHIFT 4 -#define AUD_CONFIG_LOWER_N_VALUE (0xfff << 4) +#define AUD_CONFIG_LOWER_N_MASK (0xfff << 4)#define AUD_CONFIG_PIXEL_CLOCK_HDMI_SHIFT 16#define AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK (0xf << 16)#define AUD_CONFIG_PIXEL_CLOCK_HDMI_25175 (0 << 16)
@@ -6046,40 +6047,40 @@ enum punit_power_well {#define AUD_CONFIG_DISABLE_NCTS (1 << 3)/* HSW Audio */ -#define HSW_AUD_CONFIG_A 0x65000/* Audio Configuration Transcoder A */ -#define HSW_AUD_CONFIG_B 0x65100/* Audio Configuration Transcoder B */ -#define HSW_AUD_CFG (pipe) _PIPE(pipe, \ - HSW_AUD_CONFIG_A, \ - HSW_AUD_CONFIG_B) - -#define HSW_AUD_MISC_CTRL_A 0x65010/* Audio Misc Control Convert 1 */ -#define HSW_AUD_MISC_CTRL_B 0x65110/* Audio Misc Control Convert 2 */ -#define HSW_AUD_MISC_CTRL (pipe) _PIPE(pipe, \ - HSW_AUD_MISC_CTRL_A, \ - HSW_AUD_MISC_CTRL_B) - -#define HSW_AUD_DIP_ELD_CTRL_ST_A 0x650b4/* Audio DIP and ELD Control State Transcoder A */ -#define HSW_AUD_DIP_ELD_CTRL_ST_B 0x651b4/* Audio DIP and ELD Control State Transcoder B */ -#define HSW_AUD_DIP_ELD_CTRL (pipe) _PIPE(pipe, \ - HSW_AUD_DIP_ELD_CTRL_ST_A, \ - HSW_AUD_DIP_ELD_CTRL_ST_B) +#define _HSW_AUD_CONFIG_A 0x65000 +#define _HSW_AUD_CONFIG_B 0x65100 +#define HSW_AUD_CFG (pipe) _PIPE(pipe, \ + _HSW_AUD_CONFIG_A, \ + _HSW_AUD_CONFIG_B) + +#define _HSW_AUD_MISC_CTRL_A 0x65010 +#define _HSW_AUD_MISC_CTRL_B 0x65110 +#define HSW_AUD_MISC_CTRL (pipe) _PIPE(pipe, \ + _HSW_AUD_MISC_CTRL_A, \ + _HSW_AUD_MISC_CTRL_B) + +#define _HSW_AUD_DIP_ELD_CTRL_ST_A 0x650b4 +#define _HSW_AUD_DIP_ELD_CTRL_ST_B 0x651b4 +#define HSW_AUD_DIP_ELD_CTRL (pipe) _PIPE(pipe, \ + _HSW_AUD_DIP_ELD_CTRL_ST_A, \ + _HSW_AUD_DIP_ELD_CTRL_ST_B)/* Audio Digital Converter */ -#define HSW_AUD_DIG_CNVT_1 0x65080/* Audio Converter 1 */ -#define HSW_AUD_DIG_CNVT_2 0x65180/* Audio Converter 1 */ -#define AUD_DIG_CNVT (pipe) _PIPE(pipe, \ - HSW_AUD_DIG_CNVT_1, \ - HSW_AUD_DIG_CNVT_2) -#define DIP_PORT_SEL_MASK 0x3 - -#define HSW_AUD_EDID_DATA_A 0x65050 -#define HSW_AUD_EDID_DATA_B 0x65150 -#define HSW_AUD_EDID_DATA (pipe) _PIPE(pipe, \ - HSW_AUD_EDID_DATA_A, \ - HSW_AUD_EDID_DATA_B) - -#define HSW_AUD_PIPE_CONV_CFG 0x6507c/* Audio pipe and converter configs */ -#define HSW_AUD_PIN_ELD_CP_VLD 0x650c0/* Audio ELD and CP Ready Status */ +#define _HSW_AUD_DIG_CNVT_1 0x65080 +#define _HSW_AUD_DIG_CNVT_2 0x65180 +#define AUD_DIG_CNVT (pipe) _PIPE(pipe, \ + _HSW_AUD_DIG_CNVT_1, \ + _HSW_AUD_DIG_CNVT_2) +#define DIP_PORT_SEL_MASK 0x3 + +#define _HSW_AUD_EDID_DATA_A 0x65050 +#define _HSW_AUD_EDID_DATA_B 0x65150 +#define HSW_AUD_EDID_DATA (pipe) _PIPE(pipe, \ + _HSW_AUD_EDID_DATA_A, \ + _HSW_AUD_EDID_DATA_B) + +#define HSW_AUD_PIPE_CONV_CFG 0x6507c +#define HSW_AUD_PIN_ELD_CP_VLD 0x650c0#define AUDIO_INACTIVE_C (1<<11)#define AUDIO_INACTIVE_B (1<<7)#define AUDIO_INACTIVE_A (1<<3)
drivers/gpu/drm/i915/intel_audio.c +6 -6
@@ -111,12 +111,12 @@ static void g4x_audio_codec_enable(struct drm_connector *connector,if (intel_eld_uptodate (connector,G4X_AUD_CNTL_ST , eldv, -G4X_AUD_CNTL_ST ,G4X_ELD_ADDR , +G4X_AUD_CNTL_ST ,G4X_ELD_ADDR_MASK ,G4X_HDMIW_HDMIEDID ))return ; tmp =I915_READ (G4X_AUD_CNTL_ST ); - tmp &= ~(eldv |G4X_ELD_ADDR ); + tmp &= ~(eldv |G4X_ELD_ADDR_MASK ); len = (tmp >>9 ) &0x1f ;/* ELD buffer size */ I915_WRITE (G4X_AUD_CNTL_ST , tmp);
@@ -193,7 +193,7 @@ static void hsw_audio_codec_enable(struct drm_connector *connector,if (intel_eld_uptodate (connector, aud_cntrl_st2, eldv, - aud_cntl_st,IBX_ELD_ADDRESS , + aud_cntl_st,IBX_ELD_ADDRESS_MASK , hdmiw_hdmiedid))return ;
@@ -202,7 +202,7 @@ static void hsw_audio_codec_enable(struct drm_connector *connector,I915_WRITE (aud_cntrl_st2, tmp); tmp =I915_READ (aud_cntl_st); - tmp &= ~IBX_ELD_ADDRESS ; + tmp &= ~IBX_ELD_ADDRESS_MASK ;I915_WRITE (aud_cntl_st, tmp); port = (tmp >>29 ) &DIP_PORT_SEL_MASK ;/* DIP_Port_Select, 0x1 = PortB */ DRM_DEBUG_DRIVER ("port num:%d\n" , port);
@@ -287,7 +287,7 @@ static void ilk_audio_codec_enable(struct drm_connector *connector,if (intel_eld_uptodate (connector, aud_cntrl_st2, eldv, - aud_cntl_st,IBX_ELD_ADDRESS , + aud_cntl_st,IBX_ELD_ADDRESS_MASK , hdmiw_hdmiedid))return ;
@@ -296,7 +296,7 @@ static void ilk_audio_codec_enable(struct drm_connector *connector,I915_WRITE (aud_cntrl_st2, tmp); tmp =I915_READ (aud_cntl_st); - tmp &= ~IBX_ELD_ADDRESS ; + tmp &= ~IBX_ELD_ADDRESS_MASK ;I915_WRITE (aud_cntl_st, tmp); len =min_t (int, eld[2 ],21 );/* 84 bytes of hw ELD buffer */
Signature · 1 line
1.9.1
PATCH 11/18 drm/i915: rewrite hsw/bdw audio codec enable/disable sequences
In reply to Jani NikulaThere's some serious confusion regarding ELD valid bit that gets set and cleared back and forth etc. Rewrite it all based on the documented audio codec enable/disable sequences.
--- drivers/gpu/drm/i915/intel_audio.c | 106 +++++++++++++++---------------------- 1 file changed, 44 insertions(+), 62 deletions(-)
drivers/gpu/drm/i915/intel_audio.c +44 -62
@@ -132,14 +132,26 @@ static void g4x_audio_codec_enable(struct drm_connector *connector,static void hsw_audio_codec_disable (struct intel_encoder *encoder) { -struct drm_device *dev = encoder->base.dev; -struct drm_i915_private *dev_priv = dev->dev_private; +struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;struct drm_crtc *crtc = encoder->base.crtc;enum pipe pipe =to_intel_crtc (crtc)->pipe;uint32_t tmp; +DRM_DEBUG_KMS ("Disable audio codec on pipe %c\n" ,pipe_name (pipe)); + +/* Disable timestamps */ + tmp =I915_READ (HSW_AUD_CFG (pipe)); + tmp &= ~AUD_CONFIG_N_VALUE_INDEX ; + tmp |=AUD_CONFIG_N_PROG_ENABLE ; + tmp &= ~AUD_CONFIG_UPPER_N_MASK ; + tmp &= ~AUD_CONFIG_LOWER_N_MASK ; +if (intel_pipe_has_type (crtc,INTEL_OUTPUT_DISPLAYPORT )) + tmp |=AUD_CONFIG_N_VALUE_INDEX ; +I915_WRITE (HSW_AUD_CFG (pipe), tmp); + +/* Invalidate ELD */ tmp =I915_READ (HSW_AUD_PIN_ELD_CP_VLD ); - tmp &= ~((AUDIO_OUTPUT_ENABLE_A |AUDIO_ELD_VALID_A ) << (pipe *4 )); + tmp &= ~(AUDIO_ELD_VALID_A << (pipe *4 ));I915_WRITE (HSW_AUD_PIN_ELD_CP_VLD , tmp); }
@@ -149,77 +161,47 @@ static void hsw_audio_codec_enable(struct drm_connector *connector, {struct drm_i915_private *dev_priv = connector->dev->dev_private;struct drm_crtc *crtc = encoder->base.crtc; -uint8_t *eld = connector->eld; -uint32_t eldv; +enum pipe pipe =to_intel_crtc (crtc)->pipe; +const uint8_t *eld = connector->eld;uint32_t tmp;int len, i; -enum pipe pipe =to_intel_crtc (crtc)->pipe; -enum port port; -int hdmiw_hdmiedid =HSW_AUD_EDID_DATA (pipe); -int aud_cntl_st =HSW_AUD_DIP_ELD_CTRL (pipe); -int aud_config =HSW_AUD_CFG (pipe); -int aud_cntrl_st2 =HSW_AUD_PIN_ELD_CP_VLD ; - -/* Audio output enable */ -DRM_DEBUG_DRIVER ("HDMI audio: enable codec\n" ); - tmp =I915_READ (aud_cntrl_st2); - tmp |= (AUDIO_OUTPUT_ENABLE_A << (pipe *4 )); -I915_WRITE (aud_cntrl_st2, tmp); -POSTING_READ (aud_cntrl_st2); - -/* Set ELD valid state */ - tmp =I915_READ (aud_cntrl_st2); -DRM_DEBUG_DRIVER ("HDMI audio: pin eld vld status=0x%08x\n" , tmp); - tmp |= (AUDIO_ELD_VALID_A << (pipe *4 )); -I915_WRITE (aud_cntrl_st2, tmp); - tmp =I915_READ (aud_cntrl_st2); -DRM_DEBUG_DRIVER ("HDMI audio: eld vld status=0x%08x\n" , tmp); - -/* Enable HDMI mode */ - tmp =I915_READ (aud_config); -DRM_DEBUG_DRIVER ("HDMI audio: audio conf: 0x%08x\n" , tmp); -/* clear N_programing_enable and N_value_index */ - tmp &= ~(AUD_CONFIG_N_VALUE_INDEX |AUD_CONFIG_N_PROG_ENABLE ); -I915_WRITE (aud_config, tmp); -DRM_DEBUG_DRIVER ("ELD on pipe %c\n" ,pipe_name (pipe)); - - eldv =AUDIO_ELD_VALID_A << (pipe *4 ); +DRM_DEBUG_KMS ("Enable audio codec on pipe %c, %u bytes ELD\n" , +pipe_name (pipe), eld[2 ]); -if (intel_pipe_has_type (crtc,INTEL_OUTPUT_DISPLAYPORT )) -I915_WRITE (aud_config,AUD_CONFIG_N_VALUE_INDEX );/* 0x1 = DP */ -else -I915_WRITE (aud_config,audio_config_hdmi_pixel_clock (mode)); - -if (intel_eld_uptodate (connector, - aud_cntrl_st2, eldv, - aud_cntl_st,IBX_ELD_ADDRESS_MASK , - hdmiw_hdmiedid)) -return ; +/* Enable audio presence detect, invalidate ELD */ + tmp =I915_READ (HSW_AUD_PIN_ELD_CP_VLD ); + tmp |=AUDIO_OUTPUT_ENABLE_A << (pipe *4 ); + tmp &= ~(AUDIO_ELD_VALID_A << (pipe *4 )); +I915_WRITE (HSW_AUD_PIN_ELD_CP_VLD , tmp); - tmp =I915_READ (aud_cntrl_st2); - tmp &= ~eldv; -I915_WRITE (aud_cntrl_st2, tmp); +intel_wait_for_vblank (dev_priv->dev, pipe); - tmp =I915_READ (aud_cntl_st); +/* Reset ELD write address */ + tmp =I915_READ (HSW_AUD_DIP_ELD_CTRL (pipe)); tmp &= ~IBX_ELD_ADDRESS_MASK ; -I915_WRITE (aud_cntl_st, tmp); - port = (tmp >>29 ) &DIP_PORT_SEL_MASK ;/* DIP_Port_Select, 0x1 = PortB */ -DRM_DEBUG_DRIVER ("port num:%d\n" , port); +I915_WRITE (HSW_AUD_DIP_ELD_CTRL (pipe), tmp); - len =min_t (int, eld[2 ],21 );/* 84 bytes of hw ELD buffer */ -DRM_DEBUG_DRIVER ("ELD size %d\n" , len); +/* Up to 84 bytes of hw ELD buffer */ + len =min_t (int, eld[2 ],21 );for (i =0 ; i < len; i++) -I915_WRITE (hdmiw_hdmiedid, *((uint32_t *)eld + i)); +I915_WRITE (HSW_AUD_EDID_DATA (pipe), *((uint32_t *)eld + i)); - tmp =I915_READ (aud_cntrl_st2); - tmp |= eldv; -I915_WRITE (aud_cntrl_st2, tmp); - -/* XXX: Transitional */ +/* ELD valid */ tmp =I915_READ (HSW_AUD_PIN_ELD_CP_VLD ); - tmp |= ((AUDIO_OUTPUT_ENABLE_A |AUDIO_ELD_VALID_A ) << (pipe *4 )); + tmp |=AUDIO_ELD_VALID_A << (pipe *4 );I915_WRITE (HSW_AUD_PIN_ELD_CP_VLD , tmp); + +/* Enable timestamps */ + tmp =I915_READ (HSW_AUD_CFG (pipe)); + tmp &= ~AUD_CONFIG_N_VALUE_INDEX ; + tmp &= ~AUD_CONFIG_N_PROG_ENABLE ; + tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK ; +if (intel_pipe_has_type (crtc,INTEL_OUTPUT_DISPLAYPORT )) + tmp |=AUD_CONFIG_N_VALUE_INDEX ; +else + tmp |=audio_config_hdmi_pixel_clock (mode); +I915_WRITE (HSW_AUD_CFG (pipe), tmp); } static void ilk_audio_codec_enable(struct drm_connector *connector,
Signature · 1 line
1.9.1
PATCH 13/18 drm/i915/audio: add vlv/chv/gen5-7 audio codec disable sequence
In reply to Jani NikulaAdd support for disabling the audio codec on vlv/chv/gen5-7, similar to hsw/bdw.
--- drivers/gpu/drm/i915/intel_audio.c | 52 ++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_dp.c | 4 +++ drivers/gpu/drm/i915/intel_hdmi.c | 4 +++ 3 files changed, 60 insertions(+)
drivers/gpu/drm/i915/intel_audio.c +52 -0
@@ -204,6 +204,56 @@ static void hsw_audio_codec_enable(struct drm_connector *connector,I915_WRITE (HSW_AUD_CFG (pipe), tmp); } +static void ilk_audio_codec_disable (struct intel_encoder *encoder) +{ +struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; +struct drm_crtc *crtc = encoder->base.crtc; +struct intel_digital_port *intel_dig_port = +enc_to_dig_port (&encoder->base); +enum port port = intel_dig_port->port; +enum pipe pipe =to_intel_crtc (crtc)->pipe; +uint32_t tmp, eldv; +int aud_config; +int aud_cntrl_st2; + +DRM_DEBUG_KMS ("Disable audio codec on port %c, pipe %c\n" , +port_name (port),pipe_name (pipe)); + +if (HAS_PCH_IBX (dev_priv->dev)) { + aud_config =IBX_AUD_CFG (pipe); + aud_cntrl_st2 =IBX_AUD_CNTL_ST2 ; + }else if (IS_VALLEYVIEW (dev_priv)) { + aud_config =VLV_AUD_CFG (pipe); + aud_cntrl_st2 =VLV_AUD_CNTL_ST2 ; + }else { + aud_config =CPT_AUD_CFG (pipe); + aud_cntrl_st2 =CPT_AUD_CNTRL_ST2 ; + } + +/* Disable timestamps */ + tmp =I915_READ (aud_config); + tmp &= ~AUD_CONFIG_N_VALUE_INDEX ; + tmp |=AUD_CONFIG_N_PROG_ENABLE ; + tmp &= ~AUD_CONFIG_UPPER_N_MASK ; + tmp &= ~AUD_CONFIG_LOWER_N_MASK ; +if (intel_pipe_has_type (crtc,INTEL_OUTPUT_DISPLAYPORT )) + tmp |=AUD_CONFIG_N_VALUE_INDEX ; +I915_WRITE (aud_config, tmp); + +if (WARN_ON (!port)) { + eldv =IBX_ELD_VALIDB ; + eldv |=IBX_ELD_VALIDB <<4 ; + eldv |=IBX_ELD_VALIDB <<8 ; + }else { + eldv =IBX_ELD_VALIDB << ((port -1 ) *4 ); + } + +/* Invalidate ELD */ + tmp =I915_READ (aud_cntrl_st2); + tmp &= ~eldv; +I915_WRITE (aud_cntrl_st2, tmp); +} +static void ilk_audio_codec_enable (struct drm_connector *connector,struct intel_encoder *encoder,struct drm_display_mode *mode)
@@ -333,10 +383,12 @@ void intel_init_audio(struct drm_device *dev) dev_priv->display.audio_codec_enable = g4x_audio_codec_enable; }else if (IS_VALLEYVIEW (dev)) { dev_priv->display.audio_codec_enable = ilk_audio_codec_enable; + dev_priv->display.audio_codec_disable = ilk_audio_codec_disable; }else if (IS_HASWELL (dev) ||INTEL_INFO (dev)->gen >=8 ) { dev_priv->display.audio_codec_enable = hsw_audio_codec_enable; dev_priv->display.audio_codec_disable = hsw_audio_codec_disable; }else if (HAS_PCH_SPLIT (dev)) { dev_priv->display.audio_codec_enable = ilk_audio_codec_enable; + dev_priv->display.audio_codec_disable = ilk_audio_codec_disable; } }
drivers/gpu/drm/i915/intel_dp.c +4 -0
@@ -2368,6 +2368,10 @@ static void intel_disable_dp(struct intel_encoder *encoder) {struct intel_dp *intel_dp =enc_to_intel_dp (&encoder->base);struct drm_device *dev = encoder->base.dev; +struct intel_crtc *crtc =to_intel_crtc (encoder->base.crtc); + +if (crtc->config.has_audio) +intel_audio_codec_disable (encoder);/* Make sure the panel is off before trying to change the mode. But also * ensure that we have vdd while we switch off the panel. */
drivers/gpu/drm/i915/intel_hdmi.c +4 -0
@@ -802,9 +802,13 @@ static void intel_disable_hdmi(struct intel_encoder *encoder)struct drm_device *dev = encoder->base.dev;struct drm_i915_private *dev_priv = dev->dev_private;struct intel_hdmi *intel_hdmi =enc_to_intel_hdmi (&encoder->base); +struct intel_crtc *crtc =to_intel_crtc (encoder->base.crtc);u32 temp;u32 enable_bits =SDVO_ENABLE |SDVO_AUDIO_ENABLE ; +if (crtc->config.has_audio) +intel_audio_codec_disable (encoder); + temp =I915_READ (intel_hdmi->hdmi_reg);/* HW workaround for IBX, we need to move the port to transcoder A
Signature · 1 line
1.9.1
PATCH 14/18 drm/i915: enable audio codec after port
In reply to Jani NikulaAs per spec, and similar to DDI.
--- drivers/gpu/drm/i915/intel_dp.c | 13 ++++++++----- drivers/gpu/drm/i915/intel_hdmi.c | 15 +++++++-------- 2 files changed, 15 insertions(+), 13 deletions(-)
drivers/gpu/drm/i915/intel_dp.c +8 -5
@@ -1246,12 +1246,8 @@ static void intel_dp_prepare(struct intel_encoder *encoder) intel_dp->DP |=DP_VOLTAGE_0_4 |DP_PRE_EMPHASIS_0 ; intel_dp->DP |=DP_PORT_WIDTH (intel_dp->lane_count); -if (crtc->config.has_audio) { -DRM_DEBUG_DRIVER ("Enabling DP audio on pipe %c\n" , -pipe_name (crtc->pipe)); +if (crtc->config.has_audio) intel_dp->DP |=DP_AUDIO_OUTPUT_ENABLE ; -intel_audio_codec_enable (encoder); - }/* Split out the IBX/CPU vs CPT settings */
@@ -2541,6 +2537,7 @@ static void intel_enable_dp(struct intel_encoder *encoder)struct intel_dp *intel_dp =enc_to_intel_dp (&encoder->base);struct drm_device *dev = encoder->base.dev;struct drm_i915_private *dev_priv = dev->dev_private; +struct intel_crtc *crtc =to_intel_crtc (encoder->base.crtc);uint32_t dp_reg =I915_READ (intel_dp->output_reg);if (WARN_ON (dp_reg &DP_PORT_EN ))
@@ -2554,6 +2551,12 @@ static void intel_enable_dp(struct intel_encoder *encoder)intel_dp_start_link_train (intel_dp);intel_dp_complete_link_train (intel_dp);intel_dp_stop_link_train (intel_dp); + +if (crtc->config.has_audio) { +DRM_DEBUG_DRIVER ("Enabling DP audio on pipe %c\n" , +pipe_name (crtc->pipe)); +intel_audio_codec_enable (encoder); + } }static void g4x_enable_dp (struct intel_encoder *encoder)
drivers/gpu/drm/i915/intel_hdmi.c +7 -8
@@ -661,14 +661,6 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder)if (crtc->config.has_hdmi_sink) hdmi_val |=HDMI_MODE_SELECT_HDMI ; -if (crtc->config.has_audio) { -WARN_ON (!crtc->config.has_hdmi_sink); -DRM_DEBUG_DRIVER ("Enabling HDMI audio on pipe %c\n" , -pipe_name (crtc->pipe)); - hdmi_val |=SDVO_AUDIO_ENABLE ; -intel_audio_codec_enable (encoder); - } -if (HAS_PCH_CPT (dev)) hdmi_val |=SDVO_PIPE_SEL_CPT (crtc->pipe);else if (IS_CHERRYVIEW (dev))
@@ -791,6 +783,13 @@ static void intel_enable_hdmi(struct intel_encoder *encoder)I915_WRITE (intel_hdmi->hdmi_reg, temp);POSTING_READ (intel_hdmi->hdmi_reg); } + +if (intel_crtc->config.has_audio) { +WARN_ON (!intel_crtc->config.has_hdmi_sink); +DRM_DEBUG_DRIVER ("Enabling HDMI audio on pipe %c\n" , +pipe_name (intel_crtc->pipe)); +intel_audio_codec_enable (encoder); + } }static void vlv_enable_hdmi (struct intel_encoder *encoder)
Signature · 1 line
1.9.1
PATCH 16/18 drm/i915/audio: add audio codec enable debug log for g4x
In reply to Jani Nikula--- drivers/gpu/drm/i915/intel_audio.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/i915/intel_audio.c +2 -0
@@ -122,6 +122,8 @@ static void g4x_audio_codec_enable(struct drm_connector *connector,uint32_t tmp;int len, i; +DRM_DEBUG_KMS ("Enable audio codec, %u bytes ELD\n" , eld[2 ]); + tmp =I915_READ (G4X_AUD_VID_DID );if (tmp ==INTEL_AUDIO_DEVBLC || tmp ==INTEL_AUDIO_DEVCL ) eldv =G4X_ELDV_DEVCL_DEVBLC ;
Signature · 1 line
1.9.1
PATCH 15/18 drm/i915/audio: add audio codec disable on g4x
In reply to Jani NikulaThis not based on any documentation...
--- drivers/gpu/drm/i915/intel_audio.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
drivers/gpu/drm/i915/intel_audio.c +20 -0
@@ -93,6 +93,25 @@ static bool intel_eld_uptodate(struct drm_connector *connector,return true; } +static void g4x_audio_codec_disable (struct intel_encoder *encoder) +{ +struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; +uint32_t eldv, tmp; + +DRM_DEBUG_KMS ("Disable audio codec\n" ); + + tmp =I915_READ (G4X_AUD_VID_DID ); +if (tmp ==INTEL_AUDIO_DEVBLC || tmp ==INTEL_AUDIO_DEVCL ) + eldv =G4X_ELDV_DEVCL_DEVBLC ; +else + eldv =G4X_ELDV_DEVCTG ; + +/* Invalidate ELD */ + tmp =I915_READ (G4X_AUD_CNTL_ST ); + tmp &= ~eldv; +I915_WRITE (G4X_AUD_CNTL_ST , tmp); +} +static void g4x_audio_codec_enable (struct drm_connector *connector,struct intel_encoder *encoder,struct drm_display_mode *mode)
@@ -381,6 +400,7 @@ void intel_init_audio(struct drm_device *dev)if (IS_G4X (dev)) { dev_priv->display.audio_codec_enable = g4x_audio_codec_enable; + dev_priv->display.audio_codec_disable = g4x_audio_codec_disable; }else if (IS_VALLEYVIEW (dev)) { dev_priv->display.audio_codec_enable = ilk_audio_codec_enable; dev_priv->display.audio_codec_disable = ilk_audio_codec_disable;
Signature · 1 line
1.9.1
PATCH 18/18 drm/i915/audio: add DOC comment describing HDA over HDMI/DP
In reply to Jani Nikula--- drivers/gpu/drm/i915/intel_audio.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
drivers/gpu/drm/i915/intel_audio.c +21 -0
@@ -28,6 +28,27 @@#include "intel_drv.h" #include "i915_drv.h" +/** +* DOC: High Definition Audio over HDMI and Display Port +* +* The graphics and audio drivers together support High Definition Audio over +* HDMI and Display Port. The audio programming sequences are divided into audio +* codec and controller enable and disable sequences. The graphics driver +* handles the audio codec sequences, while the audio driver handles the audio +* controller sequences. +* +* The disable sequences must be performed before disabling the transcoder or +* port. The enable sequences may only be performed after enabling the +* transcoder and port, and after completed link training. +* +* The codec and controller sequences could be done either parallel or serial, +* but generally the ELDV/PD change in the codec sequence indicates to the audio +* driver that the controller sequence should start. Indeed, most of the +* co-operation between the graphics and audio drivers is handled via audio +* related registers. (The notable exception is the power management, not +* covered here.) +*/ + static const struct { int clock; u32 config;
Signature · 1 line
1.9.1
PATCH 12/18 drm/i915/audio: rewrite vlv/chv and gen 5-7 audio codec enable sequence
In reply to Jani NikulaSimilar to the hsw/bdw enable sequence rewrite.
--- drivers/gpu/drm/i915/intel_audio.c | 58 +++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 32 deletions(-)
drivers/gpu/drm/i915/intel_audio.c +26 -32
@@ -210,6 +210,10 @@ static void ilk_audio_codec_enable(struct drm_connector *connector, {struct drm_i915_private *dev_priv = connector->dev->dev_private;struct drm_crtc *crtc = encoder->base.crtc; +struct intel_digital_port *intel_dig_port = +enc_to_dig_port (&encoder->base); +enum port port = intel_dig_port->port; +enum pipe pipe =to_intel_crtc (crtc)->pipe;uint8_t *eld = connector->eld;uint32_t eldv;uint32_t tmp;
@@ -218,8 +222,11 @@ static void ilk_audio_codec_enable(struct drm_connector *connector,int aud_config;int aud_cntl_st;int aud_cntrl_st2; -enum pipe pipe =to_intel_crtc (crtc)->pipe; -enum port port; + +DRM_DEBUG_KMS ("Enable audio codec on port %c, pipe %c, %u bytes ELD\n" , +port_name (port),pipe_name (pipe), eld[2 ]); + +intel_wait_for_vblank (dev_priv->dev, pipe);if (HAS_PCH_IBX (connector->dev)) { hdmiw_hdmiedid =IBX_HDMIW_HDMIEDID (pipe);
@@ -238,57 +245,44 @@ static void ilk_audio_codec_enable(struct drm_connector *connector, aud_cntrl_st2 =CPT_AUD_CNTRL_ST2 ; } -DRM_DEBUG_DRIVER ("ELD on pipe %c\n" ,pipe_name (pipe)); - -if (IS_VALLEYVIEW (connector->dev)) { -struct intel_digital_port *intel_dig_port; - - intel_dig_port =enc_to_dig_port (&encoder->base); - port = intel_dig_port->port; - }else { - tmp =I915_READ (aud_cntl_st); - port = (tmp >>29 ) &DIP_PORT_SEL_MASK ; -/* DIP_Port_Select, 0x1 = PortB */ - } - -if (!port) { -DRM_DEBUG_DRIVER ("Audio directed to unknown port\n" ); -/* operate blindly on all ports */ +if (WARN_ON (!port)) { eldv =IBX_ELD_VALIDB ; eldv |=IBX_ELD_VALIDB <<4 ; eldv |=IBX_ELD_VALIDB <<8 ; }else { -DRM_DEBUG_DRIVER ("ELD on port %c\n" ,port_name (port)); eldv =IBX_ELD_VALIDB << ((port -1 ) *4 ); } -if (intel_pipe_has_type (crtc,INTEL_OUTPUT_DISPLAYPORT )) -I915_WRITE (aud_config,AUD_CONFIG_N_VALUE_INDEX );/* 0x1 = DP */ -else -I915_WRITE (aud_config,audio_config_hdmi_pixel_clock (mode)); - -if (intel_eld_uptodate (connector, - aud_cntrl_st2, eldv, - aud_cntl_st,IBX_ELD_ADDRESS_MASK , - hdmiw_hdmiedid)) -return ; - +/* Invalidate ELD */ tmp =I915_READ (aud_cntrl_st2); tmp &= ~eldv;I915_WRITE (aud_cntrl_st2, tmp); +/* Reset ELD write address */ tmp =I915_READ (aud_cntl_st); tmp &= ~IBX_ELD_ADDRESS_MASK ;I915_WRITE (aud_cntl_st, tmp); - len =min_t (int, eld[2 ],21 );/* 84 bytes of hw ELD buffer */ -DRM_DEBUG_DRIVER ("ELD size %d\n" , len); +/* Up to 84 bytes of hw ELD buffer */ + len =min_t (int, eld[2 ],21 );for (i =0 ; i < len; i++)I915_WRITE (hdmiw_hdmiedid, *((uint32_t *)eld + i)); +/* ELD valid */ tmp =I915_READ (aud_cntrl_st2); tmp |= eldv;I915_WRITE (aud_cntrl_st2, tmp); + +/* Enable timestamps */ + tmp =I915_READ (aud_config); + tmp &= ~AUD_CONFIG_N_VALUE_INDEX ; + tmp &= ~AUD_CONFIG_N_PROG_ENABLE ; + tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK ; +if (intel_pipe_has_type (crtc,INTEL_OUTPUT_DISPLAYPORT )) + tmp |=AUD_CONFIG_N_VALUE_INDEX ; +else + tmp |=audio_config_hdmi_pixel_clock (mode); +I915_WRITE (aud_config, tmp); }void intel_audio_codec_enable (struct intel_encoder *intel_encoder)
Signature · 1 line
1.9.1
PATCH 17/18 drm/i915: make pipe/port based audio valid accessors easier to use
In reply to Jani Nikula--- drivers/gpu/drm/i915/i915_reg.h | 20 ++++++-------------- drivers/gpu/drm/i915/intel_audio.c | 22 ++++++++++------------ drivers/gpu/drm/i915/intel_ddi.c | 2 +- 3 files changed, 17 insertions(+), 27 deletions(-)
drivers/gpu/drm/i915/i915_reg.h +6 -14
@@ -5977,8 +5977,8 @@ enum punit_power_well {#define IBX_ELD_ADDRESS_MASK (0x1f << 5)#define IBX_ELD_ACK (1 << 4)#define IBX_AUD_CNTL_ST2 0xE20C0 -#define IBX_ELD_VALIDB (1 << 0) -#define IBX_CP_READYB (1 << 1) +#define IBX_CP_READY (port) ((1 << 1) << (((port) - 1) * 4)) +#define IBX_ELD_VALID (port) ((1 << 0) << (((port) - 1) * 4))#define _CPT_HDMIW_HDMIEDID_A 0xE5050#define _CPT_HDMIW_HDMIEDID_B 0xE5150
@@ -6081,18 +6081,10 @@ enum punit_power_well {#define HSW_AUD_PIPE_CONV_CFG 0x6507c#define HSW_AUD_PIN_ELD_CP_VLD 0x650c0 -#define AUDIO_INACTIVE_C (1<<11) -#define AUDIO_INACTIVE_B (1<<7) -#define AUDIO_INACTIVE_A (1<<3) -#define AUDIO_OUTPUT_ENABLE_A (1<<2) -#define AUDIO_OUTPUT_ENABLE_B (1<<6) -#define AUDIO_OUTPUT_ENABLE_C (1<<10) -#define AUDIO_ELD_VALID_A (1<<0) -#define AUDIO_ELD_VALID_B (1<<4) -#define AUDIO_ELD_VALID_C (1<<8) -#define AUDIO_CP_READY_A (1<<1) -#define AUDIO_CP_READY_B (1<<5) -#define AUDIO_CP_READY_C (1<<9) +#define AUDIO_INACTIVE (trans) ((1 << 3) << ((trans) * 4)) +#define AUDIO_OUTPUT_ENABLE (trans) ((1 << 2) << ((trans) * 4)) +#define AUDIO_CP_READY (trans) ((1 << 1) << ((trans) * 4)) +#define AUDIO_ELD_VALID (trans) ((1 << 0) << ((trans) * 4))/* HSW Power Wells */ #define HSW_PWR_WELL_BIOS 0x45400/* CTL1 */
drivers/gpu/drm/i915/intel_audio.c +10 -12
@@ -172,7 +172,7 @@ static void hsw_audio_codec_disable(struct intel_encoder *encoder)/* Invalidate ELD */ tmp =I915_READ (HSW_AUD_PIN_ELD_CP_VLD ); - tmp &= ~(AUDIO_ELD_VALID_A << (pipe *4 )); + tmp &= ~AUDIO_ELD_VALID (pipe);I915_WRITE (HSW_AUD_PIN_ELD_CP_VLD , tmp); }
@@ -192,8 +192,8 @@ static void hsw_audio_codec_enable(struct drm_connector *connector,/* Enable audio presence detect, invalidate ELD */ tmp =I915_READ (HSW_AUD_PIN_ELD_CP_VLD ); - tmp |=AUDIO_OUTPUT_ENABLE_A << (pipe *4 ); - tmp &= ~(AUDIO_ELD_VALID_A << (pipe *4 )); + tmp |=AUDIO_OUTPUT_ENABLE (pipe); + tmp &= ~AUDIO_ELD_VALID (pipe);I915_WRITE (HSW_AUD_PIN_ELD_CP_VLD , tmp);intel_wait_for_vblank (dev_priv->dev, pipe);
@@ -210,7 +210,7 @@ static void hsw_audio_codec_enable(struct drm_connector *connector,/* ELD valid */ tmp =I915_READ (HSW_AUD_PIN_ELD_CP_VLD ); - tmp |=AUDIO_ELD_VALID_A << (pipe *4 ); + tmp |=AUDIO_ELD_VALID (pipe);I915_WRITE (HSW_AUD_PIN_ELD_CP_VLD , tmp);/* Enable timestamps */
@@ -262,11 +262,10 @@ static void ilk_audio_codec_disable(struct intel_encoder *encoder)I915_WRITE (aud_config, tmp);if (WARN_ON (!port)) { - eldv =IBX_ELD_VALIDB ; - eldv |=IBX_ELD_VALIDB <<4 ; - eldv |=IBX_ELD_VALIDB <<8 ; + eldv =IBX_ELD_VALID (PORT_B ) |IBX_ELD_VALID (PORT_C ) | +IBX_ELD_VALID (PORT_D ); }else { - eldv =IBX_ELD_VALIDB << ((port -1 ) *4 ); + eldv =IBX_ELD_VALID (port); }/* Invalidate ELD */
@@ -317,11 +316,10 @@ static void ilk_audio_codec_enable(struct drm_connector *connector, }if (WARN_ON (!port)) { - eldv =IBX_ELD_VALIDB ; - eldv |=IBX_ELD_VALIDB <<4 ; - eldv |=IBX_ELD_VALIDB <<8 ; + eldv =IBX_ELD_VALID (PORT_B ) |IBX_ELD_VALID (PORT_C ) | +IBX_ELD_VALID (PORT_D ); }else { - eldv =IBX_ELD_VALIDB << ((port -1 ) *4 ); + eldv =IBX_ELD_VALID (port); }/* Invalidate ELD */
drivers/gpu/drm/i915/intel_ddi.c +1 -1
@@ -1504,7 +1504,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,if (intel_display_power_is_enabled (dev_priv,POWER_DOMAIN_AUDIO )) { temp =I915_READ (HSW_AUD_PIN_ELD_CP_VLD ); -if (temp & (AUDIO_OUTPUT_ENABLE_A << (intel_crtc->pipe *4 ))) +if (temp &AUDIO_OUTPUT_ENABLE (intel_crtc->pipe)) pipe_config->has_audio = true; }
Signature · 1 line
1.9.1
Re: [PATCH 18/18] drm/i915/audio: add DOC comment describing HDA over HDMI/DP
In reply to Jani NikulaQuoted 23 lines · Jani Nikula
Signed-off-by Jani Nikula <[email protected]>--- drivers/gpu/drm/i915/intel_audio.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)drivers/gpu/drm/i915/intel_audio.c +10
-0@@ -28,6 +28,27 @@#include "intel_drv.h" #include "i915_drv.h" +/** +* DOC: High Definition Audio over HDMI and Display Port +* +* The graphics and audio drivers together support High Definition Audio over +* HDMI and Display Port. The audio programming sequences are divided into audio +* codec and controller enable and disable sequences. The graphics driver +* handles the audio codec sequences, while the audio driver handles the audio +* controller sequences. +* +* The disable sequences must be performed before disabling the transcoder or
drivers/gpu/drm/i915/intel_audio.c line 50
Quoted 10 lines
drivers/gpu/drm/i915/intel_audio.c +10
-0+* port. The enable sequences may only be performed after enabling the +* transcoder and port, and after completed link training. +* +* The codec and controller sequences could be done either parallel or serial, +* but generally the ELDV/PD change in the codec sequence indicates to the audio +* driver that the controller sequence should start. Indeed, most of the +* co-operation between the graphics and audio drivers is handled via audio +* related registers. (The notable exception is the power management, not +* covered here.) +*/
Generally when documenting a new file I also document all the non-static functions exported to the driver. But I guess this can wait until the functional/interface changes are merged.
Also, this should get pulled into the drm/i915 docbook in a new chapter in the modeset section.
Otherwise I like the series, at least from a very high-level read-through. Please sign someone up for review.
-Daniel
Quoted 11 lines
drivers/gpu/drm/i915/intel_audio.c +1
-0+ static const struct { int clock; u32 config;Signature · 6 lines
1.9.1 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 3 lines
Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch