148,15 → 148,6 |
return max_link_bw; |
} |
|
static int |
intel_dp_link_clock(uint8_t link_bw) |
{ |
if (link_bw == DP_LINK_BW_2_7) |
return 270000; |
else |
return 162000; |
} |
|
/* |
* The units on the numbers in the next two are... bizarre. Examples will |
* make it clearer; this one parallels an example in the eDP spec. |
191,7 → 182,8 |
struct drm_display_mode *mode, |
bool adjust_mode) |
{ |
int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); |
int max_link_clock = |
drm_dp_bw_code_to_link_rate(intel_dp_max_link_bw(intel_dp)); |
int max_lanes = drm_dp_max_lane_count(intel_dp->dpcd); |
int max_rate, mode_rate; |
|
330,6 → 322,49 |
} |
} |
|
static uint32_t |
intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq) |
{ |
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
struct drm_device *dev = intel_dig_port->base.base.dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
uint32_t ch_ctl = intel_dp->output_reg + 0x10; |
uint32_t status; |
bool done; |
|
if (IS_HASWELL(dev)) { |
switch (intel_dig_port->port) { |
case PORT_A: |
ch_ctl = DPA_AUX_CH_CTL; |
break; |
case PORT_B: |
ch_ctl = PCH_DPB_AUX_CH_CTL; |
break; |
case PORT_C: |
ch_ctl = PCH_DPC_AUX_CH_CTL; |
break; |
case PORT_D: |
ch_ctl = PCH_DPD_AUX_CH_CTL; |
break; |
default: |
BUG(); |
} |
} |
|
#define C (((status = I915_READ_NOTRACE(ch_ctl)) & DP_AUX_CH_CTL_SEND_BUSY) == 0) |
if (has_aux_irq) |
done = wait_event_timeout(dev_priv->gmbus_wait_queue, C, |
msecs_to_jiffies(10)); |
else |
done = wait_for_atomic(C, 10) == 0; |
if (!done) |
DRM_ERROR("dp aux hw did not signal timeout (has irq: %i)!\n", |
has_aux_irq); |
#undef C |
|
return status; |
} |
|
static int |
intel_dp_aux_ch(struct intel_dp *intel_dp, |
uint8_t *send, int send_bytes, |
341,12 → 376,18 |
struct drm_i915_private *dev_priv = dev->dev_private; |
uint32_t ch_ctl = output_reg + 0x10; |
uint32_t ch_data = ch_ctl + 4; |
int i; |
int recv_bytes; |
int i, ret, recv_bytes; |
uint32_t status; |
uint32_t aux_clock_divider; |
int try, precharge; |
bool has_aux_irq = INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev); |
|
/* dp aux is extremely sensitive to irq latency, hence request the |
* lowest possible wakeup latency and so prevent the cpu from going into |
* deep sleep states. |
*/ |
// pm_qos_update_request(&dev_priv->pm_qos, 0); |
|
if (IS_HASWELL(dev)) { |
switch (intel_dig_port->port) { |
case PORT_A: |
379,7 → 420,7 |
* clock divider. |
*/ |
if (is_cpu_edp(intel_dp)) { |
if (IS_HASWELL(dev)) |
if (HAS_DDI(dev)) |
aux_clock_divider = intel_ddi_get_cdclk_freq(dev_priv) >> 1; |
else if (IS_VALLEYVIEW(dev)) |
aux_clock_divider = 100; |
399,7 → 440,7 |
|
/* Try to wait for any previous AUX channel activity */ |
for (try = 0; try < 3; try++) { |
status = I915_READ(ch_ctl); |
status = I915_READ_NOTRACE(ch_ctl); |
if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0) |
break; |
msleep(1); |
408,7 → 449,8 |
if (try == 3) { |
WARN(1, "dp_aux_ch not started status 0x%08x\n", |
I915_READ(ch_ctl)); |
return -EBUSY; |
ret = -EBUSY; |
goto out; |
} |
|
/* Must try at least 3 times according to DP spec */ |
421,6 → 463,7 |
/* Send the command and wait for it to complete */ |
I915_WRITE(ch_ctl, |
DP_AUX_CH_CTL_SEND_BUSY | |
(has_aux_irq ? DP_AUX_CH_CTL_INTERRUPT : 0) | |
DP_AUX_CH_CTL_TIME_OUT_400us | |
(send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | |
(precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | |
428,13 → 471,9 |
DP_AUX_CH_CTL_DONE | |
DP_AUX_CH_CTL_TIME_OUT_ERROR | |
DP_AUX_CH_CTL_RECEIVE_ERROR); |
for (;;) { |
status = I915_READ(ch_ctl); |
if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0) |
break; |
udelay(100); |
} |
|
status = intel_dp_aux_wait_done(intel_dp, has_aux_irq); |
|
/* Clear done status and any errors */ |
I915_WRITE(ch_ctl, |
status | |
451,7 → 490,8 |
|
if ((status & DP_AUX_CH_CTL_DONE) == 0) { |
DRM_ERROR("dp_aux_ch not done status 0x%08x\n", status); |
return -EBUSY; |
ret = -EBUSY; |
goto out; |
} |
|
/* Check for timeout or receive error. |
459,7 → 499,8 |
*/ |
if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) { |
DRM_ERROR("dp_aux_ch receive error status 0x%08x\n", status); |
return -EIO; |
ret = -EIO; |
goto out; |
} |
|
/* Timeouts occur when the device isn't connected, so they're |
466,7 → 507,8 |
* "normal" -- don't fill the kernel log with these */ |
if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) { |
DRM_DEBUG_KMS("dp_aux_ch timeout status 0x%08x\n", status); |
return -ETIMEDOUT; |
ret = -ETIMEDOUT; |
goto out; |
} |
|
/* Unload any bytes sent back from the other side */ |
479,7 → 521,11 |
unpack_aux(I915_READ(ch_data + i), |
recv + i, recv_bytes - i); |
|
return recv_bytes; |
ret = recv_bytes; |
out: |
// pm_qos_update_request(&dev_priv->pm_qos, PM_QOS_DEFAULT_VALUE); |
|
return ret; |
} |
|
/* Write data to the aux channel in native mode */ |
718,16 → 764,35 |
return false; |
|
bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; |
|
if (intel_dp->color_range_auto) { |
/* |
* See: |
* CEA-861-E - 5.1 Default Encoding Parameters |
* VESA DisplayPort Ver.1.2a - 5.1.1.1 Video Colorimetry |
*/ |
if (bpp != 18 && drm_match_cea_mode(adjusted_mode) > 1) |
intel_dp->color_range = DP_COLOR_RANGE_16_235; |
else |
intel_dp->color_range = 0; |
} |
|
if (intel_dp->color_range) |
adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE; |
|
mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp); |
|
for (clock = 0; clock <= max_clock; clock++) { |
for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { |
int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); |
int link_bw_clock = |
drm_dp_bw_code_to_link_rate(bws[clock]); |
int link_avail = intel_dp_max_data_rate(link_bw_clock, |
lane_count); |
|
if (mode_rate <= link_avail) { |
intel_dp->link_bw = bws[clock]; |
intel_dp->lane_count = lane_count; |
adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw); |
adjusted_mode->clock = link_bw_clock; |
DRM_DEBUG_KMS("DP link bw %02x lane " |
"count %d clock %d bpp %d\n", |
intel_dp->link_bw, intel_dp->lane_count, |
742,39 → 807,6 |
return false; |
} |
|
struct intel_dp_m_n { |
uint32_t tu; |
uint32_t gmch_m; |
uint32_t gmch_n; |
uint32_t link_m; |
uint32_t link_n; |
}; |
|
static void |
intel_reduce_ratio(uint32_t *num, uint32_t *den) |
{ |
while (*num > 0xffffff || *den > 0xffffff) { |
*num >>= 1; |
*den >>= 1; |
} |
} |
|
static void |
intel_dp_compute_m_n(int bpp, |
int nlanes, |
int pixel_clock, |
int link_clock, |
struct intel_dp_m_n *m_n) |
{ |
m_n->tu = 64; |
m_n->gmch_m = (pixel_clock * bpp) >> 3; |
m_n->gmch_n = link_clock * nlanes; |
intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); |
m_n->link_m = pixel_clock; |
m_n->link_n = link_clock; |
intel_reduce_ratio(&m_n->link_m, &m_n->link_n); |
} |
|
void |
intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode) |
785,9 → 817,10 |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
int lane_count = 4; |
struct intel_dp_m_n m_n; |
struct intel_link_m_n m_n; |
int pipe = intel_crtc->pipe; |
enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder; |
int target_clock; |
|
/* |
* Find the lane count in the intel_encoder private |
803,13 → 836,22 |
} |
} |
|
target_clock = mode->clock; |
for_each_encoder_on_crtc(dev, crtc, intel_encoder) { |
if (intel_encoder->type == INTEL_OUTPUT_EDP) { |
target_clock = intel_edp_target_clock(intel_encoder, |
mode); |
break; |
} |
} |
|
/* |
* Compute the GMCH and Link ratios. The '3' here is |
* the number of bytes_per_pixel post-LUT, which we always |
* set up for 8-bits of R/G/B, or 3 bytes total. |
*/ |
intel_dp_compute_m_n(intel_crtc->bpp, lane_count, |
mode->clock, adjusted_mode->clock, &m_n); |
intel_link_compute_m_n(intel_crtc->bpp, lane_count, |
target_clock, adjusted_mode->clock, &m_n); |
|
if (IS_HASWELL(dev)) { |
I915_WRITE(PIPE_DATA_M1(cpu_transcoder), |
851,6 → 893,32 |
} |
} |
|
static void ironlake_set_pll_edp(struct drm_crtc *crtc, int clock) |
{ |
struct drm_device *dev = crtc->dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
u32 dpa_ctl; |
|
DRM_DEBUG_KMS("eDP PLL enable for clock %d\n", clock); |
dpa_ctl = I915_READ(DP_A); |
dpa_ctl &= ~DP_PLL_FREQ_MASK; |
|
if (clock < 200000) { |
/* For a long time we've carried around a ILK-DevA w/a for the |
* 160MHz clock. If we're really unlucky, it's still required. |
*/ |
DRM_DEBUG_KMS("160MHz cpu eDP clock, might need ilk devA w/a\n"); |
dpa_ctl |= DP_PLL_FREQ_160MHZ; |
} else { |
dpa_ctl |= DP_PLL_FREQ_270MHZ; |
} |
|
I915_WRITE(DP_A, dpa_ctl); |
|
POSTING_READ(DP_A); |
udelay(500); |
} |
|
static void |
intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode) |
926,6 → 994,7 |
else |
intel_dp->DP |= DP_PLL_FREQ_270MHZ; |
} else if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) { |
if (!HAS_PCH_SPLIT(dev)) |
intel_dp->DP |= intel_dp->color_range; |
|
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
950,6 → 1019,9 |
} else { |
intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; |
} |
|
if (is_cpu_edp(intel_dp)) |
ironlake_set_pll_edp(crtc, adjusted_mode->clock); |
} |
|
#define IDLE_ON_MASK (PP_ON | 0 | PP_SEQUENCE_MASK | 0 | PP_SEQUENCE_STATE_MASK) |
1057,6 → 1129,8 |
struct drm_i915_private *dev_priv = dev->dev_private; |
u32 pp; |
|
WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); |
|
if (!intel_dp->want_panel_vdd && ironlake_edp_have_panel_vdd(intel_dp)) { |
pp = ironlake_get_pp_control(dev_priv); |
pp &= ~EDP_FORCE_VDD; |
1543,7 → 1617,7 |
} |
|
static uint32_t |
intel_dp_signal_levels(uint8_t train_set) |
intel_gen4_signal_levels(uint8_t train_set) |
{ |
uint32_t signal_levels = 0; |
|
1641,7 → 1715,7 |
|
/* Gen7.5's (HSW) DP voltage swing and pre-emphasis control */ |
static uint32_t |
intel_dp_signal_levels_hsw(uint8_t train_set) |
intel_hsw_signal_levels(uint8_t train_set) |
{ |
int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | |
DP_TRAIN_PRE_EMPHASIS_MASK); |
1673,6 → 1747,34 |
} |
} |
|
/* Properly updates "DP" with the correct signal levels. */ |
static void |
intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP) |
{ |
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
struct drm_device *dev = intel_dig_port->base.base.dev; |
uint32_t signal_levels, mask; |
uint8_t train_set = intel_dp->train_set[0]; |
|
if (IS_HASWELL(dev)) { |
signal_levels = intel_hsw_signal_levels(train_set); |
mask = DDI_BUF_EMP_MASK; |
} else if (IS_GEN7(dev) && is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) { |
signal_levels = intel_gen7_edp_signal_levels(train_set); |
mask = EDP_LINK_TRAIN_VOL_EMP_MASK_IVB; |
} else if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) { |
signal_levels = intel_gen6_edp_signal_levels(train_set); |
mask = EDP_LINK_TRAIN_VOL_EMP_MASK_SNB; |
} else { |
signal_levels = intel_gen4_signal_levels(train_set); |
mask = DP_VOLTAGE_MASK | DP_PRE_EMPHASIS_MASK; |
} |
|
DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels); |
|
*DP = (*DP & ~mask) | signal_levels; |
} |
|
static bool |
intel_dp_set_link_train(struct intel_dp *intel_dp, |
uint32_t dp_reg_value, |
1696,6 → 1798,8 |
temp &= ~DP_TP_CTL_LINK_TRAIN_MASK; |
switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) { |
case DP_TRAINING_PATTERN_DISABLE: |
|
if (port != PORT_A) { |
temp |= DP_TP_CTL_LINK_TRAIN_IDLE; |
I915_WRITE(DP_TP_CTL(port), temp); |
|
1704,6 → 1808,8 |
DRM_ERROR("Timed out waiting for DP idle patterns\n"); |
|
temp &= ~DP_TP_CTL_LINK_TRAIN_MASK; |
} |
|
temp |= DP_TP_CTL_LINK_TRAIN_NORMAL; |
|
break; |
1791,7 → 1897,7 |
int voltage_tries, loop_tries; |
uint32_t DP = intel_dp->DP; |
|
if (IS_HASWELL(dev)) |
if (HAS_DDI(dev)) |
intel_ddi_prepare_link_retrain(encoder); |
|
/* Write the link configuration data */ |
1809,24 → 1915,8 |
for (;;) { |
/* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ |
uint8_t link_status[DP_LINK_STATUS_SIZE]; |
uint32_t signal_levels; |
|
if (IS_HASWELL(dev)) { |
signal_levels = intel_dp_signal_levels_hsw( |
intel_dp->train_set[0]); |
DP = (DP & ~DDI_BUF_EMP_MASK) | signal_levels; |
} else if (IS_GEN7(dev) && is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) { |
signal_levels = intel_gen7_edp_signal_levels(intel_dp->train_set[0]); |
DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_IVB) | signal_levels; |
} else if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) { |
signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); |
DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
} else { |
signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]); |
DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
} |
DRM_DEBUG_KMS("training pattern 1 signal levels %08x\n", |
signal_levels); |
intel_dp_set_signal_levels(intel_dp, &DP); |
|
/* Set training pattern 1 */ |
if (!intel_dp_set_link_train(intel_dp, DP, |
1850,7 → 1940,7 |
for (i = 0; i < intel_dp->lane_count; i++) |
if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) |
break; |
if (i == intel_dp->lane_count && voltage_tries == 5) { |
if (i == intel_dp->lane_count) { |
++loop_tries; |
if (loop_tries == 5) { |
DRM_DEBUG_KMS("too many full retries, give up\n"); |
1882,7 → 1972,6 |
void |
intel_dp_complete_link_train(struct intel_dp *intel_dp) |
{ |
struct drm_device *dev = intel_dp_to_dev(intel_dp); |
bool channel_eq = false; |
int tries, cr_tries; |
uint32_t DP = intel_dp->DP; |
1892,8 → 1981,6 |
cr_tries = 0; |
channel_eq = false; |
for (;;) { |
/* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ |
uint32_t signal_levels; |
uint8_t link_status[DP_LINK_STATUS_SIZE]; |
|
if (cr_tries > 5) { |
1902,19 → 1989,7 |
break; |
} |
|
if (IS_HASWELL(dev)) { |
signal_levels = intel_dp_signal_levels_hsw(intel_dp->train_set[0]); |
DP = (DP & ~DDI_BUF_EMP_MASK) | signal_levels; |
} else if (IS_GEN7(dev) && is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) { |
signal_levels = intel_gen7_edp_signal_levels(intel_dp->train_set[0]); |
DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_IVB) | signal_levels; |
} else if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) { |
signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); |
DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
} else { |
signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]); |
DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
} |
intel_dp_set_signal_levels(intel_dp, &DP); |
|
/* channel eq pattern */ |
if (!intel_dp_set_link_train(intel_dp, DP, |
1964,6 → 2039,8 |
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
struct drm_device *dev = intel_dig_port->base.base.dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_crtc *intel_crtc = |
to_intel_crtc(intel_dig_port->base.base.crtc); |
uint32_t DP = intel_dp->DP; |
|
/* |
1981,7 → 2058,7 |
* intel_ddi_prepare_link_retrain will take care of redoing the link |
* train. |
*/ |
if (IS_HASWELL(dev)) |
if (HAS_DDI(dev)) |
return; |
|
if (WARN_ON((I915_READ(intel_dp->output_reg) & DP_PORT_EN) == 0)) |
1998,7 → 2075,8 |
} |
POSTING_READ(intel_dp->output_reg); |
|
msleep(17); |
/* We don't really know why we're doing this */ |
intel_wait_for_vblank(dev, intel_crtc->pipe); |
|
if (HAS_PCH_IBX(dev) && |
I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { |
2018,19 → 2096,14 |
/* Changes to enable or select take place the vblank |
* after being written. |
*/ |
if (crtc == NULL) { |
/* We can arrive here never having been attached |
* to a CRTC, for instance, due to inheriting |
* random state from the BIOS. |
* |
* If the pipe is not running, play safe and |
* wait for the clocks to stabilise before |
* continuing. |
*/ |
if (WARN_ON(crtc == NULL)) { |
/* We should never try to disable a port without a crtc |
* attached. For paranoia keep the code around for a |
* bit. */ |
POSTING_READ(intel_dp->output_reg); |
msleep(50); |
} else |
intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe); |
intel_wait_for_vblank(dev, intel_crtc->pipe); |
} |
|
DP &= ~DP_AUDIO_OUTPUT_ENABLE; |
2042,10 → 2115,16 |
static bool |
intel_dp_get_dpcd(struct intel_dp *intel_dp) |
{ |
char dpcd_hex_dump[sizeof(intel_dp->dpcd) * 3]; |
|
if (intel_dp_aux_native_read_retry(intel_dp, 0x000, intel_dp->dpcd, |
sizeof(intel_dp->dpcd)) == 0) |
return false; /* aux transfer failed */ |
|
hex_dump_to_buffer(intel_dp->dpcd, sizeof(intel_dp->dpcd), |
32, 1, dpcd_hex_dump, sizeof(dpcd_hex_dump), false); |
DRM_DEBUG_KMS("DPCD: %s\n", dpcd_hex_dump); |
|
if (intel_dp->dpcd[DP_DPCD_REV] == 0) |
return false; /* DPCD not present */ |
|
2206,6 → 2285,8 |
ironlake_dp_detect(struct intel_dp *intel_dp) |
{ |
struct drm_device *dev = intel_dp_to_dev(intel_dp); |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
enum drm_connector_status status; |
|
/* Can't disconnect eDP, but you can close the lid... */ |
2216,6 → 2297,9 |
return status; |
} |
|
if (!ibx_digital_port_connected(dev_priv, intel_dig_port)) |
return connector_status_disconnected; |
|
return intel_dp_detect_dpcd(intel_dp); |
} |
|
2224,17 → 2308,18 |
{ |
struct drm_device *dev = intel_dp_to_dev(intel_dp); |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
uint32_t bit; |
|
switch (intel_dp->output_reg) { |
case DP_B: |
bit = DPB_HOTPLUG_LIVE_STATUS; |
switch (intel_dig_port->port) { |
case PORT_B: |
bit = PORTB_HOTPLUG_LIVE_STATUS; |
break; |
case DP_C: |
bit = DPC_HOTPLUG_LIVE_STATUS; |
case PORT_C: |
bit = PORTC_HOTPLUG_LIVE_STATUS; |
break; |
case DP_D: |
bit = DPD_HOTPLUG_LIVE_STATUS; |
case PORT_D: |
bit = PORTD_HOTPLUG_LIVE_STATUS; |
break; |
default: |
return connector_status_unknown; |
2290,13 → 2375,6 |
return intel_ddc_get_modes(connector, adapter); |
} |
|
|
/** |
* Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection. |
* |
* \return true if DP port is connected. |
* \return false if DP port is disconnected. |
*/ |
static enum drm_connector_status |
intel_dp_detect(struct drm_connector *connector, bool force) |
{ |
2306,7 → 2384,6 |
struct drm_device *dev = connector->dev; |
enum drm_connector_status status; |
struct edid *edid = NULL; |
char dpcd_hex_dump[sizeof(intel_dp->dpcd) * 3]; |
|
intel_dp->has_audio = false; |
|
2315,10 → 2392,6 |
else |
status = g4x_dp_detect(intel_dp); |
|
// hex_dump_to_buffer(intel_dp->dpcd, sizeof(intel_dp->dpcd), |
// 32, 1, dpcd_hex_dump, sizeof(dpcd_hex_dump), false); |
// DRM_DEBUG_KMS("DPCD: %s\n", dpcd_hex_dump); |
|
if (status != connector_status_connected) |
return status; |
|
2396,7 → 2469,7 |
ret = drm_object_property_set_value(&connector->base, property, val); |
if (ret) |
return ret; |
#if 0 |
|
if (property == dev_priv->force_audio_property) { |
int i = val; |
bool has_audio; |
2419,13 → 2492,23 |
} |
|
if (property == dev_priv->broadcast_rgb_property) { |
if (val == !!intel_dp->color_range) |
return 0; |
|
intel_dp->color_range = val ? DP_COLOR_RANGE_16_235 : 0; |
switch (val) { |
case INTEL_BROADCAST_RGB_AUTO: |
intel_dp->color_range_auto = true; |
break; |
case INTEL_BROADCAST_RGB_FULL: |
intel_dp->color_range_auto = false; |
intel_dp->color_range = 0; |
break; |
case INTEL_BROADCAST_RGB_LIMITED: |
intel_dp->color_range_auto = false; |
intel_dp->color_range = DP_COLOR_RANGE_16_235; |
break; |
default: |
return -EINVAL; |
} |
goto done; |
} |
#endif |
|
if (is_edp(intel_dp) && |
property == connector->dev->mode_config.scaling_mode_property) { |
2446,11 → 2529,8 |
return -EINVAL; |
|
done: |
if (intel_encoder->base.crtc) { |
struct drm_crtc *crtc = intel_encoder->base.crtc; |
intel_set_mode(crtc, &crtc->mode, |
crtc->x, crtc->y, crtc->fb); |
} |
if (intel_encoder->base.crtc) |
intel_crtc_restore_mode(intel_encoder->base.crtc); |
|
return 0; |
} |
2479,12 → 2559,15 |
{ |
struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); |
struct intel_dp *intel_dp = &intel_dig_port->dp; |
struct drm_device *dev = intel_dp_to_dev(intel_dp); |
|
i2c_del_adapter(&intel_dp->adapter); |
drm_encoder_cleanup(encoder); |
if (is_edp(intel_dp)) { |
// cancel_delayed_work_sync(&intel_dp->panel_vdd_work); |
mutex_lock(&dev->mode_config.mutex); |
ironlake_panel_vdd_off_sync(intel_dp); |
mutex_unlock(&dev->mode_config.mutex); |
} |
kfree(intel_dig_port); |
} |
2492,7 → 2575,6 |
static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { |
.mode_fixup = intel_dp_mode_fixup, |
.mode_set = intel_dp_mode_set, |
.disable = intel_encoder_noop, |
}; |
|
static const struct drm_connector_funcs intel_dp_connector_funcs = { |
2567,6 → 2649,7 |
|
intel_attach_force_audio_property(connector); |
intel_attach_broadcast_rgb_property(connector); |
intel_dp->color_range_auto = true; |
|
if (is_edp(intel_dp)) { |
drm_mode_create_scaling_mode_property(connector->dev); |
2756,7 → 2839,7 |
intel_connector_attach_encoder(intel_connector, intel_encoder); |
drm_sysfs_connector_add(connector); |
|
if (IS_HASWELL(dev)) |
if (HAS_DDI(dev)) |
intel_connector->get_hw_state = intel_ddi_connector_get_hw_state; |
else |
intel_connector->get_hw_state = intel_connector_get_hw_state; |
2768,15 → 2851,15 |
name = "DPDDC-A"; |
break; |
case PORT_B: |
dev_priv->hotplug_supported_mask |= DPB_HOTPLUG_INT_STATUS; |
dev_priv->hotplug_supported_mask |= PORTB_HOTPLUG_INT_STATUS; |
name = "DPDDC-B"; |
break; |
case PORT_C: |
dev_priv->hotplug_supported_mask |= DPC_HOTPLUG_INT_STATUS; |
dev_priv->hotplug_supported_mask |= PORTC_HOTPLUG_INT_STATUS; |
name = "DPDDC-C"; |
break; |
case PORT_D: |
dev_priv->hotplug_supported_mask |= DPD_HOTPLUG_INT_STATUS; |
dev_priv->hotplug_supported_mask |= PORTD_HOTPLUG_INT_STATUS; |
name = "DPDDC-D"; |
break; |
default: |