aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_dp.c
diff options
context:
space:
mode:
authorZhenyu Wang <zhenyuw@linux.intel.com>2009-07-23 13:00:32 -0400
committerEric Anholt <eric@anholt.net>2009-07-29 18:16:19 -0400
commit32f9d658aee5be09ebdd28fc730630e61d0b46db (patch)
tree66f1417c8631659c17874876ab7036eb4fdf2ec9 /drivers/gpu/drm/i915/intel_dp.c
parent5eb08b69f510fadaba77eb9a1bda0f7299c4ebcc (diff)
drm/i915: Add eDP support on IGDNG mobile chip
This adds embedded DisplayPort support on next mobile chip which aims to replace origin LVDS port. VBT's driver feature block has been used to determine the type of current internal panel for eDP or LVDS. Currently no panel fitting support for eDP and backlight control would be added in future. Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com> Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp.c')
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c112
1 files changed, 105 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 0715911cbd8..a6ff15ac548 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -40,6 +40,8 @@
40 40
41#define DP_LINK_CONFIGURATION_SIZE 9 41#define DP_LINK_CONFIGURATION_SIZE 9
42 42
43#define IS_eDP(i) ((i)->type == INTEL_OUTPUT_EDP)
44
43struct intel_dp_priv { 45struct intel_dp_priv {
44 uint32_t output_reg; 46 uint32_t output_reg;
45 uint32_t DP; 47 uint32_t DP;
@@ -63,6 +65,19 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
63static void 65static void
64intel_dp_link_down(struct intel_output *intel_output, uint32_t DP); 66intel_dp_link_down(struct intel_output *intel_output, uint32_t DP);
65 67
68void
69intel_edp_link_config (struct intel_output *intel_output,
70 int *lane_num, int *link_bw)
71{
72 struct intel_dp_priv *dp_priv = intel_output->dev_priv;
73
74 *lane_num = dp_priv->lane_count;
75 if (dp_priv->link_bw == DP_LINK_BW_1_62)
76 *link_bw = 162000;
77 else if (dp_priv->link_bw == DP_LINK_BW_2_7)
78 *link_bw = 270000;
79}
80
66static int 81static int
67intel_dp_max_lane_count(struct intel_output *intel_output) 82intel_dp_max_lane_count(struct intel_output *intel_output)
68{ 83{
@@ -206,9 +221,10 @@ intel_dp_aux_ch(struct intel_output *intel_output,
206 * and would like to run at 2MHz. So, take the 221 * and would like to run at 2MHz. So, take the
207 * hrawclk value and divide by 2 and use that 222 * hrawclk value and divide by 2 and use that
208 */ 223 */
209 /* IGDNG: input clock fixed at 125Mhz, so aux_bit_clk always 62 */ 224 if (IS_eDP(intel_output))
210 if (IS_IGDNG(dev)) 225 aux_clock_divider = 225; /* eDP input clock at 450Mhz */
211 aux_clock_divider = 62; 226 else if (IS_IGDNG(dev))
227 aux_clock_divider = 62; /* IGDNG: input clock fixed at 125Mhz */
212 else 228 else
213 aux_clock_divider = intel_hrawclk(dev) / 2; 229 aux_clock_divider = intel_hrawclk(dev) / 2;
214 230
@@ -579,8 +595,38 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
579 595
580 if (intel_crtc->pipe == 1) 596 if (intel_crtc->pipe == 1)
581 dp_priv->DP |= DP_PIPEB_SELECT; 597 dp_priv->DP |= DP_PIPEB_SELECT;
598
599 if (IS_eDP(intel_output)) {
600 /* don't miss out required setting for eDP */
601 dp_priv->DP |= DP_PLL_ENABLE;
602 if (adjusted_mode->clock < 200000)
603 dp_priv->DP |= DP_PLL_FREQ_160MHZ;
604 else
605 dp_priv->DP |= DP_PLL_FREQ_270MHZ;
606 }
582} 607}
583 608
609static void igdng_edp_backlight_on (struct drm_device *dev)
610{
611 struct drm_i915_private *dev_priv = dev->dev_private;
612 u32 pp;
613
614 DRM_DEBUG("\n");
615 pp = I915_READ(PCH_PP_CONTROL);
616 pp |= EDP_BLC_ENABLE;
617 I915_WRITE(PCH_PP_CONTROL, pp);
618}
619
620static void igdng_edp_backlight_off (struct drm_device *dev)
621{
622 struct drm_i915_private *dev_priv = dev->dev_private;
623 u32 pp;
624
625 DRM_DEBUG("\n");
626 pp = I915_READ(PCH_PP_CONTROL);
627 pp &= ~EDP_BLC_ENABLE;
628 I915_WRITE(PCH_PP_CONTROL, pp);
629}
584 630
585static void 631static void
586intel_dp_dpms(struct drm_encoder *encoder, int mode) 632intel_dp_dpms(struct drm_encoder *encoder, int mode)
@@ -592,11 +638,17 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
592 uint32_t dp_reg = I915_READ(dp_priv->output_reg); 638 uint32_t dp_reg = I915_READ(dp_priv->output_reg);
593 639
594 if (mode != DRM_MODE_DPMS_ON) { 640 if (mode != DRM_MODE_DPMS_ON) {
595 if (dp_reg & DP_PORT_EN) 641 if (dp_reg & DP_PORT_EN) {
596 intel_dp_link_down(intel_output, dp_priv->DP); 642 intel_dp_link_down(intel_output, dp_priv->DP);
643 if (IS_eDP(intel_output))
644 igdng_edp_backlight_off(dev);
645 }
597 } else { 646 } else {
598 if (!(dp_reg & DP_PORT_EN)) 647 if (!(dp_reg & DP_PORT_EN)) {
599 intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); 648 intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration);
649 if (IS_eDP(intel_output))
650 igdng_edp_backlight_on(dev);
651 }
600 } 652 }
601 dp_priv->dpms_mode = mode; 653 dp_priv->dpms_mode = mode;
602} 654}
@@ -958,12 +1010,23 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)
958 struct drm_i915_private *dev_priv = dev->dev_private; 1010 struct drm_i915_private *dev_priv = dev->dev_private;
959 struct intel_dp_priv *dp_priv = intel_output->dev_priv; 1011 struct intel_dp_priv *dp_priv = intel_output->dev_priv;
960 1012
1013 DRM_DEBUG("\n");
1014
1015 if (IS_eDP(intel_output)) {
1016 DP &= ~DP_PLL_ENABLE;
1017 I915_WRITE(dp_priv->output_reg, DP);
1018 POSTING_READ(dp_priv->output_reg);
1019 udelay(100);
1020 }
1021
961 DP &= ~DP_LINK_TRAIN_MASK; 1022 DP &= ~DP_LINK_TRAIN_MASK;
962 I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); 1023 I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE);
963 POSTING_READ(dp_priv->output_reg); 1024 POSTING_READ(dp_priv->output_reg);
964 1025
965 udelay(17000); 1026 udelay(17000);
966 1027
1028 if (IS_eDP(intel_output))
1029 DP |= DP_LINK_TRAIN_OFF;
967 I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); 1030 I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN);
968 POSTING_READ(dp_priv->output_reg); 1031 POSTING_READ(dp_priv->output_reg);
969} 1032}
@@ -1089,11 +1152,27 @@ intel_dp_detect(struct drm_connector *connector)
1089static int intel_dp_get_modes(struct drm_connector *connector) 1152static int intel_dp_get_modes(struct drm_connector *connector)
1090{ 1153{
1091 struct intel_output *intel_output = to_intel_output(connector); 1154 struct intel_output *intel_output = to_intel_output(connector);
1155 struct drm_device *dev = intel_output->base.dev;
1156 struct drm_i915_private *dev_priv = dev->dev_private;
1157 int ret;
1092 1158
1093 /* We should parse the EDID data and find out if it has an audio sink 1159 /* We should parse the EDID data and find out if it has an audio sink
1094 */ 1160 */
1095 1161
1096 return intel_ddc_get_modes(intel_output); 1162 ret = intel_ddc_get_modes(intel_output);
1163 if (ret)
1164 return ret;
1165
1166 /* if eDP has no EDID, try to use fixed panel mode from VBT */
1167 if (IS_eDP(intel_output)) {
1168 if (dev_priv->panel_fixed_mode != NULL) {
1169 struct drm_display_mode *mode;
1170 mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
1171 drm_mode_probed_add(connector, mode);
1172 return 1;
1173 }
1174 }
1175 return 0;
1097} 1176}
1098 1177
1099static void 1178static void
@@ -1170,7 +1249,10 @@ intel_dp_init(struct drm_device *dev, int output_reg)
1170 DRM_MODE_CONNECTOR_DisplayPort); 1249 DRM_MODE_CONNECTOR_DisplayPort);
1171 drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); 1250 drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);
1172 1251
1173 intel_output->type = INTEL_OUTPUT_DISPLAYPORT; 1252 if (output_reg == DP_A)
1253 intel_output->type = INTEL_OUTPUT_EDP;
1254 else
1255 intel_output->type = INTEL_OUTPUT_DISPLAYPORT;
1174 1256
1175 connector->interlace_allowed = true; 1257 connector->interlace_allowed = true;
1176 connector->doublescan_allowed = 0; 1258 connector->doublescan_allowed = 0;
@@ -1191,6 +1273,9 @@ intel_dp_init(struct drm_device *dev, int output_reg)
1191 1273
1192 /* Set up the DDC bus. */ 1274 /* Set up the DDC bus. */
1193 switch (output_reg) { 1275 switch (output_reg) {
1276 case DP_A:
1277 name = "DPDDC-A";
1278 break;
1194 case DP_B: 1279 case DP_B:
1195 case PCH_DP_B: 1280 case PCH_DP_B:
1196 name = "DPDDC-B"; 1281 name = "DPDDC-B";
@@ -1206,9 +1291,22 @@ intel_dp_init(struct drm_device *dev, int output_reg)
1206 } 1291 }
1207 1292
1208 intel_dp_i2c_init(intel_output, name); 1293 intel_dp_i2c_init(intel_output, name);
1294
1209 intel_output->ddc_bus = &dp_priv->adapter; 1295 intel_output->ddc_bus = &dp_priv->adapter;
1210 intel_output->hot_plug = intel_dp_hot_plug; 1296 intel_output->hot_plug = intel_dp_hot_plug;
1211 1297
1298 if (output_reg == DP_A) {
1299 /* initialize panel mode from VBT if available for eDP */
1300 if (dev_priv->lfp_lvds_vbt_mode) {
1301 dev_priv->panel_fixed_mode =
1302 drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
1303 if (dev_priv->panel_fixed_mode) {
1304 dev_priv->panel_fixed_mode->type |=
1305 DRM_MODE_TYPE_PREFERRED;
1306 }
1307 }
1308 }
1309
1212 /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written 1310 /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
1213 * 0xd. Failure to do so will result in spurious interrupts being 1311 * 0xd. Failure to do so will result in spurious interrupts being
1214 * generated on the port when a cable is not attached. 1312 * generated on the port when a cable is not attached.