浏览代码

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 <[email protected]>
Ayush Kumar 2 年之前
父节点
当前提交
bfbfc5d3d4

+ 5 - 2
drivers/cam_isp/cam_isp_context.c

@@ -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);

+ 94 - 1
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c

@@ -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);

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h

@@ -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,
 };
 

+ 42 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.c

@@ -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);

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c

@@ -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);

+ 41 - 7
include/uapi/camera/media/cam_tfe.h

@@ -68,13 +68,14 @@
 #define CAM_ISP_TFE_PACKET_META_REG_DUMP_ON_ERROR     8
 
 /* ISP TFE Generic Cmd Buffer Blob types */
-#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_HFR_CONFIG          0
-#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_CLOCK_CONFIG        1
-#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_HFR_CONFIG            0
+#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_CLOCK_CONFIG          1
+#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_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