Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c562d20a authored by Venkat Chinta's avatar Venkat Chinta
Browse files

msm: camera: ife: Add bus write master UBWC config update



This change allows handling updates to bus write master UBWC
configuration that arrive as blob commands. It also adds
compatibility checks to support older hardware.

Change-Id: Ie62c8e230b426db06c216ee850bc7ea42abcde39
Signed-off-by: default avatarVenkat Chinta <vchinta@codeaurora.org>
parent 5a51238c
Loading
Loading
Loading
Loading
+134 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ static uint32_t blob_type_hw_cmd_map[CAM_ISP_GENERIC_BLOB_TYPE_MAX] = {
	CAM_ISP_HW_CMD_GET_HFR_UPDATE,
	CAM_ISP_HW_CMD_CLOCK_UPDATE,
	CAM_ISP_HW_CMD_BW_UPDATE,
	CAM_ISP_HW_CMD_UBWC_UPDATE,
};

static struct cam_ife_hw_mgr g_ife_hw_mgr;
@@ -2244,6 +2245,129 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv,
	return rc;
}

static int cam_isp_blob_ubwc_update(
	uint32_t                               blob_type,
	struct cam_isp_generic_blob_info      *blob_info,
	struct cam_ubwc_config                *ubwc_config,
	struct cam_hw_prepare_update_args     *prepare)
{
	struct cam_ubwc_plane_cfg_v1          *ubwc_plane_cfg;
	struct cam_kmd_buf_info               *kmd_buf_info;
	struct cam_ife_hw_mgr_ctx             *ctx = NULL;
	struct cam_ife_hw_mgr_res             *hw_mgr_res;
	uint32_t                               res_id_out, i;
	uint32_t                               total_used_bytes = 0;
	uint32_t                               kmd_buf_remain_size;
	uint32_t                              *cmd_buf_addr;
	uint32_t                               bytes_used = 0;
	int                                    num_ent, rc = 0;

	ctx = prepare->ctxt_to_hw_map;
	if (!ctx) {
		CAM_ERR(CAM_ISP, "Invalid ctx");
		rc = -EINVAL;
		goto end;
	}

	if ((prepare->num_hw_update_entries + 1) >=
		prepare->max_hw_update_entries) {
		CAM_ERR(CAM_ISP, "Insufficient HW entries :%d max:%d",
			prepare->num_hw_update_entries,
			prepare->max_hw_update_entries);
		rc = -EINVAL;
		goto end;
	}

