diff options
| author | Shridhar Rasal <srasal@nvidia.com> | 2016-12-19 08:33:35 -0500 |
|---|---|---|
| committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2016-12-26 12:46:48 -0500 |
| commit | 0183deaaf76374631e545012c91e4dc6c6d76213 (patch) | |
| tree | efb2e86715bf87416307eefd32acff710ab158ff | |
| parent | 1f0676334b884a075b25bc4c58083aa9b4906924 (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.c | 133 | ||||
| -rw-r--r-- | drivers/video/tegra/host/nvdla/nvdla.h | 31 |
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 */ |
| 92 | static 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 | |||
| 112 | err_alloc_cmd_mem: | ||
| 113 | return err; | ||
| 114 | } | ||
| 115 | |||
| 116 | static 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 | |||
| 131 | int 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 | |||
| 156 | err_get_mem: | ||
| 157 | mutex_unlock(&nvdla_dev->cmd_mem_lock); | ||
| 158 | return err; | ||
| 159 | } | ||
| 160 | |||
| 161 | int 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 | |||
| 92 | int nvdla_send_cmd(struct platform_device *pdev, | 173 | int 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 | ®ion_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 | 548 | err_alloc_cmd_mem: | |
| 469 | err_mss_init: | 549 | err_mss_init: |
| 470 | nvhost_queue_deinit(nvdla_dev->pool); | 550 | nvhost_queue_deinit(nvdla_dev->pool); |
| 471 | err_queue_init: | 551 | err_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 | */ | ||
| 67 | union 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 | |||
| 75 | struct 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); | |||
| 221 | int nvdla_send_postfences(struct nvdla_task *task, | 249 | int 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 | ||
| 252 | int nvdla_get_cmd_memory(struct platform_device *pdev, | ||
| 253 | struct nvdla_cmd_mem_info *cmd_mem_info); | ||
| 254 | int 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__ */ |
