mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-23 18:16:01 +03:00
gpu: nvgpu: fix pmu->mscg_stat optimization issue
- with help of WRITE_ONCE() & ACCESS_ONCE() make sure variable pmu->mscg_stat read/write goes through without optimization - Added WRITE_ONCE() define for kernel-3.18 version & below to support backward compatibility issue: inconsistencies on getting MSCG to trigger consistently in P5 due to a lack of memory barrier around and volatile accesses to the variable pmu->mscg_stat JIRA DNVGPU-71 Change-Id: I04d30493d42c52710304dbdfb9cb4a1e9a76f2c0 Signed-off-by: Mahantesh Kumbar <mkumbar@nvidia.com> Reviewed-on: http://git-master/r/1252524 (cherry picked from commit 8af7fc68e7ab06a856ba4ef4e44de7336682361b) Reviewed-on: http://git-master/r/1271614 Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
157ff622f3
commit
efe0758081
@@ -64,6 +64,10 @@ struct acr_desc;
|
||||
#endif
|
||||
#include "gm206/bios_gm206.h"
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
|
||||
#define WRITE_ONCE(x, val) \
|
||||
x = val
|
||||
#endif
|
||||
|
||||
/* PTIMER_REF_FREQ_HZ corresponds to a period of 32 nanoseconds.
|
||||
32 ns is the resolution of ptimer. */
|
||||
|
||||
@@ -511,15 +511,21 @@ static ssize_t mscg_enable_store(struct device *dev,
|
||||
g->mscg_enabled = true;
|
||||
if (g->ops.pmu.pmu_is_lpwr_feature_supported(g,
|
||||
PMU_PG_LPWR_FEATURE_MSCG)) {
|
||||
if (!pmu->mscg_stat)
|
||||
pmu->mscg_stat = PMU_MSCG_ENABLED;
|
||||
if (!ACCESS_ONCE(pmu->mscg_stat)) {
|
||||
WRITE_ONCE(pmu->mscg_stat,
|
||||
PMU_MSCG_ENABLED);
|
||||
/* make status visible */
|
||||
smp_mb();
|
||||
}
|
||||
}
|
||||
|
||||
} else if (!val && g->mscg_enabled) {
|
||||
if (g->ops.pmu.pmu_is_lpwr_feature_supported(g,
|
||||
PMU_PG_LPWR_FEATURE_MSCG)) {
|
||||
gk20a_pmu_pg_global_enable(g, false);
|
||||
pmu->mscg_stat = PMU_MSCG_DISABLED;
|
||||
WRITE_ONCE(pmu->mscg_stat, PMU_MSCG_DISABLED);
|
||||
/* make status visible */
|
||||
smp_mb();
|
||||
g->mscg_enabled = false;
|
||||
if (g->elpg_enabled)
|
||||
gk20a_pmu_pg_global_enable(g, true);
|
||||
|
||||
@@ -3388,7 +3388,9 @@ static void pmu_handle_pg_elpg_msg(struct gk20a *g, struct pmu_msg *msg,
|
||||
PMU_PG_FEATURE_GR_POWER_GATING_ENABLED) {
|
||||
pmu->initialized = true;
|
||||
pmu->pmu_state = PMU_STATE_STARTED;
|
||||
pmu->mscg_stat = PMU_MSCG_DISABLED;
|
||||
WRITE_ONCE(pmu->mscg_stat, PMU_MSCG_DISABLED);
|
||||
/* make status visible */
|
||||
smp_mb();
|
||||
} else {
|
||||
pmu->pmu_state = PMU_STATE_ELPG_BOOTED;
|
||||
schedule_work(&pmu->pg_init);
|
||||
@@ -4849,7 +4851,7 @@ int gk20a_pmu_enable_elpg(struct gk20a *g)
|
||||
pg_engine_id++) {
|
||||
|
||||
if (pg_engine_id == PMU_PG_ELPG_ENGINE_ID_MS &&
|
||||
pmu->mscg_stat == PMU_MSCG_DISABLED)
|
||||
ACCESS_ONCE(pmu->mscg_stat) == PMU_MSCG_DISABLED)
|
||||
continue;
|
||||
|
||||
if (BIT(pg_engine_id) & pg_engine_id_list)
|
||||
@@ -4925,7 +4927,7 @@ int gk20a_pmu_disable_elpg(struct gk20a *g)
|
||||
pg_engine_id++) {
|
||||
|
||||
if (pg_engine_id == PMU_PG_ELPG_ENGINE_ID_MS &&
|
||||
pmu->mscg_stat == PMU_MSCG_DISABLED)
|
||||
ACCESS_ONCE(pmu->mscg_stat) == PMU_MSCG_DISABLED)
|
||||
continue;
|
||||
|
||||
if (BIT(pg_engine_id) & pg_engine_id_list) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -362,8 +362,11 @@ int nvgpu_lpwr_enable_pg(struct gk20a *g, bool pstate_lock)
|
||||
is_mscg_supported = nvgpu_lpwr_is_mscg_supported(g,
|
||||
present_pstate);
|
||||
if (is_mscg_supported && g->mscg_enabled) {
|
||||
if (!pmu->mscg_stat)
|
||||
pmu->mscg_stat = PMU_MSCG_ENABLED;
|
||||
if (!ACCESS_ONCE(pmu->mscg_stat)) {
|
||||
WRITE_ONCE(pmu->mscg_stat, PMU_MSCG_ENABLED);
|
||||
/* make status visible */
|
||||
smp_mb();
|
||||
}
|
||||
}
|
||||
|
||||
is_rppg_supported = nvgpu_lpwr_is_rppg_supported(g,
|
||||
@@ -409,8 +412,11 @@ int nvgpu_lpwr_disable_pg(struct gk20a *g, bool pstate_lock)
|
||||
is_mscg_supported = nvgpu_lpwr_is_mscg_supported(g,
|
||||
present_pstate);
|
||||
if (is_mscg_supported && g->mscg_enabled) {
|
||||
if (pmu->mscg_stat)
|
||||
pmu->mscg_stat = PMU_MSCG_DISABLED;
|
||||
if (ACCESS_ONCE(pmu->mscg_stat)) {
|
||||
WRITE_ONCE(pmu->mscg_stat, PMU_MSCG_DISABLED);
|
||||
/* make status visible */
|
||||
smp_mb();
|
||||
}
|
||||
}
|
||||
|
||||
exit_unlock:
|
||||
|
||||
Reference in New Issue
Block a user