diff --git a/arch/nvgpu-hal-new.yaml b/arch/nvgpu-hal-new.yaml index eeb732fae..c502d8544 100644 --- a/arch/nvgpu-hal-new.yaml +++ b/arch/nvgpu-hal-new.yaml @@ -501,12 +501,17 @@ regops: hal/regops/regops_tu104.c, hal/regops/regops_tu104.h ] -falcon: +falcon_fusa: safe: yes owner: Sagar K sources: [ hal/falcon/falcon_gk20a_fusa.c, hal/falcon/falcon_gk20a.h ] +falcon: + safe: no + owner: Sagar K + sources: [ hal/falcon/falcon_gk20a.c ] + mc: safe: yes owner: Seema K diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile index ad7592f8a..430af0a10 100644 --- a/drivers/gpu/nvgpu/Makefile +++ b/drivers/gpu/nvgpu/Makefile @@ -46,6 +46,8 @@ ccflags-y += -DCONFIG_NVGPU_SIM ccflags-y += -DCONFIG_NVGPU_TRACE ccflags-y += -DCONFIG_NVGPU_SYSFS ccflags-y += -DCONFIG_NVGPU_CLK_ARB +ccflags-y += -DCONFIG_NVGPU_FALCON_DEBUG +ccflags-y += -DCONFIG_NVGPU_FALCON_NON_FUSA ifeq ($(CONFIG_NVGPU_LOGGING),y) ccflags-y += -DCONFIG_NVGPU_LOGGING=1 @@ -683,7 +685,8 @@ nvgpu-$(CONFIG_NVGPU_HAL_NON_FUSA) += \ hal/mm/mm_gv100.o \ hal/mm/mm_tu104.o \ hal/mm/gmmu/gmmu_gk20a.o \ - hal/mm/gmmu/gmmu_gm20b.o + hal/mm/gmmu/gmmu_gm20b.o \ + hal/falcon/falcon_gk20a.o ifeq ($(CONFIG_TEGRA_GR_VIRTUALIZATION),y) nvgpu-$(CONFIG_NVGPU_HAL_NON_FUSA) += \ diff --git a/drivers/gpu/nvgpu/Makefile.shared.configs b/drivers/gpu/nvgpu/Makefile.shared.configs index f54817c06..209f5743f 100644 --- a/drivers/gpu/nvgpu/Makefile.shared.configs +++ b/drivers/gpu/nvgpu/Makefile.shared.configs @@ -107,6 +107,8 @@ NVGPU_COMMON_CFLAGS += -DCONFIG_NVGPU_TRACE CONFIG_NVGPU_SYSFS := 1 NVGPU_COMMON_CFLAGS += -DCONFIG_NVGPU_SYSFS +NVGPU_COMMON_CFLAGS += -DCONFIG_NVGPU_FALCON_DEBUG + # # Flags enabled only for regular build profile. # @@ -171,5 +173,7 @@ NVGPU_COMMON_CFLAGS += -DCONFIG_NVGPU_HAL_NON_FUSA CONFIG_NVGPU_CLK_ARB := 1 NVGPU_COMMON_CFLAGS += -DCONFIG_NVGPU_CLK_ARB +NVGPU_COMMON_CFLAGS += -DCONFIG_NVGPU_FALCON_NON_FUSA + endif endif diff --git a/drivers/gpu/nvgpu/Makefile.sources b/drivers/gpu/nvgpu/Makefile.sources index 5bf5a1a5a..1da42d138 100644 --- a/drivers/gpu/nvgpu/Makefile.sources +++ b/drivers/gpu/nvgpu/Makefile.sources @@ -264,6 +264,7 @@ srcs += hal/init/hal_gp10b.c \ hal/bus/bus_gk20a.c \ hal/class/class_gm20b.c \ hal/clk/clk_gm20b.c \ + hal/falcon/falcon_gk20a.c \ hal/gr/ecc/ecc_gp10b.c \ hal/gr/init/gr_init_gm20b.c \ hal/gr/init/gr_init_gp10b.c \ diff --git a/drivers/gpu/nvgpu/common/acr/acr_bootstrap.c b/drivers/gpu/nvgpu/common/acr/acr_bootstrap.c index abc0d0dd6..9eb937d35 100644 --- a/drivers/gpu/nvgpu/common/acr/acr_bootstrap.c +++ b/drivers/gpu/nvgpu/common/acr/acr_bootstrap.c @@ -41,7 +41,9 @@ static int acr_wait_for_completion(struct gk20a *g, struct nvgpu_falcon *flcn, unsigned int timeout) { u32 flcn_id = nvgpu_falcon_get_id(flcn); +#ifdef CONFIG_NVGPU_FALCON_NON_FUSA u32 sctl, cpuctl; +#endif int completion = 0; u32 data = 0; u32 bar0_status = 0; @@ -52,7 +54,9 @@ static int acr_wait_for_completion(struct gk20a *g, completion = nvgpu_falcon_wait_for_halt(flcn, timeout); if (completion != 0) { nvgpu_err(g, "flcn-%d: HS ucode boot timed out", flcn_id); +#ifdef CONFIG_NVGPU_FALCON_DEBUG nvgpu_falcon_dump_stats(flcn); +#endif error_type = ACR_BOOT_TIMEDOUT; goto exit; } @@ -78,10 +82,12 @@ static int acr_wait_for_completion(struct gk20a *g, goto exit; } +#ifdef CONFIG_NVGPU_FALCON_NON_FUSA nvgpu_falcon_get_ctls(flcn, &sctl, &cpuctl); nvgpu_acr_dbg(g, "flcn-%d: sctl reg %x cpuctl reg %x", flcn_id, sctl, cpuctl); +#endif /* * When engine-falcon is used for ACR bootstrap, validate the integrity diff --git a/drivers/gpu/nvgpu/common/falcon/falcon.c b/drivers/gpu/nvgpu/common/falcon/falcon.c index 6fe582a96..f401e2249 100644 --- a/drivers/gpu/nvgpu/common/falcon/falcon.c +++ b/drivers/gpu/nvgpu/common/falcon/falcon.c @@ -50,6 +50,63 @@ static bool is_falcon_valid(struct nvgpu_falcon *flcn) return true; } +int nvgpu_falcon_reset(struct nvgpu_falcon *flcn) +{ + struct gk20a *g; + int status = 0; + + if (!is_falcon_valid(flcn)) { + return -EINVAL; + } + + g = flcn->g; + + if (flcn->flcn_engine_dep_ops.reset_eng != NULL) { + /* falcon & engine reset */ + status = flcn->flcn_engine_dep_ops.reset_eng(g); + } else { + g->ops.falcon.reset(flcn); + } + + if (status == 0) { + status = nvgpu_falcon_mem_scrub_wait(flcn); + } + + return status; +} + +int nvgpu_falcon_wait_for_halt(struct nvgpu_falcon *flcn, unsigned int timeout) +{ + struct nvgpu_timeout to; + struct gk20a *g; + int status; + + if (!is_falcon_valid(flcn)) { + return -EINVAL; + } + + g = flcn->g; + + status = nvgpu_timeout_init(g, &to, timeout, NVGPU_TIMER_CPU_TIMER); + if (status != 0) { + return status; + } + + do { + if (g->ops.falcon.is_falcon_cpu_halted(flcn)) { + break; + } + + nvgpu_udelay(10); + } while (nvgpu_timeout_expired(&to) == 0); + + if (nvgpu_timeout_peek_expired(&to) != 0) { + status = -ETIMEDOUT; + } + + return status; +} + int nvgpu_falcon_wait_idle(struct nvgpu_falcon *flcn) { struct nvgpu_timeout timeout; @@ -120,173 +177,6 @@ exit: return status; } -int nvgpu_falcon_reset(struct nvgpu_falcon *flcn) -{ - struct gk20a *g; - int status = 0; - - if (!is_falcon_valid(flcn)) { - return -EINVAL; - } - - g = flcn->g; - - if (flcn->flcn_engine_dep_ops.reset_eng != NULL) { - /* falcon & engine reset */ - status = flcn->flcn_engine_dep_ops.reset_eng(g); - } else { - g->ops.falcon.reset(flcn); - } - - if (status == 0) { - status = nvgpu_falcon_mem_scrub_wait(flcn); - } - - return status; -} - -void nvgpu_falcon_set_irq(struct nvgpu_falcon *flcn, bool enable, - u32 intr_mask, u32 intr_dest) -{ - struct gk20a *g; - - if (!is_falcon_valid(flcn)) { - return; - } - - g = flcn->g; - - if (!flcn->is_interrupt_enabled) { - nvgpu_warn(g, "Interrupt not supported on flcn 0x%x ", - flcn->flcn_id); - /* Keep interrupt disabled */ - enable = false; - } - - g->ops.falcon.set_irq(flcn, enable, intr_mask, intr_dest); -} - -int nvgpu_falcon_wait_for_halt(struct nvgpu_falcon *flcn, unsigned int timeout) -{ - struct nvgpu_timeout to; - struct gk20a *g; - int status; - - if (!is_falcon_valid(flcn)) { - return -EINVAL; - } - - g = flcn->g; - - status = nvgpu_timeout_init(g, &to, timeout, NVGPU_TIMER_CPU_TIMER); - if (status != 0) { - return status; - } - - do { - if (g->ops.falcon.is_falcon_cpu_halted(flcn)) { - break; - } - - nvgpu_udelay(10); - } while (nvgpu_timeout_expired(&to) == 0); - - if (nvgpu_timeout_peek_expired(&to) != 0) { - status = -ETIMEDOUT; - } - - return status; -} - -int nvgpu_falcon_clear_halt_intr_status(struct nvgpu_falcon *flcn, - unsigned int timeout) -{ - struct nvgpu_timeout to; - struct gk20a *g; - int status; - - if (!is_falcon_valid(flcn)) { - return -EINVAL; - } - - g = flcn->g; - - status = nvgpu_timeout_init(g, &to, timeout, NVGPU_TIMER_CPU_TIMER); - if (status != 0) { - return status; - } - - do { - if (g->ops.falcon.clear_halt_interrupt_status(flcn)) { - break; - } - - nvgpu_udelay(1); - } while (nvgpu_timeout_expired(&to) == 0); - - if (nvgpu_timeout_peek_expired(&to) != 0) { - status = -ETIMEDOUT; - } - - return status; -} - -int nvgpu_falcon_copy_from_emem(struct nvgpu_falcon *flcn, - u32 src, u8 *dst, u32 size, u8 port) -{ - struct nvgpu_falcon_engine_dependency_ops *flcn_dops; - int status = -EINVAL; - struct gk20a *g; - - if (!is_falcon_valid(flcn)) { - return -EINVAL; - } - - g = flcn->g; - flcn_dops = &flcn->flcn_engine_dep_ops; - - if (flcn_dops->copy_from_emem != NULL) { - nvgpu_mutex_acquire(&flcn->emem_lock); - status = flcn_dops->copy_from_emem(g, src, dst, size, port); - nvgpu_mutex_release(&flcn->emem_lock); - } else { - nvgpu_warn(g, "Invalid op on falcon 0x%x ", - flcn->flcn_id); - goto exit; - } - -exit: - return status; -} - -int nvgpu_falcon_copy_to_emem(struct nvgpu_falcon *flcn, - u32 dst, u8 *src, u32 size, u8 port) -{ - struct nvgpu_falcon_engine_dependency_ops *flcn_dops; - int status = -EINVAL; - struct gk20a *g; - - if (!is_falcon_valid(flcn)) { - return -EINVAL; - } - - g = flcn->g; - flcn_dops = &flcn->flcn_engine_dep_ops; - - if (flcn_dops->copy_to_emem != NULL) { - nvgpu_mutex_acquire(&flcn->emem_lock); - status = flcn_dops->copy_to_emem(g, dst, src, size, port); - nvgpu_mutex_release(&flcn->emem_lock); - } else { - nvgpu_warn(g, "Invalid op on falcon 0x%x ", - flcn->flcn_id); - goto exit; - } - -exit: - return status; -} - static int falcon_memcpy_params_check(struct nvgpu_falcon *flcn, u32 offset, u32 size, enum falcon_mem_type mem_type, u8 port) { @@ -329,31 +219,6 @@ exit: return ret; } -int nvgpu_falcon_copy_from_dmem(struct nvgpu_falcon *flcn, - u32 src, u8 *dst, u32 size, u8 port) -{ - int status = -EINVAL; - struct gk20a *g; - - if (!is_falcon_valid(flcn)) { - return -EINVAL; - } - - g = flcn->g; - - if (falcon_memcpy_params_check(flcn, src, size, MEM_DMEM, port) != 0) { - nvgpu_err(g, "incorrect parameters"); - goto exit; - } - - nvgpu_mutex_acquire(&flcn->dmem_lock); - status = g->ops.falcon.copy_from_dmem(flcn, src, dst, size, port); - nvgpu_mutex_release(&flcn->dmem_lock); - -exit: - return status; -} - int nvgpu_falcon_copy_to_dmem(struct nvgpu_falcon *flcn, u32 dst, u8 *src, u32 size, u8 port) { @@ -379,31 +244,6 @@ exit: return status; } -int nvgpu_falcon_copy_from_imem(struct nvgpu_falcon *flcn, - u32 src, u8 *dst, u32 size, u8 port) -{ - int status = -EINVAL; - struct gk20a *g; - - if (!is_falcon_valid(flcn)) { - return -EINVAL; - } - - g = flcn->g; - - if (falcon_memcpy_params_check(flcn, src, size, MEM_IMEM, port) != 0) { - nvgpu_err(g, "incorrect parameters"); - goto exit; - } - - nvgpu_mutex_acquire(&flcn->imem_lock); - status = g->ops.falcon.copy_from_imem(flcn, src, dst, size, port); - nvgpu_mutex_release(&flcn->imem_lock); - -exit: - return status; -} - int nvgpu_falcon_copy_to_imem(struct nvgpu_falcon *flcn, u32 dst, u8 *src, u32 size, u8 port, bool sec, u32 tag) { @@ -430,78 +270,6 @@ exit: return status; } -static void falcon_print_mem(struct nvgpu_falcon *flcn, u32 src, - u32 size, enum falcon_mem_type mem_type) -{ - u32 buff[64] = {0}; - u32 total_block_read = 0; - u32 byte_read_count = 0; - struct gk20a *g; - u32 i = 0; - int status = 0; - - g = flcn->g; - - if (falcon_memcpy_params_check(flcn, src, size, mem_type, 0) != 0) { - nvgpu_err(g, "incorrect parameters"); - return; - } - - nvgpu_info(g, " offset 0x%x size %d bytes", src, size); - - total_block_read = size >> 8; - do { - byte_read_count = - (total_block_read != 0U) ? (u32)sizeof(buff) : size; - - if (byte_read_count == 0U) { - break; - } - - if (mem_type == MEM_DMEM) { - status = nvgpu_falcon_copy_from_dmem(flcn, src, - (u8 *)buff, byte_read_count, 0); - } else { - status = nvgpu_falcon_copy_from_imem(flcn, src, - (u8 *)buff, byte_read_count, 0); - } - - if (status != 0) { - nvgpu_err(g, "MEM print failed"); - break; - } - - for (i = 0U; i < (byte_read_count >> 2U); i += 4U) { - nvgpu_info(g, "%#06x: %#010x %#010x %#010x %#010x", - src + (i << 2U), buff[i], buff[i+1U], - buff[i+2U], buff[i+3U]); - } - - src += byte_read_count; - size -= byte_read_count; - } while (total_block_read-- != 0U); -} - -void nvgpu_falcon_print_dmem(struct nvgpu_falcon *flcn, u32 src, u32 size) -{ - if (!is_falcon_valid(flcn)) { - return; - } - - nvgpu_info(flcn->g, " PRINT DMEM "); - falcon_print_mem(flcn, src, size, MEM_DMEM); -} - -void nvgpu_falcon_print_imem(struct nvgpu_falcon *flcn, u32 src, u32 size) -{ - if (!is_falcon_valid(flcn)) { - return; - } - - nvgpu_info(flcn->g, " PRINT IMEM "); - falcon_print_mem(flcn, src, size, MEM_IMEM); -} - int nvgpu_falcon_bootstrap(struct nvgpu_falcon *flcn, u32 boot_vector) { if (!is_falcon_valid(flcn)) { @@ -555,15 +323,6 @@ exit: return; } -void nvgpu_falcon_dump_stats(struct nvgpu_falcon *flcn) -{ - if (!is_falcon_valid(flcn)) { - return; - } - - flcn->g->ops.falcon.dump_falcon_stats(flcn); -} - int nvgpu_falcon_bl_bootstrap(struct nvgpu_falcon *flcn, struct nvgpu_falcon_bl_info *bl_info) { @@ -617,15 +376,6 @@ exit: return err; } -void nvgpu_falcon_get_ctls(struct nvgpu_falcon *flcn, u32 *sctl, u32 *cpuctl) -{ - if (!is_falcon_valid(flcn)) { - return; - } - - flcn->g->ops.falcon.get_falcon_ctls(flcn, sctl, cpuctl); -} - int nvgpu_falcon_get_mem_size(struct nvgpu_falcon *flcn, enum falcon_mem_type type, u32 *size) { @@ -769,3 +519,259 @@ void nvgpu_falcon_sw_free(struct gk20a *g, u32 flcn_id) nvgpu_mutex_destroy(&flcn->dmem_lock); nvgpu_mutex_destroy(&flcn->imem_lock); } + +#ifdef CONFIG_NVGPU_DGPU +int nvgpu_falcon_copy_from_emem(struct nvgpu_falcon *flcn, + u32 src, u8 *dst, u32 size, u8 port) +{ + struct nvgpu_falcon_engine_dependency_ops *flcn_dops; + int status = -EINVAL; + struct gk20a *g; + + if (!is_falcon_valid(flcn)) { + return -EINVAL; + } + + g = flcn->g; + flcn_dops = &flcn->flcn_engine_dep_ops; + + if (flcn_dops->copy_from_emem != NULL) { + nvgpu_mutex_acquire(&flcn->emem_lock); + status = flcn_dops->copy_from_emem(g, src, dst, size, port); + nvgpu_mutex_release(&flcn->emem_lock); + } else { + nvgpu_warn(g, "Invalid op on falcon 0x%x ", + flcn->flcn_id); + goto exit; + } + +exit: + return status; +} + +int nvgpu_falcon_copy_to_emem(struct nvgpu_falcon *flcn, + u32 dst, u8 *src, u32 size, u8 port) +{ + struct nvgpu_falcon_engine_dependency_ops *flcn_dops; + int status = -EINVAL; + struct gk20a *g; + + if (!is_falcon_valid(flcn)) { + return -EINVAL; + } + + g = flcn->g; + flcn_dops = &flcn->flcn_engine_dep_ops; + + if (flcn_dops->copy_to_emem != NULL) { + nvgpu_mutex_acquire(&flcn->emem_lock); + status = flcn_dops->copy_to_emem(g, dst, src, size, port); + nvgpu_mutex_release(&flcn->emem_lock); + } else { + nvgpu_warn(g, "Invalid op on falcon 0x%x ", + flcn->flcn_id); + goto exit; + } + +exit: + return status; +} +#endif + +#ifdef CONFIG_NVGPU_FALCON_DEBUG +void nvgpu_falcon_dump_stats(struct nvgpu_falcon *flcn) +{ + if (!is_falcon_valid(flcn)) { + return; + } + + flcn->g->ops.falcon.dump_falcon_stats(flcn); +} +#endif + +#ifdef CONFIG_NVGPU_FALCON_NON_FUSA +int nvgpu_falcon_clear_halt_intr_status(struct nvgpu_falcon *flcn, + unsigned int timeout) +{ + struct nvgpu_timeout to; + struct gk20a *g; + int status; + + if (!is_falcon_valid(flcn)) { + return -EINVAL; + } + + g = flcn->g; + + status = nvgpu_timeout_init(g, &to, timeout, NVGPU_TIMER_CPU_TIMER); + if (status != 0) { + return status; + } + + do { + if (g->ops.falcon.clear_halt_interrupt_status(flcn)) { + break; + } + + nvgpu_udelay(1); + } while (nvgpu_timeout_expired(&to) == 0); + + if (nvgpu_timeout_peek_expired(&to) != 0) { + status = -ETIMEDOUT; + } + + return status; +} + +void nvgpu_falcon_set_irq(struct nvgpu_falcon *flcn, bool enable, + u32 intr_mask, u32 intr_dest) +{ + struct gk20a *g; + + if (!is_falcon_valid(flcn)) { + return; + } + + g = flcn->g; + + if (!flcn->is_interrupt_enabled) { + nvgpu_warn(g, "Interrupt not supported on flcn 0x%x ", + flcn->flcn_id); + /* Keep interrupt disabled */ + enable = false; + } + + g->ops.falcon.set_irq(flcn, enable, intr_mask, intr_dest); +} + +int nvgpu_falcon_copy_from_dmem(struct nvgpu_falcon *flcn, + u32 src, u8 *dst, u32 size, u8 port) +{ + int status = -EINVAL; + struct gk20a *g; + + if (!is_falcon_valid(flcn)) { + return -EINVAL; + } + + g = flcn->g; + + if (falcon_memcpy_params_check(flcn, src, size, MEM_DMEM, port) != 0) { + nvgpu_err(g, "incorrect parameters"); + goto exit; + } + + nvgpu_mutex_acquire(&flcn->dmem_lock); + status = g->ops.falcon.copy_from_dmem(flcn, src, dst, size, port); + nvgpu_mutex_release(&flcn->dmem_lock); + +exit: + return status; +} + +int nvgpu_falcon_copy_from_imem(struct nvgpu_falcon *flcn, + u32 src, u8 *dst, u32 size, u8 port) +{ + int status = -EINVAL; + struct gk20a *g; + + if (!is_falcon_valid(flcn)) { + return -EINVAL; + } + + g = flcn->g; + + if (falcon_memcpy_params_check(flcn, src, size, MEM_IMEM, port) != 0) { + nvgpu_err(g, "incorrect parameters"); + goto exit; + } + + nvgpu_mutex_acquire(&flcn->imem_lock); + status = g->ops.falcon.copy_from_imem(flcn, src, dst, size, port); + nvgpu_mutex_release(&flcn->imem_lock); + +exit: + return status; +} + +static void falcon_print_mem(struct nvgpu_falcon *flcn, u32 src, + u32 size, enum falcon_mem_type mem_type) +{ + u32 buff[64] = {0}; + u32 total_block_read = 0; + u32 byte_read_count = 0; + struct gk20a *g; + u32 i = 0; + int status = 0; + + g = flcn->g; + + if (falcon_memcpy_params_check(flcn, src, size, mem_type, 0) != 0) { + nvgpu_err(g, "incorrect parameters"); + return; + } + + nvgpu_info(g, " offset 0x%x size %d bytes", src, size); + + total_block_read = size >> 8; + do { + byte_read_count = + (total_block_read != 0U) ? (u32)sizeof(buff) : size; + + if (byte_read_count == 0U) { + break; + } + + if (mem_type == MEM_DMEM) { + status = nvgpu_falcon_copy_from_dmem(flcn, src, + (u8 *)buff, byte_read_count, 0); + } else { + status = nvgpu_falcon_copy_from_imem(flcn, src, + (u8 *)buff, byte_read_count, 0); + } + + if (status != 0) { + nvgpu_err(g, "MEM print failed"); + break; + } + + for (i = 0U; i < (byte_read_count >> 2U); i += 4U) { + nvgpu_info(g, "%#06x: %#010x %#010x %#010x %#010x", + src + (i << 2U), buff[i], buff[i+1U], + buff[i+2U], buff[i+3U]); + } + + src += byte_read_count; + size -= byte_read_count; + } while (total_block_read-- != 0U); +} + +void nvgpu_falcon_print_dmem(struct nvgpu_falcon *flcn, u32 src, u32 size) +{ + if (!is_falcon_valid(flcn)) { + return; + } + + nvgpu_info(flcn->g, " PRINT DMEM "); + falcon_print_mem(flcn, src, size, MEM_DMEM); +} + +void nvgpu_falcon_print_imem(struct nvgpu_falcon *flcn, u32 src, u32 size) +{ + if (!is_falcon_valid(flcn)) { + return; + } + + nvgpu_info(flcn->g, " PRINT IMEM "); + falcon_print_mem(flcn, src, size, MEM_IMEM); +} + +void nvgpu_falcon_get_ctls(struct nvgpu_falcon *flcn, u32 *sctl, u32 *cpuctl) +{ + if (!is_falcon_valid(flcn)) { + return; + } + + flcn->g->ops.falcon.get_falcon_ctls(flcn, sctl, cpuctl); +} +#endif diff --git a/drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c b/drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c index e253d71cf..eed137dd0 100644 --- a/drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c +++ b/drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c @@ -337,9 +337,11 @@ static void pmu_dump_elpg_stats(struct nvgpu_pmu *pmu) /* Print PG stats */ nvgpu_err(g, "Print PG stats"); +#ifdef CONFIG_NVGPU_FALCON_NON_FUSA nvgpu_falcon_print_dmem(pmu->flcn, pmu->pg->stat_dmem_offset[PMU_PG_ELPG_ENGINE_ID_GRAPHICS], (u32)sizeof(struct pmu_pg_stats_v2)); +#endif /* Print ELPG stats */ g->ops.pmu.pmu_dump_elpg_stats(pmu); diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_debug.c b/drivers/gpu/nvgpu/common/pmu/pmu_debug.c index ca5d9a285..7484c6ea9 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_debug.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu_debug.c @@ -102,7 +102,9 @@ void nvgpu_pmu_dump_falcon_stats(struct nvgpu_pmu *pmu) { struct gk20a *g = pmu->g; +#ifdef CONFIG_NVGPU_FALCON_DEBUG nvgpu_falcon_dump_stats(pmu->flcn); +#endif g->ops.pmu.pmu_dump_falcon_stats(pmu); /* Print PMU F/W debug prints */ diff --git a/drivers/gpu/nvgpu/hal/falcon/falcon_gk20a.c b/drivers/gpu/nvgpu/hal/falcon/falcon_gk20a.c new file mode 100644 index 000000000..b44005ab4 --- /dev/null +++ b/drivers/gpu/nvgpu/hal/falcon/falcon_gk20a.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2017-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include +#include +#include +#include + +#include "falcon_gk20a.h" + +#include + +bool gk20a_falcon_clear_halt_interrupt_status(struct nvgpu_falcon *flcn) +{ + struct gk20a *g = flcn->g; + u32 base_addr = flcn->flcn_base; + u32 data = 0; + bool status = false; + + gk20a_writel(g, base_addr + falcon_falcon_irqsclr_r(), + gk20a_readl(g, base_addr + falcon_falcon_irqsclr_r()) | + 0x10U); + data = gk20a_readl(g, (base_addr + falcon_falcon_irqstat_r())); + + if ((data & falcon_falcon_irqstat_halt_true_f()) != + falcon_falcon_irqstat_halt_true_f()) { + /*halt irq is clear*/ + status = true; + } + + return status; +} + +void gk20a_falcon_set_irq(struct nvgpu_falcon *flcn, bool enable, + u32 intr_mask, u32 intr_dest) +{ + struct gk20a *g = flcn->g; + u32 base_addr = flcn->flcn_base; + + if (enable) { + gk20a_writel(g, base_addr + falcon_falcon_irqmset_r(), + intr_mask); + gk20a_writel(g, base_addr + falcon_falcon_irqdest_r(), + intr_dest); + } else { + gk20a_writel(g, base_addr + falcon_falcon_irqmclr_r(), + 0xffffffffU); + } +} + +int gk20a_falcon_copy_from_dmem(struct nvgpu_falcon *flcn, + u32 src, u8 *dst, u32 size, u8 port) +{ + struct gk20a *g = flcn->g; + u32 base_addr = flcn->flcn_base; + u32 i, words, bytes; + u32 data, addr_mask; + u32 *dst_u32 = (u32 *)dst; + + nvgpu_log_fn(g, " src dmem offset - %x, size - %x", src, size); + + words = size >> 2U; + bytes = size & 0x3U; + + addr_mask = falcon_falcon_dmemc_offs_m() | + falcon_falcon_dmemc_blk_m(); + + src &= addr_mask; + + nvgpu_writel(g, base_addr + falcon_falcon_dmemc_r(port), + src | falcon_falcon_dmemc_aincr_f(1)); + + if (unlikely(!nvgpu_mem_is_word_aligned(g, dst))) { + for (i = 0; i < words; i++) { + data = nvgpu_readl(g, + base_addr + falcon_falcon_dmemd_r(port)); + nvgpu_memcpy(&dst[i * 4U], (u8 *)&data, 4); + } + } else { + for (i = 0; i < words; i++) { + dst_u32[i] = nvgpu_readl(g, + base_addr + falcon_falcon_dmemd_r(port)); + } + } + + if (bytes > 0U) { + data = nvgpu_readl(g, base_addr + falcon_falcon_dmemd_r(port)); + nvgpu_memcpy(&dst[words << 2U], (u8 *)&data, bytes); + } + + return 0; +} + +int gk20a_falcon_copy_from_imem(struct nvgpu_falcon *flcn, u32 src, + u8 *dst, u32 size, u8 port) +{ + struct gk20a *g = flcn->g; + u32 base_addr = flcn->flcn_base; + u32 *dst_u32 = (u32 *)dst; + u32 words = 0; + u32 bytes = 0; + u32 data = 0; + u32 blk = 0; + u32 i = 0; + + nvgpu_log_info(g, "download %d bytes from 0x%x", size, src); + + words = size >> 2U; + bytes = size & 0x3U; + blk = src >> 8; + + nvgpu_log_info(g, "download %d words from 0x%x block %d", + words, src, blk); + + nvgpu_writel(g, base_addr + falcon_falcon_imemc_r(port), + falcon_falcon_imemc_offs_f(src >> 2) | + falcon_falcon_imemc_blk_f(blk) | + falcon_falcon_dmemc_aincr_f(1)); + + if (unlikely(!nvgpu_mem_is_word_aligned(g, dst))) { + for (i = 0; i < words; i++) { + data = nvgpu_readl(g, + base_addr + falcon_falcon_imemd_r(port)); + nvgpu_memcpy(&dst[i * 4U], (u8 *)&data, 4); + } + } else { + for (i = 0; i < words; i++) { + dst_u32[i] = nvgpu_readl(g, + base_addr + falcon_falcon_imemd_r(port)); + } + } + + if (bytes > 0U) { + data = nvgpu_readl(g, base_addr + falcon_falcon_imemd_r(port)); + nvgpu_memcpy(&dst[words << 2U], (u8 *)&data, bytes); + } + + return 0; +} + +void gk20a_falcon_get_ctls(struct nvgpu_falcon *flcn, u32 *sctl, + u32 *cpuctl) +{ + *sctl = gk20a_readl(flcn->g, flcn->flcn_base + falcon_falcon_sctl_r()); + *cpuctl = gk20a_readl(flcn->g, flcn->flcn_base + + falcon_falcon_cpuctl_r()); +} diff --git a/drivers/gpu/nvgpu/hal/falcon/falcon_gk20a.h b/drivers/gpu/nvgpu/hal/falcon/falcon_gk20a.h index c3ec25a0d..e67933ad7 100644 --- a/drivers/gpu/nvgpu/hal/falcon/falcon_gk20a.h +++ b/drivers/gpu/nvgpu/hal/falcon/falcon_gk20a.h @@ -60,20 +60,15 @@ #define FALCON_REG_SIZE (32U) void gk20a_falcon_reset(struct nvgpu_falcon *flcn); -bool gk20a_falcon_clear_halt_interrupt_status(struct nvgpu_falcon *flcn); -void gk20a_falcon_set_irq(struct nvgpu_falcon *flcn, bool enable, - u32 intr_mask, u32 intr_dest); bool gk20a_is_falcon_cpu_halted(struct nvgpu_falcon *flcn); bool gk20a_is_falcon_idle(struct nvgpu_falcon *flcn); bool gk20a_is_falcon_scrubbing_done(struct nvgpu_falcon *flcn); u32 gk20a_falcon_get_mem_size(struct nvgpu_falcon *flcn, enum falcon_mem_type mem_type); -int gk20a_falcon_copy_from_dmem(struct nvgpu_falcon *flcn, - u32 src, u8 *dst, u32 size, u8 port); +u8 gk20a_falcon_get_ports_count(struct nvgpu_falcon *flcn, + enum falcon_mem_type mem_type); int gk20a_falcon_copy_to_dmem(struct nvgpu_falcon *flcn, u32 dst, u8 *src, u32 size, u8 port); -int gk20a_falcon_copy_from_imem(struct nvgpu_falcon *flcn, u32 src, - u8 *dst, u32 size, u8 port); int gk20a_falcon_copy_to_imem(struct nvgpu_falcon *flcn, u32 dst, u8 *src, u32 size, u8 port, bool sec, u32 tag); int gk20a_falcon_bootstrap(struct nvgpu_falcon *flcn, @@ -82,10 +77,21 @@ u32 gk20a_falcon_mailbox_read(struct nvgpu_falcon *flcn, u32 mailbox_index); void gk20a_falcon_mailbox_write(struct nvgpu_falcon *flcn, u32 mailbox_index, u32 data); + +#ifdef CONFIG_NVGPU_FALCON_DEBUG void gk20a_falcon_dump_stats(struct nvgpu_falcon *flcn); +#endif + +#ifdef CONFIG_NVGPU_FALCON_NON_FUSA +bool gk20a_falcon_clear_halt_interrupt_status(struct nvgpu_falcon *flcn); +void gk20a_falcon_set_irq(struct nvgpu_falcon *flcn, bool enable, + u32 intr_mask, u32 intr_dest); +int gk20a_falcon_copy_from_dmem(struct nvgpu_falcon *flcn, + u32 src, u8 *dst, u32 size, u8 port); +int gk20a_falcon_copy_from_imem(struct nvgpu_falcon *flcn, u32 src, + u8 *dst, u32 size, u8 port); void gk20a_falcon_get_ctls(struct nvgpu_falcon *flcn, u32 *sctl, u32 *cpuctl); -u8 gk20a_falcon_get_ports_count(struct nvgpu_falcon *flcn, - enum falcon_mem_type mem_type); +#endif #endif /* NVGPU_FALCON_GK20A_H */ diff --git a/drivers/gpu/nvgpu/hal/falcon/falcon_gk20a_fusa.c b/drivers/gpu/nvgpu/hal/falcon/falcon_gk20a_fusa.c index 6edd79ba4..0f2a04162 100644 --- a/drivers/gpu/nvgpu/hal/falcon/falcon_gk20a_fusa.c +++ b/drivers/gpu/nvgpu/hal/falcon/falcon_gk20a_fusa.c @@ -41,44 +41,6 @@ void gk20a_falcon_reset(struct nvgpu_falcon *flcn) (unit_status | falcon_falcon_cpuctl_hreset_f(1))); } -bool gk20a_falcon_clear_halt_interrupt_status(struct nvgpu_falcon *flcn) -{ - struct gk20a *g = flcn->g; - u32 base_addr = flcn->flcn_base; - u32 data = 0; - bool status = false; - - gk20a_writel(g, base_addr + falcon_falcon_irqsclr_r(), - gk20a_readl(g, base_addr + falcon_falcon_irqsclr_r()) | - 0x10U); - data = gk20a_readl(g, (base_addr + falcon_falcon_irqstat_r())); - - if ((data & falcon_falcon_irqstat_halt_true_f()) != - falcon_falcon_irqstat_halt_true_f()) { - /*halt irq is clear*/ - status = true; - } - - return status; -} - -void gk20a_falcon_set_irq(struct nvgpu_falcon *flcn, bool enable, - u32 intr_mask, u32 intr_dest) -{ - struct gk20a *g = flcn->g; - u32 base_addr = flcn->flcn_base; - - if (enable) { - gk20a_writel(g, base_addr + falcon_falcon_irqmset_r(), - intr_mask); - gk20a_writel(g, base_addr + falcon_falcon_irqdest_r(), - intr_dest); - } else { - gk20a_writel(g, base_addr + falcon_falcon_irqmclr_r(), - 0xffffffffU); - } -} - bool gk20a_is_falcon_cpu_halted(struct nvgpu_falcon *flcn) { struct gk20a *g = flcn->g; @@ -165,49 +127,6 @@ u8 gk20a_falcon_get_ports_count(struct nvgpu_falcon *flcn, return ports; } -int gk20a_falcon_copy_from_dmem(struct nvgpu_falcon *flcn, - u32 src, u8 *dst, u32 size, u8 port) -{ - struct gk20a *g = flcn->g; - u32 base_addr = flcn->flcn_base; - u32 i, words, bytes; - u32 data, addr_mask; - u32 *dst_u32 = (u32 *)dst; - - nvgpu_log_fn(g, " src dmem offset - %x, size - %x", src, size); - - words = size >> 2U; - bytes = size & 0x3U; - - addr_mask = falcon_falcon_dmemc_offs_m() | - falcon_falcon_dmemc_blk_m(); - - src &= addr_mask; - - nvgpu_writel(g, base_addr + falcon_falcon_dmemc_r(port), - src | falcon_falcon_dmemc_aincr_f(1)); - - if (unlikely(!nvgpu_mem_is_word_aligned(g, dst))) { - for (i = 0; i < words; i++) { - data = nvgpu_readl(g, - base_addr + falcon_falcon_dmemd_r(port)); - nvgpu_memcpy(&dst[i * 4U], (u8 *)&data, 4); - } - } else { - for (i = 0; i < words; i++) { - dst_u32[i] = nvgpu_readl(g, - base_addr + falcon_falcon_dmemd_r(port)); - } - } - - if (bytes > 0U) { - data = nvgpu_readl(g, base_addr + falcon_falcon_dmemd_r(port)); - nvgpu_memcpy(&dst[words << 2U], (u8 *)&data, bytes); - } - - return 0; -} - int gk20a_falcon_copy_to_dmem(struct nvgpu_falcon *flcn, u32 dst, u8 *src, u32 size, u8 port) { @@ -260,53 +179,6 @@ int gk20a_falcon_copy_to_dmem(struct nvgpu_falcon *flcn, return 0; } -int gk20a_falcon_copy_from_imem(struct nvgpu_falcon *flcn, u32 src, - u8 *dst, u32 size, u8 port) -{ - struct gk20a *g = flcn->g; - u32 base_addr = flcn->flcn_base; - u32 *dst_u32 = (u32 *)dst; - u32 words = 0; - u32 bytes = 0; - u32 data = 0; - u32 blk = 0; - u32 i = 0; - - nvgpu_log_info(g, "download %d bytes from 0x%x", size, src); - - words = size >> 2U; - bytes = size & 0x3U; - blk = src >> 8; - - nvgpu_log_info(g, "download %d words from 0x%x block %d", - words, src, blk); - - nvgpu_writel(g, base_addr + falcon_falcon_imemc_r(port), - falcon_falcon_imemc_offs_f(src >> 2) | - falcon_falcon_imemc_blk_f(blk) | - falcon_falcon_dmemc_aincr_f(1)); - - if (unlikely(!nvgpu_mem_is_word_aligned(g, dst))) { - for (i = 0; i < words; i++) { - data = nvgpu_readl(g, - base_addr + falcon_falcon_imemd_r(port)); - nvgpu_memcpy(&dst[i * 4U], (u8 *)&data, 4); - } - } else { - for (i = 0; i < words; i++) { - dst_u32[i] = nvgpu_readl(g, - base_addr + falcon_falcon_imemd_r(port)); - } - } - - if (bytes > 0U) { - data = nvgpu_readl(g, base_addr + falcon_falcon_imemd_r(port)); - nvgpu_memcpy(&dst[words << 2U], (u8 *)&data, bytes); - } - - return 0; -} - int gk20a_falcon_copy_to_imem(struct nvgpu_falcon *flcn, u32 dst, u8 *src, u32 size, u8 port, bool sec, u32 tag) { @@ -417,6 +289,7 @@ void gk20a_falcon_mailbox_write(struct nvgpu_falcon *flcn, data); } +#ifdef CONFIG_NVGPU_FALCON_DEBUG static void gk20a_falcon_dump_imblk(struct nvgpu_falcon *flcn) { struct gk20a *g = flcn->g; @@ -591,11 +464,4 @@ void gk20a_falcon_dump_stats(struct nvgpu_falcon *flcn) nvgpu_err(g, "falcon_falcon_exterraddr_r : 0x%x", gk20a_readl(g, base_addr + falcon_falcon_exterraddr_r())); } - -void gk20a_falcon_get_ctls(struct nvgpu_falcon *flcn, u32 *sctl, - u32 *cpuctl) -{ - *sctl = gk20a_readl(flcn->g, flcn->flcn_base + falcon_falcon_sctl_r()); - *cpuctl = gk20a_readl(flcn->g, flcn->flcn_base + - falcon_falcon_cpuctl_r()); -} +#endif diff --git a/drivers/gpu/nvgpu/hal/gr/falcon/gr_falcon_gm20b_fusa.c b/drivers/gpu/nvgpu/hal/gr/falcon/gr_falcon_gm20b_fusa.c index 1241f928e..b38f2664b 100644 --- a/drivers/gpu/nvgpu/hal/gr/falcon/gr_falcon_gm20b_fusa.c +++ b/drivers/gpu/nvgpu/hal/gr/falcon/gr_falcon_gm20b_fusa.c @@ -725,7 +725,9 @@ void gm20b_gr_falcon_fecs_dump_stats(struct gk20a *g) { unsigned int i; +#ifdef CONFIG_NVGPU_FALCON_DEBUG nvgpu_falcon_dump_stats(&g->fecs_flcn); +#endif for (i = 0; i < g->ops.gr.falcon.fecs_ctxsw_mailbox_size(); i++) { nvgpu_err(g, "gr_fecs_ctxsw_mailbox_r(%d) : 0x%x", diff --git a/drivers/gpu/nvgpu/hal/init/hal_gm20b.c b/drivers/gpu/nvgpu/hal/init/hal_gm20b.c index 96fd95498..4f5b474d0 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_gm20b.c +++ b/drivers/gpu/nvgpu/hal/init/hal_gm20b.c @@ -973,23 +973,27 @@ static const struct gpu_ops gm20b_ops = { #endif .falcon = { .reset = gk20a_falcon_reset, - .set_irq = gk20a_falcon_set_irq, - .clear_halt_interrupt_status = - gk20a_falcon_clear_halt_interrupt_status, .is_falcon_cpu_halted = gk20a_is_falcon_cpu_halted, .is_falcon_idle = gk20a_is_falcon_idle, .is_falcon_scrubbing_done = gk20a_is_falcon_scrubbing_done, - .copy_from_dmem = gk20a_falcon_copy_from_dmem, + .get_mem_size = gk20a_falcon_get_mem_size, + .get_ports_count = gk20a_falcon_get_ports_count, .copy_to_dmem = gk20a_falcon_copy_to_dmem, .copy_to_imem = gk20a_falcon_copy_to_imem, - .copy_from_imem = gk20a_falcon_copy_from_imem, .bootstrap = gk20a_falcon_bootstrap, - .dump_falcon_stats = gk20a_falcon_dump_stats, .mailbox_read = gk20a_falcon_mailbox_read, .mailbox_write = gk20a_falcon_mailbox_write, +#ifdef CONFIG_NVGPU_FALCON_DEBUG + .dump_falcon_stats = gk20a_falcon_dump_stats, +#endif +#ifdef CONFIG_NVGPU_FALCON_NON_FUSA + .clear_halt_interrupt_status = + gk20a_falcon_clear_halt_interrupt_status, + .set_irq = gk20a_falcon_set_irq, + .copy_from_dmem = gk20a_falcon_copy_from_dmem, + .copy_from_imem = gk20a_falcon_copy_from_imem, .get_falcon_ctls = gk20a_falcon_get_ctls, - .get_mem_size = gk20a_falcon_get_mem_size, - .get_ports_count = gk20a_falcon_get_ports_count +#endif }, .priv_ring = { .enable_priv_ring = gm20b_priv_ring_enable, diff --git a/drivers/gpu/nvgpu/hal/init/hal_gp10b.c b/drivers/gpu/nvgpu/hal/init/hal_gp10b.c index e8777fd8f..3d5c72e33 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_gp10b.c +++ b/drivers/gpu/nvgpu/hal/init/hal_gp10b.c @@ -1062,23 +1062,27 @@ static const struct gpu_ops gp10b_ops = { #endif .falcon = { .reset = gk20a_falcon_reset, - .set_irq = gk20a_falcon_set_irq, - .clear_halt_interrupt_status = - gk20a_falcon_clear_halt_interrupt_status, .is_falcon_cpu_halted = gk20a_is_falcon_cpu_halted, .is_falcon_idle = gk20a_is_falcon_idle, .is_falcon_scrubbing_done = gk20a_is_falcon_scrubbing_done, - .copy_from_dmem = gk20a_falcon_copy_from_dmem, + .get_mem_size = gk20a_falcon_get_mem_size, + .get_ports_count = gk20a_falcon_get_ports_count, .copy_to_dmem = gk20a_falcon_copy_to_dmem, .copy_to_imem = gk20a_falcon_copy_to_imem, - .copy_from_imem = gk20a_falcon_copy_from_imem, .bootstrap = gk20a_falcon_bootstrap, - .dump_falcon_stats = gk20a_falcon_dump_stats, .mailbox_read = gk20a_falcon_mailbox_read, .mailbox_write = gk20a_falcon_mailbox_write, +#ifdef CONFIG_NVGPU_FALCON_DEBUG + .dump_falcon_stats = gk20a_falcon_dump_stats, +#endif +#ifdef CONFIG_NVGPU_FALCON_NON_FUSA + .clear_halt_interrupt_status = + gk20a_falcon_clear_halt_interrupt_status, + .set_irq = gk20a_falcon_set_irq, + .copy_from_dmem = gk20a_falcon_copy_from_dmem, + .copy_from_imem = gk20a_falcon_copy_from_imem, .get_falcon_ctls = gk20a_falcon_get_ctls, - .get_mem_size = gk20a_falcon_get_mem_size, - .get_ports_count = gk20a_falcon_get_ports_count +#endif }, .priv_ring = { .enable_priv_ring = gm20b_priv_ring_enable, diff --git a/drivers/gpu/nvgpu/hal/init/hal_gv11b.c b/drivers/gpu/nvgpu/hal/init/hal_gv11b.c index 3b9460716..1f19d4064 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_gv11b.c +++ b/drivers/gpu/nvgpu/hal/init/hal_gv11b.c @@ -1237,23 +1237,27 @@ static const struct gpu_ops gv11b_ops = { #endif .falcon = { .reset = gk20a_falcon_reset, - .set_irq = gk20a_falcon_set_irq, - .clear_halt_interrupt_status = - gk20a_falcon_clear_halt_interrupt_status, .is_falcon_cpu_halted = gk20a_is_falcon_cpu_halted, .is_falcon_idle = gk20a_is_falcon_idle, .is_falcon_scrubbing_done = gk20a_is_falcon_scrubbing_done, - .copy_from_dmem = gk20a_falcon_copy_from_dmem, + .get_mem_size = gk20a_falcon_get_mem_size, + .get_ports_count = gk20a_falcon_get_ports_count, .copy_to_dmem = gk20a_falcon_copy_to_dmem, .copy_to_imem = gk20a_falcon_copy_to_imem, - .copy_from_imem = gk20a_falcon_copy_from_imem, .bootstrap = gk20a_falcon_bootstrap, - .dump_falcon_stats = gk20a_falcon_dump_stats, .mailbox_read = gk20a_falcon_mailbox_read, .mailbox_write = gk20a_falcon_mailbox_write, +#ifdef CONFIG_NVGPU_FALCON_DEBUG + .dump_falcon_stats = gk20a_falcon_dump_stats, +#endif +#ifdef CONFIG_NVGPU_FALCON_NON_FUSA + .clear_halt_interrupt_status = + gk20a_falcon_clear_halt_interrupt_status, + .set_irq = gk20a_falcon_set_irq, + .copy_from_dmem = gk20a_falcon_copy_from_dmem, + .copy_from_imem = gk20a_falcon_copy_from_imem, .get_falcon_ctls = gk20a_falcon_get_ctls, - .get_mem_size = gk20a_falcon_get_mem_size, - .get_ports_count = gk20a_falcon_get_ports_count +#endif }, .priv_ring = { .enable_priv_ring = gm20b_priv_ring_enable, diff --git a/drivers/gpu/nvgpu/hal/init/hal_tu104.c b/drivers/gpu/nvgpu/hal/init/hal_tu104.c index 7fed024d6..f372b5587 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_tu104.c +++ b/drivers/gpu/nvgpu/hal/init/hal_tu104.c @@ -1295,23 +1295,27 @@ static const struct gpu_ops tu104_ops = { }, .falcon = { .reset = gk20a_falcon_reset, - .set_irq = gk20a_falcon_set_irq, - .clear_halt_interrupt_status = - gk20a_falcon_clear_halt_interrupt_status, .is_falcon_cpu_halted = gk20a_is_falcon_cpu_halted, .is_falcon_idle = gk20a_is_falcon_idle, .is_falcon_scrubbing_done = gk20a_is_falcon_scrubbing_done, - .copy_from_dmem = gk20a_falcon_copy_from_dmem, + .get_mem_size = gk20a_falcon_get_mem_size, + .get_ports_count = gk20a_falcon_get_ports_count, .copy_to_dmem = gk20a_falcon_copy_to_dmem, .copy_to_imem = gk20a_falcon_copy_to_imem, - .copy_from_imem = gk20a_falcon_copy_from_imem, .bootstrap = gk20a_falcon_bootstrap, - .dump_falcon_stats = gk20a_falcon_dump_stats, .mailbox_read = gk20a_falcon_mailbox_read, .mailbox_write = gk20a_falcon_mailbox_write, +#ifdef CONFIG_NVGPU_FALCON_DEBUG + .dump_falcon_stats = gk20a_falcon_dump_stats, +#endif +#ifdef CONFIG_NVGPU_FALCON_NON_FUSA + .clear_halt_interrupt_status = + gk20a_falcon_clear_halt_interrupt_status, + .set_irq = gk20a_falcon_set_irq, + .copy_from_dmem = gk20a_falcon_copy_from_dmem, + .copy_from_imem = gk20a_falcon_copy_from_imem, .get_falcon_ctls = gk20a_falcon_get_ctls, - .get_mem_size = gk20a_falcon_get_mem_size, - .get_ports_count = gk20a_falcon_get_ports_count +#endif }, .priv_ring = { .enable_priv_ring = gm20b_priv_ring_enable, diff --git a/drivers/gpu/nvgpu/hal/sec2/sec2_tu104.c b/drivers/gpu/nvgpu/hal/sec2/sec2_tu104.c index 8e923d97a..0be9692fd 100644 --- a/drivers/gpu/nvgpu/hal/sec2/sec2_tu104.c +++ b/drivers/gpu/nvgpu/hal/sec2/sec2_tu104.c @@ -423,7 +423,9 @@ void tu104_sec2_process_intr(struct gk20a *g, struct nvgpu_sec2 *sec2) if ((intr & psec_falcon_irqstat_halt_true_f()) != 0U) { nvgpu_err(g, "sec2 halt intr not implemented"); +#ifdef CONFIG_NVGPU_FALCON_DEBUG g->ops.falcon.dump_falcon_stats(&sec2->flcn); +#endif } if ((intr & psec_falcon_irqstat_exterr_true_f()) != 0U) { nvgpu_err(g, diff --git a/drivers/gpu/nvgpu/include/nvgpu/falcon.h b/drivers/gpu/nvgpu/include/nvgpu/falcon.h index 2bcc9d9dc..ffb1aa193 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/falcon.h +++ b/drivers/gpu/nvgpu/include/nvgpu/falcon.h @@ -119,36 +119,20 @@ struct nvgpu_falcon { struct nvgpu_falcon_engine_dependency_ops flcn_engine_dep_ops; }; -int nvgpu_falcon_wait_idle(struct nvgpu_falcon *flcn); -int nvgpu_falcon_wait_for_halt(struct nvgpu_falcon *flcn, unsigned int timeout); -int nvgpu_falcon_clear_halt_intr_status(struct nvgpu_falcon *flcn, - unsigned int timeout); int nvgpu_falcon_reset(struct nvgpu_falcon *flcn); -void nvgpu_falcon_set_irq(struct nvgpu_falcon *flcn, bool enable, - u32 intr_mask, u32 intr_dest); +int nvgpu_falcon_wait_for_halt(struct nvgpu_falcon *flcn, unsigned int timeout); +int nvgpu_falcon_wait_idle(struct nvgpu_falcon *flcn); int nvgpu_falcon_mem_scrub_wait(struct nvgpu_falcon *flcn); -int nvgpu_falcon_copy_from_emem(struct nvgpu_falcon *flcn, - u32 src, u8 *dst, u32 size, u8 port); -int nvgpu_falcon_copy_to_emem(struct nvgpu_falcon *flcn, - u32 dst, u8 *src, u32 size, u8 port); -int nvgpu_falcon_copy_from_dmem(struct nvgpu_falcon *flcn, - u32 src, u8 *dst, u32 size, u8 port); int nvgpu_falcon_copy_to_dmem(struct nvgpu_falcon *flcn, u32 dst, u8 *src, u32 size, u8 port); int nvgpu_falcon_copy_to_imem(struct nvgpu_falcon *flcn, u32 dst, u8 *src, u32 size, u8 port, bool sec, u32 tag); -int nvgpu_falcon_copy_from_imem(struct nvgpu_falcon *flcn, - u32 src, u8 *dst, u32 size, u8 port); +int nvgpu_falcon_bootstrap(struct nvgpu_falcon *flcn, u32 boot_vector); u32 nvgpu_falcon_mailbox_read(struct nvgpu_falcon *flcn, u32 mailbox_index); void nvgpu_falcon_mailbox_write(struct nvgpu_falcon *flcn, u32 mailbox_index, u32 data); -int nvgpu_falcon_bootstrap(struct nvgpu_falcon *flcn, u32 boot_vector); -void nvgpu_falcon_print_dmem(struct nvgpu_falcon *flcn, u32 src, u32 size); -void nvgpu_falcon_print_imem(struct nvgpu_falcon *flcn, u32 src, u32 size); -void nvgpu_falcon_dump_stats(struct nvgpu_falcon *flcn); int nvgpu_falcon_bl_bootstrap(struct nvgpu_falcon *flcn, struct nvgpu_falcon_bl_info *bl_info); -void nvgpu_falcon_get_ctls(struct nvgpu_falcon *flcn, u32 *sctl, u32 *cpuctl); int nvgpu_falcon_get_mem_size(struct nvgpu_falcon *flcn, enum falcon_mem_type type, u32 *size); u32 nvgpu_falcon_get_id(struct nvgpu_falcon *flcn); @@ -157,4 +141,29 @@ struct nvgpu_falcon *nvgpu_falcon_get_instance(struct gk20a *g, u32 flcn_id); int nvgpu_falcon_sw_init(struct gk20a *g, u32 flcn_id); void nvgpu_falcon_sw_free(struct gk20a *g, u32 flcn_id); +#ifdef CONFIG_NVGPU_DGPU +int nvgpu_falcon_copy_from_emem(struct nvgpu_falcon *flcn, + u32 src, u8 *dst, u32 size, u8 port); +int nvgpu_falcon_copy_to_emem(struct nvgpu_falcon *flcn, + u32 dst, u8 *src, u32 size, u8 port); +#endif + +#ifdef CONFIG_NVGPU_FALCON_DEBUG +void nvgpu_falcon_dump_stats(struct nvgpu_falcon *flcn); +#endif + +#ifdef CONFIG_NVGPU_FALCON_NON_FUSA +int nvgpu_falcon_clear_halt_intr_status(struct nvgpu_falcon *flcn, + unsigned int timeout); +void nvgpu_falcon_set_irq(struct nvgpu_falcon *flcn, bool enable, + u32 intr_mask, u32 intr_dest); +int nvgpu_falcon_copy_from_dmem(struct nvgpu_falcon *flcn, + u32 src, u8 *dst, u32 size, u8 port); +int nvgpu_falcon_copy_from_imem(struct nvgpu_falcon *flcn, + u32 src, u8 *dst, u32 size, u8 port); +void nvgpu_falcon_print_dmem(struct nvgpu_falcon *flcn, u32 src, u32 size); +void nvgpu_falcon_print_imem(struct nvgpu_falcon *flcn, u32 src, u32 size); +void nvgpu_falcon_get_ctls(struct nvgpu_falcon *flcn, u32 *sctl, u32 *cpuctl); +#endif + #endif /* NVGPU_FALCON_H */ diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h index fd0230e5a..5c7e590e5 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h @@ -1690,34 +1690,39 @@ struct gpu_ops { #endif struct { void (*reset)(struct nvgpu_falcon *flcn); - void (*set_irq)(struct nvgpu_falcon *flcn, bool enable, - u32 intr_mask, u32 intr_dest); - bool (*clear_halt_interrupt_status)(struct nvgpu_falcon *flcn); bool (*is_falcon_cpu_halted)(struct nvgpu_falcon *flcn); bool (*is_falcon_idle)(struct nvgpu_falcon *flcn); bool (*is_falcon_scrubbing_done)(struct nvgpu_falcon *flcn); - int (*copy_from_dmem)(struct nvgpu_falcon *flcn, - u32 src, u8 *dst, u32 size, u8 port); - int (*copy_to_dmem)(struct nvgpu_falcon *flcn, - u32 dst, u8 *src, u32 size, u8 port); - int (*copy_from_imem)(struct nvgpu_falcon *flcn, - u32 src, u8 *dst, u32 size, u8 port); - int (*copy_to_imem)(struct nvgpu_falcon *flcn, - u32 dst, u8 *src, u32 size, u8 port, - bool sec, u32 tag); - u32 (*mailbox_read)(struct nvgpu_falcon *flcn, - u32 mailbox_index); - void (*mailbox_write)(struct nvgpu_falcon *flcn, - u32 mailbox_index, u32 data); - int (*bootstrap)(struct nvgpu_falcon *flcn, - u32 boot_vector); - void (*dump_falcon_stats)(struct nvgpu_falcon *flcn); - void (*get_falcon_ctls)(struct nvgpu_falcon *flcn, - u32 *sctl, u32 *cpuctl); u32 (*get_mem_size)(struct nvgpu_falcon *flcn, enum falcon_mem_type mem_type); u8 (*get_ports_count)(struct nvgpu_falcon *flcn, enum falcon_mem_type mem_type); + + int (*copy_to_dmem)(struct nvgpu_falcon *flcn, + u32 dst, u8 *src, u32 size, u8 port); + int (*copy_to_imem)(struct nvgpu_falcon *flcn, + u32 dst, u8 *src, u32 size, u8 port, + bool sec, u32 tag); + int (*bootstrap)(struct nvgpu_falcon *flcn, + u32 boot_vector); + u32 (*mailbox_read)(struct nvgpu_falcon *flcn, + u32 mailbox_index); + void (*mailbox_write)(struct nvgpu_falcon *flcn, + u32 mailbox_index, u32 data); +#ifdef CONFIG_NVGPU_FALCON_DEBUG + void (*dump_falcon_stats)(struct nvgpu_falcon *flcn); +#endif +#ifdef CONFIG_NVGPU_FALCON_NON_FUSA + bool (*clear_halt_interrupt_status)(struct nvgpu_falcon *flcn); + void (*set_irq)(struct nvgpu_falcon *flcn, bool enable, + u32 intr_mask, u32 intr_dest); + int (*copy_from_dmem)(struct nvgpu_falcon *flcn, + u32 src, u8 *dst, u32 size, u8 port); + int (*copy_from_imem)(struct nvgpu_falcon *flcn, + u32 src, u8 *dst, u32 size, u8 port); + void (*get_falcon_ctls)(struct nvgpu_falcon *flcn, + u32 *sctl, u32 *cpuctl); +#endif } falcon; struct { void (*enable_priv_ring)(struct gk20a *g); diff --git a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export index 7139507d5..a848cc191 100644 --- a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export +++ b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export @@ -78,8 +78,6 @@ nvgpu_dma_alloc_map_sys nvgpu_dma_alloc_sys nvgpu_dma_free nvgpu_dma_unmap_free -nvgpu_falcon_copy_from_dmem -nvgpu_falcon_copy_from_imem nvgpu_falcon_copy_to_dmem nvgpu_falcon_copy_to_imem nvgpu_falcon_get_instance diff --git a/userspace/units/falcon/falcon/falcon.c b/userspace/units/falcon/falcon/falcon.c index eab3c1869..8ba0c2b35 100644 --- a/userspace/units/falcon/falcon/falcon.c +++ b/userspace/units/falcon/falcon/falcon.c @@ -114,6 +114,7 @@ static int free_falcon_test_env(struct unit_module *m, struct gk20a *g, return UNIT_SUCCESS; } +#ifdef CONFIG_NVGPU_FALCON_NON_FUSA /* * This function will compare rand_test_data with falcon flcn's imem/dmem * based on type from offset src of size. It returns 0 on match else @@ -176,6 +177,7 @@ free_dest: nvgpu_kfree(g, dest); return err; } +#endif /* * This function will check that falcon memory read/write functions with @@ -208,6 +210,7 @@ static int falcon_check_read_write(struct gk20a *g, goto free_dest; } +#ifdef CONFIG_NVGPU_FALCON_NON_FUSA err = nvgpu_falcon_copy_from_imem(flcn, dst, dest, byte_cnt, 0); if (err != exp_err) { @@ -215,6 +218,7 @@ static int falcon_check_read_write(struct gk20a *g, exp_err ? "fail" : "pass"); goto free_dest; } +#endif } else if (type == MEM_DMEM) { err = nvgpu_falcon_copy_to_dmem(flcn, dst, (u8 *) rand_test_data, @@ -225,6 +229,7 @@ static int falcon_check_read_write(struct gk20a *g, goto free_dest; } +#ifdef CONFIG_NVGPU_FALCON_NON_FUSA err = nvgpu_falcon_copy_from_dmem(flcn, dst, dest, byte_cnt, 0); if (err != exp_err) { @@ -232,6 +237,7 @@ static int falcon_check_read_write(struct gk20a *g, exp_err ? "fail" : "pass"); goto free_dest; } +#endif } ret = 0; @@ -307,6 +313,7 @@ static int test_falcon_mem_rw_range(struct unit_module *m, struct gk20a *g, unit_return_fail(m, "Failed to copy to IMEM\n"); } +#ifdef CONFIG_NVGPU_FALCON_NON_FUSA /* verify data written to imem matches */ unit_info(m, "Reading %d bytes from imem\n", byte_cnt); err = falcon_read_compare(m, g, MEM_IMEM, dst, byte_cnt); @@ -314,6 +321,7 @@ static int test_falcon_mem_rw_range(struct unit_module *m, struct gk20a *g, unit_err(m, "IMEM read data does not match %d\n", err); return UNIT_FAIL; } +#endif /* write data to valid range in dmem */ unit_info(m, "Writing %d bytes to dmem\n", byte_cnt); @@ -323,6 +331,7 @@ static int test_falcon_mem_rw_range(struct unit_module *m, struct gk20a *g, unit_return_fail(m, "Failed to copy to DMEM\n"); } +#ifdef CONFIG_NVGPU_FALCON_NON_FUSA /* verify data written to dmem matches */ unit_info(m, "Reading %d bytes from dmem\n", byte_cnt); err = falcon_read_compare(m, g, MEM_DMEM, dst, byte_cnt); @@ -330,7 +339,7 @@ static int test_falcon_mem_rw_range(struct unit_module *m, struct gk20a *g, unit_err(m, "DMEM read data does not match %d\n", err); return UNIT_FAIL; } - +#endif dst = UTF_FALCON_IMEM_DMEM_SIZE - RAND_DATA_SIZE; byte_cnt *= 2;