Loading drivers/gpu/drm/i915/i915_reg.h +25 −0 Original line number Original line Diff line number Diff line Loading @@ -1444,6 +1444,7 @@ #define DP_CLOCK_OUTPUT_ENABLE (1 << 13) #define DP_CLOCK_OUTPUT_ENABLE (1 << 13) #define DP_SCRAMBLING_DISABLE (1 << 12) #define DP_SCRAMBLING_DISABLE (1 << 12) #define DP_SCRAMBLING_DISABLE_IGDNG (1 << 7) /** limit RGB values to avoid confusing TVs */ /** limit RGB values to avoid confusing TVs */ #define DP_COLOR_RANGE_16_235 (1 << 8) #define DP_COLOR_RANGE_16_235 (1 << 8) Loading Loading @@ -2210,4 +2211,28 @@ #define PCH_PP_OFF_DELAYS 0xc720c #define PCH_PP_OFF_DELAYS 0xc720c #define PCH_PP_DIVISOR 0xc7210 #define PCH_PP_DIVISOR 0xc7210 #define PCH_DP_B 0xe4100 #define PCH_DPB_AUX_CH_CTL 0xe4110 #define PCH_DPB_AUX_CH_DATA1 0xe4114 #define PCH_DPB_AUX_CH_DATA2 0xe4118 #define PCH_DPB_AUX_CH_DATA3 0xe411c #define PCH_DPB_AUX_CH_DATA4 0xe4120 #define PCH_DPB_AUX_CH_DATA5 0xe4124 #define PCH_DP_C 0xe4200 #define PCH_DPC_AUX_CH_CTL 0xe4210 #define PCH_DPC_AUX_CH_DATA1 0xe4214 #define PCH_DPC_AUX_CH_DATA2 0xe4218 #define PCH_DPC_AUX_CH_DATA3 0xe421c #define PCH_DPC_AUX_CH_DATA4 0xe4220 #define PCH_DPC_AUX_CH_DATA5 0xe4224 #define PCH_DP_D 0xe4300 #define PCH_DPD_AUX_CH_CTL 0xe4310 #define PCH_DPD_AUX_CH_DATA1 0xe4314 #define PCH_DPD_AUX_CH_DATA2 0xe4318 #define PCH_DPD_AUX_CH_DATA3 0xe431c #define PCH_DPD_AUX_CH_DATA4 0xe4320 #define PCH_DPD_AUX_CH_DATA5 0xe4324 #endif /* _I915_REG_H_ */ #endif /* _I915_REG_H_ */ drivers/gpu/drm/i915/intel_display.c +49 −2 Original line number Original line Diff line number Diff line Loading @@ -268,6 +268,9 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, static bool static bool intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, int target, int refclk, intel_clock_t *best_clock); int target, int refclk, intel_clock_t *best_clock); static bool intel_find_pll_igdng_dp(const intel_limit_t *, struct drm_crtc *crtc, int target, int refclk, intel_clock_t *best_clock); static const intel_limit_t intel_limits_i8xx_dvo = { static const intel_limit_t intel_limits_i8xx_dvo = { .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, Loading Loading @@ -751,6 +754,30 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, return found; return found; } } static bool intel_find_pll_igdng_dp(const intel_limit_t *limit, struct drm_crtc *crtc, int target, int refclk, intel_clock_t *best_clock) { struct drm_device *dev = crtc->dev; intel_clock_t clock; if (target < 200000) { clock.n = 1; clock.p1 = 2; clock.p2 = 10; clock.m1 = 12; clock.m2 = 9; } else { clock.n = 2; clock.p1 = 1; clock.p2 = 10; clock.m1 = 14; clock.m2 = 8; } intel_clock(dev, refclk, &clock); memcpy(best_clock, &clock, sizeof(intel_clock_t)); return true; } static bool static bool intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, int target, int refclk, intel_clock_t *best_clock) int target, int refclk, intel_clock_t *best_clock) Loading @@ -763,6 +790,10 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, int err_most = 47; int err_most = 47; found = false; found = false; if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) return intel_find_pll_igdng_dp(limit, crtc, target, refclk, best_clock); if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) LVDS_CLKB_POWER_UP) Loading Loading @@ -2136,6 +2167,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, int lvds_reg = LVDS; int lvds_reg = LVDS; u32 temp; u32 temp; int sdvo_pixel_multiply; int sdvo_pixel_multiply; int target_clock; drm_vblank_pre_modeset(dev, pipe); drm_vblank_pre_modeset(dev, pipe); Loading Loading @@ -2218,11 +2250,18 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, } } /* FDI link */ /* FDI link */ if (IS_IGDNG(dev)) if (IS_IGDNG(dev)) { /* DP over FDI requires target mode clock instead of link clock */ if (is_dp) target_clock = mode->clock; else target_clock = adjusted_mode->clock; igdng_compute_m_n(3, 4, /* lane num 4 */ igdng_compute_m_n(3, 4, /* lane num 4 */ adjusted_mode->clock, target_clock, 270000, /* lane clock */ 270000, /* lane clock */ &m_n); &m_n); } if (IS_IGD(dev)) if (IS_IGD(dev)) fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; Loading Loading @@ -3050,6 +3089,8 @@ static void intel_setup_outputs(struct drm_device *dev) found = 0; found = 0; if (!found) if (!found) intel_hdmi_init(dev, HDMIB); intel_hdmi_init(dev, HDMIB); if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED)) intel_dp_init(dev, PCH_DP_B); } } if (I915_READ(HDMIC) & PORT_DETECTED) if (I915_READ(HDMIC) & PORT_DETECTED) Loading @@ -3058,6 +3099,12 @@ static void intel_setup_outputs(struct drm_device *dev) if (I915_READ(HDMID) & PORT_DETECTED) if (I915_READ(HDMID) & PORT_DETECTED) intel_hdmi_init(dev, HDMID); intel_hdmi_init(dev, HDMID); if (I915_READ(PCH_DP_C) & DP_DETECTED) intel_dp_init(dev, PCH_DP_C); if (I915_READ(PCH_DP_D) & DP_DETECTED) intel_dp_init(dev, PCH_DP_D); } else if (IS_I9XX(dev)) { } else if (IS_I9XX(dev)) { int found; int found; u32 reg; u32 reg; Loading drivers/gpu/drm/i915/intel_dp.c +83 −19 Original line number Original line Diff line number Diff line Loading @@ -206,7 +206,12 @@ intel_dp_aux_ch(struct intel_output *intel_output, * and would like to run at 2MHz. So, take the * and would like to run at 2MHz. So, take the * hrawclk value and divide by 2 and use that * hrawclk value and divide by 2 and use that */ */ /* IGDNG: input clock fixed at 125Mhz, so aux_bit_clk always 62 */ if (IS_IGDNG(dev)) aux_clock_divider = 62; else aux_clock_divider = intel_hrawclk(dev) / 2; aux_clock_divider = intel_hrawclk(dev) / 2; /* Must try at least 3 times according to DP spec */ /* Must try at least 3 times according to DP spec */ for (try = 0; try < 5; try++) { for (try = 0; try < 5; try++) { /* Load the send data into the aux channel data registers */ /* Load the send data into the aux channel data registers */ Loading Loading @@ -493,6 +498,23 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, intel_dp_compute_m_n(3, lane_count, intel_dp_compute_m_n(3, lane_count, mode->clock, adjusted_mode->clock, &m_n); mode->clock, adjusted_mode->clock, &m_n); if (IS_IGDNG(dev)) { if (intel_crtc->pipe == 0) { I915_WRITE(TRANSA_DATA_M1, ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | m_n.gmch_m); I915_WRITE(TRANSA_DATA_N1, m_n.gmch_n); I915_WRITE(TRANSA_DP_LINK_M1, m_n.link_m); I915_WRITE(TRANSA_DP_LINK_N1, m_n.link_n); } else { I915_WRITE(TRANSB_DATA_M1, ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | m_n.gmch_m); I915_WRITE(TRANSB_DATA_N1, m_n.gmch_n); I915_WRITE(TRANSB_DP_LINK_M1, m_n.link_m); I915_WRITE(TRANSB_DP_LINK_N1, m_n.link_n); } } else { if (intel_crtc->pipe == 0) { if (intel_crtc->pipe == 0) { I915_WRITE(PIPEA_GMCH_DATA_M, I915_WRITE(PIPEA_GMCH_DATA_M, ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | Loading @@ -511,6 +533,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, I915_WRITE(PIPEB_DP_LINK_N, m_n.link_n); I915_WRITE(PIPEB_DP_LINK_N, m_n.link_n); } } } } } static void static void intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, Loading Loading @@ -935,6 +958,12 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP) struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_dp_priv *dp_priv = intel_output->dev_priv; struct intel_dp_priv *dp_priv = intel_output->dev_priv; DP &= ~DP_LINK_TRAIN_MASK; I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); POSTING_READ(dp_priv->output_reg); udelay(17000); I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); POSTING_READ(dp_priv->output_reg); POSTING_READ(dp_priv->output_reg); } } Loading Loading @@ -978,6 +1007,24 @@ intel_dp_check_link_status(struct intel_output *intel_output) intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); } } static enum drm_connector_status igdng_dp_detect(struct drm_connector *connector) { struct intel_output *intel_output = to_intel_output(connector); struct intel_dp_priv *dp_priv = intel_output->dev_priv; enum drm_connector_status status; status = connector_status_disconnected; if (intel_dp_aux_native_read(intel_output, 0x000, dp_priv->dpcd, sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) { if (dp_priv->dpcd[0] != 0) status = connector_status_connected; } return status; } /** /** * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection. * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection. * * Loading @@ -996,6 +1043,9 @@ intel_dp_detect(struct drm_connector *connector) dp_priv->has_audio = false; dp_priv->has_audio = false; if (IS_IGDNG(dev)) return igdng_dp_detect(connector); temp = I915_READ(PORT_HOTPLUG_EN); temp = I915_READ(PORT_HOTPLUG_EN); I915_WRITE(PORT_HOTPLUG_EN, I915_WRITE(PORT_HOTPLUG_EN, Loading Loading @@ -1106,6 +1156,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) struct drm_connector *connector; struct drm_connector *connector; struct intel_output *intel_output; struct intel_output *intel_output; struct intel_dp_priv *dp_priv; struct intel_dp_priv *dp_priv; const char *name = NULL; intel_output = kcalloc(sizeof(struct intel_output) + intel_output = kcalloc(sizeof(struct intel_output) + sizeof(struct intel_dp_priv), 1, GFP_KERNEL); sizeof(struct intel_dp_priv), 1, GFP_KERNEL); Loading Loading @@ -1139,9 +1190,22 @@ intel_dp_init(struct drm_device *dev, int output_reg) drm_sysfs_connector_add(connector); drm_sysfs_connector_add(connector); /* Set up the DDC bus. */ /* Set up the DDC bus. */ intel_dp_i2c_init(intel_output, switch (output_reg) { (output_reg == DP_B) ? "DPDDC-B" : case DP_B: (output_reg == DP_C) ? "DPDDC-C" : "DPDDC-D"); case PCH_DP_B: name = "DPDDC-B"; break; case DP_C: case PCH_DP_C: name = "DPDDC-C"; break; case DP_D: case PCH_DP_D: name = "DPDDC-D"; break; } intel_dp_i2c_init(intel_output, name); intel_output->ddc_bus = &dp_priv->adapter; intel_output->ddc_bus = &dp_priv->adapter; intel_output->hot_plug = intel_dp_hot_plug; intel_output->hot_plug = intel_dp_hot_plug; Loading Loading
drivers/gpu/drm/i915/i915_reg.h +25 −0 Original line number Original line Diff line number Diff line Loading @@ -1444,6 +1444,7 @@ #define DP_CLOCK_OUTPUT_ENABLE (1 << 13) #define DP_CLOCK_OUTPUT_ENABLE (1 << 13) #define DP_SCRAMBLING_DISABLE (1 << 12) #define DP_SCRAMBLING_DISABLE (1 << 12) #define DP_SCRAMBLING_DISABLE_IGDNG (1 << 7) /** limit RGB values to avoid confusing TVs */ /** limit RGB values to avoid confusing TVs */ #define DP_COLOR_RANGE_16_235 (1 << 8) #define DP_COLOR_RANGE_16_235 (1 << 8) Loading Loading @@ -2210,4 +2211,28 @@ #define PCH_PP_OFF_DELAYS 0xc720c #define PCH_PP_OFF_DELAYS 0xc720c #define PCH_PP_DIVISOR 0xc7210 #define PCH_PP_DIVISOR 0xc7210 #define PCH_DP_B 0xe4100 #define PCH_DPB_AUX_CH_CTL 0xe4110 #define PCH_DPB_AUX_CH_DATA1 0xe4114 #define PCH_DPB_AUX_CH_DATA2 0xe4118 #define PCH_DPB_AUX_CH_DATA3 0xe411c #define PCH_DPB_AUX_CH_DATA4 0xe4120 #define PCH_DPB_AUX_CH_DATA5 0xe4124 #define PCH_DP_C 0xe4200 #define PCH_DPC_AUX_CH_CTL 0xe4210 #define PCH_DPC_AUX_CH_DATA1 0xe4214 #define PCH_DPC_AUX_CH_DATA2 0xe4218 #define PCH_DPC_AUX_CH_DATA3 0xe421c #define PCH_DPC_AUX_CH_DATA4 0xe4220 #define PCH_DPC_AUX_CH_DATA5 0xe4224 #define PCH_DP_D 0xe4300 #define PCH_DPD_AUX_CH_CTL 0xe4310 #define PCH_DPD_AUX_CH_DATA1 0xe4314 #define PCH_DPD_AUX_CH_DATA2 0xe4318 #define PCH_DPD_AUX_CH_DATA3 0xe431c #define PCH_DPD_AUX_CH_DATA4 0xe4320 #define PCH_DPD_AUX_CH_DATA5 0xe4324 #endif /* _I915_REG_H_ */ #endif /* _I915_REG_H_ */
drivers/gpu/drm/i915/intel_display.c +49 −2 Original line number Original line Diff line number Diff line Loading @@ -268,6 +268,9 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, static bool static bool intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, int target, int refclk, intel_clock_t *best_clock); int target, int refclk, intel_clock_t *best_clock); static bool intel_find_pll_igdng_dp(const intel_limit_t *, struct drm_crtc *crtc, int target, int refclk, intel_clock_t *best_clock); static const intel_limit_t intel_limits_i8xx_dvo = { static const intel_limit_t intel_limits_i8xx_dvo = { .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, Loading Loading @@ -751,6 +754,30 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, return found; return found; } } static bool intel_find_pll_igdng_dp(const intel_limit_t *limit, struct drm_crtc *crtc, int target, int refclk, intel_clock_t *best_clock) { struct drm_device *dev = crtc->dev; intel_clock_t clock; if (target < 200000) { clock.n = 1; clock.p1 = 2; clock.p2 = 10; clock.m1 = 12; clock.m2 = 9; } else { clock.n = 2; clock.p1 = 1; clock.p2 = 10; clock.m1 = 14; clock.m2 = 8; } intel_clock(dev, refclk, &clock); memcpy(best_clock, &clock, sizeof(intel_clock_t)); return true; } static bool static bool intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, int target, int refclk, intel_clock_t *best_clock) int target, int refclk, intel_clock_t *best_clock) Loading @@ -763,6 +790,10 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, int err_most = 47; int err_most = 47; found = false; found = false; if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) return intel_find_pll_igdng_dp(limit, crtc, target, refclk, best_clock); if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) LVDS_CLKB_POWER_UP) Loading Loading @@ -2136,6 +2167,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, int lvds_reg = LVDS; int lvds_reg = LVDS; u32 temp; u32 temp; int sdvo_pixel_multiply; int sdvo_pixel_multiply; int target_clock; drm_vblank_pre_modeset(dev, pipe); drm_vblank_pre_modeset(dev, pipe); Loading Loading @@ -2218,11 +2250,18 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, } } /* FDI link */ /* FDI link */ if (IS_IGDNG(dev)) if (IS_IGDNG(dev)) { /* DP over FDI requires target mode clock instead of link clock */ if (is_dp) target_clock = mode->clock; else target_clock = adjusted_mode->clock; igdng_compute_m_n(3, 4, /* lane num 4 */ igdng_compute_m_n(3, 4, /* lane num 4 */ adjusted_mode->clock, target_clock, 270000, /* lane clock */ 270000, /* lane clock */ &m_n); &m_n); } if (IS_IGD(dev)) if (IS_IGD(dev)) fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; Loading Loading @@ -3050,6 +3089,8 @@ static void intel_setup_outputs(struct drm_device *dev) found = 0; found = 0; if (!found) if (!found) intel_hdmi_init(dev, HDMIB); intel_hdmi_init(dev, HDMIB); if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED)) intel_dp_init(dev, PCH_DP_B); } } if (I915_READ(HDMIC) & PORT_DETECTED) if (I915_READ(HDMIC) & PORT_DETECTED) Loading @@ -3058,6 +3099,12 @@ static void intel_setup_outputs(struct drm_device *dev) if (I915_READ(HDMID) & PORT_DETECTED) if (I915_READ(HDMID) & PORT_DETECTED) intel_hdmi_init(dev, HDMID); intel_hdmi_init(dev, HDMID); if (I915_READ(PCH_DP_C) & DP_DETECTED) intel_dp_init(dev, PCH_DP_C); if (I915_READ(PCH_DP_D) & DP_DETECTED) intel_dp_init(dev, PCH_DP_D); } else if (IS_I9XX(dev)) { } else if (IS_I9XX(dev)) { int found; int found; u32 reg; u32 reg; Loading
drivers/gpu/drm/i915/intel_dp.c +83 −19 Original line number Original line Diff line number Diff line Loading @@ -206,7 +206,12 @@ intel_dp_aux_ch(struct intel_output *intel_output, * and would like to run at 2MHz. So, take the * and would like to run at 2MHz. So, take the * hrawclk value and divide by 2 and use that * hrawclk value and divide by 2 and use that */ */ /* IGDNG: input clock fixed at 125Mhz, so aux_bit_clk always 62 */ if (IS_IGDNG(dev)) aux_clock_divider = 62; else aux_clock_divider = intel_hrawclk(dev) / 2; aux_clock_divider = intel_hrawclk(dev) / 2; /* Must try at least 3 times according to DP spec */ /* Must try at least 3 times according to DP spec */ for (try = 0; try < 5; try++) { for (try = 0; try < 5; try++) { /* Load the send data into the aux channel data registers */ /* Load the send data into the aux channel data registers */ Loading Loading @@ -493,6 +498,23 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, intel_dp_compute_m_n(3, lane_count, intel_dp_compute_m_n(3, lane_count, mode->clock, adjusted_mode->clock, &m_n); mode->clock, adjusted_mode->clock, &m_n); if (IS_IGDNG(dev)) { if (intel_crtc->pipe == 0) { I915_WRITE(TRANSA_DATA_M1, ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | m_n.gmch_m); I915_WRITE(TRANSA_DATA_N1, m_n.gmch_n); I915_WRITE(TRANSA_DP_LINK_M1, m_n.link_m); I915_WRITE(TRANSA_DP_LINK_N1, m_n.link_n); } else { I915_WRITE(TRANSB_DATA_M1, ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | m_n.gmch_m); I915_WRITE(TRANSB_DATA_N1, m_n.gmch_n); I915_WRITE(TRANSB_DP_LINK_M1, m_n.link_m); I915_WRITE(TRANSB_DP_LINK_N1, m_n.link_n); } } else { if (intel_crtc->pipe == 0) { if (intel_crtc->pipe == 0) { I915_WRITE(PIPEA_GMCH_DATA_M, I915_WRITE(PIPEA_GMCH_DATA_M, ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | Loading @@ -511,6 +533,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, I915_WRITE(PIPEB_DP_LINK_N, m_n.link_n); I915_WRITE(PIPEB_DP_LINK_N, m_n.link_n); } } } } } static void static void intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, Loading Loading @@ -935,6 +958,12 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP) struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_dp_priv *dp_priv = intel_output->dev_priv; struct intel_dp_priv *dp_priv = intel_output->dev_priv; DP &= ~DP_LINK_TRAIN_MASK; I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); POSTING_READ(dp_priv->output_reg); udelay(17000); I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); POSTING_READ(dp_priv->output_reg); POSTING_READ(dp_priv->output_reg); } } Loading Loading @@ -978,6 +1007,24 @@ intel_dp_check_link_status(struct intel_output *intel_output) intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); } } static enum drm_connector_status igdng_dp_detect(struct drm_connector *connector) { struct intel_output *intel_output = to_intel_output(connector); struct intel_dp_priv *dp_priv = intel_output->dev_priv; enum drm_connector_status status; status = connector_status_disconnected; if (intel_dp_aux_native_read(intel_output, 0x000, dp_priv->dpcd, sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) { if (dp_priv->dpcd[0] != 0) status = connector_status_connected; } return status; } /** /** * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection. * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection. * * Loading @@ -996,6 +1043,9 @@ intel_dp_detect(struct drm_connector *connector) dp_priv->has_audio = false; dp_priv->has_audio = false; if (IS_IGDNG(dev)) return igdng_dp_detect(connector); temp = I915_READ(PORT_HOTPLUG_EN); temp = I915_READ(PORT_HOTPLUG_EN); I915_WRITE(PORT_HOTPLUG_EN, I915_WRITE(PORT_HOTPLUG_EN, Loading Loading @@ -1106,6 +1156,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) struct drm_connector *connector; struct drm_connector *connector; struct intel_output *intel_output; struct intel_output *intel_output; struct intel_dp_priv *dp_priv; struct intel_dp_priv *dp_priv; const char *name = NULL; intel_output = kcalloc(sizeof(struct intel_output) + intel_output = kcalloc(sizeof(struct intel_output) + sizeof(struct intel_dp_priv), 1, GFP_KERNEL); sizeof(struct intel_dp_priv), 1, GFP_KERNEL); Loading Loading @@ -1139,9 +1190,22 @@ intel_dp_init(struct drm_device *dev, int output_reg) drm_sysfs_connector_add(connector); drm_sysfs_connector_add(connector); /* Set up the DDC bus. */ /* Set up the DDC bus. */ intel_dp_i2c_init(intel_output, switch (output_reg) { (output_reg == DP_B) ? "DPDDC-B" : case DP_B: (output_reg == DP_C) ? "DPDDC-C" : "DPDDC-D"); case PCH_DP_B: name = "DPDDC-B"; break; case DP_C: case PCH_DP_C: name = "DPDDC-C"; break; case DP_D: case PCH_DP_D: name = "DPDDC-D"; break; } intel_dp_i2c_init(intel_output, name); intel_output->ddc_bus = &dp_priv->adapter; intel_output->ddc_bus = &dp_priv->adapter; intel_output->hot_plug = intel_dp_hot_plug; intel_output->hot_plug = intel_dp_hot_plug; Loading