Эх сурвалжийг харах

msm: camera: icp: Optimize FW uncached region for ICP

Allocate memory based on what is configured to FW. Avoid
hardcoded allocations, thereby reducing the memory
footprint. The change also updates size check for a SMMU
mapping, if the size of the buffer is beyond the assigned
va range fail the mapping.

CRs-Fixed: 3477543
Change-Id: I3c2e262f57cdfdbd51255679b2405d855d7d5353
Signed-off-by: Karthik Anantha Ram <[email protected]>
Karthik Anantha Ram 2 жил өмнө
parent
commit
6d25986b9f

+ 2 - 0
drivers/cam_icp/fw_inc/hfi_reg.h

@@ -39,11 +39,13 @@
 #define ICP_QHDR_RX_TYPE_MASK                   0x00FF0000
 #define ICP_QHDR_RX_TYPE_MASK                   0x00FF0000
 #define ICP_QHDR_PRI_TYPE_MASK                  0x0000FF00
 #define ICP_QHDR_PRI_TYPE_MASK                  0x0000FF00
 #define ICP_QHDR_Q_ID_MASK                      0x000000FF
 #define ICP_QHDR_Q_ID_MASK                      0x000000FF
+#define ICP_QTBL_SIZE_IN_BYTES                  sizeof(struct hfi_qtbl)
 
 
 #define ICP_CMD_Q_SIZE_IN_BYTES                 8192
 #define ICP_CMD_Q_SIZE_IN_BYTES                 8192
 #define ICP_MSG_Q_SIZE_IN_BYTES                 8192
 #define ICP_MSG_Q_SIZE_IN_BYTES                 8192
 #define ICP_DBG_Q_SIZE_IN_BYTES                 102400
 #define ICP_DBG_Q_SIZE_IN_BYTES                 102400
 #define ICP_MSG_SFR_SIZE_IN_BYTES               4096
 #define ICP_MSG_SFR_SIZE_IN_BYTES               4096
+#define ICP_SEC_HEAP_SIZE_IN_BYTES              1048576
 
 
 #define ICP_HFI_QTBL_HOSTID1                    0x01000000
 #define ICP_HFI_QTBL_HOSTID1                    0x01000000
 #define ICP_HFI_QTBL_STATUS_ENABLED             0x00000001
 #define ICP_HFI_QTBL_STATUS_ENABLED             0x00000001

+ 1 - 1
drivers/cam_icp/hfi.c

