1/* SPDX-License-Identifier: GPL-2.0-only */
2/* Copyright (C) 2013--2024 Intel Corporation */
3
4#ifndef IPU6_ISYS_VIDEO_H
5#define IPU6_ISYS_VIDEO_H
6
7#include <linux/atomic.h>
8#include <linux/completion.h>
9#include <linux/container_of.h>
10#include <linux/list.h>
11#include <linux/mutex.h>
12
13#include <media/media-entity.h>
14#include <media/v4l2-dev.h>
15
16#include "ipu6-isys-queue.h"
17
18#define IPU6_ISYS_OUTPUT_PINS 11
19#define IPU6_ISYS_MAX_PARALLEL_SOF 2
20
21struct file;
22struct ipu6_isys;
23struct ipu6_isys_csi2;
24struct ipu6_isys_subdev;
25
26struct ipu6_isys_pixelformat {
27	u32 pixelformat;
28	u32 bpp;
29	u32 bpp_packed;
30	u32 code;
31	u32 css_pixelformat;
32	bool is_meta;
33};
34
35struct sequence_info {
36	unsigned int sequence;
37	u64 timestamp;
38};
39
40struct output_pin_data {
41	void (*pin_ready)(struct ipu6_isys_stream *stream,
42			  struct ipu6_fw_isys_resp_info_abi *info);
43	struct ipu6_isys_queue *aq;
44};
45
46/*
47 * Align with firmware stream. Each stream represents a CSI virtual channel.
48 * May map to multiple video devices
49 */
50struct ipu6_isys_stream {
51	struct mutex mutex;
52	struct media_entity *source_entity;
53	atomic_t sequence;
54	unsigned int seq_index;
55	struct sequence_info seq[IPU6_ISYS_MAX_PARALLEL_SOF];
56	int stream_source;
57	int stream_handle;
58	unsigned int nr_output_pins;
59	struct ipu6_isys_subdev *asd;
60
61	int nr_queues;	/* Number of capture queues */
62	int nr_streaming;
63	int streaming;	/* Has streaming been really started? */
64	struct list_head queues;
65	struct completion stream_open_completion;
66	struct completion stream_close_completion;
67	struct completion stream_start_completion;
68	struct completion stream_stop_completion;
69	struct ipu6_isys *isys;
70
71	struct output_pin_data output_pins[IPU6_ISYS_OUTPUT_PINS];
72	int error;
73	u8 vc;
74};
75
76struct video_stream_watermark {
77	u32 width;
78	u32 height;
79	u32 hblank;
80	u32 frame_rate;
81	u64 pixel_rate;
82	u64 stream_data_rate;
83	u16 sram_gran_shift;
84	u16 sram_gran_size;
85	struct list_head stream_node;
86};
87
88struct ipu6_isys_video {
89	struct ipu6_isys_queue aq;
90	/* Serialise access to other fields in the struct. */
91	struct mutex mutex;
92	struct media_pad pad;
93	struct video_device vdev;
94	struct v4l2_pix_format pix_fmt;
95	struct v4l2_meta_format meta_fmt;
96	struct ipu6_isys *isys;
97	struct ipu6_isys_csi2 *csi2;
98	struct ipu6_isys_stream *stream;
99	unsigned int streaming;
100	struct video_stream_watermark watermark;
101	u32 source_stream;
102	u8 vc;
103	u8 dt;
104};
105
106#define ipu6_isys_queue_to_video(__aq) \
107	container_of(__aq, struct ipu6_isys_video, aq)
108
109extern const struct ipu6_isys_pixelformat ipu6_isys_pfmts[];
110extern const struct ipu6_isys_pixelformat ipu6_isys_pfmts_packed[];
111
112const struct ipu6_isys_pixelformat *
113ipu6_isys_get_isys_format(u32 pixelformat, u32 code);
114int ipu6_isys_video_prepare_stream(struct ipu6_isys_video *av,
115				   struct media_entity *source_entity,
116				   int nr_queues);
117int ipu6_isys_video_set_streaming(struct ipu6_isys_video *av, int state,
118				  struct ipu6_isys_buffer_list *bl);
119int ipu6_isys_fw_open(struct ipu6_isys *isys);
120void ipu6_isys_fw_close(struct ipu6_isys *isys);
121int ipu6_isys_setup_video(struct ipu6_isys_video *av,
122			  struct media_entity **source_entity, int *nr_queues);
123int ipu6_isys_video_init(struct ipu6_isys_video *av);
124void ipu6_isys_video_cleanup(struct ipu6_isys_video *av);
125void ipu6_isys_put_stream(struct ipu6_isys_stream *stream);
126struct ipu6_isys_stream *
127ipu6_isys_query_stream_by_handle(struct ipu6_isys *isys, u8 stream_handle);
128struct ipu6_isys_stream *
129ipu6_isys_query_stream_by_source(struct ipu6_isys *isys, int source, u8 vc);
130
131void ipu6_isys_configure_stream_watermark(struct ipu6_isys_video *av,
132					  bool state);
133void ipu6_isys_update_stream_watermark(struct ipu6_isys_video *av, bool state);
134
135u32 ipu6_isys_get_format(struct ipu6_isys_video *av);
136u32 ipu6_isys_get_data_size(struct ipu6_isys_video *av);
137u32 ipu6_isys_get_bytes_per_line(struct ipu6_isys_video *av);
138u32 ipu6_isys_get_frame_width(struct ipu6_isys_video *av);
139u32 ipu6_isys_get_frame_height(struct ipu6_isys_video *av);
140
141#endif /* IPU6_ISYS_VIDEO_H */
142