diff --git a/drivers/video/tegra/host/nvdla/Makefile b/drivers/video/tegra/host/nvdla/Makefile index c38c6159..1a56b416 100644 --- a/drivers/video/tegra/host/nvdla/Makefile +++ b/drivers/video/tegra/host/nvdla/Makefile @@ -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/ diff --git a/drivers/video/tegra/host/nvdla/axi/Makefile b/drivers/video/tegra/host/nvdla/axi/Makefile index ed6c45cd..63138830 100644 --- a/drivers/video/tegra/host/nvdla/axi/Makefile +++ b/drivers/video/tegra/host/nvdla/axi/Makefile @@ -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 diff --git a/drivers/video/tegra/host/nvdla/nvdla.c b/drivers/video/tegra/host/nvdla/nvdla.c index 0bdc5a6d..faa258ff 100644 --- a/drivers/video/tegra/host/nvdla/nvdla.c +++ b/drivers/video/tegra/host/nvdla/nvdla.c @@ -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); diff --git a/drivers/video/tegra/host/nvdla/nvdla.h b/drivers/video/tegra/host/nvdla/nvdla.h index 925c8206..7217ae20 100644 --- a/drivers/video/tegra/host/nvdla/nvdla.h +++ b/drivers/video/tegra/host/nvdla/nvdla.h @@ -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; }; diff --git a/drivers/video/tegra/host/nvdla/nvdla_debug.c b/drivers/video/tegra/host/nvdla/nvdla_debug.c index 3652b3de..3eeb848a 100644 --- a/drivers/video/tegra/host/nvdla/nvdla_debug.c +++ b/drivers/video/tegra/host/nvdla/nvdla_debug.c @@ -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); diff --git a/drivers/video/tegra/host/nvdla/nvdla_t25x.h b/drivers/video/tegra/host/nvdla/nvdla_t25x.h index 3ca44968..fe0b2764 100644 --- a/drivers/video/tegra/host/nvdla/nvdla_t25x.h +++ b/drivers/video/tegra/host/nvdla/nvdla_t25x.h @@ -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__ */ diff --git a/drivers/video/tegra/host/nvdla/nvdla_t264_sim.h b/drivers/video/tegra/host/nvdla/nvdla_t264_sim.h index e9b3a5f5..2cf34651 100644 --- a/drivers/video/tegra/host/nvdla/nvdla_t264_sim.h +++ b/drivers/video/tegra/host/nvdla/nvdla_t264_sim.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 = { diff --git a/drivers/video/tegra/host/nvdla/port/device/nvdla_device_axi.c b/drivers/video/tegra/host/nvdla/port/device/nvdla_device_axi.c index 4f384833..1c40e3d1 100644 --- a/drivers/video/tegra/host/nvdla/port/device/nvdla_device_axi.c +++ b/drivers/video/tegra/host/nvdla/port/device/nvdla_device_axi.c @@ -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) diff --git a/drivers/video/tegra/host/nvdla/port/fw/nvdla_fw_riscv.c b/drivers/video/tegra/host/nvdla/port/fw/nvdla_fw_riscv.c index 115b6c28..8be44645 100644 --- a/drivers/video/tegra/host/nvdla/port/fw/nvdla_fw_riscv.c +++ b/drivers/video/tegra/host/nvdla/port/fw/nvdla_fw_riscv.c @@ -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; diff --git a/drivers/video/tegra/host/nvdla/port/fw/nvdla_fw_riscv_reg.h b/drivers/video/tegra/host/nvdla/port/fw/nvdla_fw_riscv_reg.h index 899df014..fd3f2612 100644 --- a/drivers/video/tegra/host/nvdla/port/fw/nvdla_fw_riscv_reg.h +++ b/drivers/video/tegra/host/nvdla/port/fw/nvdla_fw_riscv_reg.h @@ -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 */ diff --git a/drivers/video/tegra/host/nvdla/port/sync/nvdla_sync_syncpt.c b/drivers/video/tegra/host/nvdla/port/sync/nvdla_sync_syncpt.c index 64813a25..d5b93803 100644 --- a/drivers/video/tegra/host/nvdla/port/sync/nvdla_sync_syncpt.c +++ b/drivers/video/tegra/host/nvdla/port/sync/nvdla_sync_syncpt.c @@ -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;