c6915f66d41d272ecce2d0ff9bbdfaeb63c62e83
[openwrt/staging/stintel.git] /
1 From d29db3b2d7b032385ae913c40dfa1b17feac8444 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.com>
3 Date: Tue, 23 Jun 2020 15:14:05 +0100
4 Subject: [PATCH] media: bcm2835-unicam: Fixup review comments from
5 Hans.
6
7 Updates the driver based on the upstream review comments from
8 Hans Verkuil at https://patchwork.linuxtv.org/patch/63531/
9
10 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
11 ---
12 drivers/media/platform/bcm2835/Kconfig | 12 ++--
13 .../media/platform/bcm2835/bcm2835-unicam.c | 70 ++++++++-----------
14 2 files changed, 39 insertions(+), 43 deletions(-)
15
16 --- a/drivers/media/platform/bcm2835/Kconfig
17 +++ b/drivers/media/platform/bcm2835/Kconfig
18 @@ -1,7 +1,7 @@
19 # Broadcom VideoCore4 V4L2 camera support
20
21 config VIDEO_BCM2835_UNICAM
22 - tristate "Broadcom BCM2835 Unicam video capture driver"
23 + tristate "Broadcom BCM283x/BCM271x Unicam video capture driver"
24 depends on VIDEO_V4L2
25 depends on ARCH_BCM2835 || COMPILE_TEST
26 select VIDEO_V4L2_SUBDEV_API
27 @@ -9,9 +9,13 @@ config VIDEO_BCM2835_UNICAM
28 select VIDEOBUF2_DMA_CONTIG
29 select V4L2_FWNODE
30 help
31 - Say Y here to enable support for the BCM2835 CSI-2 receiver. This is a
32 - V4L2 driver that controls the CSI-2 receiver directly, independently
33 - from the VC4 firmware.
34 + Say Y here to enable support for the BCM283x/BCM271x CSI-2 receiver.
35 + This is a V4L2 driver that controls the CSI-2 receiver directly,
36 + independently from the VC4 firmware.
37 + This driver is mutually exclusive with the use of bcm2835-camera. The
38 + firmware will disable all access to the peripheral from within the
39 + firmware if it finds a DT node using it, and bcm2835-camera will
40 + therefore fail to probe.
41
42 To compile this driver as a module, choose M here. The module will be
43 called bcm2835-unicam.
44 --- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
45 +++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
46 @@ -1,6 +1,6 @@
47 // SPDX-License-Identifier: GPL-2.0-only
48 /*
49 - * BCM2835 Unicam Capture Driver
50 + * BCM283x / BCM271x Unicam Capture Driver
51 *
52 * Copyright (C) 2017-2020 - Raspberry Pi (Trading) Ltd.
53 *
54 @@ -571,9 +571,8 @@ static const struct unicam_fmt *find_for
55 return NULL;
56 }
57
58 -static inline unsigned int bytes_per_line(u32 width,
59 - const struct unicam_fmt *fmt,
60 - u32 v4l2_fourcc)
61 +static unsigned int bytes_per_line(u32 width, const struct unicam_fmt *fmt,
62 + u32 v4l2_fourcc)
63 {
64 if (v4l2_fourcc == fmt->repacked_fourcc)
65 /* Repacking always goes to 16bpp */
66 @@ -718,7 +717,7 @@ static void unicam_wr_dma_addr(struct un
67 }
68 }
69
70 -static inline unsigned int unicam_get_lines_done(struct unicam_device *dev)
71 +static unsigned int unicam_get_lines_done(struct unicam_device *dev)
72 {
73 dma_addr_t start_addr, cur_addr;
74 unsigned int stride = dev->node[IMAGE_PAD].v_fmt.fmt.pix.bytesperline;
75 @@ -732,7 +731,7 @@ static inline unsigned int unicam_get_li
76 return (unsigned int)(cur_addr - start_addr) / stride;
77 }
78
79 -static inline void unicam_schedule_next_buffer(struct unicam_node *node)
80 +static void unicam_schedule_next_buffer(struct unicam_node *node)
81 {
82 struct unicam_device *dev = node->dev;
83 struct unicam_buffer *buf;
84 @@ -751,7 +750,7 @@ static inline void unicam_schedule_next_
85 unicam_wr_dma_addr(dev, addr, size, node->pad_id);
86 }
87
88 -static inline void unicam_schedule_dummy_buffer(struct unicam_node *node)
89 +static void unicam_schedule_dummy_buffer(struct unicam_node *node)
90 {
91 struct unicam_device *dev = node->dev;
92
93 @@ -763,8 +762,8 @@ static inline void unicam_schedule_dummy
94 node->next_frm = NULL;
95 }
96
97 -static inline void unicam_process_buffer_complete(struct unicam_node *node,
98 - unsigned int sequence)
99 +static void unicam_process_buffer_complete(struct unicam_node *node,
100 + unsigned int sequence)
101 {
102 node->cur_frm->vb.field = node->m_fmt.field;
103 node->cur_frm->vb.sequence = sequence;
104 @@ -772,16 +771,6 @@ static inline void unicam_process_buffer
105 vb2_buffer_done(&node->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
106 }
107
108 -static bool unicam_all_nodes_streaming(struct unicam_device *dev)
109 -{
110 - bool ret;
111 -
112 - ret = dev->node[IMAGE_PAD].open && dev->node[IMAGE_PAD].streaming;
113 - ret &= !dev->node[METADATA_PAD].open ||
114 - dev->node[METADATA_PAD].streaming;
115 - return ret;
116 -}
117 -
118 static void unicam_queue_event_sof(struct unicam_device *unicam)
119 {
120 struct v4l2_event event = {
121 @@ -904,8 +893,8 @@ static int unicam_querycap(struct file *
122 struct unicam_node *node = video_drvdata(file);
123 struct unicam_device *dev = node->dev;
124
125 - strlcpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver));
126 - strlcpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card));
127 + strscpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver));
128 + strscpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card));
129
130 snprintf(cap->bus_info, sizeof(cap->bus_info),
131 "platform:%s", dev_name(&dev->pdev->dev));
132 @@ -998,8 +987,8 @@ static int unicam_g_fmt_vid_cap(struct f
133 return 0;
134 }
135
136 -static
137 -const struct unicam_fmt *get_first_supported_format(struct unicam_device *dev)
138 +static const struct unicam_fmt *
139 +get_first_supported_format(struct unicam_device *dev)
140 {
141 struct v4l2_subdev_mbus_code_enum mbus_code;
142 const struct unicam_fmt *fmt = NULL;
143 @@ -1589,7 +1578,8 @@ static void unicam_disable(struct unicam
144 clk_write(dev, 0);
145 }
146
147 -static void unicam_return_buffers(struct unicam_node *node)
148 +static void unicam_return_buffers(struct unicam_node *node,
149 + enum vb2_buffer_state state)
150 {
151 struct unicam_buffer *buf, *tmp;
152 unsigned long flags;
153 @@ -1597,15 +1587,15 @@ static void unicam_return_buffers(struct
154 spin_lock_irqsave(&node->dma_queue_lock, flags);
155 list_for_each_entry_safe(buf, tmp, &node->dma_queue, list) {
156 list_del(&buf->list);
157 - vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
158 + vb2_buffer_done(&buf->vb.vb2_buf, state);
159 }
160
161 if (node->cur_frm)
162 vb2_buffer_done(&node->cur_frm->vb.vb2_buf,
163 - VB2_BUF_STATE_ERROR);
164 + state);
165 if (node->next_frm && node->cur_frm != node->next_frm)
166 vb2_buffer_done(&node->next_frm->vb.vb2_buf,
167 - VB2_BUF_STATE_ERROR);
168 + state);
169
170 node->cur_frm = NULL;
171 node->next_frm = NULL;
172 @@ -1622,7 +1612,13 @@ static int unicam_start_streaming(struct
173 int ret;
174
175 node->streaming = true;
176 - if (!unicam_all_nodes_streaming(dev)) {
177 + if (!(dev->node[IMAGE_PAD].open && dev->node[IMAGE_PAD].streaming &&
178 + (!dev->node[METADATA_PAD].open ||
179 + dev->node[METADATA_PAD].streaming))) {
180 + /*
181 + * Metadata pad must be enabled before image pad if it is
182 + * wanted.
183 + */
184 unicam_dbg(3, dev, "Not all nodes are streaming yet.");
185 return 0;
186 }
187 @@ -1726,7 +1722,7 @@ err_vpu_clock:
188 err_pm_put:
189 unicam_runtime_put(dev);
190 err_streaming:
191 - unicam_return_buffers(node);
192 + unicam_return_buffers(node, VB2_BUF_STATE_QUEUED);
193 node->streaming = false;
194
195 return ret;
196 @@ -1771,7 +1767,7 @@ static void unicam_stop_streaming(struct
197 }
198
199 /* Clear all queued buffers for the node */
200 - unicam_return_buffers(node);
201 + unicam_return_buffers(node, VB2_BUF_STATE_ERROR);
202 }
203
204 static int unicam_enum_input(struct file *file, void *priv,
205 @@ -1789,14 +1785,13 @@ static int unicam_enum_input(struct file
206 inp->std = 0;
207 } else if (v4l2_subdev_has_op(dev->sensor, video, s_std)) {
208 inp->capabilities = V4L2_IN_CAP_STD;
209 - if (v4l2_subdev_call(dev->sensor, video, g_tvnorms, &inp->std)
210 - < 0)
211 + if (v4l2_subdev_call(dev->sensor, video, g_tvnorms, &inp->std) < 0)
212 inp->std = V4L2_STD_ALL;
213 } else {
214 inp->capabilities = 0;
215 inp->std = 0;
216 }
217 - sprintf(inp->name, "Camera 0");
218 + snprintf(inp->name, sizeof(inp->name), "Camera 0");
219 return 0;
220 }
221
222 @@ -2025,6 +2020,9 @@ static int unicam_s_dv_timings(struct fi
223 ret = v4l2_subdev_call(dev->sensor, video, g_dv_timings,
224 &current_timings);
225
226 + if (ret < 0)
227 + return ret;
228 +
229 if (v4l2_match_dv_timings(timings, &current_timings, 0, false))
230 return 0;
231
232 @@ -2455,12 +2453,6 @@ static int register_node(struct unicam_d
233 unicam_err(unicam, "Unable to allocate dummy buffer.\n");
234 return -ENOMEM;
235 }
236 -
237 - if (pad_id == METADATA_PAD) {
238 - v4l2_disable_ioctl(vdev, VIDIOC_DQEVENT);
239 - v4l2_disable_ioctl(vdev, VIDIOC_SUBSCRIBE_EVENT);
240 - v4l2_disable_ioctl(vdev, VIDIOC_UNSUBSCRIBE_EVENT);
241 - }
242 if (pad_id == METADATA_PAD ||
243 !v4l2_subdev_has_op(unicam->sensor, video, s_std)) {
244 v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_STD);