aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/gma500/cdv_intel_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/gma500/cdv_intel_display.c')
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_display.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c
index 3f1106096ad3..bfb056561777 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_display.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_display.c
@@ -438,7 +438,8 @@ static const struct cdv_intel_limit_t *cdv_intel_limit(struct drm_crtc *crtc,
438 limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_96]; 438 limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_96];
439 else 439 else
440 limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_100]; 440 limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_100];
441 } else if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { 441 } else if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) ||
442 psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) {
442 if (refclk == 27000) 443 if (refclk == 27000)
443 limit = &cdv_intel_limits[CDV_LIMIT_DP_27]; 444 limit = &cdv_intel_limits[CDV_LIMIT_DP_27];
444 else 445 else
@@ -1045,6 +1046,7 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
1045 struct drm_connector *connector; 1046 struct drm_connector *connector;
1046 const struct cdv_intel_limit_t *limit; 1047 const struct cdv_intel_limit_t *limit;
1047 u32 ddi_select = 0; 1048 u32 ddi_select = 0;
1049 bool is_edp = false;
1048 1050
1049 list_for_each_entry(connector, &mode_config->connector_list, head) { 1051 list_for_each_entry(connector, &mode_config->connector_list, head) {
1050 struct psb_intel_encoder *psb_intel_encoder = 1052 struct psb_intel_encoder *psb_intel_encoder =
@@ -1071,6 +1073,9 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
1071 case INTEL_OUTPUT_DISPLAYPORT: 1073 case INTEL_OUTPUT_DISPLAYPORT:
1072 is_dp = true; 1074 is_dp = true;
1073 break; 1075 break;
1076 case INTEL_OUTPUT_EDP:
1077 is_edp = true;
1078 break;
1074 default: 1079 default:
1075 DRM_ERROR("invalid output type.\n"); 1080 DRM_ERROR("invalid output type.\n");
1076 return 0; 1081 return 0;
@@ -1083,7 +1088,15 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
1083 else 1088 else
1084 /* high-end sku, 27/100 mhz */ 1089 /* high-end sku, 27/100 mhz */
1085 refclk = 27000; 1090 refclk = 27000;
1086 if (is_dp) { 1091 if (is_dp || is_edp) {
1092 /*
1093 * Based on the spec the low-end SKU has only CRT/LVDS. So it is
1094 * unnecessary to consider it for DP/eDP.
1095 * On the high-end SKU, it will use the 27/100M reference clk
1096 * for DP/eDP. When using SSC clock, the ref clk is 100MHz.Otherwise
1097 * it will be 27MHz. From the VBIOS code it seems that the pipe A choose
1098 * 27MHz for DP/eDP while the Pipe B chooses the 100MHz.
1099 */
1087 if (pipe == 0) 1100 if (pipe == 0)
1088 refclk = 27000; 1101 refclk = 27000;
1089 else 1102 else
@@ -1133,6 +1146,31 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
1133 /* setup pipeconf */ 1146 /* setup pipeconf */
1134 pipeconf = REG_READ(map->conf); 1147 pipeconf = REG_READ(map->conf);
1135 1148
1149 pipeconf &= ~(PIPE_BPC_MASK);
1150 if (is_edp) {
1151 switch (dev_priv->edp.bpp) {
1152 case 24:
1153 pipeconf |= PIPE_8BPC;
1154 break;
1155 case 18:
1156 pipeconf |= PIPE_6BPC;
1157 break;
1158 case 30:
1159 pipeconf |= PIPE_10BPC;
1160 break;
1161 default:
1162 pipeconf |= PIPE_8BPC;
1163 break;
1164 }
1165 } else if (is_lvds) {
1166 /* the BPC will be 6 if it is 18-bit LVDS panel */
1167 if ((REG_READ(LVDS) & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP)
1168 pipeconf |= PIPE_8BPC;
1169 else
1170 pipeconf |= PIPE_6BPC;
1171 } else
1172 pipeconf |= PIPE_8BPC;
1173
1136 /* Set up the display plane register */ 1174 /* Set up the display plane register */
1137 dspcntr = DISPPLANE_GAMMA_ENABLE; 1175 dspcntr = DISPPLANE_GAMMA_ENABLE;
1138 1176