Ejemplo n.º 1
0
static enum ia_css_err
sh_css_sp_init_stage(struct sh_css_binary *binary,
		    const char *binary_name,
		    const struct ia_css_blob_info *blob_info,
		    const struct sh_css_binary_args *args,
		    unsigned int pipe_num,
		    unsigned stage,
		    bool preview_mode,
		    bool low_light,
		    bool xnr,
		    unsigned irq_buf_flags,
		    const struct ia_css_data *isp_mem_if,
		    unsigned int if_config_index)
{
	const struct ia_css_binary_info *info = binary->info;
	enum ia_css_err err = IA_CSS_SUCCESS;
	int i;

	unsigned int thread_id;
	bool continuous = sh_css_continuous_is_enabled((uint8_t)pipe_num);
	{
		/**
		 * Clear sh_css_sp_stage for easy debugging.
		 * program_input_circuit must be saved as it is set outside
		 * this function.
		 */
		uint8_t program_input_circuit;
		program_input_circuit = sh_css_sp_stage.program_input_circuit;
		memset(&sh_css_sp_stage, 0, sizeof(sh_css_sp_stage));
		sh_css_sp_stage.program_input_circuit = (uint8_t)program_input_circuit;
	}

	sh_css_query_sp_thread_id(pipe_num, &thread_id);

	if (info == NULL) {
		sh_css_sp_group.pipe[thread_id].sp_stage_addr[stage] = mmgr_NULL;
		return IA_CSS_SUCCESS;
	}

	sh_css_sp_stage.deinterleaved = stage == 0 && continuous;

	/*
	 * TODO: Make the Host dynamically determine
	 * the stage type.
	 */
	sh_css_sp_stage.stage_type = SH_CSS_ISP_STAGE_TYPE;
	sh_css_sp_stage.num		= (uint8_t)stage;
	sh_css_sp_stage.isp_online	= binary && binary->online;
	sh_css_sp_stage.isp_copy_vf     = args->copy_vf;
	sh_css_sp_stage.isp_copy_output = args->copy_output;
	sh_css_sp_stage.enable.vf_output = (args->out_vf_frame != NULL);
	/* These flags wil be set from the css top level */
	sh_css_sp_stage.irq_buf_flags   = irq_buf_flags;

	/* Copy the frame infos first, to be overwritten by the frames,
	   if these are present.
	*/
	sh_css_frame_info_to_sp(&sh_css_sp_stage.frames.in.info,
				&binary->in_frame_info);
	sh_css_frame_info_to_sp(&sh_css_sp_stage.frames.out.info,
				&binary->out_frame_info);
	sh_css_frame_info_to_sp(&sh_css_sp_stage.frames.internal_frame_info,
				&binary->internal_frame_info);
	sh_css_sp_stage.dvs_envelope.width    = binary->dvs_envelope.width;
	sh_css_sp_stage.dvs_envelope.height   = binary->dvs_envelope.height;
	sh_css_sp_stage.isp_pipe_version      = (uint8_t)info->isp_pipe_version;
	sh_css_sp_stage.isp_deci_log_factor   = (uint8_t)binary->deci_factor_log2;
	sh_css_sp_stage.isp_vf_downscale_bits = (uint8_t)binary->vf_downscale_log2;

	sh_css_sp_stage.if_config_index = (uint8_t) if_config_index;

	sh_css_sp_stage.sp_enable_xnr = xnr;
	sh_css_sp_stage.xmem_bin_addr = info->xmem_addr;
	sh_css_sp_stage.xmem_map_addr = sh_css_params_ddr_address_map();
	sh_css_sp_stage.anr	      = low_light;
	sh_css_isp_stage.blob_info = *blob_info;
	sh_css_stage_write_binary_info((struct ia_css_binary_info *)info);
	memcpy(sh_css_isp_stage.binary_name, binary_name,
		strlen(binary_name)+1);
	memcpy(&sh_css_isp_stage.mem_initializers, isp_mem_if,
		sizeof(sh_css_isp_stage.mem_initializers));

	/**
	 * Even when a stage does not need uds and does not params,
	 * sp_uds_init() seems to be called (needs further investigation)
	 * This function can not deal with dx, dy = {0, 0}
	 */
	(void)preview_mode;

	/* Clean static frame info before we update it */
	/*
	 * TODO: Initialize the static frame data with
	 * "sh_css_frame_null".
	 */
	for (i = 0; i < SH_CSS_NUM_FRAME_IDS; i++)
		/* Here, we do not initialize it to zero for now
		 * to be able to recognize non-updated elements
		 * This is what it should become:
		 * sh_css_sp_stage.frames.static_frame_data[i] = mmgr_NULL;
		 */
		sh_css_sp_stage.frames.static_frame_data[i] = mmgr_EXCEPTION;

	err = sh_css_sp_write_frame_pointers(args, pipe_num, stage);
	if (err != IA_CSS_SUCCESS)
		return err;

	if (continuous &&  binary->info->enable.raw_binning) {
		/* TODO: Remove this after preview output decimation is fixed
		 * by configuring out&vf info fiels properly */
		sh_css_sp_stage.frames.out.info.padded_width
			<<= binary->vf_downscale_log2;
		sh_css_sp_stage.frames.out.info.width
			<<= binary->vf_downscale_log2;
		sh_css_sp_stage.frames.out.info.height
			<<= binary->vf_downscale_log2;
	}

	return IA_CSS_SUCCESS;
}
Ejemplo n.º 2
0
static enum sh_css_err
sh_css_sp_init_stage(struct sh_css_binary *binary,
		    const char *binary_name,
		    const struct sh_css_blob_info *blob_info,
		    const struct sh_css_binary_args *args,
		    enum sh_css_pipe_id id,
		    unsigned stage,
		    bool preview_mode,
		    bool low_light,
		    bool xnr,
		    unsigned irq_buf_flags,
		    const struct sh_css_hmm_isp_interface *isp_mem_if)
{
	const struct sh_css_binary_info *info = binary->info;
	enum sh_css_err err = sh_css_success;
	int i;

	enum sh_css_pipe_id pipe_id = id;
	unsigned int thread_id;
	bool continuous = sh_css_continuous_is_enabled();
	{
		/**
		 * Clear sh_css_sp_stage for easy debugging.
		 * program_input_circuit must be saved as it is set outside
		 * this function.
		 */
		unsigned int program_input_circuit;
		program_input_circuit = sh_css_sp_stage.program_input_circuit;
		memset(&sh_css_sp_stage, 0, sizeof(sh_css_sp_stage));
		sh_css_sp_stage.program_input_circuit = program_input_circuit;
	}

	sh_css_query_sp_thread_id(pipe_id, &thread_id);
	sh_css_sp_group.pipe[thread_id].num_stages++;

	if (info == NULL) {
		sh_css_sp_group.pipe[thread_id].sp_stage_addr[stage] = mmgr_NULL;
		return sh_css_success;
	}

	sh_css_sp_stage.deinterleaved = stage == 0 &&
					sh_css_continuous_is_enabled();

	/*
	 * TODO: Make the Host dynamically determine
	 * the stage type.
	 */
	sh_css_sp_stage.stage_type = SH_CSS_ISP_STAGE_TYPE;
	sh_css_sp_stage.num		= stage;
	sh_css_sp_stage.isp_online	= binary && binary->online;
	sh_css_sp_stage.isp_copy_vf     = args->copy_vf;
	sh_css_sp_stage.isp_copy_output = args->copy_output;
	/* These flags wil be set from the css top level */
	sh_css_sp_stage.irq_buf_flags   = irq_buf_flags;

	/* Copy the frame infos first, to be overwritten by the frames,
	   if these are present.
	*/
	sh_css_frame_info_to_sp(&sh_css_sp_stage.frames.in.info,
				&binary->in_frame_info);
	sh_css_frame_info_to_sp(&sh_css_sp_stage.frames.out.info,
				&binary->out_frame_info);
	sh_css_frame_info_to_sp(&sh_css_sp_stage.frames.internal_frame_info,
				&binary->internal_frame_info);
	sh_css_sp_stage.dvs_envelope.width    = binary->dvs_envelope.width;
	sh_css_sp_stage.dvs_envelope.height   = binary->dvs_envelope.height;
	sh_css_sp_stage.isp_deci_log_factor   = binary->deci_factor_log2;
	sh_css_sp_stage.isp_vf_downscale_bits = binary->vf_downscale_log2;

	sh_css_sp_stage.sp_enable_xnr = xnr;
/*	sh_css_sp_stage.uds.extra_vectors   = info->uds.extra_vectors; */ /* task 3340 */
	sh_css_sp_stage.xmem_bin_addr = info->xmem_addr;
	sh_css_sp_stage.xmem_map_addr = sh_css_params_ddr_address_map();
	sh_css_sp_stage.anr	      = low_light;
	sh_css_isp_stage.blob_info = *blob_info;
	sh_css_stage_write_binary_info((struct sh_css_binary_info *)info);
	memcpy(sh_css_isp_stage.binary_name, binary_name,
		strlen(binary_name)+1);
	memcpy(&sh_css_isp_stage.mem_interface, isp_mem_if,
		sizeof(sh_css_isp_stage.mem_interface));

#if 0
	{
		struct sh_css_vector motion;
		struct sh_css_zoom zoom;

		sh_css_get_zoom(&zoom);
		sh_css_get_dis_motion(&motion);

		sh_css_update_uds_and_crop_info(binary->info,
					&binary->in_frame_info,
					&binary->out_frame_info,
					&binary->dvs_envelope,
					preview_mode,
					&zoom,
					&motion,
					&sh_css_sp_stage.uds,
					&sh_css_sp_stage.sp_out_crop_pos);
	}
#else
	/**
	 * Even when a stage does not need uds and does not params,
	 * sp_uds_init() seems to be called (needs further investigation)
	 * This function can not deal with dx, dy = {0, 0}
	 */
	(void)preview_mode;
#if 0
	sh_css_sp_stage.uds =
		(struct sh_css_uds_info){HRT_GDC_N, HRT_GDC_N, 0, 0};
#endif

#endif

	sh_css_params_set_current_binary(binary);

	/* Clean static frame info before we update it */
	/*
	 * TODO: Initialize the static frame data with
	 * "sh_css_frame_null".
	 */
	for (i = 0; i < SH_CSS_NUM_FRAME_IDS; i++)
		/* Here, we do not initialize it to zero for now */
		/* to be able to recognize non-updated elements  */
		sh_css_sp_stage.frames.static_frame_data[i] = -1;

	err = sh_css_sp_write_frame_pointers(args, pipe_id, stage);
	if (err != sh_css_success)
		return err;

	if (continuous &&  binary->info->enable.raw_binning) {
		/* TODO: Remove this after preview output decimation is fixed
		 * by configuring out&vf info fiels properly */
		sh_css_sp_stage.frames.out.info.padded_width
			<<= binary->vf_downscale_log2;
		sh_css_sp_stage.frames.out.info.width
			<<= binary->vf_downscale_log2;
		sh_css_sp_stage.frames.out.info.height
			<<= binary->vf_downscale_log2;
	}

	store_sp_stage_data(pipe_id, stage);

	return sh_css_success;
}

