xref: /linux/drivers/media/pci/hws/hws_video.c (revision 3d5e48944e824bddc20d7b874e784f7b279636fe)
1 // SPDX-License-Identifier: GPL-2.0-only
2 #include <linux/pci.h>
3 #include <linux/errno.h>
4 #include <linux/kernel.h>
5 #include <linux/compiler.h>
6 #include <linux/overflow.h>
7 #include <linux/delay.h>
8 #include <linux/bits.h>
9 #include <linux/jiffies.h>
10 #include <linux/ktime.h>
11 #include <linux/math64.h>
12 #include <linux/interrupt.h>
13 #include <linux/moduleparam.h>
14 
15 #include <media/v4l2-ioctl.h>
16 #include <media/v4l2-ctrls.h>
17 #include <media/v4l2-dev.h>
18 #include <media/v4l2-event.h>
19 #include <media/videobuf2-v4l2.h>
20 #include <media/v4l2-device.h>
21 #include <media/videobuf2-dma-contig.h>
22 
23 #include "hws.h"
24 #include "hws_reg.h"
25 #include "hws_video.h"
26 #include "hws_irq.h"
27 #include "hws_v4l2_ioctl.h"
28 
29 #define HWS_REMAP_SLOT_OFF(ch)   (0x208 + (ch) * 8)	/* one 64-bit slot per ch */
30 #define HWS_BUF_BASE_OFF(ch)     (CVBS_IN_BUF_BASE  + (ch) * PCIE_BARADDROFSIZE)
31 #define HWS_HALF_SZ_OFF(ch)      (CVBS_IN_BUF_BASE2 + (ch) * PCIE_BARADDROFSIZE)
32 
33 static void update_live_resolution(struct hws_pcie_dev *pdx, unsigned int ch,
34 				   bool interlace);
35 static bool hws_read_active_state(struct hws_pcie_dev *pdx, unsigned int ch,
36 				  bool *interlace);
37 static void handle_hwv2_path(struct hws_pcie_dev *hws, unsigned int ch);
38 static void handle_legacy_path(struct hws_pcie_dev *hws, unsigned int ch);
39 static u32 hws_calc_sizeimage(struct hws_video *v, u16 w, u16 h,
40 			      bool interlaced);
41 
42 /* DMA helper functions */
43 static void hws_program_dma_window(struct hws_video *vid, dma_addr_t dma);
44 static struct hwsvideo_buffer *
45 hws_take_queued_buffer_locked(struct hws_video *vid);
46 
47 static unsigned long long hws_elapsed_us(u64 start_ns)
48 {
49 	return div_u64(ktime_get_mono_fast_ns() - start_ns, 1000);
50 }
51 
52 static inline bool list_node_unlinked(const struct list_head *n)
53 {
54 	return n->next == LIST_POISON1 || n->prev == LIST_POISON2;
55 }
56 
57 static bool dma_window_verify;
58 module_param_named(dma_window_verify, dma_window_verify, bool, 0644);
59 MODULE_PARM_DESC(dma_window_verify,
60 		 "Read back DMA window registers after programming (debug)");
61 
62 void hws_set_dma_doorbell(struct hws_pcie_dev *hws, unsigned int ch,
63 			  dma_addr_t dma, const char *tag)
64 {
65 	iowrite32(lower_32_bits(dma), hws->bar0_base + HWS_REG_DMA_ADDR(ch));
66 	dev_dbg(&hws->pdev->dev, "dma_doorbell ch%u: dma=0x%llx tag=%s\n", ch,
67 		(u64)dma, tag ? tag : "");
68 }
69 
70 static void hws_program_dma_window(struct hws_video *vid, dma_addr_t dma)
71 {
72 	const u32 addr_mask = PCI_E_BAR_ADD_MASK;
73 	const u32 addr_low_mask = PCI_E_BAR_ADD_LOWMASK;
74 	struct hws_pcie_dev *hws = vid->parent;
75 	unsigned int ch = vid->channel_index;
76 	u32 table_off = HWS_REMAP_SLOT_OFF(ch);
77 	u32 lo = lower_32_bits(dma);
78 	u32 hi = upper_32_bits(dma);
79 	u32 pci_addr = lo & addr_low_mask;
80 	u32 page_lo = lo & addr_mask;
81 
82 	bool wrote = false;
83 
84 	/* Remap entry only when DMA crosses into a new 512 MB page */
85 	if (!vid->window_valid || vid->last_dma_hi != hi ||
86 	    vid->last_dma_page != page_lo) {
87 		writel(hi, hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off);
88 		writel(page_lo,
89 		       hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off +
90 		       PCIE_BARADDROFSIZE);
91 		vid->last_dma_hi = hi;
92 		vid->last_dma_page = page_lo;
93 		wrote = true;
94 	}
95 
96 	/* Base pointer only needs low 29 bits */
97 	if (!vid->window_valid || vid->last_pci_addr != pci_addr) {
98 		writel((ch + 1) * PCIEBAR_AXI_BASE + pci_addr,
99 		       hws->bar0_base + HWS_BUF_BASE_OFF(ch));
100 		vid->last_pci_addr = pci_addr;
101 		wrote = true;
102 	}
103 
104 	/* Half-size only changes when resolution changes */
105 	if (!vid->window_valid || vid->last_half16 != vid->pix.half_size / 16) {
106 		writel(vid->pix.half_size / 16,
107 		       hws->bar0_base + HWS_HALF_SZ_OFF(ch));
108 		vid->last_half16 = vid->pix.half_size / 16;
109 		wrote = true;
110 	}
111 
112 	vid->window_valid = true;
113 
114 	if (dma_window_verify && wrote) {
115 		u32 r_hi =
116 		    readl(hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off);
117 		u32 r_lo =
118 		    readl(hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off +
119 			  PCIE_BARADDROFSIZE);
120 		u32 r_base = readl(hws->bar0_base + HWS_BUF_BASE_OFF(ch));
121 		u32 r_half = readl(hws->bar0_base + HWS_HALF_SZ_OFF(ch));
122 
123 		dev_dbg(&hws->pdev->dev,
124 			"ch%u remap verify: hi=0x%08x page_lo=0x%08x exp_page=0x%08x base=0x%08x exp_base=0x%08x half16B=0x%08x exp_half=0x%08x\n",
125 			ch, r_hi, r_lo, page_lo, r_base,
126 			(ch + 1) * PCIEBAR_AXI_BASE + pci_addr, r_half,
127 			vid->pix.half_size / 16);
128 	} else if (wrote) {
129 		/* Flush posted writes before arming DMA */
130 		readl_relaxed(hws->bar0_base + HWS_HALF_SZ_OFF(ch));
131 	}
132 }
133 
134 static struct hwsvideo_buffer *
135 hws_take_queued_buffer_locked(struct hws_video *vid)
136 {
137 	struct hwsvideo_buffer *buf;
138 
139 	if (!vid || list_empty(&vid->capture_queue))
140 		return NULL;
141 
142 	buf = list_first_entry(&vid->capture_queue,
143 			       struct hwsvideo_buffer, list);
144 	list_del_init(&buf->list);
145 	if (vid->queued_count)
146 		vid->queued_count--;
147 	return buf;
148 }
149 
150 void hws_prime_next_locked(struct hws_video *vid)
151 {
152 	struct hws_pcie_dev *hws;
153 	struct hwsvideo_buffer *next;
154 	dma_addr_t dma;
155 
156 	if (!vid)
157 		return;
158 
159 	hws = vid->parent;
160 	if (!hws || !hws->bar0_base)
161 		return;
162 
163 	if (!READ_ONCE(vid->cap_active) || !vid->active || vid->next_prepared)
164 		return;
165 
166 	next = hws_take_queued_buffer_locked(vid);
167 	if (!next)
168 		return;
169 
170 	vid->next_prepared = next;
171 	dma = vb2_dma_contig_plane_dma_addr(&next->vb.vb2_buf, 0);
172 	hws_program_dma_for_addr(hws, vid->channel_index, dma);
173 	iowrite32(lower_32_bits(dma),
174 		  hws->bar0_base + HWS_REG_DMA_ADDR(vid->channel_index));
175 	dev_dbg(&hws->pdev->dev,
176 		"ch%u pre-armed next buffer %p dma=0x%llx\n",
177 		vid->channel_index, next, (u64)dma);
178 }
179 
180 static bool hws_force_no_signal_frame(struct hws_video *v, const char *tag)
181 {
182 	struct hws_pcie_dev *hws;
183 	unsigned long flags;
184 	struct hwsvideo_buffer *buf = NULL, *next = NULL;
185 	bool have_next = false;
186 	bool doorbell = false;
187 
188 	if (!v)
189 		return false;
190 	hws = v->parent;
191 	if (!hws || READ_ONCE(v->stop_requested) || !READ_ONCE(v->cap_active))
192 		return false;
193 	spin_lock_irqsave(&v->irq_lock, flags);
194 	if (v->active) {
195 		buf = v->active;
196 		v->active = NULL;
197 		buf->slot = 0;
198 	} else if (!list_empty(&v->capture_queue)) {
199 		buf = list_first_entry(&v->capture_queue,
200 				       struct hwsvideo_buffer, list);
201 		list_del_init(&buf->list);
202 		if (v->queued_count)
203 			v->queued_count--;
204 		buf->slot = 0;
205 	}
206 	if (v->next_prepared) {
207 		next = v->next_prepared;
208 		v->next_prepared = NULL;
209 		next->slot = 0;
210 		v->active = next;
211 		have_next = true;
212 	} else if (!list_empty(&v->capture_queue)) {
213 		next = list_first_entry(&v->capture_queue,
214 					struct hwsvideo_buffer, list);
215 		list_del_init(&next->list);
216 		if (v->queued_count)
217 			v->queued_count--;
218 		next->slot = 0;
219 		v->active = next;
220 		have_next = true;
221 	} else {
222 		v->active = NULL;
223 	}
224 	spin_unlock_irqrestore(&v->irq_lock, flags);
225 	if (!buf)
226 		return false;
227 	/* Complete buffer with a neutral frame so dequeuers keep running. */
228 	{
229 		struct vb2_v4l2_buffer *vb2v = &buf->vb;
230 		void *dst = vb2_plane_vaddr(&vb2v->vb2_buf, 0);
231 
232 		if (dst)
233 			memset(dst, 0x10, v->pix.sizeimage);
234 		vb2_set_plane_payload(&vb2v->vb2_buf, 0, v->pix.sizeimage);
235 		vb2v->sequence = (u32)atomic_inc_return(&v->sequence_number);
236 		vb2v->vb2_buf.timestamp = ktime_get_ns();
237 		vb2_buffer_done(&vb2v->vb2_buf, VB2_BUF_STATE_DONE);
238 	}
239 	if (have_next && next) {
240 		dma_addr_t dma =
241 		    vb2_dma_contig_plane_dma_addr(&next->vb.vb2_buf, 0);
242 		hws_program_dma_for_addr(hws, v->channel_index, dma);
243 		hws_set_dma_doorbell(hws, v->channel_index, dma,
244 				     tag ? tag : "nosignal_zero");
245 		doorbell = true;
246 	}
247 	if (doorbell) {
248 		wmb(); /* ensure descriptors visible before enabling capture */
249 		hws_enable_video_capture(hws, v->channel_index, true);
250 	}
251 	return true;
252 }
253 
254 static int hws_ctrls_init(struct hws_video *vid)
255 {
256 	struct v4l2_ctrl_handler *hdl = &vid->control_handler;
257 
258 	/* Create BCHS controls. */
259 	v4l2_ctrl_handler_init(hdl, 4);
260 
261 	vid->ctrl_brightness = v4l2_ctrl_new_std(hdl, &hws_ctrl_ops,
262 						 V4L2_CID_BRIGHTNESS,
263 						 MIN_VAMP_BRIGHTNESS_UNITS,
264 						 MAX_VAMP_BRIGHTNESS_UNITS, 1,
265 						 HWS_BRIGHTNESS_DEFAULT);
266 
267 	vid->ctrl_contrast =
268 	    v4l2_ctrl_new_std(hdl, &hws_ctrl_ops, V4L2_CID_CONTRAST,
269 			      MIN_VAMP_CONTRAST_UNITS, MAX_VAMP_CONTRAST_UNITS,
270 			      1, HWS_CONTRAST_DEFAULT);
271 
272 	vid->ctrl_saturation = v4l2_ctrl_new_std(hdl, &hws_ctrl_ops,
273 						 V4L2_CID_SATURATION,
274 						 MIN_VAMP_SATURATION_UNITS,
275 						 MAX_VAMP_SATURATION_UNITS, 1,
276 						 HWS_SATURATION_DEFAULT);
277 
278 	vid->ctrl_hue = v4l2_ctrl_new_std(hdl, &hws_ctrl_ops, V4L2_CID_HUE,
279 					  MIN_VAMP_HUE_UNITS,
280 					  MAX_VAMP_HUE_UNITS, 1,
281 					  HWS_HUE_DEFAULT);
282 	if (hdl->error) {
283 		int err = hdl->error;
284 
285 		v4l2_ctrl_handler_free(hdl);
286 		return err;
287 	}
288 	return 0;
289 }
290 
291 int hws_video_init_channel(struct hws_pcie_dev *pdev, int ch)
292 {
293 	struct hws_video *vid;
294 
295 	/* basic sanity */
296 	if (!pdev || ch < 0 || ch >= pdev->max_channels)
297 		return -EINVAL;
298 
299 	vid = &pdev->video[ch];
300 
301 	/* hard reset the per-channel struct (safe here since we init everything next) */
302 	memset(vid, 0, sizeof(*vid));
303 
304 	/* identity */
305 	vid->parent = pdev;
306 	vid->channel_index = ch;
307 
308 	/* locks & lists */
309 	mutex_init(&vid->state_lock);
310 	spin_lock_init(&vid->irq_lock);
311 	INIT_LIST_HEAD(&vid->capture_queue);
312 	atomic_set(&vid->sequence_number, 0);
313 	vid->active = NULL;
314 
315 	/* DMA watchdog removed; retain counters for diagnostics */
316 	vid->timeout_count = 0;
317 	vid->error_count = 0;
318 
319 	vid->queued_count = 0;
320 	vid->window_valid = false;
321 
322 	/* Default format. */
323 	vid->pix.width = 1920;
324 	vid->pix.height = 1080;
325 	vid->pix.fourcc = V4L2_PIX_FMT_YUYV;
326 	vid->pix.bytesperline = ALIGN(vid->pix.width * 2, 64);
327 	vid->pix.sizeimage = vid->pix.bytesperline * vid->pix.height;
328 	vid->pix.field = V4L2_FIELD_NONE;
329 	vid->pix.colorspace = V4L2_COLORSPACE_REC709;
330 	vid->pix.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
331 	vid->pix.quantization = V4L2_QUANTIZATION_FULL_RANGE;
332 	vid->pix.xfer_func = V4L2_XFER_FUNC_DEFAULT;
333 	vid->pix.interlaced = false;
334 	vid->pix.half_size = vid->pix.sizeimage / 2;
335 	hws_set_current_dv_timings(vid, vid->pix.width,
336 				   vid->pix.height, vid->pix.interlaced);
337 	vid->current_fps = 60;
338 
339 	/* color controls default (mid-scale) */
340 	vid->current_brightness = 0x80;
341 	vid->current_contrast = 0x80;
342 	vid->current_saturation = 0x80;
343 	vid->current_hue = 0x80;
344 
345 	/* capture state */
346 	vid->cap_active = false;
347 	vid->stop_requested = false;
348 	vid->last_buf_half_toggle = 0;
349 	vid->half_seen = false;
350 	vid->signal_loss_cnt = 0;
351 
352 	/* Create BCHS + DV power-present as modern controls */
353 	{
354 		int err = hws_ctrls_init(vid);
355 
356 		if (err) {
357 			dev_err(&pdev->pdev->dev,
358 				"v4l2 ctrl init failed on ch%d: %d\n", ch, err);
359 			return err;
360 		}
361 	}
362 
363 	return 0;
364 }
365 
366 static void hws_video_drain_queue_locked(struct hws_video *vid)
367 {
368 	/* Return in-flight first */
369 	if (vid->active) {
370 		vb2_buffer_done(&vid->active->vb.vb2_buf, VB2_BUF_STATE_ERROR);
371 		vid->active = NULL;
372 	}
373 
374 	/* Then everything queued */
375 	while (!list_empty(&vid->capture_queue)) {
376 		struct hwsvideo_buffer *b =
377 		    list_first_entry(&vid->capture_queue,
378 				     struct hwsvideo_buffer,
379 				     list);
380 		list_del_init(&b->list);
381 		vb2_buffer_done(&b->vb.vb2_buf, VB2_BUF_STATE_ERROR);
382 	}
383 }
384 
385 static void hws_video_release_registration(struct hws_video *vid)
386 {
387 	if (vid->buffer_queue.ops) {
388 		vb2_queue_release(&vid->buffer_queue);
389 		vid->buffer_queue.ops = NULL;
390 	}
391 
392 	if (!vid->video_device)
393 		return;
394 
395 	if (video_is_registered(vid->video_device))
396 		vb2_video_unregister_device(vid->video_device);
397 	else
398 		video_device_release(vid->video_device);
399 	vid->video_device = NULL;
400 }
401 
402 static void hws_video_collect_done_locked(struct hws_video *vid,
403 					  struct list_head *done)
404 {
405 	struct hwsvideo_buffer *b;
406 
407 	if (vid->active) {
408 		if (!list_node_unlinked(&vid->active->list)) {
409 			list_move_tail(&vid->active->list, done);
410 		} else {
411 			INIT_LIST_HEAD(&vid->active->list);
412 			list_add_tail(&vid->active->list, done);
413 		}
414 		vid->active = NULL;
415 	}
416 
417 	if (vid->next_prepared) {
418 		if (!list_node_unlinked(&vid->next_prepared->list)) {
419 			list_move_tail(&vid->next_prepared->list, done);
420 		} else {
421 			INIT_LIST_HEAD(&vid->next_prepared->list);
422 			list_add_tail(&vid->next_prepared->list, done);
423 		}
424 		vid->next_prepared = NULL;
425 	}
426 
427 	while (!list_empty(&vid->capture_queue)) {
428 		b = list_first_entry(&vid->capture_queue, struct hwsvideo_buffer,
429 				     list);
430 		list_move_tail(&b->list, done);
431 	}
432 
433 	vid->queued_count = 0;
434 }
435 
436 void hws_video_cleanup_channel(struct hws_pcie_dev *pdev, int ch)
437 {
438 	struct hws_video *vid;
439 	unsigned long flags;
440 
441 	if (!pdev || ch < 0 || ch >= pdev->max_channels)
442 		return;
443 
444 	vid = &pdev->video[ch];
445 
446 	/* 1) Stop HW best-effort for this channel */
447 	hws_enable_video_capture(vid->parent, vid->channel_index, false);
448 
449 	/* 2) Flip software state so IRQ/BH will be no-ops if they run */
450 	WRITE_ONCE(vid->stop_requested, true);
451 	WRITE_ONCE(vid->cap_active, false);
452 
453 	/* 3) Ensure the IRQ handler finished any in-flight completions */
454 	if (vid->parent && vid->parent->irq >= 0)
455 		synchronize_irq(vid->parent->irq);
456 
457 	/* 4) Drain SW capture queue & in-flight under lock */
458 	spin_lock_irqsave(&vid->irq_lock, flags);
459 	hws_video_drain_queue_locked(vid);
460 	spin_unlock_irqrestore(&vid->irq_lock, flags);
461 
462 	/* 5) Release VB2 queue if initialized */
463 	hws_video_release_registration(vid);
464 
465 	/* 6) Free V4L2 controls */
466 	v4l2_ctrl_handler_free(&vid->control_handler);
467 
468 	/* 8) Reset simple state; do not memset the whole struct here. */
469 	mutex_destroy(&vid->state_lock);
470 	INIT_LIST_HEAD(&vid->capture_queue);
471 	vid->active = NULL;
472 	vid->stop_requested = false;
473 	vid->last_buf_half_toggle = 0;
474 	vid->half_seen = false;
475 	vid->signal_loss_cnt = 0;
476 }
477 
478 /* Convenience cast */
479 static inline struct hwsvideo_buffer *to_hwsbuf(struct vb2_buffer *vb)
480 {
481 	return container_of(to_vb2_v4l2_buffer(vb), struct hwsvideo_buffer, vb);
482 }
483 
484 static int hws_buf_init(struct vb2_buffer *vb)
485 {
486 	struct hwsvideo_buffer *b = to_hwsbuf(vb);
487 
488 	INIT_LIST_HEAD(&b->list);
489 	return 0;
490 }
491 
492 static void hws_buf_finish(struct vb2_buffer *vb)
493 {
494 	/* vb2 core handles cache maintenance for dma-contig buffers */
495 	(void)vb;
496 }
497 
498 static void hws_buf_cleanup(struct vb2_buffer *vb)
499 {
500 	struct hwsvideo_buffer *b = to_hwsbuf(vb);
501 
502 	if (!list_empty(&b->list))
503 		list_del_init(&b->list);
504 }
505 
506 void hws_program_dma_for_addr(struct hws_pcie_dev *hws, unsigned int ch,
507 			      dma_addr_t dma)
508 {
509 	struct hws_video *vid = &hws->video[ch];
510 
511 	hws_program_dma_window(vid, dma);
512 }
513 
514 void hws_enable_video_capture(struct hws_pcie_dev *hws, unsigned int chan,
515 			      bool on)
516 {
517 	u32 status;
518 
519 	if (!hws || hws->pci_lost || chan >= hws->max_channels)
520 		return;
521 
522 	status = readl(hws->bar0_base + HWS_REG_VCAP_ENABLE);
523 	status = on ? (status | BIT(chan)) : (status & ~BIT(chan));
524 	writel(status, hws->bar0_base + HWS_REG_VCAP_ENABLE);
525 	(void)readl(hws->bar0_base + HWS_REG_VCAP_ENABLE);
526 
527 	WRITE_ONCE(hws->video[chan].cap_active, on);
528 
529 	dev_dbg(&hws->pdev->dev, "vcap %s ch%u (reg=0x%08x)\n",
530 		on ? "ON" : "OFF", chan, status);
531 }
532 
533 static void hws_seed_dma_windows(struct hws_pcie_dev *hws)
534 {
535 	const u32 addr_mask = PCI_E_BAR_ADD_MASK;
536 	const u32 addr_low_mask = PCI_E_BAR_ADD_LOWMASK;
537 	u32 table = 0x208;	/* one 64-bit entry per channel */
538 	unsigned int ch;
539 
540 	if (!hws || !hws->bar0_base)
541 		return;
542 
543 	/* If cur_max_video_ch is not set yet, default to max_channels. */
544 	if (!hws->cur_max_video_ch || hws->cur_max_video_ch > hws->max_channels)
545 		hws->cur_max_video_ch = hws->max_channels;
546 
547 	for (ch = 0; ch < hws->cur_max_video_ch; ch++, table += 8) {
548 		if (!hws->scratch_vid[ch].cpu)
549 			continue;
550 
551 		/* Program 64-bit BAR remap entry for this channel */
552 		{
553 			dma_addr_t p = hws->scratch_vid[ch].dma;
554 			u32 lo = lower_32_bits(p) & addr_mask;
555 			u32 hi = upper_32_bits(p);
556 			u32 pci_addr_low = lower_32_bits(p) & addr_low_mask;
557 
558 			writel_relaxed(hi,
559 				       hws->bar0_base + PCI_ADDR_TABLE_BASE +
560 				       table);
561 			writel_relaxed(lo,
562 				       hws->bar0_base + PCI_ADDR_TABLE_BASE +
563 				       table + PCIE_BARADDROFSIZE);
564 
565 			/* Per-channel AXI base + PCI low */
566 			writel_relaxed((ch + 1) * PCIEBAR_AXI_BASE +
567 				       pci_addr_low,
568 				       hws->bar0_base + CVBS_IN_BUF_BASE +
569 				       ch * PCIE_BARADDROFSIZE);
570 
571 			/* Half-frame length in /16 units.
572 			 * Prefer the current channel's computed half_size if available.
573 			 * Fall back to half of the probe-owned scratch buffer.
574 			 */
575 			{
576 				u32 half_bytes = hws->video[ch].pix.half_size ?
577 				    hws->video[ch].pix.half_size :
578 				    (u32)(hws->scratch_vid[ch].size / 2);
579 				writel_relaxed(half_bytes / 16,
580 					       hws->bar0_base +
581 					       CVBS_IN_BUF_BASE2 +
582 					       ch * PCIE_BARADDROFSIZE);
583 			}
584 		}
585 	}
586 
587 	/* Post writes so device sees them before we move on */
588 	(void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
589 }
590 
591 static void hws_ack_all_irqs(struct hws_pcie_dev *hws)
592 {
593 	u32 st = readl(hws->bar0_base + HWS_REG_INT_STATUS);
594 
595 	if (st) {
596 		writel(st, hws->bar0_base + HWS_REG_INT_STATUS);	/* W1C */
597 		(void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
598 	}
599 }
600 
601 static void hws_open_irq_fabric(struct hws_pcie_dev *hws)
602 {
603 	/* Route all sources to vector 0. */
604 	writel(0x00000000, hws->bar0_base + PCIE_INT_DEC_REG_BASE);
605 	(void)readl(hws->bar0_base + PCIE_INT_DEC_REG_BASE);
606 
607 	/* Enable the PCIe bridge. */
608 	writel(0x00000001, hws->bar0_base + PCIEBR_EN_REG_BASE);
609 	(void)readl(hws->bar0_base + PCIEBR_EN_REG_BASE);
610 
611 	/* Open the global/bridge gate (legacy 0x3FFFF) */
612 	writel(HWS_INT_EN_MASK, hws->bar0_base + INT_EN_REG_BASE);
613 	(void)readl(hws->bar0_base + INT_EN_REG_BASE);
614 }
615 
616 void hws_init_video_sys(struct hws_pcie_dev *hws, bool enable)
617 {
618 	int i;
619 
620 	if (hws->start_run && !enable)
621 		return;
622 
623 	/* 1) reset the decoder mode register to 0 */
624 	writel(0x00000000, hws->bar0_base + HWS_REG_DEC_MODE);
625 	hws_seed_dma_windows(hws);
626 
627 	/* 3) on a full reset, clear all per-channel status and indices */
628 	if (!enable) {
629 		for (i = 0; i < hws->max_channels; i++) {
630 			/* helpers to arm/disable capture engines */
631 			hws_enable_video_capture(hws, i, false);
632 		}
633 	}
634 
635 	/* 4) Start run: set bit31, wait a bit, then program low 24 bits. */
636 	writel(0x80000000, hws->bar0_base + HWS_REG_DEC_MODE);
637 	writel(0x80FFFFFF, hws->bar0_base + HWS_REG_DEC_MODE);
638 	writel(0x13, hws->bar0_base + HWS_REG_DEC_MODE);
639 	hws_ack_all_irqs(hws);
640 	hws_open_irq_fabric(hws);
641 	/* 6) record that we're now running */
642 	hws->start_run = true;
643 }
644 
645 int hws_check_card_status(struct hws_pcie_dev *hws)
646 {
647 	u32 status;
648 
649 	if (!hws || !hws->bar0_base)
650 		return -ENODEV;
651 
652 	status = readl(hws->bar0_base + HWS_REG_SYS_STATUS);
653 
654 	/* Common device-missing pattern. */
655 	if (status == 0xFFFFFFFF) {
656 		hws->pci_lost = true;
657 		dev_err(&hws->pdev->dev, "PCIe device not responding\n");
658 		return -ENODEV;
659 	}
660 
661 	/* If RUN/READY bit (bit0) is not set, reinitialize the video core. */
662 	if (!(status & BIT(0))) {
663 		dev_dbg(&hws->pdev->dev,
664 			"SYS_STATUS not ready (0x%08x), reinitializing\n",
665 			status);
666 		hws_init_video_sys(hws, true);
667 	}
668 
669 	return 0;
670 }
671 
672 void check_video_format(struct hws_pcie_dev *pdx)
673 {
674 	int i;
675 
676 	for (i = 0; i < pdx->cur_max_video_ch; i++) {
677 		bool interlace = false;
678 
679 		if (!hws_read_active_state(pdx, i, &interlace)) {
680 			/* No active video; optionally feed neutral frames to keep streaming. */
681 			if (pdx->video[i].signal_loss_cnt == 0)
682 				pdx->video[i].signal_loss_cnt = 1;
683 			if (READ_ONCE(pdx->video[i].cap_active))
684 				hws_force_no_signal_frame(&pdx->video[i],
685 							  "monitor_nosignal");
686 		} else {
687 			if (pdx->hw_ver > 0)
688 				handle_hwv2_path(pdx, i);
689 			else
690 				/* Legacy path stub; see handle_legacy_path() comment. */
691 				handle_legacy_path(pdx, i);
692 
693 			update_live_resolution(pdx, i, interlace);
694 			pdx->video[i].signal_loss_cnt = 0;
695 		}
696 	}
697 }
698 
699 static inline void hws_write_if_diff(struct hws_pcie_dev *hws, u32 reg_off,
700 				     u32 new_val)
701 {
702 	void __iomem *addr;
703 	u32 old;
704 
705 	if (!hws || !hws->bar0_base)
706 		return;
707 
708 	addr = hws->bar0_base + reg_off;
709 
710 	old = readl(addr);
711 	/* Treat all-ones as device gone; avoid writing garbage. */
712 	if (old == 0xFFFFFFFF) {
713 		hws->pci_lost = true;
714 		return;
715 	}
716 
717 	if (old != new_val) {
718 		writel(new_val, addr);
719 		/* Post the write on some bridges / enforce ordering. */
720 		(void)readl(addr);
721 	}
722 }
723 
724 static bool hws_read_active_state(struct hws_pcie_dev *pdx, unsigned int ch,
725 				  bool *interlace)
726 {
727 	u32 reg;
728 	bool active;
729 
730 	if (ch >= pdx->cur_max_video_ch)
731 		return false;
732 
733 	reg = readl(pdx->bar0_base + HWS_REG_ACTIVE_STATUS);
734 	active = !!(reg & BIT(ch));
735 	if (interlace)
736 		*interlace = !!(reg & BIT(8 + ch));
737 	return active;
738 }
739 
740 /* Modern hardware path: keep HW registers in sync with current per-channel
741  * software state.
742  */
743 static void handle_hwv2_path(struct hws_pcie_dev *hws, unsigned int ch)
744 {
745 	struct hws_video *vid;
746 	u32 reg, in_fps, cur_out_res, want_out_res;
747 
748 	if (!hws || !hws->bar0_base || ch >= hws->max_channels)
749 		return;
750 
751 	vid = &hws->video[ch];
752 
753 	/* 1) Input frame rate (read-only; log or export via debugfs if wanted) */
754 	in_fps = readl(hws->bar0_base + HWS_REG_FRAME_RATE(ch));
755 	/* dev_dbg(&hws->pdev->dev, "ch%u input fps=%u\n", ch, in_fps); */
756 	(void)in_fps;
757 
758 	/* 2) Output resolution programming.
759 	 * For now, mirror the current format to OUT_RES.
760 	 */
761 	want_out_res = (vid->pix.height << 16) | vid->pix.width;
762 	cur_out_res = readl(hws->bar0_base + HWS_REG_OUT_RES(ch));
763 	if (cur_out_res != want_out_res)
764 		hws_write_if_diff(hws, HWS_REG_OUT_RES(ch), want_out_res);
765 
766 	/* 3) Output FPS: only program if you actually track a target.
767 	 * Example heuristic (disabled by default):
768 	 *
769 	 *   u32 out_fps = (vid->fmt_curr.height >= 1080) ? 60 : 30;
770 	 *   hws_write_if_diff(hws, HWS_REG_OUT_FRAME_RATE(ch), out_fps);
771 	 */
772 
773 	/* 4) BCHS controls: pack from per-channel current_* fields */
774 	reg = readl(hws->bar0_base + HWS_REG_BCHS(ch));
775 	{
776 		u8 br = reg & 0xFF;
777 		u8 co = (reg >> 8) & 0xFF;
778 		u8 hu = (reg >> 16) & 0xFF;
779 		u8 sa = (reg >> 24) & 0xFF;
780 
781 		if (br != vid->current_brightness ||
782 		    co != vid->current_contrast || hu != vid->current_hue ||
783 		    sa != vid->current_saturation) {
784 			u32 packed = (vid->current_saturation << 24) |
785 			    (vid->current_hue << 16) |
786 			    (vid->current_contrast << 8) |
787 			    vid->current_brightness;
788 			hws_write_if_diff(hws, HWS_REG_BCHS(ch), packed);
789 		}
790 	}
791 
792 	/* 5) HDCP detect: read only (no cache field in your structs today) */
793 	reg = readl(hws->bar0_base + HWS_REG_HDCP_STATUS);
794 	/* bool hdcp = !!(reg & BIT(ch)); // use if you later add a field/control */
795 }
796 
797 static void handle_legacy_path(struct hws_pcie_dev *hws, unsigned int ch)
798 {
799 	/*
800 	 * Legacy (hw_ver == 0) expected behavior:
801 	 * - A per-channel SW FPS accumulator incremented on each VDONE.
802 	 * - A once-per-second poll mapped the count to discrete FPS:
803 	 *   >55*2 => 60, >45*2 => 50, >25*2 => 30, >20*2 => 25, else 60,
804 	 *   then reset the accumulator to 0.
805 	 * - The *2 factor assumed VDONE fired per-field; if legacy VDONE is
806 	 *   per-frame, drop the factor.
807 	 *
808 	 * Current code keeps this path as a no-op; vid->current_fps stays at the
809 	 * default or mode-derived value. If accurate legacy FPS reporting is
810 	 * needed (V4L2 g_parm/timeperframe), reintroduce the accumulator in the
811 	 * IRQ path and perform the mapping/reset here.
812 	 *
813 	 * No-op by default. If you introduce a SW FPS accumulator, map it here.
814 	 *
815 	 * Example skeleton:
816 	 *
817 	 *   u32 sw_rate = READ_ONCE(hws->sw_fps[ch]); // incremented elsewhere
818 	 *   if (sw_rate > THRESHOLD) {
819 	 *       u32 fps = pick_fps_from_rate(sw_rate);
820 	 *       hws_write_if_diff(hws, HWS_REG_OUT_FRAME_RATE(ch), fps);
821 	 *       WRITE_ONCE(hws->sw_fps[ch], 0);
822 	 *   }
823 	 */
824 	(void)hws;
825 	(void)ch;
826 }
827 
828 static void hws_video_apply_mode_change(struct hws_pcie_dev *pdx,
829 					unsigned int ch, u16 w, u16 h,
830 					bool interlaced, u32 fps)
831 {
832 	struct hws_video *v = &pdx->video[ch];
833 	unsigned long flags;
834 	bool queue_busy;
835 	bool geometry_changed;
836 	struct list_head done;
837 	struct hwsvideo_buffer *b, *tmp;
838 
839 	if (!pdx || !pdx->bar0_base)
840 		return;
841 	if (ch >= pdx->max_channels)
842 		return;
843 	if (!w || !h || w > MAX_VIDEO_HW_W ||
844 	    (!interlaced && h > MAX_VIDEO_HW_H) ||
845 	    (interlaced && (h * 2) > MAX_VIDEO_HW_H))
846 		return;
847 	if (!fps || fps == 0xFFFFFFFF || fps > 240)
848 		fps = (h == 576) ? 50 : 60;
849 
850 	geometry_changed = w != v->pix.width || h != v->pix.height ||
851 		interlaced != v->pix.interlaced;
852 	if (!geometry_changed && fps == v->current_fps)
853 		return;
854 
855 	if (!geometry_changed) {
856 		/* Refresh cached live timing state, but don't emit a resolution
857 		 * change event when only the frame rate changes.
858 		 */
859 		mutex_lock(&v->state_lock);
860 		v->pix.interlaced = interlaced;
861 		v->pix.field = interlaced ? V4L2_FIELD_INTERLACED :
862 					    V4L2_FIELD_NONE;
863 		hws_set_current_dv_timings(v, w, h, interlaced);
864 		v->current_fps = fps;
865 		mutex_unlock(&v->state_lock);
866 		return;
867 	}
868 
869 	if (!mutex_trylock(&v->state_lock))
870 		return;
871 
872 	INIT_LIST_HEAD(&done);
873 	queue_busy = vb2_is_busy(&v->buffer_queue);
874 
875 	WRITE_ONCE(v->stop_requested, true);
876 	WRITE_ONCE(v->cap_active, false);
877 	/* Publish software stop first so the IRQ completion path sees the stop
878 	 * before we touch MMIO or the lists. Pairs with READ_ONCE() checks in the
879 	 * VDONE handler and hws_arm_next() to prevent completions while modes
880 	 * change.
881 	 */
882 	smp_wmb();
883 
884 	hws_enable_video_capture(pdx, ch, false);
885 	readl(pdx->bar0_base + HWS_REG_INT_STATUS);
886 
887 	if (v->parent && v->parent->irq >= 0)
888 		synchronize_irq(v->parent->irq);
889 
890 	spin_lock_irqsave(&v->irq_lock, flags);
891 	hws_video_collect_done_locked(v, &done);
892 	spin_unlock_irqrestore(&v->irq_lock, flags);
893 
894 	/* Update software pixel state */
895 	v->pix.width = w;
896 	v->pix.height = h;
897 	v->pix.interlaced = interlaced;
898 	hws_set_current_dv_timings(v, w, h, interlaced);
899 	v->current_fps = fps;
900 
901 	hws_calc_sizeimage(v, w, h, interlaced);
902 	v->window_valid = false;
903 
904 	/* Geometry changes require userspace renegotiation once buffers exist.
905 	 * Emit SOURCE_CHANGE, mark the queue in error, and let userspace
906 	 * STREAMOFF/REQBUFS/STREAMON rather than trying to restart capture
907 	 * with partially drained in-flight state.
908 	 */
909 	if (queue_busy) {
910 		struct v4l2_event ev = {
911 			.type = V4L2_EVENT_SOURCE_CHANGE,
912 		};
913 
914 		ev.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION;
915 		v4l2_event_queue(v->video_device, &ev);
916 		vb2_queue_error(&v->buffer_queue);
917 	} else {
918 		WRITE_ONCE(v->stop_requested, false);
919 	}
920 
921 	/* Program HW with new resolution */
922 	hws_write_if_diff(pdx, HWS_REG_OUT_RES(ch), (h << 16) | w);
923 
924 	/* Legacy half-buffer programming */
925 	writel(v->pix.half_size / 16,
926 	       pdx->bar0_base + CVBS_IN_BUF_BASE2 + ch * PCIE_BARADDROFSIZE);
927 	(void)readl(pdx->bar0_base + CVBS_IN_BUF_BASE2 +
928 		    ch * PCIE_BARADDROFSIZE);
929 
930 	/* Reset per-channel toggles/counters */
931 	WRITE_ONCE(v->last_buf_half_toggle, 0);
932 	atomic_set(&v->sequence_number, 0);
933 
934 	mutex_unlock(&v->state_lock);
935 
936 	list_for_each_entry_safe(b, tmp, &done, list) {
937 		list_del_init(&b->list);
938 		vb2_buffer_done(&b->vb.vb2_buf, VB2_BUF_STATE_ERROR);
939 	}
940 }
941 
942 static void update_live_resolution(struct hws_pcie_dev *pdx, unsigned int ch,
943 				   bool interlace)
944 {
945 	u32 reg = readl(pdx->bar0_base + HWS_REG_IN_RES(ch));
946 	u32 fps = readl(pdx->bar0_base + HWS_REG_FRAME_RATE(ch));
947 	u16 res_w = reg & 0xFFFF;
948 	u16 res_h = (reg >> 16) & 0xFFFF;
949 	struct hws_video *vid = &pdx->video[ch];
950 	bool geometry_changed;
951 	bool fps_changed;
952 
953 	bool within_hw = (res_w <= MAX_VIDEO_HW_W) &&
954 	    ((!interlace && res_h <= MAX_VIDEO_HW_H) ||
955 	     (interlace && (res_h * 2) <= MAX_VIDEO_HW_H));
956 
957 	if (!within_hw)
958 		return;
959 
960 	geometry_changed = res_w != vid->pix.width ||
961 		res_h != vid->pix.height ||
962 		interlace != vid->pix.interlaced;
963 	fps_changed = fps && fps != 0xFFFFFFFF && fps <= 240 &&
964 		fps != vid->current_fps;
965 
966 	if (geometry_changed || fps_changed)
967 		hws_video_apply_mode_change(pdx, ch, res_w, res_h, interlace,
968 					    fps);
969 }
970 
971 static int hws_open(struct file *file)
972 {
973 	return v4l2_fh_open(file);
974 }
975 
976 static const struct v4l2_file_operations hws_fops = {
977 	.owner = THIS_MODULE,
978 	.open = hws_open,
979 	.release = vb2_fop_release,
980 	.poll = vb2_fop_poll,
981 	.unlocked_ioctl = video_ioctl2,
982 	.mmap = vb2_fop_mmap,
983 };
984 
985 static int hws_subscribe_event(struct v4l2_fh *fh,
986 			       const struct v4l2_event_subscription *sub)
987 {
988 	switch (sub->type) {
989 	case V4L2_EVENT_SOURCE_CHANGE:
990 		return v4l2_src_change_event_subscribe(fh, sub);
991 	case V4L2_EVENT_CTRL:
992 		return v4l2_ctrl_subscribe_event(fh, sub);
993 	default:
994 		return -EINVAL;
995 	}
996 }
997 
998 static const struct v4l2_ioctl_ops hws_ioctl_fops = {
999 	/* Core caps/info */
1000 	.vidioc_querycap = hws_vidioc_querycap,
1001 
1002 	/* Pixel format: still needed to report YUYV etc. */
1003 	.vidioc_enum_fmt_vid_cap = hws_vidioc_enum_fmt_vid_cap,
1004 	.vidioc_g_fmt_vid_cap = hws_vidioc_g_fmt_vid_cap,
1005 	.vidioc_s_fmt_vid_cap = hws_vidioc_s_fmt_vid_cap,
1006 	.vidioc_try_fmt_vid_cap = hws_vidioc_try_fmt_vid_cap,
1007 
1008 	/* Buffer queueing / streaming */
1009 	.vidioc_reqbufs = vb2_ioctl_reqbufs,
1010 	.vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1011 	.vidioc_create_bufs = vb2_ioctl_create_bufs,
1012 	.vidioc_querybuf = vb2_ioctl_querybuf,
1013 	.vidioc_qbuf = vb2_ioctl_qbuf,
1014 	.vidioc_dqbuf = vb2_ioctl_dqbuf,
1015 	.vidioc_expbuf = vb2_ioctl_expbuf,
1016 	.vidioc_streamon = vb2_ioctl_streamon,
1017 	.vidioc_streamoff = vb2_ioctl_streamoff,
1018 
1019 	/* Inputs */
1020 	.vidioc_enum_input = hws_vidioc_enum_input,
1021 	.vidioc_g_input = hws_vidioc_g_input,
1022 	.vidioc_s_input = hws_vidioc_s_input,
1023 
1024 	/* DV timings (HDMI/DVI/VESA modes) */
1025 	.vidioc_query_dv_timings = hws_vidioc_query_dv_timings,
1026 	.vidioc_enum_dv_timings = hws_vidioc_enum_dv_timings,
1027 	.vidioc_g_dv_timings = hws_vidioc_g_dv_timings,
1028 	.vidioc_s_dv_timings = hws_vidioc_s_dv_timings,
1029 	.vidioc_dv_timings_cap = hws_vidioc_dv_timings_cap,
1030 
1031 	.vidioc_log_status = v4l2_ctrl_log_status,
1032 	.vidioc_subscribe_event = hws_subscribe_event,
1033 	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1034 	.vidioc_g_parm = hws_vidioc_g_parm,
1035 };
1036 
1037 static u32 hws_calc_sizeimage(struct hws_video *v, u16 w, u16 h,
1038 			      bool interlaced)
1039 {
1040 	/* HWS captures packed YUYV only; stride is 16 bpp aligned to 64 bytes. */
1041 	u32 lines = h;		/* full frame lines for sizeimage */
1042 	u32 bytesperline = ALIGN(w * 2, 64);
1043 	u32 sizeimage, half0;
1044 
1045 	/* publish into pix, since we now carry these in-state */
1046 	v->pix.bytesperline = bytesperline;
1047 	sizeimage = bytesperline * lines;
1048 
1049 	half0 = sizeimage / 2;
1050 
1051 	v->pix.sizeimage = sizeimage;
1052 	v->pix.half_size = half0;	/* first half; second = sizeimage - half0 */
1053 	v->pix.field = interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
1054 
1055 	return v->pix.sizeimage;
1056 }
1057 
1058 static int hws_queue_setup(struct vb2_queue *q, unsigned int *num_buffers,
1059 			   unsigned int *nplanes, unsigned int sizes[],
1060 			   struct device *alloc_devs[])
1061 {
1062 	struct hws_video *vid = q->drv_priv;
1063 
1064 	if (*nplanes) {
1065 		if (sizes[0] < vid->pix.sizeimage)
1066 			return -EINVAL;
1067 	} else {
1068 		*nplanes = 1;
1069 		sizes[0] = vid->pix.sizeimage;
1070 	}
1071 
1072 	return 0;
1073 }
1074 
1075 static int hws_buffer_prepare(struct vb2_buffer *vb)
1076 {
1077 	struct hws_video *vid = vb->vb2_queue->drv_priv;
1078 	struct hws_pcie_dev *hws = vid->parent;
1079 	size_t need = vid->pix.sizeimage;
1080 	dma_addr_t dma_addr;
1081 
1082 	if (vb2_plane_size(vb, 0) < need)
1083 		return -EINVAL;
1084 
1085 	/* Validate DMA address alignment */
1086 	dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1087 	if (dma_addr & 0x3F) {	/* 64-byte alignment required */
1088 		dev_err(&hws->pdev->dev,
1089 			"Buffer DMA address 0x%llx not 64-byte aligned\n",
1090 			(unsigned long long)dma_addr);
1091 		return -EINVAL;
1092 	}
1093 
1094 	vb2_set_plane_payload(vb, 0, need);
1095 	return 0;
1096 }
1097 
1098 static void hws_buffer_queue(struct vb2_buffer *vb)
1099 {
1100 	struct hws_video *vid = vb->vb2_queue->drv_priv;
1101 	struct hwsvideo_buffer *buf = to_hwsbuf(vb);
1102 	struct hws_pcie_dev *hws = vid->parent;
1103 	unsigned long flags;
1104 
1105 	dev_dbg(&hws->pdev->dev,
1106 		"buffer_queue(ch=%u): vb=%p sizeimage=%u q_active=%d\n",
1107 		vid->channel_index, vb, vid->pix.sizeimage,
1108 		READ_ONCE(vid->cap_active));
1109 
1110 	/* Initialize buffer slot */
1111 	buf->slot = 0;
1112 
1113 	spin_lock_irqsave(&vid->irq_lock, flags);
1114 	list_add_tail(&buf->list, &vid->capture_queue);
1115 	vid->queued_count++;
1116 
1117 	/* If streaming and no in-flight buffer, prime HW immediately */
1118 	if (READ_ONCE(vid->cap_active) && !vid->active) {
1119 		dma_addr_t dma_addr;
1120 
1121 		dev_dbg(&hws->pdev->dev,
1122 			"buffer_queue(ch=%u): priming first vb=%p\n",
1123 			vid->channel_index, &buf->vb.vb2_buf);
1124 		list_del_init(&buf->list);
1125 		vid->queued_count--;
1126 		vid->active = buf;
1127 
1128 		dma_addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
1129 		hws_program_dma_for_addr(vid->parent, vid->channel_index,
1130 					 dma_addr);
1131 		iowrite32(lower_32_bits(dma_addr),
1132 			  hws->bar0_base + HWS_REG_DMA_ADDR(vid->channel_index));
1133 
1134 		wmb(); /* ensure descriptors visible before enabling capture */
1135 		hws_enable_video_capture(hws, vid->channel_index, true);
1136 		hws_prime_next_locked(vid);
1137 	} else if (READ_ONCE(vid->cap_active) && vid->active) {
1138 		hws_prime_next_locked(vid);
1139 	}
1140 	spin_unlock_irqrestore(&vid->irq_lock, flags);
1141 }
1142 
1143 static int hws_start_streaming(struct vb2_queue *q, unsigned int count)
1144 {
1145 	struct hws_video *v = q->drv_priv;
1146 	struct hws_pcie_dev *hws = v->parent;
1147 	struct hwsvideo_buffer *to_program = NULL;	/* local copy */
1148 	struct vb2_buffer *prog_vb2 = NULL;
1149 	unsigned long flags;
1150 	int ret;
1151 
1152 	dev_dbg(&hws->pdev->dev, "start_streaming: ch=%u count=%u\n",
1153 		v->channel_index, count);
1154 
1155 	ret = hws_check_card_status(hws);
1156 	if (ret) {
1157 		struct hwsvideo_buffer *b, *tmp;
1158 		unsigned long f;
1159 		LIST_HEAD(queued);
1160 
1161 		spin_lock_irqsave(&v->irq_lock, f);
1162 		if (v->active) {
1163 			list_add_tail(&v->active->list, &queued);
1164 			v->active = NULL;
1165 		}
1166 		if (v->next_prepared) {
1167 			list_add_tail(&v->next_prepared->list, &queued);
1168 			v->next_prepared = NULL;
1169 		}
1170 		while (!list_empty(&v->capture_queue)) {
1171 			b = list_first_entry(&v->capture_queue,
1172 					     struct hwsvideo_buffer, list);
1173 			list_move_tail(&b->list, &queued);
1174 		}
1175 		spin_unlock_irqrestore(&v->irq_lock, f);
1176 
1177 		list_for_each_entry_safe(b, tmp, &queued, list) {
1178 			list_del_init(&b->list);
1179 			vb2_buffer_done(&b->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
1180 		}
1181 		return ret;
1182 	}
1183 	(void)hws_read_active_state(hws, v->channel_index,
1184 				       &v->pix.interlaced);
1185 
1186 	lockdep_assert_held(&v->state_lock);
1187 	/* init per-stream state */
1188 	WRITE_ONCE(v->stop_requested, false);
1189 	WRITE_ONCE(v->cap_active, true);
1190 	WRITE_ONCE(v->half_seen, false);
1191 	WRITE_ONCE(v->last_buf_half_toggle, 0);
1192 
1193 	/* Try to prime a buffer, but it's OK if none are queued yet */
1194 	spin_lock_irqsave(&v->irq_lock, flags);
1195 	if (!v->active && !list_empty(&v->capture_queue)) {
1196 		to_program = list_first_entry(&v->capture_queue,
1197 					      struct hwsvideo_buffer, list);
1198 		list_del_init(&to_program->list);
1199 		v->queued_count--;
1200 		v->active = to_program;
1201 		prog_vb2 = &to_program->vb.vb2_buf;
1202 		dev_dbg(&hws->pdev->dev,
1203 			"start_streaming: ch=%u took buffer %p\n",
1204 			v->channel_index, to_program);
1205 	}
1206 	spin_unlock_irqrestore(&v->irq_lock, flags);
1207 
1208 	/* Only program/enable HW if we actually have a buffer */
1209 	if (to_program) {
1210 		if (!prog_vb2)
1211 			prog_vb2 = &to_program->vb.vb2_buf;
1212 		{
1213 			dma_addr_t dma_addr;
1214 
1215 			dma_addr = vb2_dma_contig_plane_dma_addr(prog_vb2, 0);
1216 			hws_program_dma_for_addr(hws, v->channel_index, dma_addr);
1217 			iowrite32(lower_32_bits(dma_addr),
1218 				  hws->bar0_base +
1219 				  HWS_REG_DMA_ADDR(v->channel_index));
1220 			dev_dbg(&hws->pdev->dev,
1221 				"start_streaming: ch=%u programmed buffer %p dma=0x%08x\n",
1222 				v->channel_index, to_program,
1223 				lower_32_bits(dma_addr));
1224 			(void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
1225 		}
1226 
1227 		wmb(); /* ensure descriptors visible before enabling capture */
1228 		hws_enable_video_capture(hws, v->channel_index, true);
1229 		{
1230 			unsigned long pf;
1231 
1232 			spin_lock_irqsave(&v->irq_lock, pf);
1233 			hws_prime_next_locked(v);
1234 			spin_unlock_irqrestore(&v->irq_lock, pf);
1235 		}
1236 	} else {
1237 		dev_dbg(&hws->pdev->dev,
1238 			"start_streaming: ch=%u no buffer yet (will arm on QBUF)\n",
1239 			v->channel_index);
1240 	}
1241 
1242 	return 0;
1243 }
1244 
1245 static void hws_log_video_state(struct hws_video *v, const char *action,
1246 				const char *phase)
1247 {
1248 	struct hws_pcie_dev *hws = v->parent;
1249 	unsigned long flags;
1250 	unsigned int queued = 0;
1251 	unsigned int tracked = 0;
1252 	unsigned int seq = 0;
1253 	struct hwsvideo_buffer *b;
1254 	bool streaming = vb2_is_streaming(&v->buffer_queue);
1255 	bool cap_active;
1256 	bool stop_requested;
1257 	struct hwsvideo_buffer *active;
1258 	struct hwsvideo_buffer *next_prepared;
1259 
1260 	spin_lock_irqsave(&v->irq_lock, flags);
1261 	list_for_each_entry(b, &v->capture_queue, list)
1262 		queued++;
1263 	cap_active = READ_ONCE(v->cap_active);
1264 	stop_requested = READ_ONCE(v->stop_requested);
1265 	active = v->active;
1266 	next_prepared = v->next_prepared;
1267 	tracked = v->queued_count;
1268 	seq = (u32)atomic_read(&v->sequence_number);
1269 	spin_unlock_irqrestore(&v->irq_lock, flags);
1270 
1271 	dev_dbg(&hws->pdev->dev,
1272 		"video:%s:%s ch=%u streaming=%d cap=%d stop=%d active=%p next=%p queued=%u tracked=%u seq=%u\n",
1273 		action, phase, v->channel_index, streaming, cap_active,
1274 		stop_requested, active, next_prepared, queued, tracked, seq);
1275 }
1276 
1277 static void hws_stop_streaming(struct vb2_queue *q)
1278 {
1279 	struct hws_video *v = q->drv_priv;
1280 	struct hws_pcie_dev *hws = v->parent;
1281 	unsigned long flags;
1282 	struct hwsvideo_buffer *b, *tmp;
1283 	LIST_HEAD(done);
1284 	unsigned int done_cnt = 0;
1285 	u64 start_ns = ktime_get_mono_fast_ns();
1286 
1287 	hws_log_video_state(v, "streamoff", "begin");
1288 
1289 	/* 1) Quiesce SW/HW first */
1290 	lockdep_assert_held(&v->state_lock);
1291 	WRITE_ONCE(v->cap_active, false);
1292 	WRITE_ONCE(v->stop_requested, true);
1293 
1294 	hws_enable_video_capture(v->parent, v->channel_index, false);
1295 
1296 	/* 2) Collect in-flight + queued under the IRQ lock */
1297 	spin_lock_irqsave(&v->irq_lock, flags);
1298 	hws_video_collect_done_locked(v, &done);
1299 	spin_unlock_irqrestore(&v->irq_lock, flags);
1300 
1301 	/* 3) Complete outside the lock */
1302 	list_for_each_entry_safe(b, tmp, &done, list) {
1303 		/* Unlink from 'done' before completing */
1304 		list_del_init(&b->list);
1305 		vb2_buffer_done(&b->vb.vb2_buf, VB2_BUF_STATE_ERROR);
1306 		done_cnt++;
1307 	}
1308 	dev_dbg(&hws->pdev->dev,
1309 		"video:streamoff:done ch=%u completed=%u (%lluus)\n",
1310 		v->channel_index, done_cnt, hws_elapsed_us(start_ns));
1311 	hws_log_video_state(v, "streamoff", "end");
1312 }
1313 
1314 static const struct vb2_ops hwspcie_video_qops = {
1315 	.queue_setup = hws_queue_setup,
1316 	.buf_prepare = hws_buffer_prepare,
1317 	.buf_init = hws_buf_init,
1318 	.buf_finish = hws_buf_finish,
1319 	.buf_cleanup = hws_buf_cleanup,
1320 	.buf_queue = hws_buffer_queue,
1321 	.start_streaming = hws_start_streaming,
1322 	.stop_streaming = hws_stop_streaming,
1323 };
1324 
1325 int hws_video_register(struct hws_pcie_dev *dev)
1326 {
1327 	int i, ret;
1328 
1329 	ret = v4l2_device_register(&dev->pdev->dev, &dev->v4l2_device);
1330 	if (ret) {
1331 		dev_err(&dev->pdev->dev, "v4l2_device_register failed: %d\n",
1332 			ret);
1333 		return ret;
1334 	}
1335 
1336 	for (i = 0; i < dev->cur_max_video_ch; i++) {
1337 		struct hws_video *ch = &dev->video[i];
1338 		struct video_device *vdev;
1339 		struct vb2_queue *q;
1340 
1341 		/* hws_video_init_channel() should have set:
1342 		 * - ch->parent, ch->channel_index
1343 		 * - locks (state_lock, irq_lock)
1344 		 * - capture_queue (INIT_LIST_HEAD)
1345 		 * - control_handler + controls
1346 		 * - fmt_curr (width/height)
1347 		 * Do not reinitialize any of those here.
1348 		 */
1349 
1350 		vdev = video_device_alloc();
1351 		if (!vdev) {
1352 			dev_err(&dev->pdev->dev,
1353 				"video_device_alloc ch%u failed\n", i);
1354 			ret = -ENOMEM;
1355 			goto err_unwind;
1356 		}
1357 		ch->video_device = vdev;
1358 
1359 		/* Basic V4L2 node setup */
1360 		snprintf(vdev->name, sizeof(vdev->name), "%s-hdmi%u",
1361 			 KBUILD_MODNAME, i);
1362 		vdev->v4l2_dev = &dev->v4l2_device;
1363 		vdev->fops = &hws_fops;
1364 		vdev->ioctl_ops = &hws_ioctl_fops;
1365 		vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1366 		vdev->lock = &ch->state_lock;	/* serialize file ops */
1367 		vdev->ctrl_handler = &ch->control_handler;
1368 		vdev->vfl_dir = VFL_DIR_RX;
1369 		vdev->release = video_device_release;
1370 		if (ch->control_handler.error) {
1371 			ret = ch->control_handler.error;
1372 			goto err_unwind;
1373 		}
1374 		video_set_drvdata(vdev, ch);
1375 
1376 		/* vb2 queue init (dma-contig) */
1377 		q = &ch->buffer_queue;
1378 		memset(q, 0, sizeof(*q));
1379 		q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1380 		q->io_modes = VB2_MMAP | VB2_DMABUF;
1381 		q->drv_priv = ch;
1382 		q->buf_struct_size = sizeof(struct hwsvideo_buffer);
1383 		q->ops = &hwspcie_video_qops;
1384 		q->mem_ops = &vb2_dma_contig_memops;
1385 		q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1386 		q->lock = &ch->state_lock;
1387 		q->min_queued_buffers = 1;
1388 		q->dev = &dev->pdev->dev;
1389 
1390 		ret = vb2_queue_init(q);
1391 		vdev->queue = q;
1392 		if (ret) {
1393 			dev_err(&dev->pdev->dev,
1394 				"vb2_queue_init ch%u failed: %d\n", i, ret);
1395 			goto err_unwind;
1396 		}
1397 
1398 		/* Make controls live (no-op if none or already set up) */
1399 		if (ch->control_handler.error) {
1400 			ret = ch->control_handler.error;
1401 			dev_err(&dev->pdev->dev,
1402 				"ctrl handler ch%u error: %d\n", i, ret);
1403 			goto err_unwind;
1404 		}
1405 		v4l2_ctrl_handler_setup(&ch->control_handler);
1406 		ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
1407 		if (ret) {
1408 			dev_err(&dev->pdev->dev,
1409 				"video_register_device ch%u failed: %d\n", i,
1410 				ret);
1411 			goto err_unwind;
1412 		}
1413 	}
1414 
1415 	return 0;
1416 
1417 err_unwind:
1418 	for (; i >= 0; i--) {
1419 		struct hws_video *ch = &dev->video[i];
1420 
1421 		hws_video_release_registration(ch);
1422 	}
1423 	v4l2_device_unregister(&dev->v4l2_device);
1424 	return ret;
1425 }
1426 
1427 void hws_video_unregister(struct hws_pcie_dev *dev)
1428 {
1429 	int i;
1430 
1431 	if (!dev)
1432 		return;
1433 
1434 	for (i = 0; i < dev->cur_max_video_ch; i++) {
1435 		struct hws_video *ch = &dev->video[i];
1436 
1437 		hws_video_release_registration(ch);
1438 		v4l2_ctrl_handler_free(&ch->control_handler);
1439 	}
1440 	v4l2_device_unregister(&dev->v4l2_device);
1441 }
1442 
1443 int hws_video_quiesce(struct hws_pcie_dev *hws, const char *reason)
1444 {
1445 	int i, ret = 0;
1446 	u64 start_ns = ktime_get_mono_fast_ns();
1447 
1448 	dev_dbg(&hws->pdev->dev, "video:%s:begin channels=%u\n", reason,
1449 		hws->cur_max_video_ch);
1450 	for (i = 0; i < hws->cur_max_video_ch; i++) {
1451 		struct hws_video *vid = &hws->video[i];
1452 		struct vb2_queue *q = &vid->buffer_queue;
1453 		u64 ch_start_ns = ktime_get_mono_fast_ns();
1454 		bool streaming;
1455 
1456 		if (!q || !q->ops) {
1457 			dev_dbg(&hws->pdev->dev,
1458 				"video:%s:ch=%d skipped queue-unavailable\n",
1459 				reason, i);
1460 			continue;
1461 		}
1462 
1463 		streaming = vb2_is_streaming(q);
1464 		hws_log_video_state(vid, reason, "channel");
1465 		if (streaming) {
1466 			/* Stop via vb2, which runs .stop_streaming. */
1467 			int r = vb2_streamoff(q, q->type);
1468 
1469 			dev_dbg(&hws->pdev->dev,
1470 				"video:%s:ch=%d streamoff ret=%d (%lluus)\n",
1471 				reason, i, r, hws_elapsed_us(ch_start_ns));
1472 			if (r && !ret)
1473 				ret = r;
1474 		} else {
1475 			dev_dbg(&hws->pdev->dev,
1476 				"video:%s:ch=%d idle (%lluus)\n",
1477 				reason, i, hws_elapsed_us(ch_start_ns));
1478 		}
1479 	}
1480 	dev_dbg(&hws->pdev->dev, "video:%s:done ret=%d (%lluus)\n", reason,
1481 		ret, hws_elapsed_us(start_ns));
1482 	return ret;
1483 }
1484 
1485 void hws_video_pm_resume(struct hws_pcie_dev *hws)
1486 {
1487 	/* Nothing mandatory to do here for vb2; userspace will STREAMON
1488 	 * again when ready.
1489 	 */
1490 }
1491