diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 79 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.h | 6 |
2 files changed, 18 insertions, 67 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) | |||
557 | void gk20a_free_channel(struct channel_gk20a *ch, bool finish) | 557 | void 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 | ||
1201 | clean_up_unmap: | 1163 | clean_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); | ||
1204 | clean_up_sgt: | ||
1205 | gk20a_free_sgtable(&sgt); | ||
1206 | clean_up: | 1165 | clean_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, |
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h index 5ba34bd7..2e0842f2 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h | |||
@@ -57,17 +57,13 @@ struct mem_desc_sub { | |||
57 | }; | 57 | }; |
58 | 58 | ||
59 | struct gpfifo_desc { | 59 | struct gpfifo_desc { |
60 | size_t size; | 60 | struct mem_desc mem; |
61 | u32 entry_num; | 61 | u32 entry_num; |
62 | 62 | ||
63 | u32 get; | 63 | u32 get; |
64 | u32 put; | 64 | u32 put; |
65 | 65 | ||
66 | bool wrap; | 66 | bool wrap; |
67 | |||
68 | u64 iova; | ||
69 | struct gpfifo *cpu_va; | ||
70 | u64 gpu_va; | ||
71 | }; | 67 | }; |
72 | 68 | ||
73 | struct patch_desc { | 69 | struct patch_desc { |