1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * vivid-kthread-out.h - video/vbi output thread support functions.
4  *
5  * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
6  */
7 
8 #include <linux/module.h>
9 #include <linux/errno.h>
10 #include <linux/kernel.h>
11 #include <linux/init.h>
12 #include <linux/sched.h>
13 #include <linux/slab.h>
14 #include <linux/font.h>
15 #include <linux/mutex.h>
16 #include <linux/videodev2.h>
17 #include <linux/kthread.h>
18 #include <linux/freezer.h>
19 #include <linux/random.h>
20 #include <linux/v4l2-dv-timings.h>
21 #include <asm/div64.h>
22 #include <media/videobuf2-vmalloc.h>
23 #include <media/v4l2-dv-timings.h>
24 #include <media/v4l2-ioctl.h>
25 #include <media/v4l2-fh.h>
26 #include <media/v4l2-event.h>
27 
28 #include "vivid-core.h"
29 #include "vivid-vid-common.h"
30 #include "vivid-vid-cap.h"
31 #include "vivid-vid-out.h"
32 #include "vivid-radio-common.h"
33 #include "vivid-radio-rx.h"
34 #include "vivid-radio-tx.h"
35 #include "vivid-sdr-cap.h"
36 #include "vivid-vbi-cap.h"
37 #include "vivid-vbi-out.h"
38 #include "vivid-osd.h"
39 #include "vivid-ctrls.h"
40 #include "vivid-kthread-out.h"
41 
vivid_thread_vid_out_tick(struct vivid_dev * dev)42 static void vivid_thread_vid_out_tick(struct vivid_dev *dev)
43 {
44 	struct vivid_buffer *vid_out_buf = NULL;
45 	struct vivid_buffer *vbi_out_buf = NULL;
46 
47 	dprintk(dev, 1, "Video Output Thread Tick\n");
48 
49 	/* Drop a certain percentage of buffers. */
50 	if (dev->perc_dropped_buffers &&
51 	    prandom_u32_max(100) < dev->perc_dropped_buffers)
52 		return;
53 
54 	spin_lock(&dev->slock);
55 	/*
56 	 * Only dequeue buffer if there is at least one more pending.
57 	 * This makes video loopback possible.
58 	 */
59 	if (!list_empty(&dev->vid_out_active) &&
60 	    !list_is_singular(&dev->vid_out_active)) {
61 		vid_out_buf = list_entry(dev->vid_out_active.next,
62 					 struct vivid_buffer, list);
63 		list_del(&vid_out_buf->list);
64 	}
65 	if (!list_empty(&dev->vbi_out_active) &&
66 	    (dev->field_out != V4L2_FIELD_ALTERNATE ||
67 	     (dev->vbi_out_seq_count & 1))) {
68 		vbi_out_buf = list_entry(dev->vbi_out_active.next,
69 					 struct vivid_buffer, list);
70 		list_del(&vbi_out_buf->list);
71 	}
72 	spin_unlock(&dev->slock);
73 
74 	if (!vid_out_buf && !vbi_out_buf)
75 		return;
76 
77 	if (vid_out_buf) {
78 		vid_out_buf->vb.sequence = dev->vid_out_seq_count;
79 		if (dev->field_out == V4L2_FIELD_ALTERNATE) {
80 			/*
81 			 * The sequence counter counts frames, not fields.
82 			 * So divide by two.
83 			 */
84 			vid_out_buf->vb.sequence /= 2;
85 		}
86 		vid_out_buf->vb.vb2_buf.timestamp =
87 			ktime_get_ns() + dev->time_wrap_offset;
88 		vb2_buffer_done(&vid_out_buf->vb.vb2_buf, dev->dqbuf_error ?
89 				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
90 		dprintk(dev, 2, "vid_out buffer %d done\n",
91 			vid_out_buf->vb.vb2_buf.index);
92 	}
93 
94 	if (vbi_out_buf) {
95 		if (dev->stream_sliced_vbi_out)
96 			vivid_sliced_vbi_out_process(dev, vbi_out_buf);
97 
98 		vbi_out_buf->vb.sequence = dev->vbi_out_seq_count;
99 		vbi_out_buf->vb.vb2_buf.timestamp =
100 			ktime_get_ns() + dev->time_wrap_offset;
101 		vb2_buffer_done(&vbi_out_buf->vb.vb2_buf, dev->dqbuf_error ?
102 				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
103 		dprintk(dev, 2, "vbi_out buffer %d done\n",
104 			vbi_out_buf->vb.vb2_buf.index);
105 	}
106 	dev->dqbuf_error = false;
107 }
108 
vivid_thread_vid_out(void * data)109 static int vivid_thread_vid_out(void *data)
110 {
111 	struct vivid_dev *dev = data;
112 	u64 numerators_since_start;
113 	u64 buffers_since_start;
114 	u64 next_jiffies_since_start;
115 	unsigned long jiffies_since_start;
116 	unsigned long cur_jiffies;
117 	unsigned wait_jiffies;
118 	unsigned numerator;
119 	unsigned denominator;
120 
121 	dprintk(dev, 1, "Video Output Thread Start\n");
122 
123 	set_freezable();
124 
125 	/* Resets frame counters */
126 	dev->out_seq_offset = 0;
127 	if (dev->seq_wrap)
128 		dev->out_seq_count = 0xffffff80U;
129 	dev->jiffies_vid_out = jiffies;
130 	dev->vid_out_seq_start = dev->vbi_out_seq_start = 0;
131 	dev->out_seq_resync = false;
132 
133 	for (;;) {
134 		try_to_freeze();
135 		if (kthread_should_stop())
136 			break;
137 
138 		mutex_lock(&dev->mutex);
139 		cur_jiffies = jiffies;
140 		if (dev->out_seq_resync) {
141 			dev->jiffies_vid_out = cur_jiffies;
142 			dev->out_seq_offset = dev->out_seq_count + 1;
143 			dev->out_seq_count = 0;
144 			dev->out_seq_resync = false;
145 		}
146 		numerator = dev->timeperframe_vid_out.numerator;
147 		denominator = dev->timeperframe_vid_out.denominator;
148 
149 		if (dev->field_out == V4L2_FIELD_ALTERNATE)
150 			denominator *= 2;
151 
152 		/* Calculate the number of jiffies since we started streaming */
153 		jiffies_since_start = cur_jiffies - dev->jiffies_vid_out;
154 		/* Get the number of buffers streamed since the start */
155 		buffers_since_start = (u64)jiffies_since_start * denominator +
156 				      (HZ * numerator) / 2;
157 		do_div(buffers_since_start, HZ * numerator);
158 
159 		/*
160 		 * After more than 0xf0000000 (rounded down to a multiple of
161 		 * 'jiffies-per-day' to ease jiffies_to_msecs calculation)
162 		 * jiffies have passed since we started streaming reset the
163 		 * counters and keep track of the sequence offset.
164 		 */
165 		if (jiffies_since_start > JIFFIES_RESYNC) {
166 			dev->jiffies_vid_out = cur_jiffies;
167 			dev->out_seq_offset = buffers_since_start;
168 			buffers_since_start = 0;
169 		}
170 		dev->out_seq_count = buffers_since_start + dev->out_seq_offset;
171 		dev->vid_out_seq_count = dev->out_seq_count - dev->vid_out_seq_start;
172 		dev->vbi_out_seq_count = dev->out_seq_count - dev->vbi_out_seq_start;
173 
174 		vivid_thread_vid_out_tick(dev);
175 		mutex_unlock(&dev->mutex);
176 
177 		/*
178 		 * Calculate the number of 'numerators' streamed since we started,
179 		 * not including the current buffer.
180 		 */
181 		numerators_since_start = buffers_since_start * numerator;
182 
183 		/* And the number of jiffies since we started */
184 		jiffies_since_start = jiffies - dev->jiffies_vid_out;
185 
186 		/* Increase by the 'numerator' of one buffer */
187 		numerators_since_start += numerator;
188 		/*
189 		 * Calculate when that next buffer is supposed to start
190 		 * in jiffies since we started streaming.
191 		 */
192 		next_jiffies_since_start = numerators_since_start * HZ +
193 					   denominator / 2;
194 		do_div(next_jiffies_since_start, denominator);
195 		/* If it is in the past, then just schedule asap */
196 		if (next_jiffies_since_start < jiffies_since_start)
197 			next_jiffies_since_start = jiffies_since_start;
198 
199 		wait_jiffies = next_jiffies_since_start - jiffies_since_start;
200 		schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
201 	}
202 	dprintk(dev, 1, "Video Output Thread End\n");
203 	return 0;
204 }
205 
vivid_grab_controls(struct vivid_dev * dev,bool grab)206 static void vivid_grab_controls(struct vivid_dev *dev, bool grab)
207 {
208 	v4l2_ctrl_grab(dev->ctrl_has_crop_out, grab);
209 	v4l2_ctrl_grab(dev->ctrl_has_compose_out, grab);
210 	v4l2_ctrl_grab(dev->ctrl_has_scaler_out, grab);
211 	v4l2_ctrl_grab(dev->ctrl_tx_mode, grab);
212 	v4l2_ctrl_grab(dev->ctrl_tx_rgb_range, grab);
213 }
214 
vivid_start_generating_vid_out(struct vivid_dev * dev,bool * pstreaming)215 int vivid_start_generating_vid_out(struct vivid_dev *dev, bool *pstreaming)
216 {
217 	dprintk(dev, 1, "%s\n", __func__);
218 
219 	if (dev->kthread_vid_out) {
220 		u32 seq_count = dev->out_seq_count + dev->seq_wrap * 128;
221 
222 		if (pstreaming == &dev->vid_out_streaming)
223 			dev->vid_out_seq_start = seq_count;
224 		else
225 			dev->vbi_out_seq_start = seq_count;
226 		*pstreaming = true;
227 		return 0;
228 	}
229 
230 	/* Resets frame counters */
231 	dev->jiffies_vid_out = jiffies;
232 	dev->vid_out_seq_start = dev->seq_wrap * 128;
233 	dev->vbi_out_seq_start = dev->seq_wrap * 128;
234 
235 	dev->kthread_vid_out = kthread_run(vivid_thread_vid_out, dev,
236 			"%s-vid-out", dev->v4l2_dev.name);
237 
238 	if (IS_ERR(dev->kthread_vid_out)) {
239 		v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
240 		return PTR_ERR(dev->kthread_vid_out);
241 	}
242 	*pstreaming = true;
243 	vivid_grab_controls(dev, true);
244 
245 	dprintk(dev, 1, "returning from %s\n", __func__);
246 	return 0;
247 }
248 
vivid_stop_generating_vid_out(struct vivid_dev * dev,bool * pstreaming)249 void vivid_stop_generating_vid_out(struct vivid_dev *dev, bool *pstreaming)
250 {
251 	dprintk(dev, 1, "%s\n", __func__);
252 
253 	if (dev->kthread_vid_out == NULL)
254 		return;
255 
256 	*pstreaming = false;
257 	if (pstreaming == &dev->vid_out_streaming) {
258 		/* Release all active buffers */
259 		while (!list_empty(&dev->vid_out_active)) {
260 			struct vivid_buffer *buf;
261 
262 			buf = list_entry(dev->vid_out_active.next,
263 					 struct vivid_buffer, list);
264 			list_del(&buf->list);
265 			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
266 			dprintk(dev, 2, "vid_out buffer %d done\n",
267 				buf->vb.vb2_buf.index);
268 		}
269 	}
270 
271 	if (pstreaming == &dev->vbi_out_streaming) {
272 		while (!list_empty(&dev->vbi_out_active)) {
273 			struct vivid_buffer *buf;
274 
275 			buf = list_entry(dev->vbi_out_active.next,
276 					 struct vivid_buffer, list);
277 			list_del(&buf->list);
278 			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
279 			dprintk(dev, 2, "vbi_out buffer %d done\n",
280 				buf->vb.vb2_buf.index);
281 		}
282 	}
283 
284 	if (dev->vid_out_streaming || dev->vbi_out_streaming)
285 		return;
286 
287 	/* shutdown control thread */
288 	vivid_grab_controls(dev, false);
289 	mutex_unlock(&dev->mutex);
290 	kthread_stop(dev->kthread_vid_out);
291 	dev->kthread_vid_out = NULL;
292 	mutex_lock(&dev->mutex);
293 }
294