summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShridhar Rasal <srasal@nvidia.com>2016-12-19 08:33:35 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2016-12-26 12:46:48 -0500
commit0183deaaf76374631e545012c91e4dc6c6d76213 (patch)
treeefb2e86715bf87416307eefd32acff710ab158ff
parent1f0676334b884a075b25bc4c58083aa9b4906924 (diff)
video: tegra: host: dla: alloc cmd mem init time
- as per safety coding guidelines and for command path submission improvement, move memory allocation for engine cmds during device init - allocate memory in pool, based on number of max commands supported and max memory requirement - for memory request, use bitmap and based on available bit, get memory offset within pool Jira DLA-243 Change-Id: I28c8c02b3d99b42128d1990e7f342952286e4eb3 Signed-off-by: Shridhar Rasal <srasal@nvidia.com> Reviewed-on: http://git-master/r/1274300 Reviewed-by: Prashant Gaikwad <pgaikwad@nvidia.com> GVS: Gerrit_Virtual_Submit
-rw-r--r--drivers/video/tegra/host/nvdla/nvdla.c133
-rw-r--r--drivers/video/tegra/host/nvdla/nvdla.h31
2 files changed, 139 insertions, 25 deletions
diff --git a/drivers/video/tegra/host/nvdla/nvdla.c b/drivers/video/tegra/host/nvdla/nvdla.c
index f329d7369..82cef87c3 100644
--- a/drivers/video/tegra/host/nvdla/nvdla.c
+++ b/drivers/video/tegra/host/nvdla/nvdla.c
@@ -89,6 +89,87 @@ int nvhost_nvdla_flcn_isr(struct platform_device *pdev)
89} 89}
90 90
91/* Helper API's */ 91/* Helper API's */
92static int nvdla_alloc_cmd_memory(struct platform_device *pdev)
93{
94 struct nvhost_device_data *pdata = platform_get_drvdata(pdev);
95 struct nvdla_device *nvdla_dev = pdata->private_data;
96 int err = 0;
97
98 /* allocate memory for command */
99 nvdla_dev->cmd_mem_va = dma_alloc_attrs(&pdev->dev,
100 MAX_CMD_SIZE * MAX_COMMANDS_PER_DEVICE,
101 &nvdla_dev->cmd_mem_pa, GFP_KERNEL,
102 &attrs);
103
104 if (nvdla_dev->cmd_mem_va == NULL) {
105 err = -ENOMEM;
106 goto err_alloc_cmd_mem;
107 }
108
109 mutex_init(&nvdla_dev->cmd_mem_lock);
110 nvdla_dev->cmd_alloc_table = 0;
111
112err_alloc_cmd_mem:
113 return err;
114}
115
116static int nvdla_free_cmd_memory(struct platform_device *pdev)
117{
118 struct nvhost_device_data *pdata = platform_get_drvdata(pdev);
119 struct nvdla_device *nvdla_dev = pdata->private_data;
120
121 /* free memory for command */
122 dma_free_attrs(&pdev->dev,
123 MAX_CMD_SIZE * MAX_COMMANDS_PER_DEVICE,
124 nvdla_dev->cmd_mem_va, nvdla_dev->cmd_mem_pa, &attrs);
125
126 nvdla_dev->cmd_alloc_table = 0;
127
128 return 0;
129}
130
131int nvdla_get_cmd_memory(struct platform_device *pdev,
132 struct nvdla_cmd_mem_info *cmd_mem_info)
133{
134 struct nvhost_device_data *pdata = platform_get_drvdata(pdev);
135 struct nvdla_device *nvdla_dev = pdata->private_data;
136 int err = 0, index, offset;
137
138 mutex_lock(&nvdla_dev->cmd_mem_lock);
139
140 index = find_first_zero_bit(&nvdla_dev->cmd_alloc_table,
141 MAX_COMMANDS_PER_DEVICE);
142 if (index >= MAX_COMMANDS_PER_DEVICE) {
143 nvdla_dbg_err(pdev, "failed to get cmd mem from pool\n");
144 err = -EAGAIN;
145 goto err_get_mem;
146 }
147
148 /* assign mem */
149 set_bit(index, &nvdla_dev->cmd_alloc_table);
150
151 offset = NVDLA_CMD_OFFSET(index);
152 cmd_mem_info->va = nvdla_dev->cmd_mem_va + offset;
153 cmd_mem_info->pa = nvdla_dev->cmd_mem_pa + offset;
154 cmd_mem_info->index = index;
155
156err_get_mem:
157 mutex_unlock(&nvdla_dev->cmd_mem_lock);
158 return err;
159}
160
161int nvdla_put_cmd_memory(struct platform_device *pdev, int index)
162{
163 struct nvhost_device_data *pdata = platform_get_drvdata(pdev);
164 struct nvdla_device *nvdla_dev = pdata->private_data;
165
166 mutex_lock(&nvdla_dev->cmd_mem_lock);
167 clear_bit(index, &nvdla_dev->cmd_alloc_table);
168 mutex_unlock(&nvdla_dev->cmd_mem_lock);
169
170 return 0;
171}
172
92int nvdla_send_cmd(struct platform_device *pdev, 173int nvdla_send_cmd(struct platform_device *pdev,
93 uint32_t method_id, uint32_t method_data, bool wait) 174 uint32_t method_id, uint32_t method_data, bool wait)
94{ 175{
@@ -146,7 +227,7 @@ static int nvdla_alloc_trace_region(struct platform_device *pdev)
146{ 227{
147 int err = 0; 228 int err = 0;
148 struct flcn *m; 229 struct flcn *m;
149 dma_addr_t tregion_pa; 230 struct nvdla_cmd_mem_info trace_cmd_mem_info;
150 struct dla_region_printf *trace_region = NULL; 231 struct dla_region_printf *trace_region = NULL;
151 struct nvhost_device_data *pdata = platform_get_drvdata(pdev); 232 struct nvhost_device_data *pdata = platform_get_drvdata(pdev);
152 233
@@ -177,28 +258,25 @@ static int nvdla_alloc_trace_region(struct platform_device *pdev)
177 } 258 }
178 } 259 }
179 260
180 /* allocate memory for trace command */ 261 /* assign memory for trace command */
181 trace_region = (struct dla_region_printf *) 262 err = nvdla_get_cmd_memory(pdev, &trace_cmd_mem_info);
182 dma_alloc_attrs(&pdev->dev, 263 if (err) {
183 sizeof(struct dla_region_printf),
184 &tregion_pa, GFP_KERNEL, &attrs);
185 if (!trace_region) {
186 nvdla_dbg_err(pdev, 264 nvdla_dbg_err(pdev,
187 "dma allocation failed for trace command."); 265 "dma allocation failed for trace command.");
188 err = -ENOMEM;
189 goto alloc_trace_cmd_failed; 266 goto alloc_trace_cmd_failed;
190 } 267 }
191 268
269 trace_region = (struct dla_region_printf *)(trace_cmd_mem_info.va);
270
192 trace_region->region = DLA_REGION_TRACE; 271 trace_region->region = DLA_REGION_TRACE;
193 trace_region->address = m->trace_dump_pa; 272 trace_region->address = m->trace_dump_pa;
194 trace_region->size = TRACE_BUFFER_SIZE; 273 trace_region->size = TRACE_BUFFER_SIZE;
195 274
196 err = nvdla_send_cmd(pdev, DLA_CMD_SET_REGIONS, 275 err = nvdla_send_cmd(pdev, DLA_CMD_SET_REGIONS,
197 ALIGNED_DMA(tregion_pa), true); 276 ALIGNED_DMA(trace_cmd_mem_info.pa), true);
198 277
199 /* free memory allocated for trace command */ 278 /* release memory allocated for trace command */
200 dma_free_attrs(&pdev->dev, sizeof(struct dla_region_printf), 279 nvdla_put_cmd_memory(pdev, trace_cmd_mem_info.index);
201 trace_region, tregion_pa, &attrs);
202 280
203 if (err != 0) { 281 if (err != 0) {
204 nvdla_dbg_err(pdev, "failed to send trace command"); 282 nvdla_dbg_err(pdev, "failed to send trace command");
@@ -225,8 +303,8 @@ static int nvdla_alloc_dump_region(struct platform_device *pdev)
225{ 303{
226 int err = 0; 304 int err = 0;
227 struct flcn *m; 305 struct flcn *m;
228 dma_addr_t region_pa;
229 struct dla_region_printf *region; 306 struct dla_region_printf *region;
307 struct nvdla_cmd_mem_info debug_cmd_mem_info;
230 struct nvhost_device_data *pdata = platform_get_drvdata(pdev); 308 struct nvhost_device_data *pdata = platform_get_drvdata(pdev);
231 309
232 if (!pdata->flcn_isr) 310 if (!pdata->flcn_isr)
@@ -253,28 +331,25 @@ static int nvdla_alloc_dump_region(struct platform_device *pdev)
253 } 331 }
254 } 332 }
255 333
256 /* allocate memory for command */ 334 /* assign memory for command */
257 region = (struct dla_region_printf *)dma_alloc_attrs(&pdev->dev, 335 err = nvdla_get_cmd_memory(pdev, &debug_cmd_mem_info);
258 sizeof(struct dla_region_printf), 336 if (err) {
259 &region_pa, GFP_KERNEL, &attrs); 337 nvdla_dbg_err(pdev, "dma alloc for command failed");
260 if (!region) {
261 nvdla_dbg_err(pdev, "command region dma alloc failed");
262 err = -ENOMEM;
263 goto set_region_failed; 338 goto set_region_failed;
264 } 339 }
265 340
341 region = (struct dla_region_printf *)debug_cmd_mem_info.va;
266 region->region = DLA_REGION_PRINTF; 342 region->region = DLA_REGION_PRINTF;
267 region->address = ALIGNED_DMA(m->debug_dump_pa); 343 region->address = ALIGNED_DMA(m->debug_dump_pa);
268 region->size = DEBUG_BUFFER_SIZE; 344 region->size = DEBUG_BUFFER_SIZE;
269 345
270 /* pass dump region to falcon */ 346 /* pass dump region to falcon */
271 err = nvdla_send_cmd(pdev, DLA_CMD_SET_REGIONS, 347 err = nvdla_send_cmd(pdev, DLA_CMD_SET_REGIONS,
272 ALIGNED_DMA(region_pa), true); 348 ALIGNED_DMA(debug_cmd_mem_info.pa), true);
273 349
274 350
275 /* free memory allocated for debug print command */ 351 /* release memory allocated for debug print command */
276 dma_free_attrs(&pdev->dev, sizeof(struct dla_region_printf), 352 nvdla_put_cmd_memory(pdev, debug_cmd_mem_info.index);
277 region, region_pa, &attrs);
278 353
279 if (err != 0) { 354 if (err != 0) {
280 nvdla_dbg_err(pdev, "failed to send printf command"); 355 nvdla_dbg_err(pdev, "failed to send printf command");
@@ -458,14 +533,19 @@ static int nvdla_probe(struct platform_device *pdev)
458 err = PTR_ERR(nvdla_dev->pool); 533 err = PTR_ERR(nvdla_dev->pool);
459 goto err_queue_init; 534 goto err_queue_init;
460 } 535 }
536
461 err = nvhost_syncpt_unit_interface_init(pdev); 537 err = nvhost_syncpt_unit_interface_init(pdev);
462 if (err) 538 if (err)
463 goto err_mss_init; 539 goto err_mss_init;
464 540
541 err = nvdla_alloc_cmd_memory(pdev);
542 if (err)
543 goto err_alloc_cmd_mem;
544
465 nvdla_dbg_info(pdev, "%s: pdata:%p\n", __func__, pdata); 545 nvdla_dbg_info(pdev, "%s: pdata:%p\n", __func__, pdata);
466 546
467 return 0; 547 return 0;
468 548err_alloc_cmd_mem:
469err_mss_init: 549err_mss_init:
470 nvhost_queue_deinit(nvdla_dev->pool); 550 nvhost_queue_deinit(nvdla_dev->pool);
471err_queue_init: 551err_queue_init:
@@ -513,6 +593,9 @@ static int __exit nvdla_remove(struct platform_device *pdev)
513 m->debug_dump_pa = 0; 593 m->debug_dump_pa = 0;
514 } 594 }
515 595
596 /* free command mem in last */
597 nvdla_free_cmd_memory(pdev);
598
516 nvdla_dbg_fn(pdev, ""); 599 nvdla_dbg_fn(pdev, "");
517 600
518 return 0; 601 return 0;
diff --git a/drivers/video/tegra/host/nvdla/nvdla.h b/drivers/video/tegra/host/nvdla/nvdla.h
index 3c9b20723..0694be728 100644
--- a/drivers/video/tegra/host/nvdla/nvdla.h
+++ b/drivers/video/tegra/host/nvdla/nvdla.h
@@ -26,6 +26,8 @@
26#include <linux/nvhost_nvdla_ioctl.h> 26#include <linux/nvhost_nvdla_ioctl.h>
27#include "nvhost_buffer.h" 27#include "nvhost_buffer.h"
28 28
29#include "dla_os_interface.h"
30
29/** 31/**
30 * Method ID and Method data THI registers 32 * Method ID and Method data THI registers
31 */ 33 */
@@ -58,6 +60,26 @@
58#define MAX_NUM_NVDLA_POSTFENCES 4 60#define MAX_NUM_NVDLA_POSTFENCES 4
59 61
60/** 62/**
63 * keep list of DLA command size here.
64 * max among them will be used to allocate memory
65 *
66 */
67union nvdla_cmd_mem_list {
68 struct dla_region_printf dont_use_me;
69};
70
71#define MAX_COMMANDS_PER_DEVICE 1
72#define MAX_CMD_SIZE sizeof(union nvdla_cmd_mem_list)
73#define NVDLA_CMD_OFFSET(index) (MAX_CMD_SIZE * index)
74
75struct nvdla_cmd_mem_info {
76 dma_addr_t pa;
77 void *va;
78 int index;
79};
80
81
82/**
61 * data structure to keep per DLA engine device data 83 * data structure to keep per DLA engine device data
62 * 84 *
63 * @pdev pointer to platform device 85 * @pdev pointer to platform device
@@ -75,6 +97,12 @@ struct nvdla_device {
75 u32 dbg_mask; 97 u32 dbg_mask;
76 u32 en_trace; 98 u32 en_trace;
77 u32 fw_version; 99 u32 fw_version;
100
101 /* cmd memory fields */
102 dma_addr_t cmd_mem_pa;
103 void *cmd_mem_va;
104 struct mutex cmd_mem_lock;
105 unsigned long cmd_alloc_table;
78}; 106};
79 107
80/** 108/**
@@ -221,5 +249,8 @@ int nvdla_fill_task_desc(struct nvdla_task *task);
221int nvdla_send_postfences(struct nvdla_task *task, 249int nvdla_send_postfences(struct nvdla_task *task,
222 struct nvdla_ioctl_submit_task usr_task); 250 struct nvdla_ioctl_submit_task usr_task);
223 251
252int nvdla_get_cmd_memory(struct platform_device *pdev,
253 struct nvdla_cmd_mem_info *cmd_mem_info);
254int nvdla_put_cmd_memory(struct platform_device *pdev, int index);
224 255
225#endif /* End of __NVHOST_NVDLA_H__ */ 256#endif /* End of __NVHOST_NVDLA_H__ */