	switch (ubwc_config->api_version) {
	case CAM_UBWC_CFG_VERSION_1:
		CAM_DBG(CAM_ISP, "num_ports= %d", ubwc_config->num_ports);

		kmd_buf_info = blob_info->kmd_buf_info;
		for (i = 0; i < ubwc_config->num_ports; i++) {
			ubwc_plane_cfg = &ubwc_config->ubwc_plane_cfg[i][0];
			res_id_out = ubwc_plane_cfg->port_type & 0xFF;

			CAM_DBG(CAM_ISP, "UBWC config idx %d, port_type=%d", i,
				ubwc_plane_cfg->port_type);

			if (res_id_out >= CAM_IFE_HW_OUT_RES_MAX) {
				CAM_ERR(CAM_ISP, "Invalid port type:%x",
					ubwc_plane_cfg->port_type);
				rc = -EINVAL;
				goto end;
			}

			if ((kmd_buf_info->used_bytes
				+ total_used_bytes) < kmd_buf_info->size) {
				kmd_buf_remain_size = kmd_buf_info->size -
					(kmd_buf_info->used_bytes
					+ total_used_bytes);
			} else {
				CAM_ERR(CAM_ISP,
				"no free kmd memory for base=%d bytes_used=%u buf_size=%u",
					blob_info->base_info->idx, bytes_used,
					kmd_buf_info->size);
				rc = -ENOMEM;
				goto end;
			}

			cmd_buf_addr = kmd_buf_info->cpu_addr +
				kmd_buf_info->used_bytes/4 +
				total_used_bytes/4;
			hw_mgr_res = &ctx->res_list_ife_out[res_id_out];

			if (!hw_mgr_res) {
				CAM_ERR(CAM_ISP, "Invalid hw_mgr_res");
				rc = -EINVAL;
				goto end;
			}

			rc = cam_isp_add_cmd_buf_update(
				hw_mgr_res, blob_type,
				blob_type_hw_cmd_map[blob_type],
				blob_info->base_info->idx,
				(void *)cmd_buf_addr,
				kmd_buf_remain_size,
				(void *)ubwc_plane_cfg,
				&bytes_used);
			if (rc < 0) {
				CAM_ERR(CAM_ISP,
					"Failed cmd_update, base_idx=%d, bytes_used=%u, res_id_out=0x%x",
					blob_info->base_info->idx,
					bytes_used,
					res_id_out);
				goto end;
			}

			total_used_bytes += bytes_used;
		}

		if (total_used_bytes) {
			/* 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 =
				total_used_bytes;
			prepare->hw_update_entries[num_ent].offset =
				kmd_buf_info->offset;
			num_ent++;

			kmd_buf_info->used_bytes += total_used_bytes;
			kmd_buf_info->offset     += total_used_bytes;
			prepare->num_hw_update_entries = num_ent;
		}
		break;
	default:
		CAM_ERR(CAM_ISP, "Invalid UBWC API Version %d",
			ubwc_config->api_version);
		rc = -EINVAL;
		break;
	}
end:
	return rc;
}

static int cam_isp_blob_hfr_update(
	uint32_t                               blob_type,
	struct cam_isp_generic_blob_info      *blob_info,
@@ -2484,6 +2608,16 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
			bw_config, sizeof(prepare_hw_data->bw_config[0]));
		prepare_hw_data->bw_config_valid[bw_config->usage_type] = true;

	}
		break;
	case CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG: {
		struct cam_ubwc_config *ubwc_config =
			(struct cam_ubwc_config *)blob_data;

		rc = cam_isp_blob_ubwc_update(blob_type, blob_info,
			ubwc_config, prepare);
		if (rc)
			CAM_ERR(CAM_ISP, "UBWC Update Failed rc: %d", rc);
	}
		break;
	default:
+2 −0
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ enum cam_isp_hw_cmd_type {
	CAM_ISP_HW_CMD_BW_CONTROL,
	CAM_ISP_HW_CMD_STOP_BUS_ERR_IRQ,
	CAM_ISP_HW_CMD_GET_REG_DUMP,
	CAM_ISP_HW_CMD_UBWC_UPDATE,
	CAM_ISP_HW_CMD_MAX,
};

@@ -201,6 +202,7 @@ struct cam_isp_hw_get_cmd_update {
		struct cam_isp_port_hfr_config       *hfr_update;
		struct cam_isp_clock_config          *clock_update;
		struct cam_isp_bw_config             *bw_update;
		struct cam_ubwc_plane_cfg_v1         *ubwc_update;
	};
};

+1 −0
Original line number Diff line number Diff line
@@ -703,6 +703,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type,
	case CAM_ISP_HW_CMD_GET_HFR_UPDATE:
	case CAM_ISP_HW_CMD_STRIPE_UPDATE:
	case CAM_ISP_HW_CMD_STOP_BUS_ERR_IRQ:
	case CAM_ISP_HW_CMD_UBWC_UPDATE:
		rc = core_info->vfe_bus->hw_ops.process_cmd(
			core_info->vfe_bus->bus_priv, cmd_type, cmd_args,
			arg_size);
+2 −2
Original line number Diff line number Diff line
@@ -198,7 +198,7 @@ static struct cam_vfe_bus_ver2_reg_offset_ubwc_client ubwc_regs_client_3 = {
	.meta_addr        = 0x00002538,
	.meta_offset      = 0x0000253C,
	.meta_stride      = 0x00002540,
	.mode_cfg         = 0x00002544,
	.mode_cfg_0       = 0x00002544,
	.bw_limit         = 0x000025A0,
};

@@ -209,7 +209,7 @@ static struct cam_vfe_bus_ver2_reg_offset_ubwc_client ubwc_regs_client_4 = {
	.meta_addr        = 0x00002638,
	.meta_offset      = 0x0000263C,
	.meta_stride      = 0x00002640,
	.mode_cfg         = 0x00002644,
	.mode_cfg_0       = 0x00002644,
	.bw_limit         = 0x000026A0,
};

+12 −8
Original line number Diff line number Diff line
@@ -191,7 +191,7 @@ static struct cam_irq_register_set vfe175_bus_irq_reg[3] = {
		},
};

static struct cam_vfe_bus_ver2_reg_offset_ubwc_client
static struct cam_vfe_bus_ver2_reg_offset_ubwc_3_client
	vfe175_ubwc_regs_client_3 = {
	.tile_cfg         = 0x0000252C,
	.h_init           = 0x00002530,
@@ -199,11 +199,12 @@ static struct cam_vfe_bus_ver2_reg_offset_ubwc_client
	.meta_addr        = 0x00002538,
	.meta_offset      = 0x0000253C,
	.meta_stride      = 0x00002540,
	.mode_cfg         = 0x00002544,
	.mode_cfg_0       = 0x00002544,
	.mode_cfg_1       = 0x000025A4,
	.bw_limit         = 0x000025A0,
};

static struct cam_vfe_bus_ver2_reg_offset_ubwc_client
static struct cam_vfe_bus_ver2_reg_offset_ubwc_3_client
	vfe175_ubwc_regs_client_4 = {
	.tile_cfg         = 0x0000262C,
	.h_init           = 0x00002630,
@@ -211,11 +212,12 @@ static struct cam_vfe_bus_ver2_reg_offset_ubwc_client
	.meta_addr        = 0x00002638,
	.meta_offset      = 0x0000263C,
	.meta_stride      = 0x00002640,
	.mode_cfg         = 0x00002644,
	.mode_cfg_0       = 0x00002644,
	.mode_cfg_1       = 0x000026A4,
	.bw_limit         = 0x000026A0,
};

static struct cam_vfe_bus_ver2_reg_offset_ubwc_client
static struct cam_vfe_bus_ver2_reg_offset_ubwc_3_client
	vfe175_ubwc_regs_client_20 = {
	.tile_cfg         = 0x0000362C,
	.h_init           = 0x00003630,
@@ -223,11 +225,12 @@ static struct cam_vfe_bus_ver2_reg_offset_ubwc_client
	.meta_addr        = 0x00003638,
	.meta_offset      = 0x0000363C,
	.meta_stride      = 0x00003640,
	.mode_cfg         = 0x00003644,
	.mode_cfg_0       = 0x00003644,
	.mode_cfg_1       = 0x000036A4,
	.bw_limit         = 0x000036A0,
};

static struct cam_vfe_bus_ver2_reg_offset_ubwc_client
static struct cam_vfe_bus_ver2_reg_offset_ubwc_3_client
	vfe175_ubwc_regs_client_21 = {
	.tile_cfg         = 0x0000372C,
	.h_init           = 0x00003730,
@@ -235,7 +238,8 @@ static struct cam_vfe_bus_ver2_reg_offset_ubwc_client
	.meta_addr        = 0x00003738,
	.meta_offset      = 0x0000373C,
	.meta_stride      = 0x00003740,
	.mode_cfg         = 0x00003744,
	.mode_cfg_0       = 0x00003744,
	.mode_cfg_1       = 0x000037A4,
	.bw_limit         = 0x000037A0,
};

Loading