mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-24 02:01:36 +03:00
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:
@@ -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/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user