nvdla: kmd: fix DLA3 bringup bugs

- Compile axi-nvdla.ko alongside nvhost-nvdla.ko driver.
- Fix the sequence of register programming that is unique
    to DLA3.
- Introduce a debugfs node for bitbang loading the IMEM/DMEM
    contents.
- Raised Bug 4942853 to track the syncpoint features.
- Address review comments from the previous patchsets in
    regard to the DLA3 updates.

Bug 4916080

Change-Id: I6859868e6cdd3e11f90e76a8bcf79a9676cd5a52
Signed-off-by: Arvind M <am@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3205466
Reviewed-by: svcacv <svcacv@nvidia.com>
Reviewed-by: Mitch Harwell <mharwell@nvidia.com>
Reviewed-by: Ken Adams <kadams@nvidia.com>
Reviewed-by: Amit Sharma (SW-TEGRA) <amisharma@nvidia.com>
Reviewed-by: Vishal Thoke <vthoke@nvidia.com>
This commit is contained in:
Arvind M
2024-11-04 10:29:09 +00:00
committed by Jon Hunter
parent 442dd0068f
commit 1acb4426db
11 changed files with 127 additions and 53 deletions

View File

@@ -5,16 +5,12 @@
# nvhost-nvdla.ko
#
NVDLA_TOP := .
ifndef CONFIG_TEGRA_KLEAF_BUILD
include $(src)/Makefile.config.mk
else
include $(srctree.nvidia-oot)/drivers/video/tegra/host/nvdla/Makefile.config.mk
endif
NVDLA_COMMON_OBJS := $(addprefix $(NVDLA_TOP)/,$(NVDLA_COMMON_OBJS))
ccflags-y += -DNVDLA_HAVE_CONFIG_HW_PERFMON=1
ccflags-y += -DNVDLA_HAVE_CONFIG_AXI=0
ccflags-y += -DNVDLA_HAVE_CONFIG_SYNCPTFD=1
@@ -25,12 +21,13 @@ endif
nvhost-nvdla-objs += \
$(NVDLA_COMMON_OBJS) \
$(NVDLA_TOP)/port/device/nvdla_device_host1x.o \
$(NVDLA_TOP)/port/fw/nvdla_fw_flcn.o \
$(NVDLA_TOP)/port/sync/nvdla_sync_syncpt.o
port/device/nvdla_device_host1x.o \
port/fw/nvdla_fw_flcn.o \
port/sync/nvdla_sync_syncpt.o
ifdef CONFIG_TEGRA_GRHOST
nvhost-nvdla-objs += $(NVDLA_TOP)/dla_channel.o
nvhost-nvdla-objs += dla_channel.o
endif
obj-m += nvhost-nvdla.o
obj-m += axi/

View File

@@ -3,10 +3,15 @@
# SPDX-License-Identifier: LicenseRef-NvidiaProprietary
#
NVDLA_TOP := ../
include $(src)/../Makefile.config.mk
NVDLA_MODULE_NAME=axi-nvdla
NVDLA_COMMON_OBJS := $(addprefix $(NVDLA_TOP)/,$(NVDLA_COMMON_OBJS))
NVDLA_TOP := ..
ifndef CONFIG_TEGRA_KLEAF_BUILD
include $(src)/../Makefile.config.mk
else
include $(srctree.nvidia-oot)/drivers/video/tegra/host/nvdla/Makefile.config.mk
endif
#
# axi-nvdla.ko
@@ -15,11 +20,20 @@ ccflags-y += -DNVDLA_HAVE_CONFIG_HW_PERFMON=0
ccflags-y += -DNVDLA_HAVE_CONFIG_AXI=1
ccflags-y += -DNVDLA_HAVE_CONFIG_SYNCPTFD=0
ccflags-y += -DNVDLA_HAVE_CONFIG_HSIERRINJ=0
ccflags-y += -DBUG_4942853=1
axi-nvdla-objs += \
$(NVDLA_COMMON_OBJS) \
$(NVDLA_TOP)/port/device/nvdla_device_axi.o \
$(NVDLA_TOP)/port/fw/nvdla_fw_riscv.o \
$(NVDLA_TOP)/port/sync/nvdla_sync_stub.o
NVDLA_OBJS := \
$(NVDLA_COMMON_OBJS) \
port/device/nvdla_device_axi.o \
port/fw/nvdla_fw_riscv.o \
port/sync/nvdla_sync_stub.o
obj-m += axi-nvdla.o
# Duplicate source file for forcing compilation.
NVDLA_OBJS := $(addprefix $(NVDLA_TOP)/,$(NVDLA_OBJS))
NVDLA_OBJS := $(patsubst %.o,%_$(NVDLA_MODULE_NAME).o,$(NVDLA_OBJS))
%_$(NVDLA_MODULE_NAME).c: %.c
cp $^ $@
$(NVDLA_MODULE_NAME)-objs += $(NVDLA_OBJS)
obj-m += $(NVDLA_MODULE_NAME).o

