130,9 → 130,9 |
|
static void g4x_write_infoframe(struct drm_encoder *encoder, |
enum hdmi_infoframe_type type, |
const uint8_t *frame, ssize_t len) |
const void *frame, ssize_t len) |
{ |
uint32_t *data = (uint32_t *)frame; |
const uint32_t *data = frame; |
struct drm_device *dev = encoder->dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
u32 val = I915_READ(VIDEO_DIP_CTL); |
167,9 → 167,9 |
|
static void ibx_write_infoframe(struct drm_encoder *encoder, |
enum hdmi_infoframe_type type, |
const uint8_t *frame, ssize_t len) |
const void *frame, ssize_t len) |
{ |
uint32_t *data = (uint32_t *)frame; |
const uint32_t *data = frame; |
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); |
205,9 → 205,9 |
|
static void cpt_write_infoframe(struct drm_encoder *encoder, |
enum hdmi_infoframe_type type, |
const uint8_t *frame, ssize_t len) |
const void *frame, ssize_t len) |
{ |
uint32_t *data = (uint32_t *)frame; |
const uint32_t *data = frame; |
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); |
246,9 → 246,9 |
|
static void vlv_write_infoframe(struct drm_encoder *encoder, |
enum hdmi_infoframe_type type, |
const uint8_t *frame, ssize_t len) |
const void *frame, ssize_t len) |
{ |
uint32_t *data = (uint32_t *)frame; |
const uint32_t *data = frame; |
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); |
284,9 → 284,9 |
|
static void hsw_write_infoframe(struct drm_encoder *encoder, |
enum hdmi_infoframe_type type, |
const uint8_t *frame, ssize_t len) |
const void *frame, ssize_t len) |
{ |
uint32_t *data = (uint32_t *)frame; |
const uint32_t *data = frame; |
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); |
713,6 → 713,7 |
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); |
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
u32 tmp, flags = 0; |
int dotclock; |
|
tmp = I915_READ(intel_hdmi->hdmi_reg); |
|
727,6 → 728,16 |
flags |= DRM_MODE_FLAG_NVSYNC; |
|
pipe_config->adjusted_mode.flags |= flags; |
|
if ((tmp & SDVO_COLOR_FORMAT_MASK) == HDMI_COLOR_FORMAT_12bpc) |
dotclock = pipe_config->port_clock * 2 / 3; |
else |
dotclock = pipe_config->port_clock; |
|
if (HAS_PCH_SPLIT(dev_priv->dev)) |
ironlake_check_encoder_dotclock(pipe_config, dotclock); |
|
pipe_config->adjusted_mode.crtc_clock = dotclock; |
} |
|
static void intel_enable_hdmi(struct intel_encoder *encoder) |
836,13 → 847,14 |
|
if (IS_G4X(dev)) |
return 165000; |
else if (IS_HASWELL(dev)) |
else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) |
return 300000; |
else |
return 225000; |
} |
|
static int intel_hdmi_mode_valid(struct drm_connector *connector, |
static enum drm_mode_status |
intel_hdmi_mode_valid(struct drm_connector *connector, |
struct drm_display_mode *mode) |
{ |
if (mode->clock > hdmi_portclock_limit(intel_attached_hdmi(connector))) |
862,7 → 874,7 |
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; |
int clock_12bpc = pipe_config->requested_mode.clock * 3 / 2; |
int clock_12bpc = pipe_config->adjusted_mode.crtc_clock * 3 / 2; |
int portclock_limit = hdmi_portclock_limit(intel_hdmi); |
int desired_bpp; |
|
904,7 → 916,7 |
pipe_config->pipe_bpp = desired_bpp; |
} |
|
if (adjusted_mode->clock > portclock_limit) { |
if (adjusted_mode->crtc_clock > portclock_limit) { |
DRM_DEBUG_KMS("too high HDMI clock, rejecting mode\n"); |
return false; |
} |
1063,7 → 1075,7 |
return 0; |
} |
|
static void intel_hdmi_pre_enable(struct intel_encoder *encoder) |
static void vlv_hdmi_pre_enable(struct intel_encoder *encoder) |
{ |
struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); |
struct drm_device *dev = encoder->base.dev; |
1070,7 → 1082,7 |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_crtc *intel_crtc = |
to_intel_crtc(encoder->base.crtc); |
int port = vlv_dport_to_channel(dport); |
enum dpio_channel port = vlv_dport_to_channel(dport); |
int pipe = intel_crtc->pipe; |
u32 val; |
|
1079,7 → 1091,7 |
|
/* Enable clock channels for this port */ |
mutex_lock(&dev_priv->dpio_lock); |
val = vlv_dpio_read(dev_priv, DPIO_DATA_LANE_A(port)); |
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW8(port)); |
val = 0; |
if (pipe) |
val |= (1<<21); |
1086,42 → 1098,37 |
else |
val &= ~(1<<21); |
val |= 0x001000c4; |
vlv_dpio_write(dev_priv, DPIO_DATA_CHANNEL(port), val); |
vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW8(port), val); |
|
/* HDMI 1.0V-2dB */ |
vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), 0); |
vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL4(port), |
0x2b245f5f); |
vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL2(port), |
0x5578b83a); |
vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL3(port), |
0x0c782040); |
vlv_dpio_write(dev_priv, DPIO_TX3_SWING_CTL4(port), |
0x2b247878); |
vlv_dpio_write(dev_priv, DPIO_PCS_STAGGER0(port), 0x00030000); |
vlv_dpio_write(dev_priv, DPIO_PCS_CTL_OVER1(port), |
0x00002000); |
vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), |
DPIO_TX_OCALINIT_EN); |
vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0); |
vlv_dpio_write(dev_priv, pipe, VLV_TX_DW4(port), 0x2b245f5f); |
vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(port), 0x5578b83a); |
vlv_dpio_write(dev_priv, pipe, VLV_TX_DW3(port), 0x0c782040); |
vlv_dpio_write(dev_priv, pipe, VLV_TX3_DW4(port), 0x2b247878); |
vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW11(port), 0x00030000); |
vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW9(port), 0x00002000); |
vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), DPIO_TX_OCALINIT_EN); |
|
/* Program lane clock */ |
vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF0(port), |
0x00760018); |
vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(port), |
0x00400888); |
vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW14(port), 0x00760018); |
vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW23(port), 0x00400888); |
mutex_unlock(&dev_priv->dpio_lock); |
|
intel_enable_hdmi(encoder); |
|
vlv_wait_port_ready(dev_priv, port); |
vlv_wait_port_ready(dev_priv, dport); |
} |
|
static void intel_hdmi_pre_pll_enable(struct intel_encoder *encoder) |
static void vlv_hdmi_pre_pll_enable(struct intel_encoder *encoder) |
{ |
struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); |
struct drm_device *dev = encoder->base.dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
int port = vlv_dport_to_channel(dport); |
struct intel_crtc *intel_crtc = |
to_intel_crtc(encoder->base.crtc); |
enum dpio_channel port = vlv_dport_to_channel(dport); |
int pipe = intel_crtc->pipe; |
|
if (!IS_VALLEYVIEW(dev)) |
return; |
1128,10 → 1135,10 |
|
/* Program Tx lane resets to default */ |
mutex_lock(&dev_priv->dpio_lock); |
vlv_dpio_write(dev_priv, DPIO_PCS_TX(port), |
vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW0(port), |
DPIO_PCS_TX_LANE2_RESET | |
DPIO_PCS_TX_LANE1_RESET); |
vlv_dpio_write(dev_priv, DPIO_PCS_CLK(port), |
vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW1(port), |
DPIO_PCS_CLK_CRI_RXEB_EIOS_EN | |
DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN | |
(1<<DPIO_PCS_CLK_DATAWIDTH_SHIFT) | |
1138,33 → 1145,33 |
DPIO_PCS_CLK_SOFT_RESET); |
|
/* Fix up inter-pair skew failure */ |
vlv_dpio_write(dev_priv, DPIO_PCS_STAGGER1(port), 0x00750f00); |
vlv_dpio_write(dev_priv, DPIO_TX_CTL(port), 0x00001500); |
vlv_dpio_write(dev_priv, DPIO_TX_LANE(port), 0x40400000); |
vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW12(port), 0x00750f00); |
vlv_dpio_write(dev_priv, pipe, VLV_TX_DW11(port), 0x00001500); |
vlv_dpio_write(dev_priv, pipe, VLV_TX_DW14(port), 0x40400000); |
|
vlv_dpio_write(dev_priv, DPIO_PCS_CTL_OVER1(port), |
0x00002000); |
vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), |
DPIO_TX_OCALINIT_EN); |
vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW9(port), 0x00002000); |
vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), DPIO_TX_OCALINIT_EN); |
mutex_unlock(&dev_priv->dpio_lock); |
} |
|
static void intel_hdmi_post_disable(struct intel_encoder *encoder) |
static void vlv_hdmi_post_disable(struct intel_encoder *encoder) |
{ |
struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); |
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
int port = vlv_dport_to_channel(dport); |
struct intel_crtc *intel_crtc = |
to_intel_crtc(encoder->base.crtc); |
enum dpio_channel port = vlv_dport_to_channel(dport); |
int pipe = intel_crtc->pipe; |
|
/* Reset lanes to avoid HDMI flicker (VLV w/a) */ |
mutex_lock(&dev_priv->dpio_lock); |
vlv_dpio_write(dev_priv, DPIO_PCS_TX(port), 0x00000000); |
vlv_dpio_write(dev_priv, DPIO_PCS_CLK(port), 0x00e00060); |
vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW0(port), 0x00000000); |
vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW1(port), 0x00e00060); |
mutex_unlock(&dev_priv->dpio_lock); |
} |
|
static void intel_hdmi_destroy(struct drm_connector *connector) |
{ |
drm_sysfs_connector_remove(connector); |
drm_connector_cleanup(connector); |
kfree(connector); |
} |
1211,6 → 1218,7 |
|
connector->interlace_allowed = 1; |
connector->doublescan_allowed = 0; |
connector->stereo_allowed = 1; |
|
switch (port) { |
case PORT_B: |
1275,11 → 1283,11 |
struct intel_encoder *intel_encoder; |
struct intel_connector *intel_connector; |
|
intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL); |
intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL); |
if (!intel_dig_port) |
return; |
|
intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL); |
if (!intel_connector) { |
kfree(intel_dig_port); |
return; |
1296,10 → 1304,10 |
intel_encoder->get_hw_state = intel_hdmi_get_hw_state; |
intel_encoder->get_config = intel_hdmi_get_config; |
if (IS_VALLEYVIEW(dev)) { |
intel_encoder->pre_pll_enable = intel_hdmi_pre_pll_enable; |
intel_encoder->pre_enable = intel_hdmi_pre_enable; |
intel_encoder->pre_pll_enable = vlv_hdmi_pre_pll_enable; |
intel_encoder->pre_enable = vlv_hdmi_pre_enable; |
intel_encoder->enable = vlv_enable_hdmi; |
intel_encoder->post_disable = intel_hdmi_post_disable; |
intel_encoder->post_disable = vlv_hdmi_post_disable; |
} else { |
intel_encoder->enable = intel_enable_hdmi; |
} |