diff --git a/drivers/cam_icp/fw_inc/hfi_reg.h b/drivers/cam_icp/fw_inc/hfi_reg.h index 1fbdd96bc2..7a86f78e00 100644 --- a/drivers/cam_icp/fw_inc/hfi_reg.h +++ b/drivers/cam_icp/fw_inc/hfi_reg.h @@ -39,11 +39,13 @@ #define ICP_QHDR_RX_TYPE_MASK 0x00FF0000 #define ICP_QHDR_PRI_TYPE_MASK 0x0000FF00 #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_MSG_Q_SIZE_IN_BYTES 8192 #define ICP_DBG_Q_SIZE_IN_BYTES 102400 #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_STATUS_ENABLED 0x00000001 diff --git a/drivers/cam_icp/hfi.c b/drivers/cam_icp/hfi.c index 819f4c62ae..133986f51c 100644 --- a/drivers/cam_icp/hfi.c +++ b/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_version = 0xFFFFFFFF; 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_num_q = ICP_HFI_NUMBER_OF_QS; qtbl_hdr->qtbl_num_active_q = ICP_HFI_NUMBER_OF_QS; diff --git a/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index 8dbdb00f56..ad9602e225 100644 --- a/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c @@ -52,9 +52,6 @@ #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 * 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; } -static int cam_icp_alloc_sfr_mem(struct cam_icp_hw_mgr *hw_mgr, - struct cam_mem_mgr_memory_desc *sfr) +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; 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) -{ - int rc; - struct cam_mem_mgr_request_desc alloc; - struct cam_mem_mgr_memory_desc out; - - alloc.size = SZ_1M; + alloc.size = size_requested; alloc.align = 0; alloc.flags = CAM_MEM_FLAG_HW_READ_WRITE | 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; } - *qtbl = out; + *alloc_out = 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); @@ -3541,6 +3515,7 @@ static int cam_icp_allocate_hfi_mem(struct cam_icp_hw_mgr *hw_mgr) int rc; struct cam_smmu_region_info fwuncached_region_info = {0}; 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, 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; } + /* + * 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, CAM_SMMU_REGION_FWUNCACHED, &fwuncached_region_info); 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_memory_desc out; 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.flags = CAM_MEM_FLAG_KMD_ACCESS; 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; - size = SZ_1M; 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.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.mem_handle = out.mem_handle; 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.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.mem_handle = out.mem_handle; 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.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.mem_handle = out.mem_handle; 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.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.mem_handle = out.mem_handle; 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.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.mem_handle = out.mem_handle; 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.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.mem_handle = out.mem_handle; hw_mgr->hfi_mem.sfr_buf.region = out.region; - offset += (uint32_t)size; + offset += (uint32_t)sfr_size; if (offset > out.len) { 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; } } 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) { CAM_ERR(CAM_ICP, "[%s] Unable to allocate qtbl memory, rc %d", hw_mgr->hw_mgr_name, rc); 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) { CAM_ERR(CAM_ICP, "[%s] Unable to allocate cmd q memory rc %d", hw_mgr->hw_mgr_name, rc); 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) { CAM_ERR(CAM_ICP, "[%s] Unable to allocate msg q memory rc %d", hw_mgr->hw_mgr_name, rc); 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) { CAM_ERR(CAM_ICP, "[%s] Unable to allocate dbg q memory rc %d", hw_mgr->hw_mgr_name, rc); 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) { CAM_ERR(CAM_ICP, "[%s] Unable to allocate sfr buffer rc %d", 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); 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->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.kva, hw_mgr->hfi_mem.fw_uncached_generic.len, diff --git a/drivers/cam_smmu/cam_smmu_api.c b/drivers/cam_smmu/cam_smmu_api.c index ab78b466ce..2d00bdb120 100644 --- a/drivers/cam_smmu/cam_smmu_api.c +++ b/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->orig_nents, prot); - if (size != region_info->iova_len) { + if (region_info->iova_len < size) { 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); rc = -EINVAL; goto err_unmap_sg; } *iova = (uint32_t)region_info->iova_start; - *request_len = region_info->iova_len; + /* Assign size mapped */ + *request_len = size; *is_buf_allocated = true; mutex_unlock(&cb_info->lock);