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.c168
1 files changed, 97 insertions, 71 deletions
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 5a9de21637b7..29ec1535992d 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -869,10 +869,15 @@ static enum drm_mode_status
869intel_hdmi_mode_valid(struct drm_connector *connector, 869intel_hdmi_mode_valid(struct drm_connector *connector,
870 struct drm_display_mode *mode) 870 struct drm_display_mode *mode)
871{ 871{
872 if (mode->clock > hdmi_portclock_limit(intel_attached_hdmi(connector), 872 int clock = mode->clock;
873 true)) 873
874 if (mode->flags & DRM_MODE_FLAG_DBLCLK)
875 clock *= 2;
876
877 if (clock > hdmi_portclock_limit(intel_attached_hdmi(connector),
878 true))
874 return MODE_CLOCK_HIGH; 879 return MODE_CLOCK_HIGH;
875 if (mode->clock < 20000) 880 if (clock < 20000)
876 return MODE_CLOCK_LOW; 881 return MODE_CLOCK_LOW;
877 882
878 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 883 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
@@ -890,7 +895,7 @@ static bool hdmi_12bpc_possible(struct intel_crtc *crtc)
890 if (HAS_GMCH_DISPLAY(dev)) 895 if (HAS_GMCH_DISPLAY(dev))
891 return false; 896 return false;
892 897
893 list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { 898 for_each_intel_encoder(dev, encoder) {
894 if (encoder->new_crtc != crtc) 899 if (encoder->new_crtc != crtc)
895 continue; 900 continue;
896 901
@@ -926,6 +931,10 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
926 intel_hdmi->color_range = 0; 931 intel_hdmi->color_range = 0;
927 } 932 }
928 933
934 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) {
935 pipe_config->pixel_multiplier = 2;
936 }
937
929 if (intel_hdmi->color_range) 938 if (intel_hdmi->color_range)
930 pipe_config->limited_color_range = true; 939 pipe_config->limited_color_range = true;
931 940
@@ -967,104 +976,117 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
967 return true; 976 return true;
968} 977}
969 978
970static enum drm_connector_status 979static void
971intel_hdmi_detect(struct drm_connector *connector, bool force) 980intel_hdmi_unset_edid(struct drm_connector *connector)
972{ 981{
973 struct drm_device *dev = connector->dev;
974 struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); 982 struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
975 struct intel_digital_port *intel_dig_port =
976 hdmi_to_dig_port(intel_hdmi);
977 struct intel_encoder *intel_encoder = &intel_dig_port->base;
978 struct drm_i915_private *dev_priv = dev->dev_private;
979 struct edid *edid;
980 enum intel_display_power_domain power_domain;
981 enum drm_connector_status status = connector_status_disconnected;
982 983
983 DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", 984 intel_hdmi->has_hdmi_sink = false;
984 connector->base.id, connector->name); 985 intel_hdmi->has_audio = false;
986 intel_hdmi->rgb_quant_range_selectable = false;
987
988 kfree(to_intel_connector(connector)->detect_edid);
989 to_intel_connector(connector)->detect_edid = NULL;
990}
991
992static bool
993intel_hdmi_set_edid(struct drm_connector *connector)
994{
995 struct drm_i915_private *dev_priv = to_i915(connector->dev);
996 struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
997 struct intel_encoder *intel_encoder =
998 &hdmi_to_dig_port(intel_hdmi)->base;
999 enum intel_display_power_domain power_domain;
1000 struct edid *edid;
1001 bool connected = false;
985 1002
986 power_domain = intel_display_port_power_domain(intel_encoder); 1003 power_domain = intel_display_port_power_domain(intel_encoder);
987 intel_display_power_get(dev_priv, power_domain); 1004 intel_display_power_get(dev_priv, power_domain);
988 1005
989 intel_hdmi->has_hdmi_sink = false;
990 intel_hdmi->has_audio = false;
991 intel_hdmi->rgb_quant_range_selectable = false;
992 edid = drm_get_edid(connector, 1006 edid = drm_get_edid(connector,
993 intel_gmbus_get_adapter(dev_priv, 1007 intel_gmbus_get_adapter(dev_priv,
994 intel_hdmi->ddc_bus)); 1008 intel_hdmi->ddc_bus));
995 1009
996 if (edid) { 1010 intel_display_power_put(dev_priv, power_domain);
997 if (edid->input & DRM_EDID_INPUT_DIGITAL) { 1011
998 status = connector_status_connected; 1012 to_intel_connector(connector)->detect_edid = edid;
999 if (intel_hdmi->force_audio != HDMI_AUDIO_OFF_DVI) 1013 if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
1000 intel_hdmi->has_hdmi_sink = 1014 intel_hdmi->rgb_quant_range_selectable =
1001 drm_detect_hdmi_monitor(edid); 1015 drm_rgb_quant_range_selectable(edid);
1002 intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
1003 intel_hdmi->rgb_quant_range_selectable =
1004 drm_rgb_quant_range_selectable(edid);
1005 }
1006 kfree(edid);
1007 }
1008 1016
1009 if (status == connector_status_connected) { 1017 intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
1010 if (intel_hdmi->force_audio != HDMI_AUDIO_AUTO) 1018 if (intel_hdmi->force_audio != HDMI_AUDIO_AUTO)
1011 intel_hdmi->has_audio = 1019 intel_hdmi->has_audio =
1012 (intel_hdmi->force_audio == HDMI_AUDIO_ON); 1020 intel_hdmi->force_audio == HDMI_AUDIO_ON;
1013 intel_encoder->type = INTEL_OUTPUT_HDMI; 1021
1022 if (intel_hdmi->force_audio != HDMI_AUDIO_OFF_DVI)
1023 intel_hdmi->has_hdmi_sink =
1024 drm_detect_hdmi_monitor(edid);
1025
1026 connected = true;
1014 } 1027 }
1015 1028
1016 intel_display_power_put(dev_priv, power_domain); 1029 return connected;
1030}
1031
1032static enum drm_connector_status
1033intel_hdmi_detect(struct drm_connector *connector, bool force)
1034{
1035 enum drm_connector_status status;
1036
1037 DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
1038 connector->base.id, connector->name);
1039
1040 intel_hdmi_unset_edid(connector);
1041
1042 if (intel_hdmi_set_edid(connector)) {
1043 struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
1044
1045 hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
1046 status = connector_status_connected;
1047 } else
1048 status = connector_status_disconnected;
1017 1049
1018 return status; 1050 return status;
1019} 1051}
1020 1052
1021static int intel_hdmi_get_modes(struct drm_connector *connector) 1053static void
1054intel_hdmi_force(struct drm_connector *connector)
1022{ 1055{
1023 struct intel_encoder *intel_encoder = intel_attached_encoder(connector); 1056 struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
1024 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&intel_encoder->base);
1025 struct drm_i915_private *dev_priv = connector->dev->dev_private;
1026 enum intel_display_power_domain power_domain;
1027 int ret;
1028 1057
1029 /* We should parse the EDID data and find out if it's an HDMI sink so 1058 DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
1030 * we can send audio to it. 1059 connector->base.id, connector->name);
1031 */
1032 1060
1033 power_domain = intel_display_port_power_domain(intel_encoder); 1061 intel_hdmi_unset_edid(connector);
1034 intel_display_power_get(dev_priv, power_domain);
1035 1062
1036 ret = intel_ddc_get_modes(connector, 1063 if (connector->status != connector_status_connected)
1037 intel_gmbus_get_adapter(dev_priv, 1064 return;
1038 intel_hdmi->ddc_bus));
1039 1065
1040 intel_display_power_put(dev_priv, power_domain); 1066 intel_hdmi_set_edid(connector);
1067 hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
1068}
1041 1069
1042 return ret; 1070static int intel_hdmi_get_modes(struct drm_connector *connector)
1071{
1072 struct edid *edid;
1073
1074 edid = to_intel_connector(connector)->detect_edid;
1075 if (edid == NULL)
1076 return 0;
1077
1078 return intel_connector_update_modes(connector, edid);
1043} 1079}
1044 1080
1045static bool 1081static bool
1046intel_hdmi_detect_audio(struct drm_connector *connector) 1082intel_hdmi_detect_audio(struct drm_connector *connector)
1047{ 1083{
1048 struct intel_encoder *intel_encoder = intel_attached_encoder(connector);
1049 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&intel_encoder->base);
1050 struct drm_i915_private *dev_priv = connector->dev->dev_private;
1051 enum intel_display_power_domain power_domain;
1052 struct edid *edid;
1053 bool has_audio = false; 1084 bool has_audio = false;
1085 struct edid *edid;
1054 1086
1055 power_domain = intel_display_port_power_domain(intel_encoder); 1087 edid = to_intel_connector(connector)->detect_edid;
1056 intel_display_power_get(dev_priv, power_domain); 1088 if (edid && edid->input & DRM_EDID_INPUT_DIGITAL)
1057 1089 has_audio = drm_detect_monitor_audio(edid);
1058 edid = drm_get_edid(connector,
1059 intel_gmbus_get_adapter(dev_priv,
1060 intel_hdmi->ddc_bus));
1061 if (edid) {
1062 if (edid->input & DRM_EDID_INPUT_DIGITAL)
1063 has_audio = drm_detect_monitor_audio(edid);
1064 kfree(edid);
1065 }
1066
1067 intel_display_power_put(dev_priv, power_domain);
1068 1090
1069 return has_audio; 1091 return has_audio;
1070} 1092}
@@ -1265,6 +1287,8 @@ static void chv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
1265 enum pipe pipe = intel_crtc->pipe; 1287 enum pipe pipe = intel_crtc->pipe;
1266 u32 val; 1288 u32 val;
1267 1289
1290 intel_hdmi_prepare(encoder);
1291
1268 mutex_lock(&dev_priv->dpio_lock); 1292 mutex_lock(&dev_priv->dpio_lock);
1269 1293
1270 /* program left/right clock distribution */ 1294 /* program left/right clock distribution */
@@ -1434,8 +1458,8 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
1434 1458
1435 for (i = 0; i < 4; i++) { 1459 for (i = 0; i < 4; i++) {
1436 val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i)); 1460 val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i));
1437 val &= ~DPIO_SWING_MARGIN_MASK; 1461 val &= ~DPIO_SWING_MARGIN000_MASK;
1438 val |= 102 << DPIO_SWING_MARGIN_SHIFT; 1462 val |= 102 << DPIO_SWING_MARGIN000_SHIFT;
1439 vlv_dpio_write(dev_priv, pipe, CHV_TX_DW2(ch, i), val); 1463 vlv_dpio_write(dev_priv, pipe, CHV_TX_DW2(ch, i), val);
1440 } 1464 }
1441 1465
@@ -1482,6 +1506,7 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
1482 1506
1483static void intel_hdmi_destroy(struct drm_connector *connector) 1507static void intel_hdmi_destroy(struct drm_connector *connector)
1484{ 1508{
1509 kfree(to_intel_connector(connector)->detect_edid);
1485 drm_connector_cleanup(connector); 1510 drm_connector_cleanup(connector);
1486 kfree(connector); 1511 kfree(connector);
1487} 1512}
@@ -1489,6 +1514,7 @@ static void intel_hdmi_destroy(struct drm_connector *connector)
1489static const struct drm_connector_funcs intel_hdmi_connector_funcs = { 1514static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
1490 .dpms = intel_connector_dpms, 1515 .dpms = intel_connector_dpms,
1491 .detect = intel_hdmi_detect, 1516 .detect = intel_hdmi_detect,
1517 .force = intel_hdmi_force,
1492 .fill_modes = drm_helper_probe_single_connector_modes, 1518 .fill_modes = drm_helper_probe_single_connector_modes,
1493 .set_property = intel_hdmi_set_property, 1519 .set_property = intel_hdmi_set_property,
1494 .destroy = intel_hdmi_destroy, 1520 .destroy = intel_hdmi_destroy,