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 <spatki@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3366343
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
(cherry picked from commit db54fde9c4d786b22b7f8694753de3ec80649b17)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3400219
This commit is contained in:
spatki
2025-05-19 10:50:36 +05:30
committed by Jon Hunter
parent 27970204aa
commit 9a57665a0f
8 changed files with 125 additions and 22 deletions

View File

@@ -11,6 +11,7 @@
#include "tsec.h" #include "tsec.h"
#include "tsec_boot.h" #include "tsec_boot.h"
#include "tsec_regs.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); 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) 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 */ #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 * TSEC Power Management Operations
*/ */
@@ -328,8 +343,14 @@ static int tsec_module_suspend(struct device *dev)
static int tsec_module_resume(struct device *dev) static int tsec_module_resume(struct device *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); return tsec_poweron(dev);
} }
}
/* /*
* TSEC Probe/Remove and Module Init * TSEC Probe/Remove and Module Init
@@ -359,6 +380,11 @@ static int tsec_module_init(struct platform_device *dev)
} }
pdata->reg_aperture = regs; pdata->reg_aperture = regs;
/* skip enabling clocks for T26x since PSC already does it*/
if (pdata->soc == TSEC_ON_T26x) {
return 0;
}
/* Get interrupt */ /* Get interrupt */
pdata->irq = platform_get_irq(dev, 0); pdata->irq = platform_get_irq(dev, 0);
if (pdata->irq < 0) { if (pdata->irq < 0) {
@@ -476,7 +502,16 @@ static int tsec_probe(struct platform_device *dev)
} }
#endif /* CONFIG_DEBUG_FS */ #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) static int tsec_remove(struct platform_device *dev)

View File

@@ -84,4 +84,10 @@ u32 tsec_readl(struct tsec_device_data *pdata, u32 r);
int tsec_poweron(struct device *dev); int tsec_poweron(struct device *dev);
int tsec_poweroff(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 */ #endif /* TSEC_H */

View File

@@ -18,8 +18,7 @@
#define NUM_OF_CMDS_TO_TEST (5) #define NUM_OF_CMDS_TO_TEST (5)
#endif #endif
#define TSEC_RISCV_INIT_SUCCESS (0xa5a5a5a5)
#define TSEC_RISCV_SMMU_STREAMID1 BIT_ULL(40)
/* Set this to 1 to force backdoor boot */ /* Set this to 1 to force backdoor boot */
#define TSEC_FORCE_BACKDOOR_BOOT (0) #define TSEC_FORCE_BACKDOOR_BOOT (0)

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // 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 * Tegra TSEC Module Support
*/ */
@@ -13,6 +13,11 @@
#define RISCV_IDLE_CHECK_PERIOD 10 /* 10 usec */ #define RISCV_IDLE_CHECK_PERIOD 10 /* 10 usec */
#define RISCV_IDLE_CHECK_PERIOD_LONG 1000 /* 1 milliseconds */ #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 */ /* Image descriptor format */
struct RM_RISCV_UCODE_DESC { struct RM_RISCV_UCODE_DESC {
/* /*

View File

@@ -85,6 +85,8 @@ struct tsec_reg_offsets_t {
u32 RISCV_BCR_DMACFG_SEC_GSCID; u32 RISCV_BCR_DMACFG_SEC_GSCID;
u32 FALCON_MAILBOX0; u32 FALCON_MAILBOX0;
u32 FALCON_MAILBOX1; u32 FALCON_MAILBOX1;
u32 MAILBOX0;
u32 MAILBOX1;
u32 RISCV_CPUCTL; u32 RISCV_CPUCTL;
u32 RISCV_CPUCTL_STARTCPU_TRUE; u32 RISCV_CPUCTL_STARTCPU_TRUE;
u32 RISCV_CPUCTL_ACTIVE_STAT; u32 RISCV_CPUCTL_ACTIVE_STAT;

View File

@@ -48,6 +48,8 @@ struct tsec_reg_offsets_t t23x_reg_offsets = {
.RISCV_BCR_DMACFG_SEC_GSCID = 0x1f, .RISCV_BCR_DMACFG_SEC_GSCID = 0x1f,
.FALCON_MAILBOX0 = 0x1040, .FALCON_MAILBOX0 = 0x1040,
.FALCON_MAILBOX1 = 0x1044, .FALCON_MAILBOX1 = 0x1044,
.MAILBOX0 = 0x1804,
.MAILBOX1 = 0x1808,
.RISCV_CPUCTL = 0x2388, .RISCV_CPUCTL = 0x2388,
.RISCV_CPUCTL_STARTCPU_TRUE = BIT(0), .RISCV_CPUCTL_STARTCPU_TRUE = BIT(0),
.RISCV_CPUCTL_ACTIVE_STAT = 7, .RISCV_CPUCTL_ACTIVE_STAT = 7,

View File

@@ -7,6 +7,9 @@
#include <vdso/bits.h> /* for BIT(x) macro */ #include <vdso/bits.h> /* for BIT(x) macro */
#include "tsec_regs.h" #include "tsec_regs.h"
#include "tsec_t264.h"
#include "tsec_boot.h"
#include "tsec.h"
struct tsec_reg_offsets_t t264_reg_offsets = { struct tsec_reg_offsets_t t264_reg_offsets = {
.QUEUE_HEAD_0 = 0x4c00, .QUEUE_HEAD_0 = 0x4c00,
@@ -48,6 +51,8 @@ struct tsec_reg_offsets_t t264_reg_offsets = {
.RISCV_BCR_DMACFG_SEC_GSCID = 0x1f, .RISCV_BCR_DMACFG_SEC_GSCID = 0x1f,
.FALCON_MAILBOX0 = 0x1040, .FALCON_MAILBOX0 = 0x1040,
.FALCON_MAILBOX1 = 0x1044, .FALCON_MAILBOX1 = 0x1044,
.MAILBOX0 = 0x4804,
.MAILBOX1 = 0x4808,
.RISCV_CPUCTL = 0x2388, .RISCV_CPUCTL = 0x2388,
.RISCV_CPUCTL_STARTCPU_TRUE = BIT(0), .RISCV_CPUCTL_STARTCPU_TRUE = BIT(0),
.RISCV_CPUCTL_ACTIVE_STAT = 7, .RISCV_CPUCTL_ACTIVE_STAT = 7,
@@ -59,3 +64,34 @@ struct tsec_reg_offsets_t t264_reg_offsets = {
.FALCON_DMEMD_0 = 0x11c4, .FALCON_DMEMD_0 = 0x11c4,
.DMEM_LOGBUF_OFFSET = 0x14000, .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;
}

View File

@@ -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 */