bcm27xx: update 6.1 patches to latest version
[openwrt/staging/dangole.git] / target / linux / bcm27xx / patches-6.1 / 950-0998-media-rp1-cfe-Fix-width-height-in-cfe_start_channel.patch
1 From 84c9958dd71b8a4dcf16cbf6fdb867c668652634 Mon Sep 17 00:00:00 2001
2 From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
3 Date: Wed, 27 Sep 2023 16:00:39 +0300
4 Subject: [PATCH] media: rp1: cfe: Fix width & height in cfe_start_channel()
5
6 The logic for handling width & height in cfe_start_channel() is somewhat
7 odd and, afaics, broken. The code reads:
8
9 bool start_fe = is_fe_enabled(cfe) &&
10 test_all_nodes(cfe, NODE_ENABLED, NODE_STREAMING);
11
12 if (start_fe || is_image_output_node(node)) {
13 width = node->fmt.fmt.pix.width;
14 height = node->fmt.fmt.pix.height;
15 }
16
17 cfe_start_channel() is called for all video nodes that will be used. So
18 this means that if, say, fe_stats is enabled as the last node, start_fe
19 will be true, and width and height will be taken from fe_stats' node.
20 The width and height will thus contain garbage, which then gets
21 programmed to the csi2 registers.
22
23 It seems that this often still works fine, though, probably if the width
24 & height are large enough.
25
26 Drop the above code, and instead get the width & height from the csi2
27 subdev's sink pad for the csi2 channel that is used. For metadata the
28 width & height will be 0 as before.
29
30 Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
31 ---
32 drivers/media/platform/raspberrypi/rp1_cfe/cfe.c | 16 ++++++++++------
33 1 file changed, 10 insertions(+), 6 deletions(-)
34
35 --- a/drivers/media/platform/raspberrypi/rp1_cfe/cfe.c
36 +++ b/drivers/media/platform/raspberrypi/rp1_cfe/cfe.c
37 @@ -763,20 +763,16 @@ static void cfe_start_channel(struct cfe
38 struct v4l2_mbus_framefmt *source_fmt;
39 const struct cfe_fmt *fmt;
40 unsigned long flags;
41 - unsigned int width = 0, height = 0;
42 bool start_fe = is_fe_enabled(cfe) &&
43 test_all_nodes(cfe, NODE_ENABLED, NODE_STREAMING);
44
45 cfe_dbg("%s: [%s]\n", __func__, node_desc[node->id].name);
46
47 - if (start_fe || is_image_output_node(node)) {
48 - width = node->fmt.fmt.pix.width;
49 - height = node->fmt.fmt.pix.height;
50 - }
51 -
52 state = v4l2_subdev_lock_and_get_active_state(&cfe->csi2.sd);
53
54 if (start_fe) {
55 + unsigned int width, height;
56 +
57 WARN_ON(!is_fe_enabled(cfe));
58 cfe_dbg("%s: %s using csi2 channel %d\n",
59 __func__, node_desc[FE_OUT0].name,
60 @@ -785,6 +781,9 @@ static void cfe_start_channel(struct cfe
61 source_fmt = v4l2_subdev_get_pad_format(&cfe->csi2.sd, state, cfe->fe_csi2_channel);
62 fmt = find_format_by_code(source_fmt->code);
63
64 + width = source_fmt->width;
65 + height = source_fmt->height;
66 +
67 /*
68 * Start the associated CSI2 Channel as well.
69 *
70 @@ -800,6 +799,8 @@ static void cfe_start_channel(struct cfe
71 }
72
73 if (is_csi2_node(node)) {
74 + unsigned int width = 0, height = 0;
75 +
76 u32 mode = CSI2_MODE_NORMAL;
77
78 source_fmt = v4l2_subdev_get_pad_format(&cfe->csi2.sd, state,
79 @@ -807,6 +808,9 @@ static void cfe_start_channel(struct cfe
80 fmt = find_format_by_code(source_fmt->code);
81
82 if (is_image_output_node(node)) {
83 + width = source_fmt->width;
84 + height = source_fmt->height;
85 +
86 if (node->fmt.fmt.pix.pixelformat ==
87 fmt->remap[CFE_REMAP_16BIT])
88 mode = CSI2_MODE_REMAP;