summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
diff options
context:
space:
mode:
authorNitin Kumbhar <nkumbhar@nvidia.com>2018-05-31 07:08:20 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-06-15 08:04:07 -0400
commit19e9a791955811416729ae3a94439c09000b3952 (patch)
tree4fed6ba5e9024a0d29b3e9fda2dd23f69303f669 /drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
parent8963318b140d8ad7a98281bf083c23f08735c57e (diff)
gpu: nvgpu: move ecc sysfs funcs to a common file
To make ecc sysfs related code reusable, move it to a seprate file. This allows possible optimizations with localized changes. There is no change in the code. Bug 1987855 Change-Id: I69aefb649df628d0c8dad529de6dde07ab4e6009 Signed-off-by: Nitin Kumbhar <nkumbhar@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1735988 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c')
-rw-r--r--drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c233
1 files changed, 0 insertions, 233 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c b/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
index a2506341..6f8cc507 100644
--- a/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
+++ b/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
@@ -446,12 +446,6 @@ struct gk20a_platform gp10b_tegra_platform = {
446 .secure_buffer_size = 401408, 446 .secure_buffer_size = 401408,
447}; 447};
448 448
449
450#define ECC_STAT_NAME_MAX_SIZE 100
451
452
453static DEFINE_HASHTABLE(ecc_hash_table, 5);
454
455static struct device_attribute *dev_attr_sm_lrf_ecc_single_err_count_array; 449static struct device_attribute *dev_attr_sm_lrf_ecc_single_err_count_array;
456static struct device_attribute *dev_attr_sm_lrf_ecc_double_err_count_array; 450static struct device_attribute *dev_attr_sm_lrf_ecc_double_err_count_array;
457 451
@@ -471,233 +465,6 @@ static struct device_attribute *dev_attr_tex_ecc_unique_ded_pipe1_count_array;
471static struct device_attribute *dev_attr_l2_ecc_sec_count_array; 465static struct device_attribute *dev_attr_l2_ecc_sec_count_array;
472static struct device_attribute *dev_attr_l2_ecc_ded_count_array; 466static struct device_attribute *dev_attr_l2_ecc_ded_count_array;
473 467
474
475static u32 gen_ecc_hash_key(char *str)
476{
477 int i = 0;
478 u32 hash_key = 0x811c9dc5;
479
480 while (str[i]) {
481 hash_key *= 0x1000193;
482 hash_key ^= (u32)(str[i]);
483 i++;
484 };
485
486 return hash_key;
487}
488
489static ssize_t ecc_stat_show(struct device *dev,
490 struct device_attribute *attr,
491 char *buf)
492{
493 const char *ecc_stat_full_name = attr->attr.name;
494 const char *ecc_stat_base_name;
495 unsigned int hw_unit;
496 unsigned int subunit;
497 struct gk20a_ecc_stat *ecc_stat;
498 u32 hash_key;
499 struct gk20a *g = get_gk20a(dev);
500
501 if (sscanf(ecc_stat_full_name, "ltc%u_lts%u", &hw_unit,
502 &subunit) == 2) {
503 ecc_stat_base_name = &(ecc_stat_full_name[strlen("ltc0_lts0_")]);
504 hw_unit = g->gr.slices_per_ltc * hw_unit + subunit;
505 } else if (sscanf(ecc_stat_full_name, "ltc%u", &hw_unit) == 1) {
506 ecc_stat_base_name = &(ecc_stat_full_name[strlen("ltc0_")]);
507 } else if (sscanf(ecc_stat_full_name, "gpc0_tpc%u", &hw_unit) == 1) {
508 ecc_stat_base_name = &(ecc_stat_full_name[strlen("gpc0_tpc0_")]);
509 } else if (sscanf(ecc_stat_full_name, "gpc%u", &hw_unit) == 1) {
510 ecc_stat_base_name = &(ecc_stat_full_name[strlen("gpc0_")]);
511 } else if (sscanf(ecc_stat_full_name, "eng%u", &hw_unit) == 1) {
512 ecc_stat_base_name = &(ecc_stat_full_name[strlen("eng0_")]);
513 } else {
514 return snprintf(buf,
515 PAGE_SIZE,
516 "Error: Invalid ECC stat name!\n");
517 }
518
519 hash_key = gen_ecc_hash_key((char *)ecc_stat_base_name);
520
521 hash_for_each_possible(ecc_hash_table,
522 ecc_stat,
523 hash_node,
524 hash_key) {
525 if (hw_unit >= ecc_stat->count)
526 continue;
527 if (!strcmp(ecc_stat_full_name, ecc_stat->names[hw_unit]))
528 return snprintf(buf, PAGE_SIZE, "%u\n", ecc_stat->counters[hw_unit]);
529 }
530
531 return snprintf(buf, PAGE_SIZE, "Error: No ECC stat found!\n");
532}
533
534int gr_gp10b_ecc_stat_create(struct device *dev,
535 int is_l2,
536 char *ecc_stat_name,
537 struct gk20a_ecc_stat *ecc_stat,
538 struct device_attribute **dev_attr_array)
539{
540 struct gk20a *g = get_gk20a(dev);
541 char *ltc_unit_name = "ltc";
542 char *gr_unit_name = "gpc0_tpc";
543 char *lts_unit_name = "lts";
544 int num_hw_units = 0;
545 int num_subunits = 0;
546
547 if (is_l2 == 1)
548 num_hw_units = g->ltc_count;
549 else if (is_l2 == 2) {
550 num_hw_units = g->ltc_count;
551 num_subunits = g->gr.slices_per_ltc;
552 } else
553 num_hw_units = g->gr.tpc_count;
554
555
556 return gp10b_ecc_stat_create(dev, num_hw_units, num_subunits,
557 is_l2 ? ltc_unit_name : gr_unit_name,
558 num_subunits ? lts_unit_name: NULL,
559 ecc_stat_name,
560 ecc_stat,
561 dev_attr_array);
562}
563
564int gp10b_ecc_stat_create(struct device *dev,
565 int num_hw_units,
566 int num_subunits,
567 char *ecc_unit_name,
568 char *ecc_subunit_name,
569 char *ecc_stat_name,
570 struct gk20a_ecc_stat *ecc_stat,
571 struct device_attribute **__dev_attr_array)
572{
573 int error = 0;
574 struct gk20a *g = get_gk20a(dev);
575 int hw_unit = 0;
576 int subunit = 0;
577 int element = 0;
578 u32 hash_key = 0;
579 struct device_attribute *dev_attr_array;
580
581 int num_elements = num_subunits ? num_subunits*num_hw_units :
582 num_hw_units;
583
584 /* Allocate arrays */
585 dev_attr_array = nvgpu_kzalloc(g, sizeof(struct device_attribute) *
586 num_elements);
587 ecc_stat->counters = nvgpu_kzalloc(g, sizeof(u32) * num_elements);
588 ecc_stat->names = nvgpu_kzalloc(g, sizeof(char *) * num_elements);
589 for (hw_unit = 0; hw_unit < num_elements; hw_unit++) {
590 ecc_stat->names[hw_unit] = nvgpu_kzalloc(g, sizeof(char) *
591 ECC_STAT_NAME_MAX_SIZE);
592 }
593 ecc_stat->count = num_elements;
594 if (num_subunits) {
595 for (hw_unit = 0; hw_unit < num_hw_units; hw_unit++) {
596 for (subunit = 0; subunit < num_subunits; subunit++) {
597 element = hw_unit*num_subunits + subunit;
598
599 snprintf(ecc_stat->names[element],
600 ECC_STAT_NAME_MAX_SIZE,
601 "%s%d_%s%d_%s",
602 ecc_unit_name,
603 hw_unit,
604 ecc_subunit_name,
605 subunit,
606 ecc_stat_name);
607
608 sysfs_attr_init(&dev_attr_array[element].attr);
609 dev_attr_array[element].attr.name =
610 ecc_stat->names[element];
611 dev_attr_array[element].attr.mode =
612 VERIFY_OCTAL_PERMISSIONS(S_IRUGO);
613 dev_attr_array[element].show = ecc_stat_show;
614 dev_attr_array[element].store = NULL;
615
616 /* Create sysfs file */
617 error |= device_create_file(dev,
618 &dev_attr_array[element]);
619
620 }
621 }
622 } else {
623 for (hw_unit = 0; hw_unit < num_hw_units; hw_unit++) {
624
625 /* Fill in struct device_attribute members */
626 snprintf(ecc_stat->names[hw_unit],
627 ECC_STAT_NAME_MAX_SIZE,
628 "%s%d_%s",
629 ecc_unit_name,
630 hw_unit,
631 ecc_stat_name);
632
633 sysfs_attr_init(&dev_attr_array[hw_unit].attr);
634 dev_attr_array[hw_unit].attr.name =
635 ecc_stat->names[hw_unit];
636 dev_attr_array[hw_unit].attr.mode =
637 VERIFY_OCTAL_PERMISSIONS(S_IRUGO);
638 dev_attr_array[hw_unit].show = ecc_stat_show;
639 dev_attr_array[hw_unit].store = NULL;
640
641 /* Create sysfs file */
642 error |= device_create_file(dev,
643 &dev_attr_array[hw_unit]);
644 }
645 }
646
647 /* Add hash table entry */
648 hash_key = gen_ecc_hash_key(ecc_stat_name);
649 hash_add(ecc_hash_table,
650 &ecc_stat->hash_node,
651 hash_key);
652
653 *__dev_attr_array = dev_attr_array;
654
655 return error;
656}
657
658void gr_gp10b_ecc_stat_remove(struct device *dev,
659 int is_l2,
660 struct gk20a_ecc_stat *ecc_stat,
661 struct device_attribute *dev_attr_array)
662{
663 struct gk20a *g = get_gk20a(dev);
664 int num_hw_units = 0;
665
666 if (is_l2 == 1)
667 num_hw_units = g->ltc_count;
668 else if (is_l2 == 2)
669 num_hw_units = g->ltc_count * g->gr.slices_per_ltc;
670 else
671 num_hw_units = g->gr.tpc_count;
672
673 gp10b_ecc_stat_remove(dev, num_hw_units, ecc_stat, dev_attr_array);
674}
675
676void gp10b_ecc_stat_remove(struct device *dev,
677 int num_hw_units,
678 struct gk20a_ecc_stat *ecc_stat,
679 struct device_attribute *dev_attr_array)
680{
681 struct gk20a *g = get_gk20a(dev);
682 int hw_unit = 0;
683
684 /* Remove sysfs files */
685 for (hw_unit = 0; hw_unit < num_hw_units; hw_unit++) {
686 device_remove_file(dev, &dev_attr_array[hw_unit]);
687 }
688
689 /* Remove hash table entry */
690 hash_del(&ecc_stat->hash_node);
691
692 /* Free arrays */
693 nvgpu_kfree(g, ecc_stat->counters);
694 for (hw_unit = 0; hw_unit < num_hw_units; hw_unit++) {
695 nvgpu_kfree(g, ecc_stat->names[hw_unit]);
696 }
697 nvgpu_kfree(g, ecc_stat->names);
698 nvgpu_kfree(g, dev_attr_array);
699}
700
701void gr_gp10b_create_sysfs(struct gk20a *g) 468void gr_gp10b_create_sysfs(struct gk20a *g)
702{ 469{
703 int error = 0; 470 int error = 0;