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