diff options
Diffstat (limited to 'drivers/gpu/nvgpu/common')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/driver_common.c | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/ioctl_dbg.c | 230 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/vgpu/dbg_vgpu.c | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/vgpu/dbg_vgpu.h | 4 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/vgpu/vgpu.c | 1 |
5 files changed, 232 insertions, 7 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/driver_common.c b/drivers/gpu/nvgpu/common/linux/driver_common.c index 9e567c27..45b53d88 100644 --- a/drivers/gpu/nvgpu/common/linux/driver_common.c +++ b/drivers/gpu/nvgpu/common/linux/driver_common.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "os_linux.h" | 31 | #include "os_linux.h" |
32 | #include "sysfs.h" | 32 | #include "sysfs.h" |
33 | #include "ioctl.h" | 33 | #include "ioctl.h" |
34 | #include "gk20a/regops_gk20a.h" | ||
34 | 35 | ||
35 | #define EMC3D_DEFAULT_RATIO 750 | 36 | #define EMC3D_DEFAULT_RATIO 750 |
36 | 37 | ||
diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_dbg.c b/drivers/gpu/nvgpu/common/linux/ioctl_dbg.c index 304fd71f..4bade485 100644 --- a/drivers/gpu/nvgpu/common/linux/ioctl_dbg.c +++ b/drivers/gpu/nvgpu/common/linux/ioctl_dbg.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include "platform_gk20a.h" | 40 | #include "platform_gk20a.h" |
41 | #include "ioctl_dbg.h" | 41 | #include "ioctl_dbg.h" |
42 | 42 | ||
43 | /* turn seriously unwieldy names -> something shorter */ | ||
44 | #define REGOP_LINUX(x) NVGPU_DBG_GPU_REG_OP_##x | ||
43 | 45 | ||
44 | /* silly allocator - just increment id */ | 46 | /* silly allocator - just increment id */ |
45 | static nvgpu_atomic_t unique_id = NVGPU_ATOMIC_INIT(0); | 47 | static nvgpu_atomic_t unique_id = NVGPU_ATOMIC_INIT(0); |
@@ -596,6 +598,204 @@ static int dbg_unbind_all_channels_gk20a(struct dbg_session_gk20a *dbg_s) | |||
596 | return 0; | 598 | return 0; |
597 | } | 599 | } |
598 | 600 | ||
601 | /* | ||
602 | * Convert common regops op values of the form of NVGPU_DBG_REG_OP_* | ||
603 | * into linux regops op values of the form of NVGPU_DBG_GPU_REG_OP_* | ||
604 | */ | ||
605 | static u32 nvgpu_get_regops_op_values_linux(u32 regops_op) | ||
606 | { | ||
607 | switch (regops_op) { | ||
608 | case REGOP(READ_32): | ||
609 | return REGOP_LINUX(READ_32); | ||
610 | case REGOP(WRITE_32): | ||
611 | return REGOP_LINUX(WRITE_32); | ||
612 | case REGOP(READ_64): | ||
613 | return REGOP_LINUX(READ_64); | ||
614 | case REGOP(WRITE_64): | ||
615 | return REGOP_LINUX(WRITE_64); | ||
616 | case REGOP(READ_08): | ||
617 | return REGOP_LINUX(READ_08); | ||
618 | case REGOP(WRITE_08): | ||
619 | return REGOP_LINUX(WRITE_08); | ||
620 | } | ||
621 | |||
622 | return regops_op; | ||
623 | } | ||
624 | |||
625 | /* | ||
626 | * Convert linux regops op values of the form of NVGPU_DBG_GPU_REG_OP_* | ||
627 | * into common regops op values of the form of NVGPU_DBG_REG_OP_* | ||
628 | */ | ||
629 | static u32 nvgpu_get_regops_op_values_common(u32 regops_op) | ||
630 | { | ||
631 | switch (regops_op) { | ||
632 | case REGOP_LINUX(READ_32): | ||
633 | return REGOP(READ_32); | ||
634 | case REGOP_LINUX(WRITE_32): | ||
635 | return REGOP(WRITE_32); | ||
636 | case REGOP_LINUX(READ_64): | ||
637 | return REGOP(READ_64); | ||
638 | case REGOP_LINUX(WRITE_64): | ||
639 | return REGOP(WRITE_64); | ||
640 | case REGOP_LINUX(READ_08): | ||
641 | return REGOP(READ_08); | ||
642 | case REGOP_LINUX(WRITE_08): | ||
643 | return REGOP(WRITE_08); | ||
644 | } | ||
645 | |||
646 | return regops_op; | ||
647 | } | ||
648 | |||
649 | /* | ||
650 | * Convert common regops type values of the form of NVGPU_DBG_REG_OP_TYPE_* | ||
651 | * into linux regops type values of the form of NVGPU_DBG_GPU_REG_OP_TYPE_* | ||
652 | */ | ||
653 | static u32 nvgpu_get_regops_type_values_linux(u32 regops_type) | ||
654 | { | ||
655 | switch (regops_type) { | ||
656 | case REGOP(TYPE_GLOBAL): | ||
657 | return REGOP_LINUX(TYPE_GLOBAL); | ||
658 | case REGOP(TYPE_GR_CTX): | ||
659 | return REGOP_LINUX(TYPE_GR_CTX); | ||
660 | case REGOP(TYPE_GR_CTX_TPC): | ||
661 | return REGOP_LINUX(TYPE_GR_CTX_TPC); | ||
662 | case REGOP(TYPE_GR_CTX_SM): | ||
663 | return REGOP_LINUX(TYPE_GR_CTX_SM); | ||
664 | case REGOP(TYPE_GR_CTX_CROP): | ||
665 | return REGOP_LINUX(TYPE_GR_CTX_CROP); | ||
666 | case REGOP(TYPE_GR_CTX_ZROP): | ||
667 | return REGOP_LINUX(TYPE_GR_CTX_ZROP); | ||
668 | case REGOP(TYPE_GR_CTX_QUAD): | ||
669 | return REGOP_LINUX(TYPE_GR_CTX_QUAD); | ||
670 | } | ||
671 | |||
672 | return regops_type; | ||
673 | } | ||
674 | |||
675 | /* | ||
676 | * Convert linux regops type values of the form of NVGPU_DBG_GPU_REG_OP_TYPE_* | ||
677 | * into common regops type values of the form of NVGPU_DBG_REG_OP_TYPE_* | ||
678 | */ | ||
679 | static u32 nvgpu_get_regops_type_values_common(u32 regops_type) | ||
680 | { | ||
681 | switch (regops_type) { | ||
682 | case REGOP_LINUX(TYPE_GLOBAL): | ||
683 | return REGOP(TYPE_GLOBAL); | ||
684 | case REGOP_LINUX(TYPE_GR_CTX): | ||
685 | return REGOP(TYPE_GR_CTX); | ||
686 | case REGOP_LINUX(TYPE_GR_CTX_TPC): | ||
687 | return REGOP(TYPE_GR_CTX_TPC); | ||
688 | case REGOP_LINUX(TYPE_GR_CTX_SM): | ||
689 | return REGOP(TYPE_GR_CTX_SM); | ||
690 | case REGOP_LINUX(TYPE_GR_CTX_CROP): | ||
691 | return REGOP(TYPE_GR_CTX_CROP); | ||
692 | case REGOP_LINUX(TYPE_GR_CTX_ZROP): | ||
693 | return REGOP(TYPE_GR_CTX_ZROP); | ||
694 | case REGOP_LINUX(TYPE_GR_CTX_QUAD): | ||
695 | return REGOP(TYPE_GR_CTX_QUAD); | ||
696 | } | ||
697 | |||
698 | return regops_type; | ||
699 | } | ||
700 | |||
701 | /* | ||
702 | * Convert common regops status values of the form of NVGPU_DBG_REG_OP_STATUS_* | ||
703 | * into linux regops type values of the form of NVGPU_DBG_GPU_REG_OP_STATUS_* | ||
704 | */ | ||
705 | static u32 nvgpu_get_regops_status_values_linux(u32 regops_status) | ||
706 | { | ||
707 | switch (regops_status) { | ||
708 | case REGOP(STATUS_SUCCESS): | ||
709 | return REGOP_LINUX(STATUS_SUCCESS); | ||
710 | case REGOP(STATUS_INVALID_OP): | ||
711 | return REGOP_LINUX(STATUS_INVALID_OP); | ||
712 | case REGOP(STATUS_INVALID_TYPE): | ||
713 | return REGOP_LINUX(STATUS_INVALID_TYPE); | ||
714 | case REGOP(STATUS_INVALID_OFFSET): | ||
715 | return REGOP_LINUX(STATUS_INVALID_OFFSET); | ||
716 | case REGOP(STATUS_UNSUPPORTED_OP): | ||
717 | return REGOP_LINUX(STATUS_UNSUPPORTED_OP); | ||
718 | case REGOP(STATUS_INVALID_MASK ): | ||
719 | return REGOP_LINUX(STATUS_INVALID_MASK); | ||
720 | } | ||
721 | |||
722 | return regops_status; | ||
723 | } | ||
724 | |||
725 | /* | ||
726 | * Convert linux regops status values of the form of NVGPU_DBG_GPU_REG_OP_STATUS_* | ||
727 | * into common regops type values of the form of NVGPU_DBG_REG_OP_STATUS_* | ||
728 | */ | ||
729 | static u32 nvgpu_get_regops_status_values_common(u32 regops_status) | ||
730 | { | ||
731 | switch (regops_status) { | ||
732 | case REGOP_LINUX(STATUS_SUCCESS): | ||
733 | return REGOP(STATUS_SUCCESS); | ||
734 | case REGOP_LINUX(STATUS_INVALID_OP): | ||
735 | return REGOP(STATUS_INVALID_OP); | ||
736 | case REGOP_LINUX(STATUS_INVALID_TYPE): | ||
737 | return REGOP(STATUS_INVALID_TYPE); | ||
738 | case REGOP_LINUX(STATUS_INVALID_OFFSET): | ||
739 | return REGOP(STATUS_INVALID_OFFSET); | ||
740 | case REGOP_LINUX(STATUS_UNSUPPORTED_OP): | ||
741 | return REGOP(STATUS_UNSUPPORTED_OP); | ||
742 | case REGOP_LINUX(STATUS_INVALID_MASK ): | ||
743 | return REGOP(STATUS_INVALID_MASK); | ||
744 | } | ||
745 | |||
746 | return regops_status; | ||
747 | } | ||
748 | |||
749 | static int nvgpu_get_regops_data_common(struct nvgpu_dbg_gpu_reg_op *in, | ||
750 | struct nvgpu_dbg_reg_op *out, u32 num_ops) | ||
751 | { | ||
752 | u32 i; | ||
753 | |||
754 | if(in == NULL || out == NULL) | ||
755 | return -ENOMEM; | ||
756 | |||
757 | for (i = 0; i < num_ops; i++) { | ||
758 | out[i].op = nvgpu_get_regops_op_values_common(in[i].op); | ||
759 | out[i].type = nvgpu_get_regops_type_values_common(in[i].type); | ||
760 | out[i].status = nvgpu_get_regops_status_values_common(in[i].status); | ||
761 | out[i].quad = in[i].quad; | ||
762 | out[i].group_mask = in[i].group_mask; | ||
763 | out[i].sub_group_mask = in[i].sub_group_mask; | ||
764 | out[i].offset = in[i].offset; | ||
765 | out[i].value_lo = in[i].value_lo; | ||
766 | out[i].value_hi = in[i].value_hi; | ||
767 | out[i].and_n_mask_lo = in[i].and_n_mask_lo; | ||
768 | out[i].and_n_mask_hi = in[i].and_n_mask_hi; | ||
769 | } | ||
770 | |||
771 | return 0; | ||
772 | } | ||
773 | |||
774 | static int nvgpu_get_regops_data_linux(struct nvgpu_dbg_reg_op *in, | ||
775 | struct nvgpu_dbg_gpu_reg_op *out, u32 num_ops) | ||
776 | { | ||
777 | u32 i; | ||
778 | |||
779 | if(in == NULL || out == NULL) | ||
780 | return -ENOMEM; | ||
781 | |||
782 | for (i = 0; i < num_ops; i++) { | ||
783 | out[i].op = nvgpu_get_regops_op_values_linux(in[i].op); | ||
784 | out[i].type = nvgpu_get_regops_type_values_linux(in[i].type); | ||
785 | out[i].status = nvgpu_get_regops_status_values_linux(in[i].status); | ||
786 | out[i].quad = in[i].quad; | ||
787 | out[i].group_mask = in[i].group_mask; | ||
788 | out[i].sub_group_mask = in[i].sub_group_mask; | ||
789 | out[i].offset = in[i].offset; | ||
790 | out[i].value_lo = in[i].value_lo; | ||
791 | out[i].value_hi = in[i].value_hi; | ||
792 | out[i].and_n_mask_lo = in[i].and_n_mask_lo; | ||
793 | out[i].and_n_mask_hi = in[i].and_n_mask_hi; | ||
794 | } | ||
795 | |||
796 | return 0; | ||
797 | } | ||
798 | |||
599 | static int nvgpu_ioctl_channel_reg_ops(struct dbg_session_gk20a *dbg_s, | 799 | static int nvgpu_ioctl_channel_reg_ops(struct dbg_session_gk20a *dbg_s, |
600 | struct nvgpu_dbg_gpu_exec_reg_ops_args *args) | 800 | struct nvgpu_dbg_gpu_exec_reg_ops_args *args) |
601 | { | 801 | { |
@@ -657,36 +857,56 @@ static int nvgpu_ioctl_channel_reg_ops(struct dbg_session_gk20a *dbg_s, | |||
657 | if (!powergate_err) { | 857 | if (!powergate_err) { |
658 | u64 ops_offset = 0; /* index offset */ | 858 | u64 ops_offset = 0; /* index offset */ |
659 | 859 | ||
860 | struct nvgpu_dbg_gpu_reg_op *linux_fragment = NULL; | ||
861 | |||
862 | linux_fragment = nvgpu_kzalloc(g, g->dbg_regops_tmp_buf_ops * | ||
863 | sizeof(struct nvgpu_dbg_gpu_reg_op)); | ||
864 | |||
865 | if (!linux_fragment) | ||
866 | return -ENOMEM; | ||
867 | |||
660 | while (ops_offset < args->num_ops && !err) { | 868 | while (ops_offset < args->num_ops && !err) { |
661 | const u64 num_ops = | 869 | const u64 num_ops = |
662 | min(args->num_ops - ops_offset, | 870 | min(args->num_ops - ops_offset, |
663 | (u64)(g->dbg_regops_tmp_buf_ops)); | 871 | (u64)(g->dbg_regops_tmp_buf_ops)); |
664 | const u64 fragment_size = | 872 | const u64 fragment_size = |
665 | num_ops * sizeof(g->dbg_regops_tmp_buf[0]); | 873 | num_ops * sizeof(struct nvgpu_dbg_gpu_reg_op); |
666 | 874 | ||
667 | void __user *const fragment = | 875 | void __user *const fragment = |
668 | (void __user *)(uintptr_t) | 876 | (void __user *)(uintptr_t) |
669 | (args->ops + | 877 | (args->ops + |
670 | ops_offset * sizeof(g->dbg_regops_tmp_buf[0])); | 878 | ops_offset * sizeof(struct nvgpu_dbg_gpu_reg_op)); |
671 | 879 | ||
672 | gk20a_dbg_fn("Regops fragment: start_op=%llu ops=%llu", | 880 | gk20a_dbg_fn("Regops fragment: start_op=%llu ops=%llu", |
673 | ops_offset, num_ops); | 881 | ops_offset, num_ops); |
674 | 882 | ||
675 | gk20a_dbg_fn("Copying regops from userspace"); | 883 | gk20a_dbg_fn("Copying regops from userspace"); |
676 | 884 | ||
677 | if (copy_from_user(g->dbg_regops_tmp_buf, | 885 | if (copy_from_user(linux_fragment, |
678 | fragment, fragment_size)) { | 886 | fragment, fragment_size)) { |
679 | nvgpu_err(g, "copy_from_user failed!"); | 887 | nvgpu_err(g, "copy_from_user failed!"); |
680 | err = -EFAULT; | 888 | err = -EFAULT; |
681 | break; | 889 | break; |
682 | } | 890 | } |
683 | 891 | ||
892 | err = nvgpu_get_regops_data_common(linux_fragment, | ||
893 | g->dbg_regops_tmp_buf, num_ops); | ||
894 | |||
895 | if (err) | ||
896 | break; | ||
897 | |||
684 | err = g->ops.dbg_session_ops.exec_reg_ops( | 898 | err = g->ops.dbg_session_ops.exec_reg_ops( |
685 | dbg_s, g->dbg_regops_tmp_buf, num_ops); | 899 | dbg_s, g->dbg_regops_tmp_buf, num_ops); |
686 | 900 | ||
901 | err = nvgpu_get_regops_data_linux(g->dbg_regops_tmp_buf, | ||
902 | linux_fragment, num_ops); | ||
903 | |||
904 | if (err) | ||
905 | break; | ||
906 | |||
687 | gk20a_dbg_fn("Copying result to userspace"); | 907 | gk20a_dbg_fn("Copying result to userspace"); |
688 | 908 | ||
689 | if (copy_to_user(fragment, g->dbg_regops_tmp_buf, | 909 | if (copy_to_user(fragment, linux_fragment, |
690 | fragment_size)) { | 910 | fragment_size)) { |
691 | nvgpu_err(g, "copy_to_user failed!"); | 911 | nvgpu_err(g, "copy_to_user failed!"); |
692 | err = -EFAULT; | 912 | err = -EFAULT; |
@@ -696,6 +916,8 @@ static int nvgpu_ioctl_channel_reg_ops(struct dbg_session_gk20a *dbg_s, | |||
696 | ops_offset += num_ops; | 916 | ops_offset += num_ops; |
697 | } | 917 | } |
698 | 918 | ||
919 | nvgpu_kfree(g, linux_fragment); | ||
920 | |||
699 | /* enable powergate, if previously disabled */ | 921 | /* enable powergate, if previously disabled */ |
700 | if (is_pg_disabled) { | 922 | if (is_pg_disabled) { |
701 | powergate_err = | 923 | powergate_err = |
diff --git a/drivers/gpu/nvgpu/common/linux/vgpu/dbg_vgpu.c b/drivers/gpu/nvgpu/common/linux/vgpu/dbg_vgpu.c index 06ef43b8..dfdbe3ee 100644 --- a/drivers/gpu/nvgpu/common/linux/vgpu/dbg_vgpu.c +++ b/drivers/gpu/nvgpu/common/linux/vgpu/dbg_vgpu.c | |||
@@ -21,13 +21,14 @@ | |||
21 | #include "gk20a/gk20a.h" | 21 | #include "gk20a/gk20a.h" |
22 | #include "gk20a/channel_gk20a.h" | 22 | #include "gk20a/channel_gk20a.h" |
23 | #include "gk20a/dbg_gpu_gk20a.h" | 23 | #include "gk20a/dbg_gpu_gk20a.h" |
24 | #include "gk20a/regops_gk20a.h" | ||
24 | #include "vgpu.h" | 25 | #include "vgpu.h" |
25 | #include "dbg_vgpu.h" | 26 | #include "dbg_vgpu.h" |
26 | 27 | ||
27 | #include <nvgpu/bug.h> | 28 | #include <nvgpu/bug.h> |
28 | 29 | ||
29 | int vgpu_exec_regops(struct dbg_session_gk20a *dbg_s, | 30 | int vgpu_exec_regops(struct dbg_session_gk20a *dbg_s, |
30 | struct nvgpu_dbg_gpu_reg_op *ops, | 31 | struct nvgpu_dbg_reg_op *ops, |
31 | u64 num_ops) | 32 | u64 num_ops) |
32 | { | 33 | { |
33 | struct channel_gk20a *ch; | 34 | struct channel_gk20a *ch; |
diff --git a/drivers/gpu/nvgpu/common/linux/vgpu/dbg_vgpu.h b/drivers/gpu/nvgpu/common/linux/vgpu/dbg_vgpu.h index 8552a82e..178767a2 100644 --- a/drivers/gpu/nvgpu/common/linux/vgpu/dbg_vgpu.h +++ b/drivers/gpu/nvgpu/common/linux/vgpu/dbg_vgpu.h | |||
@@ -18,12 +18,12 @@ | |||
18 | #define _DBG_VGPU_H_ | 18 | #define _DBG_VGPU_H_ |
19 | 19 | ||
20 | struct dbg_session_gk20a; | 20 | struct dbg_session_gk20a; |
21 | struct nvgpu_dbg_gpu_reg_op; | 21 | struct nvgpu_dbg_reg_op; |
22 | struct dbg_profiler_object_data; | 22 | struct dbg_profiler_object_data; |
23 | struct gk20a; | 23 | struct gk20a; |
24 | 24 | ||
25 | int vgpu_exec_regops(struct dbg_session_gk20a *dbg_s, | 25 | int vgpu_exec_regops(struct dbg_session_gk20a *dbg_s, |
26 | struct nvgpu_dbg_gpu_reg_op *ops, | 26 | struct nvgpu_dbg_reg_op *ops, |
27 | u64 num_ops); | 27 | u64 num_ops); |
28 | int vgpu_dbg_set_powergate(struct dbg_session_gk20a *dbg_s, bool disable_powergate); | 28 | int vgpu_dbg_set_powergate(struct dbg_session_gk20a *dbg_s, bool disable_powergate); |
29 | bool vgpu_check_and_set_global_reservation( | 29 | bool vgpu_check_and_set_global_reservation( |
diff --git a/drivers/gpu/nvgpu/common/linux/vgpu/vgpu.c b/drivers/gpu/nvgpu/common/linux/vgpu/vgpu.c index 7768b21d..f261d2ca 100644 --- a/drivers/gpu/nvgpu/common/linux/vgpu/vgpu.c +++ b/drivers/gpu/nvgpu/common/linux/vgpu/vgpu.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "clk_vgpu.h" | 36 | #include "clk_vgpu.h" |
37 | #include "gk20a/tsg_gk20a.h" | 37 | #include "gk20a/tsg_gk20a.h" |
38 | #include "gk20a/channel_gk20a.h" | 38 | #include "gk20a/channel_gk20a.h" |
39 | #include "gk20a/regops_gk20a.h" | ||
39 | #include "gm20b/hal_gm20b.h" | 40 | #include "gm20b/hal_gm20b.h" |
40 | 41 | ||
41 | #include "common/linux/module.h" | 42 | #include "common/linux/module.h" |