File Index
Files and directories
Sign in
FILE

ipu7-buttress.c

File preview with syntax highlighting.

linux-6.19.14/drivers/staging/media/ipu7/ipu7-buttress.c C
   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
  54struct ipu7_ipc_buttress_msg {
  55	u32 cmd;
  56	u32 expected_resp;
  57	bool require_resp;
  58	u8 cmd_size;
  59};
  60
  61static const u32 ipu7_adev_irq_mask[2] = {
  62	BUTTRESS_IRQ_IS_IRQ,
  63	BUTTRESS_IRQ_PS_IRQ
  64};
  65
  66int 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
 182static 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
 189static int
 190ipu_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
 212static 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
 220static 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
 243try:
 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
 297out:
 298	ipu_buttress_ipc_validity_close(isp, ipc);
 299	mutex_unlock(&b->ipc_mutex);
 300
 301	return ret;
 302}
 303
 304static 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
 318static 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
 334irqreturn_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	int active;
 346
 347	active = pm_runtime_get_if_active(dev);
 348	if (active <= 0)
 349		return IRQ_NONE;
 350
 351	pb_irq = readl(isp->pb_base + INTERRUPT_STATUS);
 352	writel(pb_irq, isp->pb_base + INTERRUPT_STATUS);
 353
 354	/* check btrs ATS, CFI and IMR errors, BIT(0) is unused for IPU */
 355	pb_local_irq = readl(isp->pb_base + BTRS_LOCAL_INTERRUPT_MASK);
 356	if (pb_local_irq == 0xffffffff) {
 357		dev_warn_once(dev, "invalid PB irq status\n");
 358		pm_runtime_put_noidle(dev);
 359		return IRQ_NONE;
 360	}
 361
 362	if (pb_local_irq & ~BIT(0)) {
 363		dev_warn(dev, "PB interrupt status 0x%x local 0x%x\n", pb_irq,
 364			 pb_local_irq);
 365		dev_warn(dev, "Details: %x %x %x %x %x %x %x %x\n",
 366			 readl(isp->pb_base + ATS_ERROR_LOG1),
 367			 readl(isp->pb_base + ATS_ERROR_LOG2),
 368			 readl(isp->pb_base + CFI_0_ERROR_LOG),
 369			 readl(isp->pb_base + CFI_1_ERROR_LOGGING),
 370			 readl(isp->pb_base + IMR_ERROR_LOGGING_LOW),
 371			 readl(isp->pb_base + IMR_ERROR_LOGGING_HIGH),
 372			 readl(isp->pb_base + IMR_ERROR_LOGGING_CFI_1_LOW),
 373			 readl(isp->pb_base + IMR_ERROR_LOGGING_CFI_1_HIGH));
 374	}
 375
 376	irq_status = readl(isp->base + BUTTRESS_REG_IRQ_STATUS);
 377	if (!irq_status) {
 378		pm_runtime_put_noidle(dev);
 379		return IRQ_NONE;
 380	}
 381
 382	if (irq_status == 0xffffffff) {
 383		dev_warn_once(dev, "invalid irq status 0x%08x\n", irq_status);
 384		pm_runtime_put_noidle(dev);
 385		return IRQ_NONE;
 386	}
 387
 388	do {
 389		writel(irq_status, isp->base + BUTTRESS_REG_IRQ_CLEAR);
 390
 391		for (i = 0; i < ARRAY_SIZE(ipu7_adev_irq_mask); i++) {
 392			irqreturn_t r = ipu_buttress_call_isr(adev[i]);
 393
 394			if (!(irq_status & ipu7_adev_irq_mask[i]))
 395				continue;
 396
 397			if (r == IRQ_WAKE_THREAD) {
 398				ret = IRQ_WAKE_THREAD;
 399				disable_irqs |= ipu7_adev_irq_mask[i];
 400			} else if (ret == IRQ_NONE && r == IRQ_HANDLED) {
 401				ret = IRQ_HANDLED;
 402			}
 403		}
 404
 405		if (irq_status & (BUTTRESS_IRQS | BUTTRESS_IRQ_SAI_VIOLATION) &&
 406		    ret == IRQ_NONE)
 407			ret = IRQ_HANDLED;
 408
 409		if (irq_status & BUTTRESS_IRQ_IPC_FROM_CSE_IS_WAITING) {
 410			dev_dbg(dev, "BUTTRESS_IRQ_IPC_FROM_CSE_IS_WAITING\n");
 411			ipu_buttress_ipc_recv(isp, &b->cse, &b->cse.recv_data);
 412			complete(&b->cse.recv_complete);
 413		}
 414
 415		if (irq_status & BUTTRESS_IRQ_CSE_CSR_SET)
 416			dev_dbg(dev, "BUTTRESS_IRQ_CSE_CSR_SET\n");
 417
 418		if (irq_status & BUTTRESS_IRQ_IPC_EXEC_DONE_BY_CSE) {
 419			dev_dbg(dev, "BUTTRESS_IRQ_IPC_EXEC_DONE_BY_CSE\n");
 420			complete(&b->cse.send_complete);
 421		}
 422
 423		if (irq_status & BUTTRESS_IRQ_PUNIT_2_IUNIT_IRQ)
 424			dev_dbg(dev, "BUTTRESS_IRQ_PUNIT_2_IUNIT_IRQ\n");
 425
 426		if (irq_status & BUTTRESS_IRQ_SAI_VIOLATION &&
 427		    ipu_buttress_get_secure_mode(isp))
 428			dev_err(dev, "BUTTRESS_IRQ_SAI_VIOLATION\n");
 429
 430		irq_status = readl(isp->base + BUTTRESS_REG_IRQ_STATUS);
 431	} while (irq_status);
 432
 433	if (disable_irqs)
 434		writel(BUTTRESS_IRQS & ~disable_irqs,
 435		       isp->base + BUTTRESS_REG_IRQ_ENABLE);
 436
 437	pm_runtime_put(dev);
 438
 439	return ret;
 440}
 441
 442irqreturn_t ipu_buttress_isr_threaded(int irq, void *isp_ptr)
 443{
 444	struct ipu7_device *isp = isp_ptr;
 445	struct ipu7_bus_device *adev[] = { isp->isys, isp->psys };
 446	const struct ipu7_auxdrv_data *drv_data = NULL;
 447	irqreturn_t ret = IRQ_NONE;
 448	unsigned int i;
 449
 450	for (i = 0; i < ARRAY_SIZE(ipu7_adev_irq_mask) && adev[i]; i++) {
 451		drv_data = adev[i]->auxdrv_data;
 452		if (!drv_data)
 453			continue;
 454
 455		if (drv_data->wake_isr_thread &&
 456		    drv_data->isr_threaded(adev[i]) == IRQ_HANDLED)
 457			ret = IRQ_HANDLED;
 458	}
 459
 460	writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_IRQ_ENABLE);
 461
 462	return ret;
 463}
 464
 465static int isys_d2d_power(struct device *dev, bool on)
 466{
 467	struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
 468	int ret = 0;
 469	u32 target = on ? BUTTRESS_D2D_PWR_ACK : 0U;
 470	u32 val;
 471
 472	dev_dbg(dev, "power %s isys d2d.\n", on ? "UP" : "DOWN");
 473	val = readl(isp->base + BUTTRESS_REG_D2D_CTL);
 474	if ((val & BUTTRESS_D2D_PWR_ACK) == target) {
 475		dev_info(dev, "d2d already in %s state.\n",
 476			 on ? "UP" : "DOWN");
 477		return 0;
 478	}
 479
 480	val = on ? val | BUTTRESS_D2D_PWR_EN : val & (~BUTTRESS_D2D_PWR_EN);
 481	writel(val, isp->base + BUTTRESS_REG_D2D_CTL);
 482	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_D2D_CTL,
 483				 val, (val & BUTTRESS_D2D_PWR_ACK) == target,
 484				 100, BUTTRESS_POWER_TIMEOUT_US);
 485	if (ret)
 486		dev_err(dev, "power %s d2d timeout. status: 0x%x\n",
 487			on ? "UP" : "DOWN", val);
 488
 489	return ret;
 490}
 491
 492static void isys_nde_control(struct device *dev, bool on)
 493{
 494	struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
 495	u32 val, value, scale, valid, resvec;
 496	u32 nde_reg;
 497
 498	if (on) {
 499		value = BUTTRESS_NDE_VAL_ACTIVE;
 500		scale = BUTTRESS_NDE_SCALE_ACTIVE;
 501		valid = BUTTRESS_NDE_VALID_ACTIVE;
 502	} else {
 503		value = BUTTRESS_NDE_VAL_DEFAULT;
 504		scale = BUTTRESS_NDE_SCALE_DEFAULT;
 505		valid = BUTTRESS_NDE_VALID_DEFAULT;
 506	}
 507
 508	/* only set the fabrics resource ownership for ipu8 */
 509	nde_reg = is_ipu8(isp->hw_ver) ? IPU8_BUTTRESS_REG_NDE_CONTROL :
 510		IPU7_BUTTRESS_REG_NDE_CONTROL;
 511	resvec = is_ipu8(isp->hw_ver) ? 0x2 : 0xe;
 512	val = FIELD_PREP(NDE_VAL_MASK, value) |
 513		FIELD_PREP(NDE_SCALE_MASK, scale) |
 514		FIELD_PREP(NDE_VALID_MASK, valid) |
 515		FIELD_PREP(NDE_RESVEC_MASK, resvec);
 516
 517	writel(val, isp->base + nde_reg);
 518}
 519
 520static int ipu7_buttress_powerup(struct device *dev,
 521				 const struct ipu_buttress_ctrl *ctrl)
 522{
 523	struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
 524	u32 val, exp_sts;
 525	int ret = 0;
 526
 527	if (!ctrl)
 528		return 0;
 529
 530	mutex_lock(&isp->buttress.power_mutex);
 531
 532	exp_sts = ctrl->pwr_sts_on << ctrl->pwr_sts_shift;
 533	if (ctrl->subsys_id == IPU_IS) {
 534		ret = isys_d2d_power(dev, true);
 535		if (ret)
 536			goto out_power;
 537		isys_nde_control(dev, true);
 538	}
 539
 540	/* request clock resource ownership */
 541	val = readl(isp->base + BUTTRESS_REG_SLEEP_LEVEL_CFG);
 542	val |= ctrl->ovrd_clk;
 543	writel(val, isp->base + BUTTRESS_REG_SLEEP_LEVEL_CFG);
 544	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_SLEEP_LEVEL_STS,
 545				 val, (val & ctrl->own_clk_ack),
 546				 100, BUTTRESS_POWER_TIMEOUT_US);
 547	if (ret)
 548		dev_warn(dev, "request clk ownership timeout. status 0x%x\n",
 549			 val);
 550
 551	val = ctrl->ratio << ctrl->ratio_shift | ctrl->cdyn << ctrl->cdyn_shift;
 552
 553	dev_dbg(dev, "set 0x%x to %s_WORKPOINT_REQ.\n", val,
 554		ctrl->subsys_id == IPU_IS ? "IS" : "PS");
 555	writel(val, isp->base + ctrl->freq_ctl);
 556
 557	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATUS,
 558				 val, ((val & ctrl->pwr_sts_mask) == exp_sts),
 559				 100, BUTTRESS_POWER_TIMEOUT_US);
 560	if (ret) {
 561		dev_err(dev, "%s power up timeout with status: 0x%x\n",
 562			ctrl->subsys_id == IPU_IS ? "IS" : "PS", val);
 563		goto out_power;
 564	}
 565
 566	dev_dbg(dev, "%s power up successfully. status: 0x%x\n",
 567		ctrl->subsys_id == IPU_IS ? "IS" : "PS", val);
 568
 569	/* release clock resource ownership */
 570	val = readl(isp->base + BUTTRESS_REG_SLEEP_LEVEL_CFG);
 571	val &= ~ctrl->ovrd_clk;
 572	writel(val, isp->base + BUTTRESS_REG_SLEEP_LEVEL_CFG);
 573
 574out_power:
 575	mutex_unlock(&isp->buttress.power_mutex);
 576
 577	return ret;
 578}
 579
 580static int ipu7_buttress_powerdown(struct device *dev,
 581				   const struct ipu_buttress_ctrl *ctrl)
 582{
 583	struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
 584	u32 val, exp_sts;
 585	int ret = 0;
 586
 587	if (!ctrl)
 588		return 0;
 589
 590	mutex_lock(&isp->buttress.power_mutex);
 591
 592	exp_sts = ctrl->pwr_sts_off << ctrl->pwr_sts_shift;
 593	val = 0x8U << ctrl->ratio_shift;
 594
 595	dev_dbg(dev, "set 0x%x to %s_WORKPOINT_REQ.\n", val,
 596		ctrl->subsys_id == IPU_IS ? "IS" : "PS");
 597	writel(val, isp->base + ctrl->freq_ctl);
 598	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATUS,
 599				 val, ((val & ctrl->pwr_sts_mask) == exp_sts),
 600				 100, BUTTRESS_POWER_TIMEOUT_US);
 601	if (ret) {
 602		dev_err(dev, "%s power down timeout with status: 0x%x\n",
 603			ctrl->subsys_id == IPU_IS ? "IS" : "PS", val);
 604		goto out_power;
 605	}
 606
 607	dev_dbg(dev, "%s power down successfully. status: 0x%x\n",
 608		ctrl->subsys_id == IPU_IS ? "IS" : "PS", val);
 609out_power:
 610	if (ctrl->subsys_id == IPU_IS && !ret) {
 611		isys_d2d_power(dev, false);
 612		isys_nde_control(dev, false);
 613	}
 614
 615	mutex_unlock(&isp->buttress.power_mutex);
 616
 617	return ret;
 618}
 619
 620static int ipu8_buttress_powerup(struct device *dev,
 621				 const struct ipu_buttress_ctrl *ctrl)
 622{
 623	struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
 624	u32 sleep_level_reg = BUTTRESS_REG_SLEEP_LEVEL_STS;
 625	u32 val, exp_sts;
 626	int ret = 0;
 627
 628	if (!ctrl)
 629		return 0;
 630
 631	mutex_lock(&isp->buttress.power_mutex);
 632	exp_sts = ctrl->pwr_sts_on << ctrl->pwr_sts_shift;
 633	if (ctrl->subsys_id == IPU_IS) {
 634		ret = isys_d2d_power(dev, true);
 635		if (ret)
 636			goto out_power;
 637		isys_nde_control(dev, true);
 638	}
 639
 640	/* request ps_pll when psys freq > 400Mhz */
 641	if (ctrl->subsys_id == IPU_PS && ctrl->ratio > 0x10) {
 642		writel(1, isp->base + BUTTRESS_REG_PS_PLL_ENABLE);
 643		ret = readl_poll_timeout(isp->base + sleep_level_reg,
 644					 val, (val & ctrl->own_clk_ack),
 645					 100, BUTTRESS_POWER_TIMEOUT_US);
 646		if (ret)
 647			dev_warn(dev, "ps_pll req ack timeout. status 0x%x\n",
 648				 val);
 649	}
 650
 651	val = ctrl->ratio << ctrl->ratio_shift | ctrl->cdyn << ctrl->cdyn_shift;
 652	dev_dbg(dev, "set 0x%x to %s_WORKPOINT_REQ.\n", val,
 653		ctrl->subsys_id == IPU_IS ? "IS" : "PS");
 654	writel(val, isp->base + ctrl->freq_ctl);
 655	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATUS,
 656				 val, ((val & ctrl->pwr_sts_mask) == exp_sts),
 657				 100, BUTTRESS_POWER_TIMEOUT_US);
 658	if (ret) {
 659		dev_err(dev, "%s power up timeout with status: 0x%x\n",
 660			ctrl->subsys_id == IPU_IS ? "IS" : "PS", val);
 661		goto out_power;
 662	}
 663
 664	dev_dbg(dev, "%s power up successfully. status: 0x%x\n",
 665		ctrl->subsys_id == IPU_IS ? "IS" : "PS", val);
 666out_power:
 667	mutex_unlock(&isp->buttress.power_mutex);
 668
 669	return ret;
 670}
 671
 672static int ipu8_buttress_powerdown(struct device *dev,
 673				   const struct ipu_buttress_ctrl *ctrl)
 674{
 675	struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
 676	u32 val, exp_sts;
 677	int ret = 0;
 678
 679	if (!ctrl)
 680		return 0;
 681
 682	mutex_lock(&isp->buttress.power_mutex);
 683	exp_sts = ctrl->pwr_sts_off << ctrl->pwr_sts_shift;
 684
 685	if (ctrl->subsys_id == IPU_PS)
 686		val = 0x10U << ctrl->ratio_shift;
 687	else
 688		val = 0x8U << ctrl->ratio_shift;
 689
 690	dev_dbg(dev, "set 0x%x to %s_WORKPOINT_REQ.\n", val,
 691		ctrl->subsys_id == IPU_IS ? "IS" : "PS");
 692	writel(val, isp->base + ctrl->freq_ctl);
 693	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATUS,
 694				 val, ((val & ctrl->pwr_sts_mask) == exp_sts),
 695				 100, BUTTRESS_POWER_TIMEOUT_US);
 696	if (ret) {
 697		dev_err(dev, "%s power down timeout with status: 0x%x\n",
 698			ctrl->subsys_id == IPU_IS ? "IS" : "PS", val);
 699		goto out_power;
 700	}
 701
 702	dev_dbg(dev, "%s power down successfully. status: 0x%x\n",
 703		ctrl->subsys_id == IPU_IS ? "IS" : "PS", val);
 704out_power:
 705	if (ctrl->subsys_id == IPU_IS && !ret) {
 706		isys_d2d_power(dev, false);
 707		isys_nde_control(dev, false);
 708	}
 709
 710	if (ctrl->subsys_id == IPU_PS) {
 711		val = readl(isp->base + BUTTRESS_REG_SLEEP_LEVEL_STS);
 712		if (val & ctrl->own_clk_ack)
 713			writel(0, isp->base + BUTTRESS_REG_PS_PLL_ENABLE);
 714	}
 715	mutex_unlock(&isp->buttress.power_mutex);
 716
 717	return ret;
 718}
 719
 720int ipu_buttress_powerup(struct device *dev,
 721			 const struct ipu_buttress_ctrl *ctrl)
 722{
 723	struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
 724
 725	if (is_ipu8(isp->hw_ver))
 726		return ipu8_buttress_powerup(dev, ctrl);
 727
 728	return ipu7_buttress_powerup(dev, ctrl);
 729}
 730
 731int ipu_buttress_powerdown(struct device *dev,
 732			   const struct ipu_buttress_ctrl *ctrl)
 733{
 734	struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
 735
 736	if (is_ipu8(isp->hw_ver))
 737		return ipu8_buttress_powerdown(dev, ctrl);
 738
 739	return ipu7_buttress_powerdown(dev, ctrl);
 740}
 741
 742bool ipu_buttress_get_secure_mode(struct ipu7_device *isp)
 743{
 744	u32 val;
 745
 746	val = readl(isp->base + BUTTRESS_REG_SECURITY_CTL);
 747
 748	return val & BUTTRESS_SECURITY_CTL_FW_SECURE_MODE;
 749}
 750
 751bool ipu_buttress_auth_done(struct ipu7_device *isp)
 752{
 753	u32 val;
 754
 755	if (!isp->secure_mode)
 756		return true;
 757
 758	val = readl(isp->base + BUTTRESS_REG_SECURITY_CTL);
 759	val = FIELD_GET(BUTTRESS_SECURITY_CTL_FW_SETUP_MASK, val);
 760
 761	return val == BUTTRESS_SECURITY_CTL_AUTH_DONE;
 762}
 763EXPORT_SYMBOL_NS_GPL(ipu_buttress_auth_done, "INTEL_IPU7");
 764
 765int ipu_buttress_get_isys_freq(struct ipu7_device *isp, u32 *freq)
 766{
 767	u32 reg_val;
 768	int ret;
 769
 770	ret = pm_runtime_get_sync(&isp->isys->auxdev.dev);
 771	if (ret < 0) {
 772		pm_runtime_put(&isp->isys->auxdev.dev);
 773		dev_err(&isp->pdev->dev, "Runtime PM failed (%d)\n", ret);
 774		return ret;
 775	}
 776
 777	reg_val = readl(isp->base + BUTTRESS_REG_IS_WORKPOINT_REQ);
 778
 779	pm_runtime_put(&isp->isys->auxdev.dev);
 780
 781	if (is_ipu8(isp->hw_ver))
 782		*freq = (reg_val & BUTTRESS_IS_FREQ_CTL_RATIO_MASK) * 25;
 783	else
 784		*freq = (reg_val & BUTTRESS_IS_FREQ_CTL_RATIO_MASK) * 50 / 3;
 785
 786	return 0;
 787}
 788EXPORT_SYMBOL_NS_GPL(ipu_buttress_get_isys_freq, "INTEL_IPU7");
 789
 790int ipu_buttress_get_psys_freq(struct ipu7_device *isp, u32 *freq)
 791{
 792	u32 reg_val;
 793	int ret;
 794
 795	ret = pm_runtime_get_sync(&isp->psys->auxdev.dev);
 796	if (ret < 0) {
 797		pm_runtime_put(&isp->psys->auxdev.dev);
 798		dev_err(&isp->pdev->dev, "Runtime PM failed (%d)\n", ret);
 799		return ret;
 800	}
 801
 802	reg_val = readl(isp->base + BUTTRESS_REG_PS_WORKPOINT_REQ);
 803
 804	pm_runtime_put(&isp->psys->auxdev.dev);
 805
 806	reg_val &= BUTTRESS_PS_FREQ_CTL_RATIO_MASK;
 807	*freq = BUTTRESS_PS_FREQ_RATIO_STEP * reg_val;
 808
 809	return 0;
 810}
 811EXPORT_SYMBOL_NS_GPL(ipu_buttress_get_psys_freq, "INTEL_IPU7");
 812
 813int ipu_buttress_reset_authentication(struct ipu7_device *isp)
 814{
 815	struct device *dev = &isp->pdev->dev;
 816	int ret;
 817	u32 val;
 818
 819	if (!isp->secure_mode) {
 820		dev_dbg(dev, "Skip auth for non-secure mode\n");
 821		return 0;
 822	}
 823
 824	writel(BUTTRESS_FW_RESET_CTL_START, isp->base +
 825	       BUTTRESS_REG_FW_RESET_CTL);
 826
 827	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_FW_RESET_CTL, val,
 828				 val & BUTTRESS_FW_RESET_CTL_DONE, 500,
 829				 BUTTRESS_CSE_FWRESET_TIMEOUT_US);
 830	if (ret) {
 831		dev_err(dev, "Time out while resetting authentication state\n");
 832		return ret;
 833	}
 834
 835	dev_dbg(dev, "FW reset for authentication done\n");
 836	writel(0, isp->base + BUTTRESS_REG_FW_RESET_CTL);
 837	/* leave some time for HW restore */
 838	usleep_range(800, 1000);
 839
 840	return 0;
 841}
 842
 843int ipu_buttress_authenticate(struct ipu7_device *isp)
 844{
 845	struct ipu_buttress *b = &isp->buttress;
 846	struct device *dev = &isp->pdev->dev;
 847	u32 data, mask, done, fail;
 848	int ret;
 849
 850	if (!isp->secure_mode) {
 851		dev_dbg(dev, "Skip auth for non-secure mode\n");
 852		return 0;
 853	}
 854
 855	mutex_lock(&b->auth_mutex);
 856
 857	if (ipu_buttress_auth_done(isp)) {
 858		ret = 0;
 859		goto out_unlock;
 860	}
 861
 862	/*
 863	 * BUTTRESS_REG_FW_SOURCE_BASE needs to be set with FW CPD
 864	 * package address for secure mode.
 865	 */
 866
 867	writel(isp->cpd_fw->size, isp->base + BUTTRESS_REG_FW_SOURCE_SIZE);
 868	writel(sg_dma_address(isp->psys->fw_sgt.sgl),
 869	       isp->base + BUTTRESS_REG_FW_SOURCE_BASE);
 870
 871	/*
 872	 * Write boot_load into IU2CSEDATA0
 873	 * Write sizeof(boot_load) | 0x2 << CLIENT_ID to
 874	 * IU2CSEDB.IU2CSECMD and set IU2CSEDB.IU2CSEBUSY as
 875	 */
 876	dev_info(dev, "Sending BOOT_LOAD to CSE\n");
 877	ret = ipu_buttress_ipc_send(isp, BUTTRESS_IU2CSEDATA0_IPC_BOOT_LOAD,
 878				    1, true,
 879				    BUTTRESS_CSE2IUDATA0_IPC_BOOT_LOAD_DONE);
 880	if (ret) {
 881		dev_err(dev, "CSE boot_load failed\n");
 882		goto out_unlock;
 883	}
 884
 885	mask = BUTTRESS_SECURITY_CTL_FW_SETUP_MASK;
 886	done = BUTTRESS_SECURITY_CTL_FW_SETUP_DONE;
 887	fail = BUTTRESS_SECURITY_CTL_AUTH_FAILED;
 888	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_SECURITY_CTL, data,
 889				 ((data & mask) == done ||
 890				  (data & mask) == fail), 500,
 891				 BUTTRESS_CSE_BOOTLOAD_TIMEOUT_US);
 892	if (ret) {
 893		dev_err(dev, "CSE boot_load timeout\n");
 894		goto out_unlock;
 895	}
 896
 897	if ((data & mask) == fail) {
 898		dev_err(dev, "CSE auth failed\n");
 899		ret = -EINVAL;
 900		goto out_unlock;
 901	}
 902
 903	ret = readl_poll_timeout(isp->base + BOOTLOADER_STATUS_OFFSET,
 904				 data, data == BOOTLOADER_MAGIC_KEY, 500,
 905				 BUTTRESS_CSE_BOOTLOAD_TIMEOUT_US);
 906	if (ret) {
 907		dev_err(dev, "Unexpected magic number 0x%x\n", data);
 908		goto out_unlock;
 909	}
 910
 911	/*
 912	 * Write authenticate_run into IU2CSEDATA0
 913	 * Write sizeof(boot_load) | 0x2 << CLIENT_ID to
 914	 * IU2CSEDB.IU2CSECMD and set IU2CSEDB.IU2CSEBUSY as
 915	 */
 916	dev_info(dev, "Sending AUTHENTICATE_RUN to CSE\n");
 917	ret = ipu_buttress_ipc_send(isp, BUTTRESS_IU2CSEDATA0_IPC_AUTH_RUN,
 918				    1, true,
 919				    BUTTRESS_CSE2IUDATA0_IPC_AUTH_RUN_DONE);
 920	if (ret) {
 921		dev_err(dev, "CSE authenticate_run failed\n");
 922		goto out_unlock;
 923	}
 924
 925	done = BUTTRESS_SECURITY_CTL_AUTH_DONE;
 926	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_SECURITY_CTL, data,
 927				 ((data & mask) == done ||
 928				  (data & mask) == fail), 500,
 929				 BUTTRESS_CSE_AUTHENTICATE_TIMEOUT_US);
 930	if (ret) {
 931		dev_err(dev, "CSE authenticate timeout\n");
 932		goto out_unlock;
 933	}
 934
 935	if ((data & mask) == fail) {
 936		dev_err(dev, "CSE boot_load failed\n");
 937		ret = -EINVAL;
 938		goto out_unlock;
 939	}
 940
 941	dev_info(dev, "CSE authenticate_run done\n");
 942
 943out_unlock:
 944	mutex_unlock(&b->auth_mutex);
 945
 946	return ret;
 947}
 948
 949static int ipu_buttress_send_tsc_request(struct ipu7_device *isp)
 950{
 951	u32 val, mask, done;
 952	int ret;
 953
 954	mask = BUTTRESS_PWR_STATUS_HH_STATUS_MASK;
 955
 956	writel(BUTTRESS_TSC_CMD_START_TSC_SYNC,
 957	       isp->base + BUTTRESS_REG_TSC_CMD);
 958
 959	val = readl(isp->base + BUTTRESS_REG_PWR_STATUS);
 960	val = FIELD_GET(mask, val);
 961	if (val == BUTTRESS_PWR_STATUS_HH_STATE_ERR) {
 962		dev_err(&isp->pdev->dev, "Start tsc sync failed\n");
 963		return -EINVAL;
 964	}
 965
 966	done = BUTTRESS_PWR_STATUS_HH_STATE_DONE;
 967	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATUS, val,
 968				 FIELD_GET(mask, val) == done, 500,
 969				 BUTTRESS_TSC_SYNC_TIMEOUT_US);
 970	if (ret)
 971		dev_err(&isp->pdev->dev, "Start tsc sync timeout\n");
 972
 973	return ret;
 974}
 975
 976int ipu_buttress_start_tsc_sync(struct ipu7_device *isp)
 977{
 978	void __iomem *base = isp->base;
 979	unsigned int i;
 980	u32 val;
 981
 982	if (is_ipu8(isp->hw_ver)) {
 983		for (i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) {
 984			val = readl(base + BUTTRESS_REG_PB_TIMESTAMP_VALID);
 985			if (val == 1)
 986				return 0;
 987			usleep_range(40, 50);
 988		}
 989
 990		dev_err(&isp->pdev->dev, "PB HH sync failed (valid %u)\n", val);
 991		return -ETIMEDOUT;
 992	}
 993
 994	if (is_ipu7p5(isp->hw_ver)) {
 995		val = readl(base + BUTTRESS_REG_TSC_CTL);
 996		val |= BUTTRESS_SEL_PB_TIMESTAMP;
 997		writel(val, base + BUTTRESS_REG_TSC_CTL);
 998
 999		for (i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) {
1000			val = readl(base + BUTTRESS_REG_PB_TIMESTAMP_VALID);
1001			if (val == 1)
1002				return 0;
1003			usleep_range(40, 50);
1004		}
1005
1006		dev_err(&isp->pdev->dev, "PB HH sync failed (valid %u)\n", val);
1007
1008		return -ETIMEDOUT;
1009	}
1010
1011	for (i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) {
1012		int ret;
1013
1014		ret = ipu_buttress_send_tsc_request(isp);
1015		if (ret != -ETIMEDOUT)
1016			return ret;
1017
1018		val = readl(base + BUTTRESS_REG_TSC_CTL);
1019		val = val | BUTTRESS_TSW_WA_SOFT_RESET;
1020		writel(val, base + BUTTRESS_REG_TSC_CTL);
1021		val = val & (~BUTTRESS_TSW_WA_SOFT_RESET);
1022		writel(val, base + BUTTRESS_REG_TSC_CTL);
1023	}
1024
1025	dev_err(&isp->pdev->dev, "TSC sync failed (timeout)\n");
1026
1027	return -ETIMEDOUT;
1028}
1029EXPORT_SYMBOL_NS_GPL(ipu_buttress_start_tsc_sync, "INTEL_IPU7");
1030
1031void ipu_buttress_tsc_read(struct ipu7_device *isp, u64 *val)
1032{
1033	unsigned long flags;
1034	u32 tsc_hi, tsc_lo;
1035
1036	local_irq_save(flags);
1037	if (is_ipu7(isp->hw_ver)) {
1038		tsc_lo = readl(isp->base + BUTTRESS_REG_TSC_LO);
1039		tsc_hi = readl(isp->base + BUTTRESS_REG_TSC_HI);
1040	} else {
1041		tsc_lo = readl(isp->base + BUTTRESS_REG_PB_TIMESTAMP_LO);
1042		tsc_hi = readl(isp->base + BUTTRESS_REG_PB_TIMESTAMP_HI);
1043	}
1044	*val = (u64)tsc_hi << 32 | tsc_lo;
1045	local_irq_restore(flags);
1046}
1047EXPORT_SYMBOL_NS_GPL(ipu_buttress_tsc_read, "INTEL_IPU7");
1048
1049u64 ipu_buttress_tsc_ticks_to_ns(u64 ticks, const struct ipu7_device *isp)
1050{
1051	u64 ns = ticks * 10000;
1052
1053	/*
1054	 * converting TSC tick count to ns is calculated by:
1055	 * Example (TSC clock frequency is 19.2MHz):
1056	 * ns = ticks * 1000 000 000 / 19.2Mhz
1057	 *    = ticks * 1000 000 000 / 19200000Hz
1058	 *    = ticks * 10000 / 192 ns
1059	 */
1060	return div_u64(ns, isp->buttress.ref_clk);
1061}
1062EXPORT_SYMBOL_NS_GPL(ipu_buttress_tsc_ticks_to_ns, "INTEL_IPU7");
1063
1064/* trigger uc control to wakeup fw */
1065void ipu_buttress_wakeup_is_uc(const struct ipu7_device *isp)
1066{
1067	u32 val;
1068
1069	val = readl(isp->base + BUTTRESS_REG_DRV_IS_UCX_CONTROL_STATUS);
1070	val |= UCX_CTL_WAKEUP;
1071	writel(val, isp->base + BUTTRESS_REG_DRV_IS_UCX_CONTROL_STATUS);
1072}
1073EXPORT_SYMBOL_NS_GPL(ipu_buttress_wakeup_is_uc, "INTEL_IPU7");
1074
1075void ipu_buttress_wakeup_ps_uc(const struct ipu7_device *isp)
1076{
1077	u32 val;
1078
1079	val = readl(isp->base + BUTTRESS_REG_DRV_PS_UCX_CONTROL_STATUS);
1080	val |= UCX_CTL_WAKEUP;
1081	writel(val, isp->base + BUTTRESS_REG_DRV_PS_UCX_CONTROL_STATUS);
1082}
1083EXPORT_SYMBOL_NS_GPL(ipu_buttress_wakeup_ps_uc, "INTEL_IPU7");
1084
1085static const struct x86_cpu_id ipu_misc_cfg_exclusion[] = {
1086	X86_MATCH_VFM_STEPS(INTEL_PANTHERLAKE_L, 0x1, 0x1, 0),
1087	{},
1088};
1089
1090static void ipu_buttress_setup(struct ipu7_device *isp)
1091{
1092	struct device *dev = &isp->pdev->dev;
1093	u32 val;
1094
1095	/* program PB BAR */
1096#define WRXREQOP_OVRD_VAL_MASK  GENMASK(22, 19)
1097	writel(0, isp->pb_base + GLOBAL_INTERRUPT_MASK);
1098	val = readl(isp->pb_base + BAR2_MISC_CONFIG);
1099	if (is_ipu7(isp->hw_ver) || x86_match_cpu(ipu_misc_cfg_exclusion))
1100		val |= 0x100U;
1101	else
1102		val |= FIELD_PREP(WRXREQOP_OVRD_VAL_MASK, 0xf) |
1103			BIT(18) | 0x100U;
1104
1105	writel(val, isp->pb_base + BAR2_MISC_CONFIG);
1106	val = readl(isp->pb_base + BAR2_MISC_CONFIG);
1107
1108	if (is_ipu8(isp->hw_ver)) {
1109		writel(BIT(13), isp->pb_base + TLBID_HASH_ENABLE_63_32);
1110		writel(BIT(9), isp->pb_base + TLBID_HASH_ENABLE_95_64);
1111		dev_dbg(dev, "IPU8 TLBID_HASH %x %x\n",
1112			readl(isp->pb_base + TLBID_HASH_ENABLE_63_32),
1113			readl(isp->pb_base + TLBID_HASH_ENABLE_95_64));
1114	} else if (is_ipu7p5(isp->hw_ver)) {
1115		writel(BIT(14), isp->pb_base + TLBID_HASH_ENABLE_63_32);
1116		writel(BIT(9), isp->pb_base + TLBID_HASH_ENABLE_95_64);
1117		dev_dbg(dev, "IPU7P5 TLBID_HASH %x %x\n",
1118			readl(isp->pb_base + TLBID_HASH_ENABLE_63_32),
1119			readl(isp->pb_base + TLBID_HASH_ENABLE_95_64));
1120	} else {
1121		writel(BIT(22), isp->pb_base + TLBID_HASH_ENABLE_63_32);
1122		writel(BIT(1), isp->pb_base + TLBID_HASH_ENABLE_127_96);
1123		dev_dbg(dev, "TLBID_HASH %x %x\n",
1124			readl(isp->pb_base + TLBID_HASH_ENABLE_63_32),
1125			readl(isp->pb_base + TLBID_HASH_ENABLE_127_96));
1126	}
1127
1128	writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_IRQ_CLEAR);
1129	writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_IRQ_MASK);
1130	writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_IRQ_ENABLE);
1131	/* LNL SW workaround for PS PD hang when PS sub-domain during PD */
1132	writel(PS_FSM_CG, isp->base + BUTTRESS_REG_CG_CTRL_BITS);
1133}
1134
1135void ipu_buttress_restore(struct ipu7_device *isp)
1136{
1137	struct ipu_buttress *b = &isp->buttress;
1138
1139	ipu_buttress_setup(isp);
1140
1141	writel(b->wdt_cached_value, isp->base + BUTTRESS_REG_IDLE_WDT);
1142}
1143
1144int ipu_buttress_init(struct ipu7_device *isp)
1145{
1146	int ret, ipc_reset_retry = BUTTRESS_CSE_IPC_RESET_RETRY;
1147	struct ipu_buttress *b = &isp->buttress;
1148	struct device *dev = &isp->pdev->dev;
1149	u32 val;
1150
1151	mutex_init(&b->power_mutex);
1152	mutex_init(&b->auth_mutex);
1153	mutex_init(&b->cons_mutex);
1154	mutex_init(&b->ipc_mutex);
1155	init_completion(&b->cse.send_complete);
1156	init_completion(&b->cse.recv_complete);
1157
1158	b->cse.nack = BUTTRESS_CSE2IUDATA0_IPC_NACK;
1159	b->cse.nack_mask = BUTTRESS_CSE2IUDATA0_IPC_NACK_MASK;
1160	b->cse.csr_in = BUTTRESS_REG_CSE2IUCSR;
1161	b->cse.csr_out = BUTTRESS_REG_IU2CSECSR;
1162	b->cse.db0_in = BUTTRESS_REG_CSE2IUDB0;
1163	b->cse.db0_out = BUTTRESS_REG_IU2CSEDB0;
1164	b->cse.data0_in = BUTTRESS_REG_CSE2IUDATA0;
1165	b->cse.data0_out = BUTTRESS_REG_IU2CSEDATA0;
1166
1167	isp->secure_mode = ipu_buttress_get_secure_mode(isp);
1168	val = readl(isp->base + BUTTRESS_REG_IPU_SKU);
1169	dev_info(dev, "IPU%u SKU %u in %s mode mask 0x%x\n", val & 0xfU,
1170		 (val >> 4) & 0x7U, isp->secure_mode ? "secure" : "non-secure",
1171		 readl(isp->base + BUTTRESS_REG_CAMERA_MASK));
1172	b->wdt_cached_value = readl(isp->base + BUTTRESS_REG_IDLE_WDT);
1173	b->ref_clk = 384;
1174
1175	ipu_buttress_setup(isp);
1176
1177	/* Retry couple of times in case of CSE initialization is delayed */
1178	do {
1179		ret = ipu_buttress_ipc_reset(isp, &b->cse);
1180		if (ret) {
1181			dev_warn(dev, "IPC reset protocol failed, retrying\n");
1182		} else {
1183			dev_dbg(dev, "IPC reset done\n");
1184			return 0;
1185		}
1186	} while (ipc_reset_retry--);
1187
1188	dev_err(dev, "IPC reset protocol failed\n");
1189
1190	mutex_destroy(&b->power_mutex);
1191	mutex_destroy(&b->auth_mutex);
1192	mutex_destroy(&b->cons_mutex);
1193	mutex_destroy(&b->ipc_mutex);
1194
1195	return ret;
1196}
1197
1198void ipu_buttress_exit(struct ipu7_device *isp)
1199{
1200	struct ipu_buttress *b = &isp->buttress;
1201
1202	writel(0, isp->base + BUTTRESS_REG_IRQ_ENABLE);
1203	mutex_destroy(&b->power_mutex);
1204	mutex_destroy(&b->auth_mutex);
1205	mutex_destroy(&b->cons_mutex);
1206	mutex_destroy(&b->ipc_mutex);
1207}
~/ Read-only file preview.