xref: /linux/drivers/media/platform/qcom/camss/camss-csid-gen3.c (revision ec2e0fb07d789976c601bec19ecced7a501c3705)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module
4  *
5  * Copyright (c) 2024 Qualcomm Technologies, Inc.
6  */
7 #include <linux/completion.h>
8 #include <linux/delay.h>
9 #include <linux/interrupt.h>
10 #include <linux/io.h>
11 #include <linux/kernel.h>
12 #include <linux/of.h>
13 
14 #include "camss.h"
15 #include "camss-csid.h"
16 #include "camss-csid-gen3.h"
17 
18 #define CSID_IO_PATH_CFG0(csid)		(0x4 * (csid))
19 #define		OUTPUT_IFE_EN			0x100
20 #define		INTERNAL_CSID			1
21 
22 #define CSID_RST_CFG			0xC
23 #define		RST_MODE			BIT(0)
24 #define		RST_LOCATION			BIT(4)
25 
26 #define CSID_RST_CMD			0x10
27 #define		SELECT_HW_RST			BIT(0)
28 #define		SELECT_IRQ_RST			BIT(2)
29 
30 #define CSID_IRQ_CMD			0x14
31 #define		IRQ_CMD_CLEAR			BIT(0)
32 
33 #define CSID_RUP_AUP_CMD		0x18
34 #define		CSID_RUP_AUP_RDI(rdi)		((BIT(4) | BIT(20)) << (rdi))
35 
36 #define CSID_TOP_IRQ_STATUS		0x7C
37 #define		 TOP_IRQ_STATUS_RESET_DONE	BIT(0)
38 
39 #define CSID_TOP_IRQ_MASK		0x80
40 #define CSID_TOP_IRQ_CLEAR		0x84
41 #define CSID_TOP_IRQ_SET		0x88
42 
43 #define CSID_CSI2_RX_IRQ_STATUS		0x9C
44 #define CSID_CSI2_RX_IRQ_MASK		0xA0
45 #define CSID_CSI2_RX_IRQ_CLEAR		0xA4
46 #define CSID_CSI2_RX_IRQ_SET		0xA8
47 
48 #define IS_CSID_690(csid)	((csid->camss->res->version == CAMSS_8775P) \
49 				 || (csid->camss->res->version == CAMSS_8300))
50 #define CSID_BUF_DONE_IRQ_STATUS	0x8C
51 #define BUF_DONE_IRQ_STATUS_RDI_OFFSET  (csid_is_lite(csid) ?\
52 						1 : (IS_CSID_690(csid) ?\
53 						13 : 14))
54 #define CSID_BUF_DONE_IRQ_MASK		0x90
55 #define CSID_BUF_DONE_IRQ_CLEAR		0x94
56 #define CSID_BUF_DONE_IRQ_SET		0x98
57 
58 #define CSID_CSI2_RDIN_IRQ_STATUS(rdi)	(0xEC + 0x10 * (rdi))
59 #define		RUP_DONE_IRQ_STATUS		BIT(23)
60 
61 #define CSID_CSI2_RDIN_IRQ_CLEAR(rdi)	(0xF4 + 0x10 * (rdi))
62 #define CSID_CSI2_RDIN_IRQ_SET(rdi)	(0xF8 + 0x10 * (rdi))
63 
64 #define CSID_CSI2_RX_CFG0		0x200
65 #define		CSI2_RX_CFG0_NUM_ACTIVE_LANES	0
66 #define		CSI2_RX_CFG0_VC_MODE		3
67 #define		CSI2_RX_CFG0_DL0_INPUT_SEL	4
68 #define		CSI2_RX_CFG0_PHY_NUM_SEL	20
69 
70 #define CSID_CSI2_RX_CFG1		0x204
71 #define		CSI2_RX_CFG1_ECC_CORRECTION_EN	BIT(0)
72 #define		CSI2_RX_CFG1_VC_MODE		BIT(2)
73 
74 #define CSID_RDI_CFG0(rdi)	(csid_is_lite(csid) && IS_CSID_690(csid) ?\
75 					(0x300 + 0x100 * (rdi)) :\
76 					(0x500 + 0x100 * (rdi)))
77 #define		RDI_CFG0_TIMESTAMP_EN		BIT(6)
78 #define		RDI_CFG0_TIMESTAMP_STB_SEL	BIT(8)
79 #define		RDI_CFG0_DECODE_FORMAT		12
80 #define		RDI_CFG0_DT			16
81 #define		RDI_CFG0_VC			22
82 #define		RDI_CFG0_DT_ID			27
83 #define		RDI_CFG0_EN			BIT(31)
84 
85 #define CSID_RDI_CTRL(rdi)	(csid_is_lite(csid) && IS_CSID_690(csid) ?\
86 					(0x304 + 0x100 * (rdi)) :\
87 					(0x504 + 0x100 * (rdi)))
88 #define		RDI_CTRL_START_CMD		BIT(0)
89 
90 #define CSID_RDI_CFG1(rdi)	(csid_is_lite(csid) && IS_CSID_690(csid) ?\
91 					(0x310 + 0x100 * (rdi)) :\
92 					(0x510 + 0x100 * (rdi)))
93 #define		RDI_CFG1_DROP_H_EN		BIT(5)
94 #define		RDI_CFG1_DROP_V_EN		BIT(6)
95 #define		RDI_CFG1_CROP_H_EN		BIT(7)
96 #define		RDI_CFG1_CROP_V_EN		BIT(8)
97 #define		RDI_CFG1_PIX_STORE		BIT(10)
98 #define		RDI_CFG1_PACKING_FORMAT_MIPI	BIT(15)
99 
100 #define CSID_RDI_IRQ_SUBSAMPLE_PATTERN(rdi)	(csid_is_lite(csid) && IS_CSID_690(csid) ?\
101 							(0x348 + 0x100 * (rdi)) :\
102 							(0x548 + 0x100 * (rdi)))
103 #define CSID_RDI_IRQ_SUBSAMPLE_PERIOD(rdi)	(csid_is_lite(csid) && IS_CSID_690(csid) ?\
104 							(0x34C + 0x100 * (rdi)) :\
105 							(0x54C + 0x100 * (rdi)))
106 #define CSI2_RX_CFG0_PHY_SEL_BASE_IDX	1
107 
108 static void __csid_configure_rx(struct csid_device *csid,
109 				struct csid_phy_config *phy, int vc)
110 {
111 	int val;
112 
113 	val = (phy->lane_cnt - 1) << CSI2_RX_CFG0_NUM_ACTIVE_LANES;
114 	val |= phy->lane_assign << CSI2_RX_CFG0_DL0_INPUT_SEL;
115 	val |= (phy->csiphy_id + CSI2_RX_CFG0_PHY_SEL_BASE_IDX) << CSI2_RX_CFG0_PHY_NUM_SEL;
116 
117 	writel(val, csid->base + CSID_CSI2_RX_CFG0);
118 
119 	val = CSI2_RX_CFG1_ECC_CORRECTION_EN;
120 	if (vc > 3)
121 		val |= CSI2_RX_CFG1_VC_MODE;
122 
123 	writel(val, csid->base + CSID_CSI2_RX_CFG1);
124 }
125 
126 static void __csid_ctrl_rdi(struct csid_device *csid, int enable, u8 rdi)
127 {
128 	int val = 0;
129 
130 	if (enable)
131 		val = RDI_CTRL_START_CMD;
132 
133 	writel(val, csid->base + CSID_RDI_CTRL(rdi));
134 }
135 
136 static void __csid_configure_wrapper(struct csid_device *csid)
137 {
138 	u32 val;
139 
140 	/* csid lite doesn't need to configure top register */
141 	if (csid->res->is_lite)
142 		return;
143 
144 	val = OUTPUT_IFE_EN | INTERNAL_CSID;
145 	writel(val, csid->camss->csid_wrapper_base + CSID_IO_PATH_CFG0(csid->id));
146 }
147 
148 static void __csid_configure_rdi_stream(struct csid_device *csid, u8 enable, u8 vc)
149 {
150 	u32 val;
151 	u8 lane_cnt = csid->phy.lane_cnt;
152 	/* Source pads matching RDI channels on hardware. Pad 1 -> RDI0, Pad 2 -> RDI1, etc. */
153 	struct v4l2_mbus_framefmt *input_format = &csid->fmt[MSM_CSID_PAD_FIRST_SRC + vc];
154 	const struct csid_format_info *format = csid_get_fmt_entry(csid->res->formats->formats,
155 								   csid->res->formats->nformats,
156 								   input_format->code);
157 
158 	if (!lane_cnt)
159 		lane_cnt = 4;
160 
161 	/*
162 	 * DT_ID is a two bit bitfield that is concatenated with
163 	 * the four least significant bits of the five bit VC
164 	 * bitfield to generate an internal CID value.
165 	 *
166 	 * CSID_RDI_CFG0(vc)
167 	 * DT_ID : 28:27
168 	 * VC    : 26:22
169 	 * DT    : 21:16
170 	 *
171 	 * CID   : VC 3:0 << 2 | DT_ID 1:0
172 	 */
173 	u8 dt_id = vc & 0x03;
174 
175 	val = RDI_CFG0_TIMESTAMP_EN;
176 	val |= RDI_CFG0_TIMESTAMP_STB_SEL;
177 	/* note: for non-RDI path, this should be format->decode_format */
178 	val |= DECODE_FORMAT_PAYLOAD_ONLY << RDI_CFG0_DECODE_FORMAT;
179 	val |= vc << RDI_CFG0_VC;
180 	val |= format->data_type << RDI_CFG0_DT;
181 	val |= dt_id << RDI_CFG0_DT_ID;
182 
183 	writel(val, csid->base + CSID_RDI_CFG0(vc));
184 
185 	val = RDI_CFG1_PACKING_FORMAT_MIPI;
186 	val |= RDI_CFG1_PIX_STORE;
187 	val |= RDI_CFG1_DROP_H_EN;
188 	val |= RDI_CFG1_DROP_V_EN;
189 	val |= RDI_CFG1_CROP_H_EN;
190 	val |= RDI_CFG1_CROP_V_EN;
191 
192 	writel(val, csid->base + CSID_RDI_CFG1(vc));
193 
194 	val = 0;
195 	writel(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PERIOD(vc));
196 
197 	val = 1;
198 	writel(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PATTERN(vc));
199 
200 	val = 0;
201 	writel(val, csid->base + CSID_RDI_CTRL(vc));
202 
203 	val = readl(csid->base + CSID_RDI_CFG0(vc));
204 
205 	if (enable)
206 		val |= RDI_CFG0_EN;
207 	writel(val, csid->base + CSID_RDI_CFG0(vc));
208 }
209 
210 static void csid_configure_stream(struct csid_device *csid, u8 enable)
211 {
212 	u8 i;
213 
214 	__csid_configure_wrapper(csid);
215 
216 	/* Loop through all enabled VCs and configure stream for each */
217 	for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++)
218 		if (csid->phy.en_vc & BIT(i)) {
219 			__csid_configure_rdi_stream(csid, enable, i);
220 			__csid_configure_rx(csid, &csid->phy, i);
221 			__csid_ctrl_rdi(csid, enable, i);
222 		}
223 }
224 
225 static int csid_configure_testgen_pattern(struct csid_device *csid, s32 val)
226 {
227 	return 0;
228 }
229 
230 static void csid_subdev_reg_update(struct csid_device *csid, int port_id, bool clear)
231 {
232 	if (clear) {
233 		csid->reg_update &= ~CSID_RUP_AUP_RDI(port_id);
234 	} else {
235 		csid->reg_update |= CSID_RUP_AUP_RDI(port_id);
236 		writel(csid->reg_update, csid->base + CSID_RUP_AUP_CMD);
237 	}
238 }
239 
240 /*
241  * csid_isr - CSID module interrupt service routine
242  * @irq: Interrupt line
243  * @dev: CSID device
244  *
245  * Return IRQ_HANDLED on success
246  */
247 static irqreturn_t csid_isr(int irq, void *dev)
248 {
249 	struct csid_device *csid = dev;
250 	u32 val, buf_done_val;
251 	u8 reset_done;
252 	int i;
253 
254 	val = readl(csid->base + CSID_TOP_IRQ_STATUS);
255 	writel(val, csid->base + CSID_TOP_IRQ_CLEAR);
256 	reset_done = val & TOP_IRQ_STATUS_RESET_DONE;
257 
258 	val = readl(csid->base + CSID_CSI2_RX_IRQ_STATUS);
259 	writel(val, csid->base + CSID_CSI2_RX_IRQ_CLEAR);
260 
261 	buf_done_val = readl(csid->base + CSID_BUF_DONE_IRQ_STATUS);
262 	writel(buf_done_val, csid->base + CSID_BUF_DONE_IRQ_CLEAR);
263 
264 	/* Read and clear IRQ status for each enabled RDI channel */
265 	for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++)
266 		if (csid->phy.en_vc & BIT(i)) {
267 			val = readl(csid->base + CSID_CSI2_RDIN_IRQ_STATUS(i));
268 			writel(val, csid->base + CSID_CSI2_RDIN_IRQ_CLEAR(i));
269 
270 			if (val & RUP_DONE_IRQ_STATUS)
271 				/* clear the reg update bit */
272 				csid_subdev_reg_update(csid, i, true);
273 
274 			if (buf_done_val & BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i)) {
275 				/*
276 				 * For Titan Gen3, bus done and RUP IRQ have been moved to
277 				 * CSID from VFE. Once CSID received bus done, need notify
278 				 * VFE of this event. Trigger VFE to handle bus done process.
279 				 */
280 				camss_buf_done(csid->camss, csid->id, i);
281 			}
282 		}
283 
284 	val = IRQ_CMD_CLEAR;
285 	writel(val, csid->base + CSID_IRQ_CMD);
286 
287 	if (reset_done)
288 		complete(&csid->reset_complete);
289 
290 	return IRQ_HANDLED;
291 }
292 
293 /*
294  * csid_reset - Trigger reset on CSID module and wait to complete
295  * @csid: CSID device
296  *
297  * Return 0 on success or a negative error code otherwise
298  */
299 static int csid_reset(struct csid_device *csid)
300 {
301 	unsigned long time;
302 	u32 val;
303 	int i;
304 
305 	reinit_completion(&csid->reset_complete);
306 
307 	writel(1, csid->base + CSID_TOP_IRQ_CLEAR);
308 	writel(1, csid->base + CSID_IRQ_CMD);
309 	writel(1, csid->base + CSID_TOP_IRQ_MASK);
310 
311 	for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++)
312 		if (csid->phy.en_vc & BIT(i)) {
313 			writel(BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i),
314 			       csid->base + CSID_BUF_DONE_IRQ_CLEAR);
315 			writel(IRQ_CMD_CLEAR, csid->base + CSID_IRQ_CMD);
316 			writel(BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i),
317 			       csid->base + CSID_BUF_DONE_IRQ_MASK);
318 		}
319 
320 	/* preserve registers */
321 	val = RST_LOCATION | RST_MODE;
322 	writel(val, csid->base + CSID_RST_CFG);
323 
324 	val = SELECT_HW_RST | SELECT_IRQ_RST;
325 	writel(val, csid->base + CSID_RST_CMD);
326 
327 	time = wait_for_completion_timeout(&csid->reset_complete,
328 					   msecs_to_jiffies(CSID_RESET_TIMEOUT_MS));
329 	if (!time) {
330 		dev_err(csid->camss->dev, "CSID reset timeout\n");
331 		return -EIO;
332 	}
333 
334 	return 0;
335 }
336 
337 static void csid_subdev_init(struct csid_device *csid)
338 {
339 	csid->testgen.nmodes = CSID_PAYLOAD_MODE_DISABLED;
340 }
341 
342 const struct csid_hw_ops csid_ops_gen3 = {
343 	.configure_stream = csid_configure_stream,
344 	.configure_testgen_pattern = csid_configure_testgen_pattern,
345 	.hw_version = csid_hw_version,
346 	.isr = csid_isr,
347 	.reset = csid_reset,
348 	.src_pad_code = csid_src_pad_code,
349 	.subdev_init = csid_subdev_init,
350 	.reg_update = csid_subdev_reg_update,
351 };
352