aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-05-04 22:12:09 -0400
committerDave Airlie <airlied@redhat.com>2016-05-04 22:12:09 -0400
commitfca097169faf8b9cfe92d8926da7a1fa2d3cd452 (patch)
tree00d96d041adc9f3a61fb94c5e6bb51eada5ff80d /drivers/gpu
parent80623de03b97efef8df4c8067ab606585663e042 (diff)
parent4ea3959018d09edfa36a9e7b5ccdbd4ec4b99e49 (diff)
Merge tag 'drm-intel-fixes-2016-05-02' of git://anongit.freedesktop.org/drm-intel into drm-fixes
i915 fixes for 4.6. A bit more than I'd like at this stage, but OTOH they're all stable material. * tag 'drm-intel-fixes-2016-05-02' of git://anongit.freedesktop.org/drm-intel: drm/i915: Make RPS EI/thresholds multiple of 25 on SNB-BDW drm/i915: Fake HDMI live status drm/i915: Fix eDP low vswing for Broadwell drm/i915/ddi: Fix eDP VDD handling during booting and suspend/resume drm/i915: Fix system resume if PCI device remained enabled drm/i915: Avoid stalling on pending flips for legacy cursor updates
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c32
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h9
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c22
-rw-r--r--drivers/gpu/drm/i915/intel_display.c3
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c4
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c12
7 files changed, 69 insertions, 15 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 30798cbc6fc0..6d2fb3f4ac62 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -792,7 +792,7 @@ static int i915_drm_resume(struct drm_device *dev)
792static int i915_drm_resume_early(struct drm_device *dev) 792static int i915_drm_resume_early(struct drm_device *dev)
793{ 793{
794 struct drm_i915_private *dev_priv = dev->dev_private; 794 struct drm_i915_private *dev_priv = dev->dev_private;
795 int ret = 0; 795 int ret;
796 796
797 /* 797 /*
798 * We have a resume ordering issue with the snd-hda driver also 798 * We have a resume ordering issue with the snd-hda driver also
@@ -803,6 +803,36 @@ static int i915_drm_resume_early(struct drm_device *dev)
803 * FIXME: This should be solved with a special hdmi sink device or 803 * FIXME: This should be solved with a special hdmi sink device or
804 * similar so that power domains can be employed. 804 * similar so that power domains can be employed.
805 */ 805 */
806
807 /*
808 * Note that we need to set the power state explicitly, since we
809 * powered off the device during freeze and the PCI core won't power
810 * it back up for us during thaw. Powering off the device during
811 * freeze is not a hard requirement though, and during the
812 * suspend/resume phases the PCI core makes sure we get here with the
813 * device powered on. So in case we change our freeze logic and keep
814 * the device powered we can also remove the following set power state
815 * call.
816 */
817 ret = pci_set_power_state(dev->pdev, PCI_D0);
818 if (ret) {
819 DRM_ERROR("failed to set PCI D0 power state (%d)\n", ret);
820 goto out;
821 }
822
823 /*
824 * Note that pci_enable_device() first enables any parent bridge
825 * device and only then sets the power state for this device. The
826 * bridge enabling is a nop though, since bridge devices are resumed
827 * first. The order of enabling power and enabling the device is
828 * imposed by the PCI core as described above, so here we preserve the
829 * same order for the freeze/thaw phases.
830 *
831 * TODO: eventually we should remove pci_disable_device() /
832 * pci_enable_enable_device() from suspend/resume. Due to how they
833 * depend on the device enable refcount we can't anyway depend on them
834 * disabling/enabling the device.
835 */
806 if (pci_enable_device(dev->pdev)) { 836 if (pci_enable_device(dev->pdev)) {
807 ret = -EIO; 837 ret = -EIO;
808 goto out; 838 goto out;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index f76cbf3e5d1e..fffdac801d3b 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2907,7 +2907,14 @@ enum skl_disp_power_wells {
2907#define GEN6_RP_STATE_CAP _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5998) 2907#define GEN6_RP_STATE_CAP _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5998)
2908#define BXT_RP_STATE_CAP _MMIO(0x138170) 2908#define BXT_RP_STATE_CAP _MMIO(0x138170)
2909 2909
2910#define INTERVAL_1_28_US(us) (((us) * 100) >> 7) 2910/*
2911 * Make these a multiple of magic 25 to avoid SNB (eg. Dell XPS
2912 * 8300) freezing up around GPU hangs. Looks as if even
2913 * scheduling/timer interrupts start misbehaving if the RPS
2914 * EI/thresholds are "bad", leading to a very sluggish or even
2915 * frozen machine.
2916 */
2917#define INTERVAL_1_28_US(us) roundup(((us) * 100) >> 7, 25)
2911#define INTERVAL_1_33_US(us) (((us) * 3) >> 2) 2918#define INTERVAL_1_33_US(us) (((us) * 3) >> 2)
2912#define INTERVAL_0_833_US(us) (((us) * 6) / 5) 2919#define INTERVAL_0_833_US(us) (((us) * 6) / 5)
2913#define GT_INTERVAL_FROM_US(dev_priv, us) (IS_GEN9(dev_priv) ? \ 2920#define GT_INTERVAL_FROM_US(dev_priv, us) (IS_GEN9(dev_priv) ? \
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 62de9f4bce09..3b57bf06abe8 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -443,9 +443,17 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder)
443 } else if (IS_BROADWELL(dev_priv)) { 443 } else if (IS_BROADWELL(dev_priv)) {
444 ddi_translations_fdi = bdw_ddi_translations_fdi; 444 ddi_translations_fdi = bdw_ddi_translations_fdi;
445 ddi_translations_dp = bdw_ddi_translations_dp; 445 ddi_translations_dp = bdw_ddi_translations_dp;
446 ddi_translations_edp = bdw_ddi_translations_edp; 446
447 if (dev_priv->edp_low_vswing) {
448 ddi_translations_edp = bdw_ddi_translations_edp;
449 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
450 } else {
451 ddi_translations_edp = bdw_ddi_translations_dp;
452 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
453 }
454
447 ddi_translations_hdmi = bdw_ddi_translations_hdmi; 455 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
448 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp); 456
449 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); 457 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
450 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); 458 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
451 hdmi_default_entry = 7; 459 hdmi_default_entry = 7;
@@ -3201,12 +3209,6 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
3201 intel_ddi_clock_get(encoder, pipe_config); 3209 intel_ddi_clock_get(encoder, pipe_config);
3202} 3210}
3203 3211
3204static void intel_ddi_destroy(struct drm_encoder *encoder)
3205{
3206 /* HDMI has nothing special to destroy, so we can go with this. */
3207 intel_dp_encoder_destroy(encoder);
3208}
3209
3210static bool intel_ddi_compute_config(struct intel_encoder *encoder, 3212static bool intel_ddi_compute_config(struct intel_encoder *encoder,
3211 struct intel_crtc_state *pipe_config) 3213 struct intel_crtc_state *pipe_config)
3212{ 3214{
@@ -3225,7 +3227,8 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder,
3225} 3227}
3226 3228
3227static const struct drm_encoder_funcs intel_ddi_funcs = { 3229static const struct drm_encoder_funcs intel_ddi_funcs = {
3228 .destroy = intel_ddi_destroy, 3230 .reset = intel_dp_encoder_reset,
3231 .destroy = intel_dp_encoder_destroy,
3229}; 3232};
3230 3233
3231static struct intel_connector * 3234static struct intel_connector *
@@ -3324,6 +3327,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
3324 intel_encoder->post_disable = intel_ddi_post_disable; 3327 intel_encoder->post_disable = intel_ddi_post_disable;
3325 intel_encoder->get_hw_state = intel_ddi_get_hw_state; 3328 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
3326 intel_encoder->get_config = intel_ddi_get_config; 3329 intel_encoder->get_config = intel_ddi_get_config;
3330 intel_encoder->suspend = intel_dp_encoder_suspend;
3327 3331
3328 intel_dig_port->port = port; 3332 intel_dig_port->port = port;
3329 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & 3333 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6e0d8283daa6..182f84937345 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13351,6 +13351,9 @@ static int intel_atomic_prepare_commit(struct drm_device *dev,
13351 } 13351 }
13352 13352
13353 for_each_crtc_in_state(state, crtc, crtc_state, i) { 13353 for_each_crtc_in_state(state, crtc, crtc_state, i) {
13354 if (state->legacy_cursor_update)
13355 continue;
13356
13354 ret = intel_crtc_wait_for_pending_flips(crtc); 13357 ret = intel_crtc_wait_for_pending_flips(crtc);
13355 if (ret) 13358 if (ret)
13356 return ret; 13359 return ret;
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index f069a82deb57..412a34c39522 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4898,7 +4898,7 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
4898 kfree(intel_dig_port); 4898 kfree(intel_dig_port);
4899} 4899}
4900 4900
4901static void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder) 4901void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder)
4902{ 4902{
4903 struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base); 4903 struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
4904 4904
@@ -4940,7 +4940,7 @@ static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)
4940 edp_panel_vdd_schedule_off(intel_dp); 4940 edp_panel_vdd_schedule_off(intel_dp);
4941} 4941}
4942 4942
4943static void intel_dp_encoder_reset(struct drm_encoder *encoder) 4943void intel_dp_encoder_reset(struct drm_encoder *encoder)
4944{ 4944{
4945 struct intel_dp *intel_dp; 4945 struct intel_dp *intel_dp;
4946 4946
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 4c027d69fac9..7d3af3a72abe 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1238,6 +1238,8 @@ void intel_dp_set_link_params(struct intel_dp *intel_dp,
1238void intel_dp_start_link_train(struct intel_dp *intel_dp); 1238void intel_dp_start_link_train(struct intel_dp *intel_dp);
1239void intel_dp_stop_link_train(struct intel_dp *intel_dp); 1239void intel_dp_stop_link_train(struct intel_dp *intel_dp);
1240void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode); 1240void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
1241void intel_dp_encoder_reset(struct drm_encoder *encoder);
1242void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder);
1241void intel_dp_encoder_destroy(struct drm_encoder *encoder); 1243void intel_dp_encoder_destroy(struct drm_encoder *encoder);
1242int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc); 1244int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc);
1243bool intel_dp_compute_config(struct intel_encoder *encoder, 1245bool intel_dp_compute_config(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index a0d8daed2470..1ab6f687f640 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1415,8 +1415,16 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
1415 hdmi_to_dig_port(intel_hdmi)); 1415 hdmi_to_dig_port(intel_hdmi));
1416 } 1416 }
1417 1417
1418 if (!live_status) 1418 if (!live_status) {
1419 DRM_DEBUG_KMS("Live status not up!"); 1419 DRM_DEBUG_KMS("HDMI live status down\n");
1420 /*
1421 * Live status register is not reliable on all intel platforms.
1422 * So consider live_status only for certain platforms, for
1423 * others, read EDID to determine presence of sink.
1424 */
1425 if (INTEL_INFO(dev_priv)->gen < 7 || IS_IVYBRIDGE(dev_priv))
1426 live_status = true;
1427 }
1420 1428
1421 intel_hdmi_unset_edid(connector); 1429 intel_hdmi_unset_edid(connector);
1422 1430