From 268721975c6c72418e2282126e7f594f62e6e118 Mon Sep 17 00:00:00 2001 From: Mahantesh Kumbar Date: Fri, 23 Jun 2017 17:10:13 +0530 Subject: gpu: nvgpu: PMU reset reorg - nvgpu_pmu_reset() as pmu reset for all chips & removed gk20a_pmu_reset() & gp106_pmu_reset() along with dependent code. - Created ops to do PMU engine reset & to know the engine reset status - Removed pmu.reset ops & replaced with nvgpu_flcn_reset(pmu->flcn) - Moved sec2 reset to sec2_gp106 from pmu_gp106 & cleaned PMU code part of sec2. JIRA NVGPU-99 Change-Id: I7575e4ca2b34922d73d171f6a41bfcdc2f40dc96 Signed-off-by: Mahantesh Kumbar Reviewed-on: https://git-master/r/1507881 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/falcon/falcon.c | 1 + drivers/gpu/nvgpu/common/pmu/pmu.c | 114 +++++++++++++++++++++--- drivers/gpu/nvgpu/gk20a/flcn_gk20a.c | 3 +- drivers/gpu/nvgpu/gk20a/gk20a.h | 3 +- drivers/gpu/nvgpu/gk20a/pmu_gk20a.c | 108 ++++------------------- drivers/gpu/nvgpu/gk20a/pmu_gk20a.h | 5 +- drivers/gpu/nvgpu/gm206/bios_gm206.c | 4 +- drivers/gpu/nvgpu/gm20b/pmu_gm20b.c | 3 +- drivers/gpu/nvgpu/gp106/pmu_gp106.c | 145 ++++--------------------------- drivers/gpu/nvgpu/gp106/pmu_gp106.h | 3 +- drivers/gpu/nvgpu/gp106/sec2_gp106.c | 23 +++-- drivers/gpu/nvgpu/gp10b/pmu_gp10b.c | 3 +- drivers/gpu/nvgpu/include/nvgpu/pmu.h | 3 + 13 files changed, 173 insertions(+), 245 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/nvgpu/common/falcon/falcon.c b/drivers/gpu/nvgpu/common/falcon/falcon.c index 375a9cee..b6589bd1 100644 --- a/drivers/gpu/nvgpu/common/falcon/falcon.c +++ b/drivers/gpu/nvgpu/common/falcon/falcon.c @@ -142,6 +142,7 @@ void nvgpu_flcn_sw_init(struct gk20a *g, u32 flcn_id) flcn = &g->pmu_flcn; flcn->flcn_id = flcn_id; g->pmu.flcn = &g->pmu_flcn; + g->pmu.g = g; break; case FALCON_ID_SEC2: flcn = &g->sec2_flcn; diff --git a/drivers/gpu/nvgpu/common/pmu/pmu.c b/drivers/gpu/nvgpu/common/pmu/pmu.c index eb1c83fb..cc87c89b 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu.c @@ -18,8 +18,109 @@ #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); + + if (enable) { + /* bring PMU falcon/engine out of reset */ + g->ops.pmu.reset_engine(g, true); + + if (g->ops.clock_gating.slcg_pmu_load_gating_prod) + g->ops.clock_gating.slcg_pmu_load_gating_prod(g, + g->slcg_enabled); + + if (g->ops.clock_gating.blcg_pmu_load_gating_prod) + 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 + /* 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; +} + +static int pmu_enable(struct nvgpu_pmu *pmu, bool enable) +{ + struct gk20a *g = pmu->g; + int err = 0; + + nvgpu_log_fn(g, " "); + + if (!enable) { + if (!g->ops.pmu.is_engine_in_reset(g)) { + pmu_enable_irq(pmu, false); + pmu_enable_hw(pmu, false); + } + } else { + err = pmu_enable_hw(pmu, true); + if (err) + goto exit; + + err = nvgpu_flcn_wait_idle(pmu->flcn); + if (err) + goto exit; + + pmu_enable_irq(pmu, true); + } + +exit: + nvgpu_log_fn(g, "Done, status - %d ", err); + return err; +} + +int nvgpu_pmu_reset(struct gk20a *g) +{ + struct nvgpu_pmu *pmu = &g->pmu; + int err = 0; + + nvgpu_log_fn(g, " %s ", g->name); + + err = nvgpu_flcn_wait_idle(pmu->flcn); + if (err) + goto exit; + + err = pmu_enable(pmu, false); + if (err) + goto exit; + + err = pmu_enable(pmu, true); + +exit: + nvgpu_log_fn(g, " %s Done, status - %d ", g->name, err); + return err; +} + static int nvgpu_init_task_pg_init(struct gk20a *g) { struct nvgpu_pmu *pmu = &g->pmu; @@ -139,17 +240,6 @@ skip_init: return err; } -static int nvgpu_init_pmu_reset_enable_hw(struct gk20a *g) -{ - struct nvgpu_pmu *pmu = &g->pmu; - - nvgpu_log_fn(g, " "); - - pmu_enable_hw(pmu, true); - - return 0; -} - int nvgpu_init_pmu_support(struct gk20a *g) { struct nvgpu_pmu *pmu = &g->pmu; @@ -160,7 +250,7 @@ int nvgpu_init_pmu_support(struct gk20a *g) if (pmu->initialized) return 0; - err = nvgpu_init_pmu_reset_enable_hw(g); + err = pmu_enable_hw(pmu, true); if (err) return err; diff --git a/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c b/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c index 9d378248..2a246fdc 100644 --- a/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c @@ -11,6 +11,7 @@ * more details. */ #include +#include #include "gk20a/gk20a.h" @@ -256,7 +257,7 @@ static void gk20a_falcon_engine_dependency_ops(struct nvgpu_falcon *flcn) switch (flcn->flcn_id) { case FALCON_ID_PMU: - flcn_eng_dep_ops->reset_eng = gk20a_pmu_reset; + flcn_eng_dep_ops->reset_eng = nvgpu_pmu_reset; break; default: /* NULL assignment make sure diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 191d1c39..ff37d9f3 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -755,7 +755,8 @@ struct gpu_ops { int (*pmu_lpwr_disable_pg)(struct gk20a *g, bool pstate_lock); u32 (*pmu_pg_param_post_init)(struct gk20a *g); void (*dump_secure_fuses)(struct gk20a *g); - int (*reset)(struct gk20a *g); + int (*reset_engine)(struct gk20a *g, bool do_reset); + bool (*is_engine_in_reset)(struct gk20a *g); int (*falcon_wait_for_halt)(struct gk20a *g, unsigned int timeout); int (*falcon_clear_halt_interrupt_status)(struct gk20a *g, diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c index 4a676b82..3fc73e42 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c @@ -38,8 +38,6 @@ #define gk20a_dbg_pmu(fmt, arg...) \ gk20a_dbg(gpu_dbg_pmu, fmt, ##arg) -#define PMU_MEM_SCRUBBING_TIMEOUT_MAX 1000 -#define PMU_MEM_SCRUBBING_TIMEOUT_DEFAULT 10 bool nvgpu_find_hex_in_string(char *strings, struct gk20a *g, u32 *hex_pos) { @@ -159,80 +157,7 @@ void pmu_enable_irq(struct nvgpu_pmu *pmu, bool enable) gk20a_dbg_fn("done"); } -int pmu_enable_hw(struct nvgpu_pmu *pmu, bool enable) -{ - struct gk20a *g = gk20a_from_pmu(pmu); - struct nvgpu_timeout timeout; - int err = 0; - - gk20a_dbg_fn(""); - - if (enable) { - g->ops.mc.enable(g, mc_enable_pwr_enabled_f()); - - if (g->ops.clock_gating.slcg_pmu_load_gating_prod) - g->ops.clock_gating.slcg_pmu_load_gating_prod(g, - g->slcg_enabled); - if (g->ops.clock_gating.blcg_pmu_load_gating_prod) - g->ops.clock_gating.blcg_pmu_load_gating_prod(g, - g->blcg_enabled); - - 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)) { - gk20a_dbg_fn("done"); - goto exit; - } - nvgpu_udelay(PMU_MEM_SCRUBBING_TIMEOUT_DEFAULT); - } while (!nvgpu_timeout_expired(&timeout)); - - g->ops.mc.disable(g, mc_enable_pwr_enabled_f()); - nvgpu_err(g, "Falcon mem scrubbing timeout"); - - err = -ETIMEDOUT; - } else - g->ops.mc.disable(g, mc_enable_pwr_enabled_f()); - -exit: - return err; -} -static int pmu_enable(struct nvgpu_pmu *pmu, bool enable) -{ - struct gk20a *g = gk20a_from_pmu(pmu); - u32 pmc_enable; - int err; - - gk20a_dbg_fn(""); - - if (!enable) { - pmc_enable = gk20a_readl(g, mc_enable_r()); - if (mc_enable_pwr_v(pmc_enable) != - mc_enable_pwr_disabled_v()) { - - pmu_enable_irq(pmu, false); - pmu_enable_hw(pmu, false); - } - } else { - err = pmu_enable_hw(pmu, true); - if (err) - return err; - - /* TBD: post reset */ - - err = nvgpu_flcn_wait_idle(pmu->flcn); - if (err) - return err; - - pmu_enable_irq(pmu, true); - } - - gk20a_dbg_fn("done"); - return 0; -} int pmu_bootstrap(struct nvgpu_pmu *pmu) { @@ -576,25 +501,27 @@ static void gk20a_write_dmatrfbase(struct gk20a *g, u32 addr) gk20a_writel(g, pwr_falcon_dmatrfbase_r(), addr); } -int gk20a_pmu_reset(struct gk20a *g) +bool gk20a_pmu_is_engine_in_reset(struct gk20a *g) { - struct nvgpu_pmu *pmu = &g->pmu; - int err; + u32 pmc_enable; + bool status = false; - err = nvgpu_flcn_wait_idle(pmu->flcn); - if (err) - goto exit; + pmc_enable = gk20a_readl(g, mc_enable_r()); + if (mc_enable_pwr_v(pmc_enable) == + mc_enable_pwr_disabled_v()) + status = true; - err = pmu_enable(pmu, false); - if (err) - goto exit; + return status; +} - err = pmu_enable(pmu, true); - if (err) - goto exit; +int gk20a_pmu_engine_reset(struct gk20a *g, bool do_reset) +{ + if (do_reset) + g->ops.mc.enable(g, mc_enable_pwr_enabled_f()); + else + g->ops.mc.disable(g, mc_enable_pwr_enabled_f()); -exit: - return err; + return 0; } static bool gk20a_is_pmu_supported(struct gk20a *g) @@ -650,7 +577,8 @@ void gk20a_init_pmu_ops(struct gpu_ops *gops) gops->pmu.alloc_blob_space = NULL; gops->pmu.pmu_populate_loader_cfg = NULL; gops->pmu.flcn_populate_bl_dmem_desc = NULL; - gops->pmu.reset = NULL; + gops->pmu.reset_engine = gk20a_pmu_engine_reset; + gops->pmu.is_engine_in_reset = gk20a_pmu_is_engine_in_reset; } static void pmu_handle_zbc_msg(struct gk20a *g, struct pmu_msg *msg, diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h index 8f337855..997a88d2 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h @@ -70,9 +70,10 @@ void pmu_handle_fecs_boot_acr_msg(struct gk20a *g, struct pmu_msg *msg, void *param, u32 handle, u32 status); void gk20a_pmu_elpg_statistics(struct gk20a *g, u32 pg_engine_id, struct pmu_pg_stats_data *pg_stat_data); -int gk20a_pmu_reset(struct gk20a *g); +bool gk20a_pmu_is_engine_in_reset(struct gk20a *g); +int gk20a_pmu_engine_reset(struct gk20a *g, bool do_reset); + int pmu_idle(struct nvgpu_pmu *pmu); -int pmu_enable_hw(struct nvgpu_pmu *pmu, bool enable); bool nvgpu_find_hex_in_string(char *strings, struct gk20a *g, u32 *hex_pos); diff --git a/drivers/gpu/nvgpu/gm206/bios_gm206.c b/drivers/gpu/nvgpu/gm206/bios_gm206.c index c32959a3..567b01ce 100644 --- a/drivers/gpu/nvgpu/gm206/bios_gm206.c +++ b/drivers/gpu/nvgpu/gm206/bios_gm206.c @@ -105,7 +105,7 @@ static int gm206_bios_devinit(struct gk20a *g) struct nvgpu_timeout timeout; gk20a_dbg_fn(""); - g->ops.pmu.reset(g); + nvgpu_flcn_reset(g->pmu.flcn); nvgpu_timeout_init(g, &timeout, PMU_BOOT_TIMEOUT_MAX / @@ -187,7 +187,7 @@ static int gm206_bios_preos(struct gk20a *g) struct nvgpu_timeout timeout; gk20a_dbg_fn(""); - g->ops.pmu.reset(g); + nvgpu_flcn_reset(g->pmu.flcn); nvgpu_timeout_init(g, &timeout, PMU_BOOT_TIMEOUT_MAX / diff --git a/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c b/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c index 6c5a2502..3b655b62 100644 --- a/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c @@ -309,5 +309,6 @@ void gm20b_init_pmu_ops(struct gpu_ops *gops) gops->pmu.pmu_lpwr_disable_pg = NULL; gops->pmu.pmu_pg_param_post_init = NULL; gops->pmu.dump_secure_fuses = pmu_dump_security_fuses_gm20b; - gops->pmu.reset = NULL; + gops->pmu.reset_engine = gk20a_pmu_engine_reset; + gops->pmu.is_engine_in_reset = gk20a_pmu_is_engine_in_reset; } diff --git a/drivers/gpu/nvgpu/gp106/pmu_gp106.c b/drivers/gpu/nvgpu/gp106/pmu_gp106.c index 88d68220..56f1e194 100644 --- a/drivers/gpu/nvgpu/gp106/pmu_gp106.c +++ b/drivers/gpu/nvgpu/gp106/pmu_gp106.c @@ -32,151 +32,43 @@ #include #include -#define PMU_MEM_SCRUBBING_TIMEOUT_MAX 1000 -#define PMU_MEM_SCRUBBING_TIMEOUT_DEFAULT 10 +static bool gp106_is_pmu_supported(struct gk20a *g) +{ + return true; +} -static int gp106_pmu_enable_hw(struct nvgpu_pmu *pmu, bool enable) +bool gp106_pmu_is_engine_in_reset(struct gk20a *g) { - struct gk20a *g = gk20a_from_pmu(pmu); + u32 reg_reset; + bool status = false; - gk20a_dbg_fn(""); + reg_reset = gk20a_readl(g, pwr_falcon_engine_r()); + if (reg_reset == pwr_falcon_engine_reset_true_f()) + status = true; + + return status; +} +int gp106_pmu_engine_reset(struct gk20a *g, bool do_reset) +{ /* * From GP10X onwards, we are using PPWR_FALCON_ENGINE for reset. And as - * it may come into same behaviour, reading NV_PPWR_FALCON_ENGINE again + * it may come into same behavior, reading NV_PPWR_FALCON_ENGINE again * after Reset. */ - - if (enable) { - int retries = PMU_MEM_SCRUBBING_TIMEOUT_MAX / - PMU_MEM_SCRUBBING_TIMEOUT_DEFAULT; + if (do_reset) { gk20a_writel(g, pwr_falcon_engine_r(), pwr_falcon_engine_reset_false_f()); gk20a_readl(g, pwr_falcon_engine_r()); - - /* make sure ELPG is in a good state */ - if (g->ops.clock_gating.slcg_pmu_load_gating_prod) - g->ops.clock_gating.slcg_pmu_load_gating_prod(g, - g->slcg_enabled); - if (g->ops.clock_gating.blcg_pmu_load_gating_prod) - g->ops.clock_gating.blcg_pmu_load_gating_prod(g, - g->blcg_enabled); - - /* wait for Scrubbing to complete */ - do { - if (nvgpu_flcn_get_mem_scrubbing_status(pmu->flcn)) { - gk20a_dbg_fn("done"); - return 0; - } - nvgpu_udelay(PMU_MEM_SCRUBBING_TIMEOUT_DEFAULT); - } while (--retries); - - /* If scrubbing timeout, keep PMU in reset state */ - gk20a_writel(g, pwr_falcon_engine_r(), - pwr_falcon_engine_reset_true_f()); - gk20a_readl(g, pwr_falcon_engine_r()); - nvgpu_err(g, "Falcon mem scrubbing timeout"); - return -ETIMEDOUT; } else { - /* DISBALE */ gk20a_writel(g, pwr_falcon_engine_r(), pwr_falcon_engine_reset_true_f()); gk20a_readl(g, pwr_falcon_engine_r()); - return 0; } -} -static int pmu_enable(struct nvgpu_pmu *pmu, bool enable) -{ - struct gk20a *g = gk20a_from_pmu(pmu); - u32 reg_reset; - int err; - - gk20a_dbg_fn(""); - - if (!enable) { - reg_reset = gk20a_readl(g, pwr_falcon_engine_r()); - if (reg_reset != - pwr_falcon_engine_reset_true_f()) { - - pmu_enable_irq(pmu, false); - gp106_pmu_enable_hw(pmu, false); - nvgpu_udelay(10); - } - } else { - gp106_pmu_enable_hw(pmu, true); - /* TBD: post reset */ - - /*idle the PMU and enable interrupts on the Falcon*/ - err = nvgpu_flcn_wait_idle(pmu->flcn); - if (err) - return err; - nvgpu_udelay(5); - pmu_enable_irq(pmu, true); - } - - gk20a_dbg_fn("done"); return 0; } -int gp106_pmu_reset(struct gk20a *g) -{ - struct nvgpu_pmu *pmu = &g->pmu; - int err = 0; - - gk20a_dbg_fn(""); - - err = nvgpu_flcn_wait_idle(pmu->flcn); - if (err) - return err; - - /* TBD: release pmu hw mutex */ - - err = pmu_enable(pmu, false); - if (err) - return err; - - /* TBD: cancel all sequences */ - /* TBD: init all sequences and state tables */ - /* TBD: restore pre-init message handler */ - - err = pmu_enable(pmu, true); - if (err) - return err; - - return err; -} - -static int gp106_sec2_reset(struct gk20a *g) -{ - gk20a_dbg_fn(""); - //sec2 reset - gk20a_writel(g, psec_falcon_engine_r(), - pwr_falcon_engine_reset_true_f()); - nvgpu_udelay(10); - gk20a_writel(g, psec_falcon_engine_r(), - pwr_falcon_engine_reset_false_f()); - - gk20a_dbg_fn("done"); - return 0; -} - -static int gp106_falcon_reset(struct gk20a *g) -{ - gk20a_dbg_fn(""); - - gp106_pmu_reset(g); - gp106_sec2_reset(g); - - gk20a_dbg_fn("done"); - return 0; -} - -static bool gp106_is_pmu_supported(struct gk20a *g) -{ - return true; -} - static u32 gp106_pmu_pg_feature_list(struct gk20a *g, u32 pg_engine_id) { if (pg_engine_id == PMU_PG_ELPG_ENGINE_ID_GRAPHICS) @@ -439,10 +331,11 @@ void gp106_init_pmu_ops(struct gpu_ops *gops) gops->pmu.pmu_lpwr_disable_pg = nvgpu_lpwr_disable_pg; gops->pmu.pmu_pg_param_post_init = nvgpu_lpwr_post_init; gops->pmu.dump_secure_fuses = NULL; - gops->pmu.reset = gp106_falcon_reset; gops->pmu.mclk_init = gp106_mclk_init; gops->pmu.mclk_deinit = gp106_mclk_deinit; gops->pmu.is_pmu_supported = gp106_is_pmu_supported; + gops->pmu.reset_engine = gp106_pmu_engine_reset; + gops->pmu.is_engine_in_reset = gp106_pmu_is_engine_in_reset; gk20a_dbg_fn("done"); } diff --git a/drivers/gpu/nvgpu/gp106/pmu_gp106.h b/drivers/gpu/nvgpu/gp106/pmu_gp106.h index 3213b25c..5f399b89 100644 --- a/drivers/gpu/nvgpu/gp106/pmu_gp106.h +++ b/drivers/gpu/nvgpu/gp106/pmu_gp106.h @@ -18,8 +18,9 @@ gk20a_dbg(gpu_dbg_pmu, fmt, ##arg) void gp106_init_pmu_ops(struct gpu_ops *gops); -int gp106_pmu_reset(struct gk20a *g); void gp106_pmu_elpg_statistics(struct gk20a *g, u32 pg_engine_id, struct pmu_pg_stats_data *pg_stat_data); +bool gp106_pmu_is_engine_in_reset(struct gk20a *g); +int gp106_pmu_engine_reset(struct gk20a *g, bool do_reset); #endif /*__PMU_GP106_H_*/ diff --git a/drivers/gpu/nvgpu/gp106/sec2_gp106.c b/drivers/gpu/nvgpu/gp106/sec2_gp106.c index a25fc990..f49d56c4 100644 --- a/drivers/gpu/nvgpu/gp106/sec2_gp106.c +++ b/drivers/gpu/nvgpu/gp106/sec2_gp106.c @@ -330,6 +330,20 @@ void init_pmu_setup_hw1(struct gk20a *g) } +static int gp106_sec2_reset(struct gk20a *g) +{ + nvgpu_log_fn(g, " "); + + gk20a_writel(g, psec_falcon_engine_r(), + pwr_falcon_engine_reset_true_f()); + nvgpu_udelay(10); + gk20a_writel(g, psec_falcon_engine_r(), + pwr_falcon_engine_reset_false_f()); + + nvgpu_log_fn(g, "done"); + return 0; +} + int init_sec2_setup_hw1(struct gk20a *g, void *desc, u32 bl_sz) { @@ -339,10 +353,7 @@ int init_sec2_setup_hw1(struct gk20a *g, gk20a_dbg_fn(""); - nvgpu_mutex_acquire(&pmu->isr_mutex); - g->ops.pmu.reset(g); - pmu->isr_enabled = true; - nvgpu_mutex_release(&pmu->isr_mutex); + gp106_sec2_reset(g); data = gk20a_readl(g, psec_fbif_ctl_r()); data |= psec_fbif_ctl_allow_phys_no_ctx_allow_f(); @@ -370,11 +381,7 @@ int init_sec2_setup_hw1(struct gk20a *g, psec_fbif_transcfg_target_noncoherent_sysmem_f()); /*disable irqs for hs falcon booting as we will poll for halt*/ - nvgpu_mutex_acquire(&pmu->isr_mutex); - pmu_enable_irq(pmu, false); sec_enable_irq(pmu, false); - pmu->isr_enabled = false; - nvgpu_mutex_release(&pmu->isr_mutex); err = bl_bootstrap_sec2(pmu, desc, bl_sz); if (err) return err; diff --git a/drivers/gpu/nvgpu/gp10b/pmu_gp10b.c b/drivers/gpu/nvgpu/gp10b/pmu_gp10b.c index 3d02f475..b086bf1f 100644 --- a/drivers/gpu/nvgpu/gp10b/pmu_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/pmu_gp10b.c @@ -428,6 +428,7 @@ void gp10b_init_pmu_ops(struct gpu_ops *gops) gops->pmu.pmu_lpwr_enable_pg = NULL; gops->pmu.pmu_lpwr_disable_pg = NULL; gops->pmu.pmu_pg_param_post_init = NULL; - gops->pmu.reset = NULL; gops->pmu.dump_secure_fuses = pmu_dump_security_fuses_gp10b; + gops->pmu.reset_engine = gk20a_pmu_engine_reset; + gops->pmu.is_engine_in_reset = gk20a_pmu_is_engine_in_reset; } diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmu.h b/drivers/gpu/nvgpu/include/nvgpu/pmu.h index ede238a0..107d2b2d 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pmu.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pmu.h @@ -432,6 +432,9 @@ int nvgpu_pmu_init_powergating(struct gk20a *g); int nvgpu_pmu_init_bind_fecs(struct gk20a *g); void nvgpu_pmu_setup_hw_load_zbc(struct gk20a *g); +/* PMU reset */ +int nvgpu_pmu_reset(struct gk20a *g); + /* PG enable/disable */ int nvgpu_pmu_enable_elpg(struct gk20a *g); int nvgpu_pmu_disable_elpg(struct gk20a *g); -- cgit v1.2.2