summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/os/linux
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/os/linux')
-rw-r--r--drivers/gpu/nvgpu/os/linux/ecc_sysfs.c80
-rw-r--r--drivers/gpu/nvgpu/os/linux/os_linux.h1
-rw-r--r--drivers/gpu/nvgpu/os/linux/pci.c5
-rw-r--r--drivers/gpu/nvgpu/os/linux/platform_ecc_sysfs.c269
-rw-r--r--drivers/gpu/nvgpu/os/linux/platform_ecc_sysfs.h37
-rw-r--r--drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.c165
-rw-r--r--drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.h1
-rw-r--r--drivers/gpu/nvgpu/os/linux/platform_gv11b_tegra.c331
8 files changed, 81 insertions, 808 deletions
diff --git a/drivers/gpu/nvgpu/os/linux/ecc_sysfs.c b/drivers/gpu/nvgpu/os/linux/ecc_sysfs.c
new file mode 100644
index 00000000..0962e247
--- /dev/null
+++ b/drivers/gpu/nvgpu/os/linux/ecc_sysfs.c
@@ -0,0 +1,80 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <nvgpu/ecc.h>
18
19#include "gk20a/gk20a.h"
20#include "os_linux.h"
21
22int nvgpu_ecc_sysfs_init(struct gk20a *g)
23{
24 struct device *dev = dev_from_gk20a(g);
25 struct nvgpu_ecc *ecc = &g->ecc;
26 struct dev_ext_attribute *attr;
27 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
28 struct nvgpu_ecc_stat *stat;
29 int i = 0, err;
30
31 attr = nvgpu_kzalloc(g, sizeof(*attr) * ecc->stats_count);
32 if (!attr)
33 return -ENOMEM;
34
35 nvgpu_list_for_each_entry(stat,
36 &ecc->stats_list, nvgpu_ecc_stat, node) {
37 if (i >= ecc->stats_count) {
38 err = -EINVAL;
39 nvgpu_err(g, "stats_list longer than stats_count %d",
40 ecc->stats_count);
41 break;
42 }
43 sysfs_attr_init(&attr[i].attr);
44 attr[i].attr.attr.name = stat->name;
45 attr[i].attr.attr.mode = VERIFY_OCTAL_PERMISSIONS(S_IRUGO);
46 attr[i].var = &stat->counter;
47 attr[i].attr.show = device_show_int;
48 err = device_create_file(dev, &attr[i].attr);
49 if (err) {
50 nvgpu_err(g, "sysfs node create failed for %s\n",
51 stat->name);
52 break;
53 }
54 i++;
55 }
56
57 if (err) {
58 while (i-- > 0)
59 device_remove_file(dev, &attr[i].attr);
60 nvgpu_kfree(g, attr);
61 return err;
62 }
63
64 l->ecc_attrs = attr;
65
66 return 0;
67}
68
69void nvgpu_ecc_sysfs_remove(struct gk20a *g)
70{
71 struct device *dev = dev_from_gk20a(g);
72 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
73 struct nvgpu_ecc *ecc = &g->ecc;
74 int i;
75
76 for (i = 0; i < ecc->stats_count; i++)
77 device_remove_file(dev, &l->ecc_attrs[i].attr);
78 nvgpu_kfree(g, l->ecc_attrs);
79 l->ecc_attrs = NULL;
80}
diff --git a/drivers/gpu/nvgpu/os/linux/os_linux.h b/drivers/gpu/nvgpu/os/linux/os_linux.h
index 4dcce322..85d697bd 100644
--- a/drivers/gpu/nvgpu/os/linux/os_linux.h
+++ b/drivers/gpu/nvgpu/os/linux/os_linux.h
@@ -141,6 +141,7 @@ struct nvgpu_os_linux {
141 struct dentry *debugfs_dump_ctxsw_stats; 141 struct dentry *debugfs_dump_ctxsw_stats;
142#endif 142#endif
143 DECLARE_HASHTABLE(ecc_sysfs_stats_htable, 5); 143 DECLARE_HASHTABLE(ecc_sysfs_stats_htable, 5);
144 struct dev_ext_attribute *ecc_attrs;
144 145
145 struct gk20a_cde_app cde_app; 146 struct gk20a_cde_app cde_app;
146 147
diff --git a/drivers/gpu/nvgpu/os/linux/pci.c b/drivers/gpu/nvgpu/os/linux/pci.c
index 3493b105..41fb69a0 100644
--- a/drivers/gpu/nvgpu/os/linux/pci.c
+++ b/drivers/gpu/nvgpu/os/linux/pci.c
@@ -52,11 +52,6 @@ static int nvgpu_pci_tegra_probe(struct device *dev)
52 52
53static int nvgpu_pci_tegra_remove(struct device *dev) 53static int nvgpu_pci_tegra_remove(struct device *dev)
54{ 54{
55 struct gk20a *g = get_gk20a(dev);
56
57 if (g->ops.gr.remove_gr_sysfs)
58 g->ops.gr.remove_gr_sysfs(g);
59
60 return 0; 55 return 0;
61} 56}
62 57
diff --git a/drivers/gpu/nvgpu/os/linux/platform_ecc_sysfs.c b/drivers/gpu/nvgpu/os/linux/platform_ecc_sysfs.c
deleted file mode 100644
index 2a6ace37..00000000
--- a/drivers/gpu/nvgpu/os/linux/platform_ecc_sysfs.c
+++ /dev/null
@@ -1,269 +0,0 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/hashtable.h>
18
19#include <nvgpu/kmem.h>
20#include <nvgpu/bug.h>
21#include <nvgpu/hashtable.h>
22
23#include "os_linux.h"
24
25#include "gk20a/gk20a.h"
26
27#include "platform_gk20a.h"
28#include "platform_gk20a_tegra.h"
29#include "platform_gp10b.h"
30#include "platform_gp10b_tegra.h"
31#include "platform_ecc_sysfs.h"
32
33static u32 gen_ecc_hash_key(char *str)
34{
35 int i = 0;
36 u32 hash_key = 0x811c9dc5;
37
38 while (str[i]) {
39 hash_key *= 0x1000193;
40 hash_key ^= (u32)(str[i]);
41 i++;
42 };
43
44 return hash_key;
45}
46
47static ssize_t ecc_stat_show(struct device *dev,
48 struct device_attribute *attr,
49 char *buf)
50{
51 const char *ecc_stat_full_name = attr->attr.name;
52 const char *ecc_stat_base_name;
53 unsigned int hw_unit;
54 unsigned int subunit;
55 struct gk20a_ecc_stat *ecc_stat;
56 u32 hash_key;
57 struct gk20a *g = get_gk20a(dev);
58 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
59
60 if (sscanf(ecc_stat_full_name, "ltc%u_lts%u", &hw_unit,
61 &subunit) == 2) {
62 ecc_stat_base_name = &(ecc_stat_full_name[strlen("ltc0_lts0_")]);
63 hw_unit = g->gr.slices_per_ltc * hw_unit + subunit;
64 } else if (sscanf(ecc_stat_full_name, "ltc%u", &hw_unit) == 1) {
65 ecc_stat_base_name = &(ecc_stat_full_name[strlen("ltc0_")]);
66 } else if (sscanf(ecc_stat_full_name, "gpc0_tpc%u", &hw_unit) == 1) {
67 ecc_stat_base_name = &(ecc_stat_full_name[strlen("gpc0_tpc0_")]);
68 } else if (sscanf(ecc_stat_full_name, "gpc%u", &hw_unit) == 1) {
69 ecc_stat_base_name = &(ecc_stat_full_name[strlen("gpc0_")]);
70 } else if (sscanf(ecc_stat_full_name, "eng%u", &hw_unit) == 1) {
71 ecc_stat_base_name = &(ecc_stat_full_name[strlen("eng0_")]);
72 } else {
73 return snprintf(buf,
74 PAGE_SIZE,
75 "Error: Invalid ECC stat name!\n");
76 }
77
78 hash_key = gen_ecc_hash_key((char *)ecc_stat_base_name);
79
80 hash_for_each_possible(l->ecc_sysfs_stats_htable,
81 ecc_stat,
82 hash_node,
83 hash_key) {
84 if (hw_unit >= ecc_stat->count)
85 continue;
86 if (!strcmp(ecc_stat_full_name, ecc_stat->names[hw_unit]))
87 return snprintf(buf, PAGE_SIZE, "%u\n", ecc_stat->counters[hw_unit]);
88 }
89
90 return snprintf(buf, PAGE_SIZE, "Error: No ECC stat found!\n");
91}
92
93int nvgpu_gr_ecc_stat_create(struct device *dev,
94 int is_l2, char *ecc_stat_name,
95 struct gk20a_ecc_stat *ecc_stat)
96{
97 struct gk20a *g = get_gk20a(dev);
98 char *ltc_unit_name = "ltc";
99 char *gr_unit_name = "gpc0_tpc";
100 char *lts_unit_name = "lts";
101 int num_hw_units = 0;
102 int num_subunits = 0;
103
104 if (is_l2 == 1)
105 num_hw_units = g->ltc_count;
106 else if (is_l2 == 2) {
107 num_hw_units = g->ltc_count;
108 num_subunits = g->gr.slices_per_ltc;
109 } else
110 num_hw_units = g->gr.tpc_count;
111
112
113 return nvgpu_ecc_stat_create(dev, num_hw_units, num_subunits,
114 is_l2 ? ltc_unit_name : gr_unit_name,
115 num_subunits ? lts_unit_name: NULL,
116 ecc_stat_name,
117 ecc_stat);
118}
119
120int nvgpu_ecc_stat_create(struct device *dev,
121 int num_hw_units, int num_subunits,
122 char *ecc_unit_name, char *ecc_subunit_name,
123 char *ecc_stat_name,
124 struct gk20a_ecc_stat *ecc_stat)
125{
126 int error = 0;
127 struct gk20a *g = get_gk20a(dev);
128 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
129 int hw_unit = 0;
130 int subunit = 0;
131 int element = 0;
132 u32 hash_key = 0;
133 struct device_attribute *dev_attr_array;
134
135 int num_elements = num_subunits ? num_subunits * num_hw_units :
136 num_hw_units;
137
138 /* Allocate arrays */
139 dev_attr_array = nvgpu_kzalloc(g, sizeof(struct device_attribute) *
140 num_elements);
141 ecc_stat->counters = nvgpu_kzalloc(g, sizeof(u32) * num_elements);
142 ecc_stat->names = nvgpu_kzalloc(g, sizeof(char *) * num_elements);
143
144 for (hw_unit = 0; hw_unit < num_elements; hw_unit++) {
145 ecc_stat->names[hw_unit] = nvgpu_kzalloc(g, sizeof(char) *
146 ECC_STAT_NAME_MAX_SIZE);
147 }
148 ecc_stat->count = num_elements;
149 if (num_subunits) {
150 for (hw_unit = 0; hw_unit < num_hw_units; hw_unit++) {
151 for (subunit = 0; subunit < num_subunits; subunit++) {
152 element = hw_unit*num_subunits + subunit;
153
154 snprintf(ecc_stat->names[element],
155 ECC_STAT_NAME_MAX_SIZE,
156 "%s%d_%s%d_%s",
157 ecc_unit_name,
158 hw_unit,
159 ecc_subunit_name,
160 subunit,
161 ecc_stat_name);
162
163 sysfs_attr_init(&dev_attr_array[element].attr);
164 dev_attr_array[element].attr.name =
165 ecc_stat->names[element];
166 dev_attr_array[element].attr.mode =
167 VERIFY_OCTAL_PERMISSIONS(S_IRUGO);
168 dev_attr_array[element].show = ecc_stat_show;
169 dev_attr_array[element].store = NULL;
170
171 /* Create sysfs file */
172 error |= device_create_file(dev,
173 &dev_attr_array[element]);
174
175 }
176 }
177 } else {
178 for (hw_unit = 0; hw_unit < num_hw_units; hw_unit++) {
179
180 /* Fill in struct device_attribute members */
181 snprintf(ecc_stat->names[hw_unit],
182 ECC_STAT_NAME_MAX_SIZE,
183 "%s%d_%s",
184 ecc_unit_name,
185 hw_unit,
186 ecc_stat_name);
187
188 sysfs_attr_init(&dev_attr_array[hw_unit].attr);
189 dev_attr_array[hw_unit].attr.name =
190 ecc_stat->names[hw_unit];
191 dev_attr_array[hw_unit].attr.mode =
192 VERIFY_OCTAL_PERMISSIONS(S_IRUGO);
193 dev_attr_array[hw_unit].show = ecc_stat_show;
194 dev_attr_array[hw_unit].store = NULL;
195
196 /* Create sysfs file */
197 error |= device_create_file(dev,
198 &dev_attr_array[hw_unit]);
199 }
200 }
201
202 /* Add hash table entry */
203 hash_key = gen_ecc_hash_key(ecc_stat_name);
204 hash_add(l->ecc_sysfs_stats_htable,
205 &ecc_stat->hash_node,
206 hash_key);
207
208 ecc_stat->attr_array = dev_attr_array;
209
210 return error;
211}
212
213void nvgpu_gr_ecc_stat_remove(struct device *dev,
214 int is_l2, struct gk20a_ecc_stat *ecc_stat)
215{
216 struct gk20a *g = get_gk20a(dev);
217 int num_hw_units = 0;
218 int num_subunits = 0;
219
220 if (is_l2 == 1)
221 num_hw_units = g->ltc_count;
222 else if (is_l2 == 2) {
223 num_hw_units = g->ltc_count;
224 num_subunits = g->gr.slices_per_ltc;
225 } else
226 num_hw_units = g->gr.tpc_count;
227
228 nvgpu_ecc_stat_remove(dev, num_hw_units, num_subunits, ecc_stat);
229}
230
231void nvgpu_ecc_stat_remove(struct device *dev,
232 int num_hw_units, int num_subunits,
233 struct gk20a_ecc_stat *ecc_stat)
234{
235 struct gk20a *g = get_gk20a(dev);
236 struct device_attribute *dev_attr_array = ecc_stat->attr_array;
237 int hw_unit = 0;
238 int subunit = 0;
239 int element = 0;
240 int num_elements = num_subunits ? num_subunits * num_hw_units :
241 num_hw_units;
242
243 /* Remove sysfs files */
244 if (num_subunits) {
245 for (hw_unit = 0; hw_unit < num_hw_units; hw_unit++) {
246 for (subunit = 0; subunit < num_subunits; subunit++) {
247 element = hw_unit * num_subunits + subunit;
248
249 device_remove_file(dev,
250 &dev_attr_array[element]);
251 }
252 }
253 } else {
254 for (hw_unit = 0; hw_unit < num_hw_units; hw_unit++)
255 device_remove_file(dev, &dev_attr_array[hw_unit]);
256 }
257
258 /* Remove hash table entry */
259 hash_del(&ecc_stat->hash_node);
260
261 /* Free arrays */
262 nvgpu_kfree(g, ecc_stat->counters);
263
264 for (hw_unit = 0; hw_unit < num_elements; hw_unit++)
265 nvgpu_kfree(g, ecc_stat->names[hw_unit]);
266
267 nvgpu_kfree(g, ecc_stat->names);
268 nvgpu_kfree(g, dev_attr_array);
269}
diff --git a/drivers/gpu/nvgpu/os/linux/platform_ecc_sysfs.h b/drivers/gpu/nvgpu/os/linux/platform_ecc_sysfs.h
deleted file mode 100644
index d29f7bd3..00000000
--- a/drivers/gpu/nvgpu/os/linux/platform_ecc_sysfs.h
+++ /dev/null
@@ -1,37 +0,0 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef _NVGPU_PLATFORM_SYSFS_H_
18#define _NVGPU_PLATFORM_SYSFS_H_
19
20#include "gp10b/gr_gp10b.h"
21
22#define ECC_STAT_NAME_MAX_SIZE 100
23
24int nvgpu_gr_ecc_stat_create(struct device *dev,
25 int is_l2, char *ecc_stat_name,
26 struct gk20a_ecc_stat *ecc_stat);
27int nvgpu_ecc_stat_create(struct device *dev,
28 int num_hw_units, int num_subunits,
29 char *ecc_unit_name, char *ecc_subunit_name,
30 char *ecc_stat_name,
31 struct gk20a_ecc_stat *ecc_stat);
32void nvgpu_gr_ecc_stat_remove(struct device *dev,
33 int is_l2, struct gk20a_ecc_stat *ecc_stat);
34void nvgpu_ecc_stat_remove(struct device *dev,
35 int num_hw_units, int num_subunits,
36 struct gk20a_ecc_stat *ecc_stat);
37#endif
diff --git a/drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.c b/drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.c
index d5530368..c5464d5b 100644
--- a/drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.c
+++ b/drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.c
@@ -41,7 +41,6 @@
41#include "gk20a/gk20a.h" 41#include "gk20a/gk20a.h"
42 42
43#include "platform_gk20a.h" 43#include "platform_gk20a.h"
44#include "platform_ecc_sysfs.h"
45#include "platform_gk20a_tegra.h" 44#include "platform_gk20a_tegra.h"
46#include "platform_gp10b.h" 45#include "platform_gp10b.h"
47#include "platform_gp10b_tegra.h" 46#include "platform_gp10b_tegra.h"
@@ -177,11 +176,6 @@ static int gp10b_tegra_late_probe(struct device *dev)
177 176
178static int gp10b_tegra_remove(struct device *dev) 177static int gp10b_tegra_remove(struct device *dev)
179{ 178{
180 struct gk20a *g = get_gk20a(dev);
181
182 if (g->ops.gr.remove_gr_sysfs)
183 g->ops.gr.remove_gr_sysfs(g);
184
185 /* deinitialise tegra specific scaling quirks */ 179 /* deinitialise tegra specific scaling quirks */
186 gp10b_tegra_scale_exit(dev); 180 gp10b_tegra_scale_exit(dev);
187 181
@@ -476,162 +470,3 @@ struct gk20a_platform gp10b_tegra_platform = {
476 470
477 .secure_buffer_size = 401408, 471 .secure_buffer_size = 401408,
478}; 472};
479
480void gr_gp10b_create_sysfs(struct gk20a *g)
481{
482 int error = 0;
483 struct device *dev = dev_from_gk20a(g);
484
485 /* This stat creation function is called on GR init. GR can get
486 initialized multiple times but we only need to create the ECC
487 stats once. Therefore, add the following check to avoid
488 creating duplicate stat sysfs nodes. */
489 if (g->ecc.gr.sm_lrf_single_err_count.counters != NULL)
490 return;
491
492 error |= nvgpu_gr_ecc_stat_create(dev,
493 0,
494 "sm_lrf_ecc_single_err_count",
495 &g->ecc.gr.sm_lrf_single_err_count);
496
497 error |= nvgpu_gr_ecc_stat_create(dev,
498 0,
499 "sm_lrf_ecc_double_err_count",
500 &g->ecc.gr.sm_lrf_double_err_count);
501
502 error |= nvgpu_gr_ecc_stat_create(dev,
503 0,
504 "sm_shm_ecc_sec_count",
505 &g->ecc.gr.sm_shm_sec_count);
506
507 error |= nvgpu_gr_ecc_stat_create(dev,
508 0,
509 "sm_shm_ecc_sed_count",
510 &g->ecc.gr.sm_shm_sed_count);
511
512 error |= nvgpu_gr_ecc_stat_create(dev,
513 0,
514 "sm_shm_ecc_ded_count",
515 &g->ecc.gr.sm_shm_ded_count);
516
517 error |= nvgpu_gr_ecc_stat_create(dev,
518 0,
519 "tex_ecc_total_sec_pipe0_count",
520 &g->ecc.gr.tex_total_sec_pipe0_count);
521
522 error |= nvgpu_gr_ecc_stat_create(dev,
523 0,
524 "tex_ecc_total_ded_pipe0_count",
525 &g->ecc.gr.tex_total_ded_pipe0_count);
526
527 error |= nvgpu_gr_ecc_stat_create(dev,
528 0,
529 "tex_ecc_unique_sec_pipe0_count",
530 &g->ecc.gr.tex_unique_sec_pipe0_count);
531
532 error |= nvgpu_gr_ecc_stat_create(dev,
533 0,
534 "tex_ecc_unique_ded_pipe0_count",
535 &g->ecc.gr.tex_unique_ded_pipe0_count);
536
537 error |= nvgpu_gr_ecc_stat_create(dev,
538 0,
539 "tex_ecc_total_sec_pipe1_count",
540 &g->ecc.gr.tex_total_sec_pipe1_count);
541
542 error |= nvgpu_gr_ecc_stat_create(dev,
543 0,
544 "tex_ecc_total_ded_pipe1_count",
545 &g->ecc.gr.tex_total_ded_pipe1_count);
546
547 error |= nvgpu_gr_ecc_stat_create(dev,
548 0,
549 "tex_ecc_unique_sec_pipe1_count",
550 &g->ecc.gr.tex_unique_sec_pipe1_count);
551
552 error |= nvgpu_gr_ecc_stat_create(dev,
553 0,
554 "tex_ecc_unique_ded_pipe1_count",
555 &g->ecc.gr.tex_unique_ded_pipe1_count);
556
557 error |= nvgpu_gr_ecc_stat_create(dev,
558 2,
559 "ecc_sec_count",
560 &g->ecc.ltc.l2_sec_count);
561
562 error |= nvgpu_gr_ecc_stat_create(dev,
563 2,
564 "ecc_ded_count",
565 &g->ecc.ltc.l2_ded_count);
566
567 if (error)
568 dev_err(dev, "Failed to create sysfs attributes!\n");
569}
570
571void gr_gp10b_remove_sysfs(struct gk20a *g)
572{
573 struct device *dev = dev_from_gk20a(g);
574
575 if (!g->ecc.gr.sm_lrf_single_err_count.counters)
576 return;
577
578 nvgpu_gr_ecc_stat_remove(dev,
579 0,
580 &g->ecc.gr.sm_lrf_single_err_count);
581
582 nvgpu_gr_ecc_stat_remove(dev,
583 0,
584 &g->ecc.gr.sm_lrf_double_err_count);
585
586 nvgpu_gr_ecc_stat_remove(dev,
587 0,
588 &g->ecc.gr.sm_shm_sec_count);
589
590 nvgpu_gr_ecc_stat_remove(dev,
591 0,
592 &g->ecc.gr.sm_shm_sed_count);
593
594 nvgpu_gr_ecc_stat_remove(dev,
595 0,
596 &g->ecc.gr.sm_shm_ded_count);
597
598 nvgpu_gr_ecc_stat_remove(dev,
599 0,
600 &g->ecc.gr.tex_total_sec_pipe0_count);
601
602 nvgpu_gr_ecc_stat_remove(dev,
603 0,
604 &g->ecc.gr.tex_total_ded_pipe0_count);
605
606 nvgpu_gr_ecc_stat_remove(dev,
607 0,
608 &g->ecc.gr.tex_unique_sec_pipe0_count);
609
610 nvgpu_gr_ecc_stat_remove(dev,
611 0,
612 &g->ecc.gr.tex_unique_ded_pipe0_count);
613
614 nvgpu_gr_ecc_stat_remove(dev,
615 0,
616 &g->ecc.gr.tex_total_sec_pipe1_count);
617
618 nvgpu_gr_ecc_stat_remove(dev,
619 0,
620 &g->ecc.gr.tex_total_ded_pipe1_count);
621
622 nvgpu_gr_ecc_stat_remove(dev,
623 0,
624 &g->ecc.gr.tex_unique_sec_pipe1_count);
625
626 nvgpu_gr_ecc_stat_remove(dev,
627 0,
628 &g->ecc.gr.tex_unique_ded_pipe1_count);
629
630 nvgpu_gr_ecc_stat_remove(dev,
631 2,
632 &g->ecc.ltc.l2_sec_count);
633
634 nvgpu_gr_ecc_stat_remove(dev,
635 2,
636 &g->ecc.ltc.l2_ded_count);
637}
diff --git a/drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.h b/drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.h
index 6de90275..85b46b9a 100644
--- a/drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.h
+++ b/drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.h
@@ -18,6 +18,5 @@
18#define _PLATFORM_GP10B_TEGRA_H_ 18#define _PLATFORM_GP10B_TEGRA_H_
19 19
20#include "gp10b/gr_gp10b.h" 20#include "gp10b/gr_gp10b.h"
21#include "platform_ecc_sysfs.h"
22 21
23#endif 22#endif
diff --git a/drivers/gpu/nvgpu/os/linux/platform_gv11b_tegra.c b/drivers/gpu/nvgpu/os/linux/platform_gv11b_tegra.c
index d62e7932..c9c13197 100644
--- a/drivers/gpu/nvgpu/os/linux/platform_gv11b_tegra.c
+++ b/drivers/gpu/nvgpu/os/linux/platform_gv11b_tegra.c
@@ -39,7 +39,6 @@
39 39
40#include "platform_gp10b.h" 40#include "platform_gp10b.h"
41#include "platform_gp10b_tegra.h" 41#include "platform_gp10b_tegra.h"
42#include "platform_ecc_sysfs.h"
43 42
44#include "os_linux.h" 43#include "os_linux.h"
45#include "platform_gk20a_tegra.h" 44#include "platform_gk20a_tegra.h"
@@ -94,11 +93,6 @@ static int gv11b_tegra_late_probe(struct device *dev)
94 93
95static int gv11b_tegra_remove(struct device *dev) 94static int gv11b_tegra_remove(struct device *dev)
96{ 95{
97 struct gk20a *g = get_gk20a(dev);
98
99 if (g->ops.gr.remove_gr_sysfs)
100 g->ops.gr.remove_gr_sysfs(g);
101
102 gv11b_tegra_scale_exit(dev); 96 gv11b_tegra_scale_exit(dev);
103 97
104#ifdef CONFIG_TEGRA_GK20A_NVHOST 98#ifdef CONFIG_TEGRA_GK20A_NVHOST
@@ -261,328 +255,3 @@ struct gk20a_platform gv11b_tegra_platform = {
261 255
262 .secure_buffer_size = 667648, 256 .secure_buffer_size = 667648,
263}; 257};
264
265void gr_gv11b_create_sysfs(struct gk20a *g)
266{
267 struct device *dev = dev_from_gk20a(g);
268 int error = 0;
269
270 /* This stat creation function is called on GR init. GR can get
271 initialized multiple times but we only need to create the ECC
272 stats once. Therefore, add the following check to avoid
273 creating duplicate stat sysfs nodes. */
274 if (g->ecc.gr.sm_l1_tag_corrected_err_count.counters != NULL)
275 return;
276
277 gr_gp10b_create_sysfs(g);
278
279 error |= nvgpu_gr_ecc_stat_create(dev,
280 0,
281 "sm_l1_tag_ecc_corrected_err_count",
282 &g->ecc.gr.sm_l1_tag_corrected_err_count);
283
284 error |= nvgpu_gr_ecc_stat_create(dev,
285 0,
286 "sm_l1_tag_ecc_uncorrected_err_count",
287 &g->ecc.gr.sm_l1_tag_uncorrected_err_count);
288
289 error |= nvgpu_gr_ecc_stat_create(dev,
290 0,
291 "sm_cbu_ecc_corrected_err_count",
292 &g->ecc.gr.sm_cbu_corrected_err_count);
293
294 error |= nvgpu_gr_ecc_stat_create(dev,
295 0,
296 "sm_cbu_ecc_uncorrected_err_count",
297 &g->ecc.gr.sm_cbu_uncorrected_err_count);
298
299 error |= nvgpu_gr_ecc_stat_create(dev,
300 0,
301 "sm_l1_data_ecc_corrected_err_count",
302 &g->ecc.gr.sm_l1_data_corrected_err_count);
303
304 error |= nvgpu_gr_ecc_stat_create(dev,
305 0,
306 "sm_l1_data_ecc_uncorrected_err_count",
307 &g->ecc.gr.sm_l1_data_uncorrected_err_count);
308
309 error |= nvgpu_gr_ecc_stat_create(dev,
310 0,
311 "sm_icache_ecc_corrected_err_count",
312 &g->ecc.gr.sm_icache_corrected_err_count);
313
314 error |= nvgpu_gr_ecc_stat_create(dev,
315 0,
316 "sm_icache_ecc_uncorrected_err_count",
317 &g->ecc.gr.sm_icache_uncorrected_err_count);
318
319 error |= nvgpu_gr_ecc_stat_create(dev,
320 0,
321 "gcc_l15_ecc_corrected_err_count",
322 &g->ecc.gr.gcc_l15_corrected_err_count);
323
324 error |= nvgpu_gr_ecc_stat_create(dev,
325 0,
326 "gcc_l15_ecc_uncorrected_err_count",
327 &g->ecc.gr.gcc_l15_uncorrected_err_count);
328
329 error |= nvgpu_ecc_stat_create(dev,
330 g->ltc_count,
331 0,
332 "ltc",
333 NULL,
334 "l2_cache_uncorrected_err_count",
335 &g->ecc.ltc.l2_cache_uncorrected_err_count);
336
337 error |= nvgpu_ecc_stat_create(dev,
338 g->ltc_count,
339 0,
340 "ltc",
341 NULL,
342 "l2_cache_corrected_err_count",
343 &g->ecc.ltc.l2_cache_corrected_err_count);
344
345 error |= nvgpu_ecc_stat_create(dev,
346 1,
347 0,
348 "gpc",
349 NULL,
350 "fecs_ecc_uncorrected_err_count",
351 &g->ecc.gr.fecs_uncorrected_err_count);
352
353 error |= nvgpu_ecc_stat_create(dev,
354 1,
355 0,
356 "gpc",
357 NULL,
358 "fecs_ecc_corrected_err_count",
359 &g->ecc.gr.fecs_corrected_err_count);
360
361 error |= nvgpu_ecc_stat_create(dev,
362 g->gr.gpc_count,
363 0,
364 "gpc",
365 NULL,
366 "gpccs_ecc_uncorrected_err_count",
367 &g->ecc.gr.gpccs_uncorrected_err_count);
368
369 error |= nvgpu_ecc_stat_create(dev,
370 g->gr.gpc_count,
371 0,
372 "gpc",
373 NULL,
374 "gpccs_ecc_corrected_err_count",
375 &g->ecc.gr.gpccs_corrected_err_count);
376
377 error |= nvgpu_ecc_stat_create(dev,
378 g->gr.gpc_count,
379 0,
380 "gpc",
381 NULL,
382 "mmu_l1tlb_ecc_uncorrected_err_count",
383 &g->ecc.gr.mmu_l1tlb_uncorrected_err_count);
384
385 error |= nvgpu_ecc_stat_create(dev,
386 g->gr.gpc_count,
387 0,
388 "gpc",
389 NULL,
390 "mmu_l1tlb_ecc_corrected_err_count",
391 &g->ecc.gr.mmu_l1tlb_corrected_err_count);
392
393 error |= nvgpu_ecc_stat_create(dev,
394 1,
395 0,
396 "eng",
397 NULL,
398 "mmu_l2tlb_ecc_uncorrected_err_count",
399 &g->ecc.fb.mmu_l2tlb_uncorrected_err_count);
400
401 error |= nvgpu_ecc_stat_create(dev,
402 1,
403 0,
404 "eng",
405 NULL,
406 "mmu_l2tlb_ecc_corrected_err_count",
407 &g->ecc.fb.mmu_l2tlb_corrected_err_count);
408
409 error |= nvgpu_ecc_stat_create(dev,
410 1,
411 0,
412 "eng",
413 NULL,
414 "mmu_hubtlb_ecc_uncorrected_err_count",
415 &g->ecc.fb.mmu_hubtlb_uncorrected_err_count);
416
417 error |= nvgpu_ecc_stat_create(dev,
418 1,
419 0,
420 "eng",
421 NULL,
422 "mmu_hubtlb_ecc_corrected_err_count",
423 &g->ecc.fb.mmu_hubtlb_corrected_err_count);
424
425 error |= nvgpu_ecc_stat_create(dev,
426 1,
427 0,
428 "eng",
429 NULL,
430 "mmu_fillunit_ecc_uncorrected_err_count",
431 &g->ecc.fb.mmu_fillunit_uncorrected_err_count);
432
433 error |= nvgpu_ecc_stat_create(dev,
434 1,
435 0,
436 "eng",
437 NULL,
438 "mmu_fillunit_ecc_corrected_err_count",
439 &g->ecc.fb.mmu_fillunit_corrected_err_count);
440
441 error |= nvgpu_ecc_stat_create(dev,
442 1,
443 0,
444 "eng",
445 NULL,
446 "pmu_ecc_uncorrected_err_count",
447 &g->ecc.pmu.pmu_uncorrected_err_count);
448
449 error |= nvgpu_ecc_stat_create(dev,
450 1,
451 0,
452 "eng",
453 NULL,
454 "pmu_ecc_corrected_err_count",
455 &g->ecc.pmu.pmu_corrected_err_count);
456
457 if (error)
458 dev_err(dev, "Failed to create gv11b sysfs attributes!\n");
459}
460
461void gr_gv11b_remove_sysfs(struct gk20a *g)
462{
463 struct device *dev = dev_from_gk20a(g);
464
465 if (!g->ecc.gr.sm_l1_tag_corrected_err_count.counters)
466 return;
467 gr_gp10b_remove_sysfs(g);
468
469 nvgpu_gr_ecc_stat_remove(dev,
470 0,
471 &g->ecc.gr.sm_l1_tag_corrected_err_count);
472
473 nvgpu_gr_ecc_stat_remove(dev,
474 0,
475 &g->ecc.gr.sm_l1_tag_uncorrected_err_count);
476
477 nvgpu_gr_ecc_stat_remove(dev,
478 0,
479 &g->ecc.gr.sm_cbu_corrected_err_count);
480
481 nvgpu_gr_ecc_stat_remove(dev,
482 0,
483 &g->ecc.gr.sm_cbu_uncorrected_err_count);
484
485 nvgpu_gr_ecc_stat_remove(dev,
486 0,
487 &g->ecc.gr.sm_l1_data_corrected_err_count);
488
489 nvgpu_gr_ecc_stat_remove(dev,
490 0,
491 &g->ecc.gr.sm_l1_data_uncorrected_err_count);
492
493 nvgpu_gr_ecc_stat_remove(dev,
494 0,
495 &g->ecc.gr.sm_icache_corrected_err_count);
496
497 nvgpu_gr_ecc_stat_remove(dev,
498 0,
499 &g->ecc.gr.sm_icache_uncorrected_err_count);
500
501 nvgpu_gr_ecc_stat_remove(dev,
502 0,
503 &g->ecc.gr.gcc_l15_corrected_err_count);
504
505 nvgpu_gr_ecc_stat_remove(dev,
506 0,
507 &g->ecc.gr.gcc_l15_uncorrected_err_count);
508
509 nvgpu_ecc_stat_remove(dev,
510 g->ltc_count,
511 0,
512 &g->ecc.ltc.l2_cache_uncorrected_err_count);
513
514 nvgpu_ecc_stat_remove(dev,
515 g->ltc_count,
516 0,
517 &g->ecc.ltc.l2_cache_corrected_err_count);
518
519 nvgpu_ecc_stat_remove(dev,
520 1,
521 0,
522 &g->ecc.gr.fecs_uncorrected_err_count);
523
524 nvgpu_ecc_stat_remove(dev,
525 1,
526 0,
527 &g->ecc.gr.fecs_corrected_err_count);
528
529 nvgpu_ecc_stat_remove(dev,
530 g->gr.gpc_count,
531 0,
532 &g->ecc.gr.gpccs_uncorrected_err_count);
533
534 nvgpu_ecc_stat_remove(dev,
535 g->gr.gpc_count,
536 0,
537 &g->ecc.gr.gpccs_corrected_err_count);
538
539 nvgpu_ecc_stat_remove(dev,
540 g->gr.gpc_count,
541 0,
542 &g->ecc.gr.mmu_l1tlb_uncorrected_err_count);
543
544 nvgpu_ecc_stat_remove(dev,
545 g->gr.gpc_count,
546 0,
547 &g->ecc.gr.mmu_l1tlb_corrected_err_count);
548
549 nvgpu_ecc_stat_remove(dev,
550 1,
551 0,
552 &g->ecc.fb.mmu_l2tlb_uncorrected_err_count);
553
554 nvgpu_ecc_stat_remove(dev,
555 1,
556 0,
557 &g->ecc.fb.mmu_l2tlb_corrected_err_count);
558
559 nvgpu_ecc_stat_remove(dev,
560 1,
561 0,
562 &g->ecc.fb.mmu_hubtlb_uncorrected_err_count);
563
564 nvgpu_ecc_stat_remove(dev,
565 1,
566 0,
567 &g->ecc.fb.mmu_hubtlb_corrected_err_count);
568
569 nvgpu_ecc_stat_remove(dev,
570 1,
571 0,
572 &g->ecc.fb.mmu_fillunit_uncorrected_err_count);
573
574 nvgpu_ecc_stat_remove(dev,
575 1,
576 0,
577 &g->ecc.fb.mmu_fillunit_corrected_err_count);
578
579 nvgpu_ecc_stat_remove(dev,
580 1,
581 0,
582 &g->ecc.pmu.pmu_uncorrected_err_count);
583
584 nvgpu_ecc_stat_remove(dev,
585 1,
586 0,
587 &g->ecc.pmu.pmu_corrected_err_count);
588}