static enum sh_css_err
sp_init_stage(struct sh_css_pipeline_stage *stage,
		    enum sh_css_pipe_id id,
		    unsigned stage_num,
		    bool preview_mode,
	      bool low_light,
	      bool xnr)
{
	struct sh_css_binary *binary = stage->binary;
	const struct sh_css_fw_info *firmware = stage->firmware;
	const struct sh_css_binary_args *args = &stage->args;
	const unsigned char *binary_name;
	const struct sh_css_binary_info *info = NULL;
	struct sh_css_binary tmp_binary;
	const struct sh_css_blob_info *blob_info;
	struct sh_css_hmm_isp_interface isp_mem_if[SH_CSS_NUM_ISP_MEMORIES];
	const struct sh_css_hmm_isp_interface *mem_if = isp_mem_if;
	enum sh_css_pipe_id pipe_id = id;

	memset(isp_mem_if, 0, sizeof(isp_mem_if));

	if (binary) {
		info = binary->info;
		binary_name =
			(const unsigned char *)(info->blob->name);
		blob_info = &info->blob->header.blob;
	} else {
		info = &firmware->info.isp;
		sh_css_fill_binary_info(info, false, false,
			    SH_CSS_INPUT_FORMAT_RAW_10,
			    args->in_frame  ? &args->in_frame->info  : NULL,
			    args->out_frame ? &args->out_frame->info : NULL,
			    args->out_vf_frame ? &args->out_vf_frame->info
						: NULL,
			    &tmp_binary,
			    false);
		binary = &tmp_binary;
		binary->info = info;
		binary_name = SH_CSS_EXT_ISP_PROG_NAME(firmware);
		blob_info = &firmware->blob;
		mem_if = firmware->memory_interface;
	}

	sh_css_dtrace(SH_DBG_TRACE,
		"sp_init_stage(): load binary: %s\n", binary_name);
#ifdef __KERNEL__
	printk(KERN_ERR "load binary: %s\n", binary_name);
#endif

	sh_css_sp_init_stage(binary,
			     (const char *)binary_name,
			     blob_info,
			     args,
			     pipe_id,
			     stage_num,
			     preview_mode,
			     low_light,
			     xnr,
				stage->irq_buf_flags,
				mem_if);
	return sh_css_success;
}

