]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'drm-next-3.20' of git://people.freedesktop.org/~agd5f/linux into drm...
authorDave Airlie <airlied@redhat.com>
Thu, 12 Feb 2015 00:01:51 +0000 (10:01 +1000)
committerDave Airlie <airlied@redhat.com>
Thu, 12 Feb 2015 00:01:51 +0000 (10:01 +1000)
Some radeon fixes for 3.20.

* 'drm-next-3.20' of git://people.freedesktop.org/~agd5f/linux:
  drm/radeon: only enable kv/kb dpm interrupts once v3
  drm/radeon: workaround for CP HW bug on CIK
  drm/radeon: Don't try to enable write-combining without PAT
  drm/radeon: use 0-255 rather than 0-100 for pwm fan range

drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_gem_userptr.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_dsi.c
drivers/gpu/drm/i915/intel_lrc.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_sideband.c
drivers/gpu/drm/i915/intel_uncore.c

index 211d4949a675866924d3707b0f56d4db82dc803c..96e811fe24ca79cd1b6438591cf1eb05379f0edd 100644 (file)
@@ -1223,8 +1223,11 @@ out:
 static int i915_hangcheck_info(struct seq_file *m, void *unused)
 {
        struct drm_info_node *node = m->private;
-       struct drm_i915_private *dev_priv = to_i915(node->minor->dev);
+       struct drm_device *dev = node->minor->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_engine_cs *ring;
+       u64 acthd[I915_NUM_RINGS];
+       u32 seqno[I915_NUM_RINGS];
        int i;
 
        if (!i915.enable_hangcheck) {
@@ -1232,6 +1235,15 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused)
                return 0;
        }
 
+       intel_runtime_pm_get(dev_priv);
+
+       for_each_ring(ring, dev_priv, i) {
+               seqno[i] = ring->get_seqno(ring, false);
+               acthd[i] = intel_ring_get_active_head(ring);
+       }
+
+       intel_runtime_pm_put(dev_priv);
+
        if (delayed_work_pending(&dev_priv->gpu_error.hangcheck_work)) {
                seq_printf(m, "Hangcheck active, fires in %dms\n",
                           jiffies_to_msecs(dev_priv->gpu_error.hangcheck_work.timer.expires -
@@ -1242,14 +1254,14 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused)
        for_each_ring(ring, dev_priv, i) {
                seq_printf(m, "%s:\n", ring->name);
                seq_printf(m, "\tseqno = %x [current %x]\n",
-                          ring->hangcheck.seqno, ring->get_seqno(ring, false));
-               seq_printf(m, "\taction = %d\n", ring->hangcheck.action);
-               seq_printf(m, "\tscore = %d\n", ring->hangcheck.score);
+                          ring->hangcheck.seqno, seqno[i]);
                seq_printf(m, "\tACTHD = 0x%08llx [current 0x%08llx]\n",
                           (long long)ring->hangcheck.acthd,
-                          (long long)intel_ring_get_active_head(ring));
+                          (long long)acthd[i]);
                seq_printf(m, "\tmax ACTHD = 0x%08llx\n",
                           (long long)ring->hangcheck.max_acthd);
+               seq_printf(m, "\tscore = %d\n", ring->hangcheck.score);
+               seq_printf(m, "\taction = %d\n", ring->hangcheck.action);
        }
 
        return 0;
index d182058383a9ef7264339101265e511ac8fa0609..1719078c763ac0d140c8fb7a9e954862bd8d3bc7 100644 (file)
@@ -113,7 +113,10 @@ restart:
                        continue;
 
                obj = mo->obj;
-               drm_gem_object_reference(&obj->base);
+
+               if (!kref_get_unless_zero(&obj->base.refcount))
+                       continue;
+
                spin_unlock(&mn->lock);
 
                cancel_userptr(obj);
@@ -149,7 +152,20 @@ static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn,
                        it = interval_tree_iter_first(&mn->objects, start, end);
                if (it != NULL) {
                        obj = container_of(it, struct i915_mmu_object, it)->obj;
-                       drm_gem_object_reference(&obj->base);
+
+                       /* The mmu_object is released late when destroying the
+                        * GEM object so it is entirely possible to gain a
+                        * reference on an object in the process of being freed
+                        * since our serialisation is via the spinlock and not
+                        * the struct_mutex - and consequently use it after it
+                        * is freed and then double free it.
+                        */
+                       if (!kref_get_unless_zero(&obj->base.refcount)) {
+                               spin_unlock(&mn->lock);
+                               serial = 0;
+                               continue;
+                       }
+
                        serial = mn->serial;
                }
                spin_unlock(&mn->lock);
