diff options
-rw-r--r-- | drivers/gpu/nvgpu/common/falcon/falcon.c | 40 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/pmu/pmu.c | 34 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/include/nvgpu/falcon.h | 1 |
3 files changed, 48 insertions, 27 deletions
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 @@ | |||
25 | 25 | ||
26 | #include "gk20a/gk20a.h" | 26 | #include "gk20a/gk20a.h" |
27 | 27 | ||
28 | /* Dealy depends on memory size and pwr_clk | ||
29 | * delay = MAX {IMEM_SIZE, DMEM_SIZE} * 64 + 1) / pwr_clk | ||
30 | * Timeout set is 1msec & status check at interval 10usec | ||
31 | */ | ||
32 | #define MEM_SCRUBBING_TIMEOUT_MAX 1000 | ||
33 | #define MEM_SCRUBBING_TIMEOUT_DEFAULT 10 | ||
34 | |||
28 | int nvgpu_flcn_wait_idle(struct nvgpu_falcon *flcn) | 35 | int nvgpu_flcn_wait_idle(struct nvgpu_falcon *flcn) |
29 | { | 36 | { |
30 | struct gk20a *g = flcn->g; | 37 | struct gk20a *g = flcn->g; |
@@ -56,15 +63,42 @@ int nvgpu_flcn_wait_idle(struct nvgpu_falcon *flcn) | |||
56 | return 0; | 63 | return 0; |
57 | } | 64 | } |
58 | 65 | ||
66 | int nvgpu_flcn_mem_scrub_wait(struct nvgpu_falcon *flcn) | ||
67 | { | ||
68 | struct nvgpu_timeout timeout; | ||
69 | int status = 0; | ||
70 | |||
71 | /* check IMEM/DMEM scrubbing complete status */ | ||
72 | nvgpu_timeout_init(flcn->g, &timeout, | ||
73 | MEM_SCRUBBING_TIMEOUT_MAX / | ||
74 | MEM_SCRUBBING_TIMEOUT_DEFAULT, | ||
75 | NVGPU_TIMER_RETRY_TIMER); | ||
76 | do { | ||
77 | if (nvgpu_flcn_get_mem_scrubbing_status(flcn)) | ||
78 | goto exit; | ||
79 | nvgpu_udelay(MEM_SCRUBBING_TIMEOUT_DEFAULT); | ||
80 | } while (!nvgpu_timeout_expired(&timeout)); | ||
81 | |||
82 | if (nvgpu_timeout_peek_expired(&timeout)) | ||
83 | status = -ETIMEDOUT; | ||
84 | |||
85 | exit: | ||
86 | return status; | ||
87 | } | ||
88 | |||
59 | int nvgpu_flcn_reset(struct nvgpu_falcon *flcn) | 89 | int nvgpu_flcn_reset(struct nvgpu_falcon *flcn) |
60 | { | 90 | { |
61 | int status = -EINVAL; | 91 | int status = 0; |
62 | 92 | ||
63 | if (flcn->flcn_ops.reset) | 93 | if (flcn->flcn_ops.reset) { |
64 | status = flcn->flcn_ops.reset(flcn); | 94 | status = flcn->flcn_ops.reset(flcn); |
65 | else | 95 | if (!status) |
96 | status = nvgpu_flcn_mem_scrub_wait(flcn); | ||
97 | } else { | ||
66 | nvgpu_warn(flcn->g, "Invalid op on falcon 0x%x ", | 98 | nvgpu_warn(flcn->g, "Invalid op on falcon 0x%x ", |
67 | flcn->flcn_id); | 99 | flcn->flcn_id); |
100 | status = -EINVAL; | ||
101 | } | ||
68 | 102 | ||
69 | return status; | 103 | return status; |
70 | } | 104 | } |
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 @@ | |||
31 | 31 | ||
32 | #include "gk20a/gk20a.h" | 32 | #include "gk20a/gk20a.h" |
33 | 33 | ||
34 | #define PMU_MEM_SCRUBBING_TIMEOUT_MAX 1000 | ||
35 | #define PMU_MEM_SCRUBBING_TIMEOUT_DEFAULT 10 | ||
36 | |||
37 | static int nvgpu_pg_init_task(void *arg); | 34 | static int nvgpu_pg_init_task(void *arg); |
38 | 35 | ||
39 | static int pmu_enable_hw(struct nvgpu_pmu *pmu, bool enable) | 36 | static int pmu_enable_hw(struct nvgpu_pmu *pmu, bool enable) |
40 | { | 37 | { |
41 | struct gk20a *g = pmu->g; | 38 | struct gk20a *g = pmu->g; |
42 | struct nvgpu_timeout timeout; | ||
43 | int err = 0; | 39 | int err = 0; |
44 | 40 | ||
45 | nvgpu_log_fn(g, " %s ", g->name); | 41 | nvgpu_log_fn(g, " %s ", g->name); |
@@ -56,29 +52,19 @@ static int pmu_enable_hw(struct nvgpu_pmu *pmu, bool enable) | |||
56 | g->ops.clock_gating.blcg_pmu_load_gating_prod(g, | 52 | g->ops.clock_gating.blcg_pmu_load_gating_prod(g, |
57 | g->blcg_enabled); | 53 | g->blcg_enabled); |
58 | 54 | ||
59 | /* check for PMU IMEM/DMEM scrubbing complete status */ | 55 | if (nvgpu_flcn_mem_scrub_wait(pmu->flcn)) { |
60 | nvgpu_timeout_init(g, &timeout, | 56 | /* keep PMU falcon/engine in reset |
61 | PMU_MEM_SCRUBBING_TIMEOUT_MAX / | 57 | * if IMEM/DMEM scrubbing fails |
62 | PMU_MEM_SCRUBBING_TIMEOUT_DEFAULT, | 58 | */ |
63 | NVGPU_TIMER_RETRY_TIMER); | 59 | g->ops.pmu.reset_engine(g, false); |
64 | do { | 60 | nvgpu_err(g, "Falcon mem scrubbing timeout"); |
65 | if (nvgpu_flcn_get_mem_scrubbing_status(pmu->flcn)) | 61 | err = -ETIMEDOUT; |
66 | goto exit; | 62 | } |
67 | 63 | } else { | |
68 | nvgpu_udelay(PMU_MEM_SCRUBBING_TIMEOUT_DEFAULT); | ||
69 | } while (!nvgpu_timeout_expired(&timeout)); | ||
70 | |||
71 | /* keep PMU falcon/engine in reset | ||
72 | * if IMEM/DMEM scrubbing fails | ||
73 | */ | ||
74 | g->ops.pmu.reset_engine(g, false); | ||
75 | nvgpu_err(g, "Falcon mem scrubbing timeout"); | ||
76 | err = -ETIMEDOUT; | ||
77 | } else | ||
78 | /* keep PMU falcon/engine in reset */ | 64 | /* keep PMU falcon/engine in reset */ |
79 | g->ops.pmu.reset_engine(g, false); | 65 | g->ops.pmu.reset_engine(g, false); |
66 | } | ||
80 | 67 | ||
81 | exit: | ||
82 | nvgpu_log_fn(g, "%s Done, status - %d ", g->name, err); | 68 | nvgpu_log_fn(g, "%s Done, status - %d ", g->name, err); |
83 | return err; | 69 | return err; |
84 | } | 70 | } |
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); | |||
222 | void nvgpu_flcn_set_irq(struct nvgpu_falcon *flcn, bool enable, | 222 | void nvgpu_flcn_set_irq(struct nvgpu_falcon *flcn, bool enable, |
223 | u32 intr_mask, u32 intr_dest); | 223 | u32 intr_mask, u32 intr_dest); |
224 | bool nvgpu_flcn_get_mem_scrubbing_status(struct nvgpu_falcon *flcn); | 224 | bool nvgpu_flcn_get_mem_scrubbing_status(struct nvgpu_falcon *flcn); |
225 | int nvgpu_flcn_mem_scrub_wait(struct nvgpu_falcon *flcn); | ||
225 | bool nvgpu_flcn_get_cpu_halted_status(struct nvgpu_falcon *flcn); | 226 | bool nvgpu_flcn_get_cpu_halted_status(struct nvgpu_falcon *flcn); |
226 | bool nvgpu_flcn_get_idle_status(struct nvgpu_falcon *flcn); | 227 | bool nvgpu_flcn_get_idle_status(struct nvgpu_falcon *flcn); |
227 | int nvgpu_flcn_copy_from_dmem(struct nvgpu_falcon *flcn, | 228 | int nvgpu_flcn_copy_from_dmem(struct nvgpu_falcon *flcn, |