void
sh_css_sp_init_pipeline(struct sh_css_pipeline *me,
			enum sh_css_pipe_id id,
			bool preview_mode,
			bool low_light,
			bool xnr,
			bool two_ppc,
			bool continuous,
			bool offline,
			bool input_needs_raw_binning,
			enum sh_css_pipe_config_override copy_ovrd)
{
	/* Get first stage */
	struct sh_css_pipeline_stage *stage;
	struct sh_css_binary	     *first_binary = me->stages->binary;
	struct sh_css_binary_args    *first_args   = &me->stages->args;
	unsigned num;

	enum sh_css_pipe_id pipe_id = id;
	unsigned int thread_id;

	sh_css_query_sp_thread_id(pipe_id, &thread_id);
	memset(&sh_css_sp_group.pipe[thread_id], 0, sizeof(struct sh_css_sp_pipeline));

	/* Count stages */
	for (stage = me->stages, num = 0; stage; stage = stage->next, num++) {
		stage->stage_num = num;
		sh_css_debug_pipe_graph_dump_stage(stage, id);
	}
	me->num_stages = num;

	if (first_binary != NULL) {
	/* Init pipeline data */
		sh_css_sp_init_group(two_ppc, first_binary->input_format, offline);
	/* for Capture, do we need to add more modes like */
		if (continuous &&
			(first_binary->info->mode == SH_CSS_BINARY_MODE_PREVIEW ||
			 first_binary->info->mode == SH_CSS_BINARY_MODE_PRIMARY)) {
#if 0
			sh_css_queue_buffer(SH_CSS_COPY_PIPELINE,
				SH_CSS_BUFFER_TYPE_OUTPUT_FRAME,
				(void *)first_args->cc_frame);
#endif
			sh_css_sp_start_raw_copy(first_binary, first_args->cc_frame,
				two_ppc, input_needs_raw_binning,
				copy_ovrd);

			sh_css_debug_pipe_graph_dump_sp_raw_copy(first_args->cc_frame);
		}
	} /* if (first_binary != NULL) */