index eea9e366a109e3bf2170be7a7796d80c56adb769..a74aaf9242b965797114c0d775171b181ffdd423 100644 (file)
@@ -3521,8 +3521,6 @@ intel_dp_link_down(struct intel_dp *intel_dp)
        enum port port = intel_dig_port->port;
        struct drm_device *dev = intel_dig_port->base.base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_crtc *intel_crtc =
-               to_intel_crtc(intel_dig_port->base.base.crtc);
        uint32_t DP = intel_dp->DP;
 
        if (WARN_ON(HAS_DDI(dev)))
@@ -3547,8 +3545,6 @@ intel_dp_link_down(struct intel_dp *intel_dp)
 
        if (HAS_PCH_IBX(dev) &&
            I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) {
-               struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
-
                /* Hardware workaround: leaving our transcoder select
                 * set to transcoder B while it's off will prevent the
                 * corresponding HDMI output on transcoder A.
@@ -3559,18 +3555,7 @@ intel_dp_link_down(struct intel_dp *intel_dp)
                 */
                DP &= ~DP_PIPEB_SELECT;
                I915_WRITE(intel_dp->output_reg, DP);
-
-               /* Changes to enable or select take place the vblank
-                * after being written.
-                */
-               if (WARN_ON(crtc == NULL)) {
-                       /* We should never try to disable a port without a crtc
-                        * attached. For paranoia keep the code around for a
-                        * bit. */
-                       POSTING_READ(intel_dp->output_reg);
-                       msleep(50);
-               } else
-                       intel_wait_for_vblank(dev, intel_crtc->pipe);
+               POSTING_READ(intel_dp->output_reg);
        }
 
        DP &= ~DP_AUDIO_OUTPUT_ENABLE;
@@ -4446,7 +4431,7 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
                 */
                DRM_DEBUG_KMS("ignoring long hpd on eDP port %c\n",
                              port_name(intel_dig_port->port));
-               return false;
+               return IRQ_HANDLED;
        }
 
        DRM_DEBUG_KMS("got hpd irq on port %c - %s\n",
index ef3df5e3d819fcd4dcdbbc2d3dd3d3b91d8fe548..10ab68457ca885adb3d4125478731fd0816f6553 100644 (file)
@@ -360,12 +360,11 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder)
                I915_WRITE(MIPI_DEVICE_READY(port), ULPS_STATE_ENTER);
                usleep_range(2500, 3000);
 
-               val = I915_READ(MIPI_PORT_CTRL(port));
-
                /* Enable MIPI PHY transparent latch
                 * Common bit for both MIPI Port A & MIPI Port C
                 * No similar bit in MIPI Port C reg
                 */
+               val = I915_READ(MIPI_PORT_CTRL(PORT_A));
                I915_WRITE(MIPI_PORT_CTRL(PORT_A), val | LP_OUTPUT_HOLD);
                usleep_range(1000, 1500);
 
@@ -543,10 +542,10 @@ static void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
                                                        == 0x00000), 30))
                        DRM_ERROR("DSI LP not going Low\n");
 
-               val = I915_READ(MIPI_PORT_CTRL(port));
                /* Disable MIPI PHY transparent latch
                 * Common bit for both MIPI Port A & MIPI Port C
                 */
+               val = I915_READ(MIPI_PORT_CTRL(PORT_A));
                I915_WRITE(MIPI_PORT_CTRL(PORT_A), val & ~LP_OUTPUT_HOLD);
                usleep_range(1000, 1500);
 
