summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/gv11b/gr_gv11b.c87
-rw-r--r--drivers/gpu/nvgpu/gv11b/gr_gv11b.h8
-rw-r--r--drivers/gpu/nvgpu/gv11b/platform_gv11b_tegra.c59
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/hw/gv11b/hw_gr_gv11b.h72
4 files changed, 225 insertions, 1 deletions
diff --git a/drivers/gpu/nvgpu/gv11b/gr_gv11b.c b/drivers/gpu/nvgpu/gv11b/gr_gv11b.c
index 179c7d33..ad34233c 100644
--- a/drivers/gpu/nvgpu/gv11b/gr_gv11b.c
+++ b/drivers/gpu/nvgpu/gv11b/gr_gv11b.c
@@ -108,6 +108,89 @@ static bool gr_gv11b_is_valid_compute_class(struct gk20a *g, u32 class_num)
108 return valid; 108 return valid;
109} 109}
110 110
111static int gr_gv11b_handle_l1_tag_exception(struct gk20a *g, u32 gpc, u32 tpc,
112 bool *post_event, struct channel_gk20a *fault_ch,
113 u32 *hww_global_esr)
114{
115 u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE);
116 u32 tpc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_STRIDE);
117 u32 offset = gpc_stride * gpc + tpc_in_gpc_stride * tpc;
118 u32 l1_tag_ecc_status, l1_tag_ecc_corrected_err_status = 0;
119 u32 l1_tag_ecc_uncorrected_err_status = 0;
120 u32 l1_tag_corrected_err_count_delta = 0;
121 u32 l1_tag_uncorrected_err_count_delta = 0;
122 bool is_l1_tag_ecc_corrected_total_err_overflow = 0;
123 bool is_l1_tag_ecc_uncorrected_total_err_overflow = 0;
124
125 /* Check for L1 tag ECC errors. */
126 l1_tag_ecc_status = gk20a_readl(g,
127 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_r() + offset);
128 l1_tag_ecc_corrected_err_status = l1_tag_ecc_status &
129 (gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_corrected_err_el1_0_m() |
130 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_corrected_err_el1_1_m() |
131 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_corrected_err_pixrpf_m() |
132 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_corrected_err_miss_fifo_m());
133 l1_tag_ecc_uncorrected_err_status = l1_tag_ecc_status &
134 (gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_uncorrected_err_el1_0_m() |
135 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_uncorrected_err_el1_1_m() |
136 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_uncorrected_err_pixrpf_m() |
137 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_uncorrected_err_miss_fifo_m());
138
139 if ((l1_tag_ecc_corrected_err_status == 0) && (l1_tag_ecc_uncorrected_err_status == 0))
140 return 0;
141
142 l1_tag_corrected_err_count_delta =
143 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_corrected_err_count_total_v(
144 gk20a_readl(g,
145 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_corrected_err_count_r() +
146 offset));
147 l1_tag_uncorrected_err_count_delta =
148 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_uncorrected_err_count_total_v(
149 gk20a_readl(g,
150 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_uncorrected_err_count_r() +
151 offset));
152 is_l1_tag_ecc_corrected_total_err_overflow =
153 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_corrected_err_total_counter_overflow_v(l1_tag_ecc_status);
154 is_l1_tag_ecc_uncorrected_total_err_overflow =
155 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_uncorrected_err_total_counter_overflow_v(l1_tag_ecc_status);
156
157 if ((l1_tag_corrected_err_count_delta > 0) || is_l1_tag_ecc_corrected_total_err_overflow) {
158 gk20a_dbg(gpu_dbg_fn | gpu_dbg_intr,
159 "corrected error (SBE) detected in SM L1 tag! err_mask [%08x] is_overf [%d]",
160 l1_tag_ecc_corrected_err_status, is_l1_tag_ecc_corrected_total_err_overflow);
161
162 /* HW uses 16-bits counter */
163 l1_tag_corrected_err_count_delta +=
164 (is_l1_tag_ecc_corrected_total_err_overflow <<
165 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_corrected_err_count_total_s());
166 g->gr.t19x.ecc_stats.sm_l1_tag_corrected_err_count.counters[tpc] +=
167 l1_tag_corrected_err_count_delta;
168 gk20a_writel(g,
169 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_corrected_err_count_r() + offset,
170 0);
171 }
172 if ((l1_tag_uncorrected_err_count_delta > 0) || is_l1_tag_ecc_uncorrected_total_err_overflow) {
173 gk20a_dbg(gpu_dbg_fn | gpu_dbg_intr,
174 "Uncorrected error (DBE) detected in SM L1 tag! err_mask [%08x] is_overf [%d]",
175 l1_tag_ecc_uncorrected_err_status, is_l1_tag_ecc_uncorrected_total_err_overflow);
176
177 /* HW uses 16-bits counter */
178 l1_tag_uncorrected_err_count_delta +=
179 (is_l1_tag_ecc_uncorrected_total_err_overflow <<
180 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_uncorrected_err_count_total_s());
181 g->gr.t19x.ecc_stats.sm_l1_tag_uncorrected_err_count.counters[tpc] +=
182 l1_tag_uncorrected_err_count_delta;
183 gk20a_writel(g,
184 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_uncorrected_err_count_r() + offset,
185 0);
186 }
187
188 gk20a_writel(g, gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_r() + offset,
189 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_reset_task_f());
190
191 return 0;
192
193}
111 194
112static int gr_gv11b_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, 195static int gr_gv11b_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc,
113 bool *post_event, struct channel_gk20a *fault_ch, 196 bool *post_event, struct channel_gk20a *fault_ch,
@@ -118,7 +201,8 @@ static int gr_gv11b_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc,
118 proj_tpc_in_gpc_stride_v() * tpc; 201 proj_tpc_in_gpc_stride_v() * tpc;
119 u32 lrf_ecc_status; 202 u32 lrf_ecc_status;
120 203
121 gr_gk20a_handle_sm_exception(g, gpc, tpc, post_event, fault_ch, hww_global_esr); 204 /* Check for L1 tag ECC errors. */
205 gr_gv11b_handle_l1_tag_exception(g, gpc, tpc, post_event, fault_ch, hww_global_esr);
122 206
123 /* Check for LRF ECC errors. */ 207 /* Check for LRF ECC errors. */
124 lrf_ecc_status = gk20a_readl(g, 208 lrf_ecc_status = gk20a_readl(g,
@@ -1692,6 +1776,7 @@ void gv11b_init_gr(struct gpu_ops *gops)
1692 gops->gr.pre_process_sm_exception = 1776 gops->gr.pre_process_sm_exception =
1693 gr_gv11b_pre_process_sm_exception; 1777 gr_gv11b_pre_process_sm_exception;
1694 gops->gr.handle_fecs_error = gr_gv11b_handle_fecs_error; 1778 gops->gr.handle_fecs_error = gr_gv11b_handle_fecs_error;
1779 gops->gr.create_gr_sysfs = gr_gv11b_create_sysfs;
1695 gops->gr.setup_rop_mapping = gr_gv11b_setup_rop_mapping; 1780 gops->gr.setup_rop_mapping = gr_gv11b_setup_rop_mapping;
1696 gops->gr.init_sw_veid_bundle = gr_gv11b_init_sw_veid_bundle; 1781 gops->gr.init_sw_veid_bundle = gr_gv11b_init_sw_veid_bundle;
1697 gops->gr.program_zcull_mapping = gr_gv11b_program_zcull_mapping; 1782 gops->gr.program_zcull_mapping = gr_gv11b_program_zcull_mapping;
diff --git a/drivers/gpu/nvgpu/gv11b/gr_gv11b.h b/drivers/gpu/nvgpu/gv11b/gr_gv11b.h
index 9d9f969d..2d6e3d1f 100644
--- a/drivers/gpu/nvgpu/gv11b/gr_gv11b.h
+++ b/drivers/gpu/nvgpu/gv11b/gr_gv11b.h
@@ -35,6 +35,13 @@ enum {
35 VOLTA_DMA_COPY_A = 0xC3B5, 35 VOLTA_DMA_COPY_A = 0xC3B5,
36}; 36};
37 37
38struct gr_t19x {
39 struct {
40 struct gr_gp10b_ecc_stat sm_l1_tag_corrected_err_count;
41 struct gr_gp10b_ecc_stat sm_l1_tag_uncorrected_err_count;
42 } ecc_stats;
43};
44
38#define NVC397_SET_SHADER_EXCEPTIONS 0x1528 45#define NVC397_SET_SHADER_EXCEPTIONS 0x1528
39#define NVC397_SET_CIRCULAR_BUFFER_SIZE 0x1280 46#define NVC397_SET_CIRCULAR_BUFFER_SIZE 0x1280
40#define NVC397_SET_ALPHA_CIRCULAR_BUFFER_SIZE 0x02dc 47#define NVC397_SET_ALPHA_CIRCULAR_BUFFER_SIZE 0x02dc
@@ -48,4 +55,5 @@ int gr_gv11b_alloc_buffer(struct vm_gk20a *vm, size_t size,
48/*zcull*/ 55/*zcull*/
49void gr_gv11b_program_zcull_mapping(struct gk20a *g, u32 zcull_num_entries, 56void gr_gv11b_program_zcull_mapping(struct gk20a *g, u32 zcull_num_entries,
50 u32 *zcull_map_tiles); 57 u32 *zcull_map_tiles);
58void gr_gv11b_create_sysfs(struct device *dev);
51#endif 59#endif
diff --git a/drivers/gpu/nvgpu/gv11b/platform_gv11b_tegra.c b/drivers/gpu/nvgpu/gv11b/platform_gv11b_tegra.c
index 97845035..8ca9dd30 100644
--- a/drivers/gpu/nvgpu/gv11b/platform_gv11b_tegra.c
+++ b/drivers/gpu/nvgpu/gv11b/platform_gv11b_tegra.c
@@ -27,11 +27,13 @@
27#include "tegra/linux/clk.h" 27#include "tegra/linux/clk.h"
28 28
29#include "gp10b/platform_gp10b.h" 29#include "gp10b/platform_gp10b.h"
30#include "tegra/linux/platform_gp10b_tegra.h"
30 31
31#include "tegra/linux/platform_gk20a_tegra.h" 32#include "tegra/linux/platform_gk20a_tegra.h"
32#include "gr_gv11b.h" 33#include "gr_gv11b.h"
33#include "nvgpu_gpuid_t19x.h" 34#include "nvgpu_gpuid_t19x.h"
34 35
36static void gr_gv11b_remove_sysfs(struct device *dev);
35 37
36static int gv11b_tegra_probe(struct device *dev) 38static int gv11b_tegra_probe(struct device *dev)
37{ 39{
@@ -57,6 +59,15 @@ static int gv11b_tegra_probe(struct device *dev)
57 return 0; 59 return 0;
58} 60}
59 61
62static int gv11b_tegra_remove(struct device *dev)
63{
64 gp10b_tegra_remove(dev);
65
66 gr_gv11b_remove_sysfs(dev);
67
68 return 0;
69}
70
60static bool gv11b_tegra_is_railgated(struct device *dev) 71static bool gv11b_tegra_is_railgated(struct device *dev)
61{ 72{
62 bool ret = false; 73 bool ret = false;
@@ -89,6 +100,7 @@ struct gk20a_platform t19x_gpu_tegra_platform = {
89 .ptimer_src_freq = 31250000, 100 .ptimer_src_freq = 31250000,
90 101
91 .probe = gv11b_tegra_probe, 102 .probe = gv11b_tegra_probe,
103 .remove = gv11b_tegra_remove,
92 104
93 /* power management callbacks */ 105 /* power management callbacks */
94 .suspend = gv11b_tegra_suspend, 106 .suspend = gv11b_tegra_suspend,
@@ -110,3 +122,50 @@ struct gk20a_platform t19x_gpu_tegra_platform = {
110 .reset_assert = gp10b_tegra_reset_assert, 122 .reset_assert = gp10b_tegra_reset_assert,
111 .reset_deassert = gp10b_tegra_reset_deassert, 123 .reset_deassert = gp10b_tegra_reset_deassert,
112}; 124};
125
126static struct device_attribute *dev_attr_sm_l1_tag_ecc_corrected_err_count_array;
127static struct device_attribute *dev_attr_sm_l1_tag_ecc_uncorrected_err_count_array;
128
129void gr_gv11b_create_sysfs(struct device *dev)
130{
131 struct gk20a *g = get_gk20a(dev);
132 int error = 0;
133 /* This stat creation function is called on GR init. GR can get
134 initialized multiple times but we only need to create the ECC
135 stats once. Therefore, add the following check to avoid
136 creating duplicate stat sysfs nodes. */
137 if (g->gr.t19x.ecc_stats.sm_l1_tag_corrected_err_count.counters != NULL)
138 return;
139
140 gr_gp10b_create_sysfs(dev);
141
142 error |= gr_gp10b_ecc_stat_create(dev,
143 0,
144 "sm_l1_tag_ecc_corrected_err_count",
145 &g->gr.t19x.ecc_stats.sm_l1_tag_corrected_err_count,
146 dev_attr_sm_l1_tag_ecc_corrected_err_count_array);
147
148 error |= gr_gp10b_ecc_stat_create(dev,
149 0,
150 "sm_l1_tag_ecc_uncorrected_err_count",
151 &g->gr.t19x.ecc_stats.sm_l1_tag_uncorrected_err_count,
152 dev_attr_sm_l1_tag_ecc_uncorrected_err_count_array);
153
154 if (error)
155 dev_err(dev, "Failed to create gv11b sysfs attributes!\n");
156}
157
158static void gr_gv11b_remove_sysfs(struct device *dev)
159{
160 struct gk20a *g = get_gk20a(dev);
161
162 gr_gp10b_ecc_stat_remove(dev,
163 0,
164 &g->gr.t19x.ecc_stats.sm_l1_tag_corrected_err_count,
165 dev_attr_sm_l1_tag_ecc_corrected_err_count_array);
166
167 gr_gp10b_ecc_stat_remove(dev,
168 0,
169 &g->gr.t19x.ecc_stats.sm_l1_tag_uncorrected_err_count,
170 dev_attr_sm_l1_tag_ecc_uncorrected_err_count_array);
171}
diff --git a/drivers/gpu/nvgpu/include/nvgpu/hw/gv11b/hw_gr_gv11b.h b/drivers/gpu/nvgpu/include/nvgpu/hw/gv11b/hw_gr_gv11b.h
index 592a7899..d45385a8 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/hw/gv11b/hw_gr_gv11b.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/hw/gv11b/hw_gr_gv11b.h
@@ -482,6 +482,78 @@ static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_r(void)
482{ 482{
483 return 0x00504358; 483 return 0x00504358;
484} 484}
485static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_r(void)
486{
487 return 0x00504624;
488}
489static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_corrected_err_el1_0_m(void)
490{
491 return 0x1 << 0;
492}
493static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_corrected_err_el1_1_m(void)
494{
495 return 0x1 << 1;
496}
497static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_uncorrected_err_el1_0_m(void)
498{
499 return 0x1 << 2;
500}
501static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_uncorrected_err_el1_1_m(void)
502{
503 return 0x1 << 3;
504}
505static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_corrected_err_pixrpf_m(void)
506{
507 return 0x1 << 4;
508}
509static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_corrected_err_miss_fifo_m(void)
510{
511 return 0x1 << 5;
512}
513static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_uncorrected_err_pixrpf_m(void)
514{
515 return 0x1 << 6;
516}
517static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_uncorrected_err_miss_fifo_m(void)
518{
519 return 0x1 << 7;
520}
521static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_corrected_err_total_counter_overflow_v(u32 r)
522{
523 return (r >> 8) & 0x1;
524}
525static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_uncorrected_err_total_counter_overflow_v(u32 r)
526{
527 return (r >> 10) & 0x1;
528}
529static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_reset_task_f(void)
530{
531 return 0x40000000;
532}
533static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_corrected_err_count_r(void)
534{
535 return 0x00504628;
536}
537static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_corrected_err_count_total_s(void)
538{
539 return 16;
540}
541static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_corrected_err_count_total_v(u32 r)
542{
543 return (r >> 0) & 0xffff;
544}
545static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_uncorrected_err_count_r(void)
546{
547 return 0x0050462c;
548}
549static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_uncorrected_err_count_total_s(void)
550{
551 return 16;
552}
553static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_uncorrected_err_count_total_v(u32 r)
554{
555 return (r >> 0) & 0xffff;
556}
485static inline u32 gr_pri_gpc0_tpc0_tex_m_routing_r(void) 557static inline u32 gr_pri_gpc0_tpc0_tex_m_routing_r(void)
486{ 558{
487 return 0x005042c4; 559 return 0x005042c4;