From 9a57665a0fd28f2765b06837569c2b8c42d6c85d Mon Sep 17 00:00:00 2001 From: spatki Date: Mon, 19 May 2025 10:50:36 +0530 Subject: [PATCH] tsec: Add support for t264 fw init This change adds the support for programming streamids to allow tsec fw on t264 to access PA at a low privilege level. It also includes the synchronization logic to communicate with the fw regarding completion of stream id programming so that the fw can go ahead and initialize itself. In addition to this, the mailbox used for communicating init done from tsec fw to ccplex is changed from NV_PTSEC_FALCON_MAILBOX0 to NV_PTSEC_MAILBOX1 since CCPLEX does not have access to the former from t26x onwards. Hence falcon based mailboxes are used for tsec-psc comms and non-falcon ones for tsec-ccplex comms (stream id comms and init done). Jira TSEC-14 Change-Id: I2871a52222cd69786a8cc3f53162a80486611bb5 Signed-off-by: Sahil Patki Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3366343 Reviewed-by: Bharat Nihalani GVS: buildbot_gerritrpt (cherry picked from commit db54fde9c4d786b22b7f8694753de3ec80649b17) Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3400219 --- drivers/video/tegra/tsec/tsec.c | 73 ++++++++++++++++++++-------- drivers/video/tegra/tsec/tsec.h | 6 +++ drivers/video/tegra/tsec/tsec_boot.c | 3 +- drivers/video/tegra/tsec/tsec_boot.h | 7 ++- drivers/video/tegra/tsec/tsec_regs.h | 2 + drivers/video/tegra/tsec/tsec_t23x.c | 2 + drivers/video/tegra/tsec/tsec_t264.c | 36 ++++++++++++++ drivers/video/tegra/tsec/tsec_t264.h | 18 +++++++ 8 files changed, 125 insertions(+), 22 deletions(-) create mode 100644 drivers/video/tegra/tsec/tsec_t264.h diff --git a/drivers/video/tegra/tsec/tsec.c b/drivers/video/tegra/tsec/tsec.c index d26beca0..c104a901 100644 --- a/drivers/video/tegra/tsec/tsec.c +++ b/drivers/video/tegra/tsec/tsec.c @@ -11,6 +11,7 @@ #include "tsec.h" #include "tsec_boot.h" #include "tsec_regs.h" +#include "tsec_t264.h" /* @@ -113,23 +114,6 @@ static void tsec_assert_reset(struct tsec_device_data *pdata) reset_control_release(pdata->reset_control); } -static void tsec_set_streamid_regs(struct device *dev, - struct tsec_device_data *pdata) -{ - struct iommu_fwspec *fwspec; - int streamid; - struct tsec_reg_offsets_t *reg_off = pdata->tsec_reg_offsets; - /* Get the StreamID value */ - fwspec = dev_iommu_fwspec_get(dev); - if (fwspec && fwspec->num_ids) - streamid = fwspec->ids[0] & 0xffff; - else - streamid = 0x7F; /* bypass hwid */ - - /* Update the StreamID value */ - tsec_writel(pdata, reg_off->THI_STREAMID0_0, streamid); - tsec_writel(pdata, reg_off->THI_STREAMID1_0, streamid); -} static void tsec_set_cg_regs(struct tsec_device_data *pdata) { @@ -268,6 +252,37 @@ static void tsec_module_deinit_debugfs(struct platform_device *dev) } #endif /* CONFIG_DEBUG_FS */ +/* + * TSEC StreamID Register Programming Operation + */ +void tsec_set_streamid_regs(struct device *dev, + struct tsec_device_data *pdata) +{ + struct iommu_fwspec *fwspec; + int streamid; + struct tsec_reg_offsets_t *reg_off = pdata->tsec_reg_offsets; + /* Get the StreamID value */ + switch (pdata->soc) { + case TSEC_ON_T26x: + streamid = 0x7F; /* bypass hwid */ + break; + default: + fwspec = dev_iommu_fwspec_get(dev); + if (fwspec && fwspec->num_ids) + streamid = fwspec->ids[0] & 0xffff; + else + streamid = 0x7F; /* bypass hwid */ + break; + } + + /* Update the StreamID value */ + tsec_writel(pdata, reg_off->THI_STREAMID0_0, streamid); + tsec_writel(pdata, reg_off->THI_STREAMID1_0, streamid); + + /* Indicate that streamid programming is done */ + tsec_writel(pdata, reg_off->MAILBOX0, TSEC_RISCV_STREAMID_SET_DONE); +} + /* * TSEC Power Management Operations */ @@ -328,7 +343,13 @@ static int tsec_module_suspend(struct device *dev) static int tsec_module_resume(struct device *dev) { - return tsec_poweron(dev); + struct tsec_device_data *pdata = dev_get_drvdata(dev); + switch (pdata->soc) { + case TSEC_ON_T26x: + return tsec_t264_init(to_platform_device(dev)); + default: + return tsec_poweron(dev); + } } /* @@ -359,6 +380,11 @@ static int tsec_module_init(struct platform_device *dev) } pdata->reg_aperture = regs; + /* skip enabling clocks for T26x since PSC already does it*/ + if (pdata->soc == TSEC_ON_T26x) { + return 0; + } + /* Get interrupt */ pdata->irq = platform_get_irq(dev, 0); if (pdata->irq < 0) { @@ -476,7 +502,16 @@ static int tsec_probe(struct platform_device *dev) } #endif /* CONFIG_DEBUG_FS */ - return tsec_kickoff_boot(dev); + switch (pdata->soc) { + case TSEC_ON_T26x: + err = tsec_t264_init(dev); + break; + default: + err = tsec_kickoff_boot(dev); + break; + } + + return err; } static int tsec_remove(struct platform_device *dev) diff --git a/drivers/video/tegra/tsec/tsec.h b/drivers/video/tegra/tsec/tsec.h index d5c05de2..835f5f07 100644 --- a/drivers/video/tegra/tsec/tsec.h +++ b/drivers/video/tegra/tsec/tsec.h @@ -84,4 +84,10 @@ u32 tsec_readl(struct tsec_device_data *pdata, u32 r); int tsec_poweron(struct device *dev); int tsec_poweroff(struct device *dev); +/* + * TSEC StreamID Register Programming Operation + */ +void tsec_set_streamid_regs(struct device *dev, + struct tsec_device_data *pdata); + #endif /* TSEC_H */ diff --git a/drivers/video/tegra/tsec/tsec_boot.c b/drivers/video/tegra/tsec/tsec_boot.c index 16d29802..d143e4e3 100644 --- a/drivers/video/tegra/tsec/tsec_boot.c +++ b/drivers/video/tegra/tsec/tsec_boot.c @@ -18,8 +18,7 @@ #define NUM_OF_CMDS_TO_TEST (5) #endif -#define TSEC_RISCV_INIT_SUCCESS (0xa5a5a5a5) -#define TSEC_RISCV_SMMU_STREAMID1 BIT_ULL(40) + /* Set this to 1 to force backdoor boot */ #define TSEC_FORCE_BACKDOOR_BOOT (0) diff --git a/drivers/video/tegra/tsec/tsec_boot.h b/drivers/video/tegra/tsec/tsec_boot.h index 07d162f4..4b753b88 100644 --- a/drivers/video/tegra/tsec/tsec_boot.h +++ b/drivers/video/tegra/tsec/tsec_boot.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * * Tegra TSEC Module Support */ @@ -13,6 +13,11 @@ #define RISCV_IDLE_CHECK_PERIOD 10 /* 10 usec */ #define RISCV_IDLE_CHECK_PERIOD_LONG 1000 /* 1 milliseconds */ +/* TSEC RISCV boot status values */ +#define TSEC_RISCV_INIT_SUCCESS (0xa5a5a5a5) +#define TSEC_RISCV_SMMU_STREAMID1 BIT_ULL(40) +#define TSEC_RISCV_STREAMID_SET_DONE (0xa6a6a6a6) + /* Image descriptor format */ struct RM_RISCV_UCODE_DESC { /* diff --git a/drivers/video/tegra/tsec/tsec_regs.h b/drivers/video/tegra/tsec/tsec_regs.h index 5f69112e..6ff350fd 100644 --- a/drivers/video/tegra/tsec/tsec_regs.h +++ b/drivers/video/tegra/tsec/tsec_regs.h @@ -85,6 +85,8 @@ struct tsec_reg_offsets_t { u32 RISCV_BCR_DMACFG_SEC_GSCID; u32 FALCON_MAILBOX0; u32 FALCON_MAILBOX1; + u32 MAILBOX0; + u32 MAILBOX1; u32 RISCV_CPUCTL; u32 RISCV_CPUCTL_STARTCPU_TRUE; u32 RISCV_CPUCTL_ACTIVE_STAT; diff --git a/drivers/video/tegra/tsec/tsec_t23x.c b/drivers/video/tegra/tsec/tsec_t23x.c index 36285dc0..c756ef41 100644 --- a/drivers/video/tegra/tsec/tsec_t23x.c +++ b/drivers/video/tegra/tsec/tsec_t23x.c @@ -48,6 +48,8 @@ struct tsec_reg_offsets_t t23x_reg_offsets = { .RISCV_BCR_DMACFG_SEC_GSCID = 0x1f, .FALCON_MAILBOX0 = 0x1040, .FALCON_MAILBOX1 = 0x1044, + .MAILBOX0 = 0x1804, + .MAILBOX1 = 0x1808, .RISCV_CPUCTL = 0x2388, .RISCV_CPUCTL_STARTCPU_TRUE = BIT(0), .RISCV_CPUCTL_ACTIVE_STAT = 7, diff --git a/drivers/video/tegra/tsec/tsec_t264.c b/drivers/video/tegra/tsec/tsec_t264.c index d3b867da..717f7171 100644 --- a/drivers/video/tegra/tsec/tsec_t264.c +++ b/drivers/video/tegra/tsec/tsec_t264.c @@ -7,6 +7,9 @@ #include /* 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, @@ -48,6 +51,8 @@ struct tsec_reg_offsets_t t264_reg_offsets = { .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, @@ -59,3 +64,34 @@ struct tsec_reg_offsets_t t264_reg_offsets = { .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; +} + diff --git a/drivers/video/tegra/tsec/tsec_t264.h b/drivers/video/tegra/tsec/tsec_t264.h new file mode 100644 index 00000000..e8500661 --- /dev/null +++ b/drivers/video/tegra/tsec/tsec_t264.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * + * Tegra TSEC T264 Module Support + */ + +#ifndef TSEC_T264_H +#define TSEC_T264_H + +#include "tsec_linux.h" + +/* + * Initialize TSEC T264 initialization sequence + */ +int tsec_t264_init(struct platform_device *dev); + +#endif /* TSEC_T264_H */ \ No newline at end of file