Ver Fonte

msm: camera: isp: HW mgr changes for SFE HW

HW mgr and packet parser changes for new SFE HW block,
introduced on Waipio chipset.

CRs-Fixed: 2841729
Change-Id: Ia8dbeb128448cd399fcce6c4fb74252793664574
Signed-off-by: Karthik Anantha Ram <[email protected]>
Karthik Anantha Ram há 4 anos atrás
pai
commit
57bf238016

+ 2 - 0
drivers/cam_isp/cam_isp_context.c

@@ -4499,6 +4499,8 @@ static int __cam_isp_ctx_config_dev_in_top_state(
 	cfg.in_map_entries = req_isp->fence_map_in;
 	cfg.priv  = &req_isp->hw_update_data;
 	cfg.pf_data = &(req->pf_data);
+	cfg.num_out_map_entries = 0;
+	cfg.num_in_map_entries = 0;
 
 	CAM_DBG(CAM_ISP, "try to prepare config packet......");
 

Diff do ficheiro suprimidas por serem muito extensas
+ 2806 - 1508
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c


+ 65 - 5
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h

@@ -15,8 +15,22 @@
 #include "cam_tasklet_util.h"
 #include "cam_cdm_intf_api.h"
 
+/*
+ * enum cam_ife_ctx_master_type - HW master type
+ * CAM_IFE_CTX_TYPE_NONE: IFE ctx/stream directly connected to CSID
+ * CAM_IFE_CTX_TYPE_CUSTOM: IFE ctx/stream connected to custom HW
+ * CAM_IFE_CTX_TYPE_SFE: IFE ctx/stream connected to SFE
+ */
+enum cam_ife_ctx_master_type {
+	CAM_IFE_CTX_TYPE_NONE,
+	CAM_IFE_CTX_TYPE_CUSTOM,
+	CAM_IFE_CTX_TYPE_SFE,
+	CAM_IFE_CTX_TYPE_MAX,
+};
+
 /* IFE resource constants */
 #define CAM_IFE_HW_IN_RES_MAX            (CAM_ISP_IFE_IN_RES_MAX & 0xFF)
+#define CAM_SFE_HW_OUT_RES_MAX           (CAM_ISP_SFE_OUT_RES_MAX & 0xFF)
 #define CAM_IFE_HW_RES_POOL_MAX          64
 
 /* IFE_HW_MGR custom config */
@@ -50,7 +64,43 @@ struct cam_ife_hw_mgr_debug {
 };
 
 /**
- * struct cam_vfe_hw_mgr_ctx - IFE HW manager Context object
+ * struct cam_sfe_scratch_buf_info - Scratch buf info
+ *
+ * @width: Width in pixels
+ * @height: Height in pixels
+ * @stride: Stride in pixels
+ * @slice_height: Height in lines
+ * @io_addr: Buffer address
+ * @res_id: Resource type
+ * @is_secure: secure scratch buffer
+ */
+struct cam_sfe_scratch_buf_info {
+	uint32_t   width;
+	uint32_t   height;
+	uint32_t   stride;
+	uint32_t   slice_height;
+	dma_addr_t io_addr;
+	uint32_t   res_id;
+	bool       is_secure;
+};
+
+/**
+ * struct cam_sfe_scratch_buf_cfg - Scratch buf info
+ *
+ * @config_done: To indicate if stream received it's scratch cfg
+ * @num_configs: Number of buffer configs [max of 3 currently]
+ * @buf_info: Info on each of the buffers
+ *
+ */
+struct cam_sfe_scratch_buf_cfg {
+	bool                            config_done;
+	uint32_t                        num_config;
+	struct cam_sfe_scratch_buf_info buf_info[
+		CAM_SFE_FE_RDI_NUM_MAX];
+};
+
+/**
+ * struct cam_ife_hw_mgr_ctx - IFE HW manager Context object
  *
  * @list:                   used by the ctx list.
  * @common:                 common acquired context data
@@ -64,8 +114,10 @@ struct cam_ife_hw_mgr_debug {
  *                          one.
  * @res_list_csid:          CSID resource list
  * @res_list_ife_src:       IFE input resource list
- * @res_list_ife_in_rd      IFE input resource list for read path
+ * @res_list_sfe_src        SFE input resource list
+ * @res_list_ife_in_rd      IFE/SFE input resource list for read path
  * @res_list_ife_out:       IFE output resoruces array
+ * @res_list_sfe_out:       SFE output resources array
  * @free_res_list:          Free resources list for the branch node
  * @res_pool:               memory storage for the free resource list
  * @irq_status0_mask:       irq_status0_mask for the context
@@ -96,7 +148,7 @@ struct cam_ife_hw_mgr_debug {
  * @init_done               indicate whether init hw is done
  * @is_fe_enabled           Indicate whether fetch engine\read path is enabled
  * @is_dual                 indicate whether context is in dual VFE mode
- * @custom_enabled          update the flag if context is connected to custom HW
+ * @ctx_type                Type of IFE ctx [CUSTOM/SFE etc.]
  * @custom_config           ife ctx config if custom is enabled [bit field]
  * @ts                      captured timestamp when the ctx is acquired
  * @is_tpg                  indicate whether context is using PHY TPG
@@ -107,6 +159,7 @@ struct cam_ife_hw_mgr_debug {
  * @pf_mid_found            in page fault, mid found for this ctx.
  * @buf_done_controller     Buf done controller.
  * @need_csid_top_cfg       Flag to indicate if CSID top cfg is  needed.
+ * @scratch_config          Scratch buffer config if any for this ctx
  *
  */
 struct cam_ife_hw_mgr_ctx {
@@ -123,14 +176,18 @@ struct cam_ife_hw_mgr_ctx {
 	struct cam_isp_hw_mgr_res       res_list_tpg;
 	struct list_head                res_list_ife_csid;
 	struct list_head                res_list_ife_src;
+	struct list_head                res_list_sfe_src;
 	struct list_head                res_list_ife_in_rd;
 	struct cam_isp_hw_mgr_res      *res_list_ife_out;
+	struct cam_isp_hw_mgr_res       res_list_sfe_out[
+						CAM_SFE_HW_OUT_RES_MAX];
 	struct list_head                free_res_list;
 	struct cam_isp_hw_mgr_res       res_pool[CAM_IFE_HW_RES_POOL_MAX];
 
 	uint32_t                        irq_status0_mask[CAM_IFE_HW_NUM_MAX];
 	uint32_t                        irq_status1_mask[CAM_IFE_HW_NUM_MAX];
-	struct cam_isp_ctx_base_info    base[CAM_IFE_HW_NUM_MAX];
+	struct cam_isp_ctx_base_info    base[CAM_IFE_HW_NUM_MAX +
+						CAM_SFE_HW_NUM_MAX];
 	uint32_t                        num_base;
 	uint32_t                        cdm_handle;
 	struct cam_cdm_utils_ops       *cdm_ops;
@@ -154,7 +211,7 @@ struct cam_ife_hw_mgr_ctx {
 	bool                            init_done;
 	bool                            is_fe_enabled;
 	bool                            is_dual;
-	bool                            custom_enabled;
+	enum cam_ife_ctx_master_type    ctx_type;
 	uint32_t                        custom_config;
 	struct timespec64               ts;
 	bool                            is_tpg;
@@ -164,6 +221,7 @@ struct cam_ife_hw_mgr_ctx {
 	bool                            pf_mid_found;
 	bool                            need_csid_top_cfg;
 	void                           *buf_done_controller;
+	struct cam_sfe_scratch_buf_cfg  scratch_config;
 };
 
 /**
@@ -174,6 +232,7 @@ struct cam_ife_hw_mgr_ctx {
  *                         HW manager during the initialization.
  * @ife_devices:           IFE device instances array. This will be filled by
  *                         HW layer during initialization
+ * @sfe_devices:           SFE device instance array
  * @ctx_mutex:             mutex for the hw context pool
  * @free_ctx_list:         free hw context list
  * @used_ctx_list:         used hw context list
@@ -194,6 +253,7 @@ struct cam_ife_hw_mgr {
 	struct cam_hw_intf            *tpg_devices[CAM_TOP_TPG_HW_NUM_MAX];
 	struct cam_hw_intf            *csid_devices[CAM_IFE_CSID_HW_NUM_MAX];
 	struct cam_isp_hw_intf_data   *ife_devices[CAM_IFE_HW_NUM_MAX];
+	struct cam_hw_intf            *sfe_devices[CAM_SFE_HW_NUM_MAX];
 	struct cam_soc_reg_map        *cdm_reg_map[CAM_IFE_HW_NUM_MAX];
 
 	struct mutex                   ctx_mutex;

+ 2 - 0
drivers/cam_isp/isp_hw_mgr/cam_isp_hw_mgr.h

@@ -85,10 +85,12 @@ struct cam_isp_hw_mgr_res {
  *
  * @idx:                 Base resource index
  * @split_id:            Split info for the base resource
+ * @hw_type:             HW type [IFE/SFE/..] for the base resource
  *
  */
 struct cam_isp_ctx_base_info {
 	uint32_t                       idx;
 	enum cam_isp_hw_split_id       split_id;
+	enum cam_isp_hw_type           hw_type;
 };
 #endif /* _CAM_ISP_HW_MGR_H_ */

+ 376 - 35
drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c

@@ -93,7 +93,8 @@ static int cam_isp_update_dual_config(
 	uint32_t                            split_id,
 	uint32_t                            base_idx,
 	struct cam_isp_hw_mgr_res          *res_list_isp_out,
-	uint32_t                            size_isp_out)
+	uint32_t                            out_base,
+	uint32_t                            out_max)
 {
 	int rc = -EINVAL;
 	struct cam_isp_dual_config                 *dual_config;
@@ -132,10 +133,10 @@ static int cam_isp_update_dual_config(
 	}
 	for (i = 0; i < dual_config->num_ports; i++) {
 
-		if (i >= CAM_ISP_IFE_OUT_RES_BASE + size_isp_out) {
+		if (i >= (out_max & 0xFF)) {
 			CAM_ERR(CAM_ISP,
 				"failed update for i:%d > size_isp_out:%d",
-				i, size_isp_out);
+				i, (out_max & 0xFF));
 			rc = -EINVAL;
 			goto end;
 		}
@@ -150,9 +151,8 @@ static int cam_isp_update_dual_config(
 
 			res = hw_mgr_res->hw_res[j];
 
-			if (res->res_id < CAM_ISP_IFE_OUT_RES_BASE ||
-				res->res_id >= (CAM_ISP_IFE_OUT_RES_BASE +
-				size_isp_out))
+			if (res->res_id < out_base ||
+				res->res_id >= out_max)
 				continue;
 
 			outport_id = res->res_id & 0xFF;
@@ -243,12 +243,13 @@ int cam_isp_add_cmd_buf_update(
 }
 
 int cam_isp_add_command_buffers(
-	struct cam_hw_prepare_update_args      *prepare,
+	struct cam_hw_prepare_update_args  *prepare,
 	struct cam_kmd_buf_info            *kmd_buf_info,
 	struct cam_isp_ctx_base_info       *base_info,
 	cam_packet_generic_blob_handler     blob_handler_cb,
 	struct cam_isp_hw_mgr_res          *res_list_isp_out,
-	uint32_t                            size_isp_out)
+	uint32_t                            out_base,
+	uint32_t                            out_max)
 {
 	int rc = 0;
 	uint32_t                           cmd_meta_data, num_ent, i;
@@ -350,9 +351,8 @@ int cam_isp_add_command_buffers(
 			break;
 		case CAM_ISP_PACKET_META_DUAL_CONFIG:
 			rc = cam_isp_update_dual_config(&cmd_desc[i],
-				split_id, base_idx,
-				res_list_isp_out, size_isp_out);
-
+				split_id, base_idx, res_list_isp_out,
+				out_base, out_max);
 			if (rc)
 				return rc;
 			break;
@@ -445,6 +445,217 @@ int cam_isp_add_command_buffers(
 					prepare->num_reg_dump_buf);
 			}
 			break;
+		case CAM_ISP_SFE_PACKET_META_LEFT:
+		case CAM_ISP_SFE_PACKET_META_RIGHT:
+		case CAM_ISP_SFE_PACKET_META_COMMON:
+		case CAM_ISP_SFE_PACKET_META_DUAL_CONFIG:
+			break;
+		default:
+			CAM_ERR(CAM_ISP, "invalid cdm command meta data %d",
+				cmd_meta_data);
+			return -EINVAL;
+		}
+		prepare->num_hw_update_entries = num_ent;
+	}
+
+	return rc;
+}
+
+int cam_sfe_add_command_buffers(
+	struct cam_hw_prepare_update_args  *prepare,
+	struct cam_kmd_buf_info            *kmd_buf_info,
+	struct cam_isp_ctx_base_info       *base_info,
+	cam_packet_generic_blob_handler     blob_handler_cb,
+	struct cam_isp_hw_mgr_res          *res_list_sfe_out,
+	uint32_t                            out_base,
+	uint32_t                            out_max)
+{
+	int rc = 0;
+	uint32_t                             cmd_meta_data, num_ent, i;
+	uint32_t                             base_idx;
+	enum cam_isp_hw_split_id             split_id;
+	struct cam_cmd_buf_desc             *cmd_desc = NULL;
+	struct cam_hw_update_entry          *hw_entry = NULL;
+
+	split_id = base_info->split_id;
+	base_idx = base_info->idx;
+	hw_entry = prepare->hw_update_entries;
+
+	/*
+	 * set the cmd_desc to point the first command descriptor in the
+	 * packet
+	 */
+	cmd_desc = (struct cam_cmd_buf_desc *)
+			((uint8_t *)&prepare->packet->payload +
+			prepare->packet->cmd_buf_offset);
+
+	CAM_DBG(CAM_ISP, "split id = %d, number of command buffers:%d",
+		split_id, prepare->packet->num_cmd_buf);
+
+	for (i = 0; i < prepare->packet->num_cmd_buf; i++) {
+		num_ent = prepare->num_hw_update_entries;
+		if (!cmd_desc[i].length)
+			continue;
+
+		/* One hw entry space required for left or right or common */
+		if (num_ent + 1 >= prepare->max_hw_update_entries) {
+			CAM_ERR(CAM_ISP, "Insufficient  HW entries :%d %d",
+				num_ent, prepare->max_hw_update_entries);
+			return -EINVAL;
+		}
+
+		rc = cam_packet_util_validate_cmd_desc(&cmd_desc[i]);
+		if (rc)
+			return rc;
+
+		cmd_meta_data = cmd_desc[i].meta_data;
+
+		CAM_DBG(CAM_ISP, "meta type: %d, split_id: %d",
+			cmd_meta_data, split_id);
+
+		switch (cmd_meta_data) {
+		case CAM_ISP_SFE_PACKET_META_LEFT:
+			if (split_id == CAM_ISP_HW_SPLIT_LEFT) {
+				hw_entry[num_ent].len = cmd_desc[i].length;
+				hw_entry[num_ent].handle =
+					cmd_desc[i].mem_handle;
+				hw_entry[num_ent].offset = cmd_desc[i].offset;
+				CAM_DBG(CAM_ISP,
+					"Meta_Left num_ent=%d handle=0x%x, len=%u, offset=%u",
+					num_ent,
+					hw_entry[num_ent].handle,
+					hw_entry[num_ent].len,
+					hw_entry[num_ent].offset);
+					hw_entry[num_ent].flags =
+						CAM_ISP_IQ_BL;
+
+				num_ent++;
+			}
+			break;
+		case CAM_ISP_SFE_PACKET_META_RIGHT:
+			if (split_id == CAM_ISP_HW_SPLIT_RIGHT) {
+				hw_entry[num_ent].len = cmd_desc[i].length;
+				hw_entry[num_ent].handle =
+					cmd_desc[i].mem_handle;
+				hw_entry[num_ent].offset = cmd_desc[i].offset;
+				CAM_DBG(CAM_ISP,
+					"Meta_Right num_ent=%d handle=0x%x, len=%u, offset=%u",
+					num_ent,
+					hw_entry[num_ent].handle,
+					hw_entry[num_ent].len,
+					hw_entry[num_ent].offset);
+					hw_entry[num_ent].flags =
+						CAM_ISP_IQ_BL;
+				num_ent++;
+			}
+			break;
+		case CAM_ISP_SFE_PACKET_META_COMMON:
+			hw_entry[num_ent].len = cmd_desc[i].length;
+			hw_entry[num_ent].handle =
+				cmd_desc[i].mem_handle;
+			hw_entry[num_ent].offset = cmd_desc[i].offset;
+			CAM_DBG(CAM_ISP,
+				"Meta_Common num_ent=%d handle=0x%x, len=%u, offset=%u",
+				num_ent,
+				hw_entry[num_ent].handle,
+				hw_entry[num_ent].len,
+				hw_entry[num_ent].offset);
+				hw_entry[num_ent].flags = CAM_ISP_IQ_BL;
+
+			num_ent++;
+			break;
+		case CAM_ISP_SFE_PACKET_META_DUAL_CONFIG:
+			rc = cam_isp_update_dual_config(&cmd_desc[i],
+				split_id, base_info->idx,
+				res_list_sfe_out, out_base, out_max);
+			if (rc)
+				return rc;
+			break;
+		case CAM_ISP_PACKET_META_GENERIC_BLOB_LEFT:
+			if (split_id == CAM_ISP_HW_SPLIT_LEFT) {
+				struct cam_isp_generic_blob_info   blob_info;
+
+				prepare->num_hw_update_entries = num_ent;
+				blob_info.prepare = prepare;
+				blob_info.base_info = base_info;
+				blob_info.kmd_buf_info = kmd_buf_info;
+
+				rc = cam_packet_util_process_generic_cmd_buffer(
+					&cmd_desc[i],
+					blob_handler_cb,
+					&blob_info);
+				if (rc) {
+					CAM_ERR(CAM_ISP,
+						"Failed in processing blobs %d",
+						rc);
+					return rc;
+				}
+				hw_entry[num_ent].flags = CAM_ISP_IQ_BL;
+				num_ent = prepare->num_hw_update_entries;
+			}
+			break;
+		case CAM_ISP_PACKET_META_GENERIC_BLOB_RIGHT:
+			if (split_id == CAM_ISP_HW_SPLIT_RIGHT) {
+				struct cam_isp_generic_blob_info   blob_info;
+
+				prepare->num_hw_update_entries = num_ent;
+				blob_info.prepare = prepare;
+				blob_info.base_info = base_info;
+				blob_info.kmd_buf_info = kmd_buf_info;
+
+				rc = cam_packet_util_process_generic_cmd_buffer(
+					&cmd_desc[i],
+					blob_handler_cb,
+					&blob_info);
+				if (rc) {
+					CAM_ERR(CAM_ISP,
+						"Failed in processing blobs %d",
+						rc);
+					return rc;
+				}
+				hw_entry[num_ent].flags = CAM_ISP_IQ_BL;
+				num_ent = prepare->num_hw_update_entries;
+			}
+			break;
+		case CAM_ISP_PACKET_META_GENERIC_BLOB_COMMON: {
+			struct cam_isp_generic_blob_info   blob_info;
+
+			prepare->num_hw_update_entries = num_ent;
+			blob_info.prepare = prepare;
+			blob_info.base_info = base_info;
+			blob_info.kmd_buf_info = kmd_buf_info;
+
+			rc = cam_packet_util_process_generic_cmd_buffer(
+				&cmd_desc[i],
+				blob_handler_cb,
+				&blob_info);
+			if (rc) {
+				CAM_ERR(CAM_ISP,
+					"Failed in processing blobs %d", rc);
+				return rc;
+			}
+			hw_entry[num_ent].flags = CAM_ISP_IQ_BL;
+			num_ent = prepare->num_hw_update_entries;
+		}
+			break;
+		case CAM_ISP_PACKET_META_BASE:
+		case CAM_ISP_PACKET_META_LEFT:
+		case CAM_ISP_PACKET_META_RIGHT:
+		case CAM_ISP_PACKET_META_COMMON:
+		case CAM_ISP_PACKET_META_DMI_LEFT:
+		case CAM_ISP_PACKET_META_DMI_RIGHT:
+		case CAM_ISP_PACKET_META_DMI_COMMON:
+		case CAM_ISP_PACKET_META_CLOCK:
+		case CAM_ISP_PACKET_META_CSID:
+		case CAM_ISP_PACKET_META_DUAL_CONFIG:
+		case CAM_ISP_PACKET_META_REG_DUMP_PER_REQUEST:
+		case CAM_ISP_PACKET_META_REG_DUMP_ON_FLUSH:
+		case CAM_ISP_PACKET_META_REG_DUMP_ON_ERROR:
+		case CAM_ISP_PACKET_META_MODE_SWITCH_CONFIG:
+		case CAM_ISP_PACKET_META_CSID_LEFT:
+		case CAM_ISP_PACKET_META_CSID_RIGHT:
+		case CAM_ISP_PACKET_META_CSID_COMMON:
+			break;
 		default:
 			CAM_ERR(CAM_ISP, "invalid cdm command meta data %d",
 				cmd_meta_data);
@@ -463,10 +674,13 @@ int cam_isp_add_io_buffers(
 	uint32_t                              base_idx,
 	struct cam_kmd_buf_info              *kmd_buf_info,
 	struct cam_isp_hw_mgr_res            *res_list_isp_out,
-	struct list_head                     *res_list_ife_in_rd,
-	uint32_t                              size_isp_out,
+	struct list_head                     *res_list_in_rd,
+	uint32_t                              out_base,
+	uint32_t                              out_max,
 	bool                                  fill_fence,
-	struct cam_isp_frame_header_info     *frame_header_info)
+	enum cam_isp_hw_type                  hw_type,
+	struct cam_isp_frame_header_info     *frame_header_info,
+	struct cam_isp_check_sfe_fe_io_cfg   *check_sfe_fe_cfg)
 {
 	int                                 rc = 0;
 	dma_addr_t                          io_addr[CAM_PACKET_MAX_PLANES];
@@ -489,14 +703,14 @@ int cam_isp_add_io_buffers(
 	size_t                              size;
 	int32_t                             hdl;
 	int                                 mmu_hdl;
-	bool                                is_buf_secure;
+	bool                                is_buf_secure, found = false;
 	uint32_t                            mode;
 
 	io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *)
 			&prepare->packet->payload +
 			prepare->packet->io_configs_offset);
-	num_out_buf = 0;
-	num_in_buf  = 0;
+	num_out_buf = prepare->num_out_map_entries;
+	num_in_buf  = prepare->num_in_map_entries;
 	io_cfg_used_bytes = 0;
 	prepare->pf_data->packet = prepare->packet;
 
@@ -519,11 +733,19 @@ int cam_isp_add_io_buffers(
 		CAM_DBG(CAM_ISP, "format: %d", io_cfg[i].format);
 
 		if (io_cfg[i].direction == CAM_BUF_OUTPUT) {
+			if (io_cfg[i].resource_type < out_base ||
+				io_cfg[i].resource_type >= out_max)
+				continue;
+
 			res_id_out = io_cfg[i].resource_type & 0xFF;
-			if (res_id_out >= size_isp_out) {
-				CAM_ERR(CAM_ISP, "invalid out restype:%x",
+			if (check_sfe_fe_cfg->sfe_fe_enabled &&
+				(res_id_out < ((out_base & 0xFF) +
+				CAM_SFE_FE_RDI_NUM_MAX))) {
+				CAM_DBG(CAM_ISP,
+					"SFE Write/Fetch engine cfg skip scratch buffer for res 0x%x",
 					io_cfg[i].resource_type);
-				return -EINVAL;
+				check_sfe_fe_cfg->sfe_rdi_cfg_mask |=
+					1 << res_id_out;
 			}
 
 			CAM_DBG(CAM_ISP,
@@ -554,24 +776,41 @@ int cam_isp_add_io_buffers(
 				return -EINVAL;
 			}
 		} else if (io_cfg[i].direction == CAM_BUF_INPUT) {
-			res_id_in = io_cfg[i].resource_type & 0xFF;
-			CAM_DBG(CAM_ISP,
-				"configure input io with fill fence %d",
-				fill_fence);
-			if (!res_list_ife_in_rd) {
-				CAM_ERR(CAM_ISP,
-					"No ISP in Read supported");
-				return -EINVAL;
+			res_id_in = io_cfg[i].resource_type;
+			found = false;
+			if (!res_list_in_rd) {
+				CAM_DBG(CAM_ISP,
+					"No BUS Read supported");
+				continue;
 			}
-			if (!list_empty(res_list_ife_in_rd)) {
-				hw_mgr_res =
-					list_first_entry(res_list_ife_in_rd,
-					struct cam_isp_hw_mgr_res, list);
-			} else {
-				CAM_ERR(CAM_ISP,
-					"No IFE in Read resource");
+			if (hw_type != CAM_ISP_HW_TYPE_SFE)
+				res_id_in = CAM_ISP_HW_VFE_IN_RD;
+
+			list_for_each_entry(hw_mgr_res, res_list_in_rd, list) {
+				if (hw_mgr_res->res_id == res_id_in) {
+					found = true;
+					break;
+				}
+			}
+
+			if (!found) {
+				CAM_ERR(CAM_ISP, "No Read resource");
 				return -EINVAL;
 			}
+
+			if (check_sfe_fe_cfg->sfe_fe_enabled &&
+				((res_id_in & 0xFF) < ((out_base & 0xFF) +
+				CAM_SFE_FE_RDI_NUM_MAX))) {
+				CAM_DBG(CAM_ISP,
+					"SFE Write/Fetch engine cfg skip scratch buffer for res 0x%x",
+					io_cfg[i].resource_type);
+				check_sfe_fe_cfg->sfe_rdi_cfg_mask |=
+					(1 << (res_id_in & 0xFF));
+			}
+
+			CAM_DBG(CAM_ISP,
+				"configure input io with fill fence %d",
+				fill_fence);
 			in_map_entries =
 				&prepare->in_map_entries[num_in_buf];
 			if (fill_fence) {
@@ -716,6 +955,7 @@ int cam_isp_add_io_buffers(
 
 			update_buf.cmd.size = kmd_buf_remain_size;
 			update_buf.wm_update = &wm_update;
+			update_buf.use_scratch_cfg = false;
 
 			CAM_DBG(CAM_ISP, "cmd buffer 0x%pK, size %d",
 				update_buf.cmd.cmd_buf_addr,
@@ -861,6 +1101,7 @@ int cam_isp_add_io_buffers(
 			bus_rd_update.num_buf   = plane_id;
 			bus_rd_update.io_cfg    = &io_cfg[i];
 			update_buf.cmd.size = kmd_buf_remain_size;
+			update_buf.use_scratch_cfg = false;
 			update_buf.rm_update = &bus_rd_update;
 
 			CAM_DBG(CAM_ISP, "cmd buffer 0x%pK, size %d",
@@ -1413,3 +1654,103 @@ int cam_isp_add_csid_reg_update(
 
 	return rc;
 }
+
+int cam_isp_add_csid_offline_cmd(
+	struct cam_hw_prepare_update_args    *prepare,
+	struct list_head                     *res_list,
+	uint32_t                              base_idx,
+	struct cam_kmd_buf_info              *kmd_buf_info)
+{
+	int rc = -EINVAL;
+	struct cam_isp_hw_mgr_res            *hw_mgr_res;
+	struct cam_isp_resource_node         *res;
+	uint32_t kmd_buf_remain_size, num_ent, i, go_cmd_size;
+	struct cam_ife_csid_offline_cmd_update_args go_args;
+
+	if (prepare->num_hw_update_entries + 1 >=
+		prepare->max_hw_update_entries) {
+		CAM_ERR(CAM_ISP, "Insufficient  HW entries :%d %d",
+			prepare->num_hw_update_entries,
+			prepare->max_hw_update_entries);
+		return -EINVAL;
+	}
+
+	go_cmd_size = 0;
+	list_for_each_entry(hw_mgr_res, res_list, list) {
+		if (hw_mgr_res->res_type == CAM_ISP_RESOURCE_UNINT)
+			continue;
+
+		for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+			if (!hw_mgr_res->hw_res[i])
+				continue;
+
+			res = hw_mgr_res->hw_res[i];
+			if (res->hw_intf->hw_idx != base_idx)
+				continue;
+
+			if (kmd_buf_info->size > (kmd_buf_info->used_bytes +
+				go_cmd_size)) {
+				kmd_buf_remain_size =  kmd_buf_info->size -
+					(kmd_buf_info->used_bytes +
+					go_cmd_size);
+			} else {
+				CAM_ERR(CAM_ISP, "no free mem %d %d %d",
+					base_idx, kmd_buf_info->size,
+					kmd_buf_info->used_bytes +
+					go_cmd_size);
+				rc = -EINVAL;
+				goto end;
+			}
+			go_args.cmd.cmd_buf_addr = kmd_buf_info->cpu_addr +
+				kmd_buf_info->used_bytes / 4 +
+				go_cmd_size / 4;
+			go_args.cmd.size = kmd_buf_remain_size;
+			go_args.res = res;
+
+			rc = res->hw_intf->hw_ops.process_cmd(
+				res->hw_intf->hw_priv,
+				CAM_IFE_CSID_PROGRAM_OFFLINE_CMD, &go_args,
+				sizeof(go_args));
+			if (rc)
+				goto end;
+
+			CAM_DBG(CAM_ISP,
+				"offline cmd update added for CSID: %u  res: %d",
+				res->hw_intf->hw_idx, res->res_id);
+
+			go_cmd_size += go_args.cmd.used_bytes;
+			goto go_cmd_added;
+		}
+	}
+
+go_cmd_added:
+
+	if (go_cmd_size) {
+		/* Update the HW entries */
+		num_ent = prepare->num_hw_update_entries;
+		prepare->hw_update_entries[num_ent].handle =
+			kmd_buf_info->handle;
+		prepare->hw_update_entries[num_ent].len = go_cmd_size;
+		prepare->hw_update_entries[num_ent].offset =
+			kmd_buf_info->offset;
+
+		/* Marking go update as IOCFG to reapply on bubble */
+		prepare->hw_update_entries[num_ent].flags = CAM_ISP_IOCFG_BL;
+		CAM_DBG(CAM_ISP,
+			"num_ent=%d handle=0x%x, len=%u, offset=%u",
+			num_ent,
+			prepare->hw_update_entries[num_ent].handle,
+			prepare->hw_update_entries[num_ent].len,
+			prepare->hw_update_entries[num_ent].offset);
+		num_ent++;
+
+		kmd_buf_info->used_bytes += go_cmd_size;
+		kmd_buf_info->offset     += go_cmd_size;
+		prepare->num_hw_update_entries = num_ent;
+		/* offline cmd update is success return status 0 */
+		rc = 0;
+	}
+
+end:
+	return rc;
+}

+ 71 - 7
drivers/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h

@@ -48,6 +48,18 @@ struct cam_isp_frame_header_info {
 	uint32_t                 frame_header_res_id;
 };
 
+/*
+ * struct cam_isp_check_sfe_fe_io_cfg
+ *
+ * @sfe_fe_enabled  : True if SFE fetch engine is enabled
+ * @sfe_rdi_cfg_mask: To indicate IO buf cfg for RDIs
+ *
+ */
+struct cam_isp_check_sfe_fe_io_cfg {
+	bool                     sfe_fe_enabled;
+	uint32_t                 sfe_rdi_cfg_mask;
+};
+
 /*
  * struct cam_isp_change_base_args
  *
@@ -109,6 +121,32 @@ int cam_isp_add_cmd_buf_update(
 	void                                 *cmd_update_data,
 	uint32_t                             *bytes_used);
 
+/*
+ * cam_sfe_add_command_buffers()
+ *
+ * @brief                  Add command buffer in the HW entries list for given
+ *                         left or right SFE instance.
+ *
+ * @prepare:               Contain the packet and HW update variables
+ * @kmd_buf_info:          KMD buffer to store the custom cmd data
+ * @base_info:             base hardware information
+ * @blob_handler_cb:       Call_back_function for Meta handling
+ * @res_list_isp_out:      SFE out resource list
+ * @out_base:              Base value of ISP resource (SFE)
+ * @out_max:               Max of supported ISP resources(SFE)
+ *
+ * @return:                0 for success
+ *                         Negative for Failure
+ */
+int cam_sfe_add_command_buffers(
+	struct cam_hw_prepare_update_args  *prepare,
+	struct cam_kmd_buf_info            *kmd_buf_info,
+	struct cam_isp_ctx_base_info       *base_info,
+	cam_packet_generic_blob_handler     blob_handler_cb,
+	struct cam_isp_hw_mgr_res          *res_list_sfe_out,
+	uint32_t                            out_base,
+	uint32_t                            out_max);
+
 /*
  * cam_isp_add_command_buffers()
  *
@@ -120,7 +158,8 @@ int cam_isp_add_cmd_buf_update(
  * @base_info:             base hardware information
  * @blob_handler_cb:       Call_back_function for Meta handling
  * @res_list_isp_out:      IFE /VFE out resource list
- * @size_isp_out:          Size of the res_list_isp_out array
+ * @out_base:              Base value of ISP resource (IFE)
+ * @out_max:               Max of supported ISP resources(IFE)
  *
  * @return:                0 for success
  *                         Negative for Failure
@@ -131,7 +170,8 @@ int cam_isp_add_command_buffers(
 	struct cam_isp_ctx_base_info       *base_info,
 	cam_packet_generic_blob_handler     blob_handler_cb,
 	struct cam_isp_hw_mgr_res          *res_list_isp_out,
-	uint32_t                            size_isp_out);
+	uint32_t                            out_base,
+	uint32_t                            out_max);
 
 /*
  * cam_isp_add_io_buffers()
@@ -146,11 +186,14 @@ int cam_isp_add_command_buffers(
  * @prepare:               Contain the  packet and HW update variables
  * @base_idx:              Base or dev index of the IFE/VFE HW instance
  * @kmd_buf_info:          Kmd buffer to store the change base command
- * @res_list_isp_out:      IFE /VFE out resource list
- * @res_list_ife_in_rd:    IFE /VFE in rd resource list
- * @size_isp_out:          Size of the res_list_isp_out array
+ * @res_list_isp_out:      IFE/SFE out resource list
+ * @res_list_ife_in_rd:    IFE/SFE in rd resource list
+ * @out_base:              Base value of ISP resource (IFE/SFE)
+ * @out_max:               Max of supported ISP resources(IFE/SFE)
  * @fill_fence:            If true, Fence map table will be filled
+ * @hw_type:               HW type for this ctx base (IFE/SFE)
  * @frame_header_info:     Frame header related params
+ * @check_sfe_fe_cfg:      Validate if sfe fetch received IO cfg
  * @return:                0 for success
  *                         -EINVAL for Fail
  */
@@ -162,9 +205,12 @@ int cam_isp_add_io_buffers(
 	struct cam_kmd_buf_info              *kmd_buf_info,
 	struct cam_isp_hw_mgr_res            *res_list_isp_out,
 	struct list_head                     *res_list_ife_in_rd,
-	uint32_t                              size_isp_out,
+	uint32_t                              out_base,
+	uint32_t                              out_max,
 	bool                                  fill_fence,
-	struct cam_isp_frame_header_info     *frame_header_info);
+	enum cam_isp_hw_type                  hw_type,
+	struct cam_isp_frame_header_info     *frame_header_info,
+	struct cam_isp_check_sfe_fe_io_cfg   *check_sfe_fe_cfg);
 
 /*
  * cam_isp_add_reg_update()
@@ -267,4 +313,22 @@ int cam_isp_add_csid_reg_update(
 	struct list_head                     *res_list,
 	uint32_t                              base_idx,
 	struct cam_kmd_buf_info              *kmd_buf_info);
+
+
+/* cam_isp_add_csid_offline_cmd()
+ *
+ * @brief                  Add csid go cmd for offline mode
+ *
+ * @prepare:               Contain the  packet and HW update variables
+ * @res_list:              Resource list for CSID
+ * @base_idx:              Base or dev index of the CSID/IFE HW instance
+ * @kmd_buf_info:          Kmd buffer to store the change base command
+ * @return:                0 for success
+ *                         -EINVAL for Fail
+ */
+int cam_isp_add_csid_offline_cmd(
+	struct cam_hw_prepare_update_args    *prepare,
+	struct list_head                     *res_list,
+	uint32_t                              base_idx,
+	struct cam_kmd_buf_info              *kmd_buf_info);
 #endif /*_CAM_ISP_HW_PARSER_H */

+ 9 - 6
drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h

@@ -13,12 +13,15 @@
 #include "cam_hw_mgr_intf.h"
 
 /* MAX IFE instance */
-#define CAM_IFE_HW_NUM_MAX   7
-#define CAM_IFE_RDI_NUM_MAX  4
-#define CAM_ISP_BW_CONFIG_V1 1
-#define CAM_ISP_BW_CONFIG_V2 2
-#define CAM_TFE_HW_NUM_MAX   3
-#define CAM_TFE_RDI_NUM_MAX  3
+#define CAM_IFE_HW_NUM_MAX      7
+#define CAM_SFE_HW_NUM_MAX      2
+#define CAM_IFE_RDI_NUM_MAX     4
+#define CAM_SFE_RDI_NUM_MAX     5
+#define CAM_SFE_FE_RDI_NUM_MAX  3
+#define CAM_ISP_BW_CONFIG_V1    1
+#define CAM_ISP_BW_CONFIG_V2    2
+#define CAM_TFE_HW_NUM_MAX      3
+#define CAM_TFE_RDI_NUM_MAX     3
 
 /* maximum context numbers for TFE */
 #define CAM_TFE_CTX_MAX      4

+ 3 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h

@@ -126,6 +126,9 @@ struct cam_isp_in_port_generic_info {
 	uint32_t                        udi_count;
 	uint32_t                        lcr_count;
 	uint32_t                        ife_rd_count;
+	uint32_t                        sfe_in_path_type;
+	uint32_t                        sfe_ife_enable;
+	uint32_t                        secure_mode;
 	struct cam_isp_out_port_generic_info    *data;
 };
 

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff