Loading drivers/gpu/drm/i915/i915_irq.c +2 −2 Original line number Diff line number Diff line Loading @@ -313,10 +313,10 @@ static void i915_hotplug_work_func(struct work_struct *work) if (encoder->hot_plug) encoder->hot_plug(encoder); mutex_unlock(&mode_config->mutex); /* Just fire off a uevent and let userspace tell us what to do */ drm_helper_hpd_irq_event(dev); mutex_unlock(&mode_config->mutex); } static void i915_handle_rps_change(struct drm_device *dev) Loading drivers/gpu/drm/i915/i915_reg.h +5 −3 Original line number Diff line number Diff line Loading @@ -2084,9 +2084,6 @@ #define DP_PIPEB_SELECT (1 << 30) #define DP_PIPE_MASK (1 << 30) #define DP_PIPE_ENABLED(V, P) \ (((V) & (DP_PIPE_MASK | DP_PORT_EN)) == ((P) << 30 | DP_PORT_EN)) /* Link training mode - select a suitable mode for each stage */ #define DP_LINK_TRAIN_PAT_1 (0 << 28) #define DP_LINK_TRAIN_PAT_2 (1 << 28) Loading Loading @@ -3076,6 +3073,11 @@ #define TRANS_6BPC (2<<5) #define TRANS_12BPC (3<<5) #define _TRANSA_CHICKEN2 0xf0064 #define _TRANSB_CHICKEN2 0xf1064 #define TRANS_CHICKEN2(pipe) _PIPE(pipe, _TRANSA_CHICKEN2, _TRANSB_CHICKEN2) #define TRANS_AUTOTRAIN_GEN_STALL_DIS (1<<31) #define SOUTH_CHICKEN2 0xc2004 #define DPLS_EDP_PPS_FIX_DIS (1<<0) Loading drivers/gpu/drm/i915/intel_display.c +58 −24 Original line number Diff line number Diff line Loading @@ -980,11 +980,29 @@ static void assert_transcoder_disabled(struct drm_i915_private *dev_priv, pipe_name(pipe)); } static bool dp_pipe_enabled(struct drm_i915_private *dev_priv, enum pipe pipe, int reg, u32 port_sel, u32 val) { if ((val & DP_PORT_EN) == 0) return false; if (HAS_PCH_CPT(dev_priv->dev)) { u32 trans_dp_ctl_reg = TRANS_DP_CTL(pipe); u32 trans_dp_ctl = I915_READ(trans_dp_ctl_reg); if ((trans_dp_ctl & TRANS_DP_PORT_SEL_MASK) != port_sel) return false; } else { if ((val & DP_PIPE_MASK) != (pipe << 30)) return false; } return true; } static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, enum pipe pipe, int reg) enum pipe pipe, int reg, u32 port_sel) { u32 val = I915_READ(reg); WARN(DP_PIPE_ENABLED(val, pipe), WARN(dp_pipe_enabled(dev_priv, pipe, reg, port_sel, val), "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", reg, pipe_name(pipe)); } Loading @@ -1004,9 +1022,9 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, int reg; u32 val; assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_B); assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C); assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D); assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_B, TRANS_DP_PORT_SEL_B); assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C); assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D); reg = PCH_ADPA; val = I915_READ(reg); Loading Loading @@ -1276,6 +1294,17 @@ static void intel_disable_pipe(struct drm_i915_private *dev_priv, intel_wait_for_pipe_off(dev_priv->dev, pipe); } /* * Plane regs are double buffered, going from enabled->disabled needs a * trigger in order to latch. The display address reg provides this. */ static void intel_flush_display_plane(struct drm_i915_private *dev_priv, enum plane plane) { I915_WRITE(DSPADDR(plane), I915_READ(DSPADDR(plane))); I915_WRITE(DSPSURF(plane), I915_READ(DSPSURF(plane))); } /** * intel_enable_plane - enable a display plane on a given pipe * @dev_priv: i915 private structure Loading @@ -1299,20 +1328,10 @@ static void intel_enable_plane(struct drm_i915_private *dev_priv, return; I915_WRITE(reg, val | DISPLAY_PLANE_ENABLE); intel_flush_display_plane(dev_priv, plane); intel_wait_for_vblank(dev_priv->dev, pipe); } /* * Plane regs are double buffered, going from enabled->disabled needs a * trigger in order to latch. The display address reg provides this. */ static void intel_flush_display_plane(struct drm_i915_private *dev_priv, enum plane plane) { u32 reg = DSPADDR(plane); I915_WRITE(reg, I915_READ(reg)); } /** * intel_disable_plane - disable a display plane * @dev_priv: i915 private structure Loading @@ -1338,20 +1357,25 @@ static void intel_disable_plane(struct drm_i915_private *dev_priv, } static void disable_pch_dp(struct drm_i915_private *dev_priv, enum pipe pipe, int reg) enum pipe pipe, int reg, u32 port_sel) { u32 val = I915_READ(reg); if (DP_PIPE_ENABLED(val, pipe)) if (dp_pipe_enabled(dev_priv, pipe, reg, port_sel, val)) { DRM_DEBUG_KMS("Disabling pch dp %x on pipe %d\n", reg, pipe); I915_WRITE(reg, val & ~DP_PORT_EN); } } static void disable_pch_hdmi(struct drm_i915_private *dev_priv, enum pipe pipe, int reg) { u32 val = I915_READ(reg); if (HDMI_PIPE_ENABLED(val, pipe)) if (HDMI_PIPE_ENABLED(val, pipe)) { DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n", reg, pipe); I915_WRITE(reg, val & ~PORT_ENABLE); } } /* Disable any ports connected to this transcoder */ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv, Loading @@ -1362,9 +1386,9 @@ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv, val = I915_READ(PCH_PP_CONTROL); I915_WRITE(PCH_PP_CONTROL, val | PANEL_UNLOCK_REGS); disable_pch_dp(dev_priv, pipe, PCH_DP_B); disable_pch_dp(dev_priv, pipe, PCH_DP_C); disable_pch_dp(dev_priv, pipe, PCH_DP_D); disable_pch_dp(dev_priv, pipe, PCH_DP_B, TRANS_DP_PORT_SEL_B); disable_pch_dp(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C); disable_pch_dp(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D); reg = PCH_ADPA; val = I915_READ(reg); Loading Loading @@ -5523,6 +5547,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, drm_vblank_post_modeset(dev, pipe); intel_crtc->dpms_mode = DRM_MODE_DPMS_ON; return ret; } Loading Loading @@ -7721,10 +7747,12 @@ static void gen6_init_clock_gating(struct drm_device *dev) ILK_DPARB_CLK_GATE | ILK_DPFD_CLK_GATE); for_each_pipe(pipe) for_each_pipe(pipe) { I915_WRITE(DSPCNTR(pipe), I915_READ(DSPCNTR(pipe)) | DISPPLANE_TRICKLE_FEED_DISABLE); intel_flush_display_plane(dev_priv, pipe); } } static void ivybridge_init_clock_gating(struct drm_device *dev) Loading @@ -7741,10 +7769,12 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE); for_each_pipe(pipe) for_each_pipe(pipe) { I915_WRITE(DSPCNTR(pipe), I915_READ(DSPCNTR(pipe)) | DISPPLANE_TRICKLE_FEED_DISABLE); intel_flush_display_plane(dev_priv, pipe); } } static void g4x_init_clock_gating(struct drm_device *dev) Loading Loading @@ -7827,6 +7857,7 @@ static void ibx_init_clock_gating(struct drm_device *dev) static void cpt_init_clock_gating(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int pipe; /* * On Ibex Peak and Cougar Point, we need to disable clock Loading @@ -7836,6 +7867,9 @@ static void cpt_init_clock_gating(struct drm_device *dev) I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); I915_WRITE(SOUTH_CHICKEN2, I915_READ(SOUTH_CHICKEN2) | DPLS_EDP_PPS_FIX_DIS); /* Without this, mode sets may fail silently on FDI */ for_each_pipe(pipe) I915_WRITE(TRANS_CHICKEN2(pipe), TRANS_AUTOTRAIN_GEN_STALL_DIS); } static void ironlake_teardown_rc6(struct drm_device *dev) Loading drivers/gpu/drm/i915/intel_dp.c +33 −22 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ struct intel_dp { bool has_audio; int force_audio; uint32_t color_range; int dpms_mode; uint8_t link_bw; uint8_t lane_count; uint8_t dpcd[8]; Loading Loading @@ -1012,6 +1013,8 @@ static void intel_dp_commit(struct drm_encoder *encoder) if (is_edp(intel_dp)) ironlake_edp_backlight_on(dev); intel_dp->dpms_mode = DRM_MODE_DPMS_ON; } static void Loading Loading @@ -1046,6 +1049,7 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) if (is_edp(intel_dp)) ironlake_edp_backlight_on(dev); } intel_dp->dpms_mode = mode; } /* Loading Loading @@ -1568,6 +1572,18 @@ intel_dp_link_down(struct intel_dp *intel_dp) POSTING_READ(intel_dp->output_reg); } static bool intel_dp_get_dpcd(struct intel_dp *intel_dp) { if (intel_dp_aux_native_read_retry(intel_dp, 0x000, intel_dp->dpcd, sizeof (intel_dp->dpcd)) && (intel_dp->dpcd[DP_DPCD_REV] != 0)) { return true; } return false; } /* * According to DP spec * 5.1.2: Loading @@ -1580,42 +1596,38 @@ intel_dp_link_down(struct intel_dp *intel_dp) static void intel_dp_check_link_status(struct intel_dp *intel_dp) { int ret; if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON) return; if (!intel_dp->base.base.crtc) return; /* Try to read receiver status if the link appears to be up */ if (!intel_dp_get_link_status(intel_dp)) { intel_dp_link_down(intel_dp); return; } /* Try to read receiver status if the link appears to be up */ ret = intel_dp_aux_native_read(intel_dp, 0x000, intel_dp->dpcd, sizeof (intel_dp->dpcd)); if (ret != sizeof(intel_dp->dpcd)) { /* Now read the DPCD to see if it's actually running */ if (!intel_dp_get_dpcd(intel_dp)) { intel_dp_link_down(intel_dp); return; } if (!intel_channel_eq_ok(intel_dp)) { DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", drm_get_encoder_name(&intel_dp->base.base)); intel_dp_start_link_train(intel_dp); intel_dp_complete_link_train(intel_dp); } } static enum drm_connector_status i915_dp_detect_common(struct intel_dp *intel_dp) intel_dp_detect_dpcd(struct intel_dp *intel_dp) { enum drm_connector_status status = connector_status_disconnected; if (intel_dp_aux_native_read_retry(intel_dp, 0x000, intel_dp->dpcd, sizeof (intel_dp->dpcd)) && (intel_dp->dpcd[DP_DPCD_REV] != 0)) status = connector_status_connected; return status; if (intel_dp_get_dpcd(intel_dp)) return connector_status_connected; return connector_status_disconnected; } static enum drm_connector_status Loading @@ -1631,7 +1643,7 @@ ironlake_dp_detect(struct intel_dp *intel_dp) return status; } return i915_dp_detect_common(intel_dp); return intel_dp_detect_dpcd(intel_dp); } static enum drm_connector_status Loading Loading @@ -1660,7 +1672,7 @@ g4x_dp_detect(struct intel_dp *intel_dp) if ((temp & bit) == 0) return connector_status_disconnected; return i915_dp_detect_common(intel_dp); return intel_dp_detect_dpcd(intel_dp); } /** Loading Loading @@ -1935,6 +1947,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) return; intel_dp->output_reg = output_reg; intel_dp->dpms_mode = -1; intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); if (!intel_connector) { Loading Loading @@ -2011,7 +2024,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) /* Cache some DPCD data in the eDP case */ if (is_edp(intel_dp)) { int ret; bool ret; u32 pp_on, pp_div; pp_on = I915_READ(PCH_PP_ON_DELAYS); Loading @@ -2024,11 +2037,9 @@ intel_dp_init(struct drm_device *dev, int output_reg) dev_priv->panel_t12 *= 100; /* t12 in 100ms units */ ironlake_edp_panel_vdd_on(intel_dp); ret = intel_dp_aux_native_read(intel_dp, DP_DPCD_REV, intel_dp->dpcd, sizeof(intel_dp->dpcd)); ret = intel_dp_get_dpcd(intel_dp); ironlake_edp_panel_vdd_off(intel_dp); if (ret == sizeof(intel_dp->dpcd)) { if (ret) { if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) dev_priv->no_aux_handshake = intel_dp->dpcd[DP_MAX_DOWNSPREAD] & Loading Loading
drivers/gpu/drm/i915/i915_irq.c +2 −2 Original line number Diff line number Diff line Loading @@ -313,10 +313,10 @@ static void i915_hotplug_work_func(struct work_struct *work) if (encoder->hot_plug) encoder->hot_plug(encoder); mutex_unlock(&mode_config->mutex); /* Just fire off a uevent and let userspace tell us what to do */ drm_helper_hpd_irq_event(dev); mutex_unlock(&mode_config->mutex); } static void i915_handle_rps_change(struct drm_device *dev) Loading
drivers/gpu/drm/i915/i915_reg.h +5 −3 Original line number Diff line number Diff line Loading @@ -2084,9 +2084,6 @@ #define DP_PIPEB_SELECT (1 << 30) #define DP_PIPE_MASK (1 << 30) #define DP_PIPE_ENABLED(V, P) \ (((V) & (DP_PIPE_MASK | DP_PORT_EN)) == ((P) << 30 | DP_PORT_EN)) /* Link training mode - select a suitable mode for each stage */ #define DP_LINK_TRAIN_PAT_1 (0 << 28) #define DP_LINK_TRAIN_PAT_2 (1 << 28) Loading Loading @@ -3076,6 +3073,11 @@ #define TRANS_6BPC (2<<5) #define TRANS_12BPC (3<<5) #define _TRANSA_CHICKEN2 0xf0064 #define _TRANSB_CHICKEN2 0xf1064 #define TRANS_CHICKEN2(pipe) _PIPE(pipe, _TRANSA_CHICKEN2, _TRANSB_CHICKEN2) #define TRANS_AUTOTRAIN_GEN_STALL_DIS (1<<31) #define SOUTH_CHICKEN2 0xc2004 #define DPLS_EDP_PPS_FIX_DIS (1<<0) Loading
drivers/gpu/drm/i915/intel_display.c +58 −24 Original line number Diff line number Diff line Loading @@ -980,11 +980,29 @@ static void assert_transcoder_disabled(struct drm_i915_private *dev_priv, pipe_name(pipe)); } static bool dp_pipe_enabled(struct drm_i915_private *dev_priv, enum pipe pipe, int reg, u32 port_sel, u32 val) { if ((val & DP_PORT_EN) == 0) return false; if (HAS_PCH_CPT(dev_priv->dev)) { u32 trans_dp_ctl_reg = TRANS_DP_CTL(pipe); u32 trans_dp_ctl = I915_READ(trans_dp_ctl_reg); if ((trans_dp_ctl & TRANS_DP_PORT_SEL_MASK) != port_sel) return false; } else { if ((val & DP_PIPE_MASK) != (pipe << 30)) return false; } return true; } static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, enum pipe pipe, int reg) enum pipe pipe, int reg, u32 port_sel) { u32 val = I915_READ(reg); WARN(DP_PIPE_ENABLED(val, pipe), WARN(dp_pipe_enabled(dev_priv, pipe, reg, port_sel, val), "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", reg, pipe_name(pipe)); } Loading @@ -1004,9 +1022,9 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, int reg; u32 val; assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_B); assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C); assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D); assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_B, TRANS_DP_PORT_SEL_B); assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C); assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D); reg = PCH_ADPA; val = I915_READ(reg); Loading Loading @@ -1276,6 +1294,17 @@ static void intel_disable_pipe(struct drm_i915_private *dev_priv, intel_wait_for_pipe_off(dev_priv->dev, pipe); } /* * Plane regs are double buffered, going from enabled->disabled needs a * trigger in order to latch. The display address reg provides this. */ static void intel_flush_display_plane(struct drm_i915_private *dev_priv, enum plane plane) { I915_WRITE(DSPADDR(plane), I915_READ(DSPADDR(plane))); I915_WRITE(DSPSURF(plane), I915_READ(DSPSURF(plane))); } /** * intel_enable_plane - enable a display plane on a given pipe * @dev_priv: i915 private structure Loading @@ -1299,20 +1328,10 @@ static void intel_enable_plane(struct drm_i915_private *dev_priv, return; I915_WRITE(reg, val | DISPLAY_PLANE_ENABLE); intel_flush_display_plane(dev_priv, plane); intel_wait_for_vblank(dev_priv->dev, pipe); } /* * Plane regs are double buffered, going from enabled->disabled needs a * trigger in order to latch. The display address reg provides this. */ static void intel_flush_display_plane(struct drm_i915_private *dev_priv, enum plane plane) { u32 reg = DSPADDR(plane); I915_WRITE(reg, I915_READ(reg)); } /** * intel_disable_plane - disable a display plane * @dev_priv: i915 private structure Loading @@ -1338,20 +1357,25 @@ static void intel_disable_plane(struct drm_i915_private *dev_priv, } static void disable_pch_dp(struct drm_i915_private *dev_priv, enum pipe pipe, int reg) enum pipe pipe, int reg, u32 port_sel) { u32 val = I915_READ(reg); if (DP_PIPE_ENABLED(val, pipe)) if (dp_pipe_enabled(dev_priv, pipe, reg, port_sel, val)) { DRM_DEBUG_KMS("Disabling pch dp %x on pipe %d\n", reg, pipe); I915_WRITE(reg, val & ~DP_PORT_EN); } } static void disable_pch_hdmi(struct drm_i915_private *dev_priv, enum pipe pipe, int reg) { u32 val = I915_READ(reg); if (HDMI_PIPE_ENABLED(val, pipe)) if (HDMI_PIPE_ENABLED(val, pipe)) { DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n", reg, pipe); I915_WRITE(reg, val & ~PORT_ENABLE); } } /* Disable any ports connected to this transcoder */ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv, Loading @@ -1362,9 +1386,9 @@ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv, val = I915_READ(PCH_PP_CONTROL); I915_WRITE(PCH_PP_CONTROL, val | PANEL_UNLOCK_REGS); disable_pch_dp(dev_priv, pipe, PCH_DP_B); disable_pch_dp(dev_priv, pipe, PCH_DP_C); disable_pch_dp(dev_priv, pipe, PCH_DP_D); disable_pch_dp(dev_priv, pipe, PCH_DP_B, TRANS_DP_PORT_SEL_B); disable_pch_dp(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C); disable_pch_dp(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D); reg = PCH_ADPA; val = I915_READ(reg); Loading Loading @@ -5523,6 +5547,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, drm_vblank_post_modeset(dev, pipe); intel_crtc->dpms_mode = DRM_MODE_DPMS_ON; return ret; } Loading Loading @@ -7721,10 +7747,12 @@ static void gen6_init_clock_gating(struct drm_device *dev) ILK_DPARB_CLK_GATE | ILK_DPFD_CLK_GATE); for_each_pipe(pipe) for_each_pipe(pipe) { I915_WRITE(DSPCNTR(pipe), I915_READ(DSPCNTR(pipe)) | DISPPLANE_TRICKLE_FEED_DISABLE); intel_flush_display_plane(dev_priv, pipe); } } static void ivybridge_init_clock_gating(struct drm_device *dev) Loading @@ -7741,10 +7769,12 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE); for_each_pipe(pipe) for_each_pipe(pipe) { I915_WRITE(DSPCNTR(pipe), I915_READ(DSPCNTR(pipe)) | DISPPLANE_TRICKLE_FEED_DISABLE); intel_flush_display_plane(dev_priv, pipe); } } static void g4x_init_clock_gating(struct drm_device *dev) Loading Loading @@ -7827,6 +7857,7 @@ static void ibx_init_clock_gating(struct drm_device *dev) static void cpt_init_clock_gating(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int pipe; /* * On Ibex Peak and Cougar Point, we need to disable clock Loading @@ -7836,6 +7867,9 @@ static void cpt_init_clock_gating(struct drm_device *dev) I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); I915_WRITE(SOUTH_CHICKEN2, I915_READ(SOUTH_CHICKEN2) | DPLS_EDP_PPS_FIX_DIS); /* Without this, mode sets may fail silently on FDI */ for_each_pipe(pipe) I915_WRITE(TRANS_CHICKEN2(pipe), TRANS_AUTOTRAIN_GEN_STALL_DIS); } static void ironlake_teardown_rc6(struct drm_device *dev) Loading
drivers/gpu/drm/i915/intel_dp.c +33 −22 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ struct intel_dp { bool has_audio; int force_audio; uint32_t color_range; int dpms_mode; uint8_t link_bw; uint8_t lane_count; uint8_t dpcd[8]; Loading Loading @@ -1012,6 +1013,8 @@ static void intel_dp_commit(struct drm_encoder *encoder) if (is_edp(intel_dp)) ironlake_edp_backlight_on(dev); intel_dp->dpms_mode = DRM_MODE_DPMS_ON; } static void Loading Loading @@ -1046,6 +1049,7 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) if (is_edp(intel_dp)) ironlake_edp_backlight_on(dev); } intel_dp->dpms_mode = mode; } /* Loading Loading @@ -1568,6 +1572,18 @@ intel_dp_link_down(struct intel_dp *intel_dp) POSTING_READ(intel_dp->output_reg); } static bool intel_dp_get_dpcd(struct intel_dp *intel_dp) { if (intel_dp_aux_native_read_retry(intel_dp, 0x000, intel_dp->dpcd, sizeof (intel_dp->dpcd)) && (intel_dp->dpcd[DP_DPCD_REV] != 0)) { return true; } return false; } /* * According to DP spec * 5.1.2: Loading @@ -1580,42 +1596,38 @@ intel_dp_link_down(struct intel_dp *intel_dp) static void intel_dp_check_link_status(struct intel_dp *intel_dp) { int ret; if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON) return; if (!intel_dp->base.base.crtc) return; /* Try to read receiver status if the link appears to be up */ if (!intel_dp_get_link_status(intel_dp)) { intel_dp_link_down(intel_dp); return; } /* Try to read receiver status if the link appears to be up */ ret = intel_dp_aux_native_read(intel_dp, 0x000, intel_dp->dpcd, sizeof (intel_dp->dpcd)); if (ret != sizeof(intel_dp->dpcd)) { /* Now read the DPCD to see if it's actually running */ if (!intel_dp_get_dpcd(intel_dp)) { intel_dp_link_down(intel_dp); return; } if (!intel_channel_eq_ok(intel_dp)) { DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", drm_get_encoder_name(&intel_dp->base.base)); intel_dp_start_link_train(intel_dp); intel_dp_complete_link_train(intel_dp); } } static enum drm_connector_status i915_dp_detect_common(struct intel_dp *intel_dp) intel_dp_detect_dpcd(struct intel_dp *intel_dp) { enum drm_connector_status status = connector_status_disconnected; if (intel_dp_aux_native_read_retry(intel_dp, 0x000, intel_dp->dpcd, sizeof (intel_dp->dpcd)) && (intel_dp->dpcd[DP_DPCD_REV] != 0)) status = connector_status_connected; return status; if (intel_dp_get_dpcd(intel_dp)) return connector_status_connected; return connector_status_disconnected; } static enum drm_connector_status Loading @@ -1631,7 +1643,7 @@ ironlake_dp_detect(struct intel_dp *intel_dp) return status; } return i915_dp_detect_common(intel_dp); return intel_dp_detect_dpcd(intel_dp); } static enum drm_connector_status Loading Loading @@ -1660,7 +1672,7 @@ g4x_dp_detect(struct intel_dp *intel_dp) if ((temp & bit) == 0) return connector_status_disconnected; return i915_dp_detect_common(intel_dp); return intel_dp_detect_dpcd(intel_dp); } /** Loading Loading @@ -1935,6 +1947,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) return; intel_dp->output_reg = output_reg; intel_dp->dpms_mode = -1; intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); if (!intel_connector) { Loading Loading @@ -2011,7 +2024,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) /* Cache some DPCD data in the eDP case */ if (is_edp(intel_dp)) { int ret; bool ret; u32 pp_on, pp_div; pp_on = I915_READ(PCH_PP_ON_DELAYS); Loading @@ -2024,11 +2037,9 @@ intel_dp_init(struct drm_device *dev, int output_reg) dev_priv->panel_t12 *= 100; /* t12 in 100ms units */ ironlake_edp_panel_vdd_on(intel_dp); ret = intel_dp_aux_native_read(intel_dp, DP_DPCD_REV, intel_dp->dpcd, sizeof(intel_dp->dpcd)); ret = intel_dp_get_dpcd(intel_dp); ironlake_edp_panel_vdd_off(intel_dp); if (ret == sizeof(intel_dp->dpcd)) { if (ret) { if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) dev_priv->no_aux_handshake = intel_dp->dpcd[DP_MAX_DOWNSPREAD] & Loading