diff options
author | Michael Jones <michael.jones@matrix-vision.de> | 2011-03-29 04:19:09 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-04-19 10:28:08 -0400 |
commit | c09af044db91bf0f8ca5073f5863c7280de39cc1 (patch) | |
tree | a8279dc3db8b1ca73a246c5be857bbc024a87dca /drivers/media | |
parent | 5782f97b55a0cf8ef66dff045f1beafcdaf40dda (diff) |
[media] omap3isp: lane shifter support
To use the lane shifter, set different pixel formats at each end of
the link at the CCDC input.
Signed-off-by: Michael Jones <michael.jones@matrix-vision.de>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/omap3isp/isp.c | 7 | ||||
-rw-r--r-- | drivers/media/video/omap3isp/isp.h | 5 | ||||
-rw-r--r-- | drivers/media/video/omap3isp/ispccdc.c | 27 | ||||
-rw-r--r-- | drivers/media/video/omap3isp/ispvideo.c | 108 | ||||
-rw-r--r-- | drivers/media/video/omap3isp/ispvideo.h | 3 |
5 files changed, 120 insertions, 30 deletions
diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/video/omap3isp/isp.c index e4fe836ee6d2..5d8e1ce64508 100644 --- a/drivers/media/video/omap3isp/isp.c +++ b/drivers/media/video/omap3isp/isp.c | |||
@@ -286,7 +286,8 @@ static void isp_power_settings(struct isp_device *isp, int idle) | |||
286 | */ | 286 | */ |
287 | void omap3isp_configure_bridge(struct isp_device *isp, | 287 | void omap3isp_configure_bridge(struct isp_device *isp, |
288 | enum ccdc_input_entity input, | 288 | enum ccdc_input_entity input, |
289 | const struct isp_parallel_platform_data *pdata) | 289 | const struct isp_parallel_platform_data *pdata, |
290 | unsigned int shift) | ||
290 | { | 291 | { |
291 | u32 ispctrl_val; | 292 | u32 ispctrl_val; |
292 | 293 | ||
@@ -299,9 +300,9 @@ void omap3isp_configure_bridge(struct isp_device *isp, | |||
299 | switch (input) { | 300 | switch (input) { |
300 | case CCDC_INPUT_PARALLEL: | 301 | case CCDC_INPUT_PARALLEL: |
301 | ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL; | 302 | ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL; |
302 | ispctrl_val |= pdata->data_lane_shift << ISPCTRL_SHIFT_SHIFT; | ||
303 | ispctrl_val |= pdata->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT; | 303 | ispctrl_val |= pdata->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT; |
304 | ispctrl_val |= pdata->bridge << ISPCTRL_PAR_BRIDGE_SHIFT; | 304 | ispctrl_val |= pdata->bridge << ISPCTRL_PAR_BRIDGE_SHIFT; |
305 | shift += pdata->data_lane_shift * 2; | ||
305 | break; | 306 | break; |
306 | 307 | ||
307 | case CCDC_INPUT_CSI2A: | 308 | case CCDC_INPUT_CSI2A: |
@@ -320,6 +321,8 @@ void omap3isp_configure_bridge(struct isp_device *isp, | |||
320 | return; | 321 | return; |
321 | } | 322 | } |
322 | 323 | ||
324 | ispctrl_val |= ((shift/2) << ISPCTRL_SHIFT_SHIFT) & ISPCTRL_SHIFT_MASK; | ||
325 | |||
323 | ispctrl_val &= ~ISPCTRL_SYNC_DETECT_MASK; | 326 | ispctrl_val &= ~ISPCTRL_SYNC_DETECT_MASK; |
324 | ispctrl_val |= ISPCTRL_SYNC_DETECT_VSRISE; | 327 | ispctrl_val |= ISPCTRL_SYNC_DETECT_VSRISE; |
325 | 328 | ||
diff --git a/drivers/media/video/omap3isp/isp.h b/drivers/media/video/omap3isp/isp.h index 00075c621e6b..2620c405f5e4 100644 --- a/drivers/media/video/omap3isp/isp.h +++ b/drivers/media/video/omap3isp/isp.h | |||
@@ -132,7 +132,6 @@ struct isp_reg { | |||
132 | 132 | ||
133 | /** | 133 | /** |
134 | * struct isp_parallel_platform_data - Parallel interface platform data | 134 | * struct isp_parallel_platform_data - Parallel interface platform data |
135 | * @width: Parallel bus width in bits (8, 10, 11 or 12) | ||
136 | * @data_lane_shift: Data lane shifter | 135 | * @data_lane_shift: Data lane shifter |
137 | * 0 - CAMEXT[13:0] -> CAM[13:0] | 136 | * 0 - CAMEXT[13:0] -> CAM[13:0] |
138 | * 1 - CAMEXT[13:2] -> CAM[11:0] | 137 | * 1 - CAMEXT[13:2] -> CAM[11:0] |
@@ -146,7 +145,6 @@ struct isp_reg { | |||
146 | * ISPCTRL_PAR_BRIDGE_BENDIAN - Big endian | 145 | * ISPCTRL_PAR_BRIDGE_BENDIAN - Big endian |
147 | */ | 146 | */ |
148 | struct isp_parallel_platform_data { | 147 | struct isp_parallel_platform_data { |
149 | unsigned int width; | ||
150 | unsigned int data_lane_shift:2; | 148 | unsigned int data_lane_shift:2; |
151 | unsigned int clk_pol:1; | 149 | unsigned int clk_pol:1; |
152 | unsigned int bridge:4; | 150 | unsigned int bridge:4; |
@@ -312,7 +310,8 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe, | |||
312 | enum isp_pipeline_stream_state state); | 310 | enum isp_pipeline_stream_state state); |
313 | void omap3isp_configure_bridge(struct isp_device *isp, | 311 | void omap3isp_configure_bridge(struct isp_device *isp, |
314 | enum ccdc_input_entity input, | 312 | enum ccdc_input_entity input, |
315 | const struct isp_parallel_platform_data *pdata); | 313 | const struct isp_parallel_platform_data *pdata, |
314 | unsigned int shift); | ||
316 | 315 | ||
317 | #define ISP_XCLK_NONE 0 | 316 | #define ISP_XCLK_NONE 0 |
318 | #define ISP_XCLK_A 1 | 317 | #define ISP_XCLK_A 1 |
diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c index 68941ed47194..39d501bda636 100644 --- a/drivers/media/video/omap3isp/ispccdc.c +++ b/drivers/media/video/omap3isp/ispccdc.c | |||
@@ -1116,21 +1116,38 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc) | |||
1116 | struct isp_parallel_platform_data *pdata = NULL; | 1116 | struct isp_parallel_platform_data *pdata = NULL; |
1117 | struct v4l2_subdev *sensor; | 1117 | struct v4l2_subdev *sensor; |
1118 | struct v4l2_mbus_framefmt *format; | 1118 | struct v4l2_mbus_framefmt *format; |
1119 | const struct isp_format_info *fmt_info; | ||
1120 | struct v4l2_subdev_format fmt_src; | ||
1121 | unsigned int depth_out; | ||
1122 | unsigned int depth_in = 0; | ||
1119 | struct media_pad *pad; | 1123 | struct media_pad *pad; |
1120 | unsigned long flags; | 1124 | unsigned long flags; |
1125 | unsigned int shift; | ||
1121 | u32 syn_mode; | 1126 | u32 syn_mode; |
1122 | u32 ccdc_pattern; | 1127 | u32 ccdc_pattern; |
1123 | 1128 | ||
1124 | if (ccdc->input == CCDC_INPUT_PARALLEL) { | 1129 | pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]); |
1125 | pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]); | 1130 | sensor = media_entity_to_v4l2_subdev(pad->entity); |
1126 | sensor = media_entity_to_v4l2_subdev(pad->entity); | 1131 | if (ccdc->input == CCDC_INPUT_PARALLEL) |
1127 | pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv) | 1132 | pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv) |
1128 | ->bus.parallel; | 1133 | ->bus.parallel; |
1134 | |||
1135 | /* Compute shift value for lane shifter to configure the bridge. */ | ||
1136 | fmt_src.pad = pad->index; | ||
1137 | fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE; | ||
1138 | if (!v4l2_subdev_call(sensor, pad, get_fmt, NULL, &fmt_src)) { | ||
1139 | fmt_info = omap3isp_video_format_info(fmt_src.format.code); | ||
1140 | depth_in = fmt_info->bpp; | ||
1129 | } | 1141 | } |
1130 | 1142 | ||
1131 | omap3isp_configure_bridge(isp, ccdc->input, pdata); | 1143 | fmt_info = omap3isp_video_format_info |
1144 | (isp->isp_ccdc.formats[CCDC_PAD_SINK].code); | ||
1145 | depth_out = fmt_info->bpp; | ||
1146 | |||
1147 | shift = depth_in - depth_out; | ||
1148 | omap3isp_configure_bridge(isp, ccdc->input, pdata, shift); | ||
1132 | 1149 | ||
1133 | ccdc->syncif.datsz = pdata ? pdata->width : 10; | 1150 | ccdc->syncif.datsz = depth_out; |
1134 | ccdc_config_sync_if(ccdc, &ccdc->syncif); | 1151 | ccdc_config_sync_if(ccdc, &ccdc->syncif); |
1135 | 1152 | ||
1136 | /* CCDC_PAD_SINK */ | 1153 | /* CCDC_PAD_SINK */ |
diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/video/omap3isp/ispvideo.c index 9ade7359ebca..6e18cee274c7 100644 --- a/drivers/media/video/omap3isp/ispvideo.c +++ b/drivers/media/video/omap3isp/ispvideo.c | |||
@@ -47,41 +47,59 @@ | |||
47 | 47 | ||
48 | static struct isp_format_info formats[] = { | 48 | static struct isp_format_info formats[] = { |
49 | { V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8, | 49 | { V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8, |
50 | V4L2_MBUS_FMT_Y8_1X8, V4L2_PIX_FMT_GREY, 8, }, | 50 | V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8, |
51 | V4L2_PIX_FMT_GREY, 8, }, | ||
51 | { V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y10_1X10, | 52 | { V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y10_1X10, |
52 | V4L2_MBUS_FMT_Y10_1X10, V4L2_PIX_FMT_Y10, 10, }, | 53 | V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y8_1X8, |
54 | V4L2_PIX_FMT_Y10, 10, }, | ||
53 | { V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y10_1X10, | 55 | { V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y10_1X10, |
54 | V4L2_MBUS_FMT_Y12_1X12, V4L2_PIX_FMT_Y12, 12, }, | 56 | V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y8_1X8, |
57 | V4L2_PIX_FMT_Y12, 12, }, | ||
55 | { V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8, | 58 | { V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8, |
56 | V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 8, }, | 59 | V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8, |
60 | V4L2_PIX_FMT_SBGGR8, 8, }, | ||
57 | { V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8, | 61 | { V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8, |
58 | V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG8, 8, }, | 62 | V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8, |
63 | V4L2_PIX_FMT_SGBRG8, 8, }, | ||
59 | { V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8, | 64 | { V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8, |
60 | V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG8, 8, }, | 65 | V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8, |
66 | V4L2_PIX_FMT_SGRBG8, 8, }, | ||
61 | { V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8, | 67 | { V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8, |
62 | V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB8, 8, }, | 68 | V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8, |
69 | V4L2_PIX_FMT_SRGGB8, 8, }, | ||
63 | { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, | 70 | { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, |
64 | V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10DPCM8, 8, }, | 71 | V4L2_MBUS_FMT_SGRBG10_1X10, 0, |
72 | V4L2_PIX_FMT_SGRBG10DPCM8, 8, }, | ||
65 | { V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10, | 73 | { V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10, |
66 | V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10, 10, }, | 74 | V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR8_1X8, |
75 | V4L2_PIX_FMT_SBGGR10, 10, }, | ||
67 | { V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG10_1X10, | 76 | { V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG10_1X10, |
68 | V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10, 10, }, | 77 | V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG8_1X8, |
78 | V4L2_PIX_FMT_SGBRG10, 10, }, | ||
69 | { V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG10_1X10, | 79 | { V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG10_1X10, |
70 | V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10, 10, }, | 80 | V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG8_1X8, |
81 | V4L2_PIX_FMT_SGRBG10, 10, }, | ||
71 | { V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB10_1X10, | 82 | { V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB10_1X10, |
72 | V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10, 10, }, | 83 | V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB8_1X8, |
84 | V4L2_PIX_FMT_SRGGB10, 10, }, | ||
73 | { V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR10_1X10, | 85 | { V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR10_1X10, |
74 | V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12, 12, }, | 86 | V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR8_1X8, |
87 | V4L2_PIX_FMT_SBGGR12, 12, }, | ||
75 | { V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG10_1X10, | 88 | { V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG10_1X10, |
76 | V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12, 12, }, | 89 | V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG8_1X8, |
90 | V4L2_PIX_FMT_SGBRG12, 12, }, | ||
77 | { V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG10_1X10, | 91 | { V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG10_1X10, |
78 | V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12, 12, }, | 92 | V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG8_1X8, |
93 | V4L2_PIX_FMT_SGRBG12, 12, }, | ||
79 | { V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB10_1X10, | 94 | { V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB10_1X10, |
80 | V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12, 12, }, | 95 | V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB8_1X8, |
96 | V4L2_PIX_FMT_SRGGB12, 12, }, | ||
81 | { V4L2_MBUS_FMT_UYVY8_1X16, V4L2_MBUS_FMT_UYVY8_1X16, | 97 | { V4L2_MBUS_FMT_UYVY8_1X16, V4L2_MBUS_FMT_UYVY8_1X16, |
82 | V4L2_MBUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_UYVY, 16, }, | 98 | V4L2_MBUS_FMT_UYVY8_1X16, 0, |
99 | V4L2_PIX_FMT_UYVY, 16, }, | ||
83 | { V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_1X16, | 100 | { V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_1X16, |
84 | V4L2_MBUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_YUYV, 16, }, | 101 | V4L2_MBUS_FMT_YUYV8_1X16, 0, |
102 | V4L2_PIX_FMT_YUYV, 16, }, | ||
85 | }; | 103 | }; |
86 | 104 | ||
87 | const struct isp_format_info * | 105 | const struct isp_format_info * |
@@ -98,6 +116,37 @@ omap3isp_video_format_info(enum v4l2_mbus_pixelcode code) | |||
98 | } | 116 | } |
99 | 117 | ||
100 | /* | 118 | /* |
119 | * Decide whether desired output pixel code can be obtained with | ||
120 | * the lane shifter by shifting the input pixel code. | ||
121 | * @in: input pixelcode to shifter | ||
122 | * @out: output pixelcode from shifter | ||
123 | * @additional_shift: # of bits the sensor's LSB is offset from CAMEXT[0] | ||
124 | * | ||
125 | * return true if the combination is possible | ||
126 | * return false otherwise | ||
127 | */ | ||
128 | static bool isp_video_is_shiftable(enum v4l2_mbus_pixelcode in, | ||
129 | enum v4l2_mbus_pixelcode out, | ||
130 | unsigned int additional_shift) | ||
131 | { | ||
132 | const struct isp_format_info *in_info, *out_info; | ||
133 | |||
134 | if (in == out) | ||
135 | return true; | ||
136 | |||
137 | in_info = omap3isp_video_format_info(in); | ||
138 | out_info = omap3isp_video_format_info(out); | ||
139 | |||
140 | if ((in_info->flavor == 0) || (out_info->flavor == 0)) | ||
141 | return false; | ||
142 | |||
143 | if (in_info->flavor != out_info->flavor) | ||
144 | return false; | ||
145 | |||
146 | return in_info->bpp - out_info->bpp + additional_shift <= 6; | ||
147 | } | ||
148 | |||
149 | /* | ||
101 | * isp_video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format | 150 | * isp_video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format |
102 | * @video: ISP video instance | 151 | * @video: ISP video instance |
103 | * @mbus: v4l2_mbus_framefmt format (input) | 152 | * @mbus: v4l2_mbus_framefmt format (input) |
@@ -247,6 +296,7 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe) | |||
247 | return -EPIPE; | 296 | return -EPIPE; |
248 | 297 | ||
249 | while (1) { | 298 | while (1) { |
299 | unsigned int shifter_link; | ||
250 | /* Retrieve the sink format */ | 300 | /* Retrieve the sink format */ |
251 | pad = &subdev->entity.pads[0]; | 301 | pad = &subdev->entity.pads[0]; |
252 | if (!(pad->flags & MEDIA_PAD_FL_SINK)) | 302 | if (!(pad->flags & MEDIA_PAD_FL_SINK)) |
@@ -275,6 +325,10 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe) | |||
275 | return -ENOSPC; | 325 | return -ENOSPC; |
276 | } | 326 | } |
277 | 327 | ||
328 | /* If sink pad is on CCDC, the link has the lane shifter | ||
329 | * in the middle of it. */ | ||
330 | shifter_link = subdev == &isp->isp_ccdc.subdev; | ||
331 | |||
278 | /* Retrieve the source format */ | 332 | /* Retrieve the source format */ |
279 | pad = media_entity_remote_source(pad); | 333 | pad = media_entity_remote_source(pad); |
280 | if (pad == NULL || | 334 | if (pad == NULL || |
@@ -290,10 +344,24 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe) | |||
290 | return -EPIPE; | 344 | return -EPIPE; |
291 | 345 | ||
292 | /* Check if the two ends match */ | 346 | /* Check if the two ends match */ |
293 | if (fmt_source.format.code != fmt_sink.format.code || | 347 | if (fmt_source.format.width != fmt_sink.format.width || |
294 | fmt_source.format.width != fmt_sink.format.width || | ||
295 | fmt_source.format.height != fmt_sink.format.height) | 348 | fmt_source.format.height != fmt_sink.format.height) |
296 | return -EPIPE; | 349 | return -EPIPE; |
350 | |||
351 | if (shifter_link) { | ||
352 | unsigned int parallel_shift = 0; | ||
353 | if (isp->isp_ccdc.input == CCDC_INPUT_PARALLEL) { | ||
354 | struct isp_parallel_platform_data *pdata = | ||
355 | &((struct isp_v4l2_subdevs_group *) | ||
356 | subdev->host_priv)->bus.parallel; | ||
357 | parallel_shift = pdata->data_lane_shift * 2; | ||
358 | } | ||
359 | if (!isp_video_is_shiftable(fmt_source.format.code, | ||
360 | fmt_sink.format.code, | ||
361 | parallel_shift)) | ||
362 | return -EPIPE; | ||
363 | } else if (fmt_source.format.code != fmt_sink.format.code) | ||
364 | return -EPIPE; | ||
297 | } | 365 | } |
298 | 366 | ||
299 | return 0; | 367 | return 0; |
diff --git a/drivers/media/video/omap3isp/ispvideo.h b/drivers/media/video/omap3isp/ispvideo.h index 524a1acd0906..911bea64e78a 100644 --- a/drivers/media/video/omap3isp/ispvideo.h +++ b/drivers/media/video/omap3isp/ispvideo.h | |||
@@ -49,6 +49,8 @@ struct v4l2_pix_format; | |||
49 | * bits. Identical to @code if the format is 10 bits wide or less. | 49 | * bits. Identical to @code if the format is 10 bits wide or less. |
50 | * @uncompressed: V4L2 media bus format code for the corresponding uncompressed | 50 | * @uncompressed: V4L2 media bus format code for the corresponding uncompressed |
51 | * format. Identical to @code if the format is not DPCM compressed. | 51 | * format. Identical to @code if the format is not DPCM compressed. |
52 | * @flavor: V4L2 media bus format code for the same pixel layout but | ||
53 | * shifted to be 8 bits per pixel. =0 if format is not shiftable. | ||
52 | * @pixelformat: V4L2 pixel format FCC identifier | 54 | * @pixelformat: V4L2 pixel format FCC identifier |
53 | * @bpp: Bits per pixel | 55 | * @bpp: Bits per pixel |
54 | */ | 56 | */ |
@@ -56,6 +58,7 @@ struct isp_format_info { | |||
56 | enum v4l2_mbus_pixelcode code; | 58 | enum v4l2_mbus_pixelcode code; |
57 | enum v4l2_mbus_pixelcode truncated; | 59 | enum v4l2_mbus_pixelcode truncated; |
58 | enum v4l2_mbus_pixelcode uncompressed; | 60 | enum v4l2_mbus_pixelcode uncompressed; |
61 | enum v4l2_mbus_pixelcode flavor; | ||
59 | u32 pixelformat; | 62 | u32 pixelformat; |
60 | unsigned int bpp; | 63 | unsigned int bpp; |
61 | }; | 64 | }; |