bcm27xx: update 6.1 patches to latest version
[openwrt/staging/svanheule.git] / target / linux / bcm27xx / patches-6.1 / 950-1204-media-rp1-csi2-Fix-csi2_pad_set_fmt.patch
1 From eaa8a0ae14a1ca797c1896e9dafbefa1fa51a617 Mon Sep 17 00:00:00 2001
2 From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
3 Date: Fri, 29 Sep 2023 16:25:10 +0300
4 Subject: [PATCH] media: rp1: csi2: Fix csi2_pad_set_fmt()
5
6 The CSI-2 subdev's set_fmt currently allows setting the source and sink
7 pad formats quite freely. This is not right, as the CSI-2 block can only
8 do one of the following when processing the stream: 1) pass through as
9 is, 2) expand to 16-bits, 3) compress.
10
11 The csi2_pad_set_fmt() should take this into account, and only allow
12 changing the source side mbus code, compared to the sink side format.
13
14 Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
15 ---
16 .../media/platform/raspberrypi/rp1_cfe/csi2.c | 61 +++++++++++++++----
17 1 file changed, 48 insertions(+), 13 deletions(-)
18
19 --- a/drivers/media/platform/raspberrypi/rp1_cfe/csi2.c
20 +++ b/drivers/media/platform/raspberrypi/rp1_cfe/csi2.c
21 @@ -438,25 +438,60 @@ static int csi2_pad_set_fmt(struct v4l2_
22 struct v4l2_subdev_state *state,
23 struct v4l2_subdev_format *format)
24 {
25 - struct v4l2_mbus_framefmt *fmt;
26 - const struct cfe_fmt *cfe_fmt;
27 -
28 - /* TODO: format validation */
29 + if (format->pad < CSI2_NUM_CHANNELS) {
30 + /*
31 + * Store the sink pad format and propagate it to the source pad.
32 + */
33 +
34 + struct v4l2_mbus_framefmt *fmt;
35 +
36 + fmt = v4l2_subdev_get_pad_format(sd, state, format->pad);
37 + if (!fmt)
38 + return -EINVAL;
39
40 - cfe_fmt = find_format_by_code(format->format.code);
41 - if (!cfe_fmt)
42 - cfe_fmt = find_format_by_code(MEDIA_BUS_FMT_SBGGR10_1X10);
43 + *fmt = format->format;
44
45 - format->format.code = cfe_fmt->code;
46 + fmt = v4l2_subdev_get_pad_format(sd, state,
47 + format->pad + CSI2_NUM_CHANNELS);
48 + if (!fmt)
49 + return -EINVAL;
50
51 - fmt = v4l2_subdev_get_pad_format(sd, state, format->pad);
52 - *fmt = format->format;
53 + format->format.field = V4L2_FIELD_NONE;
54
55 - if (format->pad < CSI2_NUM_CHANNELS) {
56 - /* Propagate to the source pad */
57 - fmt = v4l2_subdev_get_pad_format(sd, state,
58 - format->pad + CSI2_NUM_CHANNELS);
59 *fmt = format->format;
60 + } else {
61 + /*
62 + * Only allow changing the source pad mbus code.
63 + */
64 +
65 + struct v4l2_mbus_framefmt *sink_fmt, *source_fmt;
66 + u32 sink_code;
67 + u32 code;
68 +
69 + sink_fmt = v4l2_subdev_get_pad_format(sd, state,
70 + format->pad - CSI2_NUM_CHANNELS);
71 + if (!sink_fmt)
72 + return -EINVAL;
73 +
74 + source_fmt = v4l2_subdev_get_pad_format(sd, state, format->pad);
75 + if (!source_fmt)
76 + return -EINVAL;
77 +
78 + sink_code = sink_fmt->code;
79 + code = format->format.code;
80 +
81 + /*
82 + * If the source code from the user does not match the code in
83 + * the sink pad, check that the source code matches either the
84 + * 16-bit version or the compressed version of the sink code.
85 + */
86 +
87 + if (code != sink_code &&
88 + (code == cfe_find_16bit_code(sink_code) ||
89 + code == cfe_find_compressed_code(sink_code)))
90 + source_fmt->code = code;
91 +
92 + format->format.code = source_fmt->code;
93 }
94
95 return 0;