From be04b9b1b56d6dd478fe521277c079367c03f39d Mon Sep 17 00:00:00 2001 From: Mahantesh Kumbar Date: Tue, 25 Apr 2017 12:22:56 +0530 Subject: gpu: nvgpu: falcon reset support - Added flacon reset dependent interface & HAL methods to perform falcon reset. - method to wait for idle - method to reset falcon - method to set irq - method to read status of CPU - Updated falcon ops pointer to point gk20a falcon HAL methods - Added members to know support of falcon & interrupt. - Added falcon dependency ops member to support flacon speicifc methods JIRA NVGPU-99 JIRA NVGPU-101 Change-Id: I411477e5696a61ee73caebfdab625763b522c255 Signed-off-by: Mahantesh Kumbar Reviewed-on: http://git-master/r/1469453 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Vijayakumar Subbu --- drivers/gpu/nvgpu/common/falcon/falcon.c | 103 ++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/nvgpu/common') diff --git a/drivers/gpu/nvgpu/common/falcon/falcon.c b/drivers/gpu/nvgpu/common/falcon/falcon.c index bcc24355..9e832985 100644 --- a/drivers/gpu/nvgpu/common/falcon/falcon.c +++ b/drivers/gpu/nvgpu/common/falcon/falcon.c @@ -16,6 +16,106 @@ #include "gk20a/gk20a.h" +int nvgpu_flcn_wait_idle(struct nvgpu_falcon *flcn) +{ + struct gk20a *g = flcn->g; + struct nvgpu_falcon_ops *flcn_ops = &flcn->flcn_ops; + struct nvgpu_timeout timeout; + u32 idle_stat; + + if (!flcn_ops->is_falcon_idle) { + nvgpu_warn(g, "Invalid op on falcon 0x%x ", flcn->flcn_id); + return -EINVAL; + } + + nvgpu_timeout_init(g, &timeout, 2000, NVGPU_TIMER_RETRY_TIMER); + + /* wait for falcon idle */ + do { + idle_stat = flcn_ops->is_falcon_idle(flcn); + + if (idle_stat) + break; + + if (nvgpu_timeout_expired_msg(&timeout, + "waiting for falcon idle: 0x%08x", idle_stat)) + return -EBUSY; + + nvgpu_usleep_range(100, 200); + } while (1); + + return 0; +} + +int nvgpu_flcn_reset(struct nvgpu_falcon *flcn) +{ + int status = -EINVAL; + + if (flcn->flcn_ops.reset) + status = flcn->flcn_ops.reset(flcn); + else + nvgpu_warn(flcn->g, "Invalid op on falcon 0x%x ", + flcn->flcn_id); + + return status; +} + +void nvgpu_flcn_set_irq(struct nvgpu_falcon *flcn, bool enable, + u32 intr_mask, u32 intr_dest) +{ + struct nvgpu_falcon_ops *flcn_ops = &flcn->flcn_ops; + + if (flcn_ops->set_irq) { + flcn->intr_mask = intr_mask; + flcn->intr_dest = intr_dest; + flcn_ops->set_irq(flcn, enable); + } else + nvgpu_warn(flcn->g, "Invalid op on falcon 0x%x ", + flcn->flcn_id); +} + +bool nvgpu_flcn_get_mem_scrubbing_status(struct nvgpu_falcon *flcn) +{ + struct nvgpu_falcon_ops *flcn_ops = &flcn->flcn_ops; + bool status = false; + + if (flcn_ops->is_falcon_scrubbing_done) + status = flcn_ops->is_falcon_scrubbing_done(flcn); + else + nvgpu_warn(flcn->g, "Invalid op on falcon 0x%x ", + flcn->flcn_id); + + return status; +} + +bool nvgpu_flcn_get_cpu_halted_status(struct nvgpu_falcon *flcn) +{ + struct nvgpu_falcon_ops *flcn_ops = &flcn->flcn_ops; + bool status = false; + + if (flcn_ops->is_falcon_cpu_halted) + status = flcn_ops->is_falcon_cpu_halted(flcn); + else + nvgpu_warn(flcn->g, "Invalid op on falcon 0x%x ", + flcn->flcn_id); + + return status; +} + +bool nvgpu_flcn_get_idle_status(struct nvgpu_falcon *flcn) +{ + struct nvgpu_falcon_ops *flcn_ops = &flcn->flcn_ops; + bool status = false; + + if (flcn_ops->is_falcon_idle) + status = flcn_ops->is_falcon_idle(flcn); + else + nvgpu_warn(flcn->g, "Invalid op on falcon 0x%x ", + flcn->flcn_id); + + return status; +} + void nvgpu_flcn_sw_init(struct gk20a *g, u32 flcn_id) { struct nvgpu_falcon *flcn = NULL; @@ -25,6 +125,7 @@ void nvgpu_flcn_sw_init(struct gk20a *g, u32 flcn_id) case FALCON_ID_PMU: flcn = &g->pmu_flcn; flcn->flcn_id = flcn_id; + g->pmu.flcn = &g->pmu_flcn; break; case FALCON_ID_SEC2: flcn = &g->sec2_flcn; @@ -37,7 +138,7 @@ void nvgpu_flcn_sw_init(struct gk20a *g, u32 flcn_id) case FALCON_ID_GPCCS: flcn = &g->gpccs_flcn; flcn->flcn_id = flcn_id; - break; + break; default: nvgpu_err(g, "Invalid/Unsupported falcon ID %x", flcn_id); break; -- cgit v1.2.2