// SPDX-License-Identifier: GPL-2.0-only
/*
 * SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES.  All rights reserved.
 *
 * Tegra TSEC Module Support
 */

#include <vdso/bits.h>                     /* for BIT(x) macro */
#include "tsec_regs.h"
#include "tsec_t264.h"
#include "tsec_boot.h"
#include "tsec.h"

struct tsec_reg_offsets_t t264_reg_offsets = {
	.QUEUE_HEAD_0 = 0x4c00,
	.QUEUE_TAIL_0 = 0x4c04,
	.MSGQ_HEAD_0 = 0x4c80,
	.MSGQ_TAIL_0 = 0x4c84,
	.EMEMC_0 = 0x4ac0,
	.EMEMD_0 = 0x4ac4,
	.THI_INT_STATUS_0 = 0x78,
	.THI_INT_STATUS_CLR_0 = BIT(0),
	.THI_STREAMID0_0 = 0x30,
	.THI_STREAMID1_0 = 0x34,
	.PRIV_BLOCKER_CTRL_CG1 = 0x1e28,
	.RISCV_CG = 0x2398,
	.RISCV_IRQSCLR_0 = 0x1004,
	.RISCV_IRQSTAT_0 = 0x1008,
	.RISCV_IRQMSET_0 = 0x2520,
	.RISCV_IRQMCLR_0 = 0x2524,
	.RISCV_IRQSCLR_SWGEN0_SET = BIT(6),
	.RISCV_IRQSTAT_SWGEN0 = BIT(6),
	.RISCV_IRQSTAT_SWGEN1 = BIT(7),
	.RISCV_IRQMCLR_SWGEN0_SET = BIT(6),
	.RISCV_IRQMCLR_SWGEN1_SET = BIT(7),
	.RISCV_IRQMSET_SWGEN0_SET = BIT(6),
	.THI_SEC_0 = 0x38,
	.THI_SEC_CHLOCK = BIT(8),
	.RISCV_BCR_CTRL = 0x2668,
	.RISCV_BCR_CTRL_CORE_SELECT_RISCV = BIT(4),
	.RISCV_BCR_DMAADDR_PKCPARAM_LO = 0x2670,
	.RISCV_BCR_DMAADDR_PKCPARAM_HI = 0x2674,
	.RISCV_BCR_DMAADDR_FMCCODE_LO = 0x2678,
	.RISCV_BCR_DMAADDR_FMCCODE_HI = 0x267c,
	.RISCV_BCR_DMAADDR_FMCDATA_LO = 0x2680,
	.RISCV_BCR_DMAADDR_FMCDATA_HI = 0x2684,
	.RISCV_BCR_DMACFG = 0x266c,
	.RISCV_BCR_DMACFG_TARGET_LOCAL_FB = 0x0,
	.RISCV_BCR_DMACFG_LOCK_LOCKED = BIT(31),
	.RISCV_BCR_DMACFG_SEC = 0x2694,
	.RISCV_BCR_DMACFG_SEC_GSCID = 0x1f,
	.FALCON_MAILBOX0 = 0x1040,
	.FALCON_MAILBOX1 = 0x1044,
	.MAILBOX0 = 0x4804,
	.MAILBOX1 = 0x4808,
	.RISCV_CPUCTL = 0x2388,
	.RISCV_CPUCTL_STARTCPU_TRUE = BIT(0),
	.RISCV_CPUCTL_ACTIVE_STAT = 7,
	.RISCV_CPUCTL_ACTIVE_STAT_ACTIVE = 1,
	.RISCV_BR_RETCODE = 0x265c,
	.RISCV_BR_RETCODE_RESULT = 0,
	.RISCV_BR_RETCODE_RESULT_PASS = 0x3,
	.FALCON_DMEMC_0 = 0x11c0,
	.FALCON_DMEMD_0 = 0x11c4,
	.DMEM_LOGBUF_OFFSET = 0x14000,
};

int tsec_t264_init(struct platform_device *dev)
{
	int err = 0;
	struct tsec_device_data *pdata = platform_get_drvdata(dev);
	void __iomem *mailbox0_addr;
	u32 val;

	mailbox0_addr = pdata->reg_aperture + t264_reg_offsets.MAILBOX0;

	/* Program StreamID registers */
	tsec_set_streamid_regs(&dev->dev, pdata);

	/* Wait for tsec to convey the boot success status */
	err  = readl_poll_timeout(mailbox0_addr, val,
		(val == TSEC_RISCV_INIT_SUCCESS),
		RISCV_IDLE_CHECK_PERIOD_LONG,
		RISCV_IDLE_TIMEOUT_LONG);
	if (err) {
		dev_err(&dev->dev, "tsec boot failure, timeout! val=0x%x\n", val);
		return err;
	}

	/* set poweron to true to enable debugfs */
	pdata->power_on = true;

	dev_info(&dev->dev, "T264 TSEC init done\n");

	return err;
}

