summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/mm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/common/mm')
-rw-r--r--drivers/gpu/nvgpu/common/mm/vm.c136
1 files changed, 92 insertions, 44 deletions
diff --git a/drivers/gpu/nvgpu/common/mm/vm.c b/drivers/gpu/nvgpu/common/mm/vm.c
index cfac4f8e..be7e4207 100644
--- a/drivers/gpu/nvgpu/common/mm/vm.c
+++ b/drivers/gpu/nvgpu/common/mm/vm.c
@@ -39,6 +39,20 @@
39#include "gk20a/gk20a.h" 39#include "gk20a/gk20a.h"
40#include "gk20a/mm_gk20a.h" 40#include "gk20a/mm_gk20a.h"
41 41
42struct nvgpu_ctag_buffer_info {
43 u64 size;
44 enum gmmu_pgsz_gk20a pgsz_idx;
45 u32 flags;
46
47 s16 compr_kind;
48 s16 incompr_kind;
49
50 u32 ctag_lines;
51};
52
53static int nvgpu_vm_compute_compression(struct vm_gk20a *vm,
54 struct nvgpu_ctag_buffer_info *binfo);
55
42static void __nvgpu_vm_unmap(struct nvgpu_mapped_buf *mapped_buffer, 56static void __nvgpu_vm_unmap(struct nvgpu_mapped_buf *mapped_buffer,
43 struct vm_gk20a_mapping_batch *batch); 57 struct vm_gk20a_mapping_batch *batch);
44 58
@@ -731,11 +745,10 @@ struct nvgpu_mapped_buf *nvgpu_vm_map(struct vm_gk20a *vm,
731 struct gk20a *g = gk20a_from_vm(vm); 745 struct gk20a *g = gk20a_from_vm(vm);
732 struct nvgpu_mapped_buf *mapped_buffer = NULL; 746 struct nvgpu_mapped_buf *mapped_buffer = NULL;
733 struct nvgpu_ctag_buffer_info binfo = { 0 }; 747 struct nvgpu_ctag_buffer_info binfo = { 0 };
734 struct gk20a_comptags comptags;
735 struct nvgpu_vm_area *vm_area = NULL; 748 struct nvgpu_vm_area *vm_area = NULL;
736 int err = 0; 749 int err = 0;
737 u64 align; 750 u64 align;
738 u32 ctag_offset; 751 u32 ctag_offset = 0;
739 bool clear_ctags = false; 752 bool clear_ctags = false;
740 bool va_allocated = true; 753 bool va_allocated = true;
741 754
@@ -746,6 +759,11 @@ struct nvgpu_mapped_buf *nvgpu_vm_map(struct vm_gk20a *vm,
746 */ 759 */
747 s16 map_key_kind; 760 s16 map_key_kind;
748 761
762 /*
763 * The actual GMMU PTE kind
764 */
765 u8 pte_kind;
766
749 if (vm->userspace_managed && 767 if (vm->userspace_managed &&
750 !(flags & NVGPU_AS_MAP_BUFFER_FLAGS_FIXED_OFFSET)) { 768 !(flags & NVGPU_AS_MAP_BUFFER_FLAGS_FIXED_OFFSET)) {
751 nvgpu_err(g, 769 nvgpu_err(g,
@@ -835,57 +853,91 @@ struct nvgpu_mapped_buf *nvgpu_vm_map(struct vm_gk20a *vm,
835 if (!vm->enable_ctag) 853 if (!vm->enable_ctag)
836 binfo.ctag_lines = 0; 854 binfo.ctag_lines = 0;
837 855
838 gk20a_get_comptags(os_buf, &comptags); 856 if (binfo.ctag_lines) {
857 struct gk20a_comptags comptags = { 0 };
839 858
840 if (binfo.ctag_lines && !comptags.lines) {
841 /* 859 /*
842 * Allocate compression resources if needed. 860 * Get the comptags state
843 */ 861 */
844 if (gk20a_alloc_comptags(g, 862 gk20a_get_comptags(os_buf, &comptags);
845 os_buf,
846 &g->gr.comp_tags,
847 binfo.ctag_lines)) {
848
849 /*
850 * Prevent compression...
851 */
852 binfo.compr_kind = NV_KIND_INVALID;
853
854 /*
855 * ... And make sure we have a fallback.
856 */
857 if (binfo.incompr_kind == NV_KIND_INVALID) {
858 nvgpu_err(g, "comptag alloc failed and no "
859 "fallback kind specified");
860 err = -ENOMEM;
861 863
864 /*
865 * Allocate if not yet allocated
866 */
867 if (!comptags.allocated) {
868 err = gk20a_alloc_comptags(g, os_buf,
869 &g->gr.comp_tags,
870 binfo.ctag_lines);
871 if (err) {
862 /* 872 /*
863 * Any alloced comptags are cleaned up when the 873 * This is an irrecoverable failure and we need
864 * dmabuf is freed. 874 * to abort. In particular, it is not safe to
875 * proceed with incompressible fallback, since
876 * we could not mark our alloc failure
877 * anywere. Later we would retry allocation and
878 * break compressible map aliasing.
865 */ 879 */
880 nvgpu_err(g,
881 "Error %d setting up comptags", err);
866 goto clean_up; 882 goto clean_up;
867 } 883 }
868 } else { 884
885 /*
886 * Refresh comptags state after alloc. Field
887 * comptags.lines will be 0 if alloc failed.
888 */
869 gk20a_get_comptags(os_buf, &comptags); 889 gk20a_get_comptags(os_buf, &comptags);
870 890
871 if (g->ops.ltc.cbc_ctrl) 891 /*
872 g->ops.ltc.cbc_ctrl(g, gk20a_cbc_op_clear, 892 * Newly allocated comptags needs to be cleared
873 comptags.offset, 893 */
874 comptags.offset + 894 if (comptags.lines) {
875 comptags.allocated_lines - 1); 895 if (g->ops.ltc.cbc_ctrl)
876 else 896 g->ops.ltc.cbc_ctrl(
877 clear_ctags = true; 897 g, gk20a_cbc_op_clear,
898 comptags.offset,
899 (comptags.offset +
900 comptags.lines - 1));
901 else
902 /*
903 * The comptags will be cleared as part
904 * of mapping (vgpu)
905 */
906 clear_ctags = true;
907 }
878 } 908 }
909
910 /*
911 * Store the ctag offset for later use if we got the comptags
912 */
913 if (comptags.lines)
914 ctag_offset = comptags.offset;
879 } 915 }
880 916
881 /* 917 /*
882 * Calculate comptag index for this mapping. Differs in case of partial 918 * Figure out the kind and ctag offset for the GMMU page tables
883 * mapping.
884 */ 919 */
885 ctag_offset = comptags.offset; 920 if (binfo.compr_kind != NV_KIND_INVALID && ctag_offset) {
886 if (ctag_offset) 921 /*
922 * Adjust the ctag_offset as per the buffer map offset
923 */
887 ctag_offset += phys_offset >> 924 ctag_offset += phys_offset >>
888 ilog2(g->ops.fb.compression_page_size(g)); 925 ilog2(g->ops.fb.compression_page_size(g));
926 pte_kind = binfo.compr_kind;
927 } else if (binfo.incompr_kind != NV_KIND_INVALID) {
928 /*
929 * Incompressible kind, ctag offset will not be programmed
930 */
931 ctag_offset = 0;
932 pte_kind = binfo.incompr_kind;
933 } else {
934 /*
935 * Caller required compression, but we cannot provide it
936 */
937 nvgpu_err(g, "No comptags and no incompressible fallback kind");
938 err = -ENOMEM;
939 goto clean_up;
940 }
889 941
890 map_addr = g->ops.mm.gmmu_map(vm, 942 map_addr = g->ops.mm.gmmu_map(vm,
891 map_addr, 943 map_addr,
@@ -893,8 +945,7 @@ struct nvgpu_mapped_buf *nvgpu_vm_map(struct vm_gk20a *vm,
893 phys_offset, 945 phys_offset,
894 map_size, 946 map_size,
895 binfo.pgsz_idx, 947 binfo.pgsz_idx,
896 binfo.compr_kind != NV_KIND_INVALID ? 948 pte_kind,
897 binfo.compr_kind : binfo.incompr_kind,
898 ctag_offset, 949 ctag_offset,
899 flags, 950 flags,
900 rw, 951 rw,
@@ -913,9 +964,6 @@ struct nvgpu_mapped_buf *nvgpu_vm_map(struct vm_gk20a *vm,
913 mapped_buffer->addr = map_addr; 964 mapped_buffer->addr = map_addr;
914 mapped_buffer->size = map_size; 965 mapped_buffer->size = map_size;
915 mapped_buffer->pgsz_idx = binfo.pgsz_idx; 966 mapped_buffer->pgsz_idx = binfo.pgsz_idx;
916 mapped_buffer->ctag_offset = ctag_offset;
917 mapped_buffer->ctag_lines = binfo.ctag_lines;
918 mapped_buffer->ctag_allocated_lines = comptags.allocated_lines;
919 mapped_buffer->vm = vm; 967 mapped_buffer->vm = vm;
920 mapped_buffer->flags = flags; 968 mapped_buffer->flags = flags;
921 mapped_buffer->kind = map_key_kind; 969 mapped_buffer->kind = map_key_kind;
@@ -1074,8 +1122,8 @@ done:
1074 return; 1122 return;
1075} 1123}
1076 1124
1077int nvgpu_vm_compute_compression(struct vm_gk20a *vm, 1125static int nvgpu_vm_compute_compression(struct vm_gk20a *vm,
1078 struct nvgpu_ctag_buffer_info *binfo) 1126 struct nvgpu_ctag_buffer_info *binfo)
1079{ 1127{
1080 bool kind_compressible = (binfo->compr_kind != NV_KIND_INVALID); 1128 bool kind_compressible = (binfo->compr_kind != NV_KIND_INVALID);
1081 struct gk20a *g = gk20a_from_vm(vm); 1129 struct gk20a *g = gk20a_from_vm(vm);