Pārlūkot izejas kodu

video: driver: Add support to map synx fence registers

Add support to map below mentioned registers
required for synx v2 fence support
- FENCE
- QTMR0_F0V1_QTMR_V1_CNTPCT_LO
- QTMR0_F0V1_QTMR_V1_CNTPCT_HI

Change-Id: I43a80ca9be282eb4bbfc46a8d62d875478619516
Signed-off-by: Akshata Sahukar <[email protected]>
Akshata Sahukar 2 gadi atpakaļ
vecāks
revīzija
eaf80f36cb

+ 15 - 1
driver/platform/pineapple/src/msm_vidc_pineapple.c

@@ -2658,7 +2658,21 @@ static const struct reg_preset_table pineapple_reg_preset_table[] = {
 
 /* name, phys_addr, size, device_addr, device region type */
 static const struct device_region_table pineapple_device_region_table[] = {
-	{ "aon-registers", 0x0AAE0000, 0x1000, 0xFFAE0000, MSM_VIDC_AON_REGISTERS },
+	{
+		"aon-registers",
+		0x0AAE0000, 0x1000, 0xFFAE0000,
+		MSM_VIDC_AON
+	},
+	{
+		"ipc_protocol4_client8_version-registers",
+		0x00508000, 0x1000, 0xFFADD000,
+		MSM_VIDC_PROTOCOL_FENCE_CLIENT_VPU
+	},
+	{
+		"qtimer_f0v1_qtmr_v1_cntpct_lo",
+		0x17421000, 0x1000, 0xFFADC000,
+		MSM_VIDC_QTIMER
+	},
 };
 
 /* decoder properties */

+ 3 - 1
driver/vidc/inc/msm_vidc_core.h

@@ -92,7 +92,9 @@ struct msm_vidc_core {
 	struct msm_vidc_mem_addr               sfr;
 	struct msm_vidc_mem_addr               iface_q_table;
 	struct msm_vidc_mem_addr               mmap_buf;
-	struct msm_vidc_mem_addr               aon;
+	struct msm_vidc_mem_addr               aon_reg;
+	struct msm_vidc_mem_addr               fence_reg;
+	struct msm_vidc_mem_addr               qtimer_reg;
 	struct msm_vidc_iface_q_info           iface_queues[VIDC_IFACEQ_NUMQ];
 	struct delayed_work                    pm_work;
 	struct workqueue_struct               *pm_workq;

+ 3 - 1
driver/vidc/inc/msm_vidc_internal.h

@@ -464,7 +464,9 @@ enum msm_vidc_buffer_region {
 
 enum msm_vidc_device_region {
 	MSM_VIDC_DEVICE_REGION_NONE = 0,
-	MSM_VIDC_AON_REGISTERS,
+	MSM_VIDC_AON,
+	MSM_VIDC_PROTOCOL_FENCE_CLIENT_VPU,
+	MSM_VIDC_QTIMER,
 	MSM_VIDC_DEVICE_REGION_MAX,
 };
 

+ 94 - 28
driver/vidc/src/venus_hfi_queue.c

@@ -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;
 }