msm: camera: isp: Buffer alignment support for TFE WM
This change is added to support buffer alignment for TFE WM in x and y axis. This change is required in SHDR usecase to align short exposure frame with long exposure frame. CRs-Fixed: 3538642 Change-Id: I9a3d35d0884bfbd6f62034b207e5784fdf2f7430 Signed-off-by: Ayush Kumar <quic_ayushkr@quicinc.com>
This commit is contained in:

committed by
Alok Chauhan

parent
fe4bd2e6a1
commit
bfbfc5d3d4
@@ -2008,12 +2008,15 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
|
||||
}
|
||||
|
||||
if (!req_isp->bubble_detected) {
|
||||
handle_type = __cam_isp_resource_handle_id_to_type(
|
||||
ctx_isp->isp_device_type,
|
||||
req_isp->fence_map_out[j].resource_handle);
|
||||
CAM_DBG(CAM_ISP,
|
||||
"Sync with success: req %lld res 0x%x fd 0x%x, ctx %u link: 0x%x",
|
||||
"Sync with success: req %lld res 0x%x fd 0x%x, ctx %u link: 0x%x port %s",
|
||||
req->request_id,
|
||||
req_isp->fence_map_out[j].resource_handle,
|
||||
req_isp->fence_map_out[j].sync_id,
|
||||
ctx->ctx_id, ctx->link_hdl);
|
||||
ctx->ctx_id, ctx->link_hdl, handle_type);
|
||||
|
||||
cam_smmu_buffer_tracker_buffer_putref(
|
||||
req_isp->fence_map_out[j].buffer_tracker);
|
||||
|
@@ -40,7 +40,6 @@
|
||||
#define CAM_TFE_SAFE_ENABLE 1
|
||||
#define SMMU_SE_TFE 0
|
||||
|
||||
|
||||
static struct cam_tfe_hw_mgr g_tfe_hw_mgr;
|
||||
|
||||
static int cam_tfe_hw_mgr_event_handler(
|
||||
@@ -4091,6 +4090,56 @@ static int cam_tfe_mgr_release_hw(void *hw_mgr_priv,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_isp_tfe_blob_buffer_alignment_update(
|
||||
uint32_t blob_type,
|
||||
struct cam_isp_generic_blob_info *blob_info,
|
||||
struct cam_isp_tfe_alignment_resource_info *alignment_info,
|
||||
struct cam_hw_prepare_update_args *prepare)
|
||||
{
|
||||
struct cam_isp_tfe_alignment_offset_config *alignment_port_cfg;
|
||||
struct cam_isp_resource_node *res;
|
||||
struct cam_isp_hw_get_cmd_update cmd_update;
|
||||
struct cam_tfe_hw_mgr_ctx *ctx = NULL;
|
||||
struct cam_isp_hw_mgr_res *hw_mgr_res;
|
||||
struct cam_hw_intf *hw_intf;
|
||||
uint32_t res_id_out, i;
|
||||
int rc = 0;
|
||||
|
||||
ctx = prepare->ctxt_to_hw_map;
|
||||
for (i = 0; i < alignment_info->num_ports; i++) {
|
||||
alignment_port_cfg = &alignment_info->port_alignment_cfg[i];
|
||||
res_id_out = alignment_port_cfg->resource_type & 0xFF;
|
||||
|
||||
if (res_id_out >= CAM_TFE_HW_OUT_RES_MAX) {
|
||||
CAM_ERR(CAM_ISP, "invalid out restype:%x ctx %d",
|
||||
alignment_port_cfg->resource_type, ctx->ctx_index);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hw_mgr_res = &ctx->res_list_tfe_out[res_id_out];
|
||||
res = hw_mgr_res->hw_res[i];
|
||||
hw_intf = res->hw_intf;
|
||||
if (hw_intf && hw_intf->hw_ops.process_cmd) {
|
||||
cmd_update.res = res;
|
||||
cmd_update.data = alignment_port_cfg;
|
||||
cmd_update.cmd_type = CAM_ISP_HW_CMD_BUFFER_ALIGNMENT_UPDATE;
|
||||
rc = hw_intf->hw_ops.process_cmd(
|
||||
hw_intf->hw_priv,
|
||||
CAM_ISP_HW_CMD_BUFFER_ALIGNMENT_UPDATE,
|
||||
&cmd_update,
|
||||
sizeof(struct cam_isp_hw_get_cmd_update));
|
||||
if (rc)
|
||||
CAM_ERR(CAM_ISP, "Ctx %d Buffer alignment Update failed",
|
||||
ctx->ctx_index);
|
||||
} else {
|
||||
CAM_ERR(CAM_ISP, "NULL hw_intf! ctx %d", ctx->ctx_index);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_isp_tfe_blob_hfr_update(
|
||||
uint32_t blob_type,
|
||||
struct cam_isp_generic_blob_info *blob_info,
|
||||
@@ -4774,6 +4823,50 @@ static int cam_isp_tfe_packet_generic_blob_handler(void *user_data,
|
||||
prepare->packet->header.request_id, rc, tfe_mgr_ctx->ctx_index);
|
||||
}
|
||||
break;
|
||||
case CAM_ISP_TFE_GENERIC_BLOB_TYPE_ALIGNMENT_OFFSET_INFO: {
|
||||
struct cam_isp_tfe_alignment_resource_info *alignment_info =
|
||||
(struct cam_isp_tfe_alignment_resource_info *)blob_data;
|
||||
|
||||
if (tfe_mgr_ctx->is_dual) {
|
||||
CAM_ERR(CAM_ISP, "Alignment blob can't be use in dual mode ctx %d",
|
||||
tfe_mgr_ctx->ctx_index);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (blob_size < sizeof(struct cam_isp_tfe_alignment_resource_info)) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Invalid alignment blob size %u expected %u ctx %d",
|
||||
blob_size, sizeof(struct cam_isp_tfe_alignment_resource_info),
|
||||
tfe_mgr_ctx->ctx_index);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (alignment_info->num_ports > CAM_ISP_TFE_OUT_RES_MAX) {
|
||||
CAM_ERR(CAM_ISP, "Invalid num_ports %u in alignment config",
|
||||
alignment_info->num_ports);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((alignment_info->num_ports != 0) && (blob_size <
|
||||
(sizeof(struct cam_isp_tfe_alignment_resource_info) +
|
||||
(alignment_info->num_ports - 1) *
|
||||
sizeof(struct cam_isp_tfe_alignment_offset_config)))) {
|
||||
CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu",
|
||||
blob_size,
|
||||
sizeof(struct cam_isp_tfe_alignment_resource_info) +
|
||||
(alignment_info->num_ports - 1) *
|
||||
sizeof(struct cam_isp_tfe_alignment_offset_config));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = cam_isp_tfe_blob_buffer_alignment_update(blob_type, blob_info,
|
||||
alignment_info, prepare);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Alignment buffer update failed for req %lld rc %d ctx %d",
|
||||
prepare->packet->header.request_id, rc, tfe_mgr_ctx->ctx_index);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CAM_WARN(CAM_ISP, "Invalid blob type %d ctx %d", blob_type,
|
||||
tfe_mgr_ctx->ctx_index);
|
||||
|
@@ -259,6 +259,7 @@ enum cam_isp_hw_cmd_type {
|
||||
CAM_ISP_HW_CMD_DYNAMIC_CLOCK_UPDATE,
|
||||
CAM_ISP_HW_CMD_SET_SYNC_HW_IDX,
|
||||
CAM_ISP_HW_CMD_BUS_WM_DISABLE,
|
||||
CAM_ISP_HW_CMD_BUFFER_ALIGNMENT_UPDATE,
|
||||
CAM_ISP_HW_CMD_MAX,
|
||||
};
|
||||
|
||||
|
@@ -111,6 +111,9 @@ struct cam_tfe_bus_wm_resource_data {
|
||||
uint32_t acquired_width;
|
||||
uint32_t acquired_height;
|
||||
uint32_t acquired_stride;
|
||||
|
||||
uint32_t buffer_offset;
|
||||
bool is_buffer_aligned;
|
||||
bool limiter_blob_status;
|
||||
};
|
||||
|
||||
@@ -2293,6 +2296,7 @@ static int cam_tfe_bus_update_wm(void *priv, void *cmd_args,
|
||||
(wm_data->mode == CAM_ISP_TFE_WM_LINE_BASED_MODE)) ||
|
||||
(wm_data->out_id == CAM_TFE_BUS_TFE_OUT_PDAF) ||
|
||||
(wm_data->index >= 11 && wm_data->index <= 15)) {
|
||||
|
||||
CAM_TFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||
wm_data->hw_regs->image_cfg_2,
|
||||
io_cfg->planes[i].plane_stride);
|
||||
@@ -2304,6 +2308,9 @@ static int cam_tfe_bus_update_wm(void *priv, void *cmd_args,
|
||||
frame_inc = io_cfg->planes[i].plane_stride *
|
||||
io_cfg->planes[i].slice_height;
|
||||
|
||||
if (wm_data->is_buffer_aligned)
|
||||
update_buf->wm_update->image_buf[i] += wm_data->buffer_offset;
|
||||
|
||||
CAM_TFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||
wm_data->hw_regs->image_addr,
|
||||
update_buf->wm_update->image_buf[i]);
|
||||
@@ -2351,6 +2358,38 @@ static int cam_tfe_bus_update_wm(void *priv, void *cmd_args,
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int cam_tfe_buffer_alignment_update(void *priv, void *cmd_args,
|
||||
uint32_t arg_size)
|
||||
{
|
||||
struct cam_tfe_bus_priv *bus_priv;
|
||||
struct cam_isp_hw_get_cmd_update *alignment_cmd;
|
||||
struct cam_tfe_bus_tfe_out_data *tfe_out_data = NULL;
|
||||
struct cam_tfe_bus_wm_resource_data *wm_data = NULL;
|
||||
struct cam_isp_tfe_alignment_offset_config *alignment_port_cfg = NULL;
|
||||
uint32_t i, rc = 0;
|
||||
|
||||
bus_priv = (struct cam_tfe_bus_priv *) priv;
|
||||
alignment_cmd = (struct cam_isp_hw_get_cmd_update *) cmd_args;
|
||||
alignment_port_cfg = (struct cam_isp_tfe_alignment_offset_config *) alignment_cmd->data;
|
||||
|
||||
tfe_out_data = (struct cam_tfe_bus_tfe_out_data *) alignment_cmd->res->res_priv;
|
||||
|
||||
if (!tfe_out_data) {
|
||||
CAM_ERR(CAM_ISP, "Failed! invalid data");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < tfe_out_data->num_wm; i++) {
|
||||
wm_data = tfe_out_data->wm_res[i]->res_priv;
|
||||
wm_data->is_buffer_aligned = true;
|
||||
wm_data->offset = alignment_port_cfg->x_offset;
|
||||
wm_data->buffer_offset = alignment_port_cfg->y_offset;
|
||||
CAM_DBG(CAM_ISP, "wm %d X-Offset %x Y-Offset %x", wm_data->index,
|
||||
wm_data->offset, wm_data->buffer_offset);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_tfe_bus_update_hfr(void *priv, void *cmd_args,
|
||||
uint32_t arg_size)
|
||||
@@ -2858,6 +2897,9 @@ static int cam_tfe_bus_process_cmd(void *priv,
|
||||
case CAM_ISP_HW_NOTIFY_OVERFLOW:
|
||||
rc = cam_tfe_bus_check_overflow(priv, cmd_args, arg_size);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_BUFFER_ALIGNMENT_UPDATE:
|
||||
rc = cam_tfe_buffer_alignment_update(priv, cmd_args, arg_size);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d",
|
||||
cmd_type);
|
||||
|
@@ -3441,6 +3441,7 @@ int cam_tfe_process_cmd(void *hw_priv, uint32_t cmd_type,
|
||||
case CAM_ISP_HW_CMD_WM_BW_LIMIT_CONFIG:
|
||||
case CAM_ISP_HW_CMD_GET_LAST_CONSUMED_ADDR:
|
||||
case CAM_ISP_HW_CMD_BUS_WM_DISABLE:
|
||||
case CAM_ISP_HW_CMD_BUFFER_ALIGNMENT_UPDATE:
|
||||
rc = core_info->tfe_bus->hw_ops.process_cmd(
|
||||
core_info->tfe_bus->bus_priv, cmd_type, cmd_args,
|
||||
arg_size);
|
||||
|
@@ -73,8 +73,9 @@
|
||||
#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_BW_CONFIG_V2 2
|
||||
#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG 3
|
||||
#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_INIT_CONFIG 4
|
||||
#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_BW_LIMITER_CFG 16
|
||||
#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_DYNAMIC_MODE_SWITCH 15
|
||||
#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_BW_LIMITER_CFG 16
|
||||
#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_ALIGNMENT_OFFSET_INFO 17
|
||||
|
||||
/* DSP mode */
|
||||
#define CAM_ISP_TFE_DSP_MODE_NONE 0
|
||||
@@ -528,6 +529,39 @@ struct cam_isp_tfe_out_rsrc_bw_limiter_config {
|
||||
struct cam_isp_tfe_wm_bw_limiter_config bw_limiter_config[1];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cam_isp_tfe_alignment_offset_config - ISP TFE buffer alignment config
|
||||
*
|
||||
* @resource_type: Resourse type
|
||||
* @x_offset: Offset of the buffer from x-axies
|
||||
* @y_offset: Offset of the buffer from y-axies
|
||||
* @width: Width of out resource
|
||||
* @height: Height of out resource
|
||||
* @stride: Stride of out resource
|
||||
*
|
||||
*/
|
||||
struct cam_isp_tfe_alignment_offset_config {
|
||||
__u32 resource_type;
|
||||
__u32 x_offset;
|
||||
__u32 y_offset;
|
||||
__u32 width;
|
||||
__u32 height;
|
||||
__u32 stride;
|
||||
} __attribute__((packed));
|
||||
|
||||
/**
|
||||
* struct cam_isp_tfe_alignment_resource_info - ISP TFE Resource Alignment
|
||||
*
|
||||
* @version: Alignment api version
|
||||
* @num_ports: Number of ports
|
||||
* @port_alignment_cfg: Buffer alignment for each IO port
|
||||
*/
|
||||
struct cam_isp_tfe_alignment_resource_info {
|
||||
__u32 version;
|
||||
__u32 num_ports;
|
||||
struct cam_isp_tfe_alignment_offset_config port_alignment_cfg[1];
|
||||
} __attribute__((packed));
|
||||
|
||||
#define CAM_TFE_ACQUIRE_COMMON_VER0 0x1000
|
||||
|
||||
#define CAM_TFE_ACQUIRE_COMMON_SIZE_VER0 0x0
|
||||
|
Reference in New Issue
Block a user