From f53a0dd96b25cfb64b17ab816ae1f9b0b144db07 Mon Sep 17 00:00:00 2001 From: Mahantesh Kumbar Date: Wed, 15 Nov 2017 16:37:27 +0530 Subject: gpu: nvgpu: falcon interface update -Added nvgpu_flcn_mem_scrub_wait() to falcon interface layer to poll imem/dmem scrubbing status complete check for 1msec with status check interval of 10usec. -Called nvgpu_flcn_mem_scrub_wait() in falcon reset interface to check scrubbing status upon falcon/engine reset. -Replaced mem scrubbing wait check code in pmu_enable_hw() by calling nvgpu_flcn_mem_scrub_wait() Bug 200346134 Change-Id: Iac68e24dea466f6dd5facc371947269db64d238d Signed-off-by: Mahantesh Kumbar Reviewed-on: https://git-master.nvidia.com/r/1598644 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Vijayakumar Subbu Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/falcon/falcon.c | 40 +++++++++++++++++++++++++++++--- drivers/gpu/nvgpu/common/pmu/pmu.c | 34 ++++++++------------------- drivers/gpu/nvgpu/include/nvgpu/falcon.h | 1 + 3 files changed, 48 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/nvgpu/common/falcon/falcon.c b/drivers/gpu/nvgpu/common/falcon/falcon.c index d8420ece..42b33c27 100644 --- a/drivers/gpu/nvgpu/common/falcon/falcon.c +++ b/drivers/gpu/nvgpu/common/falcon/falcon.c @@ -25,6 +25,13 @@ #include "gk20a/gk20a.h" +/* Dealy depends on memory size and pwr_clk + * delay = MAX {IMEM_SIZE, DMEM_SIZE} * 64 + 1) / pwr_clk + * Timeout set is 1msec & status check at interval 10usec + */ +#define MEM_SCRUBBING_TIMEOUT_MAX 1000 +#define MEM_SCRUBBING_TIMEOUT_DEFAULT 10 + int nvgpu_flcn_wait_idle(struct nvgpu_falcon *flcn) { struct gk20a *g = flcn->g; @@ -56,15 +63,42 @@ int nvgpu_flcn_wait_idle(struct nvgpu_falcon *flcn) return 0; } +int nvgpu_flcn_mem_scrub_wait(struct nvgpu_falcon *flcn) +{ + struct nvgpu_timeout timeout; + int status = 0; + + /* check IMEM/DMEM scrubbing complete status */ + nvgpu_timeout_init(flcn->g, &timeout, + MEM_SCRUBBING_TIMEOUT_MAX / + MEM_SCRUBBING_TIMEOUT_DEFAULT, + NVGPU_TIMER_RETRY_TIMER); + do { + if (nvgpu_flcn_get_mem_scrubbing_status(flcn)) + goto exit; + nvgpu_udelay(MEM_SCRUBBING_TIMEOUT_DEFAULT); + } while (!nvgpu_timeout_expired(&timeout)); + + if (nvgpu_timeout_peek_expired(&timeout)) + status = -ETIMEDOUT; + +exit: + return status; +} + int nvgpu_flcn_reset(struct nvgpu_falcon *flcn) { - int status = -EINVAL; + int status = 0; - if (flcn->flcn_ops.reset) + if (flcn->flcn_ops.reset) { status = flcn->flcn_ops.reset(flcn); - else + if (!status) + status = nvgpu_flcn_mem_scrub_wait(flcn); + } else { nvgpu_warn(flcn->g, "Invalid op on falcon 0x%x ", flcn->flcn_id); + status = -EINVAL; + } return status; } diff --git a/drivers/gpu/nvgpu/common/pmu/pmu.c b/drivers/gpu/nvgpu/common/pmu/pmu.c index d595097b..e96ea090 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu.c @@ -31,15 +31,11 @@ #include "gk20a/gk20a.h" -#define PMU_MEM_SCRUBBING_TIMEOUT_MAX 1000 -#define PMU_MEM_SCRUBBING_TIMEOUT_DEFAULT 10 - static int nvgpu_pg_init_task(void *arg); static int pmu_enable_hw(struct nvgpu_pmu *pmu, bool enable) { struct gk20a *g = pmu->g; - struct nvgpu_timeout timeout; int err = 0; nvgpu_log_fn(g, " %s ", g->name); @@ -56,29 +52,19 @@ static int pmu_enable_hw(struct nvgpu_pmu *pmu, bool enable) g->ops.clock_gating.blcg_pmu_load_gating_prod(g, g->blcg_enabled); - /* check for PMU IMEM/DMEM scrubbing complete status */ - nvgpu_timeout_init(g, &timeout, - PMU_MEM_SCRUBBING_TIMEOUT_MAX / - PMU_MEM_SCRUBBING_TIMEOUT_DEFAULT, - NVGPU_TIMER_RETRY_TIMER); - do { - if (nvgpu_flcn_get_mem_scrubbing_status(pmu->flcn)) - goto exit; - - nvgpu_udelay(PMU_MEM_SCRUBBING_TIMEOUT_DEFAULT); - } while (!nvgpu_timeout_expired(&timeout)); - - /* keep PMU falcon/engine in reset - * if IMEM/DMEM scrubbing fails - */ - g->ops.pmu.reset_engine(g, false); - nvgpu_err(g, "Falcon mem scrubbing timeout"); - err = -ETIMEDOUT; - } else + if (nvgpu_flcn_mem_scrub_wait(pmu->flcn)) { + /* keep PMU falcon/engine in reset + * if IMEM/DMEM scrubbing fails + */ + g->ops.pmu.reset_engine(g, false); + nvgpu_err(g, "Falcon mem scrubbing timeout"); + err = -ETIMEDOUT; + } + } else { /* keep PMU falcon/engine in reset */ g->ops.pmu.reset_engine(g, false); + } -exit: nvgpu_log_fn(g, "%s Done, status - %d ", g->name, err); return err; } diff --git a/drivers/gpu/nvgpu/include/nvgpu/falcon.h b/drivers/gpu/nvgpu/include/nvgpu/falcon.h index 4be16576..1f104fa1 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/falcon.h +++ b/drivers/gpu/nvgpu/include/nvgpu/falcon.h @@ -222,6 +222,7 @@ int nvgpu_flcn_reset(struct nvgpu_falcon *flcn); void nvgpu_flcn_set_irq(struct nvgpu_falcon *flcn, bool enable, u32 intr_mask, u32 intr_dest); bool nvgpu_flcn_get_mem_scrubbing_status(struct nvgpu_falcon *flcn); +int nvgpu_flcn_mem_scrub_wait(struct nvgpu_falcon *flcn); bool nvgpu_flcn_get_cpu_halted_status(struct nvgpu_falcon *flcn); bool nvgpu_flcn_get_idle_status(struct nvgpu_falcon *flcn); int nvgpu_flcn_copy_from_dmem(struct nvgpu_falcon *flcn, -- cgit v1.2.2