diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_rtos_init.c b/drivers/gpu/nvgpu/common/pmu/pmu_rtos_init.c index 15fd95285..06b5e0c06 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_rtos_init.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu_rtos_init.c @@ -21,6 +21,8 @@ */ #include +#include +#include #include #include #include @@ -52,6 +54,10 @@ #include #endif +#if defined(CONFIG_NVGPU_NEXT) +#define PMU_PRIV_LOCKDOWN_RELEASE_POLLING_US (1U) +#endif + /* PMU locks used to sync with PMU-RTOS */ int nvgpu_pmu_lock_acquire(struct gk20a *g, struct nvgpu_pmu *pmu, u32 id, u32 *token) @@ -313,6 +319,35 @@ s32 nvgpu_pmu_next_core_rtos_args_allocate(struct gk20a *g, exit: return err; } + +static int nvgpu_pmu_wait_for_priv_lockdown_release(struct gk20a *g, + struct nvgpu_falcon *flcn, unsigned int timeout) +{ + struct nvgpu_timeout to; + int status; + + nvgpu_log_fn(g, " "); + + status = nvgpu_timeout_init(g, &to, timeout, NVGPU_TIMER_CPU_TIMER); + if (status != 0) { + return status; + } + + /* poll for priv lockdown release */ + do { + if (!g->ops.falcon.is_priv_lockdown(flcn)) { + break; + } + + nvgpu_udelay(PMU_PRIV_LOCKDOWN_RELEASE_POLLING_US); + } while (nvgpu_timeout_expired(&to) == 0); + + if (nvgpu_timeout_peek_expired(&to)) { + status = -ETIMEDOUT; + } + + return status; +} #endif int nvgpu_pmu_rtos_init(struct gk20a *g) @@ -381,6 +416,12 @@ int nvgpu_pmu_rtos_init(struct gk20a *g) #if defined(CONFIG_NVGPU_NEXT) if (nvgpu_is_enabled(g, NVGPU_PMU_NEXT_CORE_ENABLED)) { g->ops.falcon.bootstrap(g->pmu->flcn, 0U); + err = nvgpu_pmu_wait_for_priv_lockdown_release(g, + g->pmu->flcn, U32_MAX); + if(err != 0) { + nvgpu_err(g, "PRIV lockdown polling failed"); + return err; + } } else #endif { @@ -395,6 +436,16 @@ int nvgpu_pmu_rtos_init(struct gk20a *g) if (err != 0) { goto exit; } +#if defined(CONFIG_NVGPU_NEXT) + if (nvgpu_is_enabled(g, NVGPU_PMU_NEXT_CORE_ENABLED)) { + err = nvgpu_pmu_wait_for_priv_lockdown_release(g, + g->pmu->flcn, U32_MAX); + if(err != 0) { + nvgpu_err(g, "PRIV lockdown polling failed"); + return err; + } + } +#endif } nvgpu_pmu_fw_state_change(g, g->pmu, PMU_FW_STATE_STARTING, false); diff --git a/drivers/gpu/nvgpu/include/nvgpu/gops/falcon.h b/drivers/gpu/nvgpu/include/nvgpu/gops/falcon.h index c0ea7d2f9..471ce3478 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gops/falcon.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gops/falcon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2021, 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"), @@ -53,6 +53,9 @@ struct gops_falcon { void (*set_bcr)(struct nvgpu_falcon *flcn); void (*dump_brom_stats)(struct nvgpu_falcon *flcn); u32 (*get_brom_retcode)(struct nvgpu_falcon *flcn); +#if defined(CONFIG_NVGPU_NEXT) + bool (*is_priv_lockdown)(struct nvgpu_falcon *flcn); +#endif u32 (*dmemc_blk_mask)(void); bool (*check_brom_passed)(u32 retcode); void (*brom_config)(struct nvgpu_falcon *flcn, u64 fmc_code_addr,