index a94346fee16027aa8bdc4a6e3abb40b365a4c828..0f358c5999ec8e0c8771a3d932447d281748a8b1 100644 (file)
@@ -1211,15 +1211,17 @@ static int gen8_emit_flush(struct intel_ringbuffer *ringbuf,
 
        cmd = MI_FLUSH_DW + 1;
 
-       if (ring == &dev_priv->ring[VCS]) {
-               if (invalidate_domains & I915_GEM_GPU_DOMAINS)
-                       cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD |
-                               MI_FLUSH_DW_STORE_INDEX |
-                               MI_FLUSH_DW_OP_STOREDW;
-       } else {
-               if (invalidate_domains & I915_GEM_DOMAIN_RENDER)
-                       cmd |= MI_INVALIDATE_TLB | MI_FLUSH_DW_STORE_INDEX |
-                               MI_FLUSH_DW_OP_STOREDW;
+       /* We always require a command barrier so that subsequent
+        * commands, such as breadcrumb interrupts, are strictly ordered
+        * wrt the contents of the write cache being flushed to memory
+        * (and thus being coherent from the CPU).
+        */
+       cmd |= MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW;
+
+       if (invalidate_domains & I915_GEM_GPU_DOMAINS) {
+               cmd |= MI_INVALIDATE_TLB;
+               if (ring == &dev_priv->ring[VCS])
+                       cmd |= MI_INVALIDATE_BSD;
        }
 
        intel_logical_ring_emit(ringbuf, cmd);
index 6ece663f3394bca7ed2bc7b317520ad54b2c1a56..24d77ddcc5f47bc648309068cb81f69464aeb305 100644 (file)
@@ -4005,7 +4005,10 @@ static void gen6_init_rps_frequencies(struct drm_device *dev)
                                        &ddcc_status);
                if (0 == ret)
                        dev_priv->rps.efficient_freq =
-                               (ddcc_status >> 8) & 0xff;
+                               clamp_t(u8,
+                                       ((ddcc_status >> 8) & 0xff),
+                                       dev_priv->rps.min_freq,
+                                       dev_priv->rps.max_freq);
        }
 
        /* Preserve min/max settings in case of re-init */
index 0bd3976d88e1197740a0f065175d67acaef43cb9..e5b3c6dbd46780798e1607b0f3390db5465ecbd5 100644 (file)
@@ -2240,6 +2240,14 @@ static int gen6_bsd_ring_flush(struct intel_engine_cs *ring,
        cmd = MI_FLUSH_DW;
        if (INTEL_INFO(ring->dev)->gen >= 8)
                cmd += 1;
+
+       /* We always require a command barrier so that subsequent
+        * commands, such as breadcrumb interrupts, are strictly ordered
+        * wrt the contents of the write cache being flushed to memory
+        * (and thus being coherent from the CPU).
+        */
+       cmd |= MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW;
+
        /*
         * Bspec vol 1c.5 - video engine command streamer:
         * "If ENABLED, all TLBs will be invalidated once the flush
@@ -2247,8 +2255,8 @@ static int gen6_bsd_ring_flush(struct intel_engine_cs *ring,
         * Post-Sync Operation field is a value of 1h or 3h."
         */
        if (invalidate & I915_GEM_GPU_DOMAINS)
-               cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD |
-                       MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW;
+               cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD;
+
        intel_ring_emit(ring, cmd);
        intel_ring_emit(ring, I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT);
        if (INTEL_INFO(ring->dev)->gen >= 8) {
@@ -2344,6 +2352,14 @@ static int gen6_ring_flush(struct intel_engine_cs *ring,
        cmd = MI_FLUSH_DW;
        if (INTEL_INFO(ring->dev)->gen >= 8)
                cmd += 1;
+
+       /* We always require a command barrier so that subsequent
+        * commands, such as breadcrumb interrupts, are strictly ordered
+        * wrt the contents of the write cache being flushed to memory
+        * (and thus being coherent from the CPU).
+        */
+       cmd |= MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW;
+
        /*
         * Bspec vol 1c.3 - blitter engine command streamer:
         * "If ENABLED, all TLBs will be invalidated once the flush
@@ -2351,8 +2367,7 @@ static int gen6_ring_flush(struct intel_engine_cs *ring,
         * Post-Sync Operation field is a value of 1h or 3h."
         */
        if (invalidate & I915_GEM_DOMAIN_RENDER)
-               cmd |= MI_INVALIDATE_TLB | MI_FLUSH_DW_STORE_INDEX |
-                       MI_FLUSH_DW_OP_STOREDW;
+               cmd |= MI_INVALIDATE_TLB;
        intel_ring_emit(ring, cmd);
        intel_ring_emit(ring, I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT);
        if (INTEL_INFO(ring->dev)->gen >= 8) {
index 3c42eeffa3cb4550fef0205969719d6633cd8c0d..693ce82819709f2dc1b0130c81834c39579cb45c 100644 (file)
@@ -82,7 +82,7 @@ u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr)
        WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
 
        mutex_lock(&dev_priv->dpio_lock);
-       vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT,
+       vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
                        SB_CRRDDA_NP, addr, &val);
        mutex_unlock(&dev_priv->dpio_lock);
 
@@ -94,7 +94,7 @@ void vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val)
        WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
 
        mutex_lock(&dev_priv->dpio_lock);
-       vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT,
+       vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
                        SB_CRWRDA_NP, addr, &val);
        mutex_unlock(&dev_priv->dpio_lock);
 }
