50,7 → 50,7 |
|
enabled_bits = HAS_DDI(dev) ? DDI_BUF_CTL_ENABLE : SDVO_ENABLE; |
|
WARN(I915_READ(intel_hdmi->sdvox_reg) & enabled_bits, |
WARN(I915_READ(intel_hdmi->hdmi_reg) & enabled_bits, |
"HDMI port enabled, expecting disabled\n"); |
} |
|
120,13 → 120,14 |
} |
} |
|
static u32 hsw_infoframe_data_reg(struct dip_infoframe *frame, enum pipe pipe) |
static u32 hsw_infoframe_data_reg(struct dip_infoframe *frame, |
enum transcoder cpu_transcoder) |
{ |
switch (frame->type) { |
case DIP_TYPE_AVI: |
return HSW_TVIDEO_DIP_AVI_DATA(pipe); |
return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder); |
case DIP_TYPE_SPD: |
return HSW_TVIDEO_DIP_SPD_DATA(pipe); |
return HSW_TVIDEO_DIP_SPD_DATA(cpu_transcoder); |
default: |
DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); |
return 0; |
293,8 → 294,8 |
struct drm_device *dev = encoder->dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->pipe); |
u32 data_reg = hsw_infoframe_data_reg(frame, intel_crtc->pipe); |
u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config.cpu_transcoder); |
u32 data_reg = hsw_infoframe_data_reg(frame, intel_crtc->config.cpu_transcoder); |
unsigned int i, len = DIP_HEADER_SIZE + frame->len; |
u32 val = I915_READ(ctl_reg); |
|
332,6 → 333,7 |
struct drm_display_mode *adjusted_mode) |
{ |
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
struct dip_infoframe avi_if = { |
.type = DIP_TYPE_AVI, |
.ver = DIP_VERSION_AVI, |
342,7 → 344,7 |
avi_if.body.avi.YQ_CN_PR |= DIP_AVI_PR_2; |
|
if (intel_hdmi->rgb_quant_range_selectable) { |
if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE) |
if (intel_crtc->config.limited_color_range) |
avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_LIMITED; |
else |
avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_FULL; |
568,7 → 570,7 |
struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc->pipe); |
u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config.cpu_transcoder); |
u32 val = I915_READ(reg); |
|
assert_hdmi_port_disabled(intel_hdmi); |
597,40 → 599,40 |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
u32 sdvox; |
u32 hdmi_val; |
|
sdvox = SDVO_ENCODING_HDMI; |
if (!HAS_PCH_SPLIT(dev)) |
sdvox |= intel_hdmi->color_range; |
hdmi_val = SDVO_ENCODING_HDMI; |
if (!HAS_PCH_SPLIT(dev) && !IS_VALLEYVIEW(dev)) |
hdmi_val |= intel_hdmi->color_range; |
if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) |
sdvox |= SDVO_VSYNC_ACTIVE_HIGH; |
hdmi_val |= SDVO_VSYNC_ACTIVE_HIGH; |
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
sdvox |= SDVO_HSYNC_ACTIVE_HIGH; |
hdmi_val |= SDVO_HSYNC_ACTIVE_HIGH; |
|
if (intel_crtc->bpp > 24) |
sdvox |= COLOR_FORMAT_12bpc; |
if (intel_crtc->config.pipe_bpp > 24) |
hdmi_val |= HDMI_COLOR_FORMAT_12bpc; |
else |
sdvox |= COLOR_FORMAT_8bpc; |
hdmi_val |= SDVO_COLOR_FORMAT_8bpc; |
|
/* Required on CPT */ |
if (intel_hdmi->has_hdmi_sink && HAS_PCH_CPT(dev)) |
sdvox |= HDMI_MODE_SELECT; |
hdmi_val |= HDMI_MODE_SELECT_HDMI; |
|
if (intel_hdmi->has_audio) { |
DRM_DEBUG_DRIVER("Enabling HDMI audio on pipe %c\n", |
pipe_name(intel_crtc->pipe)); |
sdvox |= SDVO_AUDIO_ENABLE; |
sdvox |= SDVO_NULL_PACKETS_DURING_VSYNC; |
hdmi_val |= SDVO_AUDIO_ENABLE; |
hdmi_val |= HDMI_MODE_SELECT_HDMI; |
intel_write_eld(encoder, adjusted_mode); |
} |
|
if (HAS_PCH_CPT(dev)) |
sdvox |= PORT_TRANS_SEL_CPT(intel_crtc->pipe); |
else if (intel_crtc->pipe == PIPE_B) |
sdvox |= SDVO_PIPE_B_SELECT; |
hdmi_val |= SDVO_PIPE_SEL_CPT(intel_crtc->pipe); |
else |
hdmi_val |= SDVO_PIPE_SEL(intel_crtc->pipe); |
|
I915_WRITE(intel_hdmi->sdvox_reg, sdvox); |
POSTING_READ(intel_hdmi->sdvox_reg); |
I915_WRITE(intel_hdmi->hdmi_reg, hdmi_val); |
POSTING_READ(intel_hdmi->hdmi_reg); |
|
intel_hdmi->set_infoframes(encoder, adjusted_mode); |
} |
643,7 → 645,7 |
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); |
u32 tmp; |
|
tmp = I915_READ(intel_hdmi->sdvox_reg); |
tmp = I915_READ(intel_hdmi->hdmi_reg); |
|
if (!(tmp & SDVO_ENABLE)) |
return false; |
660,6 → 662,7 |
{ |
struct drm_device *dev = encoder->base.dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); |
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); |
u32 temp; |
u32 enable_bits = SDVO_ENABLE; |
667,38 → 670,32 |
if (intel_hdmi->has_audio) |
enable_bits |= SDVO_AUDIO_ENABLE; |
|
temp = I915_READ(intel_hdmi->sdvox_reg); |
temp = I915_READ(intel_hdmi->hdmi_reg); |
|
/* HW workaround for IBX, we need to move the port to transcoder A |
* before disabling it. */ |
if (HAS_PCH_IBX(dev)) { |
struct drm_crtc *crtc = encoder->base.crtc; |
int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1; |
* before disabling it, so restore the transcoder select bit here. */ |
if (HAS_PCH_IBX(dev)) |
enable_bits |= SDVO_PIPE_SEL(intel_crtc->pipe); |
|
/* Restore the transcoder select bit. */ |
if (pipe == PIPE_B) |
enable_bits |= SDVO_PIPE_B_SELECT; |
} |
|
/* HW workaround, need to toggle enable bit off and on for 12bpc, but |
* we do this anyway which shows more stable in testing. |
*/ |
if (HAS_PCH_SPLIT(dev)) { |
I915_WRITE(intel_hdmi->sdvox_reg, temp & ~SDVO_ENABLE); |
POSTING_READ(intel_hdmi->sdvox_reg); |
I915_WRITE(intel_hdmi->hdmi_reg, temp & ~SDVO_ENABLE); |
POSTING_READ(intel_hdmi->hdmi_reg); |
} |
|
temp |= enable_bits; |
|
I915_WRITE(intel_hdmi->sdvox_reg, temp); |
POSTING_READ(intel_hdmi->sdvox_reg); |
I915_WRITE(intel_hdmi->hdmi_reg, temp); |
POSTING_READ(intel_hdmi->hdmi_reg); |
|
/* HW workaround, need to write this twice for issue that may result |
* in first write getting masked. |
*/ |
if (HAS_PCH_SPLIT(dev)) { |
I915_WRITE(intel_hdmi->sdvox_reg, temp); |
POSTING_READ(intel_hdmi->sdvox_reg); |
I915_WRITE(intel_hdmi->hdmi_reg, temp); |
POSTING_READ(intel_hdmi->hdmi_reg); |
} |
} |
|
710,7 → 707,7 |
u32 temp; |
u32 enable_bits = SDVO_ENABLE | SDVO_AUDIO_ENABLE; |
|
temp = I915_READ(intel_hdmi->sdvox_reg); |
temp = I915_READ(intel_hdmi->hdmi_reg); |
|
/* HW workaround for IBX, we need to move the port to transcoder A |
* before disabling it. */ |
720,12 → 717,12 |
|
if (temp & SDVO_PIPE_B_SELECT) { |
temp &= ~SDVO_PIPE_B_SELECT; |
I915_WRITE(intel_hdmi->sdvox_reg, temp); |
POSTING_READ(intel_hdmi->sdvox_reg); |
I915_WRITE(intel_hdmi->hdmi_reg, temp); |
POSTING_READ(intel_hdmi->hdmi_reg); |
|
/* Again we need to write this twice. */ |
I915_WRITE(intel_hdmi->sdvox_reg, temp); |
POSTING_READ(intel_hdmi->sdvox_reg); |
I915_WRITE(intel_hdmi->hdmi_reg, temp); |
POSTING_READ(intel_hdmi->hdmi_reg); |
|
/* Transcoder selection bits only update |
* effectively on vblank. */ |
740,21 → 737,21 |
* we do this anyway which shows more stable in testing. |
*/ |
if (HAS_PCH_SPLIT(dev)) { |
I915_WRITE(intel_hdmi->sdvox_reg, temp & ~SDVO_ENABLE); |
POSTING_READ(intel_hdmi->sdvox_reg); |
I915_WRITE(intel_hdmi->hdmi_reg, temp & ~SDVO_ENABLE); |
POSTING_READ(intel_hdmi->hdmi_reg); |
} |
|
temp &= ~enable_bits; |
|
I915_WRITE(intel_hdmi->sdvox_reg, temp); |
POSTING_READ(intel_hdmi->sdvox_reg); |
I915_WRITE(intel_hdmi->hdmi_reg, temp); |
POSTING_READ(intel_hdmi->hdmi_reg); |
|
/* HW workaround, need to write this twice for issue that may result |
* in first write getting masked. |
*/ |
if (HAS_PCH_SPLIT(dev)) { |
I915_WRITE(intel_hdmi->sdvox_reg, temp); |
POSTING_READ(intel_hdmi->sdvox_reg); |
I915_WRITE(intel_hdmi->hdmi_reg, temp); |
POSTING_READ(intel_hdmi->hdmi_reg); |
} |
} |
|
772,24 → 769,41 |
return MODE_OK; |
} |
|
bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, |
const struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode) |
bool intel_hdmi_compute_config(struct intel_encoder *encoder, |
struct intel_crtc_config *pipe_config) |
{ |
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); |
struct drm_device *dev = encoder->base.dev; |
struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; |
|
if (intel_hdmi->color_range_auto) { |
/* See CEA-861-E - 5.1 Default Encoding Parameters */ |
if (intel_hdmi->has_hdmi_sink && |
drm_match_cea_mode(adjusted_mode) > 1) |
intel_hdmi->color_range = SDVO_COLOR_RANGE_16_235; |
intel_hdmi->color_range = HDMI_COLOR_RANGE_16_235; |
else |
intel_hdmi->color_range = 0; |
} |
|
if (intel_hdmi->color_range) |
adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE; |
pipe_config->limited_color_range = true; |
|
if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev)) |
pipe_config->has_pch_encoder = true; |
|
/* |
* HDMI is either 12 or 8, so if the display lets 10bpc sneak |
* through, clamp it down. Note that g4x/vlv don't support 12bpc hdmi |
* outputs. |
*/ |
if (pipe_config->pipe_bpp > 8*3 && HAS_PCH_SPLIT(dev)) { |
DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n"); |
pipe_config->pipe_bpp = 12*3; |
} else { |
DRM_DEBUG_KMS("forcing bpc to 8 for HDMI\n"); |
pipe_config->pipe_bpp = 8*3; |
} |
|
return true; |
} |
|
906,6 → 920,9 |
} |
|
if (property == dev_priv->broadcast_rgb_property) { |
bool old_auto = intel_hdmi->color_range_auto; |
uint32_t old_range = intel_hdmi->color_range; |
|
switch (val) { |
case INTEL_BROADCAST_RGB_AUTO: |
intel_hdmi->color_range_auto = true; |
916,11 → 933,16 |
break; |
case INTEL_BROADCAST_RGB_LIMITED: |
intel_hdmi->color_range_auto = false; |
intel_hdmi->color_range = SDVO_COLOR_RANGE_16_235; |
intel_hdmi->color_range = HDMI_COLOR_RANGE_16_235; |
break; |
default: |
return -EINVAL; |
} |
|
if (old_auto == intel_hdmi->color_range_auto && |
old_range == intel_hdmi->color_range) |
return 0; |
|
goto done; |
} |
|
941,7 → 963,6 |
} |
|
static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { |
.mode_fixup = intel_hdmi_mode_fixup, |
.mode_set = intel_hdmi_mode_set, |
}; |
|
985,7 → 1006,6 |
DRM_MODE_CONNECTOR_HDMIA); |
drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs); |
|
connector->polled = DRM_CONNECTOR_POLL_HPD; |
connector->interlace_allowed = 1; |
connector->doublescan_allowed = 0; |
|
992,29 → 1012,30 |
switch (port) { |
case PORT_B: |
intel_hdmi->ddc_bus = GMBUS_PORT_DPB; |
dev_priv->hotplug_supported_mask |= PORTB_HOTPLUG_INT_STATUS; |
intel_encoder->hpd_pin = HPD_PORT_B; |
break; |
case PORT_C: |
intel_hdmi->ddc_bus = GMBUS_PORT_DPC; |
dev_priv->hotplug_supported_mask |= PORTC_HOTPLUG_INT_STATUS; |
intel_encoder->hpd_pin = HPD_PORT_C; |
break; |
case PORT_D: |
intel_hdmi->ddc_bus = GMBUS_PORT_DPD; |
dev_priv->hotplug_supported_mask |= PORTD_HOTPLUG_INT_STATUS; |
intel_encoder->hpd_pin = HPD_PORT_D; |
break; |
case PORT_A: |
intel_encoder->hpd_pin = HPD_PORT_A; |
/* Internal port only for eDP. */ |
default: |
BUG(); |
} |
|
if (!HAS_PCH_SPLIT(dev)) { |
if (IS_VALLEYVIEW(dev)) { |
intel_hdmi->write_infoframe = vlv_write_infoframe; |
intel_hdmi->set_infoframes = vlv_set_infoframes; |
} else if (!HAS_PCH_SPLIT(dev)) { |
intel_hdmi->write_infoframe = g4x_write_infoframe; |
intel_hdmi->set_infoframes = g4x_set_infoframes; |
} else if (IS_VALLEYVIEW(dev)) { |
intel_hdmi->write_infoframe = vlv_write_infoframe; |
intel_hdmi->set_infoframes = vlv_set_infoframes; |
} else if (IS_HASWELL(dev)) { |
} else if (HAS_DDI(dev)) { |
intel_hdmi->write_infoframe = hsw_write_infoframe; |
intel_hdmi->set_infoframes = hsw_set_infoframes; |
} else if (HAS_PCH_IBX(dev)) { |
1045,7 → 1066,7 |
} |
} |
|
void intel_hdmi_init(struct drm_device *dev, int sdvox_reg, enum port port) |
void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port) |
{ |
struct intel_digital_port *intel_dig_port; |
struct intel_encoder *intel_encoder; |
1069,6 → 1090,7 |
DRM_MODE_ENCODER_TMDS); |
drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs); |
|
intel_encoder->compute_config = intel_hdmi_compute_config; |
intel_encoder->enable = intel_enable_hdmi; |
intel_encoder->disable = intel_disable_hdmi; |
intel_encoder->get_hw_state = intel_hdmi_get_hw_state; |
1078,7 → 1100,7 |
intel_encoder->cloneable = false; |
|
intel_dig_port->port = port; |
intel_dig_port->hdmi.sdvox_reg = sdvox_reg; |
intel_dig_port->hdmi.hdmi_reg = hdmi_reg; |
intel_dig_port->dp.output_reg = 0; |
|
intel_hdmi_init_connector(intel_dig_port, intel_connector); |