summaryrefslogtreecommitdiffstats
path: root/kernel/drivers/gpu/drm/i915
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/drivers/gpu/drm/i915')
-rw-r--r--kernel/drivers/gpu/drm/i915/i915_drv.c15
-rw-r--r--kernel/drivers/gpu/drm/i915/i915_drv.h10
-rw-r--r--kernel/drivers/gpu/drm/i915/i915_gem_execbuffer.c2
-rw-r--r--kernel/drivers/gpu/drm/i915/intel_display.c29
-rw-r--r--kernel/drivers/gpu/drm/i915/intel_dp.c11
-rw-r--r--kernel/drivers/gpu/drm/i915/intel_dsi.c9
6 files changed, 42 insertions, 34 deletions
diff --git a/kernel/drivers/gpu/drm/i915/i915_drv.c b/kernel/drivers/gpu/drm/i915/i915_drv.c
index a19d2c71e..fb91df163 100644
--- a/kernel/drivers/gpu/drm/i915/i915_drv.c
+++ b/kernel/drivers/gpu/drm/i915/i915_drv.c
@@ -647,15 +647,18 @@ static int i915_drm_suspend_late(struct drm_device *drm_dev, bool hibernation)
pci_disable_device(drm_dev->pdev);
/*
- * During hibernation on some GEN4 platforms the BIOS may try to access
+ * During hibernation on some platforms the BIOS may try to access
* the device even though it's already in D3 and hang the machine. So
* leave the device in D0 on those platforms and hope the BIOS will
- * power down the device properly. Platforms where this was seen:
- * Lenovo Thinkpad X301, X61s
+ * power down the device properly. The issue was seen on multiple old
+ * GENs with different BIOS vendors, so having an explicit blacklist
+ * is inpractical; apply the workaround on everything pre GEN6. The
+ * platforms where the issue was seen:
+ * Lenovo Thinkpad X301, X61s, X60, T60, X41
+ * Fujitsu FSC S7110
+ * Acer Aspire 1830T
*/
- if (!(hibernation &&
- drm_dev->pdev->subsystem_vendor == PCI_VENDOR_ID_LENOVO &&
- INTEL_INFO(dev_priv)->gen == 4))
+ if (!(hibernation && INTEL_INFO(dev_priv)->gen < 6))
pci_set_power_state(drm_dev->pdev, PCI_D3hot);
return 0;
diff --git a/kernel/drivers/gpu/drm/i915/i915_drv.h b/kernel/drivers/gpu/drm/i915/i915_drv.h
index 683a9b004..7d53d7e15 100644
--- a/kernel/drivers/gpu/drm/i915/i915_drv.h
+++ b/kernel/drivers/gpu/drm/i915/i915_drv.h
@@ -3190,13 +3190,13 @@ int intel_freq_opcode(struct drm_i915_private *dev_priv, int val);
#define I915_READ64(reg) dev_priv->uncore.funcs.mmio_readq(dev_priv, (reg), true)
#define I915_READ64_2x32(lower_reg, upper_reg) ({ \
- u32 upper, lower, tmp; \
- tmp = I915_READ(upper_reg); \
+ u32 upper, lower, old_upper, loop = 0; \
+ upper = I915_READ(upper_reg); \
do { \
- upper = tmp; \
+ old_upper = upper; \
lower = I915_READ(lower_reg); \
- tmp = I915_READ(upper_reg); \
- } while (upper != tmp); \
+ upper = I915_READ(upper_reg); \
+ } while (upper != old_upper && loop++ < 2); \
(u64)upper << 32 | lower; })
#define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg)
diff --git a/kernel/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/kernel/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index a3eadb970..a67a351e8 100644
--- a/kernel/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/kernel/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1026,6 +1026,7 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas,
u32 old_read = obj->base.read_domains;
u32 old_write = obj->base.write_domain;
+ obj->dirty = 1; /* be paranoid */
obj->base.write_domain = obj->base.pending_write_domain;
if (obj->base.write_domain == 0)
obj->base.pending_read_domains |= obj->base.read_domains;
@@ -1033,7 +1034,6 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas,
i915_vma_move_to_active(vma, ring);
if (obj->base.write_domain) {
- obj->dirty = 1;
i915_gem_request_assign(&obj->last_write_req, req);
intel_fb_obj_invalidate(obj, ring, ORIGIN_CS);
diff --git a/kernel/drivers/gpu/drm/i915/intel_display.c b/kernel/drivers/gpu/drm/i915/intel_display.c
index 4021633ca..338d1de57 100644
--- a/kernel/drivers/gpu/drm/i915/intel_display.c
+++ b/kernel/drivers/gpu/drm/i915/intel_display.c
@@ -13781,6 +13781,24 @@ void intel_modeset_init(struct drm_device *dev)
if (INTEL_INFO(dev)->num_pipes == 0)
return;
+ /*
+ * There may be no VBT; and if the BIOS enabled SSC we can
+ * just keep using it to avoid unnecessary flicker. Whereas if the
+ * BIOS isn't using it, don't assume it will work even if the VBT
+ * indicates as much.
+ */
+ if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
+ bool bios_lvds_use_ssc = !!(I915_READ(PCH_DREF_CONTROL) &
+ DREF_SSC1_ENABLE);
+
+ if (dev_priv->vbt.lvds_use_ssc != bios_lvds_use_ssc) {
+ DRM_DEBUG_KMS("SSC %sabled by BIOS, overriding VBT which says %sabled\n",
+ bios_lvds_use_ssc ? "en" : "dis",
+ dev_priv->vbt.lvds_use_ssc ? "en" : "dis");
+ dev_priv->vbt.lvds_use_ssc = bios_lvds_use_ssc;
+ }
+ }
+
intel_init_display(dev);
intel_init_audio(dev);
@@ -14266,7 +14284,6 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
void intel_modeset_gem_init(struct drm_device *dev)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *c;
struct drm_i915_gem_object *obj;
int ret;
@@ -14275,16 +14292,6 @@ void intel_modeset_gem_init(struct drm_device *dev)
intel_init_gt_powersave(dev);
mutex_unlock(&dev->struct_mutex);
- /*
- * There may be no VBT; and if the BIOS enabled SSC we can
- * just keep using it to avoid unnecessary flicker. Whereas if the
- * BIOS isn't using it, don't assume it will work even if the VBT
- * indicates as much.
- */
- if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
- dev_priv->vbt.lvds_use_ssc = !!(I915_READ(PCH_DREF_CONTROL) &
- DREF_SSC1_ENABLE);
-
intel_modeset_init_hw(dev);
intel_setup_overlay(dev);
diff --git a/kernel/drivers/gpu/drm/i915/intel_dp.c b/kernel/drivers/gpu/drm/i915/intel_dp.c
index b1fe32b11..fb2983f77 100644
--- a/kernel/drivers/gpu/drm/i915/intel_dp.c
+++ b/kernel/drivers/gpu/drm/i915/intel_dp.c
@@ -4691,9 +4691,12 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
intel_dp_probe_oui(intel_dp);
- if (!intel_dp_probe_mst(intel_dp))
+ if (!intel_dp_probe_mst(intel_dp)) {
+ drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+ intel_dp_check_link_status(intel_dp);
+ drm_modeset_unlock(&dev->mode_config.connection_mutex);
goto mst_fail;
-
+ }
} else {
if (intel_dp->is_mst) {
if (intel_dp_check_mst_status(intel_dp) == -EINVAL)
@@ -4701,10 +4704,6 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
}
if (!intel_dp->is_mst) {
- /*
- * we'll check the link status via the normal hot plug path later -
- * but for short hpds we should check it now
- */
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
intel_dp_check_link_status(intel_dp);
drm_modeset_unlock(&dev->mode_config.connection_mutex);
diff --git a/kernel/drivers/gpu/drm/i915/intel_dsi.c b/kernel/drivers/gpu/drm/i915/intel_dsi.c
index 51966426a..c7a0b8d8f 100644
--- a/kernel/drivers/gpu/drm/i915/intel_dsi.c
+++ b/kernel/drivers/gpu/drm/i915/intel_dsi.c
@@ -1036,11 +1036,7 @@ void intel_dsi_init(struct drm_device *dev)
intel_connector->unregister = intel_connector_unregister;
/* Pipe A maps to MIPI DSI port A, pipe B maps to MIPI DSI port C */
- if (dev_priv->vbt.dsi.config->dual_link) {
- /* XXX: does dual link work on either pipe? */
- intel_encoder->crtc_mask = (1 << PIPE_A);
- intel_dsi->ports = ((1 << PORT_A) | (1 << PORT_C));
- } else if (dev_priv->vbt.dsi.port == DVO_PORT_MIPIA) {
+ if (dev_priv->vbt.dsi.port == DVO_PORT_MIPIA) {
intel_encoder->crtc_mask = (1 << PIPE_A);
intel_dsi->ports = (1 << PORT_A);
} else if (dev_priv->vbt.dsi.port == DVO_PORT_MIPIC) {
@@ -1048,6 +1044,9 @@ void intel_dsi_init(struct drm_device *dev)
intel_dsi->ports = (1 << PORT_C);
}
+ if (dev_priv->vbt.dsi.config->dual_link)
+ intel_dsi->ports = ((1 << PORT_A) | (1 << PORT_C));
+
/* Create a DSI host (and a device) for each port. */
for_each_dsi_port(port, intel_dsi->ports) {
struct intel_dsi_host *host;