@@ -103,7 +103,7 @@ u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg)
 {
        u32 val = 0;
 
-       vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_BUNIT,
+       vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_BUNIT,
                        SB_CRRDDA_NP, reg, &val);
 
        return val;
@@ -111,7 +111,7 @@ u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg)
 
 void vlv_bunit_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
 {
-       vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_BUNIT,
+       vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_BUNIT,
                        SB_CRWRDA_NP, reg, &val);
 }
 
@@ -122,7 +122,7 @@ u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr)
        WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
 
        mutex_lock(&dev_priv->dpio_lock);
-       vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_NC,
+       vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_NC,
                        SB_CRRDDA_NP, addr, &val);
        mutex_unlock(&dev_priv->dpio_lock);
 
@@ -132,56 +132,56 @@ u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr)
 u32 vlv_gpio_nc_read(struct drm_i915_private *dev_priv, u32 reg)
 {
        u32 val = 0;
-       vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPIO_NC,
+       vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_GPIO_NC,
                        SB_CRRDDA_NP, reg, &val);
        return val;
 }
 
 void vlv_gpio_nc_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
 {
-       vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPIO_NC,
+       vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_GPIO_NC,
                        SB_CRWRDA_NP, reg, &val);
 }
 
 u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg)
 {
        u32 val = 0;
-       vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCK,
+       vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_CCK,
                        SB_CRRDDA_NP, reg, &val);
        return val;
 }
 
 void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
 {
-       vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCK,
+       vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_CCK,
                        SB_CRWRDA_NP, reg, &val);
 }
 
 u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg)
 {
        u32 val = 0;
-       vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCU,
+       vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_CCU,
                        SB_CRRDDA_NP, reg, &val);
        return val;
 }
 
 void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
 {
-       vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCU,
+       vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_CCU,
                        SB_CRWRDA_NP, reg, &val);
 }
 
 u32 vlv_gps_core_read(struct drm_i915_private *dev_priv, u32 reg)
 {
        u32 val = 0;
-       vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPS_CORE,
+       vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_GPS_CORE,
                        SB_CRRDDA_NP, reg, &val);
        return val;
 }
 
 void vlv_gps_core_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
 {
-       vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPS_CORE,
+       vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_GPS_CORE,
                        SB_CRWRDA_NP, reg, &val);
 }
 
index 76b60a3538b28d97e659dddbb537c20984a66933..c47a3baa53d5963cdfc1663320ac2e88398f276d 100644 (file)
@@ -166,7 +166,8 @@ fw_domains_reset(struct drm_i915_private *dev_priv, enum forcewake_domains fw_do
        struct intel_uncore_forcewake_domain *d;
        enum forcewake_domain_id id;
 
-       WARN_ON(dev_priv->uncore.fw_domains == 0);
+       if (dev_priv->uncore.fw_domains == 0)
+               return;
 
        for_each_fw_domain_mask(d, fw_domains, dev_priv, id)
                fw_domain_reset(d);
@@ -997,6 +998,9 @@ static void intel_uncore_fw_domains_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
+       if (INTEL_INFO(dev_priv->dev)->gen <= 5)
+               return;
+
        if (IS_GEN9(dev)) {
                dev_priv->uncore.funcs.force_wake_get = fw_domains_get;
                dev_priv->uncore.funcs.force_wake_put = fw_domains_put;
@@ -1069,6 +1073,9 @@ static void intel_uncore_fw_domains_init(struct drm_device *dev)
                fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
                               FORCEWAKE, FORCEWAKE_ACK);
        }
+
+       /* All future platforms are expected to require complex power gating */
+       WARN_ON(dev_priv->uncore.fw_domains == 0);
 }
 
 void intel_uncore_init(struct drm_device *dev)