Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 306289
b: refs/heads/master
c: a6d7a62
h: refs/heads/master
i:
  306287: 1d24c55
v: v3
  • Loading branch information
Sakari Ailus authored and Mauro Carvalho Chehab committed May 14, 2012
1 parent 39bf06f commit 10d4b27
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 85 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 20d4ab7bea8e79bb330c2d52da9c245911ea29ed
refs/heads/master: a6d7a62dcd1fccb3140100551b205315491eadc5
65 changes: 65 additions & 0 deletions trunk/drivers/media/video/omap3isp/ispccdc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2154,6 +2154,69 @@ static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
return 0;
}

/*
* Decide whether desired output pixel code can be obtained with
* the lane shifter by shifting the input pixel code.
* @in: input pixelcode to shifter
* @out: output pixelcode from shifter
* @additional_shift: # of bits the sensor's LSB is offset from CAMEXT[0]
*
* return true if the combination is possible
* return false otherwise
*/
static bool ccdc_is_shiftable(enum v4l2_mbus_pixelcode in,
enum v4l2_mbus_pixelcode out,
unsigned int additional_shift)
{
const struct isp_format_info *in_info, *out_info;

if (in == out)
return true;

in_info = omap3isp_video_format_info(in);
out_info = omap3isp_video_format_info(out);

if ((in_info->flavor == 0) || (out_info->flavor == 0))
return false;

if (in_info->flavor != out_info->flavor)
return false;

return in_info->bpp - out_info->bpp + additional_shift <= 6;
}

static int ccdc_link_validate(struct v4l2_subdev *sd,
struct media_link *link,
struct v4l2_subdev_format *source_fmt,
struct v4l2_subdev_format *sink_fmt)
{
struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
unsigned long parallel_shift;

/* Check if the two ends match */
if (source_fmt->format.width != sink_fmt->format.width ||
source_fmt->format.height != sink_fmt->format.height)
return -EPIPE;

/* We've got a parallel sensor here. */
if (ccdc->input == CCDC_INPUT_PARALLEL) {
struct isp_parallel_platform_data *pdata =
&((struct isp_v4l2_subdevs_group *)
media_entity_to_v4l2_subdev(link->source->entity)
->host_priv)->bus.parallel;
parallel_shift = pdata->data_lane_shift * 2;
} else {
parallel_shift = 0;
}

/* Lane shifter may be used to drop bits on CCDC sink pad */
if (!ccdc_is_shiftable(source_fmt->format.code,
sink_fmt->format.code, parallel_shift))
return -EPIPE;

return 0;
}

/*
* ccdc_init_formats - Initialize formats on all pads
* @sd: ISP CCDC V4L2 subdevice
Expand Down Expand Up @@ -2198,6 +2261,7 @@ static const struct v4l2_subdev_pad_ops ccdc_v4l2_pad_ops = {
.set_fmt = ccdc_set_format,
.get_selection = ccdc_get_selection,
.set_selection = ccdc_set_selection,
.link_validate = ccdc_link_validate,
};

/* V4L2 subdev operations */
Expand Down Expand Up @@ -2307,6 +2371,7 @@ static int ccdc_link_setup(struct media_entity *entity,
/* media operations */
static const struct media_entity_operations ccdc_media_ops = {
.link_setup = ccdc_link_setup,
.link_validate = v4l2_subdev_link_validate,
};

void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc)
Expand Down
95 changes: 11 additions & 84 deletions trunk/drivers/media/video/omap3isp/ispvideo.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,37 +129,6 @@ omap3isp_video_format_info(enum v4l2_mbus_pixelcode code)
return NULL;
}

/*
* Decide whether desired output pixel code can be obtained with
* the lane shifter by shifting the input pixel code.
* @in: input pixelcode to shifter
* @out: output pixelcode from shifter
* @additional_shift: # of bits the sensor's LSB is offset from CAMEXT[0]
*
* return true if the combination is possible
* return false otherwise
*/
static bool isp_video_is_shiftable(enum v4l2_mbus_pixelcode in,
enum v4l2_mbus_pixelcode out,
unsigned int additional_shift)
{
const struct isp_format_info *in_info, *out_info;

if (in == out)
return true;

in_info = omap3isp_video_format_info(in);
out_info = omap3isp_video_format_info(out);

if ((in_info->flavor == 0) || (out_info->flavor == 0))
return false;

if (in_info->flavor != out_info->flavor)
return false;

return in_info->bpp - out_info->bpp + additional_shift <= 6;
}

