Loading drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +11 −7 Original line number Original line Diff line number Diff line Loading @@ -86,7 +86,8 @@ static int __cam_isp_ctx_enqueue_init_request( struct cam_ctx_request, list); struct cam_ctx_request, list); req_isp_old = (struct cam_isp_ctx_req *) req_old->req_priv; req_isp_old = (struct cam_isp_ctx_req *) req_old->req_priv; req_isp_new = (struct cam_isp_ctx_req *) req->req_priv; req_isp_new = (struct cam_isp_ctx_req *) req->req_priv; if (req_isp_old->packet_opcode_type == CAM_ISP_PACKET_INIT_DEV) { if (req_isp_old->hw_update_data.packet_opcode_type == CAM_ISP_PACKET_INIT_DEV) { if ((req_isp_old->num_cfg + req_isp_new->num_cfg) >= if ((req_isp_old->num_cfg + req_isp_new->num_cfg) >= CAM_ISP_CTX_CFG_MAX) { CAM_ISP_CTX_CFG_MAX) { CAM_WARN(CAM_ISP, "Can not merge INIT pkt"); CAM_WARN(CAM_ISP, "Can not merge INIT pkt"); Loading Loading @@ -1071,6 +1072,7 @@ static int __cam_isp_ctx_apply_req_in_activated_state( cfg.ctxt_to_hw_map = ctx_isp->hw_ctx; cfg.ctxt_to_hw_map = ctx_isp->hw_ctx; cfg.hw_update_entries = req_isp->cfg; cfg.hw_update_entries = req_isp->cfg; cfg.num_hw_update_entries = req_isp->num_cfg; cfg.num_hw_update_entries = req_isp->num_cfg; cfg.priv = &req_isp->hw_update_data; rc = ctx->hw_mgr_intf->hw_config(ctx->hw_mgr_intf->hw_mgr_priv, &cfg); rc = ctx->hw_mgr_intf->hw_config(ctx->hw_mgr_intf->hw_mgr_priv, &cfg); if (rc) { if (rc) { Loading Loading @@ -1817,7 +1819,6 @@ static int __cam_isp_ctx_config_dev_in_top_state( struct cam_req_mgr_add_request add_req; struct cam_req_mgr_add_request add_req; struct cam_isp_context *ctx_isp = struct cam_isp_context *ctx_isp = (struct cam_isp_context *) ctx->ctx_priv; (struct cam_isp_context *) ctx->ctx_priv; struct cam_isp_prepare_hw_update_data hw_update_data; CAM_DBG(CAM_ISP, "get free request object......"); CAM_DBG(CAM_ISP, "get free request object......"); Loading Loading @@ -1868,7 +1869,7 @@ static int __cam_isp_ctx_config_dev_in_top_state( cfg.max_in_map_entries = CAM_ISP_CTX_RES_MAX; cfg.max_in_map_entries = CAM_ISP_CTX_RES_MAX; cfg.out_map_entries = req_isp->fence_map_out; cfg.out_map_entries = req_isp->fence_map_out; cfg.in_map_entries = req_isp->fence_map_in; cfg.in_map_entries = req_isp->fence_map_in; cfg.priv = &hw_update_data; cfg.priv = &req_isp->hw_update_data; CAM_DBG(CAM_ISP, "try to prepare config packet......"); CAM_DBG(CAM_ISP, "try to prepare config packet......"); Loading @@ -1883,7 +1884,6 @@ static int __cam_isp_ctx_config_dev_in_top_state( req_isp->num_fence_map_out = cfg.num_out_map_entries; req_isp->num_fence_map_out = cfg.num_out_map_entries; req_isp->num_fence_map_in = cfg.num_in_map_entries; req_isp->num_fence_map_in = cfg.num_in_map_entries; req_isp->num_acked = 0; req_isp->num_acked = 0; req_isp->packet_opcode_type = hw_update_data.packet_opcode_type; CAM_DBG(CAM_ISP, "num_entry: %d, num fence out: %d, num fence in: %d", CAM_DBG(CAM_ISP, "num_entry: %d, num fence out: %d, num fence in: %d", req_isp->num_cfg, req_isp->num_fence_map_out, req_isp->num_cfg, req_isp->num_fence_map_out, Loading @@ -1893,9 +1893,11 @@ static int __cam_isp_ctx_config_dev_in_top_state( req->status = 1; req->status = 1; CAM_DBG(CAM_ISP, "Packet request id 0x%llx packet opcode:%d", CAM_DBG(CAM_ISP, "Packet request id 0x%llx packet opcode:%d", packet->header.request_id, req_isp->packet_opcode_type); packet->header.request_id, req_isp->hw_update_data.packet_opcode_type); if (req_isp->packet_opcode_type == CAM_ISP_PACKET_INIT_DEV) { if (req_isp->hw_update_data.packet_opcode_type == CAM_ISP_PACKET_INIT_DEV) { if (ctx->state < CAM_CTX_ACTIVATED) { if (ctx->state < CAM_CTX_ACTIVATED) { rc = __cam_isp_ctx_enqueue_init_request(ctx, req); rc = __cam_isp_ctx_enqueue_init_request(ctx, req); if (rc) if (rc) Loading Loading @@ -2140,7 +2142,7 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx, struct cam_start_stop_dev_cmd *cmd) struct cam_start_stop_dev_cmd *cmd) { { int rc = 0; int rc = 0; struct cam_hw_start_args arg; struct cam_hw_config_args arg; struct cam_ctx_request *req; struct cam_ctx_request *req; struct cam_isp_ctx_req *req_isp; struct cam_isp_ctx_req *req_isp; struct cam_isp_context *ctx_isp = struct cam_isp_context *ctx_isp = Loading Loading @@ -2168,9 +2170,11 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx, rc = -EFAULT; rc = -EFAULT; goto end; goto end; } } arg.ctxt_to_hw_map = ctx_isp->hw_ctx; arg.ctxt_to_hw_map = ctx_isp->hw_ctx; arg.hw_update_entries = req_isp->cfg; arg.hw_update_entries = req_isp->cfg; arg.num_hw_update_entries = req_isp->num_cfg; arg.num_hw_update_entries = req_isp->num_cfg; arg.priv = &req_isp->hw_update_data; ctx_isp->frame_id = 0; ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; ctx_isp->active_req_cnt = 0; Loading drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h +13 −13 Original line number Original line Diff line number Diff line Loading @@ -82,8 +82,7 @@ struct cam_isp_ctx_irq_ops { * the request has been completed. * the request has been completed. * @bubble_report: Flag to track if bubble report is active on * @bubble_report: Flag to track if bubble report is active on * current request * current request * @packet_opcode_type: Request packet opcode type, * @hw_update_data: HW update data for this request * ie INIT packet or update packet * * */ */ struct cam_isp_ctx_req { struct cam_isp_ctx_req { Loading @@ -91,13 +90,14 @@ struct cam_isp_ctx_req { struct cam_hw_update_entry cfg[CAM_ISP_CTX_CFG_MAX]; struct cam_hw_update_entry cfg[CAM_ISP_CTX_CFG_MAX]; uint32_t num_cfg; uint32_t num_cfg; struct cam_hw_fence_map_entry fence_map_out[CAM_ISP_CTX_RES_MAX]; struct cam_hw_fence_map_entry fence_map_out [CAM_ISP_CTX_RES_MAX]; uint32_t num_fence_map_out; uint32_t num_fence_map_out; struct cam_hw_fence_map_entry fence_map_in[CAM_ISP_CTX_RES_MAX]; struct cam_hw_fence_map_entry fence_map_in[CAM_ISP_CTX_RES_MAX]; uint32_t num_fence_map_in; uint32_t num_fence_map_in; uint32_t num_acked; uint32_t num_acked; int32_t bubble_report; int32_t bubble_report; uint32_t packet_opcode_type; struct cam_isp_prepare_hw_update_data hw_update_data; }; }; /** /** Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +121 −94 Original line number Original line Diff line number Diff line Loading @@ -1444,15 +1444,97 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, return rc; return rc; } } static int cam_isp_blob_bw_update( struct cam_isp_bw_config *bw_config, struct cam_ife_hw_mgr_ctx *ctx) { struct cam_ife_hw_mgr_res *hw_mgr_res; struct cam_hw_intf *hw_intf; struct cam_vfe_bw_update_args bw_upd_args; uint64_t cam_bw_bps = 0; uint64_t ext_bw_bps = 0; int rc = -EINVAL; uint32_t i; CAM_DBG(CAM_ISP, "usage=%u left cam_bw_bps=%llu ext_bw_bps=%llu\n" "right cam_bw_bps=%llu ext_bw_bps=%llu", bw_config->usage_type, bw_config->left_pix_vote.cam_bw_bps, bw_config->left_pix_vote.ext_bw_bps, bw_config->right_pix_vote.cam_bw_bps, bw_config->right_pix_vote.ext_bw_bps); list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) { for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { if (!hw_mgr_res->hw_res[i]) continue; if (hw_mgr_res->res_id == CAM_ISP_HW_VFE_IN_CAMIF) if (i == CAM_ISP_HW_SPLIT_LEFT) { cam_bw_bps = bw_config->left_pix_vote.cam_bw_bps; ext_bw_bps = bw_config->left_pix_vote.ext_bw_bps; } else { cam_bw_bps = bw_config->right_pix_vote.cam_bw_bps; ext_bw_bps = bw_config->right_pix_vote.ext_bw_bps; } else if ((hw_mgr_res->res_id >= CAM_ISP_HW_VFE_IN_RDI0) && (hw_mgr_res->res_id <= CAM_ISP_HW_VFE_IN_RDI3)) { uint32_t idx = hw_mgr_res->res_id - CAM_ISP_HW_VFE_IN_RDI0; if (idx >= bw_config->num_rdi) continue; cam_bw_bps = bw_config->rdi_vote[idx].cam_bw_bps; ext_bw_bps = bw_config->rdi_vote[idx].ext_bw_bps; } else if (hw_mgr_res->hw_res[i]) { CAM_ERR(CAM_ISP, "Invalid res_id %u", hw_mgr_res->res_id); rc = -EINVAL; return rc; } hw_intf = hw_mgr_res->hw_res[i]->hw_intf; if (hw_intf && hw_intf->hw_ops.process_cmd) { bw_upd_args.node_res = hw_mgr_res->hw_res[i]; bw_upd_args.camnoc_bw_bytes = cam_bw_bps; bw_upd_args.external_bw_bytes = ext_bw_bps; rc = hw_intf->hw_ops.process_cmd( hw_intf->hw_priv, CAM_ISP_HW_CMD_BW_UPDATE, &bw_upd_args, sizeof(struct cam_vfe_bw_update_args)); if (rc) CAM_ERR(CAM_ISP, "BW Update failed"); } else CAM_WARN(CAM_ISP, "NULL hw_intf!"); } } return rc; } /* entry function: config_hw */ /* entry function: config_hw */ static int cam_ife_mgr_config_hw(void *hw_mgr_priv, static int cam_ife_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args) void *config_hw_args) { { int rc = -1, i; int rc = -1, i; struct cam_hw_start_args *cfg; struct cam_hw_config_args *cfg; struct cam_hw_update_entry *cmd; struct cam_hw_update_entry *cmd; struct cam_cdm_bl_request *cdm_cmd; struct cam_cdm_bl_request *cdm_cmd; struct cam_ife_hw_mgr_ctx *ctx; struct cam_ife_hw_mgr_ctx *ctx; struct cam_isp_prepare_hw_update_data *hw_update_data; CAM_DBG(CAM_ISP, "Enter"); CAM_DBG(CAM_ISP, "Enter"); if (!hw_mgr_priv || !config_hw_args) { if (!hw_mgr_priv || !config_hw_args) { Loading @@ -1474,6 +1556,18 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv, if (atomic_read(&ctx->overflow_pending)) if (atomic_read(&ctx->overflow_pending)) return -EINVAL; return -EINVAL; hw_update_data = (struct cam_isp_prepare_hw_update_data *) cfg->priv; for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) { if (hw_update_data->bw_config_valid[i] == true) { rc = cam_isp_blob_bw_update( (struct cam_isp_bw_config *) &hw_update_data->bw_config[i], ctx); if (rc) CAM_ERR(CAM_ISP, "Bandwidth Update Failed"); } } CAM_DBG(CAM_ISP, "Enter ctx id:%d num_hw_upd_entries %d", CAM_DBG(CAM_ISP, "Enter ctx id:%d num_hw_upd_entries %d", ctx->ctx_index, cfg->num_hw_update_entries); ctx->ctx_index, cfg->num_hw_update_entries); Loading Loading @@ -1805,7 +1899,7 @@ static int cam_ife_mgr_restart_hw(void *start_hw_args) static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args) static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args) { { int rc = -1; int rc = -1; struct cam_hw_start_args *start_args = start_hw_args; struct cam_hw_config_args *start_args = start_hw_args; struct cam_ife_hw_mgr_ctx *ctx; struct cam_ife_hw_mgr_ctx *ctx; struct cam_ife_hw_mgr_res *hw_mgr_res; struct cam_ife_hw_mgr_res *hw_mgr_res; uint32_t i; uint32_t i; Loading Loading @@ -2211,92 +2305,6 @@ static int cam_isp_blob_clock_update( return rc; return rc; } } static int cam_isp_blob_bw_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, struct cam_isp_bw_config *bw_config, struct cam_hw_prepare_update_args *prepare) { struct cam_ife_hw_mgr_ctx *ctx = NULL; struct cam_ife_hw_mgr_res *hw_mgr_res; struct cam_hw_intf *hw_intf; struct cam_vfe_bw_update_args bw_upd_args; uint64_t cam_bw_bps = 0; uint64_t ext_bw_bps = 0; int rc = -EINVAL; uint32_t i; ctx = prepare->ctxt_to_hw_map; CAM_DBG(CAM_ISP, "usage=%u left cam_bw_bps=%llu ext_bw_bps=%llu\n" "right cam_bw_bps=%llu ext_bw_bps=%llu", bw_config->usage_type, bw_config->left_pix_vote.cam_bw_bps, bw_config->left_pix_vote.ext_bw_bps, bw_config->right_pix_vote.cam_bw_bps, bw_config->right_pix_vote.ext_bw_bps); list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) { for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { if (!hw_mgr_res->hw_res[i]) continue; if (hw_mgr_res->res_id == CAM_ISP_HW_VFE_IN_CAMIF) if (i == CAM_ISP_HW_SPLIT_LEFT) { cam_bw_bps = bw_config->left_pix_vote.cam_bw_bps; ext_bw_bps = bw_config->left_pix_vote.ext_bw_bps; } else { cam_bw_bps = bw_config->right_pix_vote.cam_bw_bps; ext_bw_bps = bw_config->right_pix_vote.ext_bw_bps; } else if ((hw_mgr_res->res_id >= CAM_ISP_HW_VFE_IN_RDI0) && (hw_mgr_res->res_id <= CAM_ISP_HW_VFE_IN_RDI3)) { uint32_t idx = hw_mgr_res->res_id - CAM_ISP_HW_VFE_IN_RDI0; if (idx >= bw_config->num_rdi) continue; cam_bw_bps = bw_config->rdi_vote[idx].cam_bw_bps; ext_bw_bps = bw_config->rdi_vote[idx].ext_bw_bps; } else if (hw_mgr_res->hw_res[i]) { CAM_ERR(CAM_ISP, "Invalid res_id %u", hw_mgr_res->res_id); rc = -EINVAL; return rc; } hw_intf = hw_mgr_res->hw_res[i]->hw_intf; if (hw_intf && hw_intf->hw_ops.process_cmd) { bw_upd_args.node_res = hw_mgr_res->hw_res[i]; bw_upd_args.camnoc_bw_bytes = cam_bw_bps; bw_upd_args.external_bw_bytes = ext_bw_bps; rc = hw_intf->hw_ops.process_cmd( hw_intf->hw_priv, CAM_ISP_HW_CMD_BW_UPDATE, &bw_upd_args, sizeof(struct cam_vfe_bw_update_args)); if (rc) CAM_ERR(CAM_ISP, "BW Update failed"); } else CAM_WARN(CAM_ISP, "NULL hw_intf!"); } } return rc; } static int cam_isp_packet_generic_blob_handler(void *user_data, static int cam_isp_packet_generic_blob_handler(void *user_data, uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data) uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data) { { Loading Loading @@ -2347,11 +2355,22 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, case CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG: { case CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG: { struct cam_isp_bw_config *bw_config = struct cam_isp_bw_config *bw_config = (struct cam_isp_bw_config *)blob_data; (struct cam_isp_bw_config *)blob_data; struct cam_isp_prepare_hw_update_data *prepare_hw_data; if (!prepare || !prepare->priv || (bw_config->usage_type >= CAM_IFE_HW_NUM_MAX)) { CAM_ERR(CAM_ISP, "Invalid inputs"); rc = -EINVAL; break; } prepare_hw_data = (struct cam_isp_prepare_hw_update_data *) prepare->priv; memcpy(&prepare_hw_data->bw_config[bw_config->usage_type], bw_config, sizeof(prepare_hw_data->bw_config[0])); prepare_hw_data->bw_config_valid[bw_config->usage_type] = true; rc = cam_isp_blob_bw_update(blob_type, blob_info, bw_config, prepare); if (rc) CAM_ERR(CAM_ISP, "Bandwidth Update Failed"); } } break; break; default: default: Loading Loading @@ -2382,6 +2401,9 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, CAM_DBG(CAM_ISP, "enter"); CAM_DBG(CAM_ISP, "enter"); prepare_hw_data = (struct cam_isp_prepare_hw_update_data *) prepare->priv; ctx = (struct cam_ife_hw_mgr_ctx *) prepare->ctxt_to_hw_map; ctx = (struct cam_ife_hw_mgr_ctx *) prepare->ctxt_to_hw_map; hw_mgr = (struct cam_ife_hw_mgr *)hw_mgr_priv; hw_mgr = (struct cam_ife_hw_mgr *)hw_mgr_priv; Loading @@ -2406,6 +2428,13 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, prepare->num_in_map_entries = 0; prepare->num_in_map_entries = 0; prepare->num_out_map_entries = 0; prepare->num_out_map_entries = 0; memset(&prepare_hw_data->bw_config[0], 0x0, sizeof(prepare_hw_data->bw_config[0]) * CAM_IFE_HW_NUM_MAX); memset(&prepare_hw_data->bw_config_valid[0], 0x0, sizeof(prepare_hw_data->bw_config_valid[0]) * CAM_IFE_HW_NUM_MAX); for (i = 0; i < ctx->num_base; i++) { for (i = 0; i < ctx->num_base; i++) { CAM_DBG(CAM_ISP, "process cmd buffer for device %d", i); CAM_DBG(CAM_ISP, "process cmd buffer for device %d", i); Loading Loading @@ -2459,8 +2488,6 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, * bits to get the type of operation since UMD definition * bits to get the type of operation since UMD definition * of op_code has some difference from KMD. * of op_code has some difference from KMD. */ */ prepare_hw_data = (struct cam_isp_prepare_hw_update_data *) prepare->priv; if (((prepare->packet->header.op_code + 1) & 0xF) == if (((prepare->packet->header.op_code + 1) & 0xF) == CAM_ISP_PACKET_INIT_DEV) { CAM_ISP_PACKET_INIT_DEV) { prepare_hw_data->packet_opcode_type = CAM_ISP_PACKET_INIT_DEV; prepare_hw_data->packet_opcode_type = CAM_ISP_PACKET_INIT_DEV; Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +1 −4 Original line number Original line Diff line number Diff line /* Copyright (c) 2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and Loading @@ -18,9 +18,6 @@ #include "cam_ife_csid_hw_intf.h" #include "cam_ife_csid_hw_intf.h" #include "cam_tasklet_util.h" #include "cam_tasklet_util.h" /* MAX IFE instance */ #define CAM_IFE_HW_NUM_MAX 4 /* enum cam_ife_hw_mgr_res_type - manager resource node type */ /* enum cam_ife_hw_mgr_res_type - manager resource node type */ enum cam_ife_hw_mgr_res_type { enum cam_ife_hw_mgr_res_type { CAM_IFE_HW_MGR_RES_UNINIT, CAM_IFE_HW_MGR_RES_UNINIT, Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h +30 −3 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,10 @@ #include <uapi/media/cam_isp.h> #include <uapi/media/cam_isp.h> #include "cam_hw_mgr_intf.h" #include "cam_hw_mgr_intf.h" /* MAX IFE instance */ #define CAM_IFE_HW_NUM_MAX 4 #define CAM_IFE_RDI_NUM_MAX 4 /** /** * enum cam_isp_hw_event_type - Collection of the ISP hardware events * enum cam_isp_hw_event_type - Collection of the ISP hardware events */ */ Loading Loading @@ -46,16 +50,39 @@ enum cam_isp_hw_err_type { CAM_ISP_HW_ERROR_MAX, CAM_ISP_HW_ERROR_MAX, }; }; /** * struct cam_isp_bw_config_internal - Internal Bandwidth configuration * * @usage_type: Usage type (Single/Dual) * @num_rdi: Number of RDI votes * @left_pix_vote: Bandwidth vote for left ISP * @right_pix_vote: Bandwidth vote for right ISP * @rdi_vote: RDI bandwidth requirements */ struct cam_isp_bw_config_internal { uint32_t usage_type; uint32_t num_rdi; struct cam_isp_bw_vote left_pix_vote; struct cam_isp_bw_vote right_pix_vote; struct cam_isp_bw_vote rdi_vote[CAM_IFE_RDI_NUM_MAX]; }; /** /** * struct cam_isp_prepare_hw_update_data - hw prepare data * struct cam_isp_prepare_hw_update_data - hw prepare data * * * @packet_opcode_type: Packet header opcode in the packet header * @packet_opcode_type: Packet header opcode in the packet header * this opcode defines, packet is init packet or * this opcode defines, packet is init packet or * update packet * update packet * @bw_config: BW config information * @bw_config_valid: Flag indicating whether the bw_config at the index * is valid or not * * */ */ struct cam_isp_prepare_hw_update_data { struct cam_isp_prepare_hw_update_data { uint32_t packet_opcode_type; uint32_t packet_opcode_type; struct cam_isp_bw_config_internal bw_config[CAM_IFE_HW_NUM_MAX]; bool bw_config_valid[CAM_IFE_HW_NUM_MAX]; }; }; Loading Loading
drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +11 −7 Original line number Original line Diff line number Diff line Loading @@ -86,7 +86,8 @@ static int __cam_isp_ctx_enqueue_init_request( struct cam_ctx_request, list); struct cam_ctx_request, list); req_isp_old = (struct cam_isp_ctx_req *) req_old->req_priv; req_isp_old = (struct cam_isp_ctx_req *) req_old->req_priv; req_isp_new = (struct cam_isp_ctx_req *) req->req_priv; req_isp_new = (struct cam_isp_ctx_req *) req->req_priv; if (req_isp_old->packet_opcode_type == CAM_ISP_PACKET_INIT_DEV) { if (req_isp_old->hw_update_data.packet_opcode_type == CAM_ISP_PACKET_INIT_DEV) { if ((req_isp_old->num_cfg + req_isp_new->num_cfg) >= if ((req_isp_old->num_cfg + req_isp_new->num_cfg) >= CAM_ISP_CTX_CFG_MAX) { CAM_ISP_CTX_CFG_MAX) { CAM_WARN(CAM_ISP, "Can not merge INIT pkt"); CAM_WARN(CAM_ISP, "Can not merge INIT pkt"); Loading Loading @@ -1071,6 +1072,7 @@ static int __cam_isp_ctx_apply_req_in_activated_state( cfg.ctxt_to_hw_map = ctx_isp->hw_ctx; cfg.ctxt_to_hw_map = ctx_isp->hw_ctx; cfg.hw_update_entries = req_isp->cfg; cfg.hw_update_entries = req_isp->cfg; cfg.num_hw_update_entries = req_isp->num_cfg; cfg.num_hw_update_entries = req_isp->num_cfg; cfg.priv = &req_isp->hw_update_data; rc = ctx->hw_mgr_intf->hw_config(ctx->hw_mgr_intf->hw_mgr_priv, &cfg); rc = ctx->hw_mgr_intf->hw_config(ctx->hw_mgr_intf->hw_mgr_priv, &cfg); if (rc) { if (rc) { Loading Loading @@ -1817,7 +1819,6 @@ static int __cam_isp_ctx_config_dev_in_top_state( struct cam_req_mgr_add_request add_req; struct cam_req_mgr_add_request add_req; struct cam_isp_context *ctx_isp = struct cam_isp_context *ctx_isp = (struct cam_isp_context *) ctx->ctx_priv; (struct cam_isp_context *) ctx->ctx_priv; struct cam_isp_prepare_hw_update_data hw_update_data; CAM_DBG(CAM_ISP, "get free request object......"); CAM_DBG(CAM_ISP, "get free request object......"); Loading Loading @@ -1868,7 +1869,7 @@ static int __cam_isp_ctx_config_dev_in_top_state( cfg.max_in_map_entries = CAM_ISP_CTX_RES_MAX; cfg.max_in_map_entries = CAM_ISP_CTX_RES_MAX; cfg.out_map_entries = req_isp->fence_map_out; cfg.out_map_entries = req_isp->fence_map_out; cfg.in_map_entries = req_isp->fence_map_in; cfg.in_map_entries = req_isp->fence_map_in; cfg.priv = &hw_update_data; cfg.priv = &req_isp->hw_update_data; CAM_DBG(CAM_ISP, "try to prepare config packet......"); CAM_DBG(CAM_ISP, "try to prepare config packet......"); Loading @@ -1883,7 +1884,6 @@ static int __cam_isp_ctx_config_dev_in_top_state( req_isp->num_fence_map_out = cfg.num_out_map_entries; req_isp->num_fence_map_out = cfg.num_out_map_entries; req_isp->num_fence_map_in = cfg.num_in_map_entries; req_isp->num_fence_map_in = cfg.num_in_map_entries; req_isp->num_acked = 0; req_isp->num_acked = 0; req_isp->packet_opcode_type = hw_update_data.packet_opcode_type; CAM_DBG(CAM_ISP, "num_entry: %d, num fence out: %d, num fence in: %d", CAM_DBG(CAM_ISP, "num_entry: %d, num fence out: %d, num fence in: %d", req_isp->num_cfg, req_isp->num_fence_map_out, req_isp->num_cfg, req_isp->num_fence_map_out, Loading @@ -1893,9 +1893,11 @@ static int __cam_isp_ctx_config_dev_in_top_state( req->status = 1; req->status = 1; CAM_DBG(CAM_ISP, "Packet request id 0x%llx packet opcode:%d", CAM_DBG(CAM_ISP, "Packet request id 0x%llx packet opcode:%d", packet->header.request_id, req_isp->packet_opcode_type); packet->header.request_id, req_isp->hw_update_data.packet_opcode_type); if (req_isp->packet_opcode_type == CAM_ISP_PACKET_INIT_DEV) { if (req_isp->hw_update_data.packet_opcode_type == CAM_ISP_PACKET_INIT_DEV) { if (ctx->state < CAM_CTX_ACTIVATED) { if (ctx->state < CAM_CTX_ACTIVATED) { rc = __cam_isp_ctx_enqueue_init_request(ctx, req); rc = __cam_isp_ctx_enqueue_init_request(ctx, req); if (rc) if (rc) Loading Loading @@ -2140,7 +2142,7 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx, struct cam_start_stop_dev_cmd *cmd) struct cam_start_stop_dev_cmd *cmd) { { int rc = 0; int rc = 0; struct cam_hw_start_args arg; struct cam_hw_config_args arg; struct cam_ctx_request *req; struct cam_ctx_request *req; struct cam_isp_ctx_req *req_isp; struct cam_isp_ctx_req *req_isp; struct cam_isp_context *ctx_isp = struct cam_isp_context *ctx_isp = Loading Loading @@ -2168,9 +2170,11 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx, rc = -EFAULT; rc = -EFAULT; goto end; goto end; } } arg.ctxt_to_hw_map = ctx_isp->hw_ctx; arg.ctxt_to_hw_map = ctx_isp->hw_ctx; arg.hw_update_entries = req_isp->cfg; arg.hw_update_entries = req_isp->cfg; arg.num_hw_update_entries = req_isp->num_cfg; arg.num_hw_update_entries = req_isp->num_cfg; arg.priv = &req_isp->hw_update_data; ctx_isp->frame_id = 0; ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; ctx_isp->active_req_cnt = 0; Loading
drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h +13 −13 Original line number Original line Diff line number Diff line Loading @@ -82,8 +82,7 @@ struct cam_isp_ctx_irq_ops { * the request has been completed. * the request has been completed. * @bubble_report: Flag to track if bubble report is active on * @bubble_report: Flag to track if bubble report is active on * current request * current request * @packet_opcode_type: Request packet opcode type, * @hw_update_data: HW update data for this request * ie INIT packet or update packet * * */ */ struct cam_isp_ctx_req { struct cam_isp_ctx_req { Loading @@ -91,13 +90,14 @@ struct cam_isp_ctx_req { struct cam_hw_update_entry cfg[CAM_ISP_CTX_CFG_MAX]; struct cam_hw_update_entry cfg[CAM_ISP_CTX_CFG_MAX]; uint32_t num_cfg; uint32_t num_cfg; struct cam_hw_fence_map_entry fence_map_out[CAM_ISP_CTX_RES_MAX]; struct cam_hw_fence_map_entry fence_map_out [CAM_ISP_CTX_RES_MAX]; uint32_t num_fence_map_out; uint32_t num_fence_map_out; struct cam_hw_fence_map_entry fence_map_in[CAM_ISP_CTX_RES_MAX]; struct cam_hw_fence_map_entry fence_map_in[CAM_ISP_CTX_RES_MAX]; uint32_t num_fence_map_in; uint32_t num_fence_map_in; uint32_t num_acked; uint32_t num_acked; int32_t bubble_report; int32_t bubble_report; uint32_t packet_opcode_type; struct cam_isp_prepare_hw_update_data hw_update_data; }; }; /** /** Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +121 −94 Original line number Original line Diff line number Diff line Loading @@ -1444,15 +1444,97 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, return rc; return rc; } } static int cam_isp_blob_bw_update( struct cam_isp_bw_config *bw_config, struct cam_ife_hw_mgr_ctx *ctx) { struct cam_ife_hw_mgr_res *hw_mgr_res; struct cam_hw_intf *hw_intf; struct cam_vfe_bw_update_args bw_upd_args; uint64_t cam_bw_bps = 0; uint64_t ext_bw_bps = 0; int rc = -EINVAL; uint32_t i; CAM_DBG(CAM_ISP, "usage=%u left cam_bw_bps=%llu ext_bw_bps=%llu\n" "right cam_bw_bps=%llu ext_bw_bps=%llu", bw_config->usage_type, bw_config->left_pix_vote.cam_bw_bps, bw_config->left_pix_vote.ext_bw_bps, bw_config->right_pix_vote.cam_bw_bps, bw_config->right_pix_vote.ext_bw_bps); list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) { for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { if (!hw_mgr_res->hw_res[i]) continue; if (hw_mgr_res->res_id == CAM_ISP_HW_VFE_IN_CAMIF) if (i == CAM_ISP_HW_SPLIT_LEFT) { cam_bw_bps = bw_config->left_pix_vote.cam_bw_bps; ext_bw_bps = bw_config->left_pix_vote.ext_bw_bps; } else { cam_bw_bps = bw_config->right_pix_vote.cam_bw_bps; ext_bw_bps = bw_config->right_pix_vote.ext_bw_bps; } else if ((hw_mgr_res->res_id >= CAM_ISP_HW_VFE_IN_RDI0) && (hw_mgr_res->res_id <= CAM_ISP_HW_VFE_IN_RDI3)) { uint32_t idx = hw_mgr_res->res_id - CAM_ISP_HW_VFE_IN_RDI0; if (idx >= bw_config->num_rdi) continue; cam_bw_bps = bw_config->rdi_vote[idx].cam_bw_bps; ext_bw_bps = bw_config->rdi_vote[idx].ext_bw_bps; } else if (hw_mgr_res->hw_res[i]) { CAM_ERR(CAM_ISP, "Invalid res_id %u", hw_mgr_res->res_id); rc = -EINVAL; return rc; } hw_intf = hw_mgr_res->hw_res[i]->hw_intf; if (hw_intf && hw_intf->hw_ops.process_cmd) { bw_upd_args.node_res = hw_mgr_res->hw_res[i]; bw_upd_args.camnoc_bw_bytes = cam_bw_bps; bw_upd_args.external_bw_bytes = ext_bw_bps; rc = hw_intf->hw_ops.process_cmd( hw_intf->hw_priv, CAM_ISP_HW_CMD_BW_UPDATE, &bw_upd_args, sizeof(struct cam_vfe_bw_update_args)); if (rc) CAM_ERR(CAM_ISP, "BW Update failed"); } else CAM_WARN(CAM_ISP, "NULL hw_intf!"); } } return rc; } /* entry function: config_hw */ /* entry function: config_hw */ static int cam_ife_mgr_config_hw(void *hw_mgr_priv, static int cam_ife_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args) void *config_hw_args) { { int rc = -1, i; int rc = -1, i; struct cam_hw_start_args *cfg; struct cam_hw_config_args *cfg; struct cam_hw_update_entry *cmd; struct cam_hw_update_entry *cmd; struct cam_cdm_bl_request *cdm_cmd; struct cam_cdm_bl_request *cdm_cmd; struct cam_ife_hw_mgr_ctx *ctx; struct cam_ife_hw_mgr_ctx *ctx; struct cam_isp_prepare_hw_update_data *hw_update_data; CAM_DBG(CAM_ISP, "Enter"); CAM_DBG(CAM_ISP, "Enter"); if (!hw_mgr_priv || !config_hw_args) { if (!hw_mgr_priv || !config_hw_args) { Loading @@ -1474,6 +1556,18 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv, if (atomic_read(&ctx->overflow_pending)) if (atomic_read(&ctx->overflow_pending)) return -EINVAL; return -EINVAL; hw_update_data = (struct cam_isp_prepare_hw_update_data *) cfg->priv; for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) { if (hw_update_data->bw_config_valid[i] == true) { rc = cam_isp_blob_bw_update( (struct cam_isp_bw_config *) &hw_update_data->bw_config[i], ctx); if (rc) CAM_ERR(CAM_ISP, "Bandwidth Update Failed"); } } CAM_DBG(CAM_ISP, "Enter ctx id:%d num_hw_upd_entries %d", CAM_DBG(CAM_ISP, "Enter ctx id:%d num_hw_upd_entries %d", ctx->ctx_index, cfg->num_hw_update_entries); ctx->ctx_index, cfg->num_hw_update_entries); Loading Loading @@ -1805,7 +1899,7 @@ static int cam_ife_mgr_restart_hw(void *start_hw_args) static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args) static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args) { { int rc = -1; int rc = -1; struct cam_hw_start_args *start_args = start_hw_args; struct cam_hw_config_args *start_args = start_hw_args; struct cam_ife_hw_mgr_ctx *ctx; struct cam_ife_hw_mgr_ctx *ctx; struct cam_ife_hw_mgr_res *hw_mgr_res; struct cam_ife_hw_mgr_res *hw_mgr_res; uint32_t i; uint32_t i; Loading Loading @@ -2211,92 +2305,6 @@ static int cam_isp_blob_clock_update( return rc; return rc; } } static int cam_isp_blob_bw_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, struct cam_isp_bw_config *bw_config, struct cam_hw_prepare_update_args *prepare) { struct cam_ife_hw_mgr_ctx *ctx = NULL; struct cam_ife_hw_mgr_res *hw_mgr_res; struct cam_hw_intf *hw_intf; struct cam_vfe_bw_update_args bw_upd_args; uint64_t cam_bw_bps = 0; uint64_t ext_bw_bps = 0; int rc = -EINVAL; uint32_t i; ctx = prepare->ctxt_to_hw_map; CAM_DBG(CAM_ISP, "usage=%u left cam_bw_bps=%llu ext_bw_bps=%llu\n" "right cam_bw_bps=%llu ext_bw_bps=%llu", bw_config->usage_type, bw_config->left_pix_vote.cam_bw_bps, bw_config->left_pix_vote.ext_bw_bps, bw_config->right_pix_vote.cam_bw_bps, bw_config->right_pix_vote.ext_bw_bps); list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) { for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { if (!hw_mgr_res->hw_res[i]) continue; if (hw_mgr_res->res_id == CAM_ISP_HW_VFE_IN_CAMIF) if (i == CAM_ISP_HW_SPLIT_LEFT) { cam_bw_bps = bw_config->left_pix_vote.cam_bw_bps; ext_bw_bps = bw_config->left_pix_vote.ext_bw_bps; } else { cam_bw_bps = bw_config->right_pix_vote.cam_bw_bps; ext_bw_bps = bw_config->right_pix_vote.ext_bw_bps; } else if ((hw_mgr_res->res_id >= CAM_ISP_HW_VFE_IN_RDI0) && (hw_mgr_res->res_id <= CAM_ISP_HW_VFE_IN_RDI3)) { uint32_t idx = hw_mgr_res->res_id - CAM_ISP_HW_VFE_IN_RDI0; if (idx >= bw_config->num_rdi) continue; cam_bw_bps = bw_config->rdi_vote[idx].cam_bw_bps; ext_bw_bps = bw_config->rdi_vote[idx].ext_bw_bps; } else if (hw_mgr_res->hw_res[i]) { CAM_ERR(CAM_ISP, "Invalid res_id %u", hw_mgr_res->res_id); rc = -EINVAL; return rc; } hw_intf = hw_mgr_res->hw_res[i]->hw_intf; if (hw_intf && hw_intf->hw_ops.process_cmd) { bw_upd_args.node_res = hw_mgr_res->hw_res[i]; bw_upd_args.camnoc_bw_bytes = cam_bw_bps; bw_upd_args.external_bw_bytes = ext_bw_bps; rc = hw_intf->hw_ops.process_cmd( hw_intf->hw_priv, CAM_ISP_HW_CMD_BW_UPDATE, &bw_upd_args, sizeof(struct cam_vfe_bw_update_args)); if (rc) CAM_ERR(CAM_ISP, "BW Update failed"); } else CAM_WARN(CAM_ISP, "NULL hw_intf!"); } } return rc; } static int cam_isp_packet_generic_blob_handler(void *user_data, static int cam_isp_packet_generic_blob_handler(void *user_data, uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data) uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data) { { Loading Loading @@ -2347,11 +2355,22 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, case CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG: { case CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG: { struct cam_isp_bw_config *bw_config = struct cam_isp_bw_config *bw_config = (struct cam_isp_bw_config *)blob_data; (struct cam_isp_bw_config *)blob_data; struct cam_isp_prepare_hw_update_data *prepare_hw_data; if (!prepare || !prepare->priv || (bw_config->usage_type >= CAM_IFE_HW_NUM_MAX)) { CAM_ERR(CAM_ISP, "Invalid inputs"); rc = -EINVAL; break; } prepare_hw_data = (struct cam_isp_prepare_hw_update_data *) prepare->priv; memcpy(&prepare_hw_data->bw_config[bw_config->usage_type], bw_config, sizeof(prepare_hw_data->bw_config[0])); prepare_hw_data->bw_config_valid[bw_config->usage_type] = true; rc = cam_isp_blob_bw_update(blob_type, blob_info, bw_config, prepare); if (rc) CAM_ERR(CAM_ISP, "Bandwidth Update Failed"); } } break; break; default: default: Loading Loading @@ -2382,6 +2401,9 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, CAM_DBG(CAM_ISP, "enter"); CAM_DBG(CAM_ISP, "enter"); prepare_hw_data = (struct cam_isp_prepare_hw_update_data *) prepare->priv; ctx = (struct cam_ife_hw_mgr_ctx *) prepare->ctxt_to_hw_map; ctx = (struct cam_ife_hw_mgr_ctx *) prepare->ctxt_to_hw_map; hw_mgr = (struct cam_ife_hw_mgr *)hw_mgr_priv; hw_mgr = (struct cam_ife_hw_mgr *)hw_mgr_priv; Loading @@ -2406,6 +2428,13 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, prepare->num_in_map_entries = 0; prepare->num_in_map_entries = 0; prepare->num_out_map_entries = 0; prepare->num_out_map_entries = 0; memset(&prepare_hw_data->bw_config[0], 0x0, sizeof(prepare_hw_data->bw_config[0]) * CAM_IFE_HW_NUM_MAX); memset(&prepare_hw_data->bw_config_valid[0], 0x0, sizeof(prepare_hw_data->bw_config_valid[0]) * CAM_IFE_HW_NUM_MAX); for (i = 0; i < ctx->num_base; i++) { for (i = 0; i < ctx->num_base; i++) { CAM_DBG(CAM_ISP, "process cmd buffer for device %d", i); CAM_DBG(CAM_ISP, "process cmd buffer for device %d", i); Loading Loading @@ -2459,8 +2488,6 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, * bits to get the type of operation since UMD definition * bits to get the type of operation since UMD definition * of op_code has some difference from KMD. * of op_code has some difference from KMD. */ */ prepare_hw_data = (struct cam_isp_prepare_hw_update_data *) prepare->priv; if (((prepare->packet->header.op_code + 1) & 0xF) == if (((prepare->packet->header.op_code + 1) & 0xF) == CAM_ISP_PACKET_INIT_DEV) { CAM_ISP_PACKET_INIT_DEV) { prepare_hw_data->packet_opcode_type = CAM_ISP_PACKET_INIT_DEV; prepare_hw_data->packet_opcode_type = CAM_ISP_PACKET_INIT_DEV; Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +1 −4 Original line number Original line Diff line number Diff line /* Copyright (c) 2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and Loading @@ -18,9 +18,6 @@ #include "cam_ife_csid_hw_intf.h" #include "cam_ife_csid_hw_intf.h" #include "cam_tasklet_util.h" #include "cam_tasklet_util.h" /* MAX IFE instance */ #define CAM_IFE_HW_NUM_MAX 4 /* enum cam_ife_hw_mgr_res_type - manager resource node type */ /* enum cam_ife_hw_mgr_res_type - manager resource node type */ enum cam_ife_hw_mgr_res_type { enum cam_ife_hw_mgr_res_type { CAM_IFE_HW_MGR_RES_UNINIT, CAM_IFE_HW_MGR_RES_UNINIT, Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h +30 −3 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,10 @@ #include <uapi/media/cam_isp.h> #include <uapi/media/cam_isp.h> #include "cam_hw_mgr_intf.h" #include "cam_hw_mgr_intf.h" /* MAX IFE instance */ #define CAM_IFE_HW_NUM_MAX 4 #define CAM_IFE_RDI_NUM_MAX 4 /** /** * enum cam_isp_hw_event_type - Collection of the ISP hardware events * enum cam_isp_hw_event_type - Collection of the ISP hardware events */ */ Loading Loading @@ -46,16 +50,39 @@ enum cam_isp_hw_err_type { CAM_ISP_HW_ERROR_MAX, CAM_ISP_HW_ERROR_MAX, }; }; /** * struct cam_isp_bw_config_internal - Internal Bandwidth configuration * * @usage_type: Usage type (Single/Dual) * @num_rdi: Number of RDI votes * @left_pix_vote: Bandwidth vote for left ISP * @right_pix_vote: Bandwidth vote for right ISP * @rdi_vote: RDI bandwidth requirements */ struct cam_isp_bw_config_internal { uint32_t usage_type; uint32_t num_rdi; struct cam_isp_bw_vote left_pix_vote; struct cam_isp_bw_vote right_pix_vote; struct cam_isp_bw_vote rdi_vote[CAM_IFE_RDI_NUM_MAX]; }; /** /** * struct cam_isp_prepare_hw_update_data - hw prepare data * struct cam_isp_prepare_hw_update_data - hw prepare data * * * @packet_opcode_type: Packet header opcode in the packet header * @packet_opcode_type: Packet header opcode in the packet header * this opcode defines, packet is init packet or * this opcode defines, packet is init packet or * update packet * update packet * @bw_config: BW config information * @bw_config_valid: Flag indicating whether the bw_config at the index * is valid or not * * */ */ struct cam_isp_prepare_hw_update_data { struct cam_isp_prepare_hw_update_data { uint32_t packet_opcode_type; uint32_t packet_opcode_type; struct cam_isp_bw_config_internal bw_config[CAM_IFE_HW_NUM_MAX]; bool bw_config_valid[CAM_IFE_HW_NUM_MAX]; }; }; Loading