From c81cc032c48a1b25e095b17b77399166c9091ff3 Mon Sep 17 00:00:00 2001 From: Debarshi Dutta Date: Tue, 30 Apr 2019 13:54:08 +0530 Subject: gpu: nvgpu: add cg and pg function Add new power/clock gating functions that can be called by other units. New clock_gating functions will reside in cg.c under common/power_features/cg unit. New power gating functions will reside in pg.c under common/power_features/pg unit. Use nvgpu_pg_elpg_disable and nvgpu_pg_elpg_enable to disable/enable elpg and also in gr_gk20a_elpg_protected macro to access gr registers. Add cg_pg_lock to make elpg_enabled, elcg_enabled, blcg_enabled and slcg_enabled thread safe. JIRA NVGPU-2014 Change-Id: I00d124c2ee16242c9a3ef82e7620fbb7f1297aff Signed-off-by: Seema Khowala Reviewed-on: https://git-master.nvidia.com/r/2025493 Signed-off-by: Debarshi Dutta (cherry-picked from c90585856567a547173a8b207365b3a4a3ccdd57 in dev-kernel) Reviewed-on: https://git-master.nvidia.com/r/2108406 GVS: Gerrit_Virtual_Submit Reviewed-by: Bibek Basu Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/os/linux/driver_common.c | 1 + drivers/gpu/nvgpu/os/linux/sysfs.c | 137 +++++++-------------------- drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c | 1 + 3 files changed, 36 insertions(+), 103 deletions(-) (limited to 'drivers/gpu/nvgpu/os/linux') diff --git a/drivers/gpu/nvgpu/os/linux/driver_common.c b/drivers/gpu/nvgpu/os/linux/driver_common.c index cf7877e2..ea4dadac 100644 --- a/drivers/gpu/nvgpu/os/linux/driver_common.c +++ b/drivers/gpu/nvgpu/os/linux/driver_common.c @@ -65,6 +65,7 @@ static void nvgpu_init_vars(struct gk20a *g) nvgpu_mutex_init(&g->ctxsw_disable_lock); nvgpu_mutex_init(&g->tpc_pg_lock); nvgpu_mutex_init(&g->clk_arb_enable_lock); + nvgpu_mutex_init(&g->cg_pg_lock); /* Init the clock req count to 0 */ nvgpu_atomic_set(&g->clk_arb_global_nr, 0); diff --git a/drivers/gpu/nvgpu/os/linux/sysfs.c b/drivers/gpu/nvgpu/os/linux/sysfs.c index 1ffb6539..759c12e8 100644 --- a/drivers/gpu/nvgpu/os/linux/sysfs.c +++ b/drivers/gpu/nvgpu/os/linux/sysfs.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include "os_linux.h" #include "sysfs.h" @@ -49,16 +51,14 @@ static ssize_t elcg_enable_store(struct device *dev, return err; if (val) { - g->elcg_enabled = true; - gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_AUTO); + nvgpu_cg_elcg_set_elcg_enabled(g, true); } else { - g->elcg_enabled = false; - gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_RUN); + nvgpu_cg_elcg_set_elcg_enabled(g, false); } gk20a_idle(g); - nvgpu_info(g, "ELCG is %s.", g->elcg_enabled ? "enabled" : + nvgpu_info(g, "ELCG is %s.", val ? "enabled" : "disabled"); return count; @@ -84,45 +84,19 @@ static ssize_t blcg_enable_store(struct device *dev, if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; - if (val) - g->blcg_enabled = true; - else - g->blcg_enabled = false; - err = gk20a_busy(g); if (err) return err; - if (g->ops.clock_gating.blcg_bus_load_gating_prod) - g->ops.clock_gating.blcg_bus_load_gating_prod(g, - g->blcg_enabled); - if (g->ops.clock_gating.blcg_ce_load_gating_prod) - g->ops.clock_gating.blcg_ce_load_gating_prod(g, - g->blcg_enabled); - if (g->ops.clock_gating.blcg_ctxsw_firmware_load_gating_prod) - g->ops.clock_gating.blcg_ctxsw_firmware_load_gating_prod(g, - g->blcg_enabled); - if (g->ops.clock_gating.blcg_fb_load_gating_prod) - g->ops.clock_gating.blcg_fb_load_gating_prod(g, - g->blcg_enabled); - if (g->ops.clock_gating.blcg_fifo_load_gating_prod) - g->ops.clock_gating.blcg_fifo_load_gating_prod(g, - g->blcg_enabled); - if (g->ops.clock_gating.blcg_gr_load_gating_prod) - g->ops.clock_gating.blcg_gr_load_gating_prod(g, - g->blcg_enabled); - if (g->ops.clock_gating.blcg_ltc_load_gating_prod) - g->ops.clock_gating.blcg_ltc_load_gating_prod(g, - g->blcg_enabled); - if (g->ops.clock_gating.blcg_pmu_load_gating_prod) - g->ops.clock_gating.blcg_pmu_load_gating_prod(g, - g->blcg_enabled); - if (g->ops.clock_gating.blcg_xbar_load_gating_prod) - g->ops.clock_gating.blcg_xbar_load_gating_prod(g, - g->blcg_enabled); + if (val) { + nvgpu_cg_blcg_set_blcg_enabled(g, true); + } else { + nvgpu_cg_blcg_set_blcg_enabled(g, false); + } + gk20a_idle(g); - nvgpu_info(g, "BLCG is %s.", g->blcg_enabled ? "enabled" : + nvgpu_info(g, "BLCG is %s.", val ? "enabled" : "disabled"); return count; @@ -149,59 +123,25 @@ static ssize_t slcg_enable_store(struct device *dev, if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; - if (val) - g->slcg_enabled = true; - else - g->slcg_enabled = false; + err = gk20a_busy(g); + if (err) { + return err; + } + + if (val) { + nvgpu_cg_slcg_set_slcg_enabled(g, true); + } else { + nvgpu_cg_slcg_set_slcg_enabled(g, false); + } /* * TODO: slcg_therm_load_gating is not enabled anywhere during * init. Therefore, it would be incongruous to add it here. Once * it is added to init, we should add it here too. */ - err = gk20a_busy(g); - if (err) - return err; - - if (g->ops.clock_gating.slcg_bus_load_gating_prod) - g->ops.clock_gating.slcg_bus_load_gating_prod(g, - g->slcg_enabled); - if (g->ops.clock_gating.slcg_ce2_load_gating_prod) - g->ops.clock_gating.slcg_ce2_load_gating_prod(g, - g->slcg_enabled); - if (g->ops.clock_gating.slcg_chiplet_load_gating_prod) - g->ops.clock_gating.slcg_chiplet_load_gating_prod(g, - g->slcg_enabled); - if (g->ops.clock_gating.slcg_ctxsw_firmware_load_gating_prod) - g->ops.clock_gating.slcg_ctxsw_firmware_load_gating_prod(g, - g->slcg_enabled); - if (g->ops.clock_gating.slcg_fb_load_gating_prod) - g->ops.clock_gating.slcg_fb_load_gating_prod(g, - g->slcg_enabled); - if (g->ops.clock_gating.slcg_fifo_load_gating_prod) - g->ops.clock_gating.slcg_fifo_load_gating_prod(g, - g->slcg_enabled); - if (g->ops.clock_gating.slcg_gr_load_gating_prod) - g->ops.clock_gating.slcg_gr_load_gating_prod(g, - g->slcg_enabled); - if (g->ops.clock_gating.slcg_ltc_load_gating_prod) - g->ops.clock_gating.slcg_ltc_load_gating_prod(g, - g->slcg_enabled); - if (g->ops.clock_gating.slcg_perf_load_gating_prod) - g->ops.clock_gating.slcg_perf_load_gating_prod(g, - g->slcg_enabled); - if (g->ops.clock_gating.slcg_priring_load_gating_prod) - g->ops.clock_gating.slcg_priring_load_gating_prod(g, - g->slcg_enabled); - 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.slcg_xbar_load_gating_prod) - g->ops.clock_gating.slcg_xbar_load_gating_prod(g, - g->slcg_enabled); gk20a_idle(g); - nvgpu_info(g, "SLCG is %s.", g->slcg_enabled ? "enabled" : + nvgpu_info(g, "SLCG is %s.", val ? "enabled" : "disabled"); return count; @@ -474,7 +414,7 @@ static ssize_t elpg_enable_store(struct device *dev, return -EINVAL; if (!g->power_on) { - g->elpg_enabled = val ? true : false; + return -EINVAL; } else { err = gk20a_busy(g); if (err) @@ -483,25 +423,14 @@ static ssize_t elpg_enable_store(struct device *dev, * Since elpg is refcounted, we should not unnecessarily call * enable/disable if it is already so. */ - if (val && !g->elpg_enabled) { - g->elpg_enabled = true; - nvgpu_pmu_pg_global_enable(g, true); - - } else if (!val && g->elpg_enabled) { - if (g->ops.pmu.pmu_pg_engines_feature_list && - g->ops.pmu.pmu_pg_engines_feature_list(g, - PMU_PG_ELPG_ENGINE_ID_GRAPHICS) != - NVGPU_PMU_GR_FEATURE_MASK_POWER_GATING) { - nvgpu_pmu_pg_global_enable(g, false); - g->elpg_enabled = false; - } else { - g->elpg_enabled = false; - nvgpu_pmu_pg_global_enable(g, false); - } + if (val != 0) { + nvgpu_pg_elpg_set_elpg_enabled(g, true); + } else { + nvgpu_pg_elpg_set_elpg_enabled(g, false); } gk20a_idle(g); } - nvgpu_info(g, "ELPG is %s.", g->elpg_enabled ? "enabled" : + nvgpu_info(g, "ELPG is %s.", val ? "enabled" : "disabled"); return count; @@ -512,7 +441,8 @@ static ssize_t elpg_enable_read(struct device *dev, { struct gk20a *g = get_gk20a(dev); - return snprintf(buf, PAGE_SIZE, "%d\n", g->elpg_enabled ? 1 : 0); + return snprintf(buf, PAGE_SIZE, "%d\n", + nvgpu_pg_elpg_is_enabled(g) ? 1 : 0); } static DEVICE_ATTR(elpg_enable, ROOTRW, elpg_enable_read, elpg_enable_store); @@ -610,8 +540,9 @@ static ssize_t mscg_enable_store(struct device *dev, /* make status visible */ smp_mb(); g->mscg_enabled = false; - if (g->elpg_enabled) - nvgpu_pmu_pg_global_enable(g, true); + if (nvgpu_pg_elpg_is_enabled(g)) { + nvgpu_pg_elpg_enable(g); + } } g->mscg_enabled = false; } diff --git a/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c b/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c index 91e94696..522f1b86 100644 --- a/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c +++ b/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c @@ -69,6 +69,7 @@ static void vgpu_init_vars(struct gk20a *g, struct gk20a_platform *platform) nvgpu_mutex_init(&g->power_lock); nvgpu_mutex_init(&g->ctxsw_disable_lock); nvgpu_mutex_init(&g->clk_arb_enable_lock); + nvgpu_mutex_init(&g->cg_pg_lock); nvgpu_mutex_init(&priv->vgpu_clk_get_freq_lock); -- cgit v1.2.2