161,9 → 161,9 |
} |
|
static bool intel_eld_uptodate(struct drm_connector *connector, |
int reg_eldv, uint32_t bits_eldv, |
int reg_elda, uint32_t bits_elda, |
int reg_edid) |
i915_reg_t reg_eldv, uint32_t bits_eldv, |
i915_reg_t reg_elda, uint32_t bits_elda, |
i915_reg_t reg_edid) |
{ |
struct drm_i915_private *dev_priv = connector->dev->dev_private; |
uint8_t *eld = connector->eld; |
364,8 → 364,7 |
enum port port = intel_dig_port->port; |
enum pipe pipe = intel_crtc->pipe; |
uint32_t tmp, eldv; |
int aud_config; |
int aud_cntrl_st2; |
i915_reg_t aud_config, aud_cntrl_st2; |
|
DRM_DEBUG_KMS("Disable audio codec on port %c, pipe %c\n", |
port_name(port), pipe_name(pipe)); |
376,7 → 375,7 |
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)) { |
} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { |
aud_config = VLV_AUD_CFG(pipe); |
aud_cntrl_st2 = VLV_AUD_CNTL_ST2; |
} else { |
416,10 → 415,7 |
uint32_t eldv; |
uint32_t tmp; |
int len, i; |
int hdmiw_hdmiedid; |
int aud_config; |
int aud_cntl_st; |
int aud_cntrl_st2; |
i915_reg_t hdmiw_hdmiedid, aud_config, aud_cntl_st, aud_cntrl_st2; |
|
DRM_DEBUG_KMS("Enable audio codec on port %c, pipe %c, %u bytes ELD\n", |
port_name(port), pipe_name(pipe), drm_eld_size(eld)); |
439,7 → 435,8 |
aud_config = IBX_AUD_CFG(pipe); |
aud_cntl_st = IBX_AUD_CNTL_ST(pipe); |
aud_cntrl_st2 = IBX_AUD_CNTL_ST2; |
} else if (IS_VALLEYVIEW(connector->dev)) { |
} else if (IS_VALLEYVIEW(connector->dev) || |
IS_CHERRYVIEW(connector->dev)) { |
hdmiw_hdmiedid = VLV_HDMIW_HDMIEDID(pipe); |
aud_config = VLV_AUD_CFG(pipe); |
aud_cntl_st = VLV_AUD_CNTL_ST(pipe); |
525,6 → 522,12 |
dev_priv->display.audio_codec_enable(connector, intel_encoder, |
adjusted_mode); |
|
mutex_lock(&dev_priv->av_mutex); |
intel_dig_port->audio_connector = connector; |
/* referred in audio callbacks */ |
dev_priv->dig_port_map[port] = intel_encoder; |
mutex_unlock(&dev_priv->av_mutex); |
|
if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) |
acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port); |
} |
548,6 → 551,11 |
if (dev_priv->display.audio_codec_disable) |
dev_priv->display.audio_codec_disable(intel_encoder); |
|
mutex_lock(&dev_priv->av_mutex); |
intel_dig_port->audio_connector = NULL; |
dev_priv->dig_port_map[port] = NULL; |
mutex_unlock(&dev_priv->av_mutex); |
|
if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) |
acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port); |
} |
591,7 → 599,7 |
struct drm_i915_private *dev_priv = dev_to_i915(dev); |
u32 tmp; |
|
if (!IS_SKYLAKE(dev_priv)) |
if (!IS_SKYLAKE(dev_priv) && !IS_KABYLAKE(dev_priv)) |
return; |
|
/* |
632,18 → 640,18 |
int port, int rate) |
{ |
struct drm_i915_private *dev_priv = dev_to_i915(dev); |
struct drm_device *drm_dev = dev_priv->dev; |
struct intel_encoder *intel_encoder; |
struct intel_digital_port *intel_dig_port; |
struct intel_crtc *crtc; |
struct drm_display_mode *mode; |
struct i915_audio_component *acomp = dev_priv->audio_component; |
enum pipe pipe = -1; |
enum pipe pipe = INVALID_PIPE; |
u32 tmp; |
int n; |
int err = 0; |
|
/* HSW, BDW SKL need this fix */ |
/* HSW, BDW, SKL, KBL need this fix */ |
if (!IS_SKYLAKE(dev_priv) && |
!IS_KABYLAKE(dev_priv) && |
!IS_BROADWELL(dev_priv) && |
!IS_HASWELL(dev_priv)) |
return 0; |
650,26 → 658,22 |
|
mutex_lock(&dev_priv->av_mutex); |
/* 1. get the pipe */ |
for_each_intel_encoder(drm_dev, intel_encoder) { |
if (intel_encoder->type != INTEL_OUTPUT_HDMI) |
continue; |
intel_dig_port = enc_to_dig_port(&intel_encoder->base); |
if (port == intel_dig_port->port) { |
intel_encoder = dev_priv->dig_port_map[port]; |
/* intel_encoder might be NULL for DP MST */ |
if (!intel_encoder || !intel_encoder->base.crtc || |
intel_encoder->type != INTEL_OUTPUT_HDMI) { |
DRM_DEBUG_KMS("no valid port %c\n", port_name(port)); |
err = -ENODEV; |
goto unlock; |
} |
crtc = to_intel_crtc(intel_encoder->base.crtc); |
if (!crtc) { |
DRM_DEBUG_KMS("%s: crtc is NULL\n", __func__); |
continue; |
} |
pipe = crtc->pipe; |
break; |
} |
} |
|
if (pipe == INVALID_PIPE) { |
DRM_DEBUG_KMS("no pipe for the port %c\n", port_name(port)); |
mutex_unlock(&dev_priv->av_mutex); |
return -ENODEV; |
err = -ENODEV; |
goto unlock; |
} |
|
DRM_DEBUG_KMS("pipe %c connects port %c\n", |
pipe_name(pipe), port_name(port)); |
mode = &crtc->config->base.adjusted_mode; |
682,8 → 686,7 |
tmp = I915_READ(HSW_AUD_CFG(pipe)); |
tmp &= ~AUD_CONFIG_N_PROG_ENABLE; |
I915_WRITE(HSW_AUD_CFG(pipe), tmp); |
mutex_unlock(&dev_priv->av_mutex); |
return 0; |
goto unlock; |
} |
|
n = audio_config_get_n(mode, rate); |
693,8 → 696,7 |
tmp = I915_READ(HSW_AUD_CFG(pipe)); |
tmp &= ~AUD_CONFIG_N_PROG_ENABLE; |
I915_WRITE(HSW_AUD_CFG(pipe), tmp); |
mutex_unlock(&dev_priv->av_mutex); |
return 0; |
goto unlock; |
} |
|
/* 3. set the N/CTS/M */ |
702,10 → 704,39 |
tmp = audio_config_setup_n_reg(n, tmp); |
I915_WRITE(HSW_AUD_CFG(pipe), tmp); |
|
unlock: |
mutex_unlock(&dev_priv->av_mutex); |
return 0; |
return err; |
} |
|
static int i915_audio_component_get_eld(struct device *dev, int port, |
bool *enabled, |
unsigned char *buf, int max_bytes) |
{ |
struct drm_i915_private *dev_priv = dev_to_i915(dev); |
struct intel_encoder *intel_encoder; |
struct intel_digital_port *intel_dig_port; |
const u8 *eld; |
int ret = -EINVAL; |
|
mutex_lock(&dev_priv->av_mutex); |
intel_encoder = dev_priv->dig_port_map[port]; |
/* intel_encoder might be NULL for DP MST */ |
if (intel_encoder) { |
ret = 0; |
intel_dig_port = enc_to_dig_port(&intel_encoder->base); |
*enabled = intel_dig_port->audio_connector != NULL; |
if (*enabled) { |
eld = intel_dig_port->audio_connector->eld; |
ret = drm_eld_size(eld); |
memcpy(buf, eld, min(max_bytes, ret)); |
} |
} |
|
mutex_unlock(&dev_priv->av_mutex); |
return ret; |
} |
|
static const struct i915_audio_component_ops i915_audio_component_ops = { |
.owner = THIS_MODULE, |
.get_power = i915_audio_component_get_power, |
713,6 → 744,7 |
.codec_wake_override = i915_audio_component_codec_wake_override, |
.get_cdclk_freq = i915_audio_component_get_cdclk_freq, |
.sync_audio_rate = i915_audio_component_sync_audio_rate, |
.get_eld = i915_audio_component_get_eld, |
}; |
|
static int i915_audio_component_bind(struct device *i915_dev, |
773,6 → 805,16 |
*/ |
void i915_audio_component_init(struct drm_i915_private *dev_priv) |
{ |
int ret; |
|
// ret = component_add(dev_priv->dev->dev, &i915_audio_component_bind_ops); |
// if (ret < 0) { |
// DRM_ERROR("failed to add audio component (%d)\n", ret); |
// /* continue with reduced functionality */ |
// return; |
// } |
|
dev_priv->audio_component_registered = true; |
} |
|
/** |
784,4 → 826,9 |
*/ |
void i915_audio_component_cleanup(struct drm_i915_private *dev_priv) |
{ |
if (!dev_priv->audio_component_registered) |
return; |
|
// component_del(dev_priv->dev->dev, &i915_audio_component_bind_ops); |
dev_priv->audio_component_registered = false; |
} |