|
@@ -427,7 +427,9 @@ void venus_hfi_queue_deinit(struct msm_vidc_core *core)
|
|
|
|
|
|
call_mem_op(core, memory_unmap_free, core, &core->iface_q_table.mem);
|
|
|
call_mem_op(core, memory_unmap_free, core, &core->sfr.mem);
|
|
|
- call_mem_op(core, iommu_unmap, core, &core->aon.mem);
|
|
|
+ call_mem_op(core, iommu_unmap, core, &core->aon_reg.mem);
|
|
|
+ call_mem_op(core, iommu_unmap, core, &core->fence_reg.mem);
|
|
|
+ call_mem_op(core, iommu_unmap, core, &core->qtimer_reg.mem);
|
|
|
call_mem_op(core, memory_unmap_free, core, &core->mmap_buf.mem);
|
|
|
call_mem_op(core, mem_dma_unmap_page, core,
|
|
|
&core->synx_fence_data.queue);
|
|
@@ -444,8 +446,14 @@ void venus_hfi_queue_deinit(struct msm_vidc_core *core)
|
|
|
core->sfr.align_virtual_addr = NULL;
|
|
|
core->sfr.align_device_addr = 0;
|
|
|
|
|
|
- core->aon.align_virtual_addr = NULL;
|
|
|
- core->aon.align_device_addr = 0;
|
|
|
+ core->aon_reg.align_virtual_addr = NULL;
|
|
|
+ core->aon_reg.align_device_addr = 0;
|
|
|
+
|
|
|
+ core->fence_reg.align_virtual_addr = NULL;
|
|
|
+ core->fence_reg.align_device_addr = 0;
|
|
|
+
|
|
|
+ core->qtimer_reg.align_virtual_addr = NULL;
|
|
|
+ core->qtimer_reg.align_device_addr = 0;
|
|
|
|
|
|
core->mmap_buf.align_virtual_addr = NULL;
|
|
|
core->mmap_buf.align_device_addr = 0;
|
|
@@ -490,13 +498,52 @@ int venus_hfi_reset_queue_header(struct msm_vidc_core *core)
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
+static int venus_hfi_iommu_map_registers(struct msm_vidc_core *core,
|
|
|
+ enum msm_vidc_device_region reg_region,
|
|
|
+ enum msm_vidc_buffer_region buf_region,
|
|
|
+ struct msm_vidc_mem_addr *core_mem)
|
|
|
+{
|
|
|
+ int rc = 0;
|
|
|
+ struct device_region_info *dev_reg;
|
|
|
+ struct msm_vidc_mem mem;
|
|
|
+
|
|
|
+ if (!core_mem) {
|
|
|
+ d_vpr_h("%s: invalid params\n", __func__);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ memset(&mem, 0, sizeof(mem));
|
|
|
+ dev_reg = venus_hfi_get_device_region_info(core, reg_region);
|
|
|
+ if (!dev_reg) {
|
|
|
+ d_vpr_h("%s: %u device region not available\n",
|
|
|
+ __func__, reg_region);
|
|
|
+ goto skip_mmap_buffer;
|
|
|
+ }
|
|
|
+
|
|
|
+ mem.region = buf_region;
|
|
|
+ mem.phys_addr = dev_reg->phy_addr;
|
|
|
+ mem.size = dev_reg->size;
|
|
|
+ mem.device_addr = dev_reg->dev_addr;
|
|
|
+ rc = call_mem_op(core, iommu_map, core, &mem);
|
|
|
+ if (rc) {
|
|
|
+ d_vpr_e("%s: %u map failed\n", __func__, reg_region);
|
|
|
+ goto fail_alloc_queue;
|
|
|
+ }
|
|
|
+ core_mem->align_device_addr = mem.device_addr;
|
|
|
+ core_mem->mem = mem;
|
|
|
+
|
|
|
+skip_mmap_buffer:
|
|
|
+ return 0;
|
|
|
+fail_alloc_queue:
|
|
|
+ return -ENOMEM;
|
|
|
+}
|
|
|
+
|
|
|
int venus_hfi_queue_init(struct msm_vidc_core *core)
|
|
|
{
|
|
|
int rc = 0;
|
|
|
struct hfi_queue_table_header *q_tbl_hdr;
|
|
|
struct hfi_queue_header *q_hdr;
|
|
|
struct msm_vidc_iface_q_info *iface_q;
|
|
|
- struct device_region_info *dev_reg;
|
|
|
struct msm_vidc_mem mem;
|
|
|
int offset = 0;
|
|
|
u32 *payload;
|
|
@@ -504,6 +551,11 @@ int venus_hfi_queue_init(struct msm_vidc_core *core)
|
|
|
|
|
|
d_vpr_h("%s()\n", __func__);
|
|
|
|
|
|
+ if (!core || !core->capabilities) {
|
|
|
+ d_vpr_h("%s: invalid params\n", __func__);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
if (core->iface_q_table.align_virtual_addr) {
|
|
|
d_vpr_h("%s: queues already allocated\n", __func__);
|
|
|
venus_hfi_reset_queue_header(core);
|
|
@@ -604,25 +656,25 @@ int venus_hfi_queue_init(struct msm_vidc_core *core)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /* map aon registers */
|
|
|
- memset(&mem, 0, sizeof(mem));
|
|
|
- dev_reg = venus_hfi_get_device_region_info(core, MSM_VIDC_AON_REGISTERS);
|
|
|
- if (!dev_reg) {
|
|
|
- d_vpr_h("%s: aon device region not available\n", __func__);
|
|
|
- goto skip_mmap_buffer;
|
|
|
- }
|
|
|
- mem.region = MSM_VIDC_NON_SECURE;
|
|
|
- mem.phys_addr = dev_reg->phy_addr;
|
|
|
- mem.size = dev_reg->size;
|
|
|
- mem.device_addr = dev_reg->dev_addr;
|
|
|
- rc = call_mem_op(core, iommu_map, core, &mem);
|
|
|
- if (rc) {
|
|
|
- d_vpr_e("%s: aon map failed\n", __func__);
|
|
|
- goto fail_alloc_queue;
|
|
|
- }
|
|
|
- core->aon.align_virtual_addr = mem.kvaddr;
|
|
|
- core->aon.align_device_addr = mem.device_addr;
|
|
|
- core->aon.mem = mem;
|
|
|
+ /* map aon_reg registers */
|
|
|
+ rc = venus_hfi_iommu_map_registers(core, MSM_VIDC_AON,
|
|
|
+ MSM_VIDC_NON_SECURE, &core->aon_reg);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+
|
|
|
+ /* map fence registers */
|
|
|
+ rc = venus_hfi_iommu_map_registers(core,
|
|
|
+ MSM_VIDC_PROTOCOL_FENCE_CLIENT_VPU,
|
|
|
+ MSM_VIDC_NON_SECURE, &core->fence_reg);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+
|
|
|
+ /* map qtimer low registers */
|
|
|
+ rc = venus_hfi_iommu_map_registers(core,
|
|
|
+ MSM_VIDC_QTIMER,
|
|
|
+ MSM_VIDC_NON_SECURE, &core->qtimer_reg);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
|
|
|
/* allocate 4k buffer for HFI_MMAP_ADDR */
|
|
|
memset(&mem, 0, sizeof(mem));
|
|
@@ -651,17 +703,31 @@ int venus_hfi_queue_init(struct msm_vidc_core *core)
|
|
|
* payload[9-10] : address and size of IPCC registers
|
|
|
* payload[11-12] : address and size of AON registers
|
|
|
* payload[13-14] : address and size of synx fence queue memory
|
|
|
+ * payload[19-20] : address and size of IPC_PROTOCOL4_CLIENT_VERSION registers
|
|
|
+ * payload[21-22] : address and size of FENCE QTIMER registers
|
|
|
*/
|
|
|
memset(core->mmap_buf.align_virtual_addr, 0, ALIGNED_MMAP_BUF_SIZE);
|
|
|
payload = ((u32 *)core->mmap_buf.align_virtual_addr);
|
|
|
payload[0] = 1;
|
|
|
- payload[11] = core->aon.mem.device_addr;
|
|
|
- payload[12] = core->aon.mem.size;
|
|
|
- payload[13] = core->synx_fence_data.queue.device_addr;
|
|
|
- payload[14] = core->synx_fence_data.queue.size;
|
|
|
+ if (core->aon_reg.mem.device_addr) {
|
|
|
+ payload[11] = core->aon_reg.mem.device_addr;
|
|
|
+ payload[12] = core->aon_reg.mem.size;
|
|
|
+ }
|
|
|
+ if (core->synx_fence_data.queue.device_addr) {
|
|
|
+ payload[13] = core->synx_fence_data.queue.device_addr;
|
|
|
+ payload[14] = core->synx_fence_data.queue.size;
|
|
|
+ }
|
|
|
+ if (core->fence_reg.mem.device_addr) {
|
|
|
+ payload[19] = core->fence_reg.mem.device_addr;
|
|
|
+ payload[20] = core->fence_reg.mem.size;
|
|
|
+ }
|
|
|
+ if (core->qtimer_reg.mem.device_addr) {
|
|
|
+ payload[21] = core->qtimer_reg.mem.device_addr;
|
|
|
+ payload[22] = core->qtimer_reg.mem.size;
|
|
|
+ }
|
|
|
|
|
|
-skip_mmap_buffer:
|
|
|
return 0;
|
|
|
+
|
|
|
fail_alloc_queue:
|
|
|
return -ENOMEM;
|
|
|
}
|