summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2015-03-19 17:17:08 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-04-04 22:01:37 -0400
commit92b667b88856240d3129912934d6e25e526c6d5e (patch)
tree046484500cbfa6f1bc7913d2f38d1acb04b5d2ff /drivers/gpu/nvgpu/gk20a/channel_gk20a.c
parent2fc4169293b6929716ee623324dfc9a0d0183b10 (diff)
gpu: nvgpu: Use common allocator for GPFIFO
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: I81701427ae29b298039a77f1634af9c14237812e Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/719872
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/channel_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c79
1 files changed, 17 insertions, 62 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index 598237ab..ec75b50e 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -557,7 +557,6 @@ static void gk20a_free_error_notifiers(struct channel_gk20a *ch)
557void gk20a_free_channel(struct channel_gk20a *ch, bool finish) 557void gk20a_free_channel(struct channel_gk20a *ch, bool finish)
558{ 558{
559 struct gk20a *g = ch->g; 559 struct gk20a *g = ch->g;
560 struct device *d = dev_from_gk20a(g);
561 struct fifo_gk20a *f = &g->fifo; 560 struct fifo_gk20a *f = &g->fifo;
562 struct gr_gk20a *gr = &g->gr; 561 struct gr_gk20a *gr = &g->gr;
563 struct vm_gk20a *ch_vm = ch->vm; 562 struct vm_gk20a *ch_vm = ch->vm;
@@ -597,15 +596,7 @@ void gk20a_free_channel(struct channel_gk20a *ch, bool finish)
597 596
598 memset(&ch->ramfc, 0, sizeof(struct mem_desc_sub)); 597 memset(&ch->ramfc, 0, sizeof(struct mem_desc_sub));
599 598
600 /* free gpfifo */ 599 gk20a_gmmu_unmap_free(ch_vm, &ch->gpfifo.mem);
601 if (ch->gpfifo.gpu_va)
602 gk20a_gmmu_unmap(ch_vm, ch->gpfifo.gpu_va,
603 ch->gpfifo.size, gk20a_mem_flag_none);
604 if (ch->gpfifo.cpu_va)
605 dma_free_coherent(d, ch->gpfifo.size,
606 ch->gpfifo.cpu_va, ch->gpfifo.iova);
607 ch->gpfifo.cpu_va = NULL;
608 ch->gpfifo.iova = 0;
609 600
610 memset(&ch->gpfifo, 0, sizeof(struct gpfifo_desc)); 601 memset(&ch->gpfifo, 0, sizeof(struct gpfifo_desc));
611 602
@@ -1101,8 +1092,6 @@ int gk20a_alloc_channel_gpfifo(struct channel_gk20a *c,
1101 struct vm_gk20a *ch_vm; 1092 struct vm_gk20a *ch_vm;
1102 u32 gpfifo_size; 1093 u32 gpfifo_size;
1103 int err = 0; 1094 int err = 0;
1104 struct sg_table *sgt;
1105 dma_addr_t iova;
1106 1095
1107 /* Kernel can insert one extra gpfifo entry before user submitted gpfifos 1096 /* Kernel can insert one extra gpfifo entry before user submitted gpfifos
1108 and another one after, for internal usage. Triple the requested size. */ 1097 and another one after, for internal usage. Triple the requested size. */
@@ -1131,53 +1120,28 @@ int gk20a_alloc_channel_gpfifo(struct channel_gk20a *c,
1131 c->ramfc.offset = 0; 1120 c->ramfc.offset = 0;
1132 c->ramfc.size = ram_in_ramfc_s() / 8; 1121 c->ramfc.size = ram_in_ramfc_s() / 8;
1133 1122
1134 if (c->gpfifo.cpu_va) { 1123 if (c->gpfifo.mem.cpu_va) {
1135 gk20a_err(d, "channel %d :" 1124 gk20a_err(d, "channel %d :"
1136 "gpfifo already allocated", c->hw_chid); 1125 "gpfifo already allocated", c->hw_chid);
1137 return -EEXIST; 1126 return -EEXIST;
1138 } 1127 }
1139 1128
1140 c->gpfifo.size = gpfifo_size * sizeof(struct gpfifo); 1129 err = gk20a_gmmu_alloc_map(ch_vm, gpfifo_size * sizeof(struct gpfifo),
1141 c->gpfifo.cpu_va = (struct gpfifo *)dma_alloc_coherent(d, 1130 &c->gpfifo.mem);
1142 c->gpfifo.size, 1131 if (err) {
1143 &iova,
1144 GFP_KERNEL);
1145 if (!c->gpfifo.cpu_va) {
1146 gk20a_err(d, "%s: memory allocation failed\n", __func__); 1132 gk20a_err(d, "%s: memory allocation failed\n", __func__);
1147 err = -ENOMEM;
1148 goto clean_up; 1133 goto clean_up;
1149 } 1134 }
1150 1135
1151 c->gpfifo.iova = iova;
1152 c->gpfifo.entry_num = gpfifo_size; 1136 c->gpfifo.entry_num = gpfifo_size;
1153
1154 c->gpfifo.get = c->gpfifo.put = 0; 1137 c->gpfifo.get = c->gpfifo.put = 0;
1155 1138
1156 err = gk20a_get_sgtable(d, &sgt,
1157 c->gpfifo.cpu_va, c->gpfifo.iova, c->gpfifo.size);
1158 if (err) {
1159 gk20a_err(d, "%s: failed to allocate sg table\n", __func__);
1160 goto clean_up;
1161 }
1162
1163 c->gpfifo.gpu_va = gk20a_gmmu_map(ch_vm,
1164 &sgt,
1165 c->gpfifo.size,
1166 0, /* flags */
1167 gk20a_mem_flag_none);
1168 if (!c->gpfifo.gpu_va) {
1169 gk20a_err(d, "channel %d : failed to map"
1170 " gpu_va for gpfifo", c->hw_chid);
1171 err = -ENOMEM;
1172 goto clean_up_sgt;
1173 }
1174
1175 gk20a_dbg_info("channel %d : gpfifo_base 0x%016llx, size %d", 1139 gk20a_dbg_info("channel %d : gpfifo_base 0x%016llx, size %d",
1176 c->hw_chid, c->gpfifo.gpu_va, c->gpfifo.entry_num); 1140 c->hw_chid, c->gpfifo.mem.gpu_va, c->gpfifo.entry_num);
1177 1141
1178 channel_gk20a_setup_userd(c); 1142 channel_gk20a_setup_userd(c);
1179 1143
1180 err = g->ops.fifo.setup_ramfc(c, c->gpfifo.gpu_va, c->gpfifo.entry_num); 1144 err = g->ops.fifo.setup_ramfc(c, c->gpfifo.mem.gpu_va, c->gpfifo.entry_num);
1181 if (err) 1145 if (err)
1182 goto clean_up_unmap; 1146 goto clean_up_unmap;
1183 1147
@@ -1193,21 +1157,12 @@ int gk20a_alloc_channel_gpfifo(struct channel_gk20a *c,
1193 1157
1194 g->ops.fifo.bind_channel(c); 1158 g->ops.fifo.bind_channel(c);
1195 1159
1196 gk20a_free_sgtable(&sgt);
1197
1198 gk20a_dbg_fn("done"); 1160 gk20a_dbg_fn("done");
1199 return 0; 1161 return 0;
1200 1162
1201clean_up_unmap: 1163clean_up_unmap:
1202 gk20a_gmmu_unmap(ch_vm, c->gpfifo.gpu_va, 1164 gk20a_gmmu_unmap_free(ch_vm, &c->gpfifo.mem);
1203 c->gpfifo.size, gk20a_mem_flag_none);
1204clean_up_sgt:
1205 gk20a_free_sgtable(&sgt);
1206clean_up: 1165clean_up:
1207 dma_free_coherent(d, c->gpfifo.size,
1208 c->gpfifo.cpu_va, c->gpfifo.iova);
1209 c->gpfifo.cpu_va = NULL;
1210 c->gpfifo.iova = 0;
1211 memset(&c->gpfifo, 0, sizeof(struct gpfifo_desc)); 1166 memset(&c->gpfifo, 0, sizeof(struct gpfifo_desc));
1212 gk20a_err(d, "fail"); 1167 gk20a_err(d, "fail");
1213 return err; 1168 return err;
@@ -1313,8 +1268,8 @@ static int gk20a_channel_submit_wfi(struct channel_gk20a *c)
1313 1268
1314 WARN_ON(!c->last_submit.post_fence->wfi); 1269 WARN_ON(!c->last_submit.post_fence->wfi);
1315 1270
1316 c->gpfifo.cpu_va[c->gpfifo.put].entry0 = u64_lo32(cmd->gva); 1271 ((struct gpfifo *)(c->gpfifo.mem.cpu_va))[c->gpfifo.put].entry0 = u64_lo32(cmd->gva);
1317 c->gpfifo.cpu_va[c->gpfifo.put].entry1 = u64_hi32(cmd->gva) | 1272 ((struct gpfifo *)(c->gpfifo.mem.cpu_va))[c->gpfifo.put].entry1 = u64_hi32(cmd->gva) |
1318 pbdma_gp_entry1_length_f(cmd->size); 1273 pbdma_gp_entry1_length_f(cmd->size);
1319 1274
1320 c->gpfifo.put = (c->gpfifo.put + 1) & (c->gpfifo.entry_num - 1); 1275 c->gpfifo.put = (c->gpfifo.put + 1) & (c->gpfifo.entry_num - 1);
@@ -1627,9 +1582,9 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
1627 } 1582 }
1628 1583
1629 if (wait_cmd) { 1584 if (wait_cmd) {
1630 c->gpfifo.cpu_va[c->gpfifo.put].entry0 = 1585 ((struct gpfifo *)(c->gpfifo.mem.cpu_va))[c->gpfifo.put].entry0 =
1631 u64_lo32(wait_cmd->gva); 1586 u64_lo32(wait_cmd->gva);
1632 c->gpfifo.cpu_va[c->gpfifo.put].entry1 = 1587 ((struct gpfifo *)(c->gpfifo.mem.cpu_va))[c->gpfifo.put].entry1 =
1633 u64_hi32(wait_cmd->gva) | 1588 u64_hi32(wait_cmd->gva) |
1634 pbdma_gp_entry1_length_f(wait_cmd->size); 1589 pbdma_gp_entry1_length_f(wait_cmd->size);
1635 trace_gk20a_push_cmdbuf(c->g->dev->name, 1590 trace_gk20a_push_cmdbuf(c->g->dev->name,
@@ -1654,16 +1609,16 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
1654 int length0 = c->gpfifo.entry_num - start; 1609 int length0 = c->gpfifo.entry_num - start;
1655 int length1 = num_entries - length0; 1610 int length1 = num_entries - length0;
1656 1611
1657 memcpy(c->gpfifo.cpu_va + start, gpfifo, 1612 memcpy((struct gpfifo *)c->gpfifo.mem.cpu_va + start, gpfifo,
1658 length0 * sizeof(*gpfifo)); 1613 length0 * sizeof(*gpfifo));
1659 1614
1660 memcpy(c->gpfifo.cpu_va, gpfifo + length0, 1615 memcpy((struct gpfifo *)c->gpfifo.mem.cpu_va, gpfifo + length0,
1661 length1 * sizeof(*gpfifo)); 1616 length1 * sizeof(*gpfifo));
1662 1617
1663 trace_write_pushbuffer_range(c, gpfifo, length0); 1618 trace_write_pushbuffer_range(c, gpfifo, length0);
1664 trace_write_pushbuffer_range(c, gpfifo + length0, length1); 1619 trace_write_pushbuffer_range(c, gpfifo + length0, length1);
1665 } else { 1620 } else {
1666 memcpy(c->gpfifo.cpu_va + start, gpfifo, 1621 memcpy((struct gpfifo *)c->gpfifo.mem.cpu_va + start, gpfifo,
1667 num_entries * sizeof(*gpfifo)); 1622 num_entries * sizeof(*gpfifo));
1668 1623
1669 trace_write_pushbuffer_range(c, gpfifo, num_entries); 1624 trace_write_pushbuffer_range(c, gpfifo, num_entries);
@@ -1672,9 +1627,9 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
1672 (c->gpfifo.entry_num - 1); 1627 (c->gpfifo.entry_num - 1);
1673 1628
1674 if (incr_cmd) { 1629 if (incr_cmd) {
1675 c->gpfifo.cpu_va[c->gpfifo.put].entry0 = 1630 ((struct gpfifo *)(c->gpfifo.mem.cpu_va))[c->gpfifo.put].entry0 =
1676 u64_lo32(incr_cmd->gva); 1631 u64_lo32(incr_cmd->gva);
1677 c->gpfifo.cpu_va[c->gpfifo.put].entry1 = 1632 ((struct gpfifo *)(c->gpfifo.mem.cpu_va))[c->gpfifo.put].entry1 =
1678 u64_hi32(incr_cmd->gva) | 1633 u64_hi32(incr_cmd->gva) |
1679 pbdma_gp_entry1_length_f(incr_cmd->size); 1634 pbdma_gp_entry1_length_f(incr_cmd->size);
1680 trace_gk20a_push_cmdbuf(c->g->dev->name, 1635 trace_gk20a_push_cmdbuf(c->g->dev->name,