	/* Init stage data */
	sh_css_init_host2sp_frame_data();

	sh_css_sp_group.pipe[thread_id].num_stages = 0;
	sh_css_sp_group.pipe[thread_id].pipe_id = pipe_id;
	/* TODO: next indicates from which queues parameters need to be
		 sampled, needs checking/improvement */
	if (sh_css_pipe_uses_params(me)) {
		sh_css_sp_group.pipe[thread_id].pipe_config =
			SH_CSS_PIPE_CONFIG_SAMPLE_PARAMS << thread_id;
	}

	/* For continuous use-cases, SP copy is responsible for sampling the
	 * parameters */
	if (sh_css_continuous_is_enabled())
		sh_css_sp_group.pipe[thread_id].pipe_config = 0;

	for (stage = me->stages, num = 0; stage; stage = stage->next, num++)
		sp_init_stage(stage, pipe_id, num, preview_mode, low_light, xnr);

	store_sp_group_data();

}

void
sh_css_sp_uninit_pipeline(enum sh_css_pipe_id pipe_id)
{
	unsigned int thread_id;
	sh_css_query_sp_thread_id(pipe_id, &thread_id);
	/*memset(&sh_css_sp_group.pipe[thread_id], 0, sizeof(struct sh_css_sp_pipeline));*/
	sh_css_sp_group.pipe[thread_id].num_stages = 0;
}
static enum ia_css_err
sh_css_sp_init_stage(struct ia_css_binary *binary,
		    const char *binary_name,
		    const struct ia_css_blob_info *blob_info,
		    const struct sh_css_binary_args *args,
		    unsigned int pipe_num,
		    unsigned stage,
		    bool xnr,
		    const struct ia_css_isp_param_css_segments *isp_mem_if,
		    unsigned int if_config_index)
{
	const struct ia_css_binary_xinfo *xinfo;
	const struct ia_css_binary_info  *info;
	enum ia_css_err err = IA_CSS_SUCCESS;
	int i;

	unsigned int thread_id;
	bool continuous = sh_css_continuous_is_enabled((uint8_t)pipe_num);

	assert(binary != NULL);
	assert(blob_info != NULL);
	assert(args != NULL);
	assert(isp_mem_if != NULL);

	xinfo = binary->info;
	info  = &xinfo->sp;
	{
		/**
		 * Clear sh_css_sp_stage for easy debugging.
		 * program_input_circuit must be saved as it is set outside
		 * this function.
		 */
		uint8_t program_input_circuit;
		program_input_circuit = sh_css_sp_stage.program_input_circuit;
		memset(&sh_css_sp_stage, 0, sizeof(sh_css_sp_stage));
		sh_css_sp_stage.program_input_circuit = (uint8_t)program_input_circuit;
	}

	ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id);

	if (info == NULL) {
		sh_css_sp_group.pipe[thread_id].sp_stage_addr[stage] = mmgr_NULL;
		return IA_CSS_SUCCESS;
	}

#if defined(USE_INPUT_SYSTEM_VERSION_2401)
	(void)continuous;
	sh_css_sp_stage.deinterleaved = 0;
#else
	sh_css_sp_stage.deinterleaved = ((stage == 0) && continuous);
#endif

	/*
	 * TODO: Make the Host dynamically determine
	 * the stage type.
	 */
	sh_css_sp_stage.stage_type = SH_CSS_ISP_STAGE_TYPE;
	sh_css_sp_stage.num		= (uint8_t)stage;
	sh_css_sp_stage.isp_online	= (uint8_t)binary->online;
	sh_css_sp_stage.isp_copy_vf     = (uint8_t)args->copy_vf;
	sh_css_sp_stage.isp_copy_output = (uint8_t)args->copy_output;
	sh_css_sp_stage.enable.vf_output = (args->out_vf_frame != NULL);

	/* Copy the frame infos first, to be overwritten by the frames,
	   if these are present.
	*/
	sh_css_sp_stage.frames.effective_in_res.width = binary->effective_in_frame_res.width;
	sh_css_sp_stage.frames.effective_in_res.height = binary->effective_in_frame_res.height;

	sh_css_frame_info_to_sp(&sh_css_sp_stage.frames.in.info,
				&binary->in_frame_info);
	sh_css_frame_info_to_sp(&sh_css_sp_stage.frames.out.info,
				&binary->out_frame_info);
	sh_css_frame_info_to_sp(&sh_css_sp_stage.frames.internal_frame_info,
				&binary->internal_frame_info);
	sh_css_sp_stage.dvs_envelope.width    = binary->dvs_envelope.width;
	sh_css_sp_stage.dvs_envelope.height   = binary->dvs_envelope.height;
	sh_css_sp_stage.isp_pipe_version      = (uint8_t)info->isp_pipe_version;
	sh_css_sp_stage.isp_deci_log_factor   = (uint8_t)binary->deci_factor_log2;
	sh_css_sp_stage.isp_vf_downscale_bits = (uint8_t)binary->vf_downscale_log2;

	sh_css_sp_stage.if_config_index = (uint8_t) if_config_index;

	sh_css_sp_stage.sp_enable_xnr = (uint8_t)xnr;
	sh_css_sp_stage.xmem_bin_addr = xinfo->xmem_addr;
	sh_css_sp_stage.xmem_map_addr = sh_css_params_ddr_address_map();
	sh_css_isp_stage.blob_info = *blob_info;
	sh_css_stage_write_binary_info((struct ia_css_binary_info *)info);
	strncpy(sh_css_isp_stage.binary_name, binary_name, SH_CSS_MAX_BINARY_NAME);
	sh_css_isp_stage.binary_name[SH_CSS_MAX_BINARY_NAME - 1] = 0;
	sh_css_isp_stage.mem_initializers = *isp_mem_if;

	/**
	 * Even when a stage does not need uds and does not params,
	 * ia_css_uds_sp_scale_params() seems to be called (needs
	 * further investigation). This function can not deal with
	 * dx, dy = {0, 0}
	 */

	/* Clean static frame info before we update it */
	/*
	 * TODO: Initialize the static frame data with
	 * "sh_css_frame_null".
	 */
	for (i = 0; i < SH_CSS_NUM_FRAME_IDS; i++)
		/* Here, we do not initialize it to zero for now
		 * to be able to recognize non-updated elements
		 * This is what it should become:
		 * sh_css_sp_stage.frames.static_frame_data[i] = mmgr_NULL;
		 */
		sh_css_sp_stage.frames.static_frame_data[i] = mmgr_EXCEPTION;

	err = sh_css_sp_write_frame_pointers(args, pipe_num, stage);
	if (err != IA_CSS_SUCCESS)
		return err;

	configure_isp_from_args(&sh_css_sp_group.pipe[thread_id], binary, args);

	/* we do this only for preview pipe because in fill_binary_info function
	 * we assign vf_out res to out res, but for ISP internal processing, we need
	 * the original out res. for video pipe, it has two output pins --- out and
	 * vf_out, so it can keep these two resolutions already. */
	if (binary->info->sp.mode == IA_CSS_BINARY_MODE_PREVIEW &&
		(binary->vf_downscale_log2 > 0)) {
		/* TODO: Remove this after preview output decimation is fixed
		 * by configuring out&vf info fiels properly */
		sh_css_sp_stage.frames.out.info.padded_width
			<<= binary->vf_downscale_log2;
		sh_css_sp_stage.frames.out.info.width
			<<= binary->vf_downscale_log2;
		sh_css_sp_stage.frames.out.info.height
			<<= binary->vf_downscale_log2;
	}
	err = copy_isp_mem_if_to_ddr(binary);
	if (err != IA_CSS_SUCCESS)
		return err;

	return IA_CSS_SUCCESS;
}