aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHelen Koike <helen.koike@collabora.com>2019-08-08 20:27:41 -0400
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2019-08-13 10:40:38 -0400
commit09c41a23a2e2de7ed347251d7079a42de0dd230b (patch)
tree04317b6c35374a578a8df257de210c06c527d71d
parent10b1aed6dac01d566b6b3c261a191546c82f0157 (diff)
media: Revert "media: vimc: propagate pixel format in the stream"
This reverts commit b6c61a6c37317efd7327199bfe24770af3d7e799. The requested pixelformat is being propagated from the capture to the tpg in the sensor. This was a bad design choice, as we start having the following issues: * We set a pixelformat in the capture; * We set matching media bus formats in the subdevices pads; * Link validate looks fine (sizes matches, media bus formats matches); * Issue: if some of the subdevice doesn't know how to generate the requested pixelformat in the capture, then stream_on fails. This is bad because capture says it supports that pixelformat, everything looks fine, but it is not, and there is no way to find it out through the links. This patch was implemented so we could request any pixelformat from the pipeline regardeless of the media bus format configured between pads. Not all pixelformat can be mapped into a media bus code (e.g. multiplanar formats), so with this patch we could request those pixelformats from the tpg. Solution: map pixelformats to media bus codes as before, and implement conversions to other pixelformats in the capture to support multiplanar. So first step to this solution is to revert this patch. Signed-off-by: Helen Koike <helen.koike@collabora.com> Signed-off-by: Lucas A. M. Magalhaes <lucmaga@gmail.com> Tested-by: André Almeida <andrealmeid@collabora.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
-rw-r--r--drivers/media/platform/vimc/vimc-capture.c76
-rw-r--r--drivers/media/platform/vimc/vimc-common.c309
-rw-r--r--drivers/media/platform/vimc/vimc-common.h58
-rw-r--r--drivers/media/platform/vimc/vimc-debayer.c83
-rw-r--r--drivers/media/platform/vimc/vimc-scaler.c63
-rw-r--r--drivers/media/platform/vimc/vimc-sensor.c51
-rw-r--r--drivers/media/platform/vimc/vimc-streamer.c2
-rw-r--r--drivers/media/platform/vimc/vimc-streamer.h8
8 files changed, 342 insertions, 308 deletions
diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c
index 664855708fdf..1d56b91830ba 100644
--- a/drivers/media/platform/vimc/vimc-capture.c
+++ b/drivers/media/platform/vimc/vimc-capture.c
@@ -18,32 +18,6 @@
18 18
19#define VIMC_CAP_DRV_NAME "vimc-capture" 19#define VIMC_CAP_DRV_NAME "vimc-capture"
20 20
21static const u32 vimc_cap_supported_pixfmt[] = {
22 V4L2_PIX_FMT_BGR24,
23 V4L2_PIX_FMT_RGB24,
24 V4L2_PIX_FMT_ARGB32,
25 V4L2_PIX_FMT_SBGGR8,
26 V4L2_PIX_FMT_SGBRG8,
27 V4L2_PIX_FMT_SGRBG8,
28 V4L2_PIX_FMT_SRGGB8,
29 V4L2_PIX_FMT_SBGGR10,
30 V4L2_PIX_FMT_SGBRG10,
31 V4L2_PIX_FMT_SGRBG10,
32 V4L2_PIX_FMT_SRGGB10,
33 V4L2_PIX_FMT_SBGGR10ALAW8,
34 V4L2_PIX_FMT_SGBRG10ALAW8,
35 V4L2_PIX_FMT_SGRBG10ALAW8,
36 V4L2_PIX_FMT_SRGGB10ALAW8,
37 V4L2_PIX_FMT_SBGGR10DPCM8,
38 V4L2_PIX_FMT_SGBRG10DPCM8,
39 V4L2_PIX_FMT_SGRBG10DPCM8,
40 V4L2_PIX_FMT_SRGGB10DPCM8,
41 V4L2_PIX_FMT_SBGGR12,
42 V4L2_PIX_FMT_SGBRG12,
43 V4L2_PIX_FMT_SGRBG12,
44 V4L2_PIX_FMT_SRGGB12,
45};
46
47struct vimc_cap_device { 21struct vimc_cap_device {
48 struct vimc_ent_device ved; 22 struct vimc_ent_device ved;
49 struct video_device vdev; 23 struct video_device vdev;
@@ -117,25 +91,29 @@ static int vimc_cap_try_fmt_vid_cap(struct file *file, void *priv,
117 struct v4l2_format *f) 91 struct v4l2_format *f)
118{ 92{
119 struct v4l2_pix_format *format = &f->fmt.pix; 93 struct v4l2_pix_format *format = &f->fmt.pix;
94 const struct vimc_pix_map *vpix;
120 95
121 format->width = clamp_t(u32, format->width, VIMC_FRAME_MIN_WIDTH, 96 format->width = clamp_t(u32, format->width, VIMC_FRAME_MIN_WIDTH,
122 VIMC_FRAME_MAX_WIDTH) & ~1; 97 VIMC_FRAME_MAX_WIDTH) & ~1;
123 format->height = clamp_t(u32, format->height, VIMC_FRAME_MIN_HEIGHT, 98 format->height = clamp_t(u32, format->height, VIMC_FRAME_MIN_HEIGHT,
124 VIMC_FRAME_MAX_HEIGHT) & ~1; 99 VIMC_FRAME_MAX_HEIGHT) & ~1;
125 100
126 vimc_colorimetry_clamp(format); 101 /* Don't accept a pixelformat that is not on the table */
102 vpix = vimc_pix_map_by_pixelformat(format->pixelformat);
103 if (!vpix) {
104 format->pixelformat = fmt_default.pixelformat;
105 vpix = vimc_pix_map_by_pixelformat(format->pixelformat);
106 }
107 /* TODO: Add support for custom bytesperline values */
108 format->bytesperline = format->width * vpix->bpp;
109 format->sizeimage = format->bytesperline * format->height;
127 110
128 if (format->field == V4L2_FIELD_ANY) 111 if (format->field == V4L2_FIELD_ANY)
129 format->field = fmt_default.field; 112 format->field = fmt_default.field;
130 113
131 /* TODO: Add support for custom bytesperline values */ 114 vimc_colorimetry_clamp(format);
132
133 /* Don't accept a pixelformat that is not on the table */
134 if (!v4l2_format_info(format->pixelformat))
135 format->pixelformat = fmt_default.pixelformat;
136 115
137 return v4l2_fill_pixfmt(format, format->pixelformat, 116 return 0;
138 format->width, format->height);
139} 117}
140 118
141static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv, 119static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv,
@@ -174,31 +152,27 @@ static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv,
174static int vimc_cap_enum_fmt_vid_cap(struct file *file, void *priv, 152static int vimc_cap_enum_fmt_vid_cap(struct file *file, void *priv,
175 struct v4l2_fmtdesc *f) 153 struct v4l2_fmtdesc *f)
176{ 154{
177 if (f->index >= ARRAY_SIZE(vimc_cap_supported_pixfmt)) 155 const struct vimc_pix_map *vpix = vimc_pix_map_by_index(f->index);
156
157 if (!vpix)
178 return -EINVAL; 158 return -EINVAL;
179 159
180 f->pixelformat = vimc_cap_supported_pixfmt[f->index]; 160 f->pixelformat = vpix->pixelformat;
181 161
182 return 0; 162 return 0;
183} 163}
184 164
185static bool vimc_cap_is_pixfmt_supported(u32 pixelformat)
186{
187 unsigned int i;
188
189 for (i = 0; i < ARRAY_SIZE(vimc_cap_supported_pixfmt); i++)
190 if (vimc_cap_supported_pixfmt[i] == pixelformat)
191 return true;
192 return false;
193}
194
195static int vimc_cap_enum_framesizes(struct file *file, void *fh, 165static int vimc_cap_enum_framesizes(struct file *file, void *fh,
196 struct v4l2_frmsizeenum *fsize) 166 struct v4l2_frmsizeenum *fsize)
197{ 167{
168 const struct vimc_pix_map *vpix;
169
198 if (fsize->index) 170 if (fsize->index)
199 return -EINVAL; 171 return -EINVAL;
200 172
201 if (!vimc_cap_is_pixfmt_supported(fsize->pixel_format)) 173 /* Only accept code in the pix map table */
174 vpix = vimc_pix_map_by_code(fsize->pixel_format);
175 if (!vpix)
202 return -EINVAL; 176 return -EINVAL;
203 177
204 fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; 178 fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
@@ -272,7 +246,6 @@ static int vimc_cap_start_streaming(struct vb2_queue *vq, unsigned int count)
272 return ret; 246 return ret;
273 } 247 }
274 248
275 vcap->stream.producer_pixfmt = vcap->format.pixelformat;
276 ret = vimc_streamer_s_stream(&vcap->stream, &vcap->ved, 1); 249 ret = vimc_streamer_s_stream(&vcap->stream, &vcap->ved, 1);
277 if (ret) { 250 if (ret) {
278 media_pipeline_stop(entity); 251 media_pipeline_stop(entity);
@@ -423,6 +396,7 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master,
423{ 396{
424 struct v4l2_device *v4l2_dev = master_data; 397 struct v4l2_device *v4l2_dev = master_data;
425 struct vimc_platform_data *pdata = comp->platform_data; 398 struct vimc_platform_data *pdata = comp->platform_data;
399 const struct vimc_pix_map *vpix;
426 struct vimc_cap_device *vcap; 400 struct vimc_cap_device *vcap;
427 struct video_device *vdev; 401 struct video_device *vdev;
428 struct vb2_queue *q; 402 struct vb2_queue *q;
@@ -477,8 +451,10 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master,
477 451
478 /* Set default frame format */ 452 /* Set default frame format */
479 vcap->format = fmt_default; 453 vcap->format = fmt_default;
480 v4l2_fill_pixfmt(&vcap->format, vcap->format.pixelformat, 454 vpix = vimc_pix_map_by_pixelformat(vcap->format.pixelformat);
481 vcap->format.width, vcap->format.height); 455 vcap->format.bytesperline = vcap->format.width * vpix->bpp;
456 vcap->format.sizeimage = vcap->format.bytesperline *
457 vcap->format.height;
482 458
483 /* Fill the vimc_ent_device struct */ 459 /* Fill the vimc_ent_device struct */
484 vcap->ved.ent = &vcap->vdev.entity; 460 vcap->ved.ent = &vcap->vdev.entity;
diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c
index 03016f204d05..7e1ae0b12f1e 100644
--- a/drivers/media/platform/vimc/vimc-common.c
+++ b/drivers/media/platform/vimc/vimc-common.c
@@ -10,139 +10,192 @@
10 10
11#include "vimc-common.h" 11#include "vimc-common.h"
12 12
13static const __u32 vimc_mbus_list[] = { 13/*
14 MEDIA_BUS_FMT_FIXED, 14 * NOTE: non-bayer formats need to come first (necessary for enum_mbus_code
15 MEDIA_BUS_FMT_RGB444_1X12, 15 * in the scaler)
16 MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, 16 */
17 MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, 17static const struct vimc_pix_map vimc_pix_map_list[] = {
18 MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, 18 /* TODO: add all missing formats */
19 MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, 19
20 MEDIA_BUS_FMT_RGB565_1X16, 20 /* RGB formats */
21 MEDIA_BUS_FMT_BGR565_2X8_BE, 21 {
22 MEDIA_BUS_FMT_BGR565_2X8_LE, 22 .code = MEDIA_BUS_FMT_BGR888_1X24,
23 MEDIA_BUS_FMT_RGB565_2X8_BE, 23 .pixelformat = V4L2_PIX_FMT_BGR24,
24 MEDIA_BUS_FMT_RGB565_2X8_LE, 24 .bpp = 3,
25 MEDIA_BUS_FMT_RGB666_1X18, 25 .bayer = false,
26 MEDIA_BUS_FMT_RBG888_1X24, 26 },
27 MEDIA_BUS_FMT_RGB666_1X24_CPADHI, 27 {
28 MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, 28 .code = MEDIA_BUS_FMT_RGB888_1X24,
29 MEDIA_BUS_FMT_BGR888_1X24, 29 .pixelformat = V4L2_PIX_FMT_RGB24,
30 MEDIA_BUS_FMT_GBR888_1X24, 30 .bpp = 3,
31 MEDIA_BUS_FMT_RGB888_1X24, 31 .bayer = false,
32 MEDIA_BUS_FMT_RGB888_2X12_BE, 32 },
33 MEDIA_BUS_FMT_RGB888_2X12_LE, 33 {
34 MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, 34 .code = MEDIA_BUS_FMT_ARGB8888_1X32,
35 MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, 35 .pixelformat = V4L2_PIX_FMT_ARGB32,
36 MEDIA_BUS_FMT_ARGB8888_1X32, 36 .bpp = 4,
37 MEDIA_BUS_FMT_RGB888_1X32_PADHI, 37 .bayer = false,
38 MEDIA_BUS_FMT_RGB101010_1X30, 38 },
39 MEDIA_BUS_FMT_RGB121212_1X36, 39
40 MEDIA_BUS_FMT_RGB161616_1X48, 40 /* Bayer formats */
41 MEDIA_BUS_FMT_Y8_1X8, 41 {
42 MEDIA_BUS_FMT_UV8_1X8, 42 .code = MEDIA_BUS_FMT_SBGGR8_1X8,
43 MEDIA_BUS_FMT_UYVY8_1_5X8, 43 .pixelformat = V4L2_PIX_FMT_SBGGR8,
44 MEDIA_BUS_FMT_VYUY8_1_5X8, 44 .bpp = 1,
45 MEDIA_BUS_FMT_YUYV8_1_5X8, 45 .bayer = true,
46 MEDIA_BUS_FMT_YVYU8_1_5X8, 46 },
47 MEDIA_BUS_FMT_UYVY8_2X8, 47 {
48 MEDIA_BUS_FMT_VYUY8_2X8, 48 .code = MEDIA_BUS_FMT_SGBRG8_1X8,
49 MEDIA_BUS_FMT_YUYV8_2X8, 49 .pixelformat = V4L2_PIX_FMT_SGBRG8,
50 MEDIA_BUS_FMT_YVYU8_2X8, 50 .bpp = 1,
51 MEDIA_BUS_FMT_Y10_1X10, 51 .bayer = true,
52 MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 52 },
53 MEDIA_BUS_FMT_UYVY10_2X10, 53 {
54 MEDIA_BUS_FMT_VYUY10_2X10, 54 .code = MEDIA_BUS_FMT_SGRBG8_1X8,
55 MEDIA_BUS_FMT_YUYV10_2X10, 55 .pixelformat = V4L2_PIX_FMT_SGRBG8,
56 MEDIA_BUS_FMT_YVYU10_2X10, 56 .bpp = 1,
57 MEDIA_BUS_FMT_Y12_1X12, 57 .bayer = true,
58 MEDIA_BUS_FMT_UYVY12_2X12, 58 },
59 MEDIA_BUS_FMT_VYUY12_2X12, 59 {
60 MEDIA_BUS_FMT_YUYV12_2X12, 60 .code = MEDIA_BUS_FMT_SRGGB8_1X8,
61 MEDIA_BUS_FMT_YVYU12_2X12, 61 .pixelformat = V4L2_PIX_FMT_SRGGB8,
62 MEDIA_BUS_FMT_UYVY8_1X16, 62 .bpp = 1,
63 MEDIA_BUS_FMT_VYUY8_1X16, 63 .bayer = true,
64 MEDIA_BUS_FMT_YUYV8_1X16, 64 },
65 MEDIA_BUS_FMT_YVYU8_1X16, 65 {
66 MEDIA_BUS_FMT_YDYUYDYV8_1X16, 66 .code = MEDIA_BUS_FMT_SBGGR10_1X10,
67 MEDIA_BUS_FMT_UYVY10_1X20, 67 .pixelformat = V4L2_PIX_FMT_SBGGR10,
68 MEDIA_BUS_FMT_VYUY10_1X20, 68 .bpp = 2,
69 MEDIA_BUS_FMT_YUYV10_1X20, 69 .bayer = true,
70 MEDIA_BUS_FMT_YVYU10_1X20, 70 },
71 MEDIA_BUS_FMT_VUY8_1X24, 71 {
72 MEDIA_BUS_FMT_YUV8_1X24, 72 .code = MEDIA_BUS_FMT_SGBRG10_1X10,
73 MEDIA_BUS_FMT_UYYVYY8_0_5X24, 73 .pixelformat = V4L2_PIX_FMT_SGBRG10,
74 MEDIA_BUS_FMT_UYVY12_1X24, 74 .bpp = 2,
75 MEDIA_BUS_FMT_VYUY12_1X24, 75 .bayer = true,
76 MEDIA_BUS_FMT_YUYV12_1X24, 76 },
77 MEDIA_BUS_FMT_YVYU12_1X24, 77 {
78 MEDIA_BUS_FMT_YUV10_1X30, 78 .code = MEDIA_BUS_FMT_SGRBG10_1X10,
79 MEDIA_BUS_FMT_UYYVYY10_0_5X30, 79 .pixelformat = V4L2_PIX_FMT_SGRBG10,
80 MEDIA_BUS_FMT_AYUV8_1X32, 80 .bpp = 2,
81 MEDIA_BUS_FMT_UYYVYY12_0_5X36, 81 .bayer = true,
82 MEDIA_BUS_FMT_YUV12_1X36, 82 },
83 MEDIA_BUS_FMT_YUV16_1X48, 83 {
84 MEDIA_BUS_FMT_UYYVYY16_0_5X48, 84 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
85 MEDIA_BUS_FMT_SBGGR8_1X8, 85 .pixelformat = V4L2_PIX_FMT_SRGGB10,
86 MEDIA_BUS_FMT_SGBRG8_1X8, 86 .bpp = 2,
87 MEDIA_BUS_FMT_SGRBG8_1X8, 87 .bayer = true,
88 MEDIA_BUS_FMT_SRGGB8_1X8, 88 },
89 MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8, 89
90 MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8, 90 /* 10bit raw bayer a-law compressed to 8 bits */
91 MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, 91 {
92 MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8, 92 .code = MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8,
93 MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, 93 .pixelformat = V4L2_PIX_FMT_SBGGR10ALAW8,
94 MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, 94 .bpp = 1,
95 MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, 95 .bayer = true,
96 MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, 96 },
97 MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, 97 {
98 MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, 98 .code = MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8,
99 MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, 99 .pixelformat = V4L2_PIX_FMT_SGBRG10ALAW8,
100 MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, 100 .bpp = 1,
101 MEDIA_BUS_FMT_SBGGR10_1X10, 101 .bayer = true,
102 MEDIA_BUS_FMT_SGBRG10_1X10, 102 },
103 MEDIA_BUS_FMT_SGRBG10_1X10, 103 {
104 MEDIA_BUS_FMT_SRGGB10_1X10, 104 .code = MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8,
105 MEDIA_BUS_FMT_SBGGR12_1X12, 105 .pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8,
106 MEDIA_BUS_FMT_SGBRG12_1X12, 106 .bpp = 1,
107 MEDIA_BUS_FMT_SGRBG12_1X12, 107 .bayer = true,
108 MEDIA_BUS_FMT_SRGGB12_1X12, 108 },
109 MEDIA_BUS_FMT_SBGGR14_1X14, 109 {
110 MEDIA_BUS_FMT_SGBRG14_1X14, 110 .code = MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8,
111 MEDIA_BUS_FMT_SGRBG14_1X14, 111 .pixelformat = V4L2_PIX_FMT_SRGGB10ALAW8,
112 MEDIA_BUS_FMT_SRGGB14_1X14, 112 .bpp = 1,
113 MEDIA_BUS_FMT_SBGGR16_1X16, 113 .bayer = true,
114 MEDIA_BUS_FMT_SGBRG16_1X16, 114 },
115 MEDIA_BUS_FMT_SGRBG16_1X16, 115
116 MEDIA_BUS_FMT_SRGGB16_1X16, 116 /* 10bit raw bayer DPCM compressed to 8 bits */
117 MEDIA_BUS_FMT_JPEG_1X8, 117 {
118 MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8, 118 .code = MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8,
119 MEDIA_BUS_FMT_AHSV8888_1X32, 119 .pixelformat = V4L2_PIX_FMT_SBGGR10DPCM8,
120 .bpp = 1,
121 .bayer = true,
122 },
123 {
124 .code = MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8,
125 .pixelformat = V4L2_PIX_FMT_SGBRG10DPCM8,
126 .bpp = 1,
127 .bayer = true,
128 },
129 {
130 .code = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
131 .pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
132 .bpp = 1,
133 .bayer = true,
134 },
135 {
136 .code = MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8,
137 .pixelformat = V4L2_PIX_FMT_SRGGB10DPCM8,
138 .bpp = 1,
139 .bayer = true,
140 },
141 {
142 .code = MEDIA_BUS_FMT_SBGGR12_1X12,
143 .pixelformat = V4L2_PIX_FMT_SBGGR12,
144 .bpp = 2,
145 .bayer = true,
146 },
147 {
148 .code = MEDIA_BUS_FMT_SGBRG12_1X12,
149 .pixelformat = V4L2_PIX_FMT_SGBRG12,
150 .bpp = 2,
151 .bayer = true,
152 },
153 {
154 .code = MEDIA_BUS_FMT_SGRBG12_1X12,
155 .pixelformat = V4L2_PIX_FMT_SGRBG12,
156 .bpp = 2,
157 .bayer = true,
158 },
159 {
160 .code = MEDIA_BUS_FMT_SRGGB12_1X12,
161 .pixelformat = V4L2_PIX_FMT_SRGGB12,
162 .bpp = 2,
163 .bayer = true,
164 },
120}; 165};
121 166
122/* Helper function to check mbus codes */ 167const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i)
123bool vimc_mbus_code_supported(__u32 code) 168{
169 if (i >= ARRAY_SIZE(vimc_pix_map_list))
170 return NULL;
171
172 return &vimc_pix_map_list[i];
173}
174EXPORT_SYMBOL_GPL(vimc_pix_map_by_index);
175
176const struct vimc_pix_map *vimc_pix_map_by_code(u32 code)
124{ 177{
125 unsigned int i; 178 unsigned int i;
126 179
127 for (i = 0; i < ARRAY_SIZE(vimc_mbus_list); i++) 180 for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) {
128 if (code == vimc_mbus_list[i]) 181 if (vimc_pix_map_list[i].code == code)
129 return true; 182 return &vimc_pix_map_list[i];
130 return false; 183 }
184 return NULL;
131} 185}
132EXPORT_SYMBOL_GPL(vimc_mbus_code_supported); 186EXPORT_SYMBOL_GPL(vimc_pix_map_by_code);
133 187
134/* Helper function to enumerate mbus codes */ 188const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat)
135int vimc_enum_mbus_code(struct v4l2_subdev *sd,
136 struct v4l2_subdev_pad_config *cfg,
137 struct v4l2_subdev_mbus_code_enum *code)
138{ 189{
139 if (code->index >= ARRAY_SIZE(vimc_mbus_list)) 190 unsigned int i;
140 return -EINVAL;
141 191
142 code->code = vimc_mbus_list[code->index]; 192 for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) {
143 return 0; 193 if (vimc_pix_map_list[i].pixelformat == pixelformat)
194 return &vimc_pix_map_list[i];
195 }
196 return NULL;
144} 197}
145EXPORT_SYMBOL_GPL(vimc_enum_mbus_code); 198EXPORT_SYMBOL_GPL(vimc_pix_map_by_pixelformat);
146 199
147/* Helper function to allocate and initialize pads */ 200/* Helper function to allocate and initialize pads */
148struct media_pad *vimc_pads_init(u16 num_pads, const unsigned long *pads_flag) 201struct media_pad *vimc_pads_init(u16 num_pads, const unsigned long *pads_flag)
@@ -214,13 +267,15 @@ static int vimc_get_mbus_format(struct media_pad *pad,
214 struct video_device, 267 struct video_device,
215 entity); 268 entity);
216 struct vimc_ent_device *ved = video_get_drvdata(vdev); 269 struct vimc_ent_device *ved = video_get_drvdata(vdev);
270 const struct vimc_pix_map *vpix;
217 struct v4l2_pix_format vdev_fmt; 271 struct v4l2_pix_format vdev_fmt;
218 272
219 if (!ved->vdev_get_format) 273 if (!ved->vdev_get_format)
220 return -ENOIOCTLCMD; 274 return -ENOIOCTLCMD;
221 275
222 ved->vdev_get_format(ved, &vdev_fmt); 276 ved->vdev_get_format(ved, &vdev_fmt);
223 v4l2_fill_mbus_format(&fmt->format, &vdev_fmt, 0); 277 vpix = vimc_pix_map_by_pixelformat(vdev_fmt.pixelformat);
278 v4l2_fill_mbus_format(&fmt->format, &vdev_fmt, vpix->code);
224 } else { 279 } else {
225 return -EINVAL; 280 return -EINVAL;
226 } 281 }
@@ -260,12 +315,8 @@ int vimc_link_validate(struct media_link *link)
260 /* The width, height and code must match. */ 315 /* The width, height and code must match. */
261 if (source_fmt.format.width != sink_fmt.format.width 316 if (source_fmt.format.width != sink_fmt.format.width
262 || source_fmt.format.height != sink_fmt.format.height 317 || source_fmt.format.height != sink_fmt.format.height
263 || (source_fmt.format.code && sink_fmt.format.code && 318 || source_fmt.format.code != sink_fmt.format.code)
264 source_fmt.format.code != sink_fmt.format.code)) {
265 pr_err("vimc: format doesn't match in link %s->%s\n",
266 link->source->entity->name, link->sink->entity->name);
267 return -EPIPE; 319 return -EPIPE;
268 }
269 320
270 /* 321 /*
271 * The field order must match, or the sink field order must be NONE 322 * The field order must match, or the sink field order must be NONE
diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h
index 7b4d988b208b..9c2e0e216c6b 100644
--- a/drivers/media/platform/vimc/vimc-common.h
+++ b/drivers/media/platform/vimc/vimc-common.h
@@ -12,8 +12,6 @@
12#include <media/media-device.h> 12#include <media/media-device.h>
13#include <media/v4l2-device.h> 13#include <media/v4l2-device.h>
14 14
15#include "vimc-streamer.h"
16
17#define VIMC_PDEV_NAME "vimc" 15#define VIMC_PDEV_NAME "vimc"
18 16
19/* VIMC-specific controls */ 17/* VIMC-specific controls */
@@ -70,6 +68,23 @@ struct vimc_platform_data {
70}; 68};
71 69
72/** 70/**
71 * struct vimc_pix_map - maps media bus code with v4l2 pixel format
72 *
73 * @code: media bus format code defined by MEDIA_BUS_FMT_* macros
74 * @bbp: number of bytes each pixel occupies
75 * @pixelformat: pixel format devined by V4L2_PIX_FMT_* macros
76 *
77 * Struct which matches the MEDIA_BUS_FMT_* codes with the corresponding
78 * V4L2_PIX_FMT_* fourcc pixelformat and its bytes per pixel (bpp)
79 */
80struct vimc_pix_map {
81 unsigned int code;
82 unsigned int bpp;
83 u32 pixelformat;
84 bool bayer;
85};
86
87/**
73 * struct vimc_ent_device - core struct that represents a node in the topology 88 * struct vimc_ent_device - core struct that represents a node in the topology
74 * 89 *
75 * @ent: the pointer to struct media_entity for the node 90 * @ent: the pointer to struct media_entity for the node
@@ -90,7 +105,6 @@ struct vimc_platform_data {
90struct vimc_ent_device { 105struct vimc_ent_device {
91 struct media_entity *ent; 106 struct media_entity *ent;
92 struct media_pad *pads; 107 struct media_pad *pads;
93 struct vimc_stream *stream;
94 void * (*process_frame)(struct vimc_ent_device *ved, 108 void * (*process_frame)(struct vimc_ent_device *ved,
95 const void *frame); 109 const void *frame);
96 void (*vdev_get_format)(struct vimc_ent_device *ved, 110 void (*vdev_get_format)(struct vimc_ent_device *ved,
@@ -98,23 +112,6 @@ struct vimc_ent_device {
98}; 112};
99 113
100/** 114/**
101 * vimc_mbus_code_supported - helper to check supported mbus codes
102 *
103 * Helper function to check if mbus code is enumerated by vimc_enum_mbus_code()
104 */
105bool vimc_mbus_code_supported(__u32 code);
106
107/**
108 * vimc_enum_mbus_code - enumerate mbus codes
109 *
110 * Helper function to be pluged in .enum_mbus_code from
111 * struct v4l2_subdev_pad_ops.
112 */
113int vimc_enum_mbus_code(struct v4l2_subdev *sd,
114 struct v4l2_subdev_pad_config *cfg,
115 struct v4l2_subdev_mbus_code_enum *code);
116
117/**
118 * vimc_pads_init - initialize pads 115 * vimc_pads_init - initialize pads
119 * 116 *
120 * @num_pads: number of pads to initialize 117 * @num_pads: number of pads to initialize
@@ -149,6 +146,27 @@ static inline void vimc_pads_cleanup(struct media_pad *pads)
149int vimc_pipeline_s_stream(struct media_entity *ent, int enable); 146int vimc_pipeline_s_stream(struct media_entity *ent, int enable);
150 147
151/** 148/**
149 * vimc_pix_map_by_index - get vimc_pix_map struct by its index
150 *
151 * @i: index of the vimc_pix_map struct in vimc_pix_map_list
152 */
153const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i);
154
155/**
156 * vimc_pix_map_by_code - get vimc_pix_map struct by media bus code
157 *
158 * @code: media bus format code defined by MEDIA_BUS_FMT_* macros
159 */
160const struct vimc_pix_map *vimc_pix_map_by_code(u32 code);
161
162/**
163 * vimc_pix_map_by_pixelformat - get vimc_pix_map struct by v4l2 pixel format
164 *
165 * @pixelformat: pixel format devined by V4L2_PIX_FMT_* macros
166 */
167const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat);
168
169/**
152 * vimc_ent_sd_register - initialize and register a subdev node 170 * vimc_ent_sd_register - initialize and register a subdev node
153 * 171 *
154 * @ved: the vimc_ent_device struct to be initialize 172 * @ved: the vimc_ent_device struct to be initialize
diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c
index 72adba6cf892..b72b8385067b 100644
--- a/drivers/media/platform/vimc/vimc-debayer.c
+++ b/drivers/media/platform/vimc/vimc-debayer.c
@@ -16,11 +16,6 @@
16#include "vimc-common.h" 16#include "vimc-common.h"
17 17
18#define VIMC_DEB_DRV_NAME "vimc-debayer" 18#define VIMC_DEB_DRV_NAME "vimc-debayer"
19/* This module only supports transforming a bayer format
20 * to V4L2_PIX_FMT_RGB24
21 */
22#define VIMC_DEB_SRC_PIXFMT V4L2_PIX_FMT_RGB24
23#define VIMC_DEB_SRC_MBUS_FMT_DEFAULT MEDIA_BUS_FMT_RGB888_1X24
24 19
25static unsigned int deb_mean_win_size = 3; 20static unsigned int deb_mean_win_size = 3;
26module_param(deb_mean_win_size, uint, 0000); 21module_param(deb_mean_win_size, uint, 0000);
@@ -39,7 +34,6 @@ enum vimc_deb_rgb_colors {
39}; 34};
40 35
41struct vimc_deb_pix_map { 36struct vimc_deb_pix_map {
42 u32 pixelformat;
43 u32 code; 37 u32 code;
44 enum vimc_deb_rgb_colors order[2][2]; 38 enum vimc_deb_rgb_colors order[2][2];
45}; 39};
@@ -69,73 +63,61 @@ static const struct v4l2_mbus_framefmt sink_fmt_default = {
69 63
70static const struct vimc_deb_pix_map vimc_deb_pix_map_list[] = { 64static const struct vimc_deb_pix_map vimc_deb_pix_map_list[] = {
71 { 65 {
72 .pixelformat = V4L2_PIX_FMT_SBGGR8,
73 .code = MEDIA_BUS_FMT_SBGGR8_1X8, 66 .code = MEDIA_BUS_FMT_SBGGR8_1X8,
74 .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN }, 67 .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
75 { VIMC_DEB_GREEN, VIMC_DEB_RED } } 68 { VIMC_DEB_GREEN, VIMC_DEB_RED } }
76 }, 69 },
77 { 70 {
78 .pixelformat = V4L2_PIX_FMT_SGBRG8,
79 .code = MEDIA_BUS_FMT_SGBRG8_1X8, 71 .code = MEDIA_BUS_FMT_SGBRG8_1X8,
80 .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE }, 72 .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
81 { VIMC_DEB_RED, VIMC_DEB_GREEN } } 73 { VIMC_DEB_RED, VIMC_DEB_GREEN } }
82 }, 74 },
83 { 75 {
84 .pixelformat = V4L2_PIX_FMT_SGRBG8,
85 .code = MEDIA_BUS_FMT_SGRBG8_1X8, 76 .code = MEDIA_BUS_FMT_SGRBG8_1X8,
86 .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED }, 77 .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
87 { VIMC_DEB_BLUE, VIMC_DEB_GREEN } } 78 { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
88 }, 79 },
89 { 80 {
90 .pixelformat = V4L2_PIX_FMT_SRGGB8,
91 .code = MEDIA_BUS_FMT_SRGGB8_1X8, 81 .code = MEDIA_BUS_FMT_SRGGB8_1X8,
92 .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN }, 82 .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
93 { VIMC_DEB_GREEN, VIMC_DEB_BLUE } } 83 { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
94 }, 84 },
95 { 85 {
96 .pixelformat = V4L2_PIX_FMT_SBGGR10,
97 .code = MEDIA_BUS_FMT_SBGGR10_1X10, 86 .code = MEDIA_BUS_FMT_SBGGR10_1X10,
98 .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN }, 87 .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
99 { VIMC_DEB_GREEN, VIMC_DEB_RED } } 88 { VIMC_DEB_GREEN, VIMC_DEB_RED } }
100 }, 89 },
101 { 90 {
102 .pixelformat = V4L2_PIX_FMT_SGBRG10,
103 .code = MEDIA_BUS_FMT_SGBRG10_1X10, 91 .code = MEDIA_BUS_FMT_SGBRG10_1X10,
104 .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE }, 92 .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
105 { VIMC_DEB_RED, VIMC_DEB_GREEN } } 93 { VIMC_DEB_RED, VIMC_DEB_GREEN } }
106 }, 94 },
107 { 95 {
108 .pixelformat = V4L2_PIX_FMT_SGRBG10,
109 .code = MEDIA_BUS_FMT_SGRBG10_1X10, 96 .code = MEDIA_BUS_FMT_SGRBG10_1X10,
110 .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED }, 97 .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
111 { VIMC_DEB_BLUE, VIMC_DEB_GREEN } } 98 { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
112 }, 99 },
113 { 100 {
114 .pixelformat = V4L2_PIX_FMT_SRGGB10,
115 .code = MEDIA_BUS_FMT_SRGGB10_1X10, 101 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
116 .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN }, 102 .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
117 { VIMC_DEB_GREEN, VIMC_DEB_BLUE } } 103 { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
118 }, 104 },
119 { 105 {
120 .pixelformat = V4L2_PIX_FMT_SBGGR12,
121 .code = MEDIA_BUS_FMT_SBGGR12_1X12, 106 .code = MEDIA_BUS_FMT_SBGGR12_1X12,
122 .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN }, 107 .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
123 { VIMC_DEB_GREEN, VIMC_DEB_RED } } 108 { VIMC_DEB_GREEN, VIMC_DEB_RED } }
124 }, 109 },
125 { 110 {
126 .pixelformat = V4L2_PIX_FMT_SGBRG12,
127 .code = MEDIA_BUS_FMT_SGBRG12_1X12, 111 .code = MEDIA_BUS_FMT_SGBRG12_1X12,
128 .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE }, 112 .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
129 { VIMC_DEB_RED, VIMC_DEB_GREEN } } 113 { VIMC_DEB_RED, VIMC_DEB_GREEN } }
130 }, 114 },
131 { 115 {
132 .pixelformat = V4L2_PIX_FMT_SGRBG12,
133 .code = MEDIA_BUS_FMT_SGRBG12_1X12, 116 .code = MEDIA_BUS_FMT_SGRBG12_1X12,
134 .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED }, 117 .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
135 { VIMC_DEB_BLUE, VIMC_DEB_GREEN } } 118 { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
136 }, 119 },
137 { 120 {
138 .pixelformat = V4L2_PIX_FMT_SRGGB12,
139 .code = MEDIA_BUS_FMT_SRGGB12_1X12, 121 .code = MEDIA_BUS_FMT_SRGGB12_1X12,
140 .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN }, 122 .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
141 { VIMC_DEB_GREEN, VIMC_DEB_BLUE } } 123 { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
@@ -176,32 +158,41 @@ static int vimc_deb_enum_mbus_code(struct v4l2_subdev *sd,
176 struct v4l2_subdev_pad_config *cfg, 158 struct v4l2_subdev_pad_config *cfg,
177 struct v4l2_subdev_mbus_code_enum *code) 159 struct v4l2_subdev_mbus_code_enum *code)
178{ 160{
179 /* For the sink pad we only support codes in the map_list */ 161 /* We only support one format for source pads */
180 if (IS_SINK(code->pad)) { 162 if (IS_SRC(code->pad)) {
163 struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
164
165 if (code->index)
166 return -EINVAL;
167
168 code->code = vdeb->src_code;
169 } else {
181 if (code->index >= ARRAY_SIZE(vimc_deb_pix_map_list)) 170 if (code->index >= ARRAY_SIZE(vimc_deb_pix_map_list))
182 return -EINVAL; 171 return -EINVAL;
183 172
184 code->code = vimc_deb_pix_map_list[code->index].code; 173 code->code = vimc_deb_pix_map_list[code->index].code;
185 return 0;
186 } 174 }
187 175
188 return vimc_enum_mbus_code(sd, cfg, code); 176 return 0;
189} 177}
190 178
191static int vimc_deb_enum_frame_size(struct v4l2_subdev *sd, 179static int vimc_deb_enum_frame_size(struct v4l2_subdev *sd,
192 struct v4l2_subdev_pad_config *cfg, 180 struct v4l2_subdev_pad_config *cfg,
193 struct v4l2_subdev_frame_size_enum *fse) 181 struct v4l2_subdev_frame_size_enum *fse)
194{ 182{
183 struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
184
195 if (fse->index) 185 if (fse->index)
196 return -EINVAL; 186 return -EINVAL;
197 187
198 /* For the sink pad we only support codes in the map_list */
199 if (IS_SINK(fse->pad)) { 188 if (IS_SINK(fse->pad)) {
200 const struct vimc_deb_pix_map *vpix = 189 const struct vimc_deb_pix_map *vpix =
201 vimc_deb_pix_map_by_code(fse->code); 190 vimc_deb_pix_map_by_code(fse->code);
202 191
203 if (!vpix) 192 if (!vpix)
204 return -EINVAL; 193 return -EINVAL;
194 } else if (fse->code != vdeb->src_code) {
195 return -EINVAL;
205 } 196 }
206 197
207 fse->min_width = VIMC_FRAME_MIN_WIDTH; 198 fse->min_width = VIMC_FRAME_MIN_WIDTH;
@@ -257,9 +248,6 @@ static int vimc_deb_set_fmt(struct v4l2_subdev *sd,
257 struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd); 248 struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
258 struct v4l2_mbus_framefmt *sink_fmt; 249 struct v4l2_mbus_framefmt *sink_fmt;
259 250
260 if (!vimc_mbus_code_supported(fmt->format.code))
261 fmt->format.code = sink_fmt_default.code;
262
263 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { 251 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
264 /* Do not change the format while stream is on */ 252 /* Do not change the format while stream is on */
265 if (vdeb->src_frame) 253 if (vdeb->src_frame)
@@ -272,11 +260,11 @@ static int vimc_deb_set_fmt(struct v4l2_subdev *sd,
272 260
273 /* 261 /*
274 * Do not change the format of the source pad, 262 * Do not change the format of the source pad,
275 * it is propagated from the sink (except for the code) 263 * it is propagated from the sink
276 */ 264 */
277 if (IS_SRC(fmt->pad)) { 265 if (IS_SRC(fmt->pad)) {
278 vdeb->src_code = fmt->format.code;
279 fmt->format = *sink_fmt; 266 fmt->format = *sink_fmt;
267 /* TODO: Add support for other formats */
280 fmt->format.code = vdeb->src_code; 268 fmt->format.code = vdeb->src_code;
281 } else { 269 } else {
282 /* Set the new format in the sink pad */ 270 /* Set the new format in the sink pad */
@@ -308,7 +296,7 @@ static const struct v4l2_subdev_pad_ops vimc_deb_pad_ops = {
308 .set_fmt = vimc_deb_set_fmt, 296 .set_fmt = vimc_deb_set_fmt,
309}; 297};
310 298
311static void vimc_deb_set_rgb_pix_rgb24(struct vimc_deb_device *vdeb, 299static void vimc_deb_set_rgb_mbus_fmt_rgb888_1x24(struct vimc_deb_device *vdeb,
312 unsigned int lin, 300 unsigned int lin,
313 unsigned int col, 301 unsigned int col,
314 unsigned int rgb[3]) 302 unsigned int rgb[3])
@@ -325,38 +313,25 @@ static int vimc_deb_s_stream(struct v4l2_subdev *sd, int enable)
325 struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd); 313 struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
326 314
327 if (enable) { 315 if (enable) {
328 u32 src_pixelformat = vdeb->ved.stream->producer_pixfmt; 316 const struct vimc_pix_map *vpix;
329 const struct v4l2_format_info *pix_info;
330 unsigned int frame_size; 317 unsigned int frame_size;
331 318
332 if (vdeb->src_frame) 319 if (vdeb->src_frame)
333 return 0; 320 return 0;
334 321
335 /* We only support translating bayer to RGB24 */ 322 /* Calculate the frame size of the source pad */
336 if (src_pixelformat != V4L2_PIX_FMT_RGB24) { 323 vpix = vimc_pix_map_by_code(vdeb->src_code);
337 dev_err(vdeb->dev, 324 frame_size = vdeb->sink_fmt.width * vdeb->sink_fmt.height *
338 "translating to pixfmt (0x%08x) is not supported\n", 325 vpix->bpp;
339 src_pixelformat); 326
340 return -EINVAL; 327 /* Save the bytes per pixel of the sink */
341 } 328 vpix = vimc_pix_map_by_code(vdeb->sink_fmt.code);
329 vdeb->sink_bpp = vpix->bpp;
342 330
343 /* Get the corresponding pixel map from the table */ 331 /* Get the corresponding pixel map from the table */
344 vdeb->sink_pix_map = 332 vdeb->sink_pix_map =
345 vimc_deb_pix_map_by_code(vdeb->sink_fmt.code); 333 vimc_deb_pix_map_by_code(vdeb->sink_fmt.code);
346 334
347 /* Request bayer format from the pipeline for the sink pad */
348 vdeb->ved.stream->producer_pixfmt =
349 vdeb->sink_pix_map->pixelformat;
350
351 /* Calculate frame_size of the source */
352 pix_info = v4l2_format_info(src_pixelformat);
353 frame_size = vdeb->sink_fmt.width * vdeb->sink_fmt.height *
354 pix_info->bpp[0];
355
356 /* Get bpp from the sink */
357 pix_info = v4l2_format_info(vdeb->sink_pix_map->pixelformat);
358 vdeb->sink_bpp = pix_info->bpp[0];
359
360 /* 335 /*
361 * Allocate the frame buffer. Use vmalloc to be able to 336 * Allocate the frame buffer. Use vmalloc to be able to
362 * allocate a large amount of memory 337 * allocate a large amount of memory
@@ -557,14 +532,14 @@ static int vimc_deb_comp_bind(struct device *comp, struct device *master,
557 532
558 /* Initialize the frame format */ 533 /* Initialize the frame format */
559 vdeb->sink_fmt = sink_fmt_default; 534 vdeb->sink_fmt = sink_fmt_default;
560 vdeb->src_code = VIMC_DEB_SRC_MBUS_FMT_DEFAULT;
561 /* 535 /*
562 * TODO: Add support for more output formats, we only support 536 * TODO: Add support for more output formats, we only support
563 * RGB24 for now. 537 * RGB888 for now
564 * NOTE: the src format is always the same as the sink, except 538 * NOTE: the src format is always the same as the sink, except
565 * for the code 539 * for the code
566 */ 540 */
567 vdeb->set_rgb_src = vimc_deb_set_rgb_pix_rgb24; 541 vdeb->src_code = MEDIA_BUS_FMT_RGB888_1X24;
542 vdeb->set_rgb_src = vimc_deb_set_rgb_mbus_fmt_rgb888_1x24;
568 543
569 return 0; 544 return 0;
570} 545}
diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c
index 5f31c1e351a3..49ab8d9dd9c9 100644
--- a/drivers/media/platform/vimc/vimc-scaler.c
+++ b/drivers/media/platform/vimc/vimc-scaler.c
@@ -25,12 +25,6 @@ MODULE_PARM_DESC(sca_mult, " the image size multiplier");
25#define IS_SRC(pad) (pad) 25#define IS_SRC(pad) (pad)
26#define MAX_ZOOM 8 26#define MAX_ZOOM 8
27 27
28static const u32 vimc_sca_supported_pixfmt[] = {
29 V4L2_PIX_FMT_BGR24,
30 V4L2_PIX_FMT_RGB24,
31 V4L2_PIX_FMT_ARGB32,
32};
33
34struct vimc_sca_device { 28struct vimc_sca_device {
35 struct vimc_ent_device ved; 29 struct vimc_ent_device ved;
36 struct v4l2_subdev sd; 30 struct v4l2_subdev sd;
@@ -53,16 +47,6 @@ static const struct v4l2_mbus_framefmt sink_fmt_default = {
53 .colorspace = V4L2_COLORSPACE_DEFAULT, 47 .colorspace = V4L2_COLORSPACE_DEFAULT,
54}; 48};
55 49
56static bool vimc_sca_is_pixfmt_supported(u32 pixelformat)
57{
58 unsigned int i;
59
60 for (i = 0; i < ARRAY_SIZE(vimc_sca_supported_pixfmt); i++)
61 if (vimc_sca_supported_pixfmt[i] == pixelformat)
62 return true;
63 return false;
64}
65
66static int vimc_sca_init_cfg(struct v4l2_subdev *sd, 50static int vimc_sca_init_cfg(struct v4l2_subdev *sd,
67 struct v4l2_subdev_pad_config *cfg) 51 struct v4l2_subdev_pad_config *cfg)
68{ 52{
@@ -82,13 +66,35 @@ static int vimc_sca_init_cfg(struct v4l2_subdev *sd,
82 return 0; 66 return 0;
83} 67}
84 68
69static int vimc_sca_enum_mbus_code(struct v4l2_subdev *sd,
70 struct v4l2_subdev_pad_config *cfg,
71 struct v4l2_subdev_mbus_code_enum *code)
72{
73 const struct vimc_pix_map *vpix = vimc_pix_map_by_index(code->index);
74
75 /* We don't support bayer format */
76 if (!vpix || vpix->bayer)
77 return -EINVAL;
78
79 code->code = vpix->code;
80
81 return 0;
82}
83
85static int vimc_sca_enum_frame_size(struct v4l2_subdev *sd, 84static int vimc_sca_enum_frame_size(struct v4l2_subdev *sd,
86 struct v4l2_subdev_pad_config *cfg, 85 struct v4l2_subdev_pad_config *cfg,
87 struct v4l2_subdev_frame_size_enum *fse) 86 struct v4l2_subdev_frame_size_enum *fse)
88{ 87{
88 const struct vimc_pix_map *vpix;
89
89 if (fse->index) 90 if (fse->index)
90 return -EINVAL; 91 return -EINVAL;
91 92
93 /* Only accept code in the pix map table in non bayer format */
94 vpix = vimc_pix_map_by_code(fse->code);
95 if (!vpix || vpix->bayer)
96 return -EINVAL;
97
92 fse->min_width = VIMC_FRAME_MIN_WIDTH; 98 fse->min_width = VIMC_FRAME_MIN_WIDTH;
93 fse->min_height = VIMC_FRAME_MIN_HEIGHT; 99 fse->min_height = VIMC_FRAME_MIN_HEIGHT;
94 100
@@ -125,6 +131,13 @@ static int vimc_sca_get_fmt(struct v4l2_subdev *sd,
125 131
126static void vimc_sca_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt) 132static void vimc_sca_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt)
127{ 133{
134 const struct vimc_pix_map *vpix;
135
136 /* Only accept code in the pix map table in non bayer format */
137 vpix = vimc_pix_map_by_code(fmt->code);
138 if (!vpix || vpix->bayer)
139 fmt->code = sink_fmt_default.code;
140
128 fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH, 141 fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH,
129 VIMC_FRAME_MAX_WIDTH) & ~1; 142 VIMC_FRAME_MAX_WIDTH) & ~1;
130 fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT, 143 fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT,
@@ -143,9 +156,6 @@ static int vimc_sca_set_fmt(struct v4l2_subdev *sd,
143 struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); 156 struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
144 struct v4l2_mbus_framefmt *sink_fmt; 157 struct v4l2_mbus_framefmt *sink_fmt;
145 158
146 if (!vimc_mbus_code_supported(fmt->format.code))
147 fmt->format.code = sink_fmt_default.code;
148
149 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { 159 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
150 /* Do not change the format while stream is on */ 160 /* Do not change the format while stream is on */
151 if (vsca->src_frame) 161 if (vsca->src_frame)
@@ -188,7 +198,7 @@ static int vimc_sca_set_fmt(struct v4l2_subdev *sd,
188 198
189static const struct v4l2_subdev_pad_ops vimc_sca_pad_ops = { 199static const struct v4l2_subdev_pad_ops vimc_sca_pad_ops = {
190 .init_cfg = vimc_sca_init_cfg, 200 .init_cfg = vimc_sca_init_cfg,
191 .enum_mbus_code = vimc_enum_mbus_code, 201 .enum_mbus_code = vimc_sca_enum_mbus_code,
192 .enum_frame_size = vimc_sca_enum_frame_size, 202 .enum_frame_size = vimc_sca_enum_frame_size,
193 .get_fmt = vimc_sca_get_fmt, 203 .get_fmt = vimc_sca_get_fmt,
194 .set_fmt = vimc_sca_set_fmt, 204 .set_fmt = vimc_sca_set_fmt,
@@ -199,22 +209,15 @@ static int vimc_sca_s_stream(struct v4l2_subdev *sd, int enable)
199 struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); 209 struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
200 210
201 if (enable) { 211 if (enable) {
202 u32 pixelformat = vsca->ved.stream->producer_pixfmt; 212 const struct vimc_pix_map *vpix;
203 const struct v4l2_format_info *pix_info;
204 unsigned int frame_size; 213 unsigned int frame_size;
205 214
206 if (vsca->src_frame) 215 if (vsca->src_frame)
207 return 0; 216 return 0;
208 217
209 if (!vimc_sca_is_pixfmt_supported(pixelformat)) {
210 dev_err(vsca->dev, "pixfmt (0x%08x) is not supported\n",
211 pixelformat);
212 return -EINVAL;
213 }
214
215 /* Save the bytes per pixel of the sink */ 218 /* Save the bytes per pixel of the sink */
216 pix_info = v4l2_format_info(pixelformat); 219 vpix = vimc_pix_map_by_code(vsca->sink_fmt.code);
217 vsca->bpp = pix_info->bpp[0]; 220 vsca->bpp = vpix->bpp;
218 221
219 /* Calculate the width in bytes of the src frame */ 222 /* Calculate the width in bytes of the src frame */
220 vsca->src_line_size = vsca->sink_fmt.width * 223 vsca->src_line_size = vsca->sink_fmt.width *
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
index c47454cc7f70..6c53b9fc1617 100644
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -55,13 +55,34 @@ static int vimc_sen_init_cfg(struct v4l2_subdev *sd,
55 return 0; 55 return 0;
56} 56}
57 57
58static int vimc_sen_enum_mbus_code(struct v4l2_subdev *sd,
59 struct v4l2_subdev_pad_config *cfg,
60 struct v4l2_subdev_mbus_code_enum *code)
61{
62 const struct vimc_pix_map *vpix = vimc_pix_map_by_index(code->index);
63
64 if (!vpix)
65 return -EINVAL;
66
67 code->code = vpix->code;
68
69 return 0;
70}
71
58static int vimc_sen_enum_frame_size(struct v4l2_subdev *sd, 72static int vimc_sen_enum_frame_size(struct v4l2_subdev *sd,
59 struct v4l2_subdev_pad_config *cfg, 73 struct v4l2_subdev_pad_config *cfg,
60 struct v4l2_subdev_frame_size_enum *fse) 74 struct v4l2_subdev_frame_size_enum *fse)
61{ 75{
76 const struct vimc_pix_map *vpix;
77
62 if (fse->index) 78 if (fse->index)
63 return -EINVAL; 79 return -EINVAL;
64 80
81 /* Only accept code in the pix map table */
82 vpix = vimc_pix_map_by_code(fse->code);
83 if (!vpix)
84 return -EINVAL;
85
65 fse->min_width = VIMC_FRAME_MIN_WIDTH; 86 fse->min_width = VIMC_FRAME_MIN_WIDTH;
66 fse->max_width = VIMC_FRAME_MAX_WIDTH; 87 fse->max_width = VIMC_FRAME_MAX_WIDTH;
67 fse->min_height = VIMC_FRAME_MIN_HEIGHT; 88 fse->min_height = VIMC_FRAME_MIN_HEIGHT;
@@ -86,17 +107,14 @@ static int vimc_sen_get_fmt(struct v4l2_subdev *sd,
86 107
87static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen) 108static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen)
88{ 109{
89 u32 pixelformat = vsen->ved.stream->producer_pixfmt; 110 const struct vimc_pix_map *vpix =
90 const struct v4l2_format_info *pix_info; 111 vimc_pix_map_by_code(vsen->mbus_format.code);
91
92 pix_info = v4l2_format_info(pixelformat);
93 112
94 tpg_reset_source(&vsen->tpg, vsen->mbus_format.width, 113 tpg_reset_source(&vsen->tpg, vsen->mbus_format.width,
95 vsen->mbus_format.height, vsen->mbus_format.field); 114 vsen->mbus_format.height, vsen->mbus_format.field);
96 tpg_s_bytesperline(&vsen->tpg, 0, 115 tpg_s_bytesperline(&vsen->tpg, 0, vsen->mbus_format.width * vpix->bpp);
97 vsen->mbus_format.width * pix_info->bpp[0]);
98 tpg_s_buf_height(&vsen->tpg, vsen->mbus_format.height); 116 tpg_s_buf_height(&vsen->tpg, vsen->mbus_format.height);
99 tpg_s_fourcc(&vsen->tpg, pixelformat); 117 tpg_s_fourcc(&vsen->tpg, vpix->pixelformat);
100 /* TODO: add support for V4L2_FIELD_ALTERNATE */ 118 /* TODO: add support for V4L2_FIELD_ALTERNATE */
101 tpg_s_field(&vsen->tpg, vsen->mbus_format.field, false); 119 tpg_s_field(&vsen->tpg, vsen->mbus_format.field, false);
102 tpg_s_colorspace(&vsen->tpg, vsen->mbus_format.colorspace); 120 tpg_s_colorspace(&vsen->tpg, vsen->mbus_format.colorspace);
@@ -107,6 +125,13 @@ static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen)
107 125
108static void vimc_sen_adjust_fmt(struct v4l2_mbus_framefmt *fmt) 126static void vimc_sen_adjust_fmt(struct v4l2_mbus_framefmt *fmt)
109{ 127{
128 const struct vimc_pix_map *vpix;
129
130 /* Only accept code in the pix map table */
131 vpix = vimc_pix_map_by_code(fmt->code);
132 if (!vpix)
133 fmt->code = fmt_default.code;
134
110 fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH, 135 fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH,
111 VIMC_FRAME_MAX_WIDTH) & ~1; 136 VIMC_FRAME_MAX_WIDTH) & ~1;
112 fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT, 137 fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT,
@@ -126,9 +151,6 @@ static int vimc_sen_set_fmt(struct v4l2_subdev *sd,
126 struct vimc_sen_device *vsen = v4l2_get_subdevdata(sd); 151 struct vimc_sen_device *vsen = v4l2_get_subdevdata(sd);
127 struct v4l2_mbus_framefmt *mf; 152 struct v4l2_mbus_framefmt *mf;
128 153
129 if (!vimc_mbus_code_supported(fmt->format.code))
130 fmt->format.code = fmt_default.code;
131
132 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { 154 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
133 /* Do not change the format while stream is on */ 155 /* Do not change the format while stream is on */
134 if (vsen->frame) 156 if (vsen->frame)
@@ -161,7 +183,7 @@ static int vimc_sen_set_fmt(struct v4l2_subdev *sd,
161 183
162static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = { 184static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = {
163 .init_cfg = vimc_sen_init_cfg, 185 .init_cfg = vimc_sen_init_cfg,
164 .enum_mbus_code = vimc_enum_mbus_code, 186 .enum_mbus_code = vimc_sen_enum_mbus_code,
165 .enum_frame_size = vimc_sen_enum_frame_size, 187 .enum_frame_size = vimc_sen_enum_frame_size,
166 .get_fmt = vimc_sen_get_fmt, 188 .get_fmt = vimc_sen_get_fmt,
167 .set_fmt = vimc_sen_set_fmt, 189 .set_fmt = vimc_sen_set_fmt,
@@ -183,8 +205,7 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable)
183 container_of(sd, struct vimc_sen_device, sd); 205 container_of(sd, struct vimc_sen_device, sd);
184 206
185 if (enable) { 207 if (enable) {
186 u32 pixelformat = vsen->ved.stream->producer_pixfmt; 208 const struct vimc_pix_map *vpix;
187 const struct v4l2_format_info *pix_info;
188 unsigned int frame_size; 209 unsigned int frame_size;
189 210
190 if (vsen->kthread_sen) 211 if (vsen->kthread_sen)
@@ -192,8 +213,8 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable)
192 return 0; 213 return 0;
193 214
194 /* Calculate the frame size */ 215 /* Calculate the frame size */
195 pix_info = v4l2_format_info(pixelformat); 216 vpix = vimc_pix_map_by_code(vsen->mbus_format.code);
196 frame_size = vsen->mbus_format.width * pix_info->bpp[0] * 217 frame_size = vsen->mbus_format.width * vpix->bpp *
197 vsen->mbus_format.height; 218 vsen->mbus_format.height;
198 219
199 /* 220 /*
diff --git a/drivers/media/platform/vimc/vimc-streamer.c b/drivers/media/platform/vimc/vimc-streamer.c
index 62dde7d74c24..048d770e498b 100644
--- a/drivers/media/platform/vimc/vimc-streamer.c
+++ b/drivers/media/platform/vimc/vimc-streamer.c
@@ -54,7 +54,6 @@ static void vimc_streamer_pipeline_terminate(struct vimc_stream *stream)
54 while (stream->pipe_size) { 54 while (stream->pipe_size) {
55 stream->pipe_size--; 55 stream->pipe_size--;
56 ved = stream->ved_pipeline[stream->pipe_size]; 56 ved = stream->ved_pipeline[stream->pipe_size];
57 ved->stream = NULL;
58 stream->ved_pipeline[stream->pipe_size] = NULL; 57 stream->ved_pipeline[stream->pipe_size] = NULL;
59 58
60 if (!is_media_entity_v4l2_subdev(ved->ent)) 59 if (!is_media_entity_v4l2_subdev(ved->ent))
@@ -93,7 +92,6 @@ static int vimc_streamer_pipeline_init(struct vimc_stream *stream,
93 return -EINVAL; 92 return -EINVAL;
94 } 93 }
95 stream->ved_pipeline[stream->pipe_size++] = ved; 94 stream->ved_pipeline[stream->pipe_size++] = ved;
96 ved->stream = stream;
97 95
98 if (is_media_entity_v4l2_subdev(ved->ent)) { 96 if (is_media_entity_v4l2_subdev(ved->ent)) {
99 sd = media_entity_to_v4l2_subdev(ved->ent); 97 sd = media_entity_to_v4l2_subdev(ved->ent);
diff --git a/drivers/media/platform/vimc/vimc-streamer.h b/drivers/media/platform/vimc/vimc-streamer.h
index d744a787e0e7..fe3c51f15fad 100644
--- a/drivers/media/platform/vimc/vimc-streamer.h
+++ b/drivers/media/platform/vimc/vimc-streamer.h
@@ -25,13 +25,6 @@
25 * processed in the pipeline. 25 * processed in the pipeline.
26 * @pipe_size: size of @ved_pipeline 26 * @pipe_size: size of @ved_pipeline
27 * @kthread: thread that generates the frames of the stream. 27 * @kthread: thread that generates the frames of the stream.
28 * @producer_pixfmt: the pixel format requested from the pipeline. This must
29 * be set just before calling
30 * vimc_streamer_s_stream(ent, 1). This value is propagated
31 * up to the source of the base image (usually a sensor
32 * node) and can be modified by entities during s_stream
33 * callback to request a differentformat from rest of
34 * the pipeline.
35 * 28 *
36 * When the user call stream_on in a video device, struct vimc_stream is 29 * When the user call stream_on in a video device, struct vimc_stream is
37 * used to keep track of all entities and subdevices that generates and 30 * used to keep track of all entities and subdevices that generates and
@@ -42,7 +35,6 @@ struct vimc_stream {
42 struct vimc_ent_device *ved_pipeline[VIMC_STREAMER_PIPELINE_MAX_SIZE]; 35 struct vimc_ent_device *ved_pipeline[VIMC_STREAMER_PIPELINE_MAX_SIZE];
43 unsigned int pipe_size; 36 unsigned int pipe_size;
44 struct task_struct *kthread; 37 struct task_struct *kthread;
45 u32 producer_pixfmt;
46}; 38};
47 39
48int vimc_streamer_s_stream(struct vimc_stream *stream, 40int vimc_streamer_s_stream(struct vimc_stream *stream,