aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_irq.c
diff options
context:
space:
mode:
authorBen Widawsky <ben@bwidawsk.net>2012-08-22 14:32:15 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-08-24 10:58:36 -0400
commit050ee91f128bd767b1413383fea6c973aa464c54 (patch)
tree1c16fd49d2935fa9a6b008c6647aef9d7c814806 /drivers/gpu/drm/i915/i915_irq.c
parentd53bd48459a554503e07bc3a4b8bba2b57c2ff48 (diff)
drm/i915: Use new INSTDONE registers (Gen7+)
Using the extracted INSTDONE reading, and our new register definitions, update our hangcheck detection and error collection to use it. This primarily means changing == to memcmp, and changing = to memcpy. Hopefully this will give more info on error dump, and provide more accurate hangcheck detection (both are actually TBD). Also, remove the reading of instdone1 from the ring error collection function, and just crap everything in capture_error_state (that could be split into a separate patch if it wasn't so trivial). v2: Now assuming i915_get_extra_instdone does the memset we can clean up the code a bit (Jani) v3: use ARRAY_SIZE as requested earlier by Jani (didn't change sizeof) Updated commit msg Cc: Jani Nikula <jani.nikula@intel.com> Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b7ec34ed5c30..34dc7158f03c 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1077,12 +1077,25 @@ static void i915_get_extra_instdone(struct drm_device *dev,
1077 struct drm_i915_private *dev_priv = dev->dev_private; 1077 struct drm_i915_private *dev_priv = dev->dev_private;
1078 memset(instdone, 0, sizeof(*instdone) * I915_NUM_INSTDONE_REG); 1078 memset(instdone, 0, sizeof(*instdone) * I915_NUM_INSTDONE_REG);
1079 1079
1080 if (INTEL_INFO(dev)->gen < 4) { 1080 switch(INTEL_INFO(dev)->gen) {
1081 case 2:
1082 case 3:
1081 instdone[0] = I915_READ(INSTDONE); 1083 instdone[0] = I915_READ(INSTDONE);
1082 instdone[1] = 0; 1084 break;
1083 } else { 1085 case 4:
1086 case 5:
1087 case 6:
1084 instdone[0] = I915_READ(INSTDONE_I965); 1088 instdone[0] = I915_READ(INSTDONE_I965);
1085 instdone[1] = I915_READ(INSTDONE1); 1089 instdone[1] = I915_READ(INSTDONE1);
1090 break;
1091 default:
1092 WARN_ONCE(1, "Unsupported platform\n");
1093 case 7:
1094 instdone[0] = I915_READ(GEN7_INSTDONE_1);
1095 instdone[1] = I915_READ(GEN7_SC_INSTDONE);
1096 instdone[2] = I915_READ(GEN7_SAMPLER_INSTDONE);
1097 instdone[3] = I915_READ(GEN7_ROW_INSTDONE);
1098 break;
1086 } 1099 }
1087} 1100}
1088 1101
@@ -1108,10 +1121,8 @@ static void i915_record_ring_state(struct drm_device *dev,
1108 error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base)); 1121 error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base));
1109 error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base)); 1122 error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base));
1110 error->instps[ring->id] = I915_READ(RING_INSTPS(ring->mmio_base)); 1123 error->instps[ring->id] = I915_READ(RING_INSTPS(ring->mmio_base));
1111 if (ring->id == RCS) { 1124 if (ring->id == RCS)
1112 error->instdone1 = I915_READ(INSTDONE1);
1113 error->bbaddr = I915_READ64(BB_ADDR); 1125 error->bbaddr = I915_READ64(BB_ADDR);
1114 }
1115 } else { 1126 } else {
1116 error->faddr[ring->id] = I915_READ(DMA_FADD_I8XX); 1127 error->faddr[ring->id] = I915_READ(DMA_FADD_I8XX);
1117 error->ipeir[ring->id] = I915_READ(IPEIR); 1128 error->ipeir[ring->id] = I915_READ(IPEIR);
@@ -1230,6 +1241,8 @@ static void i915_capture_error_state(struct drm_device *dev)
1230 if (INTEL_INFO(dev)->gen == 7) 1241 if (INTEL_INFO(dev)->gen == 7)
1231 error->err_int = I915_READ(GEN7_ERR_INT); 1242 error->err_int = I915_READ(GEN7_ERR_INT);
1232 1243
1244 i915_get_extra_instdone(dev, error->extra_instdone);
1245
1233 i915_gem_record_fences(dev, error); 1246 i915_gem_record_fences(dev, error);
1234 i915_gem_record_rings(dev, error); 1247 i915_gem_record_rings(dev, error);
1235 1248
@@ -1307,7 +1320,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev)
1307 struct drm_i915_private *dev_priv = dev->dev_private; 1320 struct drm_i915_private *dev_priv = dev->dev_private;
1308 uint32_t instdone[I915_NUM_INSTDONE_REG]; 1321 uint32_t instdone[I915_NUM_INSTDONE_REG];
1309 u32 eir = I915_READ(EIR); 1322 u32 eir = I915_READ(EIR);
1310 int pipe; 1323 int pipe, i;
1311 1324
1312 if (!eir) 1325 if (!eir)
1313 return; 1326 return;
@@ -1322,9 +1335,9 @@ static void i915_report_and_clear_eir(struct drm_device *dev)
1322 1335
1323 pr_err(" IPEIR: 0x%08x\n", I915_READ(IPEIR_I965)); 1336 pr_err(" IPEIR: 0x%08x\n", I915_READ(IPEIR_I965));
1324 pr_err(" IPEHR: 0x%08x\n", I915_READ(IPEHR_I965)); 1337 pr_err(" IPEHR: 0x%08x\n", I915_READ(IPEHR_I965));
1325 pr_err(" INSTDONE: 0x%08x\n", instdone[0]); 1338 for (i = 0; i < ARRAY_SIZE(instdone); i++)
1339 pr_err(" INSTDONE_%d: 0x%08x\n", i, instdone[i]);
1326 pr_err(" INSTPS: 0x%08x\n", I915_READ(INSTPS)); 1340 pr_err(" INSTPS: 0x%08x\n", I915_READ(INSTPS));
1327 pr_err(" INSTDONE1: 0x%08x\n", instdone[1]);
1328 pr_err(" ACTHD: 0x%08x\n", I915_READ(ACTHD_I965)); 1341 pr_err(" ACTHD: 0x%08x\n", I915_READ(ACTHD_I965));
1329 I915_WRITE(IPEIR_I965, ipeir); 1342 I915_WRITE(IPEIR_I965, ipeir);
1330 POSTING_READ(IPEIR_I965); 1343 POSTING_READ(IPEIR_I965);
@@ -1358,12 +1371,13 @@ static void i915_report_and_clear_eir(struct drm_device *dev)
1358 if (eir & I915_ERROR_INSTRUCTION) { 1371 if (eir & I915_ERROR_INSTRUCTION) {
1359 pr_err("instruction error\n"); 1372 pr_err("instruction error\n");
1360 pr_err(" INSTPM: 0x%08x\n", I915_READ(INSTPM)); 1373 pr_err(" INSTPM: 0x%08x\n", I915_READ(INSTPM));
1374 for (i = 0; i < ARRAY_SIZE(instdone); i++)
1375 pr_err(" INSTDONE_%d: 0x%08x\n", i, instdone[i]);
1361 if (INTEL_INFO(dev)->gen < 4) { 1376 if (INTEL_INFO(dev)->gen < 4) {
1362 u32 ipeir = I915_READ(IPEIR); 1377 u32 ipeir = I915_READ(IPEIR);
1363 1378
1364 pr_err(" IPEIR: 0x%08x\n", I915_READ(IPEIR)); 1379 pr_err(" IPEIR: 0x%08x\n", I915_READ(IPEIR));
1365 pr_err(" IPEHR: 0x%08x\n", I915_READ(IPEHR)); 1380 pr_err(" IPEHR: 0x%08x\n", I915_READ(IPEHR));
1366 pr_err(" INSTDONE: 0x%08x\n", instdone[0]);
1367 pr_err(" ACTHD: 0x%08x\n", I915_READ(ACTHD)); 1381 pr_err(" ACTHD: 0x%08x\n", I915_READ(ACTHD));
1368 I915_WRITE(IPEIR, ipeir); 1382 I915_WRITE(IPEIR, ipeir);
1369 POSTING_READ(IPEIR); 1383 POSTING_READ(IPEIR);
@@ -1372,9 +1386,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev)
1372 1386
1373 pr_err(" IPEIR: 0x%08x\n", I915_READ(IPEIR_I965)); 1387 pr_err(" IPEIR: 0x%08x\n", I915_READ(IPEIR_I965));
1374 pr_err(" IPEHR: 0x%08x\n", I915_READ(IPEHR_I965)); 1388 pr_err(" IPEHR: 0x%08x\n", I915_READ(IPEHR_I965));
1375 pr_err(" INSTDONE: 0x%08x\n", instdone[0]);
1376 pr_err(" INSTPS: 0x%08x\n", I915_READ(INSTPS)); 1389 pr_err(" INSTPS: 0x%08x\n", I915_READ(INSTPS));
1377 pr_err(" INSTDONE1: 0x%08x\n", instdone[1]);
1378 pr_err(" ACTHD: 0x%08x\n", I915_READ(ACTHD_I965)); 1390 pr_err(" ACTHD: 0x%08x\n", I915_READ(ACTHD_I965));
1379 I915_WRITE(IPEIR_I965, ipeir); 1391 I915_WRITE(IPEIR_I965, ipeir);
1380 POSTING_READ(IPEIR_I965); 1392 POSTING_READ(IPEIR_I965);
@@ -1718,18 +1730,15 @@ void i915_hangcheck_elapsed(unsigned long data)
1718 } 1730 }
1719 1731
1720 i915_get_extra_instdone(dev, instdone); 1732 i915_get_extra_instdone(dev, instdone);
1721
1722 if (memcmp(dev_priv->last_acthd, acthd, sizeof(acthd)) == 0 && 1733 if (memcmp(dev_priv->last_acthd, acthd, sizeof(acthd)) == 0 &&
1723 dev_priv->last_instdone == instdone[0] && 1734 memcmp(dev_priv->prev_instdone, instdone, sizeof(instdone)) == 0) {
1724 dev_priv->last_instdone1 == instdone[1]) {
1725 if (i915_hangcheck_hung(dev)) 1735 if (i915_hangcheck_hung(dev))
1726 return; 1736 return;
1727 } else { 1737 } else {
1728 dev_priv->hangcheck_count = 0; 1738 dev_priv->hangcheck_count = 0;
1729 1739
1730 memcpy(dev_priv->last_acthd, acthd, sizeof(acthd)); 1740 memcpy(dev_priv->last_acthd, acthd, sizeof(acthd));
1731 dev_priv->last_instdone = instdone[0]; 1741 memcpy(dev_priv->prev_instdone, instdone, sizeof(instdone));
1732 dev_priv->last_instdone1 = instdone[1];
1733 } 1742 }
1734 1743
1735repeat: 1744repeat: