mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-24 02:22:34 +03:00
gpu: nvgpu: add priv lockdown release check for NVRISCV pmu
IRQ register access will cause priv errors if they are accessed before priv lockdown is released. This change adds a polling loop to check priv lockdown before proceeding further while booting NVRISCV pmu. Bug 200709761 Signed-off-by: Ramesh Mylavarapu <rmylavarapu@nvidia.com> Change-Id: I44b8ce4c59b5a9f20901e5ce08610d17725da779 Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2512351 Reviewed-by: Mahantesh Kumbar <mkumbar@nvidia.com> Reviewed-by: Seema Khowala <seemaj@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit
This commit is contained in:
committed by
mobile promotions
parent
4d3a935b1a
commit
a0b1b3f2be
@@ -21,6 +21,8 @@
|
||||
*/
|
||||
|
||||
#include <nvgpu/gk20a.h>
|
||||
#include <nvgpu/timers.h>
|
||||
#include <nvgpu/io.h>
|
||||
#include <nvgpu/dma.h>
|
||||
#include <nvgpu/log.h>
|
||||
#include <nvgpu/enabled.h>
|
||||
@@ -52,6 +54,10 @@
|
||||
#include <nvgpu/sec2/lsfm.h>
|
||||
#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);
|
||||
|
||||
Reference in New Issue
Block a user