xref: /linux/drivers/staging/media/ipu7/ipu7-buttress.c (revision 8d2b0853add1d7534dc0794e3c8e0b9e8c4ec640)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2013 - 2025 Intel Corporation
4  */
5 
6 #include <asm/cpu_device_id.h>
7 #include <linux/bitfield.h>
8 #include <linux/bits.h>
9 #include <linux/completion.h>
10 #include <linux/device.h>
11 #include <linux/dma-mapping.h>
12 #include <linux/firmware.h>
13 #include <linux/interrupt.h>
14 #include <linux/iopoll.h>
15 #include <linux/math64.h>
16 #include <linux/mm.h>
17 #include <linux/mutex.h>
18 #include <linux/module.h>
19 #include <linux/pci.h>
20 #include <linux/pm_runtime.h>
21 #include <linux/scatterlist.h>
22 #include <linux/types.h>
23 
24 #include "ipu7.h"
25 #include "ipu7-bus.h"
26 #include "ipu7-buttress.h"
27 #include "ipu7-buttress-regs.h"
28 
29 #define BOOTLOADER_STATUS_OFFSET	BUTTRESS_REG_FW_BOOT_PARAMS7
30 
31 #define BOOTLOADER_MAGIC_KEY		0xb00710adU
32 
33 #define ENTRY	BUTTRESS_IU2CSECSR_IPC_PEER_COMP_ACTIONS_RST_PHASE1
34 #define EXIT	BUTTRESS_IU2CSECSR_IPC_PEER_COMP_ACTIONS_RST_PHASE2
35 #define QUERY	BUTTRESS_IU2CSECSR_IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE
36 
37 #define BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX	10U
38 
39 #define BUTTRESS_POWER_TIMEOUT_US		(200 * USEC_PER_MSEC)
40 
41 #define BUTTRESS_CSE_BOOTLOAD_TIMEOUT_US	(5 * USEC_PER_SEC)
42 #define BUTTRESS_CSE_AUTHENTICATE_TIMEOUT_US	(10 * USEC_PER_SEC)
43 #define BUTTRESS_CSE_FWRESET_TIMEOUT_US		(100 * USEC_PER_MSEC)
44 
45 #define BUTTRESS_IPC_TX_TIMEOUT_MS		MSEC_PER_SEC
46 #define BUTTRESS_IPC_RX_TIMEOUT_MS		MSEC_PER_SEC
47 #define BUTTRESS_IPC_VALIDITY_TIMEOUT_US	(1 * USEC_PER_SEC)
48 #define BUTTRESS_TSC_SYNC_TIMEOUT_US		(5 * USEC_PER_MSEC)
49 
50 #define BUTTRESS_IPC_RESET_RETRY		2000U
51 #define BUTTRESS_CSE_IPC_RESET_RETRY		4U
52 #define BUTTRESS_IPC_CMD_SEND_RETRY		1U
53 
54 struct ipu7_ipc_buttress_msg {
55 	u32 cmd;
56 	u32 expected_resp;
57 	bool require_resp;
58 	u8 cmd_size;
59 };
60 
61 static const u32 ipu7_adev_irq_mask[2] = {
62 	BUTTRESS_IRQ_IS_IRQ,
63 	BUTTRESS_IRQ_PS_IRQ
64 };
65 
66 int ipu_buttress_ipc_reset(struct ipu7_device *isp,
67 			   struct ipu_buttress_ipc *ipc)
68 {
69 	unsigned int retries = BUTTRESS_IPC_RESET_RETRY;
70 	struct ipu_buttress *b = &isp->buttress;
71 	struct device *dev = &isp->pdev->dev;
72 	u32 val = 0, csr_in_clr;
73 
74 	if (!isp->secure_mode) {
75 		dev_dbg(dev, "Skip IPC reset for non-secure mode\n");
76 		return 0;
77 	}
78 
79 	mutex_lock(&b->ipc_mutex);
80 
81 	/* Clear-by-1 CSR (all bits), corresponding internal states. */
82 	val = readl(isp->base + ipc->csr_in);
83 	writel(val, isp->base + ipc->csr_in);
84 
85 	/* Set peer CSR bit IPC_PEER_COMP_ACTIONS_RST_PHASE1 */
86 	writel(ENTRY, isp->base + ipc->csr_out);
87 	/*
88 	 * Clear-by-1 all CSR bits EXCEPT following
89 	 * bits:
90 	 * A. IPC_PEER_COMP_ACTIONS_RST_PHASE1.
91 	 * B. IPC_PEER_COMP_ACTIONS_RST_PHASE2.
92 	 * C. Possibly custom bits, depending on
93 	 * their role.
94 	 */
95 	csr_in_clr = BUTTRESS_IU2CSECSR_IPC_PEER_DEASSERTED_REG_VALID_REQ |
96 		BUTTRESS_IU2CSECSR_IPC_PEER_ACKED_REG_VALID |
97 		BUTTRESS_IU2CSECSR_IPC_PEER_ASSERTED_REG_VALID_REQ | QUERY;
98 
99 	do {
100 		usleep_range(400, 500);
101 		val = readl(isp->base + ipc->csr_in);
102 		switch (val) {
103 		case ENTRY | EXIT:
104 		case ENTRY | EXIT | QUERY:
105 			/*
106 			 * 1) Clear-by-1 CSR bits
107 			 * (IPC_PEER_COMP_ACTIONS_RST_PHASE1,
108 			 * IPC_PEER_COMP_ACTIONS_RST_PHASE2).
109 			 * 2) Set peer CSR bit
110 			 * IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE.
111 			 */
112 			writel(ENTRY | EXIT, isp->base + ipc->csr_in);
113 			writel(QUERY, isp->base + ipc->csr_out);
114 			break;
115 		case ENTRY:
116 		case ENTRY | QUERY:
117 			/*
118 			 * 1) Clear-by-1 CSR bits
119 			 * (IPC_PEER_COMP_ACTIONS_RST_PHASE1,
120 			 * IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE).
121 			 * 2) Set peer CSR bit
122 			 * IPC_PEER_COMP_ACTIONS_RST_PHASE1.
123 			 */
124 			writel(ENTRY | QUERY, isp->base + ipc->csr_in);
125 			writel(ENTRY, isp->base + ipc->csr_out);
126 			break;
127 		case EXIT:
128 		case EXIT | QUERY:
129 			/*
130 			 * Clear-by-1 CSR bit
131 			 * IPC_PEER_COMP_ACTIONS_RST_PHASE2.
132 			 * 1) Clear incoming doorbell.
133 			 * 2) Clear-by-1 all CSR bits EXCEPT following
134 			 * bits:
135 			 * A. IPC_PEER_COMP_ACTIONS_RST_PHASE1.
136 			 * B. IPC_PEER_COMP_ACTIONS_RST_PHASE2.
137 			 * C. Possibly custom bits, depending on
138 			 * their role.
139 			 * 3) Set peer CSR bit
140 			 * IPC_PEER_COMP_ACTIONS_RST_PHASE2.
141 			 */
142 			writel(EXIT, isp->base + ipc->csr_in);
143 			writel(0, isp->base + ipc->db0_in);
144 			writel(csr_in_clr, isp->base + ipc->csr_in);
145 			writel(EXIT, isp->base + ipc->csr_out);
146 
147 			/*
148 			 * Read csr_in again to make sure if RST_PHASE2 is done.
149 			 * If csr_in is QUERY, it should be handled again.
150 			 */
151 			usleep_range(200, 300);
152 			val = readl(isp->base + ipc->csr_in);
153 			if (val & QUERY) {
154 				dev_dbg(dev,
155 					"RST_PHASE2 retry csr_in = %x\n", val);
156 				break;
157 			}
158 			mutex_unlock(&b->ipc_mutex);
159 			return 0;
160 		case QUERY:
161 			/*
162 			 * 1) Clear-by-1 CSR bit
163 			 * IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE.
164 			 * 2) Set peer CSR bit
165 			 * IPC_PEER_COMP_ACTIONS_RST_PHASE1
166 			 */
167 			writel(QUERY, isp->base + ipc->csr_in);
168 			writel(ENTRY, isp->base + ipc->csr_out);
169 			break;
170 		default:
171 			dev_dbg_ratelimited(dev, "Unexpected CSR 0x%x\n", val);
172 			break;
173 		}
174 	} while (retries--);
175 
176 	mutex_unlock(&b->ipc_mutex);
177 	dev_err(dev, "Timed out while waiting for CSE\n");
178 
179 	return -ETIMEDOUT;
180 }
181 
182 static void ipu_buttress_ipc_validity_close(struct ipu7_device *isp,
183 					    struct ipu_buttress_ipc *ipc)
184 {
185 	writel(BUTTRESS_IU2CSECSR_IPC_PEER_DEASSERTED_REG_VALID_REQ,
186 	       isp->base + ipc->csr_out);
187 }
188 
189 static int
190 ipu_buttress_ipc_validity_open(struct ipu7_device *isp,
191 			       struct ipu_buttress_ipc *ipc)
192 {
193 	unsigned int mask = BUTTRESS_IU2CSECSR_IPC_PEER_ACKED_REG_VALID;
194 	void __iomem *addr;
195 	int ret;
196 	u32 val;
197 
198 	writel(BUTTRESS_IU2CSECSR_IPC_PEER_ASSERTED_REG_VALID_REQ,
199 	       isp->base + ipc->csr_out);
200 
201 	addr = isp->base + ipc->csr_in;
202 	ret = readl_poll_timeout(addr, val, val & mask, 200,
203 				 BUTTRESS_IPC_VALIDITY_TIMEOUT_US);
204 	if (ret) {
205 		dev_err(&isp->pdev->dev, "CSE validity timeout 0x%x\n", val);
206 		ipu_buttress_ipc_validity_close(isp, ipc);
207 	}
208 
209 	return ret;
210 }
211 
212 static void ipu_buttress_ipc_recv(struct ipu7_device *isp,
213 				  struct ipu_buttress_ipc *ipc, u32 *ipc_msg)
214 {
215 	if (ipc_msg)
216 		*ipc_msg = readl(isp->base + ipc->data0_in);
217 	writel(0, isp->base + ipc->db0_in);
218 }
219 
220 static int ipu_buttress_ipc_send_msg(struct ipu7_device *isp,
221 				     struct ipu7_ipc_buttress_msg *msg)
222 {
223 	unsigned long tx_timeout_jiffies, rx_timeout_jiffies;
224 	unsigned int retry = BUTTRESS_IPC_CMD_SEND_RETRY;
225 	struct ipu_buttress *b = &isp->buttress;
226 	struct ipu_buttress_ipc *ipc = &b->cse;
227 	struct device *dev = &isp->pdev->dev;
228 	int tout;
229 	u32 val;
230 	int ret;
231 
232 	mutex_lock(&b->ipc_mutex);
233 
234 	ret = ipu_buttress_ipc_validity_open(isp, ipc);
235 	if (ret) {
236 		dev_err(dev, "IPC validity open failed\n");
237 		goto out;
238 	}
239 
240 	tx_timeout_jiffies = msecs_to_jiffies(BUTTRESS_IPC_TX_TIMEOUT_MS);
241 	rx_timeout_jiffies = msecs_to_jiffies(BUTTRESS_IPC_RX_TIMEOUT_MS);
242 
243 try:
244 	reinit_completion(&ipc->send_complete);
245 	if (msg->require_resp)
246 		reinit_completion(&ipc->recv_complete);
247 
248 	dev_dbg(dev, "IPC command: 0x%x\n", msg->cmd);
249 	writel(msg->cmd, isp->base + ipc->data0_out);
250 	val = BUTTRESS_IU2CSEDB0_BUSY | msg->cmd_size;
251 	writel(val, isp->base + ipc->db0_out);
252 
253 	tout = wait_for_completion_timeout(&ipc->send_complete,
254 					   tx_timeout_jiffies);
255 	if (!tout) {
256 		dev_err(dev, "send IPC response timeout\n");
257 		if (!retry--) {
258 			ret = -ETIMEDOUT;
259 			goto out;
260 		}
261 
262 		/* Try again if CSE is not responding on first try */
263 		writel(0, isp->base + ipc->db0_out);
264 		goto try;
265 	}
266 
267 	if (!msg->require_resp) {
268 		ret = -EIO;
269 		goto out;
270 	}
271 
272 	tout = wait_for_completion_timeout(&ipc->recv_complete,
273 					   rx_timeout_jiffies);
274 	if (!tout) {
275 		dev_err(dev, "recv IPC response timeout\n");
276 		ret = -ETIMEDOUT;
277 		goto out;
278 	}
279 
280 	if (ipc->nack_mask &&
281 	    (ipc->recv_data & ipc->nack_mask) == ipc->nack) {
282 		dev_err(dev, "IPC NACK for cmd 0x%x\n", msg->cmd);
283 		ret = -EIO;
284 		goto out;
285 	}
286 
287 	if (ipc->recv_data != msg->expected_resp) {
288 		dev_err(dev,
289 			"expected resp: 0x%x, IPC response: 0x%x\n",
290 			msg->expected_resp, ipc->recv_data);
291 		ret = -EIO;
292 		goto out;
293 	}
294 
295 	dev_dbg(dev, "IPC commands done\n");
296 
297 out:
298 	ipu_buttress_ipc_validity_close(isp, ipc);
299 	mutex_unlock(&b->ipc_mutex);
300 
301 	return ret;
302 }
303 
304 static int ipu_buttress_ipc_send(struct ipu7_device *isp,
305 				 u32 ipc_msg, u32 size, bool require_resp,
306 				 u32 expected_resp)
307 {
308 	struct ipu7_ipc_buttress_msg msg = {
309 		.cmd = ipc_msg,
310 		.cmd_size = size,
311 		.require_resp = require_resp,
312 		.expected_resp = expected_resp,
313 	};
314 
315 	return ipu_buttress_ipc_send_msg(isp, &msg);
316 }
317 
318 static irqreturn_t ipu_buttress_call_isr(struct ipu7_bus_device *adev)
319 {
320 	irqreturn_t ret = IRQ_WAKE_THREAD;
321 
322 	if (!adev || !adev->auxdrv || !adev->auxdrv_data)
323 		return IRQ_NONE;
324 
325 	if (adev->auxdrv_data->isr)
326 		ret = adev->auxdrv_data->isr(adev);
327 
328 	if (ret == IRQ_WAKE_THREAD && !adev->auxdrv_data->isr_threaded)
329 		ret = IRQ_NONE;
330 
331 	return ret;
332 }
333 
334 irqreturn_t ipu_buttress_isr(int irq, void *isp_ptr)
335 {
336 	struct ipu7_device *isp = isp_ptr;
337 	struct ipu7_bus_device *adev[] = { isp->isys, isp->psys };
338 	struct ipu_buttress *b = &isp->buttress;
339 	struct device *dev = &isp->pdev->dev;
340 	irqreturn_t ret = IRQ_NONE;
341 	u32 pb_irq, pb_local_irq;
342 	u32 disable_irqs = 0;
343 	u32 irq_status;
344 	unsigned int i;
345 
346 	pm_runtime_get_noresume(dev);
347 
348 	pb_irq = readl(isp->pb_base + INTERRUPT_STATUS);
349 	writel(pb_irq, isp->pb_base + INTERRUPT_STATUS);
350 
351 	/* check btrs ATS, CFI and IMR errors, BIT(0) is unused for IPU */
352 	pb_local_irq = readl(isp->pb_base + BTRS_LOCAL_INTERRUPT_MASK);
353 	if (pb_local_irq & ~BIT(0)) {
354 		dev_warn(dev, "PB interrupt status 0x%x local 0x%x\n", pb_irq,
355 			 pb_local_irq);
356 		dev_warn(dev, "Details: %x %x %x %x %x %x %x %x\n",
357 			 readl(isp->pb_base + ATS_ERROR_LOG1),
358 			 readl(isp->pb_base + ATS_ERROR_LOG2),
359 			 readl(isp->pb_base + CFI_0_ERROR_LOG),
360 			 readl(isp->pb_base + CFI_1_ERROR_LOGGING),
361 			 readl(isp->pb_base + IMR_ERROR_LOGGING_LOW),
362 			 readl(isp->pb_base + IMR_ERROR_LOGGING_HIGH),
363 			 readl(isp->pb_base + IMR_ERROR_LOGGING_CFI_1_LOW),
364 			 readl(isp->pb_base + IMR_ERROR_LOGGING_CFI_1_HIGH));
365 	}
366 
367 	irq_status = readl(isp->base + BUTTRESS_REG_IRQ_STATUS);
368 	if (!irq_status) {
369 		pm_runtime_put_noidle(dev);
370 		return IRQ_NONE;
371 	}
372 
373 	do {
374 		writel(irq_status, isp->base + BUTTRESS_REG_IRQ_CLEAR);
375 
376 		for (i = 0; i < ARRAY_SIZE(ipu7_adev_irq_mask); i++) {
377 			irqreturn_t r = ipu_buttress_call_isr(adev[i]);
378 
379 			if (!(irq_status & ipu7_adev_irq_mask[i]))
380 				continue;
381 
382 			if (r == IRQ_WAKE_THREAD) {
383 				ret = IRQ_WAKE_THREAD;
384 				disable_irqs |= ipu7_adev_irq_mask[i];
385 			} else if (ret == IRQ_NONE && r == IRQ_HANDLED) {
386 				ret = IRQ_HANDLED;
387 			}
388 		}
389 
390 		if (irq_status & (BUTTRESS_IRQS | BUTTRESS_IRQ_SAI_VIOLATION) &&
391 		    ret == IRQ_NONE)
392 			ret = IRQ_HANDLED;
393 
394 		if (irq_status & BUTTRESS_IRQ_IPC_FROM_CSE_IS_WAITING) {
395 			dev_dbg(dev, "BUTTRESS_IRQ_IPC_FROM_CSE_IS_WAITING\n");
396 			ipu_buttress_ipc_recv(isp, &b->cse, &b->cse.recv_data);
397 			complete(&b->cse.recv_complete);
398 		}
399 
400 		if (irq_status & BUTTRESS_IRQ_CSE_CSR_SET)
401 			dev_dbg(dev, "BUTTRESS_IRQ_CSE_CSR_SET\n");
402 
403 		if (irq_status & BUTTRESS_IRQ_IPC_EXEC_DONE_BY_CSE) {
404 			dev_dbg(dev, "BUTTRESS_IRQ_IPC_EXEC_DONE_BY_CSE\n");
405 			complete(&b->cse.send_complete);
406 		}
407 
408 		if (irq_status & BUTTRESS_IRQ_PUNIT_2_IUNIT_IRQ)
409 			dev_dbg(dev, "BUTTRESS_IRQ_PUNIT_2_IUNIT_IRQ\n");
410 
411 		if (irq_status & BUTTRESS_IRQ_SAI_VIOLATION &&
412 		    ipu_buttress_get_secure_mode(isp))
413 			dev_err(dev, "BUTTRESS_IRQ_SAI_VIOLATION\n");
414 
415 		irq_status = readl(isp->base + BUTTRESS_REG_IRQ_STATUS);
416 	} while (irq_status);
417 
418 	if (disable_irqs)
419 		writel(BUTTRESS_IRQS & ~disable_irqs,
420 		       isp->base + BUTTRESS_REG_IRQ_ENABLE);
421 
422 	pm_runtime_put(dev);
423 
424 	return ret;
425 }
426 
427 irqreturn_t ipu_buttress_isr_threaded(int irq, void *isp_ptr)
428 {
429 	struct ipu7_device *isp = isp_ptr;
430 	struct ipu7_bus_device *adev[] = { isp->isys, isp->psys };
431 	const struct ipu7_auxdrv_data *drv_data = NULL;
432 	irqreturn_t ret = IRQ_NONE;
433 	unsigned int i;
434 
435 	for (i = 0; i < ARRAY_SIZE(ipu7_adev_irq_mask) && adev[i]; i++) {
436 		drv_data = adev[i]->auxdrv_data;
437 		if (!drv_data)
438 			continue;
439 
440 		if (drv_data->wake_isr_thread &&
441 		    drv_data->isr_threaded(adev[i]) == IRQ_HANDLED)
442 			ret = IRQ_HANDLED;
443 	}
444 
445 	writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_IRQ_ENABLE);
446 
447 	return ret;
448 }
449 
450 static int isys_d2d_power(struct device *dev, bool on)
451 {
452 	struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
453 	int ret = 0;
454 	u32 target = on ? BUTTRESS_D2D_PWR_ACK : 0U;
455 	u32 val;
456 
457 	dev_dbg(dev, "power %s isys d2d.\n", on ? "UP" : "DOWN");
458 	val = readl(isp->base + BUTTRESS_REG_D2D_CTL);
459 	if ((val & BUTTRESS_D2D_PWR_ACK) == target) {
460 		dev_info(dev, "d2d already in %s state.\n",
461 			 on ? "UP" : "DOWN");
462 		return 0;
463 	}
464 
465 	val = on ? val | BUTTRESS_D2D_PWR_EN : val & (~BUTTRESS_D2D_PWR_EN);
466 	writel(val, isp->base + BUTTRESS_REG_D2D_CTL);
467 	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_D2D_CTL,
468 				 val, (val & BUTTRESS_D2D_PWR_ACK) == target,
469 				 100, BUTTRESS_POWER_TIMEOUT_US);
470 	if (ret)
471 		dev_err(dev, "power %s d2d timeout. status: 0x%x\n",
472 			on ? "UP" : "DOWN", val);
473 
474 	return ret;
475 }
476 
477 static void isys_nde_control(struct device *dev, bool on)
478 {
479 	struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
480 	u32 val, value, scale, valid, resvec;
481 	u32 nde_reg;
482 
483 	if (on) {
484 		value = BUTTRESS_NDE_VAL_ACTIVE;
485 		scale = BUTTRESS_NDE_SCALE_ACTIVE;
486 		valid = BUTTRESS_NDE_VALID_ACTIVE;
487 	} else {
488 		value = BUTTRESS_NDE_VAL_DEFAULT;
489 		scale = BUTTRESS_NDE_SCALE_DEFAULT;
490 		valid = BUTTRESS_NDE_VALID_DEFAULT;
491 	}
492 
493 	/* only set the fabrics resource ownership for ipu8 */
494 	nde_reg = is_ipu8(isp->hw_ver) ? IPU8_BUTTRESS_REG_NDE_CONTROL :
495 		IPU7_BUTTRESS_REG_NDE_CONTROL;
496 	resvec = is_ipu8(isp->hw_ver) ? 0x2 : 0xe;
497 	val = FIELD_PREP(NDE_VAL_MASK, value) |
498 		FIELD_PREP(NDE_SCALE_MASK, scale) |
499 		FIELD_PREP(NDE_VALID_MASK, valid) |
500 		FIELD_PREP(NDE_RESVEC_MASK, resvec);
501 
502 	writel(val, isp->base + nde_reg);
503 }
504 
505 static int ipu7_buttress_powerup(struct device *dev,
506 				 const struct ipu_buttress_ctrl *ctrl)
507 {
508 	struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
509 	u32 val, exp_sts;
510 	int ret = 0;
511 
512 	if (!ctrl)
513 		return 0;
514 
515 	mutex_lock(&isp->buttress.power_mutex);
516 
517 	exp_sts = ctrl->pwr_sts_on << ctrl->pwr_sts_shift;
518 	if (ctrl->subsys_id == IPU_IS) {
519 		ret = isys_d2d_power(dev, true);
520 		if (ret)
521 			goto out_power;
522 		isys_nde_control(dev, true);
523 	}
524 
525 	/* request clock resource ownership */
526 	val = readl(isp->base + BUTTRESS_REG_SLEEP_LEVEL_CFG);
527 	val |= ctrl->ovrd_clk;
528 	writel(val, isp->base + BUTTRESS_REG_SLEEP_LEVEL_CFG);
529 	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_SLEEP_LEVEL_STS,
530 				 val, (val & ctrl->own_clk_ack),
531 				 100, BUTTRESS_POWER_TIMEOUT_US);
532 	if (ret)
533 		dev_warn(dev, "request clk ownership timeout. status 0x%x\n",
534 			 val);
535 
536 	val = ctrl->ratio << ctrl->ratio_shift | ctrl->cdyn << ctrl->cdyn_shift;
537 
538 	dev_dbg(dev, "set 0x%x to %s_WORKPOINT_REQ.\n", val,
539 		ctrl->subsys_id == IPU_IS ? "IS" : "PS");
540 	writel(val, isp->base + ctrl->freq_ctl);
541 
542 	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATUS,
543 				 val, ((val & ctrl->pwr_sts_mask) == exp_sts),
544 				 100, BUTTRESS_POWER_TIMEOUT_US);
545 	if (ret) {
546 		dev_err(dev, "%s power up timeout with status: 0x%x\n",
547 			ctrl->subsys_id == IPU_IS ? "IS" : "PS", val);
548 		goto out_power;
549 	}
550 
551 	dev_dbg(dev, "%s power up successfully. status: 0x%x\n",
552 		ctrl->subsys_id == IPU_IS ? "IS" : "PS", val);
553 
554 	/* release clock resource ownership */
555 	val = readl(isp->base + BUTTRESS_REG_SLEEP_LEVEL_CFG);
556 	val &= ~ctrl->ovrd_clk;
557 	writel(val, isp->base + BUTTRESS_REG_SLEEP_LEVEL_CFG);
558 
559 out_power:
560 	mutex_unlock(&isp->buttress.power_mutex);
561 
562 	return ret;
563 }
564 
565 static int ipu7_buttress_powerdown(struct device *dev,
566 				   const struct ipu_buttress_ctrl *ctrl)
567 {
568 	struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
569 	u32 val, exp_sts;
570 	int ret = 0;
571 
572 	if (!ctrl)
573 		return 0;
574 
575 	mutex_lock(&isp->buttress.power_mutex);
576 
577 	exp_sts = ctrl->pwr_sts_off << ctrl->pwr_sts_shift;
578 	val = 0x8U << ctrl->ratio_shift;
579 
580 	dev_dbg(dev, "set 0x%x to %s_WORKPOINT_REQ.\n", val,
581 		ctrl->subsys_id == IPU_IS ? "IS" : "PS");
582 	writel(val, isp->base + ctrl->freq_ctl);
583 	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATUS,
584 				 val, ((val & ctrl->pwr_sts_mask) == exp_sts),
585 				 100, BUTTRESS_POWER_TIMEOUT_US);
586 	if (ret) {
587 		dev_err(dev, "%s power down timeout with status: 0x%x\n",
588 			ctrl->subsys_id == IPU_IS ? "IS" : "PS", val);
589 		goto out_power;
590 	}
591 
592 	dev_dbg(dev, "%s power down successfully. status: 0x%x\n",
593 		ctrl->subsys_id == IPU_IS ? "IS" : "PS", val);
594 out_power:
595 	if (ctrl->subsys_id == IPU_IS && !ret) {
596 		isys_d2d_power(dev, false);
597 		isys_nde_control(dev, false);
598 	}
599 
600 	mutex_unlock(&isp->buttress.power_mutex);
601 
602 	return ret;
603 }
604 
605 static int ipu8_buttress_powerup(struct device *dev,
606 				 const struct ipu_buttress_ctrl *ctrl)
607 {
608 	struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
609 	u32 sleep_level_reg = BUTTRESS_REG_SLEEP_LEVEL_STS;
610 	u32 val, exp_sts;
611 	int ret = 0;
612 
613 	if (!ctrl)
614 		return 0;
615 
616 	mutex_lock(&isp->buttress.power_mutex);
617 	exp_sts = ctrl->pwr_sts_on << ctrl->pwr_sts_shift;
618 	if (ctrl->subsys_id == IPU_IS) {
619 		ret = isys_d2d_power(dev, true);
620 		if (ret)
621 			goto out_power;
622 		isys_nde_control(dev, true);
623 	}
624 
625 	/* request ps_pll when psys freq > 400Mhz */
626 	if (ctrl->subsys_id == IPU_PS && ctrl->ratio > 0x10) {
627 		writel(1, isp->base + BUTTRESS_REG_PS_PLL_ENABLE);
628 		ret = readl_poll_timeout(isp->base + sleep_level_reg,
629 					 val, (val & ctrl->own_clk_ack),
630 					 100, BUTTRESS_POWER_TIMEOUT_US);
631 		if (ret)
632 			dev_warn(dev, "ps_pll req ack timeout. status 0x%x\n",
633 				 val);
634 	}
635 
636 	val = ctrl->ratio << ctrl->ratio_shift | ctrl->cdyn << ctrl->cdyn_shift;
637 	dev_dbg(dev, "set 0x%x to %s_WORKPOINT_REQ.\n", val,
638 		ctrl->subsys_id == IPU_IS ? "IS" : "PS");
639 	writel(val, isp->base + ctrl->freq_ctl);
640 	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATUS,
641 				 val, ((val & ctrl->pwr_sts_mask) == exp_sts),
642 				 100, BUTTRESS_POWER_TIMEOUT_US);
643 	if (ret) {
644 		dev_err(dev, "%s power up timeout with status: 0x%x\n",
645 			ctrl->subsys_id == IPU_IS ? "IS" : "PS", val);
646 		goto out_power;
647 	}
648 
649 	dev_dbg(dev, "%s power up successfully. status: 0x%x\n",
650 		ctrl->subsys_id == IPU_IS ? "IS" : "PS", val);
651 out_power:
652 	mutex_unlock(&isp->buttress.power_mutex);
653 
654 	return ret;
655 }
656 
657 static int ipu8_buttress_powerdown(struct device *dev,
658 				   const struct ipu_buttress_ctrl *ctrl)
659 {
660 	struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
661 	u32 val, exp_sts;
662 	int ret = 0;
663 
664 	if (!ctrl)
665 		return 0;
666 
667 	mutex_lock(&isp->buttress.power_mutex);
668 	exp_sts = ctrl->pwr_sts_off << ctrl->pwr_sts_shift;
669 
670 	if (ctrl->subsys_id == IPU_PS)
671 		val = 0x10U << ctrl->ratio_shift;
672 	else
673 		val = 0x8U << ctrl->ratio_shift;
674 
675 	dev_dbg(dev, "set 0x%x to %s_WORKPOINT_REQ.\n", val,
676 		ctrl->subsys_id == IPU_IS ? "IS" : "PS");
677 	writel(val, isp->base + ctrl->freq_ctl);
678 	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATUS,
679 				 val, ((val & ctrl->pwr_sts_mask) == exp_sts),
680 				 100, BUTTRESS_POWER_TIMEOUT_US);
681 	if (ret) {
682 		dev_err(dev, "%s power down timeout with status: 0x%x\n",
683 			ctrl->subsys_id == IPU_IS ? "IS" : "PS", val);
684 		goto out_power;
685 	}
686 
687 	dev_dbg(dev, "%s power down successfully. status: 0x%x\n",
688 		ctrl->subsys_id == IPU_IS ? "IS" : "PS", val);
689 out_power:
690 	if (ctrl->subsys_id == IPU_IS && !ret) {
691 		isys_d2d_power(dev, false);
692 		isys_nde_control(dev, false);
693 	}
694 
695 	if (ctrl->subsys_id == IPU_PS) {
696 		val = readl(isp->base + BUTTRESS_REG_SLEEP_LEVEL_STS);
697 		if (val & ctrl->own_clk_ack)
698 			writel(0, isp->base + BUTTRESS_REG_PS_PLL_ENABLE);
699 	}
700 	mutex_unlock(&isp->buttress.power_mutex);
701 
702 	return ret;
703 }
704 
705 int ipu_buttress_powerup(struct device *dev,
706 			 const struct ipu_buttress_ctrl *ctrl)
707 {
708 	struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
709 
710 	if (is_ipu8(isp->hw_ver))
711 		return ipu8_buttress_powerup(dev, ctrl);
712 
713 	return ipu7_buttress_powerup(dev, ctrl);
714 }
715 
716 int ipu_buttress_powerdown(struct device *dev,
717 			   const struct ipu_buttress_ctrl *ctrl)
718 {
719 	struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
720 
721 	if (is_ipu8(isp->hw_ver))
722 		return ipu8_buttress_powerdown(dev, ctrl);
723 
724 	return ipu7_buttress_powerdown(dev, ctrl);
725 }
726 
727 bool ipu_buttress_get_secure_mode(struct ipu7_device *isp)
728 {
729 	u32 val;
730 
731 	val = readl(isp->base + BUTTRESS_REG_SECURITY_CTL);
732 
733 	return val & BUTTRESS_SECURITY_CTL_FW_SECURE_MODE;
734 }
735 
736 bool ipu_buttress_auth_done(struct ipu7_device *isp)
737 {
738 	u32 val;
739 
740 	if (!isp->secure_mode)
741 		return true;
742 
743 	val = readl(isp->base + BUTTRESS_REG_SECURITY_CTL);
744 	val = FIELD_GET(BUTTRESS_SECURITY_CTL_FW_SETUP_MASK, val);
745 
746 	return val == BUTTRESS_SECURITY_CTL_AUTH_DONE;
747 }
748 EXPORT_SYMBOL_NS_GPL(ipu_buttress_auth_done, "INTEL_IPU7");
749 
750 int ipu_buttress_get_isys_freq(struct ipu7_device *isp, u32 *freq)
751 {
752 	u32 reg_val;
753 	int ret;
754 
755 	ret = pm_runtime_get_sync(&isp->isys->auxdev.dev);
756 	if (ret < 0) {
757 		pm_runtime_put(&isp->isys->auxdev.dev);
758 		dev_err(&isp->pdev->dev, "Runtime PM failed (%d)\n", ret);
759 		return ret;
760 	}
761 
762 	reg_val = readl(isp->base + BUTTRESS_REG_IS_WORKPOINT_REQ);
763 
764 	pm_runtime_put(&isp->isys->auxdev.dev);
765 
766 	if (is_ipu8(isp->hw_ver))
767 		*freq = (reg_val & BUTTRESS_IS_FREQ_CTL_RATIO_MASK) * 25;
768 	else
769 		*freq = (reg_val & BUTTRESS_IS_FREQ_CTL_RATIO_MASK) * 50 / 3;
770 
771 	return 0;
772 }
773 EXPORT_SYMBOL_NS_GPL(ipu_buttress_get_isys_freq, "INTEL_IPU7");
774 
775 int ipu_buttress_get_psys_freq(struct ipu7_device *isp, u32 *freq)
776 {
777 	u32 reg_val;
778 	int ret;
779 
780 	ret = pm_runtime_get_sync(&isp->psys->auxdev.dev);
781 	if (ret < 0) {
782 		pm_runtime_put(&isp->psys->auxdev.dev);
783 		dev_err(&isp->pdev->dev, "Runtime PM failed (%d)\n", ret);
784 		return ret;
785 	}
786 
787 	reg_val = readl(isp->base + BUTTRESS_REG_PS_WORKPOINT_REQ);
788 
789 	pm_runtime_put(&isp->psys->auxdev.dev);
790 
791 	reg_val &= BUTTRESS_PS_FREQ_CTL_RATIO_MASK;
792 	*freq = BUTTRESS_PS_FREQ_RATIO_STEP * reg_val;
793 
794 	return 0;
795 }
796 EXPORT_SYMBOL_NS_GPL(ipu_buttress_get_psys_freq, "INTEL_IPU7");
797 
798 int ipu_buttress_reset_authentication(struct ipu7_device *isp)
799 {
800 	struct device *dev = &isp->pdev->dev;
801 	int ret;
802 	u32 val;
803 
804 	if (!isp->secure_mode) {
805 		dev_dbg(dev, "Skip auth for non-secure mode\n");
806 		return 0;
807 	}
808 
809 	writel(BUTTRESS_FW_RESET_CTL_START, isp->base +
810 	       BUTTRESS_REG_FW_RESET_CTL);
811 
812 	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_FW_RESET_CTL, val,
813 				 val & BUTTRESS_FW_RESET_CTL_DONE, 500,
814 				 BUTTRESS_CSE_FWRESET_TIMEOUT_US);
815 	if (ret) {
816 		dev_err(dev, "Time out while resetting authentication state\n");
817 		return ret;
818 	}
819 
820 	dev_dbg(dev, "FW reset for authentication done\n");
821 	writel(0, isp->base + BUTTRESS_REG_FW_RESET_CTL);
822 	/* leave some time for HW restore */
823 	usleep_range(800, 1000);
824 
825 	return 0;
826 }
827 
828 int ipu_buttress_authenticate(struct ipu7_device *isp)
829 {
830 	struct ipu_buttress *b = &isp->buttress;
831 	struct device *dev = &isp->pdev->dev;
832 	u32 data, mask, done, fail;
833 	int ret;
834 
835 	if (!isp->secure_mode) {
836 		dev_dbg(dev, "Skip auth for non-secure mode\n");
837 		return 0;
838 	}
839 
840 	mutex_lock(&b->auth_mutex);
841 
842 	if (ipu_buttress_auth_done(isp)) {
843 		ret = 0;
844 		goto out_unlock;
845 	}
846 
847 	/*
848 	 * BUTTRESS_REG_FW_SOURCE_BASE needs to be set with FW CPD
849 	 * package address for secure mode.
850 	 */
851 
852 	writel(isp->cpd_fw->size, isp->base + BUTTRESS_REG_FW_SOURCE_SIZE);
853 	writel(sg_dma_address(isp->psys->fw_sgt.sgl),
854 	       isp->base + BUTTRESS_REG_FW_SOURCE_BASE);
855 
856 	/*
857 	 * Write boot_load into IU2CSEDATA0
858 	 * Write sizeof(boot_load) | 0x2 << CLIENT_ID to
859 	 * IU2CSEDB.IU2CSECMD and set IU2CSEDB.IU2CSEBUSY as
860 	 */
861 	dev_info(dev, "Sending BOOT_LOAD to CSE\n");
862 	ret = ipu_buttress_ipc_send(isp, BUTTRESS_IU2CSEDATA0_IPC_BOOT_LOAD,
863 				    1, true,
864 				    BUTTRESS_CSE2IUDATA0_IPC_BOOT_LOAD_DONE);
865 	if (ret) {
866 		dev_err(dev, "CSE boot_load failed\n");
867 		goto out_unlock;
868 	}
869 
870 	mask = BUTTRESS_SECURITY_CTL_FW_SETUP_MASK;
871 	done = BUTTRESS_SECURITY_CTL_FW_SETUP_DONE;
872 	fail = BUTTRESS_SECURITY_CTL_AUTH_FAILED;
873 	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_SECURITY_CTL, data,
874 				 ((data & mask) == done ||
875 				  (data & mask) == fail), 500,
876 				 BUTTRESS_CSE_BOOTLOAD_TIMEOUT_US);
877 	if (ret) {
878 		dev_err(dev, "CSE boot_load timeout\n");
879 		goto out_unlock;
880 	}
881 
882 	if ((data & mask) == fail) {
883 		dev_err(dev, "CSE auth failed\n");
884 		ret = -EINVAL;
885 		goto out_unlock;
886 	}
887 
888 	ret = readl_poll_timeout(isp->base + BOOTLOADER_STATUS_OFFSET,
889 				 data, data == BOOTLOADER_MAGIC_KEY, 500,
890 				 BUTTRESS_CSE_BOOTLOAD_TIMEOUT_US);
891 	if (ret) {
892 		dev_err(dev, "Unexpected magic number 0x%x\n", data);
893 		goto out_unlock;
894 	}
895 
896 	/*
897 	 * Write authenticate_run into IU2CSEDATA0
898 	 * Write sizeof(boot_load) | 0x2 << CLIENT_ID to
899 	 * IU2CSEDB.IU2CSECMD and set IU2CSEDB.IU2CSEBUSY as
900 	 */
901 	dev_info(dev, "Sending AUTHENTICATE_RUN to CSE\n");
902 	ret = ipu_buttress_ipc_send(isp, BUTTRESS_IU2CSEDATA0_IPC_AUTH_RUN,
903 				    1, true,
904 				    BUTTRESS_CSE2IUDATA0_IPC_AUTH_RUN_DONE);
905 	if (ret) {
906 		dev_err(dev, "CSE authenticate_run failed\n");
907 		goto out_unlock;
908 	}
909 
910 	done = BUTTRESS_SECURITY_CTL_AUTH_DONE;
911 	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_SECURITY_CTL, data,
912 				 ((data & mask) == done ||
913 				  (data & mask) == fail), 500,
914 				 BUTTRESS_CSE_AUTHENTICATE_TIMEOUT_US);
915 	if (ret) {
916 		dev_err(dev, "CSE authenticate timeout\n");
917 		goto out_unlock;
918 	}
919 
920 	if ((data & mask) == fail) {
921 		dev_err(dev, "CSE boot_load failed\n");
922 		ret = -EINVAL;
923 		goto out_unlock;
924 	}
925 
926 	dev_info(dev, "CSE authenticate_run done\n");
927 
928 out_unlock:
929 	mutex_unlock(&b->auth_mutex);
930 
931 	return ret;
932 }
933 
934 static int ipu_buttress_send_tsc_request(struct ipu7_device *isp)
935 {
936 	u32 val, mask, done;
937 	int ret;
938 
939 	mask = BUTTRESS_PWR_STATUS_HH_STATUS_MASK;
940 
941 	writel(BUTTRESS_TSC_CMD_START_TSC_SYNC,
942 	       isp->base + BUTTRESS_REG_TSC_CMD);
943 
944 	val = readl(isp->base + BUTTRESS_REG_PWR_STATUS);
945 	val = FIELD_GET(mask, val);
946 	if (val == BUTTRESS_PWR_STATUS_HH_STATE_ERR) {
947 		dev_err(&isp->pdev->dev, "Start tsc sync failed\n");
948 		return -EINVAL;
949 	}
950 
951 	done = BUTTRESS_PWR_STATUS_HH_STATE_DONE;
952 	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATUS, val,
953 				 FIELD_GET(mask, val) == done, 500,
954 				 BUTTRESS_TSC_SYNC_TIMEOUT_US);
955 	if (ret)
956 		dev_err(&isp->pdev->dev, "Start tsc sync timeout\n");
957 
958 	return ret;
959 }
960 
961 int ipu_buttress_start_tsc_sync(struct ipu7_device *isp)
962 {
963 	void __iomem *base = isp->base;
964 	unsigned int i;
965 	u32 val;
966 
967 	if (is_ipu8(isp->hw_ver)) {
968 		for (i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) {
969 			val = readl(base + BUTTRESS_REG_PB_TIMESTAMP_VALID);
970 			if (val == 1)
971 				return 0;
972 			usleep_range(40, 50);
973 		}
974 
975 		dev_err(&isp->pdev->dev, "PB HH sync failed (valid %u)\n", val);
976 		return -ETIMEDOUT;
977 	}
978 
979 	if (is_ipu7p5(isp->hw_ver)) {
980 		val = readl(base + BUTTRESS_REG_TSC_CTL);
981 		val |= BUTTRESS_SEL_PB_TIMESTAMP;
982 		writel(val, base + BUTTRESS_REG_TSC_CTL);
983 
984 		for (i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) {
985 			val = readl(base + BUTTRESS_REG_PB_TIMESTAMP_VALID);
986 			if (val == 1)
987 				return 0;
988 			usleep_range(40, 50);
989 		}
990 
991 		dev_err(&isp->pdev->dev, "PB HH sync failed (valid %u)\n", val);
992 
993 		return -ETIMEDOUT;
994 	}
995 
996 	for (i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) {
997 		int ret;
998 
999 		ret = ipu_buttress_send_tsc_request(isp);
1000 		if (ret != -ETIMEDOUT)
1001 			return ret;
1002 
1003 		val = readl(base + BUTTRESS_REG_TSC_CTL);
1004 		val = val | BUTTRESS_TSW_WA_SOFT_RESET;
1005 		writel(val, base + BUTTRESS_REG_TSC_CTL);
1006 		val = val & (~BUTTRESS_TSW_WA_SOFT_RESET);
1007 		writel(val, base + BUTTRESS_REG_TSC_CTL);
1008 	}
1009 
1010 	dev_err(&isp->pdev->dev, "TSC sync failed (timeout)\n");
1011 
1012 	return -ETIMEDOUT;
1013 }
1014 EXPORT_SYMBOL_NS_GPL(ipu_buttress_start_tsc_sync, "INTEL_IPU7");
1015 
1016 void ipu_buttress_tsc_read(struct ipu7_device *isp, u64 *val)
1017 {
1018 	unsigned long flags;
1019 	u32 tsc_hi, tsc_lo;
1020 
1021 	local_irq_save(flags);
1022 	if (is_ipu7(isp->hw_ver)) {
1023 		tsc_lo = readl(isp->base + BUTTRESS_REG_TSC_LO);
1024 		tsc_hi = readl(isp->base + BUTTRESS_REG_TSC_HI);
1025 	} else {
1026 		tsc_lo = readl(isp->base + BUTTRESS_REG_PB_TIMESTAMP_LO);
1027 		tsc_hi = readl(isp->base + BUTTRESS_REG_PB_TIMESTAMP_HI);
1028 	}
1029 	*val = (u64)tsc_hi << 32 | tsc_lo;
1030 	local_irq_restore(flags);
1031 }
1032 EXPORT_SYMBOL_NS_GPL(ipu_buttress_tsc_read, "INTEL_IPU7");
1033 
1034 u64 ipu_buttress_tsc_ticks_to_ns(u64 ticks, const struct ipu7_device *isp)
1035 {
1036 	u64 ns = ticks * 10000;
1037 
1038 	/*
1039 	 * converting TSC tick count to ns is calculated by:
1040 	 * Example (TSC clock frequency is 19.2MHz):
1041 	 * ns = ticks * 1000 000 000 / 19.2Mhz
1042 	 *    = ticks * 1000 000 000 / 19200000Hz
1043 	 *    = ticks * 10000 / 192 ns
1044 	 */
1045 	return div_u64(ns, isp->buttress.ref_clk);
1046 }
1047 EXPORT_SYMBOL_NS_GPL(ipu_buttress_tsc_ticks_to_ns, "INTEL_IPU7");
1048 
1049 /* trigger uc control to wakeup fw */
1050 void ipu_buttress_wakeup_is_uc(const struct ipu7_device *isp)
1051 {
1052 	u32 val;
1053 
1054 	val = readl(isp->base + BUTTRESS_REG_DRV_IS_UCX_CONTROL_STATUS);
1055 	val |= UCX_CTL_WAKEUP;
1056 	writel(val, isp->base + BUTTRESS_REG_DRV_IS_UCX_CONTROL_STATUS);
1057 }
1058 EXPORT_SYMBOL_NS_GPL(ipu_buttress_wakeup_is_uc, "INTEL_IPU7");
1059 
1060 void ipu_buttress_wakeup_ps_uc(const struct ipu7_device *isp)
1061 {
1062 	u32 val;
1063 
1064 	val = readl(isp->base + BUTTRESS_REG_DRV_PS_UCX_CONTROL_STATUS);
1065 	val |= UCX_CTL_WAKEUP;
1066 	writel(val, isp->base + BUTTRESS_REG_DRV_PS_UCX_CONTROL_STATUS);
1067 }
1068 EXPORT_SYMBOL_NS_GPL(ipu_buttress_wakeup_ps_uc, "INTEL_IPU7");
1069 
1070 static const struct x86_cpu_id ipu_misc_cfg_exclusion[] = {
1071 	X86_MATCH_VFM_STEPS(INTEL_PANTHERLAKE_L, 0x1, 0x1, 0),
1072 	{},
1073 };
1074 
1075 static void ipu_buttress_setup(struct ipu7_device *isp)
1076 {
1077 	struct device *dev = &isp->pdev->dev;
1078 	u32 val;
1079 
1080 	/* program PB BAR */
1081 #define WRXREQOP_OVRD_VAL_MASK  GENMASK(22, 19)
1082 	writel(0, isp->pb_base + GLOBAL_INTERRUPT_MASK);
1083 	val = readl(isp->pb_base + BAR2_MISC_CONFIG);
1084 	if (is_ipu7(isp->hw_ver) || x86_match_cpu(ipu_misc_cfg_exclusion))
1085 		val |= 0x100U;
1086 	else
1087 		val |= FIELD_PREP(WRXREQOP_OVRD_VAL_MASK, 0xf) |
1088 			BIT(18) | 0x100U;
1089 
1090 	writel(val, isp->pb_base + BAR2_MISC_CONFIG);
1091 	val = readl(isp->pb_base + BAR2_MISC_CONFIG);
1092 
1093 	if (is_ipu8(isp->hw_ver)) {
1094 		writel(BIT(13), isp->pb_base + TLBID_HASH_ENABLE_63_32);
1095 		writel(BIT(9), isp->pb_base + TLBID_HASH_ENABLE_95_64);
1096 		dev_dbg(dev, "IPU8 TLBID_HASH %x %x\n",
1097 			readl(isp->pb_base + TLBID_HASH_ENABLE_63_32),
1098 			readl(isp->pb_base + TLBID_HASH_ENABLE_95_64));
1099 	} else if (is_ipu7p5(isp->hw_ver)) {
1100 		writel(BIT(14), isp->pb_base + TLBID_HASH_ENABLE_63_32);
1101 		writel(BIT(9), isp->pb_base + TLBID_HASH_ENABLE_95_64);
1102 		dev_dbg(dev, "IPU7P5 TLBID_HASH %x %x\n",
1103 			readl(isp->pb_base + TLBID_HASH_ENABLE_63_32),
1104 			readl(isp->pb_base + TLBID_HASH_ENABLE_95_64));
1105 	} else {
1106 		writel(BIT(22), isp->pb_base + TLBID_HASH_ENABLE_63_32);
1107 		writel(BIT(1), isp->pb_base + TLBID_HASH_ENABLE_127_96);
1108 		dev_dbg(dev, "TLBID_HASH %x %x\n",
1109 			readl(isp->pb_base + TLBID_HASH_ENABLE_63_32),
1110 			readl(isp->pb_base + TLBID_HASH_ENABLE_127_96));
1111 	}
1112 
1113 	writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_IRQ_CLEAR);
1114 	writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_IRQ_MASK);
1115 	writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_IRQ_ENABLE);
1116 	/* LNL SW workaround for PS PD hang when PS sub-domain during PD */
1117 	writel(PS_FSM_CG, isp->base + BUTTRESS_REG_CG_CTRL_BITS);
1118 }
1119 
1120 void ipu_buttress_restore(struct ipu7_device *isp)
1121 {
1122 	struct ipu_buttress *b = &isp->buttress;
1123 
1124 	ipu_buttress_setup(isp);
1125 
1126 	writel(b->wdt_cached_value, isp->base + BUTTRESS_REG_IDLE_WDT);
1127 }
1128 
1129 int ipu_buttress_init(struct ipu7_device *isp)
1130 {
1131 	int ret, ipc_reset_retry = BUTTRESS_CSE_IPC_RESET_RETRY;
1132 	struct ipu_buttress *b = &isp->buttress;
1133 	struct device *dev = &isp->pdev->dev;
1134 	u32 val;
1135 
1136 	mutex_init(&b->power_mutex);
1137 	mutex_init(&b->auth_mutex);
1138 	mutex_init(&b->cons_mutex);
1139 	mutex_init(&b->ipc_mutex);
1140 	init_completion(&b->cse.send_complete);
1141 	init_completion(&b->cse.recv_complete);
1142 
1143 	b->cse.nack = BUTTRESS_CSE2IUDATA0_IPC_NACK;
1144 	b->cse.nack_mask = BUTTRESS_CSE2IUDATA0_IPC_NACK_MASK;
1145 	b->cse.csr_in = BUTTRESS_REG_CSE2IUCSR;
1146 	b->cse.csr_out = BUTTRESS_REG_IU2CSECSR;
1147 	b->cse.db0_in = BUTTRESS_REG_CSE2IUDB0;
1148 	b->cse.db0_out = BUTTRESS_REG_IU2CSEDB0;
1149 	b->cse.data0_in = BUTTRESS_REG_CSE2IUDATA0;
1150 	b->cse.data0_out = BUTTRESS_REG_IU2CSEDATA0;
1151 
1152 	isp->secure_mode = ipu_buttress_get_secure_mode(isp);
1153 	val = readl(isp->base + BUTTRESS_REG_IPU_SKU);
1154 	dev_info(dev, "IPU%u SKU %u in %s mode mask 0x%x\n", val & 0xfU,
1155 		 (val >> 4) & 0x7U, isp->secure_mode ? "secure" : "non-secure",
1156 		 readl(isp->base + BUTTRESS_REG_CAMERA_MASK));
1157 	b->wdt_cached_value = readl(isp->base + BUTTRESS_REG_IDLE_WDT);
1158 	b->ref_clk = 384;
1159 
1160 	ipu_buttress_setup(isp);
1161 
1162 	/* Retry couple of times in case of CSE initialization is delayed */
1163 	do {
1164 		ret = ipu_buttress_ipc_reset(isp, &b->cse);
1165 		if (ret) {
1166 			dev_warn(dev, "IPC reset protocol failed, retrying\n");
1167 		} else {
1168 			dev_dbg(dev, "IPC reset done\n");
1169 			return 0;
1170 		}
1171 	} while (ipc_reset_retry--);
1172 
1173 	dev_err(dev, "IPC reset protocol failed\n");
1174 
1175 	mutex_destroy(&b->power_mutex);
1176 	mutex_destroy(&b->auth_mutex);
1177 	mutex_destroy(&b->cons_mutex);
1178 	mutex_destroy(&b->ipc_mutex);
1179 
1180 	return ret;
1181 }
1182 
1183 void ipu_buttress_exit(struct ipu7_device *isp)
1184 {
1185 	struct ipu_buttress *b = &isp->buttress;
1186 
1187 	writel(0, isp->base + BUTTRESS_REG_IRQ_ENABLE);
1188 	mutex_destroy(&b->power_mutex);
1189 	mutex_destroy(&b->auth_mutex);
1190 	mutex_destroy(&b->cons_mutex);
1191 	mutex_destroy(&b->ipc_mutex);
1192 }
1193