mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
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:
@@ -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,7 +343,13 @@ static int tsec_module_suspend(struct device *dev)
|
|||||||
|
|
||||||
static int tsec_module_resume(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;
|
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)
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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 {
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
18
drivers/video/tegra/tsec/tsec_t264.h
Normal file
18
drivers/video/tegra/tsec/tsec_t264.h
Normal 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 */
|
||||||
Reference in New Issue
Block a user