diff options
author | Terje Bergstrom <tbergstrom@nvidia.com> | 2015-03-19 17:17:15 -0400 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2015-04-04 22:01:36 -0400 |
commit | 2fc4169293b6929716ee623324dfc9a0d0183b10 (patch) | |
tree | 8ad11fdfdb77f60b6322034dab809ae4a72158e2 /drivers/gpu/nvgpu/gk20a | |
parent | 672680dfc069f08722b98f52097106021c7e2b0f (diff) |
gpu: nvgpu: Use common allocator for cmd queue
Reduce amount of duplicate code around memory allocation by using
common helpers, and common data structure for storing results of
allocations.
Bug 1605769
Change-Id: If93063acbbfaa92aef530208241988427b5df8eb
Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-on: http://git-master/r/719871
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 58 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.h | 9 |
2 files changed, 10 insertions, 57 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index e11ecc8b..598237ab 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |||
@@ -864,8 +864,6 @@ static int channel_gk20a_alloc_priv_cmdbuf(struct channel_gk20a *c) | |||
864 | struct priv_cmd_entry *e; | 864 | struct priv_cmd_entry *e; |
865 | u32 i = 0, size; | 865 | u32 i = 0, size; |
866 | int err = 0; | 866 | int err = 0; |
867 | struct sg_table *sgt; | ||
868 | dma_addr_t iova; | ||
869 | 867 | ||
870 | /* Kernel can insert gpfifos before and after user gpfifos. | 868 | /* Kernel can insert gpfifos before and after user gpfifos. |
871 | Before user gpfifos, kernel inserts fence_wait, which takes | 869 | Before user gpfifos, kernel inserts fence_wait, which takes |
@@ -879,38 +877,12 @@ static int channel_gk20a_alloc_priv_cmdbuf(struct channel_gk20a *c) | |||
879 | size = roundup_pow_of_two( | 877 | size = roundup_pow_of_two( |
880 | c->gpfifo.entry_num * 2 * 10 * sizeof(u32) / 3); | 878 | c->gpfifo.entry_num * 2 * 10 * sizeof(u32) / 3); |
881 | 879 | ||
882 | q->mem.base_cpuva = dma_alloc_coherent(d, size, | 880 | err = gk20a_gmmu_alloc_map(ch_vm, size, &q->mem); |
883 | &iova, | ||
884 | GFP_KERNEL); | ||
885 | if (!q->mem.base_cpuva) { | ||
886 | gk20a_err(d, "%s: memory allocation failed\n", __func__); | ||
887 | err = -ENOMEM; | ||
888 | goto clean_up; | ||
889 | } | ||
890 | |||
891 | q->mem.base_iova = iova; | ||
892 | q->mem.size = size; | ||
893 | |||
894 | err = gk20a_get_sgtable(d, &sgt, | ||
895 | q->mem.base_cpuva, q->mem.base_iova, size); | ||
896 | if (err) { | 881 | if (err) { |
897 | gk20a_err(d, "%s: failed to create sg table\n", __func__); | 882 | gk20a_err(d, "%s: memory allocation failed\n", __func__); |
898 | goto clean_up; | 883 | goto clean_up; |
899 | } | 884 | } |
900 | 885 | ||
901 | memset(q->mem.base_cpuva, 0, size); | ||
902 | |||
903 | q->base_gpuva = gk20a_gmmu_map(ch_vm, &sgt, | ||
904 | size, | ||
905 | 0, /* flags */ | ||
906 | gk20a_mem_flag_none); | ||
907 | if (!q->base_gpuva) { | ||
908 | gk20a_err(d, "ch %d : failed to map gpu va" | ||
909 | "for priv cmd buffer", c->hw_chid); | ||
910 | err = -ENOMEM; | ||
911 | goto clean_up_sgt; | ||
912 | } | ||
913 | |||
914 | q->size = q->mem.size / sizeof (u32); | 886 | q->size = q->mem.size / sizeof (u32); |
915 | 887 | ||
916 | INIT_LIST_HEAD(&q->head); | 888 | INIT_LIST_HEAD(&q->head); |
@@ -923,18 +895,14 @@ static int channel_gk20a_alloc_priv_cmdbuf(struct channel_gk20a *c) | |||
923 | gk20a_err(d, "ch %d: fail to pre-alloc cmd entry", | 895 | gk20a_err(d, "ch %d: fail to pre-alloc cmd entry", |
924 | c->hw_chid); | 896 | c->hw_chid); |
925 | err = -ENOMEM; | 897 | err = -ENOMEM; |
926 | goto clean_up_sgt; | 898 | goto clean_up; |
927 | } | 899 | } |
928 | e->pre_alloc = true; | 900 | e->pre_alloc = true; |
929 | list_add(&e->list, &q->free); | 901 | list_add(&e->list, &q->free); |
930 | } | 902 | } |
931 | 903 | ||
932 | gk20a_free_sgtable(&sgt); | ||
933 | |||
934 | return 0; | 904 | return 0; |
935 | 905 | ||
936 | clean_up_sgt: | ||
937 | gk20a_free_sgtable(&sgt); | ||
938 | clean_up: | 906 | clean_up: |
939 | channel_gk20a_free_priv_cmdbuf(c); | 907 | channel_gk20a_free_priv_cmdbuf(c); |
940 | return err; | 908 | return err; |
@@ -942,7 +910,6 @@ clean_up: | |||
942 | 910 | ||
943 | static void channel_gk20a_free_priv_cmdbuf(struct channel_gk20a *c) | 911 | static void channel_gk20a_free_priv_cmdbuf(struct channel_gk20a *c) |
944 | { | 912 | { |
945 | struct device *d = dev_from_gk20a(c->g); | ||
946 | struct vm_gk20a *ch_vm = c->vm; | 913 | struct vm_gk20a *ch_vm = c->vm; |
947 | struct priv_cmd_queue *q = &c->priv_cmd_q; | 914 | struct priv_cmd_queue *q = &c->priv_cmd_q; |
948 | struct priv_cmd_entry *e; | 915 | struct priv_cmd_entry *e; |
@@ -951,14 +918,7 @@ static void channel_gk20a_free_priv_cmdbuf(struct channel_gk20a *c) | |||
951 | if (q->size == 0) | 918 | if (q->size == 0) |
952 | return; | 919 | return; |
953 | 920 | ||
954 | if (q->base_gpuva) | 921 | gk20a_gmmu_unmap_free(ch_vm, &q->mem); |
955 | gk20a_gmmu_unmap(ch_vm, q->base_gpuva, | ||
956 | q->mem.size, gk20a_mem_flag_none); | ||
957 | if (q->mem.base_cpuva) | ||
958 | dma_free_coherent(d, q->mem.size, | ||
959 | q->mem.base_cpuva, q->mem.base_iova); | ||
960 | q->mem.base_cpuva = NULL; | ||
961 | q->mem.base_iova = 0; | ||
962 | 922 | ||
963 | /* free used list */ | 923 | /* free used list */ |
964 | head = &q->head; | 924 | head = &q->head; |
@@ -1039,12 +999,12 @@ TRY_AGAIN: | |||
1039 | /* if we have increased size to skip free space in the end, set put | 999 | /* if we have increased size to skip free space in the end, set put |
1040 | to beginning of cmd buffer (0) + size */ | 1000 | to beginning of cmd buffer (0) + size */ |
1041 | if (size != orig_size) { | 1001 | if (size != orig_size) { |
1042 | e->ptr = q->mem.base_cpuva; | 1002 | e->ptr = (u32 *)q->mem.cpu_va; |
1043 | e->gva = q->base_gpuva; | 1003 | e->gva = q->mem.gpu_va; |
1044 | q->put = orig_size; | 1004 | q->put = orig_size; |
1045 | } else { | 1005 | } else { |
1046 | e->ptr = q->mem.base_cpuva + q->put; | 1006 | e->ptr = (u32 *)q->mem.cpu_va + q->put; |
1047 | e->gva = q->base_gpuva + q->put * sizeof(u32); | 1007 | e->gva = q->mem.gpu_va + q->put * sizeof(u32); |
1048 | q->put = (q->put + orig_size) & (q->size - 1); | 1008 | q->put = (q->put + orig_size) & (q->size - 1); |
1049 | } | 1009 | } |
1050 | 1010 | ||
@@ -1119,7 +1079,7 @@ static void recycle_priv_cmdbuf(struct channel_gk20a *c) | |||
1119 | } | 1079 | } |
1120 | 1080 | ||
1121 | if (found) | 1081 | if (found) |
1122 | q->get = (e->ptr - q->mem.base_cpuva) + e->size; | 1082 | q->get = (e->ptr - (u32 *)q->mem.cpu_va) + e->size; |
1123 | else { | 1083 | else { |
1124 | gk20a_dbg_info("no free entry recycled"); | 1084 | gk20a_dbg_info("no free entry recycled"); |
1125 | return; | 1085 | return; |
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h index ca7fef01..5ba34bd7 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h | |||
@@ -79,12 +79,6 @@ struct patch_desc { | |||
79 | u32 data_count; | 79 | u32 data_count; |
80 | }; | 80 | }; |
81 | 81 | ||
82 | struct priv_cmd_queue_mem_desc { | ||
83 | u64 base_iova; | ||
84 | u32 *base_cpuva; | ||
85 | size_t size; | ||
86 | }; | ||
87 | |||
88 | struct zcull_ctx_desc { | 82 | struct zcull_ctx_desc { |
89 | u64 gpu_va; | 83 | u64 gpu_va; |
90 | u32 ctx_attr; | 84 | u32 ctx_attr; |
@@ -176,8 +170,7 @@ struct gk20a_mm_entry { | |||
176 | }; | 170 | }; |
177 | 171 | ||
178 | struct priv_cmd_queue { | 172 | struct priv_cmd_queue { |
179 | struct priv_cmd_queue_mem_desc mem; | 173 | struct mem_desc mem; |
180 | u64 base_gpuva; /* gpu_va base */ | ||
181 | u32 size; /* num of entries in words */ | 174 | u32 size; /* num of entries in words */ |
182 | u32 put; /* put for priv cmd queue */ | 175 | u32 put; /* put for priv cmd queue */ |
183 | u32 get; /* get for priv cmd queue */ | 176 | u32 get; /* get for priv cmd queue */ |