aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_hdmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_hdmi.c')
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c102
1 files changed, 99 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index eee2bbec2958..f9151f6641d9 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -367,6 +367,9 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
367 union hdmi_infoframe frame; 367 union hdmi_infoframe frame;
368 int ret; 368 int ret;
369 369
370 /* Set user selected PAR to incoming mode's member */
371 adjusted_mode->picture_aspect_ratio = intel_hdmi->aspect_ratio;
372
370 ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, 373 ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
371 adjusted_mode); 374 adjusted_mode);
372 if (ret < 0) { 375 if (ret < 0) {
@@ -879,7 +882,7 @@ static bool hdmi_12bpc_possible(struct intel_crtc *crtc)
879 struct intel_encoder *encoder; 882 struct intel_encoder *encoder;
880 int count = 0, count_hdmi = 0; 883 int count = 0, count_hdmi = 0;
881 884
882 if (!HAS_PCH_SPLIT(dev)) 885 if (HAS_GMCH_DISPLAY(dev))
883 return false; 886 return false;
884 887
885 list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { 888 list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) {
@@ -1124,6 +1127,23 @@ intel_hdmi_set_property(struct drm_connector *connector,
1124 goto done; 1127 goto done;
1125 } 1128 }
1126 1129
1130 if (property == connector->dev->mode_config.aspect_ratio_property) {
1131 switch (val) {
1132 case DRM_MODE_PICTURE_ASPECT_NONE:
1133 intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
1134 break;
1135 case DRM_MODE_PICTURE_ASPECT_4_3:
1136 intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_4_3;
1137 break;
1138 case DRM_MODE_PICTURE_ASPECT_16_9:
1139 intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_16_9;
1140 break;
1141 default:
1142 return -EINVAL;
1143 }
1144 goto done;
1145 }
1146
1127 return -EINVAL; 1147 return -EINVAL;
1128 1148
1129done: 1149done:
@@ -1229,6 +1249,70 @@ static void vlv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
1229 mutex_unlock(&dev_priv->dpio_lock); 1249 mutex_unlock(&dev_priv->dpio_lock);
1230} 1250}
1231 1251
1252static void chv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
1253{
1254 struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
1255 struct drm_device *dev = encoder->base.dev;
1256 struct drm_i915_private *dev_priv = dev->dev_private;
1257 struct intel_crtc *intel_crtc =
1258 to_intel_crtc(encoder->base.crtc);
1259 enum dpio_channel ch = vlv_dport_to_channel(dport);
1260 enum pipe pipe = intel_crtc->pipe;
1261 u32 val;
1262
1263 mutex_lock(&dev_priv->dpio_lock);
1264
1265 /* program left/right clock distribution */
1266 if (pipe != PIPE_B) {
1267 val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
1268 val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK);
1269 if (ch == DPIO_CH0)
1270 val |= CHV_BUFLEFTENA1_FORCE;
1271 if (ch == DPIO_CH1)
1272 val |= CHV_BUFRIGHTENA1_FORCE;
1273 vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW5_CH0, val);
1274 } else {
1275 val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW1_CH1);
1276 val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK);
1277 if (ch == DPIO_CH0)
1278 val |= CHV_BUFLEFTENA2_FORCE;
1279 if (ch == DPIO_CH1)
1280 val |= CHV_BUFRIGHTENA2_FORCE;
1281 vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW1_CH1, val);
1282 }
1283
1284 /* program clock channel usage */
1285 val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW8(ch));
1286 val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE;
1287 if (pipe != PIPE_B)
1288 val &= ~CHV_PCS_USEDCLKCHANNEL;
1289 else
1290 val |= CHV_PCS_USEDCLKCHANNEL;
1291 vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW8(ch), val);
1292
1293 val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW8(ch));
1294 val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE;
1295 if (pipe != PIPE_B)
1296 val &= ~CHV_PCS_USEDCLKCHANNEL;
1297 else
1298 val |= CHV_PCS_USEDCLKCHANNEL;
1299 vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW8(ch), val);
1300
1301 /*
1302 * This a a bit weird since generally CL
1303 * matches the pipe, but here we need to
1304 * pick the CL based on the port.
1305 */
1306 val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW19(ch));
1307 if (pipe != PIPE_B)
1308 val &= ~CHV_CMN_USEDCLKCHANNEL;
1309 else
1310 val |= CHV_CMN_USEDCLKCHANNEL;
1311 vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW19(ch), val);
1312
1313 mutex_unlock(&dev_priv->dpio_lock);
1314}
1315
1232static void vlv_hdmi_post_disable(struct intel_encoder *encoder) 1316static void vlv_hdmi_post_disable(struct intel_encoder *encoder)
1233{ 1317{
1234 struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); 1318 struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
@@ -1416,11 +1500,22 @@ static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {
1416}; 1500};
1417 1501
1418static void 1502static void
1503intel_attach_aspect_ratio_property(struct drm_connector *connector)
1504{
1505 if (!drm_mode_create_aspect_ratio_property(connector->dev))
1506 drm_object_attach_property(&connector->base,
1507 connector->dev->mode_config.aspect_ratio_property,
1508 DRM_MODE_PICTURE_ASPECT_NONE);
1509}
1510
1511static void
1419intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector) 1512intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector)
1420{ 1513{
1421 intel_attach_force_audio_property(connector); 1514 intel_attach_force_audio_property(connector);
1422 intel_attach_broadcast_rgb_property(connector); 1515 intel_attach_broadcast_rgb_property(connector);
1423 intel_hdmi->color_range_auto = true; 1516 intel_hdmi->color_range_auto = true;
1517 intel_attach_aspect_ratio_property(connector);
1518 intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
1424} 1519}
1425 1520
1426void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, 1521void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
@@ -1467,7 +1562,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
1467 if (IS_VALLEYVIEW(dev)) { 1562 if (IS_VALLEYVIEW(dev)) {
1468 intel_hdmi->write_infoframe = vlv_write_infoframe; 1563 intel_hdmi->write_infoframe = vlv_write_infoframe;
1469 intel_hdmi->set_infoframes = vlv_set_infoframes; 1564 intel_hdmi->set_infoframes = vlv_set_infoframes;
1470 } else if (!HAS_PCH_SPLIT(dev)) { 1565 } else if (IS_G4X(dev)) {
1471 intel_hdmi->write_infoframe = g4x_write_infoframe; 1566 intel_hdmi->write_infoframe = g4x_write_infoframe;
1472 intel_hdmi->set_infoframes = g4x_set_infoframes; 1567 intel_hdmi->set_infoframes = g4x_set_infoframes;
1473 } else if (HAS_DDI(dev)) { 1568 } else if (HAS_DDI(dev)) {
@@ -1490,7 +1585,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
1490 intel_hdmi_add_properties(intel_hdmi, connector); 1585 intel_hdmi_add_properties(intel_hdmi, connector);
1491 1586
1492 intel_connector_attach_encoder(intel_connector, intel_encoder); 1587 intel_connector_attach_encoder(intel_connector, intel_encoder);
1493 drm_sysfs_connector_add(connector); 1588 drm_connector_register(connector);
1494 1589
1495 /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written 1590 /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
1496 * 0xd. Failure to do so will result in spurious interrupts being 1591 * 0xd. Failure to do so will result in spurious interrupts being
@@ -1528,6 +1623,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port)
1528 intel_encoder->get_hw_state = intel_hdmi_get_hw_state; 1623 intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
1529 intel_encoder->get_config = intel_hdmi_get_config; 1624 intel_encoder->get_config = intel_hdmi_get_config;
1530 if (IS_CHERRYVIEW(dev)) { 1625 if (IS_CHERRYVIEW(dev)) {
1626 intel_encoder->pre_pll_enable = chv_hdmi_pre_pll_enable;
1531 intel_encoder->pre_enable = chv_hdmi_pre_enable; 1627 intel_encoder->pre_enable = chv_hdmi_pre_enable;
1532 intel_encoder->enable = vlv_enable_hdmi; 1628 intel_encoder->enable = vlv_enable_hdmi;
1533 intel_encoder->post_disable = chv_hdmi_post_disable; 1629 intel_encoder->post_disable = chv_hdmi_post_disable;