Эх сурвалжийг харах

Merge "msm: camera: tfe: Add support for epoch blob in TFE HW" into camera-kernel.lnx.7.0

Camera Software Integration 1 жил өмнө
parent
commit
76dfa04d50

+ 67 - 2
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/slab.h>
@@ -4200,6 +4200,39 @@ static int cam_isp_tfe_blob_csid_clock_update(
 	return rc;
 }
 
+static int cam_isp_blob_tfe_init_config_update(
+	struct cam_hw_prepare_update_args    *prepare,
+	struct cam_isp_init_config           *init_config)
+{
+	int i, rc = 0;
+	struct cam_tfe_hw_mgr_ctx             *ctx = NULL;
+	struct cam_isp_hw_init_config_update   init_cfg_update;
+	struct cam_hw_intf                    *hw_intf;
+
+	ctx = prepare->ctxt_to_hw_map;
+	init_cfg_update.init_config = init_config;
+
+	for (i = 0; i < ctx->num_base; i++) {
+		if (ctx->base[i].hw_type != CAM_ISP_HW_TYPE_TFE)
+			continue;
+
+		hw_intf = g_tfe_hw_mgr.tfe_devices[ctx->base[i].idx]->hw_intf;
+		if (hw_intf && hw_intf->hw_ops.process_cmd) {
+			CAM_DBG(CAM_ISP, "Epoch/init config update for ctx %d",
+				ctx->ctx_index);
+			rc = hw_intf->hw_ops.process_cmd(hw_intf->hw_priv,
+				CAM_ISP_HW_CMD_INIT_CONFIG_UPDATE,
+				&init_cfg_update,
+				sizeof(struct cam_isp_hw_init_config_update));
+			if (rc)
+				CAM_ERR(CAM_ISP, "Epoch/init config failed rc %d ctx %d",
+					rc, ctx->ctx_index);
+		}
+	}
+
+	return rc;
+}
+
 static int cam_isp_tfe_blob_clock_update(
 	uint32_t                               blob_type,
 	struct cam_isp_generic_blob_info      *blob_info,
@@ -4673,8 +4706,40 @@ static int cam_isp_tfe_packet_generic_blob_handler(void *user_data,
 		prepare_hw_data->num_exp = mup_config->num_expoures;
 	}
 		break;
+	case CAM_ISP_TFE_GENERIC_BLOB_TYPE_INIT_CONFIG: {
+		struct cam_isp_init_config            *init_config;
+		struct cam_isp_prepare_hw_update_data *prepare_hw_data;
+
+		prepare_hw_data = (struct cam_isp_prepare_hw_update_data *)prepare->priv;
+
+		if (prepare_hw_data->packet_opcode_type != CAM_ISP_PACKET_INIT_DEV) {
+			CAM_ERR(CAM_ISP,
+				"Epoch config blob not supported packet type: %u req: %llu Ctx %d",
+				prepare_hw_data->packet_opcode_type,
+				prepare->packet->header.request_id,
+				tfe_mgr_ctx->ctx_index);
+			return -EINVAL;
+		}
+
+		if (blob_size != sizeof(struct cam_isp_init_config)) {
+			CAM_ERR(CAM_ISP,
+				"Invalid init config blob size %u expected %u ctx %d",
+				blob_size, sizeof(struct cam_isp_init_config),
+				tfe_mgr_ctx->ctx_index);
+			return -EINVAL;
+		}
+
+		init_config = (struct cam_isp_init_config *)blob_data;
+		rc = cam_isp_blob_tfe_init_config_update(prepare, init_config);
+		if (rc)
+			CAM_ERR(CAM_ISP,
+				"Init config failed for req: %llu 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", blob_type);
+		CAM_WARN(CAM_ISP, "Invalid blob type %d ctx %d", blob_type,
+			tfe_mgr_ctx->ctx_index);
 		break;
 	}
 

+ 62 - 4
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c

@@ -95,6 +95,7 @@ struct cam_tfe_camif_data {
 	uint32_t                           core_cfg;
 	bool                               shdr_en;
 	bool                               is_shdr_master;
+	uint32_t                           epoch_factor;
 };
 
 struct cam_tfe_rdi_data {
@@ -113,6 +114,7 @@ struct cam_tfe_rdi_data {
 	uint32_t                                     last_line;
 	bool                                         shdr_en;
 	bool                                         is_shdr_master;
+	uint32_t                                     epoch_factor;
 };
 
 struct cam_tfe_ppp_data {
@@ -1575,6 +1577,54 @@ static int cam_tfe_top_get_reg_update(
 	return 0;
 }
 
+static int cam_tfe_top_init_config_update(
+	struct cam_tfe_top_priv *top_priv,
+	void *cmd_args, uint32_t arg_size)
+{
+	int i = 0;
+	struct cam_isp_hw_init_config_update *init_cfg = NULL;
+	struct cam_isp_resource_node *rsrc_node = NULL;
+	struct cam_tfe_camif_data *camif_data;
+
+	init_cfg = (struct cam_isp_hw_init_config_update *)cmd_args;
+
+	if (arg_size != sizeof(struct cam_isp_hw_init_config_update)) {
+		CAM_ERR(CAM_ISP, "Invalid args size expected: %zu actual: %zu",
+			sizeof(struct cam_isp_hw_init_config_update), arg_size);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < CAM_TFE_TOP_IN_PORT_MAX; i++) {
+		if (top_priv->in_rsrc[i].res_id == CAM_ISP_HW_TFE_IN_CAMIF) {
+			rsrc_node = &top_priv->in_rsrc[i];
+			break;
+		}
+	}
+
+	if (!rsrc_node) {
+		CAM_ERR(CAM_ISP, "TFE %d null input res node",
+			top_priv->common_data.hw_intf->hw_idx);
+		return -EINVAL;
+	}
+
+	if (rsrc_node->res_type != CAM_ISP_RESOURCE_TFE_IN) {
+		CAM_ERR(CAM_ISP, "TFE %d Invalid res_type %d res id %d ",
+			rsrc_node->hw_intf->hw_idx, rsrc_node->res_type,
+			rsrc_node->res_id);
+		return -EINVAL;
+	}
+
+	camif_data = (struct cam_tfe_camif_data *)rsrc_node->res_priv;
+	camif_data->epoch_factor = init_cfg->init_config->epoch_cfg.epoch_factor;
+
+	CAM_DBG(CAM_ISP,
+		"Init Update TFE %d res type: %d res id %d epoch_factor: %u",
+		rsrc_node->hw_intf->hw_idx, rsrc_node->res_type,
+		rsrc_node->res_id, camif_data->epoch_factor);
+
+	return 0;
+}
+
 static int cam_tfe_top_clock_update(
 	struct cam_tfe_top_priv *top_priv,
 	void *cmd_args, uint32_t arg_size)
@@ -2309,7 +2359,7 @@ static int cam_tfe_camif_resource_start(
 	struct cam_tfe_camif_data           *rsrc_data;
 	struct cam_tfe_soc_private          *soc_private;
 	struct cam_tfe_top_priv             *top_priv;
-	uint32_t                             val = 0;
+	uint32_t                             val = 0, epoch_factor = 50;
 	uint32_t                             epoch0_irq_mask;
 	uint32_t                             epoch1_irq_mask;
 	uint32_t                             computed_epoch_line_cfg;
@@ -2403,8 +2453,12 @@ static int cam_tfe_camif_resource_start(
 	}
 
 	/* Epoch config */
+	if ((rsrc_data->epoch_factor) && (rsrc_data->epoch_factor <= 100))
+		epoch_factor = rsrc_data->epoch_factor;
+
 	epoch0_irq_mask = (((rsrc_data->last_line + rsrc_data->vbi_value) -
-			rsrc_data->first_line) / 2);
+		rsrc_data->first_line) * epoch_factor / 100);
+
 	if (epoch0_irq_mask > (rsrc_data->last_line - rsrc_data->first_line))
 		epoch0_irq_mask = (rsrc_data->last_line -
 					rsrc_data->first_line);
@@ -2421,11 +2475,11 @@ static int cam_tfe_camif_resource_start(
 			rsrc_data->camif_reg->epoch_irq_cfg);
 	CAM_DBG(CAM_ISP, "TFE:%d first_line: %u\n"
 			"last_line: %u\n"
-			"epoch_line_cfg: 0x%x",
+			"epoch_line_cfg: 0x%x epoch factor %d",
 			core_info->core_index,
 			rsrc_data->first_line,
 			rsrc_data->last_line,
-			computed_epoch_line_cfg);
+			computed_epoch_line_cfg, epoch_factor);
 
 	camif_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
 
@@ -3344,6 +3398,10 @@ int cam_tfe_process_cmd(void *hw_priv, uint32_t cmd_type,
 		rc = cam_tfe_top_dynamic_clock_update(core_info->top_priv, cmd_args,
 			arg_size);
 		break;
+	case CAM_ISP_HW_CMD_INIT_CONFIG_UPDATE:
+		rc = cam_tfe_top_init_config_update(core_info->top_priv, cmd_args,
+			arg_size);
+		break;
 	case CAM_ISP_HW_CMD_GET_BUF_UPDATE:
 	case CAM_ISP_HW_CMD_GET_HFR_UPDATE:
 	case CAM_ISP_HW_CMD_STRIPE_UPDATE:

+ 1 - 0
include/uapi/camera/media/cam_tfe.h

@@ -72,6 +72,7 @@
 #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