/*
* isp_video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format
* @video: ISP video instance
Expand Down Expand Up @@ -315,51 +284,24 @@ static int isp_video_get_graph_data(struct isp_video *video,
static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
{
struct isp_device *isp = pipe->output->isp;
struct v4l2_subdev_format fmt_source;
struct v4l2_subdev_format fmt_sink;
struct media_pad *pad;
struct v4l2_subdev *subdev;
int ret;

subdev = isp_video_remote_subdev(pipe->output, NULL);
if (subdev == NULL)
return -EPIPE;

while (1) {
unsigned int shifter_link;

/* Retrieve the sink format */
pad = &subdev->entity.pads[0];
if (!(pad->flags & MEDIA_PAD_FL_SINK))
break;

fmt_sink.pad = pad->index;
fmt_sink.which = V4L2_SUBDEV_FORMAT_ACTIVE;
ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt_sink);
if (ret < 0 && ret != -ENOIOCTLCMD)
return -EPIPE;

/* Update the maximum frame rate */
if (subdev == &isp->isp_res.subdev)
omap3isp_resizer_max_rate(&isp->isp_res,
&pipe->max_rate);

/* Check ccdc maximum data rate when data comes from sensor
* TODO: Include ccdc rate in pipe->max_rate and compare the
* total pipe rate with the input data rate from sensor.
*/
if (subdev == &isp->isp_ccdc.subdev && pipe->input == NULL) {
unsigned int rate = UINT_MAX;

omap3isp_ccdc_max_rate(&isp->isp_ccdc, &rate);
if (pipe->external_rate > rate)
return -ENOSPC;
}

/* If sink pad is on CCDC, the link has the lane shifter
* in the middle of it. */
shifter_link = subdev == &isp->isp_ccdc.subdev;

/* Retrieve the source format. Return an error if no source
* entity can be found, and stop checking the pipeline if the
* source entity isn't a subdev.
Expand All @@ -372,32 +314,6 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
break;

subdev = media_entity_to_v4l2_subdev(pad->entity);

fmt_source.pad = pad->index;
fmt_source.which = V4L2_SUBDEV_FORMAT_ACTIVE;
ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt_source);
if (ret < 0 && ret != -ENOIOCTLCMD)
return -EPIPE;

/* Check if the two ends match */
if (fmt_source.format.width != fmt_sink.format.width ||
fmt_source.format.height != fmt_sink.format.height)
return -EPIPE;

if (shifter_link) {
unsigned int parallel_shift = 0;
if (isp->isp_ccdc.input == CCDC_INPUT_PARALLEL) {
struct isp_parallel_platform_data *pdata =
&((struct isp_v4l2_subdevs_group *)
subdev->host_priv)->bus.parallel;
parallel_shift = pdata->data_lane_shift * 2;
}
if (!isp_video_is_shiftable(fmt_source.format.code,
fmt_sink.format.code,
parallel_shift))
return -EPIPE;
} else if (fmt_source.format.code != fmt_sink.format.code)
return -EPIPE;
}

return 0;
Expand Down Expand Up @@ -1024,6 +940,17 @@ static int isp_video_check_external_subdevs(struct isp_video *video,

pipe->external_rate = ctrl.value64;

if (pipe->entities & (1 << isp->isp_ccdc.subdev.entity.id)) {
unsigned int rate = UINT_MAX;
/*
* Check that maximum allowed CCDC pixel rate isn't
* exceeded by the pixel rate.
*/
omap3isp_ccdc_max_rate(&isp->isp_ccdc, &rate);
if (pipe->external_rate > rate)
return -ENOSPC;
}

return 0;
}

Expand Down

0 comments on commit 10d4b27

Please sign in to comment.