xref: /linux/drivers/media/pci/intel/ipu6/ipu6-isys.h (revision ab93e0dd72c37d378dd936f031ffb83ff2bd87ce)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /* Copyright (C) 2013--2024 Intel Corporation */
3 
4 #ifndef IPU6_ISYS_H
5 #define IPU6_ISYS_H
6 
7 #include <linux/irqreturn.h>
8 #include <linux/list.h>
9 #include <linux/mutex.h>
10 #include <linux/pm_qos.h>
11 #include <linux/spinlock_types.h>
12 #include <linux/types.h>
13 
14 #include <media/media-device.h>
15 #include <media/v4l2-async.h>
16 #include <media/v4l2-device.h>
17 
18 #include "ipu6.h"
19 #include "ipu6-fw-isys.h"
20 #include "ipu6-isys-csi2.h"
21 #include "ipu6-isys-video.h"
22 
23 struct ipu6_bus_device;
24 
25 #define IPU6_ISYS_ENTITY_PREFIX		"Intel IPU6"
26 /* FW support max 16 streams */
27 #define IPU6_ISYS_MAX_STREAMS		16
28 #define ISYS_UNISPART_IRQS	(IPU6_ISYS_UNISPART_IRQ_SW |	\
29 				 IPU6_ISYS_UNISPART_IRQ_CSI0 |	\
30 				 IPU6_ISYS_UNISPART_IRQ_CSI1)
31 
32 /*
33  * Current message queue configuration. These must be big enough
34  * so that they never gets full. Queues are located in system memory
35  */
36 #define IPU6_ISYS_SIZE_RECV_QUEUE 40
37 #define IPU6_ISYS_SIZE_SEND_QUEUE 40
38 #define IPU6_ISYS_SIZE_PROXY_RECV_QUEUE 5
39 #define IPU6_ISYS_SIZE_PROXY_SEND_QUEUE 5
40 #define IPU6_ISYS_NUM_RECV_QUEUE 1
41 
42 #define IPU6_ISYS_MIN_WIDTH		2U
43 #define IPU6_ISYS_MIN_HEIGHT		1U
44 #define IPU6_ISYS_MAX_WIDTH		4672U
45 #define IPU6_ISYS_MAX_HEIGHT		3416U
46 
47 /* the threshold granularity is 2KB on IPU6 */
48 #define IPU6_SRAM_GRANULARITY_SHIFT	11
49 #define IPU6_SRAM_GRANULARITY_SIZE	2048
50 /* the threshold granularity is 1KB on IPU6SE */
51 #define IPU6SE_SRAM_GRANULARITY_SHIFT	10
52 #define IPU6SE_SRAM_GRANULARITY_SIZE	1024
53 /* IS pixel buffer is 256KB, MaxSRAMSize is 200KB on IPU6 */
54 #define IPU6_MAX_SRAM_SIZE			(200 << 10)
55 /* IS pixel buffer is 128KB, MaxSRAMSize is 96KB on IPU6SE */
56 #define IPU6SE_MAX_SRAM_SIZE			(96 << 10)
57 
58 #define IPU6EP_LTR_VALUE			200
59 #define IPU6EP_MIN_MEMOPEN_TH			0x4
60 #define IPU6EP_MTL_LTR_VALUE			1023
61 #define IPU6EP_MTL_MIN_MEMOPEN_TH		0xc
62 
63 struct ltr_did {
64 	union {
65 		u32 value;
66 		struct {
67 			u8 val0;
68 			u8 val1;
69 			u8 val2;
70 			u8 val3;
71 		} bits;
72 	} lut_ltr;
73 	union {
74 		u32 value;
75 		struct {
76 			u8 th0;
77 			u8 th1;
78 			u8 th2;
79 			u8 th3;
80 		} bits;
81 	} lut_fill_time;
82 };
83 
84 struct isys_iwake_watermark {
85 	bool iwake_enabled;
86 	bool force_iwake_disable;
87 	u32 iwake_threshold;
88 	u64 isys_pixelbuffer_datarate;
89 	struct ltr_did ltrdid;
90 	struct mutex mutex; /* protect whole struct */
91 	struct ipu6_isys *isys;
92 	struct list_head video_list;
93 };
94 
95 struct ipu6_isys_csi2_config {
96 	u32 nlanes;
97 	u32 port;
98 };
99 
100 struct sensor_async_sd {
101 	struct v4l2_async_connection asc;
102 	struct ipu6_isys_csi2_config csi2;
103 };
104 
105 /*
106  * struct ipu6_isys
107  *
108  * @media_dev: Media device
109  * @v4l2_dev: V4L2 device
110  * @adev: ISYS bus device
111  * @power: Is ISYS powered on or not?
112  * @isr_bits: Which bits does the ISR handle?
113  * @power_lock: Serialise access to power (power state in general)
114  * @csi2_rx_ctrl_cached: cached shared value between all CSI2 receivers
115  * @streams_lock: serialise access to streams
116  * @streams: streams per firmware stream ID
117  * @fwcom: fw communication layer private pointer
118  *         or optional external library private pointer
119  * @phy_termcal_val: the termination calibration value, only used for DWC PHY
120  * @need_reset: Isys requires d0i0->i3 transition
121  * @ref_count: total number of callers fw open
122  * @mutex: serialise access isys video open/release related operations
123  * @stream_mutex: serialise stream start and stop, queueing requests
124  * @pdata: platform data pointer
125  * @csi2: CSI-2 receivers
126  */
127 struct ipu6_isys {
128 	struct media_device media_dev;
129 	struct v4l2_device v4l2_dev;
130 	struct ipu6_bus_device *adev;
131 
132 	int power;
133 	spinlock_t power_lock;
134 	u32 isr_csi2_bits;
135 	u32 csi2_rx_ctrl_cached;
136 	spinlock_t streams_lock;
137 	struct ipu6_isys_stream streams[IPU6_ISYS_MAX_STREAMS];
138 	int streams_ref_count[IPU6_ISYS_MAX_STREAMS];
139 	void *fwcom;
140 	u32 phy_termcal_val;
141 	bool need_reset;
142 	bool icache_prefetch;
143 	bool csi2_cse_ipc_not_supported;
144 	unsigned int ref_count;
145 	unsigned int stream_opened;
146 	unsigned int sensor_type;
147 
148 	struct mutex mutex;
149 	struct mutex stream_mutex;
150 
151 	struct ipu6_isys_pdata *pdata;
152 
153 	int (*phy_set_power)(struct ipu6_isys *isys,
154 			     struct ipu6_isys_csi2_config *cfg,
155 			     const struct ipu6_isys_csi2_timing *timing,
156 			     bool on);
157 
158 	struct ipu6_isys_csi2 *csi2;
159 
160 	struct pm_qos_request pm_qos;
161 	spinlock_t listlock;	/* Protect framebuflist */
162 	struct list_head framebuflist;
163 	struct list_head framebuflist_fw;
164 	struct v4l2_async_notifier notifier;
165 	struct isys_iwake_watermark iwake_watermark;
166 };
167 
168 struct isys_fw_msgs {
169 	union {
170 		u64 dummy;
171 		struct ipu6_fw_isys_frame_buff_set_abi frame;
172 		struct ipu6_fw_isys_stream_cfg_data_abi stream;
173 	} fw_msg;
174 	struct list_head head;
175 	dma_addr_t dma_addr;
176 };
177 
178 struct isys_fw_msgs *ipu6_get_fw_msg_buf(struct ipu6_isys_stream *stream);
179 void ipu6_put_fw_msg_buf(struct ipu6_isys *isys, uintptr_t data);
180 void ipu6_cleanup_fw_msg_bufs(struct ipu6_isys *isys);
181 
182 extern const struct v4l2_ioctl_ops ipu6_isys_ioctl_ops;
183 
184 void isys_setup_hw(struct ipu6_isys *isys);
185 irqreturn_t isys_isr(struct ipu6_bus_device *adev);
186 void update_watermark_setting(struct ipu6_isys *isys);
187 
188 int ipu6_isys_mcd_phy_set_power(struct ipu6_isys *isys,
189 				struct ipu6_isys_csi2_config *cfg,
190 				const struct ipu6_isys_csi2_timing *timing,
191 				bool on);
192 
193 int ipu6_isys_dwc_phy_set_power(struct ipu6_isys *isys,
194 				struct ipu6_isys_csi2_config *cfg,
195 				const struct ipu6_isys_csi2_timing *timing,
196 				bool on);
197 
198 int ipu6_isys_jsl_phy_set_power(struct ipu6_isys *isys,
199 				struct ipu6_isys_csi2_config *cfg,
200 				const struct ipu6_isys_csi2_timing *timing,
201 				bool on);
202 #endif /* IPU6_ISYS_H */
203