diff --git a/drivers/cam_cdm/cam_cdm_hw_core.c b/drivers/cam_cdm/cam_cdm_hw_core.c index 552034b867..afd32c28d1 100644 --- a/drivers/cam_cdm/cam_cdm_hw_core.c +++ b/drivers/cam_cdm/cam_cdm_hw_core.c @@ -829,6 +829,21 @@ int cam_hw_cdm_submit_gen_irq( goto end; } + if (cam_presil_mode_enabled()) { + CAM_DBG(CAM_PRESIL, + "Sending CDM gen irq cmd buffer:%d with iommu_hdl:%d", + core->gen_irq[fifo_idx].handle, core->iommu_hdl.non_secure); + + rc = cam_mem_mgr_send_buffer_to_presil(core->iommu_hdl.non_secure, + core->gen_irq[fifo_idx].handle); + if (rc) { + CAM_ERR(CAM_PRESIL, + "Failed to send CDM gen irq cmd buffer fifo_idx:%d mem_handle:%d rc:%d", + fifo_idx, core->gen_irq[fifo_idx].handle, rc); + goto end; + } + } + if (cam_hw_cdm_commit_bl_write(cdm_hw, fifo_idx)) { CAM_ERR(CAM_CDM, "Cannot commit the genirq BL with tag tag=%d", @@ -948,6 +963,22 @@ static int cam_hw_cdm_arb_submit_bl(struct cam_hw_info *cdm_hw, kfree(node); return -EIO; } + + if (cam_presil_mode_enabled()) { + CAM_DBG(CAM_PRESIL, + "Sending CDM arb cmd buffer:%d with iommu_hdl:%d", + cdm_cmd->cmd[i].bl_addr.mem_handle, core->iommu_hdl.non_secure); + + rc = cam_mem_mgr_send_buffer_to_presil(core->iommu_hdl.non_secure, + cdm_cmd->cmd[i].bl_addr.mem_handle); + if (rc) { + CAM_ERR(CAM_PRESIL, + "Failed to send CDM arb cmd buffer i:%d mem_handle:%d rc:%d", + i, cdm_cmd->cmd[i].bl_addr.mem_handle, rc); + return rc; + } + } + rc = cam_hw_cdm_commit_bl_write(cdm_hw, fifo_idx); if (rc) { diff --git a/drivers/cam_core/cam_context.c b/drivers/cam_core/cam_context.c index e8301568d1..5b815fc281 100644 --- a/drivers/cam_core/cam_context.c +++ b/drivers/cam_core/cam_context.c @@ -729,7 +729,7 @@ int cam_context_init(struct cam_context *ctx, struct cam_req_mgr_kmd_ops *crm_node_intf, struct cam_hw_mgr_intf *hw_mgr_intf, struct cam_ctx_request *req_list, - uint32_t req_size) + uint32_t req_size, int img_iommu_hdl) { int i; @@ -772,6 +772,7 @@ int cam_context_init(struct cam_context *ctx, ctx->state = CAM_CTX_AVAILABLE; ctx->state_machine = NULL; ctx->ctx_priv = NULL; + ctx->img_iommu_hdl = img_iommu_hdl; return 0; } diff --git a/drivers/cam_core/cam_context.h b/drivers/cam_core/cam_context.h index a2673131a0..dd44ff0d10 100644 --- a/drivers/cam_core/cam_context.h +++ b/drivers/cam_core/cam_context.h @@ -221,6 +221,7 @@ struct cam_ctx_ops { * @in_map_entries: In map update entry * @out_map_entries: Out map entry * @mini dump cb: Mini dump cb + * @img_iommu_hdl: Image IOMMU handle * */ struct cam_context { @@ -266,7 +267,7 @@ struct cam_context { struct cam_hw_fence_map_entry *in_map_entries; struct cam_hw_fence_map_entry *out_map_entries; cam_ctx_mini_dump_cb_func mini_dump_cb; - + int img_iommu_hdl; }; /** @@ -592,6 +593,7 @@ int cam_context_deinit(struct cam_context *ctx); * @hw_mgr_intf: Function table for context to hw interface * @req_list: Requests storage * @req_size: Size of the request storage + * @img_iommu_hdl: IOMMU Handle for image buffers * */ int cam_context_init(struct cam_context *ctx, @@ -601,7 +603,7 @@ int cam_context_init(struct cam_context *ctx, struct cam_req_mgr_kmd_ops *crm_node_intf, struct cam_hw_mgr_intf *hw_mgr_intf, struct cam_ctx_request *req_list, - uint32_t req_size); + uint32_t req_size, int img_iommu_hdl); /** * cam_context_putref() diff --git a/drivers/cam_core/cam_context_utils.c b/drivers/cam_core/cam_context_utils.c index c356ed838d..dfdcbfac90 100644 --- a/drivers/cam_core/cam_context_utils.c +++ b/drivers/cam_core/cam_context_utils.c @@ -19,6 +19,7 @@ #include "cam_trace.h" #include "cam_debug_util.h" #include "cam_cpas_api.h" +#include "cam_packet_util.h" static uint cam_debug_ctx_req_list; module_param(cam_debug_ctx_req_list, uint, 0644); @@ -173,6 +174,16 @@ int cam_context_buf_done_from_hw(struct cam_context *ctx, ctx->dev_name, ctx->ctx_id, req->request_id, result); for (j = 0; j < req->num_out_map_entries; j++) { + /* Get buf handles from packet and retrieve them from presil framework */ + if (cam_presil_mode_enabled()) { + rc = cam_presil_retrieve_buffers_from_packet(req->pf_data.packet, + ctx->img_iommu_hdl, req->out_map_entries[j].resource_handle); + if (rc) { + CAM_ERR(CAM_CTXT, "Failed to retrieve image buffers rc:%d", rc); + return rc; + } + } + CAM_DBG(CAM_REQ, "fence %d signal with %d", req->out_map_entries[j].sync_id, result); cam_sync_signal(req->out_map_entries[j].sync_id, result, diff --git a/drivers/cam_cre/cam_cre_context.c b/drivers/cam_cre/cam_cre_context.c index 0f5971d11e..979956aa32 100644 --- a/drivers/cam_cre/cam_cre_context.c +++ b/drivers/cam_cre/cam_cre_context.c @@ -239,7 +239,7 @@ static struct cam_ctx_ops int cam_cre_context_init(struct cam_cre_context *ctx, struct cam_hw_mgr_intf *hw_intf, - uint32_t ctx_id) + uint32_t ctx_id, int img_iommu_hdl) { int rc; int i; @@ -254,7 +254,7 @@ int cam_cre_context_init(struct cam_cre_context *ctx, ctx->req_base[i].req_priv = ctx; rc = cam_context_init(ctx->base, cre_dev_name, CAM_CRE, ctx_id, - NULL, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX); + NULL, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX, img_iommu_hdl); if (rc) { CAM_ERR(CAM_CRE, "Camera Context Base init failed"); goto err; diff --git a/drivers/cam_cre/cam_cre_context.h b/drivers/cam_cre/cam_cre_context.h index 1c46373a5b..c3e5e3f646 100644 --- a/drivers/cam_cre/cam_cre_context.h +++ b/drivers/cam_cre/cam_cre_context.h @@ -46,11 +46,13 @@ struct cam_cre_ctx_irq_ops { * @ctx: CRE context obj to be initialized * @hw_intf: CRE hw manager interface * @ctx_id: ID for this context + * @img_iommu_hdl: IOMMU HDL for image buffers * */ int cam_cre_context_init(struct cam_cre_context *ctx, struct cam_hw_mgr_intf *hw_intf, - uint32_t ctx_id); + uint32_t ctx_id, + int img_iommu_hdl); /** * cam_cre_context_deinit() diff --git a/drivers/cam_cre/cam_cre_dev.c b/drivers/cam_cre/cam_cre_dev.c index 9990166ab9..36a42cb4b6 100644 --- a/drivers/cam_cre/cam_cre_dev.c +++ b/drivers/cam_cre/cam_cre_dev.c @@ -144,7 +144,7 @@ static int cam_cre_subdev_component_bind(struct device *dev, for (i = 0; i < CAM_CRE_CTX_MAX; i++) { g_cre_dev.ctx_cre[i].base = &g_cre_dev.ctx[i]; rc = cam_cre_context_init(&g_cre_dev.ctx_cre[i], - hw_mgr_intf, i); + hw_mgr_intf, i, iommu_hdl); if (rc) { CAM_ERR(CAM_CRE, "CRE context init failed %d %d", i, rc); diff --git a/drivers/cam_cust/cam_custom_context.c b/drivers/cam_cust/cam_custom_context.c index 78561ff85f..ebd9d8105d 100644 --- a/drivers/cam_cust/cam_custom_context.c +++ b/drivers/cam_cust/cam_custom_context.c @@ -1683,7 +1683,7 @@ int cam_custom_dev_context_init(struct cam_custom_context *ctx, struct cam_context *ctx_base, struct cam_req_mgr_kmd_ops *crm_node_intf, struct cam_hw_mgr_intf *hw_intf, - uint32_t ctx_id) + uint32_t ctx_id, int img_iommu_hdl) { int rc = -1, i = 0; @@ -1707,7 +1707,7 @@ int cam_custom_dev_context_init(struct cam_custom_context *ctx, /* camera context setup */ rc = cam_context_init(ctx_base, custom_dev_name, CAM_CUSTOM, ctx_id, - crm_node_intf, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX); + crm_node_intf, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX, img_iommu_hdl); if (rc) { CAM_ERR(CAM_CUSTOM, "Camera Context Base init failed"); return rc; diff --git a/drivers/cam_cust/cam_custom_context.h b/drivers/cam_cust/cam_custom_context.h index f8eae6a2cf..054fb3815f 100644 --- a/drivers/cam_cust/cam_custom_context.h +++ b/drivers/cam_cust/cam_custom_context.h @@ -132,13 +132,14 @@ struct cam_custom_context { * @bridge_ops: Bridge call back funciton * @hw_intf: Cust hw manager interface * @ctx_id: ID for this context + * @img_iommu_hdl: IOMMU HDL for Image buffers * */ int cam_custom_dev_context_init(struct cam_custom_context *ctx, struct cam_context *ctx_base, struct cam_req_mgr_kmd_ops *bridge_ops, struct cam_hw_mgr_intf *hw_intf, - uint32_t ctx_id); + uint32_t ctx_id, int img_iommu_hdl); /** * cam_custom_dev_context_deinit() diff --git a/drivers/cam_cust/cam_custom_dev.c b/drivers/cam_cust/cam_custom_dev.c index 1c997f6595..fa3b0017c8 100644 --- a/drivers/cam_cust/cam_custom_dev.c +++ b/drivers/cam_cust/cam_custom_dev.c @@ -138,7 +138,7 @@ static int cam_custom_component_bind(struct device *dev, &g_custom_dev.ctx[i], &node->crm_node_intf, &node->hw_mgr_intf, - i); + i, iommu_hdl); if (rc) { CAM_ERR(CAM_CUSTOM, "Custom context init failed!"); goto unregister; diff --git a/drivers/cam_fd/cam_fd_context.c b/drivers/cam_fd/cam_fd_context.c index 4328a1376f..2814834164 100644 --- a/drivers/cam_fd/cam_fd_context.c +++ b/drivers/cam_fd/cam_fd_context.c @@ -223,7 +223,7 @@ static struct cam_ctx_ops int cam_fd_context_init(struct cam_fd_context *fd_ctx, struct cam_context *base_ctx, struct cam_hw_mgr_intf *hw_intf, - uint32_t ctx_id) + uint32_t ctx_id, int img_iommu_hdl) { int rc; @@ -235,7 +235,7 @@ int cam_fd_context_init(struct cam_fd_context *fd_ctx, memset(fd_ctx, 0, sizeof(*fd_ctx)); rc = cam_context_init(base_ctx, fd_dev_name, CAM_FD, ctx_id, - NULL, hw_intf, fd_ctx->req_base, CAM_CTX_REQ_MAX); + NULL, hw_intf, fd_ctx->req_base, CAM_CTX_REQ_MAX, img_iommu_hdl); if (rc) { CAM_ERR(CAM_FD, "Camera Context Base init failed, rc=%d", rc); return rc; diff --git a/drivers/cam_fd/cam_fd_context.h b/drivers/cam_fd/cam_fd_context.h index caa7645531..1f4e846093 100644 --- a/drivers/cam_fd/cam_fd_context.h +++ b/drivers/cam_fd/cam_fd_context.h @@ -24,7 +24,7 @@ struct cam_fd_context { int cam_fd_context_init(struct cam_fd_context *fd_ctx, struct cam_context *base_ctx, struct cam_hw_mgr_intf *hw_intf, - uint32_t ctx_id); + uint32_t ctx_id, int img_iommu_hdl); int cam_fd_context_deinit(struct cam_fd_context *ctx); #endif /* _CAM_FD_CONTEXT_H_ */ diff --git a/drivers/cam_fd/cam_fd_dev.c b/drivers/cam_fd/cam_fd_dev.c index 3c9377f9e8..b513a792f8 100644 --- a/drivers/cam_fd/cam_fd_dev.c +++ b/drivers/cam_fd/cam_fd_dev.c @@ -136,7 +136,7 @@ static int cam_fd_dev_component_bind(struct device *dev, for (i = 0; i < CAM_CTX_MAX; i++) { rc = cam_fd_context_init(&g_fd_dev.fd_ctx[i], - &g_fd_dev.base_ctx[i], &node->hw_mgr_intf, i); + &g_fd_dev.base_ctx[i], &node->hw_mgr_intf, i, -1); if (rc) { CAM_ERR(CAM_FD, "FD context init failed i=%d, rc=%d", i, rc); diff --git a/drivers/cam_icp/cam_icp_context.c b/drivers/cam_icp/cam_icp_context.c index e291f92550..41d1ffe483 100644 --- a/drivers/cam_icp/cam_icp_context.c +++ b/drivers/cam_icp/cam_icp_context.c @@ -300,7 +300,7 @@ static struct cam_ctx_ops }; int cam_icp_context_init(struct cam_icp_context *ctx, - struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id) + struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id, int img_iommu_hdl) { int rc; @@ -311,7 +311,7 @@ int cam_icp_context_init(struct cam_icp_context *ctx, } rc = cam_context_init(ctx->base, icp_dev_name, CAM_ICP, ctx_id, - NULL, hw_intf, ctx->req_base, CAM_CTX_ICP_REQ_MAX); + NULL, hw_intf, ctx->req_base, CAM_CTX_ICP_REQ_MAX, img_iommu_hdl); if (rc) { CAM_ERR(CAM_ICP, "Camera Context Base init failed"); goto err; diff --git a/drivers/cam_icp/cam_icp_context.h b/drivers/cam_icp/cam_icp_context.h index dc9018d1c2..8f619782dc 100644 --- a/drivers/cam_icp/cam_icp_context.h +++ b/drivers/cam_icp/cam_icp_context.h @@ -29,9 +29,11 @@ struct cam_icp_context { * @ctx: Pointer to context * @hw_intf: Pointer to ICP hardware interface * @ctx_id: ID for this context + * @img_iommu_hdl: IOMMU HDL for image buffers + * */ int cam_icp_context_init(struct cam_icp_context *ctx, - struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id); + struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id, int img_iommu_hdl); /** * cam_icp_context_deinit() - ICP context deinit diff --git a/drivers/cam_icp/cam_icp_subdev.c b/drivers/cam_icp/cam_icp_subdev.c index 016217bfa8..c835e9a5ea 100644 --- a/drivers/cam_icp/cam_icp_subdev.c +++ b/drivers/cam_icp/cam_icp_subdev.c @@ -209,7 +209,7 @@ static int cam_icp_component_bind(struct device *dev, for (i = 0; i < CAM_ICP_CTX_MAX; i++) { g_icp_dev.ctx_icp[i].base = &g_icp_dev.ctx[i]; rc = cam_icp_context_init(&g_icp_dev.ctx_icp[i], - hw_mgr_intf, i); + hw_mgr_intf, i, iommu_hdl); if (rc) { CAM_ERR(CAM_ICP, "ICP context init failed"); goto ctx_fail; diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index ae4b3e4287..d1cf140f28 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/drivers/cam_isp/cam_isp_context.c @@ -1213,6 +1213,18 @@ static int __cam_isp_ctx_handle_buf_done_for_request( continue; } + /* Get buf handles from packet and retrieve them from presil framework */ + if (cam_presil_mode_enabled()) { + rc = cam_presil_retrieve_buffers_from_packet(req_isp->hw_update_data.packet, + ctx->img_iommu_hdl, req_isp->fence_map_out[i].resource_handle); + if (rc) { + CAM_ERR(CAM_ISP, + "Failed to retrieve image buffers req_id:%d ctx_id:%d bubble detected:%d rc:%d", + req->request_id, ctx->ctx_id, req_isp->bubble_detected, rc); + return rc; + } + } + if (!req_isp->bubble_detected) { if (req_isp->is_sync_mode) { CAM_DBG(CAM_ISP, @@ -1424,6 +1436,18 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr( continue; } + /* Get buf handles from packet and retrieve them from presil framework */ + if (cam_presil_mode_enabled()) { + rc = cam_presil_retrieve_buffers_from_packet(req_isp->hw_update_data.packet, + ctx->img_iommu_hdl, req_isp->fence_map_out[i].resource_handle); + if (rc) { + CAM_ERR(CAM_ISP, + "Failed to retrieve image buffers req_id:%d ctx_id:%d bubble detected:%d rc:%d", + req->request_id, ctx->ctx_id, req_isp->bubble_detected, rc); + return rc; + } + } + if (defer_buf_done) { uint32_t deferred_indx = req_isp->num_deferred_acks; @@ -6911,8 +6935,8 @@ int cam_isp_context_init(struct cam_isp_context *ctx, struct cam_req_mgr_kmd_ops *crm_node_intf, struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id, - uint32_t isp_device_type) - + uint32_t isp_device_type, + int img_iommu_hdl) { int rc = -1; int i; @@ -6951,7 +6975,7 @@ int cam_isp_context_init(struct cam_isp_context *ctx, /* camera context setup */ rc = cam_context_init(ctx_base, isp_dev_name, CAM_ISP, ctx_id, - crm_node_intf, hw_intf, ctx->req_base, CAM_ISP_CTX_REQ_MAX); + crm_node_intf, hw_intf, ctx->req_base, CAM_ISP_CTX_REQ_MAX, img_iommu_hdl); if (rc) { CAM_ERR(CAM_ISP, "Camera Context Base init failed"); goto err; diff --git a/drivers/cam_isp/cam_isp_context.h b/drivers/cam_isp/cam_isp_context.h index 3e06b7894c..8245f3e65f 100644 --- a/drivers/cam_isp/cam_isp_context.h +++ b/drivers/cam_isp/cam_isp_context.h @@ -474,6 +474,7 @@ struct cam_isp_ctx_mini_dump_info { * @hw_intf: ISP hw manager interface * @ctx_id: ID for this context * @isp_device_type Isp device type + * @img_iommu_hdl IOMMU HDL for image buffers * */ int cam_isp_context_init(struct cam_isp_context *ctx, @@ -481,7 +482,8 @@ int cam_isp_context_init(struct cam_isp_context *ctx, struct cam_req_mgr_kmd_ops *bridge_ops, struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id, - uint32_t isp_device_type); + uint32_t isp_device_type, + int img_iommu_hdl); /** * cam_isp_context_deinit() diff --git a/drivers/cam_isp/cam_isp_dev.c b/drivers/cam_isp/cam_isp_dev.c index 2ab976e221..d121f017e7 100644 --- a/drivers/cam_isp/cam_isp_dev.c +++ b/drivers/cam_isp/cam_isp_dev.c @@ -173,7 +173,7 @@ static int cam_isp_dev_component_bind(struct device *dev, &node->crm_node_intf, &node->hw_mgr_intf, i, - g_isp_dev.isp_device_type); + g_isp_dev.isp_device_type, iommu_hdl); if (rc) { CAM_ERR(CAM_ISP, "ISP context init failed!"); goto kfree; diff --git a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 6310283b00..9fc2dfc309 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -24,8 +24,10 @@ #include "cam_packet_util.h" #include "cam_debug_util.h" #include "cam_cpas_api.h" +#include "cam_mem_mgr.h" #include "cam_mem_mgr_api.h" #include "cam_common_util.h" +#include "cam_presil_hw_access.h" #define CAM_IFE_SAFE_DISABLE 0 #define CAM_IFE_SAFE_ENABLE 1 @@ -5809,6 +5811,19 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv, } cdm_cmd->cmd_arrary_count = cfg->num_hw_update_entries - skip; + if (cam_presil_mode_enabled()) { + CAM_INFO(CAM_ISP, "Sending relevant buffers for request:%llu to presil", + cfg->request_id); + rc = cam_presil_send_buffers_from_packet(hw_update_data->packet, + g_ife_hw_mgr.mgr_common.img_iommu_hdl, + g_ife_hw_mgr.mgr_common.cmd_iommu_hdl); + if (rc) { + CAM_ERR(CAM_ISP, "Error sending buffers for request:%llu to presil", + cfg->request_id); + return rc; + } + } + reinit_completion(&ctx->config_done_complete); ctx->applied_req_id = cfg->request_id; diff --git a/drivers/cam_jpeg/cam_jpeg_context.c b/drivers/cam_jpeg/cam_jpeg_context.c index a4ff774ad1..40b04480b1 100644 --- a/drivers/cam_jpeg/cam_jpeg_context.c +++ b/drivers/cam_jpeg/cam_jpeg_context.c @@ -202,7 +202,8 @@ static struct cam_ctx_ops int cam_jpeg_context_init(struct cam_jpeg_context *ctx, struct cam_context *ctx_base, struct cam_hw_mgr_intf *hw_intf, - uint32_t ctx_id) + uint32_t ctx_id, + int img_iommu_hdl) { int rc; int i; @@ -221,7 +222,7 @@ int cam_jpeg_context_init(struct cam_jpeg_context *ctx, ctx->req_base[i].req_priv = &ctx->jpeg_req[i]; rc = cam_context_init(ctx_base, jpeg_dev_name, CAM_JPEG, ctx_id, - NULL, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX); + NULL, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX, img_iommu_hdl); if (rc) { CAM_ERR(CAM_JPEG, "Camera Context Base init failed"); goto err; diff --git a/drivers/cam_jpeg/cam_jpeg_context.h b/drivers/cam_jpeg/cam_jpeg_context.h index 39f0794e12..492cf1b99d 100644 --- a/drivers/cam_jpeg/cam_jpeg_context.h +++ b/drivers/cam_jpeg/cam_jpeg_context.h @@ -49,12 +49,14 @@ struct cam_jpeg_ctx_irq_ops { * @ctx_base: Context base from cam_context * @hw_intf: JPEG hw manager interface * @ctx_id: ID for this context + * @img_iommu_hdl: IOMMU HDL for image buffers * */ int cam_jpeg_context_init(struct cam_jpeg_context *ctx, struct cam_context *ctx_base, struct cam_hw_mgr_intf *hw_intf, - uint32_t ctx_id); + uint32_t ctx_id, + int img_iommu_hdl); /** * cam_jpeg_context_deinit() diff --git a/drivers/cam_jpeg/cam_jpeg_dev.c b/drivers/cam_jpeg/cam_jpeg_dev.c index b4c2c31cf1..14b0e7460c 100644 --- a/drivers/cam_jpeg/cam_jpeg_dev.c +++ b/drivers/cam_jpeg/cam_jpeg_dev.c @@ -147,7 +147,7 @@ static int cam_jpeg_dev_component_bind(struct device *dev, rc = cam_jpeg_context_init(&g_jpeg_dev.ctx_jpeg[i], &g_jpeg_dev.ctx[i], &node->hw_mgr_intf, - i); + i, iommu_hdl); if (rc) { CAM_ERR(CAM_JPEG, "JPEG context init failed %d %d", i, rc); diff --git a/drivers/cam_lrme/cam_lrme_context.c b/drivers/cam_lrme/cam_lrme_context.c index 3a11ff4ad8..2def32f859 100644 --- a/drivers/cam_lrme/cam_lrme_context.c +++ b/drivers/cam_lrme/cam_lrme_context.c @@ -226,7 +226,8 @@ static struct cam_ctx_ops int cam_lrme_context_init(struct cam_lrme_context *lrme_ctx, struct cam_context *base_ctx, struct cam_hw_mgr_intf *hw_intf, - uint32_t index) + uint32_t index + int img_iommu_hdl) { int rc = 0; @@ -240,7 +241,7 @@ int cam_lrme_context_init(struct cam_lrme_context *lrme_ctx, memset(lrme_ctx, 0, sizeof(*lrme_ctx)); rc = cam_context_init(base_ctx, lrme_dev_name, CAM_LRME, index, - NULL, hw_intf, lrme_ctx->req_base, CAM_CTX_REQ_MAX); + NULL, hw_intf, lrme_ctx->req_base, CAM_CTX_REQ_MAX, img_iommu_hdl); if (rc) { CAM_ERR(CAM_LRME, "Failed to init context"); return rc; diff --git a/drivers/cam_lrme/cam_lrme_context.h b/drivers/cam_lrme/cam_lrme_context.h index 6b67bf247f..abc831f414 100644 --- a/drivers/cam_lrme/cam_lrme_context.h +++ b/drivers/cam_lrme/cam_lrme_context.h @@ -27,7 +27,7 @@ struct cam_lrme_context { int cam_lrme_context_init(struct cam_lrme_context *lrme_ctx, struct cam_context *base_ctx, struct cam_hw_mgr_intf *hw_intf, - uint32_t index); + uint32_t index, int img_iommu_hdl); int cam_lrme_context_deinit(struct cam_lrme_context *lrme_ctx); #endif /* _CAM_LRME_CONTEXT_H_ */ diff --git a/drivers/cam_lrme/cam_lrme_dev.c b/drivers/cam_lrme/cam_lrme_dev.c index 3aa9fd8f57..1a2ec6f14a 100644 --- a/drivers/cam_lrme/cam_lrme_dev.c +++ b/drivers/cam_lrme/cam_lrme_dev.c @@ -159,7 +159,7 @@ static int cam_lrme_component_bind(struct device *dev, for (i = 0; i < CAM_CTX_MAX; i++) { rc = cam_lrme_context_init(&g_lrme_dev->lrme_ctx[i], &g_lrme_dev->ctx[i], - &node->hw_mgr_intf, i); + &node->hw_mgr_intf, i, -1); if (rc) { CAM_ERR(CAM_LRME, "LRME context init failed"); goto deinit_ctx; diff --git a/drivers/cam_ope/cam_ope_context.c b/drivers/cam_ope/cam_ope_context.c index 6507b9156f..5feb2c3c34 100644 --- a/drivers/cam_ope/cam_ope_context.c +++ b/drivers/cam_ope/cam_ope_context.c @@ -251,7 +251,7 @@ static struct cam_ctx_ops }; int cam_ope_context_init(struct cam_ope_context *ctx, - struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id) + struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id, int img_iommu_hdl) { int rc; @@ -262,7 +262,7 @@ int cam_ope_context_init(struct cam_ope_context *ctx, } rc = cam_context_init(ctx->base, ope_dev_name, CAM_OPE, ctx_id, - NULL, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX); + NULL, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX, img_iommu_hdl); if (rc) { CAM_ERR(CAM_OPE, "Camera Context Base init failed"); goto err; diff --git a/drivers/cam_ope/cam_ope_context.h b/drivers/cam_ope/cam_ope_context.h index e79e0f3322..e91c6a7e8b 100644 --- a/drivers/cam_ope/cam_ope_context.h +++ b/drivers/cam_ope/cam_ope_context.h @@ -31,9 +31,11 @@ struct cam_ope_context { * @ctx: Pointer to context * @hw_intf: Pointer to OPE hardware interface * @ctx_id: ID for this context + * @img_iommu_hdl: IOMMU HDL for image buffers + * */ int cam_ope_context_init(struct cam_ope_context *ctx, - struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id); + struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id, int img_iommu_hdl); /** * cam_ope_context_deinit() - OPE context deinit diff --git a/drivers/cam_ope/cam_ope_subdev.c b/drivers/cam_ope/cam_ope_subdev.c index c2cc450d93..896b587fca 100644 --- a/drivers/cam_ope/cam_ope_subdev.c +++ b/drivers/cam_ope/cam_ope_subdev.c @@ -195,7 +195,7 @@ static int cam_ope_subdev_component_bind(struct device *dev, for (i = 0; i < OPE_CTX_MAX; i++) { g_ope_dev.ctx_ope[i].base = &g_ope_dev.ctx[i]; rc = cam_ope_context_init(&g_ope_dev.ctx_ope[i], - hw_mgr_intf, i); + hw_mgr_intf, i, iommu_hdl); if (rc) { CAM_ERR(CAM_OPE, "OPE context init failed"); goto ctx_fail; diff --git a/drivers/cam_utils/cam_packet_util.c b/drivers/cam_utils/cam_packet_util.c index ed9d19227c..944aa4e540 100644 --- a/drivers/cam_utils/cam_packet_util.c +++ b/drivers/cam_utils/cam_packet_util.c @@ -12,6 +12,7 @@ #include "cam_common_util.h" #define CAM_UNIQUE_SRC_HDL_MAX 50 +#define CAM_PRESIL_UNIQUE_HDL_MAX 50 struct cam_patch_unique_src_buf_tbl { int32_t hdl; @@ -462,3 +463,168 @@ int cam_packet_util_process_generic_cmd_buffer( end: return rc; } + +int cam_presil_retrieve_buffers_from_packet(struct cam_packet *packet, int iommu_hdl, + int out_res_id) +{ + int rc = 0, i, j; + struct cam_buf_io_cfg *io_cfg = NULL; + dma_addr_t io_addr[CAM_PACKET_MAX_PLANES]; + size_t size; + + if (!packet || (iommu_hdl < 0)) { + CAM_ERR(CAM_PRESIL, "Invalid params packet %pK iommu_hdl: %d", packet, iommu_hdl); + return -EINVAL; + } + + CAM_DBG(CAM_PRESIL, "Retrieving output buffer corresponding to res: 0x%x", out_res_id); + io_cfg = (struct cam_buf_io_cfg *)((uint8_t *)&packet->payload + packet->io_configs_offset); + for (i = 0; i < packet->num_io_configs; i++) { + if ((io_cfg[i].direction != CAM_BUF_OUTPUT) || + (io_cfg[i].resource_type != out_res_id)) + continue; + + memset(io_addr, 0, sizeof(io_addr)); + for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) { + if (!io_cfg[i].mem_handle[j]) + break; + + rc = cam_mem_get_io_buf(io_cfg[i].mem_handle[j], iommu_hdl, &io_addr[j], + &size, NULL); + if (rc) { + CAM_ERR(CAM_PRESIL, "no io addr for plane%d", j); + rc = -ENOMEM; + return rc; + } + + /* For presil, address should be within 32 bit */ + if (io_addr[j] >> 32) { + CAM_ERR(CAM_PRESIL, + "Invalid address, presil mapped address should be 32 bit"); + rc = -EINVAL; + return rc; + } + + CAM_INFO(CAM_PRESIL, + "Retrieving IO CFG buffer:%d addr: 0x%x offset 0x%x res_id: 0x%x", + io_cfg[i].mem_handle[j], io_addr[j], io_cfg[i].offsets[j], + io_cfg[i].resource_type); + cam_mem_mgr_retrieve_buffer_from_presil(io_cfg[i].mem_handle[j], size, + io_cfg[i].offsets[j], iommu_hdl); + } + } + + return rc; +} + +static void cam_presil_add_unique_buf_hdl_to_list(int32_t buf_hdl, + int32_t *hdl_list, int *num_hdls, int max_handles) +{ + int k; + bool hdl_found = false; + + if (!buf_hdl) + return; + + if (*num_hdls >= max_handles) { + CAM_ERR(CAM_PRESIL, "Failed to add entry num_hdls: %d max_handles:%d", *num_hdls, + max_handles); + return; + } + + for (k = 0; k < *num_hdls; k++) { + if (hdl_list[k] == buf_hdl) { + hdl_found = true; + break; + } + } + + if (!hdl_found) + hdl_list[(*num_hdls)++] = buf_hdl; +} + +int cam_presil_send_buffers_from_packet(struct cam_packet *packet, int img_iommu_hdl, + int cdm_iommu_hdl) +{ + struct cam_buf_io_cfg *io_cfg = NULL; + struct cam_cmd_buf_desc *cmd_desc = NULL; + struct cam_patch_desc *patch_desc = NULL; + int i, j, rc = 0; + int32_t unique_img_buffers[CAM_PRESIL_UNIQUE_HDL_MAX] = {0}; + int32_t unique_cmd_buffers[CAM_PRESIL_UNIQUE_HDL_MAX] = {0}; + int num_img_handles = 0, num_cmd_handles = 0; + + if(!packet) { + CAM_ERR(CAM_PRESIL, "Packet is NULL"); + return -EINVAL; + } + + if (img_iommu_hdl == -1) { + goto send_cmd_buffers; + } + + /* Adding IO config buffer handles to list*/ + io_cfg = (struct cam_buf_io_cfg *)((uint8_t *)&packet->payload + packet->io_configs_offset); + for (i = 0; i < packet->num_io_configs; i++) { + if (io_cfg[i].direction == CAM_BUF_OUTPUT) + continue; + + for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) { + if (!io_cfg[i].mem_handle[j]) + break; + + CAM_DBG(CAM_PRESIL, "Adding IO CFG buffer:%d", io_cfg[i].mem_handle[j]); + cam_presil_add_unique_buf_hdl_to_list(io_cfg[i].mem_handle[j], + unique_img_buffers, &num_img_handles, CAM_PRESIL_UNIQUE_HDL_MAX); + } + } + + for (i = 0; i < num_img_handles; i++) { + CAM_DBG(CAM_PRESIL, "Sending Image buffer i:%d mem_handle:%d", i, + unique_img_buffers[i]); + rc = cam_mem_mgr_send_buffer_to_presil(img_iommu_hdl, + unique_img_buffers[i]); + if (rc) { + CAM_ERR(CAM_PRESIL, "Failed to send buffer i:%d mem_handle:%d rc:%d", + i, unique_img_buffers[i], rc); + return rc; + } + } + +send_cmd_buffers: + if (cdm_iommu_hdl == -1) { + goto end; + } + + /* Adding CMD buffer handles to list*/ + cmd_desc = (struct cam_cmd_buf_desc *) ((uint8_t *)&packet->payload + + packet->cmd_buf_offset); + for (i = 0; i < packet->num_cmd_buf; i++) { + CAM_DBG(CAM_PRESIL, "Adding CMD buffer:%d", cmd_desc[i].mem_handle); + cam_presil_add_unique_buf_hdl_to_list(cmd_desc[i].mem_handle, + unique_cmd_buffers, &num_cmd_handles, CAM_PRESIL_UNIQUE_HDL_MAX); + } + + /* Adding Patch src buffer handles to list */ + patch_desc = (struct cam_patch_desc *) ((uint8_t *)&packet->payload + packet->patch_offset); + for (i = 0; i < packet->num_patches; i++) { + CAM_DBG(CAM_PRESIL, "Adding Patch src buffer:%d", patch_desc[i].src_buf_hdl); + cam_presil_add_unique_buf_hdl_to_list(patch_desc[i].src_buf_hdl, + unique_cmd_buffers, &num_cmd_handles, CAM_PRESIL_UNIQUE_HDL_MAX); + } + + for (i = 0; i < num_cmd_handles; i++) { + CAM_DBG(CAM_PRESIL, "Sending Command buffer i:%d mem_handle:%d", i, + unique_cmd_buffers[i]); + rc = cam_mem_mgr_send_buffer_to_presil(cdm_iommu_hdl, + unique_cmd_buffers[i]); + if (rc) { + CAM_ERR(CAM_PRESIL, "Failed to send buffer i:%d mem_handle:%d rc:%d", + i, unique_cmd_buffers[i], rc); + return rc; + } + } + +end: + return rc; +} diff --git a/drivers/cam_utils/cam_packet_util.h b/drivers/cam_utils/cam_packet_util.h index 62866a962c..54ae0db76a 100644 --- a/drivers/cam_utils/cam_packet_util.h +++ b/drivers/cam_utils/cam_packet_util.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ #ifndef _CAM_PACKET_UTIL_H_ @@ -137,4 +137,28 @@ int cam_packet_util_process_generic_cmd_buffer( struct cam_cmd_buf_desc *cmd_buf, cam_packet_generic_blob_handler blob_handler_cb, void *user_data); +/** + * @brief : API to retrieve image buffers from presil after processing is + * done,using packet from request + * + * @packet: Packet pointer for current request + * @iommu_hdl: IOMMU hdl for Image buffers + * @out_res_id: Resource ID corresponding to the output buffer + * + * @return: Success or Failure + */ +int cam_presil_retrieve_buffers_from_packet(struct cam_packet *packet, int iommu_hdl, + int out_res_id); + +/** + * @brief : API to send relevant buffers to presil + * + * @packet : Packet pointer for current request + * @img_iommu_hdl: IOMMU hdl for Image buffers + * @cdm_iommu_hdl: IOMMU hdl for cdm buffers + * + */ +int cam_presil_send_buffers_from_packet(struct cam_packet *packet, int img_iommu_hdl, + int cdm_iommu_hdl); + #endif /* _CAM_PACKET_UTIL_H_ */