@@ -928,7 +928,7 @@ int cam_hfi_init(int client_handle, struct hfi_mem_info *hfi_mem,
 	qtbl_hdr = &qtbl->q_tbl_hdr;
 	qtbl_hdr = &qtbl->q_tbl_hdr;
 	qtbl_hdr->qtbl_version = 0xFFFFFFFF;
 	qtbl_hdr->qtbl_version = 0xFFFFFFFF;
 	qtbl_hdr->qtbl_size = sizeof(struct hfi_qtbl);
 	qtbl_hdr->qtbl_size = sizeof(struct hfi_qtbl);
-	qtbl_hdr->qtbl_qhdr0_offset = sizeof(struct hfi_qtbl_hdr);
+	qtbl_hdr->qtbl_qhdr0_offset = offsetof(struct hfi_qtbl, q_hdr);
 	qtbl_hdr->qtbl_qhdr_size = sizeof(struct hfi_q_hdr);
 	qtbl_hdr->qtbl_qhdr_size = sizeof(struct hfi_q_hdr);
 	qtbl_hdr->qtbl_num_q = ICP_HFI_NUMBER_OF_QS;
 	qtbl_hdr->qtbl_num_q = ICP_HFI_NUMBER_OF_QS;
 	qtbl_hdr->qtbl_num_active_q = ICP_HFI_NUMBER_OF_QS;
 	qtbl_hdr->qtbl_num_active_q = ICP_HFI_NUMBER_OF_QS;

+ 43 - 57
drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c

@@ -52,9 +52,6 @@
 
 
 #define ICP_DEVICE_IDLE_TIMEOUT 400
 #define ICP_DEVICE_IDLE_TIMEOUT 400
 
 
-/* Memory required to setup all HFI queues and sec heap */
-#define ICP_HFI_QUEUES_MEM_SIZE 0x700000
-
 /*
 /*
  * If synx fencing is enabled, send FW memory mapping
  * If synx fencing is enabled, send FW memory mapping
  * for synx hw_mutex, ipc hw_mutex, synx global mem
  * for synx hw_mutex, ipc hw_mutex, synx global mem
@@ -3258,38 +3255,15 @@ static int cam_icp_alloc_secheap_mem(struct cam_icp_hw_mgr *hw_mgr,
 	return rc;
 	return rc;
 }
 }
 
 
-static int cam_icp_alloc_sfr_mem(struct cam_icp_hw_mgr *hw_mgr,
-	struct cam_mem_mgr_memory_desc *sfr)
-{
-	int rc;
-	struct cam_mem_mgr_request_desc alloc;
-	struct cam_mem_mgr_memory_desc out;
-
-	alloc.size = SZ_8K;
-	alloc.align = 0;
-	alloc.flags = CAM_MEM_FLAG_HW_READ_WRITE |
-		CAM_MEM_FLAG_HW_SHARED_ACCESS;
-
-	alloc.smmu_hdl = hw_mgr->iommu_hdl;
-	rc = cam_mem_mgr_request_mem(&alloc, &out);
-	if (rc)
-		return rc;
-
-	*sfr = out;
-	CAM_DBG(CAM_ICP, "[%s] kva: %llX, iova: %x, hdl: %x, len: %lld",
-		hw_mgr->hw_mgr_name, out.kva, out.iova, out.mem_handle, out.len);
-
-	return rc;
-}
-
-static int cam_icp_alloc_shared_mem(struct cam_icp_hw_mgr *hw_mgr,
-	struct cam_mem_mgr_memory_desc *qtbl)
+static int cam_icp_alloc_shared_mem(
+	struct cam_icp_hw_mgr *hw_mgr, size_t size_requested,
+	struct cam_mem_mgr_memory_desc *alloc_out)
 {
 {
 	int rc;
 	int rc;
 	struct cam_mem_mgr_request_desc alloc;
 	struct cam_mem_mgr_request_desc alloc;
 	struct cam_mem_mgr_memory_desc out;
 	struct cam_mem_mgr_memory_desc out;
 
 
-	alloc.size = SZ_1M;
+	alloc.size = size_requested;
 	alloc.align = 0;
 	alloc.align = 0;
 	alloc.flags = CAM_MEM_FLAG_HW_READ_WRITE |
 	alloc.flags = CAM_MEM_FLAG_HW_READ_WRITE |
 		CAM_MEM_FLAG_HW_SHARED_ACCESS;
 		CAM_MEM_FLAG_HW_SHARED_ACCESS;
@@ -3301,7 +3275,7 @@ static int cam_icp_alloc_shared_mem(struct cam_icp_hw_mgr *hw_mgr,
 		return rc;
 		return rc;
 	}
 	}
 
 
-	*qtbl = out;
+	*alloc_out = out;
 	CAM_DBG(CAM_ICP, "[%s] kva: %llX, iova: %x, hdl: %x, len: %lld",
 	CAM_DBG(CAM_ICP, "[%s] kva: %llX, iova: %x, hdl: %x, len: %lld",
 		hw_mgr->hw_mgr_name,
 		hw_mgr->hw_mgr_name,
 		out.kva, out.iova, out.mem_handle, out.len);
 		out.kva, out.iova, out.mem_handle, out.len);
@@ -3541,6 +3515,7 @@ static int cam_icp_allocate_hfi_mem(struct cam_icp_hw_mgr *hw_mgr)
 	int rc;
 	int rc;
 	struct cam_smmu_region_info fwuncached_region_info = {0};
 	struct cam_smmu_region_info fwuncached_region_info = {0};
 	bool fwuncached_region_exists = false;
 	bool fwuncached_region_exists = false;
+	size_t qtbl_size, cmdq_size, msgq_size, dbgq_size, sfr_size, sec_heap_size;
 
 
 	rc = cam_smmu_get_region_info(hw_mgr->iommu_hdl,
 	rc = cam_smmu_get_region_info(hw_mgr->iommu_hdl,
 		CAM_SMMU_REGION_SHARED, &hw_mgr->hfi_mem.shmem);
 		CAM_SMMU_REGION_SHARED, &hw_mgr->hfi_mem.shmem);
@@ -3564,6 +3539,17 @@ static int cam_icp_allocate_hfi_mem(struct cam_icp_hw_mgr *hw_mgr)
 		goto fw_alloc_failed;
 		goto fw_alloc_failed;
 	}
 	}
 
 
+	/*
+	 * Compute sizes aligned to page size, and add a padding
+	 * of a page between regions
+	 */
+	qtbl_size = ALIGN(ICP_QTBL_SIZE_IN_BYTES, PAGE_SIZE) + PAGE_SIZE;
+	cmdq_size = ALIGN(ICP_CMD_Q_SIZE_IN_BYTES, PAGE_SIZE) + PAGE_SIZE;
+	msgq_size = ALIGN(ICP_MSG_Q_SIZE_IN_BYTES, PAGE_SIZE) + PAGE_SIZE;
+	dbgq_size = ALIGN(ICP_DBG_Q_SIZE_IN_BYTES, PAGE_SIZE) + PAGE_SIZE;
+	sfr_size = ALIGN(ICP_MSG_SFR_SIZE_IN_BYTES, PAGE_SIZE) + PAGE_SIZE;
+	sec_heap_size = ALIGN(ICP_SEC_HEAP_SIZE_IN_BYTES, PAGE_SIZE) + PAGE_SIZE;
+
 	rc = cam_smmu_get_region_info(hw_mgr->iommu_hdl,
 	rc = cam_smmu_get_region_info(hw_mgr->iommu_hdl,
 		CAM_SMMU_REGION_FWUNCACHED, &fwuncached_region_info);
 		CAM_SMMU_REGION_FWUNCACHED, &fwuncached_region_info);
 	if (!rc)
 	if (!rc)
@@ -3573,9 +3559,13 @@ static int cam_icp_allocate_hfi_mem(struct cam_icp_hw_mgr *hw_mgr)
 		struct cam_mem_mgr_request_desc alloc;
 		struct cam_mem_mgr_request_desc alloc;
 		struct cam_mem_mgr_memory_desc out;
 		struct cam_mem_mgr_memory_desc out;
 		uint32_t offset;
 		uint32_t offset;
-		uint64_t size;
 
 
-		alloc.size = ICP_HFI_QUEUES_MEM_SIZE;
+		/*
+		 * FW uncached consists of the qtbl, HFI queues, SFR buffer
+		 * and secondary heap
+		 */
+		alloc.size = qtbl_size + cmdq_size + msgq_size + dbgq_size +
+			sfr_size + sec_heap_size;
 		alloc.align = 0;
 		alloc.align = 0;
 		alloc.flags = CAM_MEM_FLAG_KMD_ACCESS;
 		alloc.flags = CAM_MEM_FLAG_KMD_ACCESS;
 		alloc.smmu_hdl = hw_mgr->iommu_hdl;
 		alloc.smmu_hdl = hw_mgr->iommu_hdl;
@@ -3600,59 +3590,53 @@ static int cam_icp_allocate_hfi_mem(struct cam_icp_hw_mgr *hw_mgr)
 
 
 		offset = 0;
 		offset = 0;
 
 
-		size = SZ_1M;
 		hw_mgr->hfi_mem.sec_heap.iova       = out.iova + offset;
 		hw_mgr->hfi_mem.sec_heap.iova       = out.iova + offset;
 		hw_mgr->hfi_mem.sec_heap.kva        = out.kva + offset;
 		hw_mgr->hfi_mem.sec_heap.kva        = out.kva + offset;
-		hw_mgr->hfi_mem.sec_heap.len        = size;
+		hw_mgr->hfi_mem.sec_heap.len        = sec_heap_size;
 		hw_mgr->hfi_mem.sec_heap.smmu_hdl   = out.smmu_hdl;
 		hw_mgr->hfi_mem.sec_heap.smmu_hdl   = out.smmu_hdl;
 		hw_mgr->hfi_mem.sec_heap.mem_handle = out.mem_handle;
 		hw_mgr->hfi_mem.sec_heap.mem_handle = out.mem_handle;
 		hw_mgr->hfi_mem.sec_heap.region     = out.region;
 		hw_mgr->hfi_mem.sec_heap.region     = out.region;
-		offset += (uint32_t)size;
+		offset += (uint32_t)sec_heap_size;
 
 
-		size = SZ_1M;
 		hw_mgr->hfi_mem.qtbl.iova       = out.iova + offset;
 		hw_mgr->hfi_mem.qtbl.iova       = out.iova + offset;
 		hw_mgr->hfi_mem.qtbl.kva        = out.kva + offset;
 		hw_mgr->hfi_mem.qtbl.kva        = out.kva + offset;
-		hw_mgr->hfi_mem.qtbl.len        = size;
+		hw_mgr->hfi_mem.qtbl.len        = qtbl_size;
 		hw_mgr->hfi_mem.qtbl.smmu_hdl   = out.smmu_hdl;
 		hw_mgr->hfi_mem.qtbl.smmu_hdl   = out.smmu_hdl;
 		hw_mgr->hfi_mem.qtbl.mem_handle = out.mem_handle;
 		hw_mgr->hfi_mem.qtbl.mem_handle = out.mem_handle;
 		hw_mgr->hfi_mem.qtbl.region     = out.region;
 		hw_mgr->hfi_mem.qtbl.region     = out.region;
-		offset += (uint32_t)size;
+		offset += (uint32_t)qtbl_size;
 
 
-		size = SZ_1M;
 		hw_mgr->hfi_mem.cmd_q.iova       = out.iova + offset;
 		hw_mgr->hfi_mem.cmd_q.iova       = out.iova + offset;
 		hw_mgr->hfi_mem.cmd_q.kva        = out.kva + offset;
 		hw_mgr->hfi_mem.cmd_q.kva        = out.kva + offset;
-		hw_mgr->hfi_mem.cmd_q.len        = size;
+		hw_mgr->hfi_mem.cmd_q.len        = cmdq_size;
 		hw_mgr->hfi_mem.cmd_q.smmu_hdl   = out.smmu_hdl;
 		hw_mgr->hfi_mem.cmd_q.smmu_hdl   = out.smmu_hdl;
 		hw_mgr->hfi_mem.cmd_q.mem_handle = out.mem_handle;
 		hw_mgr->hfi_mem.cmd_q.mem_handle = out.mem_handle;
 		hw_mgr->hfi_mem.cmd_q.region     = out.region;
 		hw_mgr->hfi_mem.cmd_q.region     = out.region;
-		offset += (uint32_t)size;
+		offset += (uint32_t)cmdq_size;
 
 
-		size = SZ_1M;
 		hw_mgr->hfi_mem.msg_q.iova       = out.iova + offset;
 		hw_mgr->hfi_mem.msg_q.iova       = out.iova + offset;
 		hw_mgr->hfi_mem.msg_q.kva        = out.kva + offset;
 		hw_mgr->hfi_mem.msg_q.kva        = out.kva + offset;
-		hw_mgr->hfi_mem.msg_q.len        = size;
+		hw_mgr->hfi_mem.msg_q.len        = msgq_size;
 		hw_mgr->hfi_mem.msg_q.smmu_hdl   = out.smmu_hdl;
 		hw_mgr->hfi_mem.msg_q.smmu_hdl   = out.smmu_hdl;
 		hw_mgr->hfi_mem.msg_q.mem_handle = out.mem_handle;
 		hw_mgr->hfi_mem.msg_q.mem_handle = out.mem_handle;
 		hw_mgr->hfi_mem.msg_q.region     = out.region;
 		hw_mgr->hfi_mem.msg_q.region     = out.region;
-		offset += (uint32_t)size;
+		offset += (uint32_t)msgq_size;
 
 
-		size = SZ_1M;
 		hw_mgr->hfi_mem.dbg_q.iova       = out.iova + offset;
 		hw_mgr->hfi_mem.dbg_q.iova       = out.iova + offset;
 		hw_mgr->hfi_mem.dbg_q.kva        = out.kva + offset;
 		hw_mgr->hfi_mem.dbg_q.kva        = out.kva + offset;
-		hw_mgr->hfi_mem.dbg_q.len        = size;
+		hw_mgr->hfi_mem.dbg_q.len        = dbgq_size;
 		hw_mgr->hfi_mem.dbg_q.smmu_hdl   = out.smmu_hdl;
 		hw_mgr->hfi_mem.dbg_q.smmu_hdl   = out.smmu_hdl;
 		hw_mgr->hfi_mem.dbg_q.mem_handle = out.mem_handle;
 		hw_mgr->hfi_mem.dbg_q.mem_handle = out.mem_handle;
 		hw_mgr->hfi_mem.dbg_q.region     = out.region;
 		hw_mgr->hfi_mem.dbg_q.region     = out.region;
-		offset += (uint32_t)size;
+		offset += (uint32_t)dbgq_size;
 
 
-		size = SZ_8K;
 		hw_mgr->hfi_mem.sfr_buf.iova       = out.iova + offset;
 		hw_mgr->hfi_mem.sfr_buf.iova       = out.iova + offset;
 		hw_mgr->hfi_mem.sfr_buf.kva        = out.kva + offset;
 		hw_mgr->hfi_mem.sfr_buf.kva        = out.kva + offset;
-		hw_mgr->hfi_mem.sfr_buf.len        = size;
+		hw_mgr->hfi_mem.sfr_buf.len        = sfr_size;
 		hw_mgr->hfi_mem.sfr_buf.smmu_hdl   = out.smmu_hdl;
 		hw_mgr->hfi_mem.sfr_buf.smmu_hdl   = out.smmu_hdl;
 		hw_mgr->hfi_mem.sfr_buf.mem_handle = out.mem_handle;
 		hw_mgr->hfi_mem.sfr_buf.mem_handle = out.mem_handle;
 		hw_mgr->hfi_mem.sfr_buf.region     = out.region;
 		hw_mgr->hfi_mem.sfr_buf.region     = out.region;
-		offset += (uint32_t)size;
+		offset += (uint32_t)sfr_size;
 
 
 		if (offset > out.len) {
 		if (offset > out.len) {
 			CAM_ERR(CAM_ICP,
 			CAM_ERR(CAM_ICP,
@@ -3662,35 +3646,35 @@ static int cam_icp_allocate_hfi_mem(struct cam_icp_hw_mgr *hw_mgr)
 			goto qtbl_alloc_failed;
 			goto qtbl_alloc_failed;
 		}
 		}
 	} else {
 	} else {
-		rc = cam_icp_alloc_shared_mem(hw_mgr, &hw_mgr->hfi_mem.qtbl);
+		rc = cam_icp_alloc_shared_mem(hw_mgr, qtbl_size, &hw_mgr->hfi_mem.qtbl);
 		if (rc) {
 		if (rc) {
 			CAM_ERR(CAM_ICP, "[%s] Unable to allocate qtbl memory, rc %d",
 			CAM_ERR(CAM_ICP, "[%s] Unable to allocate qtbl memory, rc %d",
 				hw_mgr->hw_mgr_name, rc);
 				hw_mgr->hw_mgr_name, rc);
 			goto qtbl_alloc_failed;
 			goto qtbl_alloc_failed;
 		}
 		}
 
 
-		rc = cam_icp_alloc_shared_mem(hw_mgr, &hw_mgr->hfi_mem.cmd_q);
+		rc = cam_icp_alloc_shared_mem(hw_mgr, cmdq_size, &hw_mgr->hfi_mem.cmd_q);
 		if (rc) {
 		if (rc) {
 			CAM_ERR(CAM_ICP, "[%s] Unable to allocate cmd q memory rc %d",
 			CAM_ERR(CAM_ICP, "[%s] Unable to allocate cmd q memory rc %d",
 				hw_mgr->hw_mgr_name, rc);
 				hw_mgr->hw_mgr_name, rc);
 			goto cmd_q_alloc_failed;
 			goto cmd_q_alloc_failed;
 		}
 		}
 
 
-		rc = cam_icp_alloc_shared_mem(hw_mgr, &hw_mgr->hfi_mem.msg_q);
+		rc = cam_icp_alloc_shared_mem(hw_mgr, msgq_size, &hw_mgr->hfi_mem.msg_q);
 		if (rc) {
 		if (rc) {
 			CAM_ERR(CAM_ICP, "[%s] Unable to allocate msg q memory rc %d",
 			CAM_ERR(CAM_ICP, "[%s] Unable to allocate msg q memory rc %d",
 				hw_mgr->hw_mgr_name, rc);
 				hw_mgr->hw_mgr_name, rc);
 			goto msg_q_alloc_failed;
 			goto msg_q_alloc_failed;
 		}
 		}
 
 
-		rc = cam_icp_alloc_shared_mem(hw_mgr, &hw_mgr->hfi_mem.dbg_q);
+		rc = cam_icp_alloc_shared_mem(hw_mgr, dbgq_size, &hw_mgr->hfi_mem.dbg_q);
 		if (rc) {
 		if (rc) {
 			CAM_ERR(CAM_ICP, "[%s] Unable to allocate dbg q memory rc %d",
 			CAM_ERR(CAM_ICP, "[%s] Unable to allocate dbg q memory rc %d",
 				hw_mgr->hw_mgr_name, rc);
 				hw_mgr->hw_mgr_name, rc);
 			goto dbg_q_alloc_failed;
 			goto dbg_q_alloc_failed;
 		}
 		}
 
 
-		rc = cam_icp_alloc_sfr_mem(hw_mgr, &hw_mgr->hfi_mem.sfr_buf);
+		rc = cam_icp_alloc_shared_mem(hw_mgr, sfr_size, &hw_mgr->hfi_mem.sfr_buf);
 		if (rc) {
 		if (rc) {
 			CAM_ERR(CAM_ICP, "[%s] Unable to allocate sfr buffer rc %d",
 			CAM_ERR(CAM_ICP, "[%s] Unable to allocate sfr buffer rc %d",
 				hw_mgr->hw_mgr_name, rc);
 				hw_mgr->hw_mgr_name, rc);
@@ -3713,8 +3697,10 @@ static int cam_icp_allocate_hfi_mem(struct cam_icp_hw_mgr *hw_mgr)
 		fwuncached_region_info.iova_len);
 		fwuncached_region_info.iova_len);
 
 
 	CAM_DBG(CAM_ICP,
 	CAM_DBG(CAM_ICP,
-		"[%s] FwUncached[0x%x %p %lld] QTbl[0x%x %p %lld] CmdQ[0x%x %p %lld] MsgQ[0x%x %p %lld]",
+		"[%s] FwUncached[0x%x %lld] FwUncached_Generic[0x%x %p %lld] QTbl[0x%x %p %lld] CmdQ[0x%x %p %lld] MsgQ[0x%x %p %lld]",
 		hw_mgr->hw_mgr_name,
 		hw_mgr->hw_mgr_name,
+		hw_mgr->hfi_mem.fw_uncached.iova_start,
+		hw_mgr->hfi_mem.fw_uncached.iova_len,
 		hw_mgr->hfi_mem.fw_uncached_generic.iova,
 		hw_mgr->hfi_mem.fw_uncached_generic.iova,
 		hw_mgr->hfi_mem.fw_uncached_generic.kva,
 		hw_mgr->hfi_mem.fw_uncached_generic.kva,
 		hw_mgr->hfi_mem.fw_uncached_generic.len,
 		hw_mgr->hfi_mem.fw_uncached_generic.len,

+ 4 - 3
drivers/cam_smmu/cam_smmu_api.c

@@ -2461,16 +2461,17 @@ int cam_smmu_reserve_buf_region(enum cam_smmu_region_id region,
 		buf_info->table->sgl,
 		buf_info->table->sgl,
 		buf_info->table->orig_nents,
 		buf_info->table->orig_nents,
 		prot);
 		prot);
-	if (size != region_info->iova_len) {
+	if (region_info->iova_len < size) {
 		CAM_ERR(CAM_SMMU,
 		CAM_ERR(CAM_SMMU,
-			"IOMMU mapping failed size=%zu, iova_len=%zu",
+			"IOMMU mapping failed for size=%zu available iova_len=%zu",
 			size, region_info->iova_len);
 			size, region_info->iova_len);
 		rc = -EINVAL;
 		rc = -EINVAL;
 		goto err_unmap_sg;
 		goto err_unmap_sg;
 	}
 	}
 
 
 	*iova = (uint32_t)region_info->iova_start;
 	*iova = (uint32_t)region_info->iova_start;
-	*request_len = region_info->iova_len;
+	/* Assign size mapped */
+	*request_len = size;
 	*is_buf_allocated = true;
 	*is_buf_allocated = true;
 	mutex_unlock(&cb_info->lock);
 	mutex_unlock(&cb_info->lock);