gpu: nvgpu: Fix and enable L2 error processing
Terje Bergstrom [Tue, 2 Sep 2014 07:38:55 +0000 (10:38 +0300)]
Fix L2 error processing to look into interrupts in each L2 and slice.
Enable L2 error interrupts.

Bug 1549451

Change-Id: If6dd77f1333426a10b6a148c9432c12df8d879c7
Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-on: http://git-master/r/494656
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Deepak Nibade <dnibade@nvidia.com>

drivers/gpu/nvgpu/gm20b/hw_ltc_gm20b.h
drivers/gpu/nvgpu/gm20b/hw_mc_gm20b.h
drivers/gpu/nvgpu/gm20b/ltc_gm20b.c

index 1bc024b..8cef53d 100644 (file)
@@ -122,10 +122,6 @@ static inline u32 ltc_ltcs_ltss_cbc_ctrl2_clear_lower_bound_f(u32 v)
 {
        return (v & 0x1ffff) << 0;
 }
-static inline u32 ltc_ltcs_ltss_intr_r(void)
-{
-       return 0x0017e20c;
-}
 static inline u32 ltc_ltcs_ltss_cbc_ctrl3_r(void)
 {
        return 0x0017e274;
@@ -274,9 +270,17 @@ static inline u32 ltc_ltc1_ltss_g_elpg_flush_pending_f(void)
 {
        return 0x1;
 }
-static inline u32 ltc_ltc0_ltss_intr_r(void)
+static inline u32 ltc_ltcs_ltss_intr_r(void)
+{
+       return 0x0017e20c;
+}
+static inline u32 ltc_ltcs_ltss_intr_en_evicted_cb_m(void)
+{
+       return 0x1 << 20;
+}
+static inline u32 ltc_ltc0_lts0_intr_r(void)
 {
-       return 0x0014020c;
+       return 0x0014040c;
 }
 static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_r(void)
 {
index e978adf..1b74167 100644 (file)
@@ -186,6 +186,10 @@ static inline u32 mc_enable_hub_enabled_f(void)
 {
        return 0x20000000;
 }
+static inline u32 mc_intr_ltc_r(void)
+{
+       return 0x0000017c;
+}
 static inline u32 mc_enable_pb_r(void)
 {
        return 0x00000204;
index c265df0..0548105 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/types.h>
 #include <linux/jiffies.h>
 
+#include "hw_mc_gm20b.h"
 #include "hw_ltc_gm20b.h"
 #include "hw_top_gm20b.h"
 #include "hw_proj_gm20b.h"
@@ -172,6 +173,8 @@ out:
 
 static void gm20b_ltc_init_fs_state(struct gk20a *g)
 {
+       u32 reg;
+
        gk20a_dbg_info("initialize gm20b l2");
 
        g->max_ltc_count = gk20a_readl(g, top_num_ltcs_r());
@@ -188,16 +191,34 @@ static void gm20b_ltc_init_fs_state(struct gk20a *g)
                     ltc_ltcs_ltss_dstg_cfg0_vdc_4to2_disable_m());
 
        /* Disable LTC interrupts */
-       gk20a_writel(g, ltc_ltcs_ltss_intr_r(), 0);
+       reg = gk20a_readl(g, ltc_ltcs_ltss_intr_r());
+       reg &= ~(1<<20);
+       gk20a_writel(g, ltc_ltcs_ltss_intr_r(), reg);
 }
 
 void gm20b_ltc_isr(struct gk20a *g)
 {
-       u32 intr;
+       u32 mc_intr, ltc_intr;
+       int ltc, slice;
 
-       intr = gk20a_readl(g, ltc_ltc0_ltss_intr_r());
-       gk20a_err(dev_from_gk20a(g), "ltc: %08x\n", intr);
-       gk20a_writel(g, ltc_ltc0_ltss_intr_r(), intr);
+       mc_intr = gk20a_readl(g, mc_intr_ltc_r());
+       gk20a_err(dev_from_gk20a(g), "mc_ltc_intr: %08x",
+                 mc_intr);
+       for (ltc = 0; ltc < g->ltc_count; ltc++) {
+               if ((mc_intr & 1 << ltc) == 0)
+                       continue;
+               for (slice = 0; slice < g->gr.slices_per_ltc; slice++) {
+                       ltc_intr = gk20a_readl(g, ltc_ltc0_lts0_intr_r() +
+                                          proj_ltc_stride_v() * ltc +
+                                          proj_lts_stride_v() * slice);
+                       gk20a_err(dev_from_gk20a(g), "ltc%d, slice %d: %08x",
+                                 ltc, slice, ltc_intr);
+                       gk20a_writel(g, ltc_ltc0_lts0_intr_r() +
+                                          proj_ltc_stride_v() * ltc +
+                                          proj_lts_stride_v() * slice,
+                                    ltc_intr);
+               }
+       }
 }
 
 static void gm20b_ltc_g_elpg_flush_locked(struct gk20a *g)