aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_connectors.c
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2011-05-20 04:34:31 -0400
committerDave Airlie <airlied@redhat.com>2011-05-20 06:02:35 -0400
commitd291767b6056540277497d91baa9120428d7cd1a (patch)
treeadf2ad3bf1593dc01bc1b635a3be2a66e979a158 /drivers/gpu/drm/radeon/radeon_connectors.c
parent7c3ed0fd9b72d489243ff97f3cea2e1d4d07d9fa (diff)
drm/radeon/kms: fixup eDP connector handling
It's more like LVDS then DP in some ways. Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_connectors.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c80
1 files changed, 72 insertions, 8 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 532f17d39e1c..ee1dccb3fec9 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1055,16 +1055,44 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
1055 int ret; 1055 int ret;
1056 1056
1057 if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { 1057 if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
1058 struct drm_encoder *encoder;
1059 struct drm_display_mode *mode;
1060
1058 if (!radeon_dig_connector->edp_on) 1061 if (!radeon_dig_connector->edp_on)
1059 atombios_set_edp_panel_power(connector, 1062 atombios_set_edp_panel_power(connector,
1060 ATOM_TRANSMITTER_ACTION_POWER_ON); 1063 ATOM_TRANSMITTER_ACTION_POWER_ON);
1061 } 1064 ret = radeon_ddc_get_modes(radeon_connector);
1062 ret = radeon_ddc_get_modes(radeon_connector);
1063 if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
1064 if (!radeon_dig_connector->edp_on) 1065 if (!radeon_dig_connector->edp_on)
1065 atombios_set_edp_panel_power(connector, 1066 atombios_set_edp_panel_power(connector,
1066 ATOM_TRANSMITTER_ACTION_POWER_OFF); 1067 ATOM_TRANSMITTER_ACTION_POWER_OFF);
1067 } 1068
1069 if (ret > 0) {
1070 encoder = radeon_best_single_encoder(connector);
1071 if (encoder) {
1072 radeon_fixup_lvds_native_mode(encoder, connector);
1073 /* add scaled modes */
1074 radeon_add_common_modes(encoder, connector);
1075 }
1076 return ret;
1077 }
1078
1079 encoder = radeon_best_single_encoder(connector);
1080 if (!encoder)
1081 return 0;
1082
1083 /* we have no EDID modes */
1084 mode = radeon_fp_native_mode(encoder);
1085 if (mode) {
1086 ret = 1;
1087 drm_mode_probed_add(connector, mode);
1088 /* add the width/height from vbios tables if available */
1089 connector->display_info.width_mm = mode->width_mm;
1090 connector->display_info.height_mm = mode->height_mm;
1091 /* add scaled modes */
1092 radeon_add_common_modes(encoder, connector);
1093 }
1094 } else
1095 ret = radeon_ddc_get_modes(radeon_connector);
1068 1096
1069 return ret; 1097 return ret;
1070} 1098}
@@ -1155,6 +1183,15 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
1155 } 1183 }
1156 1184
1157 if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { 1185 if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
1186 struct drm_encoder *encoder = radeon_best_single_encoder(connector);
1187 if (encoder) {
1188 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1189 struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
1190
1191 /* check if panel is valid */
1192 if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240)
1193 ret = connector_status_connected;
1194 }
1158 /* eDP is always DP */ 1195 /* eDP is always DP */
1159 radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; 1196 radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT;
1160 if (!radeon_dig_connector->edp_on) 1197 if (!radeon_dig_connector->edp_on)
@@ -1194,11 +1231,38 @@ static int radeon_dp_mode_valid(struct drm_connector *connector,
1194 1231
1195 /* XXX check mode bandwidth */ 1232 /* XXX check mode bandwidth */
1196 1233
1197 if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || 1234 if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
1198 (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) 1235 struct drm_encoder *encoder = radeon_best_single_encoder(connector);
1199 return radeon_dp_mode_valid_helper(connector, mode); 1236
1200 else 1237 if ((mode->hdisplay < 320) || (mode->vdisplay < 240))
1238 return MODE_PANEL;
1239
1240 if (encoder) {
1241 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1242 struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
1243
1244 /* AVIVO hardware supports downscaling modes larger than the panel
1245 * to the panel size, but I'm not sure this is desirable.
1246 */
1247 if ((mode->hdisplay > native_mode->hdisplay) ||
1248 (mode->vdisplay > native_mode->vdisplay))
1249 return MODE_PANEL;
1250
1251 /* if scaling is disabled, block non-native modes */
1252 if (radeon_encoder->rmx_type == RMX_OFF) {
1253 if ((mode->hdisplay != native_mode->hdisplay) ||
1254 (mode->vdisplay != native_mode->vdisplay))
1255 return MODE_PANEL;
1256 }
1257 }
1201 return MODE_OK; 1258 return MODE_OK;
1259 } else {
1260 if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
1261 (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
1262 return radeon_dp_mode_valid_helper(connector, mode);
1263 else
1264 return MODE_OK;
1265 }
1202} 1266}
1203 1267
1204struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = { 1268struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = {