/* Setup sp/sp1 binary */
static enum ia_css_err
setup_sp(struct ia_css_fw_info *fw, const char *fw_data, struct ia_css_fw_info *sh_css_sp_sp1_fw, unsigned sp_id)
{
	const char *blob_data;

	if ((fw == NULL) || (fw_data == NULL))
		return IA_CSS_ERR_INVALID_ARGUMENTS;

	blob_data = fw_data + fw->blob.offset;

	*sh_css_sp_sp1_fw = *fw;

#if defined(C_RUN) || defined(HRT_UNSCHED)
	sh_css_sp_sp1_fw->blob.code = sh_css_malloc(1);
#else
	sh_css_sp_sp1_fw->blob.code = sh_css_malloc(fw->blob.size);
#endif

	if (sh_css_sp_sp1_fw->blob.code == NULL)
		return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;

	memcpy((void *)sh_css_sp_sp1_fw->blob.code, blob_data, fw->blob.size);
	sh_css_sp_sp1_fw->blob.data = (char *)sh_css_sp_sp1_fw->blob.code + fw->blob.data_source;
	fw_minibuffer[sp_id].buffer = sh_css_sp_sp1_fw->blob.code;

	return IA_CSS_SUCCESS;
}
Ejemplo n.º 2
0
enum ia_css_err ia_css_refcount_init(uint32_t size)
{
	enum ia_css_err err = IA_CSS_SUCCESS;

	if (size == 0) {
		ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
				    "ia_css_refcount_init(): Size of 0 for Ref count init!\n");
		return IA_CSS_ERR_INVALID_ARGUMENTS;
	}
	if (myrefcount.items != NULL) {
		ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
				    "ia_css_refcount_init(): Ref count is already initialized\n");
		return IA_CSS_ERR_INTERNAL_ERROR;
	}
	myrefcount.items =
	    sh_css_malloc(sizeof(struct ia_css_refcount_entry) * size);
	if (!myrefcount.items)
		err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
	if (err == IA_CSS_SUCCESS) {
		memset(myrefcount.items, 0,
		       sizeof(struct ia_css_refcount_entry) * size);
		myrefcount.size = size;
	}
	return err;
}
/**
 * @brief Initialize the resource pool (host, vbuf)
 *
 * @param pool	The pointer to the pool
 */
enum ia_css_err ia_css_rmgr_init_vbuf(struct ia_css_rmgr_vbuf_pool *pool)
{
    enum ia_css_err err = IA_CSS_SUCCESS;
    size_t bytes_needed;
    rmgr_refcount_init_vbuf();
    assert(pool != NULL);
    if (pool == NULL)
        return IA_CSS_ERR_INVALID_ARGUMENTS;
    /* initialize the recycle pool if used */
    if (pool->recycle && pool->size) {
        /* allocate memory for storing the handles */
        bytes_needed =
            sizeof(void *) *
            pool->size;
        pool->handles = sh_css_malloc(bytes_needed);
        if (pool->handles != NULL)
            memset(pool->handles, 0, bytes_needed);
        else
            err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
    } else {
        /* just in case, set the size to 0 */
        pool->size = 0;
        pool->handles = NULL;
    }
    return err;
}
Ejemplo n.º 4
0
/* When binaries are put at the beginning, they will only
 * be selected if no other primary matches.
 */
enum sh_css_err
sh_css_init_binary_infos(void)
{
	unsigned int i;
	unsigned int num_of_isp_binaries = sh_css_num_binaries - 1;

	all_binaries = sh_css_malloc(num_of_isp_binaries *
						sizeof(*all_binaries));

	for (i = 0; i < num_of_isp_binaries; i++) {
		enum sh_css_err ret;
		struct sh_css_binary_info *binary = &all_binaries[i];
		bool binary_found;

		ret = init_binary_info(binary, i, &binary_found);
		if (ret != sh_css_success)
			return ret;
		if (!binary_found)
			continue;
		/* Prepend new binary information */
		binary->next = binary_infos[binary->mode];
		binary_infos[binary->mode] = binary;
		binary->blob = &sh_css_blob_info[i];
	}
	return sh_css_success;
}
static struct ia_css_frame *frame_create(unsigned int width,
	unsigned int height,
	enum ia_css_frame_format format,
	unsigned int padded_width,
	unsigned int raw_bit_depth,
	bool contiguous,
	bool valid)
{
	struct ia_css_frame *me = sh_css_malloc(sizeof(*me));

	if (me == NULL)
		return NULL;

	me->info.res.width = width;
	me->info.res.height = height;
	me->info.format = format;
	me->info.padded_width = padded_width;
	me->info.raw_bit_depth = raw_bit_depth;
	me->contiguous = contiguous;
	me->valid = valid;
	me->data_bytes = 0;
	me->data = mmgr_NULL;
	/* To indicate it is not valid frame. */
	me->dynamic_data_index = SH_CSS_INVALID_FRAME_ID;

	return me;
}
/* When binaries are put at the beginning, they will only
 * be selected if no other primary matches.
 */
enum ia_css_err
sh_css_init_binary_infos(void)
{
	unsigned int i;
	unsigned int num_of_isp_binaries = sh_css_num_binaries - 1;

	all_binaries = sh_css_malloc(num_of_isp_binaries *
						sizeof(*all_binaries));
	if (all_binaries == NULL)
		return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;

	for (i = 0; i < num_of_isp_binaries; i++) {
		enum ia_css_err ret;
		struct ia_css_binary_info *binary = &all_binaries[i];
		bool binary_found;

		ret = init_binary_info(binary, i, &binary_found);
		if (ret != IA_CSS_SUCCESS)
			return ret;
		if (!binary_found)
			continue;
		/* Prepend new binary information */
		binary->next = binary_infos[binary->mode];
		binary_infos[binary->mode] = binary;
		binary->blob = &sh_css_blob_info[i];
	}
	return IA_CSS_SUCCESS;
}
Ejemplo n.º 7
0
static void
generate_id_shading_table(struct sh_css_shading_table_isp **target_table,
			  const struct sh_css_binary *binary)
{
	unsigned int c, l, x, table_width, table_height, table_stride;
	struct sh_css_shading_table_isp *result;

	table_width  = binary->sctbl_width_per_color;
	table_stride = binary->sctbl_aligned_width_per_color;
	table_height = binary->sctbl_height;

	result = sh_css_malloc(sizeof(*result));
	if (result == NULL) {
		*target_table = NULL;
		return;
	}
	result->width	  = table_width;
	result->stride	  = table_stride;
	result->height	  = table_height;
	result->sensor_width  = 0;
	result->sensor_height = 0;
	result->fraction_bits = 0;

	result->data =
	    sh_css_malloc(SH_CSS_SC_NUM_COLORS * table_stride * table_height *
		    				sizeof(*result->data));
	if (result->data == NULL) {
		sh_css_free(result);
		*target_table = NULL;
		return;
	}

	/* initialize table with ones and padding with zeros*/
	for (c = 0; c < SH_CSS_SC_NUM_COLORS; c++) {
		for (l = 0; l < table_height; l++) {
			for (x = 0; x < table_width; x++)
				*sh_table_entry(result, c, l, x) = 1;
			for (; x < table_stride; x++)
				*sh_table_entry(result, c, l, x) = 0;
		}
	}

	*target_table = result;
}
Ejemplo n.º 8
0
static void
make_histogram(struct sh_css_pc_histogram *histogram, unsigned length)
{
	assert_exit(histogram != NULL);

	if (histogram->length)
		return;
	if (histogram->run)
		return;
	histogram->run = sh_css_malloc(length * sizeof(*histogram->run));
	if (!histogram->run)
		return;
	histogram->stall = sh_css_malloc(length * sizeof(*histogram->stall));
	if (!histogram->stall)
		return;
	histogram->msink = sh_css_malloc(length * sizeof(*histogram->msink));
	if (!histogram->msink)
		return;

	histogram->length = length;
	clear_histogram(histogram);
}
Ejemplo n.º 9
0
struct sh_css_shading_table *
sh_css_shading_table_alloc(
	unsigned int width,
	unsigned int height)
{
	unsigned int i;
	struct sh_css_shading_table *me = sh_css_malloc(sizeof(*me));

	sh_css_dtrace(SH_DBG_TRACE_PRIVATE,
		"sh_css_shading_table_alloc() enter:\n");

	if (me == NULL) {
/* Checkpatch patch */
		return me;
	}
	me->width		 = width;
	me->height		= height;
	me->sensor_width  = 0;
	me->sensor_height = 0;
	me->fraction_bits = 0;
	for (i = 0; i < SH_CSS_SC_NUM_COLORS; i++) {
		me->data[i] =
		    sh_css_malloc(width * height * sizeof(*me->data[0]));
		if (me->data[i] == NULL) {
			unsigned int j;
			for (j = 0; j < i; j++)
				sh_css_free(me->data[j]);
			sh_css_free(me);
			return NULL;
		}
	}

	sh_css_dtrace(SH_DBG_TRACE_PRIVATE,
		"sh_css_shading_table_alloc() leave:\n");

	return me;
}
struct ia_css_shading_table *
ia_css_shading_table_alloc(
	unsigned int width,
	unsigned int height)
{
	unsigned int i;
	struct ia_css_shading_table *me;

	IA_CSS_ENTER("");

	me = sh_css_malloc(sizeof(*me));
	if (me == NULL) {
		IA_CSS_ERROR("out of memory");
		return me;
	}

	me->width         = width;
	me->height        = height;
	me->sensor_width  = 0;
	me->sensor_height = 0;
	me->fraction_bits = 0;
	for (i = 0; i < IA_CSS_SC_NUM_COLORS; i++) {
		me->data[i] =
		    sh_css_malloc(width * height * sizeof(*me->data[0]));
		if (me->data[i] == NULL) {
			unsigned int j;
			for (j = 0; j < i; j++)
				sh_css_free(me->data[j]);
			sh_css_free(me);
			return NULL;
		}
	}

	IA_CSS_LEAVE("");
	return me;
}
Ejemplo n.º 11
0
enum sh_css_err sh_css_refcount_init(void)
{
	enum sh_css_err err = sh_css_success;
	int size = 1000;

assert(myrefcount.items == NULL);

	myrefcount.items =
		sh_css_malloc(sizeof(struct sh_css_refcount_entry)*size);
	if (!myrefcount.items)
		err = sh_css_err_cannot_allocate_memory;
	if (err == sh_css_success) {
		memset(myrefcount.items, 0,
			   sizeof(struct sh_css_refcount_entry)*size);
		myrefcount.size = size;
	}
	return err;
}
Ejemplo n.º 12
0
enum ia_css_err sh_css_refcount_init(void)
{
	enum ia_css_err err = IA_CSS_SUCCESS;
	int size = 1000;

	assert_exit_code(myrefcount.items == NULL, IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY);

	myrefcount.items =
		sh_css_malloc(sizeof(struct sh_css_refcount_entry)*size);
	if (!myrefcount.items)
		err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
	if (err == IA_CSS_SUCCESS) {
		memset(myrefcount.items, 0,
			   sizeof(struct sh_css_refcount_entry)*size);
		myrefcount.size = size;
	}
	return err;
}
enum ia_css_err ia_css_refcount_init(uint32_t size)
{
	enum ia_css_err err = IA_CSS_SUCCESS;

	assert(size != 0);
	assert(myrefcount.items == NULL);

	myrefcount.items =
	    sh_css_malloc(sizeof(struct ia_css_refcount_entry) * size);
	if (!myrefcount.items)
		err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
	if (err == IA_CSS_SUCCESS) {
		memset(myrefcount.items, 0,
		       sizeof(struct ia_css_refcount_entry) * size);
		myrefcount.size = size;
	}
	return err;
}
Ejemplo n.º 14
0
struct ia_css_dvs_6axis_config *
generate_dvs_6axis_table(const struct ia_css_resolution	*frame_res, const struct ia_css_resolution *dvs_offset)
{
	
	unsigned int x,y;
	unsigned int width_y;
	unsigned int height_y;
	unsigned int width_uv;
	unsigned int height_uv;
	enum ia_css_err err = IA_CSS_SUCCESS;	
	struct ia_css_dvs_6axis_config  *dvs_config = NULL;
	
	dvs_config = (struct ia_css_dvs_6axis_config *)sh_css_malloc(sizeof(struct ia_css_dvs_6axis_config));
	if(dvs_config == NULL)
	{
		sh_css_dtrace(SH_DBG_TRACE, "out of memory\n");
		err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
	}
	else
	{	/*Initialize new struct with latest config settings*/	
		dvs_config->width_y = width_y = DVS_TABLE_IN_BLOCKDIM_X_LUMA(frame_res->width);
		dvs_config->height_y = height_y = DVS_TABLE_IN_BLOCKDIM_Y_LUMA(frame_res->height);
		dvs_config->width_uv = width_uv = DVS_TABLE_IN_BLOCKDIM_X_CHROMA(frame_res->width / 2); /* UV = Y/2, depens on colour format YUV 4.2.0*/
		dvs_config->height_uv = height_uv = DVS_TABLE_IN_BLOCKDIM_Y_CHROMA(frame_res->height / 2);/* UV = Y/2, depens on colour format YUV 4.2.0*/

		sh_css_dtrace(SH_DBG_TRACE, "generate_dvs_6axis_table: Env_X %d Env_Y %d\n",dvs_offset->width,dvs_offset->height);
		sh_css_dtrace(SH_DBG_TRACE, "generate_dvs_6axis_table Y: W %d H %d\n",width_y,height_y);
		/* Generate Y buffers  */
		dvs_config->xcoords_y = (uint32_t *)sh_css_malloc( width_y * height_y * sizeof(uint32_t));	
		if(dvs_config->xcoords_y == NULL)
		{
			sh_css_dtrace(SH_DBG_TRACE, "out of memory\n");
			err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
		}
		else
		{
			for(y = 0; y < height_y; y++)
			{
				for(x=0;x<width_y;x++)
				{
					dvs_config->xcoords_y[y*width_y + x] =  (  ( dvs_offset->width + x*DVS_BLOCKDIM_X) << DVS_COORD_FRAC_BITS );
				}
			}
		}

		dvs_config->ycoords_y = (uint32_t *)sh_css_malloc( width_y * height_y * sizeof(uint32_t));
		if(dvs_config->ycoords_y == NULL)
		{
			sh_css_dtrace(SH_DBG_TRACE, "out of memory\n");
			err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
		}
		else
		{			
			for(y = 0; y < height_y; y++)
			{
				for(x=0;x<width_y;x++)
				{
					dvs_config->ycoords_y[y*width_y + x] =  (  ( dvs_offset->height + y*DVS_BLOCKDIM_Y_LUMA) << DVS_COORD_FRAC_BITS );
				}
			}
		}
		
		/* Generate UV buffers  */		
		sh_css_dtrace(SH_DBG_TRACE, "generate_dvs_6axis_table UV W %d H %d\n",width_uv,height_uv);
		
		dvs_config->xcoords_uv = (uint32_t *)sh_css_malloc( width_uv * height_uv * sizeof(uint32_t));	
		if(dvs_config->xcoords_uv == NULL)
		{
			sh_css_dtrace(SH_DBG_TRACE, "out of memory\n");
			err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
		}
		else
		{			
			for(y = 0; y < height_uv; y++)
			{
				for(x=0;x<width_uv;x++)
				{	/* Envelope dimesions set in Ypixels hence offset UV = offset Y/2 */
					dvs_config->xcoords_uv[y*width_uv + x] =  (  ( (dvs_offset->width / 2) + x*DVS_BLOCKDIM_X) << DVS_COORD_FRAC_BITS ); 
				}
			}
		}
		    
		dvs_config->ycoords_uv = (uint32_t *)sh_css_malloc( width_uv * height_uv * sizeof(uint32_t));
		if(dvs_config->ycoords_uv == NULL)
		{
			sh_css_dtrace(SH_DBG_TRACE, "out of memory\n");
			err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
		}
		else
		{	
			for(y = 0; y < height_uv; y++)
			{
				for(x=0;x<width_uv;x++)
				{ 	/* Envelope dimesions set in Ypixels hence offset UV = offset Y/2 */
					dvs_config->ycoords_uv[y*width_uv + x] =  (  ( (dvs_offset->height / 2) + y*DVS_BLOCKDIM_Y_CHROMA) << DVS_COORD_FRAC_BITS );
				}
			}
		}
		
#if 0
		for(y = 0; y < height_y; y++)
		{
			for(x=0;x<width_y;x++)
				sh_css_dtrace(SH_DBG_TRACE, "xcoords_y: %d \n",dvs_config->xcoords_y[y*width_y + x]); 
			sh_css_dtrace(SH_DBG_TRACE, "\n");
		}
		
		for(y = 0; y < height_y; y++)
		{
			for(x=0;x<width_y;x++)
				sh_css_dtrace(SH_DBG_TRACE, "ycoords_y: %d \n",dvs_config->ycoords_y[y*width_y + x]); 
			sh_css_dtrace(SH_DBG_TRACE, "\n");
		}	
		
				for(y = 0; y < height_y; y++)
		{
			for(x=0;x<width_uv;x++)
				sh_css_dtrace(SH_DBG_TRACE, "xcoords_uv: %d \n",dvs_config->xcoords_uv[y*width_uv + x]); 
			sh_css_dtrace(SH_DBG_TRACE, "\n");
		}
		
		for(y = 0; y < height_uv; y++)
		{
			for(x=0;x<width_uv;x++)
				sh_css_dtrace(SH_DBG_TRACE, "ycoords_uv: %d \n",dvs_config->ycoords_uv[y*width_uv + x]); 
			sh_css_dtrace(SH_DBG_TRACE, "\n");
		}				
#endif		    
		if (err != IA_CSS_SUCCESS)
		{
			sh_css_dtrace(SH_DBG_TRACE, "generate_dvs_6axis_table: err %d\n, leave() ",(int)err);	
			dvs_config = NULL;
		}
		else
		{
			sh_css_dtrace(SH_DBG_TRACE, "generate_dvs_6axis_table leave() , dvs_config %p\n",dvs_config);
		}
	}
	
	return dvs_config;
}
Ejemplo n.º 15
0
static enum ia_css_err pipeline_stage_create(
	struct ia_css_pipeline_stage_desc *stage_desc,
	struct ia_css_pipeline_stage **new_stage)
{
	enum ia_css_err err = IA_CSS_SUCCESS;
	struct ia_css_pipeline_stage *stage = NULL;
	struct ia_css_binary *binary;
	struct ia_css_frame *vf_frame;
	struct ia_css_frame *out_frame[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
	const struct ia_css_fw_info *firmware;
	unsigned int i;

	/* Verify input parameters*/
	if (!(stage_desc->in_frame) && !(stage_desc->firmware)
	    && (stage_desc->binary) && !(stage_desc->binary->online)) {
		err = IA_CSS_ERR_INTERNAL_ERROR;
		goto ERR;
	}

	binary = stage_desc->binary;
	firmware = stage_desc->firmware;
	vf_frame = stage_desc->vf_frame;
	for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) {
		out_frame[i] = stage_desc->out_frame[i];
	}

	stage = sh_css_malloc(sizeof(*stage));
	if (stage == NULL) {
		err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
		goto ERR;
	}
	memset(stage, 0, sizeof(*stage));

	if (firmware) {
		stage->binary = NULL;
		stage->binary_info =
		    (struct ia_css_binary_info *)&firmware->info.isp;
	} else {
		stage->binary = binary;
		if (binary)
			stage->binary_info =
			    (struct ia_css_binary_info *)binary->info;
		else
			stage->binary_info = NULL;
	}

	stage->firmware = firmware;
	stage->sp_func = stage_desc->sp_func;
	stage->max_input_width = stage_desc->max_input_width;
	stage->mode = stage_desc->mode;
	for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
		stage->out_frame_allocated[i] = false;
	stage->vf_frame_allocated = false;
	stage->next = NULL;
	sh_css_binary_args_reset(&stage->args);

	for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) {
		if (!(out_frame[i]) && (binary)
			&& (binary->out_frame_info[i].res.width)) {
			err = ia_css_frame_allocate_from_info(&out_frame[i],
							&binary->out_frame_info[i]);
			if (err != IA_CSS_SUCCESS)
				goto ERR;
			stage->out_frame_allocated[i] = true;
		}
	}
	/* VF frame is not needed in case of need_pp
	   However, the capture binary needs a vf frame to write to.
	 */
	if (!vf_frame) {
		if ((binary && binary->vf_frame_info.res.width) ||
		    (firmware && firmware->info.isp.sp.enable.vf_veceven)
		    ) {
			err = ia_css_frame_allocate_from_info(&vf_frame,
							&binary->vf_frame_info);
			if (err != IA_CSS_SUCCESS)
				goto ERR;
			stage->vf_frame_allocated = true;
		}
	} else if (vf_frame && binary && binary->vf_frame_info.res.width
		&& !firmware) {
		/* only mark as allocated if buffer pointer available */
		if (vf_frame->data != mmgr_NULL)
			stage->vf_frame_allocated = true;
	}

	stage->args.in_frame = stage_desc->in_frame;
	for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
		stage->args.out_frame[i] = out_frame[i];
	stage->args.out_vf_frame = vf_frame;
	*new_stage = stage;
	return err;
ERR:
	if (stage != NULL)
		pipeline_stage_destroy(stage);
	return err;
}
enum ia_css_err
sh_css_load_firmware(const char *fw_data,
		     unsigned int fw_size)
{
	unsigned i;
	struct ia_css_fw_info *binaries;
	struct sh_css_fw_bi_file_h *file_header;
	bool valid_firmware = false;

	firmware_header = (struct firmware_header *)fw_data;
	file_header = (struct sh_css_fw_bi_file_h *)&firmware_header->file_header;
	binaries = (struct ia_css_fw_info *)&firmware_header->binary_header;
	strncpy(FW_rel_ver_name, file_header->version, min(sizeof(FW_rel_ver_name), sizeof(file_header->version)) - 1);
	valid_firmware = sh_css_check_firmware_version(fw_data);
	if (!valid_firmware) {
#if (!defined HRT_CSIM && !defined HRT_RTL)
		IA_CSS_ERROR("CSS code version (%s) and firmware version (%s) mismatch!",
				file_header->version, release_version);
		return IA_CSS_ERR_VERSION_MISMATCH;
#endif
	} else {
		IA_CSS_LOG("successfully load firmware version %s", release_version);
	}

	/* some sanity checks */
	if (!fw_data || fw_size < sizeof(struct sh_css_fw_bi_file_h))
		return IA_CSS_ERR_INTERNAL_ERROR;

	if (file_header->h_size != sizeof(struct sh_css_fw_bi_file_h))
		return IA_CSS_ERR_INTERNAL_ERROR;

	sh_css_num_binaries = file_header->binary_nr;
	/* Only allocate memory for ISP blob info */
	if (sh_css_num_binaries > NUM_OF_SPS) {
		sh_css_blob_info = sh_css_malloc(
					(sh_css_num_binaries - NUM_OF_SPS) *
					sizeof(*sh_css_blob_info));
		if (sh_css_blob_info == NULL)
			return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
	} else {
		sh_css_blob_info = NULL;
	}

	fw_minibuffer = sh_css_malloc(sh_css_num_binaries * sizeof(struct fw_param));
	if (fw_minibuffer == NULL)
		return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
	memset(fw_minibuffer, 0, sh_css_num_binaries * sizeof(struct fw_param));

	for (i = 0; i < sh_css_num_binaries; i++) {
		struct ia_css_fw_info *bi = &binaries[i];
		/* note: the var below is made static as it is quite large;
		   if it is not static it ends up on the stack which could
		   cause issues for drivers
		*/
		static struct ia_css_blob_descr bd;
		enum ia_css_err err;

		err = sh_css_load_blob_info(fw_data, bi, &bd, i);

		if (err != IA_CSS_SUCCESS)
			return IA_CSS_ERR_INTERNAL_ERROR;

		if (bi->blob.offset + bi->blob.size > fw_size)
			return IA_CSS_ERR_INTERNAL_ERROR;

		if (bi->type == ia_css_sp_firmware) {
			if (i != SP_FIRMWARE)
				return IA_CSS_ERR_INTERNAL_ERROR;
			err = setup_sp(bi, fw_data, &sh_css_sp_fw, i);
			if (err != IA_CSS_SUCCESS)
				return err;
#if defined(HAS_SEC_SP)
		} else if (bi->type == ia_css_sp1_firmware) {
			if (i != SP1_FIRMWARE)
				return IA_CSS_ERR_INTERNAL_ERROR;
			err = setup_sp(bi, fw_data, &sh_css_sp1_fw, i);
			if (err != IA_CSS_SUCCESS)
				return err;
#endif /* HAS_SEC_SP */
		} else {
			/* All subsequent binaries (i>NUM_OF_SPS) are ISP firmware */
			if (i < NUM_OF_SPS)
				return IA_CSS_ERR_INTERNAL_ERROR;
			if (bi->type != ia_css_isp_firmware)
				return IA_CSS_ERR_INTERNAL_ERROR;
			if (sh_css_blob_info == NULL) /* cannot happen but KW does not see this */
				return IA_CSS_ERR_INTERNAL_ERROR;
			sh_css_blob_info[i-NUM_OF_SPS] = bd;
		}
	}

	return IA_CSS_SUCCESS;
}
enum ia_css_err
sh_css_load_blob_info(const char *fw, const struct ia_css_fw_info *bi, struct ia_css_blob_descr *bd, unsigned index)
{
	const char *name;
	const unsigned char *blob;

	if ((fw == NULL) || (bd == NULL))
		return IA_CSS_ERR_INVALID_ARGUMENTS;

	/* Special case: only one binary in fw */
	if (bi == NULL) bi = (const struct ia_css_fw_info *)fw;

	name = (const char *)fw + bi->blob.prog_name_offset;
	blob = (const unsigned char *)fw + bi->blob.offset;

	/* sanity check */
	if (bi->blob.size != bi->blob.text_size + bi->blob.icache_size + bi->blob.data_size + bi->blob.padding_size) {
		/* sanity check, note the padding bytes added for section to DDR alignment */
		return IA_CSS_ERR_INVALID_ARGUMENTS;
	}

	if ((bi->blob.offset % (1UL<<(ISP_PMEM_WIDTH_LOG2-3))) != 0)
		return IA_CSS_ERR_INVALID_ARGUMENTS;

	bd->blob = blob;
	bd->header = *bi;

	if ((bi->type == ia_css_isp_firmware) || (bi->type == ia_css_sp_firmware)
#if defined(HAS_SEC_SP)
	|| (bi->type == ia_css_sp1_firmware)
#endif /* HAS_SEC_SP */
	)
	{
		char *namebuffer;
		int namelength = (int)strlen(name);

		namebuffer = (char *) sh_css_malloc(namelength+1);
		if (namebuffer == NULL)
			return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;

		memcpy(namebuffer, name, namelength+1);

		bd->name = fw_minibuffer[index].name = namebuffer;
	} else {
		bd->name = name;
	}

	if (bi->type == ia_css_isp_firmware) {
		size_t paramstruct_size = sizeof(struct ia_css_memory_offsets);
		size_t configstruct_size = sizeof(struct ia_css_config_memory_offsets);
		size_t statestruct_size = sizeof(struct ia_css_state_memory_offsets);

		char *parambuf = (char *) sh_css_malloc(paramstruct_size + configstruct_size + statestruct_size);
		if (parambuf == NULL)
			return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;

		bd->mem_offsets.array[IA_CSS_PARAM_CLASS_PARAM].ptr = NULL;
		bd->mem_offsets.array[IA_CSS_PARAM_CLASS_CONFIG].ptr = NULL;
		bd->mem_offsets.array[IA_CSS_PARAM_CLASS_STATE].ptr = NULL;

		fw_minibuffer[index].buffer = parambuf;

		/* copy ia_css_memory_offsets */
		memcpy(parambuf, (void *)(fw + bi->blob.memory_offsets.offsets[IA_CSS_PARAM_CLASS_PARAM]),
			paramstruct_size);
		bd->mem_offsets.array[IA_CSS_PARAM_CLASS_PARAM].ptr = parambuf;

		/* copy ia_css_config_memory_offsets */
		memcpy(parambuf + paramstruct_size,
				(void *)(fw + bi->blob.memory_offsets.offsets[IA_CSS_PARAM_CLASS_CONFIG]),
				configstruct_size);
		bd->mem_offsets.array[IA_CSS_PARAM_CLASS_CONFIG].ptr = parambuf + paramstruct_size;

		/* copy ia_css_state_memory_offsets */
		memcpy(parambuf + paramstruct_size + configstruct_size,
				(void *)(fw + bi->blob.memory_offsets.offsets[IA_CSS_PARAM_CLASS_STATE]),
				statestruct_size);
		bd->mem_offsets.array[IA_CSS_PARAM_CLASS_STATE].ptr = parambuf + paramstruct_size + configstruct_size;
	}
	return IA_CSS_SUCCESS;
}
Ejemplo n.º 18
0
static void
sh_css_param_shading_table_prepare(const struct sh_css_shading_table *in_table,
			unsigned int sensor_binning,
			bool raw_binning,
			struct sh_css_shading_table_isp **target_table,
			const struct sh_css_binary *binary)
{
	unsigned int input_width,
		     input_height,
		     table_width,
		     table_stride,
		     table_height,
		     left_padding,
		     right_padding;

	struct sh_css_shading_table_isp *result;

	if (!in_table) {
		generate_id_shading_table(target_table, binary);
		return;
	}

	/* We use the ISP input resolution for the shading table because
	   shading correction is performed in the bayer domain (before bayer
	   down scaling). */
	input_height  = binary->in_frame_info.height;
	input_width   = binary->in_frame_info.width;
	left_padding  = binary->left_padding;
	right_padding = binary->in_frame_info.padded_width -
			(input_width + left_padding);

	if ((binary->info->mode == SH_CSS_BINARY_MODE_PREVIEW)
			&& raw_binning
			&& binary->info->enable.raw_binning) {
		input_width = input_width * 2 - binary->info->left_cropping;
		input_height = input_height * 2 - binary->info->top_cropping;
	}

	/* We take into account the binning done by the sensor. We do this
	   by cropping the non-binned part of the shading table and then
	   increasing the size of a grid cell with this same binning factor. */
	input_width  <<= sensor_binning;
	input_height <<= sensor_binning;
	/* We also scale the padding by the same binning factor. This will
	   make it much easier later on to calculate the padding of the
	   shading table. */
	left_padding  <<= sensor_binning;
	right_padding <<= sensor_binning;

	/* during simulation, the used resolution can exceed the sensor
	   resolution, so we clip it. */
	input_width  = min(input_width,  in_table->sensor_width);
	input_height = min(input_height, in_table->sensor_height);

	table_width  = binary->sctbl_width_per_color;
	table_stride = binary->sctbl_aligned_width_per_color;
	table_height = binary->sctbl_height;

	result = sh_css_malloc(sizeof(*result));
	if (result == NULL) {
		*target_table = NULL;
		return;
	}
	result->width	  = table_width;
	result->stride	  = table_stride;
	result->height	  = table_height;
	result->sensor_width  = in_table->sensor_width;
	result->sensor_height = in_table->sensor_height;
	result->fraction_bits = in_table->fraction_bits;

	result->data =
	    sh_css_malloc(SH_CSS_SC_NUM_COLORS * table_stride * table_height *
		    				sizeof(*result->data));
	if (result->data == NULL) {
		sh_css_free(result);
		*target_table = NULL;
		return;
	}

	crop_and_interpolate(input_width, input_height,
			     left_padding, right_padding,
			     in_table,
			     result);

	*target_table = result;

}