View File

@@ -38,10 +38,15 @@
#include "nvdla.h"
#include "nvdla_hw_flcn.h"
#include "nvdla_t194.h"
#include "nvdla_t234.h"
#if defined(NVDLA_HAVE_CONFIG_AXI) && (NVDLA_HAVE_CONFIG_AXI == 1)
#include "nvdla_t25x.h"
#include "nvdla_t264_sim.h"
#else
#include "nvdla_t194.h"
#include "nvdla_t234.h"
#endif /* NVDLA_HAVE_CONFIG_AXI */
#include "dla_t19x_fw_version.h"
#include "dla_t23x_fw_version.h"
#include "dla_queue.h"
#include "nvdla_buffer.h"
#include "nvdla_debug.h"
@@ -907,6 +912,23 @@ static struct kobj_type nvdla_kobj_ktype = {
#endif
/* driver probe and init */
#if defined(NVDLA_HAVE_CONFIG_AXI) && (NVDLA_HAVE_CONFIG_AXI == 1)
static struct of_device_id tegra_nvdla_of_match[] = {
{
.name = "nvdla0",
.compatible = "nvidia,tegra25x-nvdla",
.data = (struct nvhost_device_data *)&t25x_nvdla0_info },
{
.name = "nvdla1",
.compatible = "nvidia,tegra25x-nvdla",
.data = (struct nvhost_device_data *)&t25x_nvdla1_info },
{
.name = "nvdla0",
.compatible = "nvidia,tegra264-nvdla",
.data = (struct nvhost_device_data *)&t264_sim_nvdla0_info },
{ },
};
#else
static struct of_device_id tegra_nvdla_of_match[] = {
{
.name = "nvdla0",
@@ -924,16 +946,9 @@ static struct of_device_id tegra_nvdla_of_match[] = {
.name = "nvdla1",
.compatible = "nvidia,tegra234-nvdla",
.data = (struct nvhost_device_data *)&t23x_nvdla1_info },
{
.name = "nvdla0",
.compatible = "nvidia,tegra25x-nvdla",
.data = (struct nvhost_device_data *)&t25x_nvdla0_info },
{
.name = "nvdla",
.compatible = "nvidia,tegra264-nvdla",
.data = (struct nvhost_device_data *)&t264_sim_nvdla_info },
{ },
};
#endif /* NVDLA_HAVE_CONFIG_AXI */
MODULE_DEVICE_TABLE(of, tegra_nvdla_of_match);
static uint32_t num_enabled_dla_instances(uint32_t soft_fuse_ret,
@@ -1103,10 +1118,14 @@ static int nvdla_probe(struct platform_device *pdev)
nvdla_reset_handler_init(nvdla_dev);
nvdla_dev->sync_dev = nvdla_sync_device_create_syncpoint(pdev);
#if defined(BUG_4942853) && (BUG_4942853 == 1)
/* Intentionally left empty until bug is resolved */
#else
if (nvdla_dev->sync_dev == NULL) {
err = -ENOMEM;
goto err_mss_init;
}
#endif // BUG_4942853
err = nvdla_alloc_cmd_memory(pdev);
if (err)
@@ -1198,7 +1217,11 @@ err_alloc_utilization_rate_mem:
nvdla_free_cmd_memory(pdev);
err_alloc_cmd_mem:
nvdla_sync_device_destroy(nvdla_dev->sync_dev);
#if defined(BUG_4942853) && (BUG_4942853 == 1)
/* Intentionally left empty until bug is resolved */
#else
err_mss_init:
#endif
nvdla_queue_deinit(nvdla_dev->pool);
err_queue_init:
nvdla_fw_deinit(pdev);

View File

@@ -270,7 +270,7 @@ enum nvdla_submit_mode {
* @window_mem_va virtual address of window size buffer
* @is_suspended flag to check if module is in suspend state.
* @ping_lock lock to synchronize the ping operation requests.
* @avaiable flag to check if device is available to use.
* @available flag to check if device is available to use.
*/
struct nvdla_device {
struct device *dev;
@@ -305,6 +305,7 @@ struct nvdla_device {
#endif
struct mutex ping_lock;
bool available;
u32 bitbang;
struct nvdla_sync_device *sync_dev;
};

View File

@@ -1261,6 +1261,7 @@ void nvdla_debug_init(struct platform_device *pdev)
debugfs_create_u32("debug_mask", S_IRUGO | S_IWUSR, de,
&nvdla_dev->dbg_mask);
debugfs_create_u32("bitbang", 0644, de, &nvdla_dev->bitbang);
#ifdef CONFIG_TEGRA_NVDLA_TRACE_PRINTK
debugfs_create_u32("en_trace", S_IRUGO | S_IWUSR, de,
&nvdla_dev->en_trace);

View File

@@ -49,4 +49,35 @@ static struct nvhost_device_data t25x_nvdla0_info = {
.firmware_not_in_subdir = true,
};
static struct nvhost_device_data t25x_nvdla1_info = {
.devfs_name_family = "nvdla",
.class = NV_DLA1_CLASS_ID,
.clocks = {
{"nvdla1", UINT_MAX},
{"nvdla1_flcn", UINT_MAX}
},
.resource_policy = RESOURCE_PER_CHANNEL_INSTANCE,
.finalize_poweron = nvdla_finalize_poweron,
.prepare_poweroff = nvdla_prepare_poweroff,
.flcn_isr = nvdla_flcn_isr,
.self_config_flcn_isr = true,
.vm_regs = {{0x30, true}, {0x34, false} },
.firmware_name = NV_DLA_TEGRA25X_FW,
.version = FIRMWARE_ENCODE_VERSION(T25X),
.autosuspend_delay = 500,
.keepalive = true,
.poweron_reset = true,
.serialize = true,
.ctrl_ops = &tegra_nvdla_ctrl_ops,
.get_reloc_phys_addr = NULL,
.module_irq = 1,
.engine_cg_regs = nvdla_t25x_gating_registers,
.engine_can_cg = true,
.can_powergate = true,
.icc_id = TEGRA_ICC_DLA_1,
.transcfg_addr = 0x0444,
.transcfg_val = 0x201,
.firmware_not_in_subdir = true,
};
#endif /* End of __NVHOST_NVDLA_T25X_H__ */

View File

@@ -18,7 +18,7 @@ static struct nvhost_gating_register nvdla_t264_gating_registers[] = {
{}
};
static struct nvhost_device_data t264_sim_nvdla_info = {
static struct nvhost_device_data t264_sim_nvdla0_info = {
.devfs_name_family = "nvdla",
.class = NV_DLA0_SIM_CLASS_ID,
.clocks = {

View File

@@ -108,7 +108,7 @@ static int32_t s_nvdla_module_pm_enable(struct platform_device *pdev)
goto fail;
}
reset_control_acquire(pdata->reset_control);
err = reset_control_acquire(pdata->reset_control);
if (err < 0) {
nvdla_dbg_err(pdev, "failed to acquire reset: %d\n", err);
goto fail;
@@ -134,6 +134,7 @@ static int32_t s_nvdla_module_pm_enable(struct platform_device *pdev)
/* Enable the power module. */
pm_runtime_enable(&pdev->dev);
if (!pm_runtime_enabled(&pdev->dev)) {
nvdla_dbg_err(pdev, "failed to enable pm_runtime\n");
err = -EOPNOTSUPP;
goto fail;
}
@@ -200,7 +201,6 @@ static int32_t s_nvdla_module_device_create(struct platform_device *pdev)
NULL,
"nvhost-ctrl-%s",
pdev->dev.of_node->name);
if (IS_ERR(dev)) {
nvdla_dbg_err(pdev, "failed to create nvhost-ctrl-%s device\n",
pdev->dev.of_node->name);
@@ -307,14 +307,15 @@ int32_t nvdla_module_busy(struct platform_device *pdev)
struct nvhost_device_data *pdata = platform_get_drvdata(pdev);
if (pdata->class == NV_DLA0_SIM_CLASS_ID) {
err = 0;
nvdla_dbg_warn(pdev, "skipping PM for simulator\n");
/* Temporarily force power on. */
nvdla_module_load_regs(pdev, pdata->engine_can_cg);
if (pdata->finalize_poweron)
pdata->finalize_poweron(pdev);
err = 0;
err = pdata->finalize_poweron(pdev);
goto fail;
}
@@ -344,9 +345,9 @@ void nvdla_module_idle_mult(struct platform_device *pdev, int32_t refs)
if (pdata->class == NV_DLA0_SIM_CLASS_ID) {
nvdla_dbg_warn(pdev, "skipping PM for simulator\n");
/* Temporarily force power off. */
if (pdata->prepare_poweroff)
pdata->prepare_poweroff(pdev);
goto fail;
}
@@ -417,14 +418,19 @@ int nvdla_module_runtime_suspend(struct device *dev)
if (pdata->prepare_poweroff) {
err = pdata->prepare_poweroff(pdev);
if (err)
return err;
if (err) {
nvdla_dbg_err(pdev, "failed to poweroff %d\n", err);
goto fail;
}
}
if (pdata->class != NV_DLA0_SIM_CLASS_ID)
clk_bulk_disable_unprepare(pdata->num_clks, pdata->clks);
return 0;
fail:
return err;
}
int nvdla_module_runtime_resume(struct device *dev)

View File

@@ -21,7 +21,6 @@
#define DLA_UCODE_BIN_HEADER_MAGIC 0x10fe
#define DLA_BOOTVECTOR_LO 0x100000
static bool s_force_bitbang_load = true;
struct riscv_bin_header {
uint32_t magic;
@@ -56,6 +55,7 @@ struct riscv_ucode_header {
struct riscv {
struct device *dev;
struct nvdla_device *nvdladev;
void __iomem *regs;
void *cpuva;
@@ -331,7 +331,7 @@ static int32_t s_riscv_boot(struct riscv *riscv)
dev_info(riscv->dev, "Switched to RISCV MCU successfully\n");
if (s_force_bitbang_load)
if (riscv->nvdladev->bitbang == 1U)
s_riscv_load_mem_bitbang(riscv);
else
s_riscv_load_mem_dma(riscv);
@@ -364,13 +364,6 @@ static int32_t s_riscv_finalize_poweron(struct platform_device *pdev)
nvdla_device_register_write(pdev, pdata->transcfg_addr,
pdata->transcfg_val);
/* TODO: Check if STREAMID need to be set. */
if (pdata->class == NV_DLA0_SIM_CLASS_ID)
nvdla_device_register_write(pdev, riscv_irqtype_r(),
(riscv_irqtype_swgen0_host_nonstall_f() |
riscv_irqtype_swgen1_host_nonstall_f()));
err = s_riscv_boot(riscv);
if (err < 0) {
nvdla_dbg_err(pdev, "boot err: %d\n", err);
@@ -496,6 +489,7 @@ int32_t nvdla_fw_init(struct platform_device *pdev)
{
int err = 0;
struct nvhost_device_data *pdata = platform_get_drvdata(pdev);
struct nvdla_device *nvdladev = pdata->private_data;
struct riscv *riscv;
pdata->irq = platform_get_irq(pdev, 0);
@@ -523,6 +517,7 @@ int32_t nvdla_fw_init(struct platform_device *pdev)
}
riscv->dev = &pdev->dev;
riscv->nvdladev = nvdladev;
riscv->regs = pdata->aperture[0];
pdata->falcon_data = riscv;
@@ -586,12 +581,12 @@ int32_t nvdla_fw_send_cmd(struct platform_device *pdev,
nvdla_dev->waiting = 1;
nvdla_dbg_reg(pdev, "method_data=[0x%x]", method_data);
nvdla_device_register_write(pdev, riscv_mthdwdat_r(), method_data);
nvdla_dbg_reg(pdev, "method_id=[0x%x]", method_id);
nvdla_device_register_write(pdev, riscv_mthdid_r(), method_id);
nvdla_dbg_reg(pdev, "method_data=[0x%x]", method_data);
nvdla_device_register_write(pdev, riscv_mthddata_r(), method_data);
if (!wait)
goto reset_waiting_status;

View File

@@ -38,10 +38,10 @@
#ifndef __NVDLA_FW_RISCV_REG_H__
#define __NVDLA_FW_RISCV_REG_H__
static inline uint32_t riscv_mthddata_r(void)
static inline uint32_t riscv_mthdwdat_r(void)
{
/* NV_PNVDLA_FALCON_MTHDDATA */
return 0x00000064U;
/* NV_PNVDLA_FALCON_MTHDWDAT */
return 0x0000006cU;
}
static inline uint32_t riscv_mthdid_r(void)
@@ -62,6 +62,12 @@ static inline uint32_t riscv_mailbox1_r(void)
return 0x00000044U;
}
static inline uint32_t riscv_irqstat_r(void)
{
/* NV_PNVDLA_FALCON_IRQSTAT */
return 0x00000008U;
}
static inline uint32_t riscv_irqmclr_r(void)
{
/* NV_PNVDLA_RISCV_IRQMCLR */

View File

@@ -195,7 +195,7 @@ int32_t nvdla_sync_wait(struct nvdla_sync_context *context,
context->syncptid,
threshold);
if (wait_complete == 0) {
nvdla_dbg_info(device->pdev,
nvdla_dbg_err(device->pdev,
"Wait on sp[%u] for threshold[%u] timedout\n",
context->syncptid, threshold);
err = -ETIMEDOUT;